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 */