1 /* 2 * Copyright 2008-2013 Solarflare Communications Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "efsys.h" 27 #include "efx.h" 28 #include "efx_types.h" 29 #include "efx_regs.h" 30 #include "efx_impl.h" 31 #include "falcon_gmac.h" 32 #include "falcon_stats.h" 33 34 #if EFSYS_OPT_MAC_FALCON_GMAC 35 36 __checkReturn int 37 falcon_gmac_reset( 38 __in efx_nic_t *enp) 39 { 40 efx_port_t *epp = &(enp->en_port); 41 efx_oword_t oword; 42 int rc; 43 44 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC); 45 46 EFSYS_PROBE(reset); 47 48 /* Ensure that the GMAC registers are accessible */ 49 EFX_BAR_READO(enp, FR_AB_NIC_STAT_REG, &oword); 50 EFX_SET_OWORD_FIELD(oword, FRF_BB_EE_STRAP_EN, 1); 51 EFX_SET_OWORD_FIELD(oword, FRF_BB_EE_STRAP, 0x3); 52 EFX_BAR_WRITEO(enp, FR_AB_NIC_STAT_REG, &oword); 53 54 if ((rc = falcon_mac_wrapper_disable(enp)) != 0) 55 goto fail1; 56 57 enp->en_reset_flags |= EFX_RESET_MAC; 58 59 return (0); 60 61 fail1: 62 EFSYS_PROBE1(fail1, int, rc); 63 64 return (rc); 65 } 66 67 static void 68 falcon_gmac_core_reconfigure( 69 __in efx_nic_t *enp) 70 { 71 efx_port_t *epp = &(enp->en_port); 72 efx_oword_t oword; 73 boolean_t full_duplex; 74 boolean_t byte_mode; 75 76 full_duplex = (epp->ep_link_mode == EFX_LINK_100FDX || 77 epp->ep_link_mode == EFX_LINK_1000FDX); 78 byte_mode = (epp->ep_link_mode == EFX_LINK_1000HDX || 79 epp->ep_link_mode == EFX_LINK_1000FDX); 80 #if EFSYS_OPT_LOOPBACK 81 byte_mode |= (epp->ep_loopback_type == EFX_LOOPBACK_GMAC); 82 83 EFX_POPULATE_OWORD_5(oword, 84 FRF_AB_GM_LOOP, 85 (epp->ep_loopback_type == EFX_LOOPBACK_GMAC) ? 1 : 0, 86 FRF_AB_GM_TX_EN, 1, 87 FRF_AB_GM_TX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_GENERATE) ? 1 : 0, 88 FRF_AB_GM_RX_EN, 1, 89 FRF_AB_GM_RX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_RESPOND) ? 1 : 0); 90 91 #else /* EFSYS_OPT_LOOPBACK */ 92 93 EFX_POPULATE_OWORD_4(oword, 94 FRF_AB_GM_TX_EN, 1, 95 FRF_AB_GM_TX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_GENERATE) ? 1 : 0, 96 FRF_AB_GM_RX_EN, 1, 97 FRF_AB_GM_RX_FC_EN, (epp->ep_fcntl & EFX_FCNTL_RESPOND) ? 1 : 0); 98 99 #endif /* EFSYS_OPT_LOOPBACK */ 100 101 EFX_BAR_WRITEO(enp, FR_AB_GM_CFG1_REG, &oword); 102 EFSYS_SPIN(10); 103 104 EFX_POPULATE_OWORD_4(oword, 105 FRF_AB_GM_IF_MODE, (byte_mode) ? 106 FRF_AB_GM_IF_MODE_BYTE_MODE : FRF_AB_GM_IF_MODE_NIBBLE_MODE, 107 FRF_AB_GM_PAD_CRC_EN, 1, 108 FRF_AB_GM_FD, full_duplex ? 1 : 0, 109 FRF_AB_GM_PAMBL_LEN, 7); 110 111 EFX_BAR_WRITEO(enp, FR_AB_GM_CFG2_REG, &oword); 112 EFSYS_SPIN(10); 113 114 EFX_POPULATE_OWORD_1(oword, FRF_AB_GM_MAX_FLEN, epp->ep_mac_pdu); 115 116 EFX_BAR_WRITEO(enp, FR_AB_GM_MAX_FLEN_REG, &oword); 117 EFSYS_SPIN(10); 118 119 EFX_POPULATE_OWORD_5(oword, 120 FRF_AB_GMF_FTFENREQ, 1, 121 FRF_AB_GMF_STFENREQ, 1, 122 FRF_AB_GMF_FRFENREQ, 1, 123 FRF_AB_GMF_SRFENREQ, 1, 124 FRF_AB_GMF_WTMENREQ, 1); 125 126 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG0_REG, &oword); 127 EFSYS_SPIN(10); 128 129 EFX_POPULATE_OWORD_2(oword, 130 FRF_AB_GMF_CFGFRTH, 0x12, 131 FRF_AB_GMF_CFGXOFFRTX, 0xffff); 132 133 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG1_REG, &oword); 134 EFSYS_SPIN(10); 135 136 EFX_POPULATE_OWORD_2(oword, 137 FRF_AB_GMF_CFGHWM, 0x3f, 138 FRF_AB_GMF_CFGLWM, 0x0a); 139 140 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG2_REG, &oword); 141 EFSYS_SPIN(10); 142 143 EFX_POPULATE_OWORD_2(oword, 144 FRF_AB_GMF_CFGHWMFT, 0x1c, 145 FRF_AB_GMF_CFGFTTH, 0x08); 146 147 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG3_REG, &oword); 148 EFSYS_SPIN(10); 149 150 EFX_POPULATE_OWORD_1(oword, FRF_AB_GMF_HSTFLTRFRM, 0x1000); 151 152 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG4_REG, &oword); 153 EFSYS_SPIN(10); 154 155 EFX_BAR_READO(enp, FR_AB_GMF_CFG5_REG, &oword); 156 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_CFGBYTMODE, byte_mode ? 1 : 0); 157 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_CFGHDPLX, full_duplex ? 0 : 1); 158 EFX_SET_OWORD_FIELD(oword, 159 FRF_AB_GMF_HSTDRPLT64, full_duplex ? 0 : 1); 160 EFX_SET_OWORD_FIELD(oword, FRF_AB_GMF_HSTFLTRFRMDC, 0x3efff); 161 EFX_BAR_WRITEO(enp, FR_AB_GMF_CFG5_REG, &oword); 162 EFSYS_SPIN(10); 163 164 EFX_POPULATE_OWORD_4(oword, 165 FRF_AB_GM_ADR_B0, epp->ep_mac_addr[5], 166 FRF_AB_GM_ADR_B1, epp->ep_mac_addr[4], 167 FRF_AB_GM_ADR_B2, epp->ep_mac_addr[3], 168 FRF_AB_GM_ADR_B3, epp->ep_mac_addr[2]); 169 170 EFX_BAR_WRITEO(enp, FR_AB_GM_ADR1_REG, &oword); 171 EFSYS_SPIN(10); 172 173 EFX_POPULATE_OWORD_2(oword, 174 FRF_AB_GM_ADR_B4, epp->ep_mac_addr[1], 175 FRF_AB_GM_ADR_B5, epp->ep_mac_addr[0]); 176 177 EFX_BAR_WRITEO(enp, FR_AB_GM_ADR2_REG, &oword); 178 EFSYS_SPIN(10); 179 } 180 181 __checkReturn int 182 falcon_gmac_downlink_check( 183 __in efx_nic_t *enp, 184 __out boolean_t *upp) 185 { 186 efx_port_t *epp = &(enp->en_port); 187 188 _NOTE(ARGUNUSED(upp)) 189 190 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC); 191 192 return (ENOTSUP); 193 } 194 195 __checkReturn int 196 falcon_gmac_reconfigure( 197 __in efx_nic_t *enp) 198 { 199 efx_port_t *epp = &(enp->en_port); 200 201 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC); 202 EFSYS_ASSERT3U(epp->ep_link_mode, !=, EFX_LINK_10000FDX); 203 204 EFSYS_PROBE(reconfigure); 205 206 falcon_gmac_core_reconfigure(enp); 207 falcon_mac_wrapper_enable(enp); 208 209 return (0); 210 } 211 212 void 213 falcon_gmac_downlink_reset( 214 __in efx_nic_t *enp, 215 __in boolean_t hold) 216 { 217 _NOTE(ARGUNUSED(enp, hold)) 218 } 219 220 #if EFSYS_OPT_MAC_STATS 221 static uint32_t 222 falcon_gmac_stat_read( 223 __in efsys_mem_t *esmp, 224 __in unsigned int offset, 225 __in unsigned int width) 226 { 227 uint32_t val; 228 229 switch (width) { 230 case 2: { 231 efx_dword_t dword; 232 233 EFSYS_MEM_READD(esmp, offset, &dword); 234 235 val = (uint16_t)EFX_DWORD_FIELD(dword, EFX_WORD_0); 236 break; 237 } 238 case 4: { 239 efx_dword_t dword; 240 241 EFSYS_MEM_READD(esmp, offset, &dword); 242 243 val = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 244 break; 245 } 246 case 6: { 247 efx_qword_t qword; 248 249 EFSYS_MEM_READQ(esmp, offset, &qword); 250 251 val = EFX_QWORD_FIELD(qword, EFX_DWORD_0); 252 break; 253 } 254 default: 255 EFSYS_ASSERT(B_FALSE); 256 257 val = 0; 258 break; 259 } 260 261 return (val); 262 } 263 264 #define GMAC_STAT_READ(_esmp, _id) \ 265 falcon_gmac_stat_read((_esmp), G_STAT_OFFSET(_id), \ 266 G_STAT_WIDTH(_id)) 267 268 #define GMAC_STAT_INCR(_esmp, _stat, _id) \ 269 do { \ 270 delta = GMAC_STAT_READ(_esmp, _id); \ 271 EFSYS_STAT_INCR(&(_stat), delta); \ 272 _NOTE(CONSTANTCONDITION) \ 273 } while (0) 274 275 #define GMAC_STAT_DECR(_esmp, _stat, _id) \ 276 do { \ 277 delta = GMAC_STAT_READ(_esmp, _id); \ 278 EFSYS_STAT_DECR(&(_stat), delta); \ 279 _NOTE(CONSTANTCONDITION) \ 280 } while (0) 281 282 __checkReturn int 283 falcon_gmac_stats_update( 284 __in efx_nic_t *enp, 285 __in efsys_mem_t *esmp, 286 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, 287 __out_opt uint32_t *generationp) 288 { 289 efx_port_t *epp = &(enp->en_port); 290 efx_oword_t oword; 291 uint32_t delta; 292 293 _NOTE(ARGUNUSED(generationp)); 294 EFSYS_ASSERT3U(epp->ep_mac_type, ==, EFX_MAC_FALCON_GMAC); 295 296 /* Check the DMA flag */ 297 if (GMAC_STAT_READ(esmp, DMA_DONE) != DMA_IS_DONE) 298 return (EAGAIN); 299 EFSYS_MEM_READ_BARRIER(); 300 301 /* RX */ 302 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_OCTETS], RX_GOOD_OCT); 303 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_OCTETS], RX_BAD_OCT); 304 305 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_GOOD_LT_64_PKT); 306 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_64_PKT); 307 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_65_TO_127_PKT); 308 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_128_TO_255_PKT); 309 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_256_TO_511_PKT); 310 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_512_TO_1023_PKT); 311 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_1024_TO_15XX_PKT); 312 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_15XX_TO_JUMBO_PKT); 313 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PKTS], RX_GT_JUMBO_PKT); 314 315 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_UNICST_PKTS], RX_UCAST_PKT); 316 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_MULTICST_PKTS], RX_MCAST_PKT); 317 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_BRDCST_PKTS], RX_BCAST_PKT); 318 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_PAUSE_PKTS], RX_PAUSE_PKT); 319 320 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_GOOD_LT_64_PKT); 321 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_BAD_LT_64_PKT); 322 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_LE_64_PKTS], RX_64_PKT); 323 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_65_TO_127_PKTS], 324 RX_65_TO_127_PKT); 325 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_128_TO_255_PKTS], 326 RX_128_TO_255_PKT); 327 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_256_TO_511_PKTS], 328 RX_256_TO_511_PKT); 329 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_512_TO_1023_PKTS], 330 RX_512_TO_1023_PKT); 331 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_1024_TO_15XX_PKTS], 332 RX_1024_TO_15XX_PKT); 333 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_GE_15XX_PKTS], 334 RX_15XX_TO_JUMBO_PKT); 335 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_GE_15XX_PKTS], RX_GT_JUMBO_PKT); 336 337 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_ERRORS], RX_BAD_PKT); 338 GMAC_STAT_DECR(esmp, stat[EFX_MAC_RX_ERRORS], RX_PAUSE_PKT); 339 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS], 340 RX_FCS_ERR_64_TO_15XX_PKT); 341 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS], 342 RX_FCS_ERR_15XX_TO_JUMBO_PKT); 343 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FCS_ERRORS], 344 RX_FCS_ERR_GT_JUMBO_PKT); 345 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_DROP_EVENTS], RX_MISS_PKT); 346 GMAC_STAT_INCR(esmp, stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS], 347 RX_FALSE_CRS); 348 349 EFX_BAR_READO(enp, FR_AZ_RX_NODESC_DROP_REG, &oword); 350 delta = (uint32_t)EFX_OWORD_FIELD(oword, FRF_AZ_RX_NODESC_DROP_CNT); 351 EFSYS_STAT_INCR(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), delta); 352 353 /* TX */ 354 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_OCTETS], TX_GOOD_BAD_OCT); 355 356 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_LT_64_PKT); 357 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_64_PKT); 358 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_65_TO_127_PKT); 359 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_128_TO_255_PKT); 360 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_256_TO_511_PKT); 361 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_512_TO_1023_PKT); 362 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_1024_TO_15XX_PKT); 363 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_15XX_TO_JUMBO_PKT); 364 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PKTS], TX_GT_JUMBO_PKT); 365 366 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_UNICST_PKTS], TX_UCAST_PKT); 367 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_MULTICST_PKTS], TX_MCAST_PKT); 368 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_BRDCST_PKTS], TX_BCAST_PKT); 369 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_PAUSE_PKTS], TX_PAUSE_PKT); 370 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LE_64_PKTS], TX_LT_64_PKT); 371 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LE_64_PKTS], TX_64_PKT); 372 373 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_65_TO_127_PKTS], 374 TX_65_TO_127_PKT); 375 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_128_TO_255_PKTS], 376 TX_128_TO_255_PKT); 377 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_256_TO_511_PKTS], 378 TX_256_TO_511_PKT); 379 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_512_TO_1023_PKTS], 380 TX_512_TO_1023_PKT); 381 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_1024_TO_15XX_PKTS], 382 TX_1024_TO_15XX_PKT); 383 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_GE_15XX_PKTS], 384 TX_15XX_TO_JUMBO_PKT); 385 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_GE_15XX_PKTS], 386 TX_GT_JUMBO_PKT); 387 388 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_ERRORS], TX_BAD_PKT); 389 GMAC_STAT_DECR(esmp, stat[EFX_MAC_TX_ERRORS], TX_PAUSE_PKT); 390 391 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_SGL_COL_PKTS], TX_SGL_COL_PKT); 392 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_MULT_COL_PKTS], TX_MULT_COL_PKT); 393 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_EX_COL_PKTS], TX_EX_COL_PKT); 394 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_LATE_COL_PKTS], TX_LATE_COL); 395 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_DEF_PKTS], TX_DEF_PKT); 396 GMAC_STAT_INCR(esmp, stat[EFX_MAC_TX_EX_DEF_PKTS], TX_EX_DEF_PKT); 397 398 return (0); 399 } 400 401 #endif /* EFSYS_OPT_MAC_STATS */ 402 403 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */