Home | History | Annotate | Line # | Download | only in cxgb
      1 /**************************************************************************
      2 
      3 Copyright (c) 2007, Chelsio Inc.
      4 All rights reserved.
      5 
      6 Redistribution and use in source and binary forms, with or without
      7 modification, are permitted provided that the following conditions are met:
      8 
      9  1. Redistributions of source code must retain the above copyright notice,
     10     this list of conditions and the following disclaimer.
     11 
     12  2. Neither the name of the Chelsio Corporation nor the names of its
     13     contributors may be used to endorse or promote products derived from
     14     this software without specific prior written permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26 POSSIBILITY OF SUCH DAMAGE.
     27 
     28 ***************************************************************************/
     29 
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: cxgb_main.c,v 1.10 2021/08/07 16:19:14 thorpej Exp $");
     32 
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/kernel.h>
     36 #include <sys/conf.h>
     37 #include <sys/bus.h>
     38 #include <sys/ioccom.h>
     39 #include <sys/mbuf.h>
     40 #include <sys/socket.h>
     41 #include <sys/sockio.h>
     42 #include <sys/sysctl.h>
     43 #include <sys/queue.h>
     44 
     45 #include <net/bpf.h>
     46 #include <net/if.h>
     47 #include <net/if_arp.h>
     48 #include <net/if_dl.h>
     49 #include <net/if_media.h>
     50 #include <net/if_types.h>
     51 
     52 #include <netinet/in_systm.h>
     53 #include <netinet/in.h>
     54 #include <netinet/ip.h>
     55 #include <netinet/ip.h>
     56 #include <netinet/tcp.h>
     57 #include <netinet/udp.h>
     58 #include <netinet/if_inarp.h>
     59 
     60 #include <dev/pci/pcireg.h>
     61 #include <dev/pci/pcivar.h>
     62 
     63 #ifdef CONFIG_DEFINED
     64 #include <cxgb_include.h>
     65 #else
     66 #include <dev/pci/cxgb/cxgb_include.h>
     67 #endif
     68 
     69 #ifdef PRIV_SUPPORTED
     70 #include <sys/priv.h>
     71 #endif
     72 
     73 #include <altq/altq_conf.h>
     74 
     75 static int cxgb_setup_msix(adapter_t *, int);
     76 static void cxgb_teardown_msix(adapter_t *);
     77 static int cxgb_init(struct ifnet *);
     78 static void cxgb_init_locked(struct port_info *);
     79 static void cxgb_stop_locked(struct port_info *);
     80 static void cxgb_set_rxmode(struct port_info *);
     81 static int cxgb_ioctl(struct ifnet *, unsigned long, void *);
     82 static void cxgb_start(struct ifnet *);
     83 static void cxgb_stop(struct ifnet *, int);
     84 static void cxgb_start_proc(struct work *, void *);
     85 static int cxgb_media_change(struct ifnet *);
     86 static void cxgb_media_status(struct ifnet *, struct ifmediareq *);
     87 static int setup_sge_qsets(adapter_t *);
     88 static int cxgb_async_intr(void *);
     89 static void cxgb_ext_intr_handler(struct work *, void *);
     90 static void cxgb_tick_handler(struct work *, void *);
     91 static void cxgb_down_locked(struct adapter *sc);
     92 static void cxgb_tick(void *);
     93 static void setup_rss(adapter_t *sc);
     94 
     95 /* Attachment glue for the PCI controller end of the device.  Each port of
     96  * the device is attached separately, as defined later.
     97  */
     98 static int cxgb_controller_match(device_t dev, cfdata_t match, void *context);
     99 static void cxgb_controller_attach(device_t parent, device_t dev, void *context);
    100 static int cxgb_controller_detach(device_t dev, int flags);
    101 static void cxgb_free(struct adapter *);
    102 static __inline void reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
    103     unsigned int end);
    104 static void touch_bars(device_t dev);
    105 
    106 #ifdef notyet
    107 static int offload_close(struct toedev *tdev);
    108 #endif
    109 
    110 
    111 CFATTACH_DECL_NEW(cxgbc, sizeof(struct adapter), cxgb_controller_match, cxgb_controller_attach, cxgb_controller_detach, NULL);
    112 
    113 /*
    114  * Attachment glue for the ports.  Attachment is done directly to the
    115  * controller device.
    116  */
    117 static int cxgb_port_match(device_t dev, cfdata_t match, void *context);
    118 static void cxgb_port_attach(device_t dev, device_t self, void *context);
    119 static int cxgb_port_detach(device_t dev, int flags);
    120 
    121 CFATTACH_DECL_NEW(cxgb, sizeof(struct port_device), cxgb_port_match, cxgb_port_attach, cxgb_port_detach, NULL);
    122 
    123 #define SGE_MSIX_COUNT (SGE_QSETS + 1)
    124 
    125 extern int collapse_mbufs;
    126 #ifdef MSI_SUPPORTED
    127 /*
    128  * The driver uses the best interrupt scheme available on a platform in the
    129  * order MSI-X, MSI, legacy pin interrupts.  This parameter determines which
    130  * of these schemes the driver may consider as follows:
    131  *
    132  * msi = 2: choose from among all three options
    133  * msi = 1 : only consider MSI and pin interrupts
    134  * msi = 0: force pin interrupts
    135  */
    136 static int msi_allowed = 2;
    137 #endif
    138 
    139 /*
    140  * The driver uses an auto-queue algorithm by default.
    141  * To disable it and force a single queue-set per port, use singleq = 1.
    142  */
    143 static int singleq = 1;
    144 
    145 enum {
    146     MAX_TXQ_ENTRIES      = 16384,
    147     MAX_CTRL_TXQ_ENTRIES = 1024,
    148     MAX_RSPQ_ENTRIES     = 16384,
    149     MAX_RX_BUFFERS       = 16384,
    150     MAX_RX_JUMBO_BUFFERS = 16384,
    151     MIN_TXQ_ENTRIES      = 4,
    152     MIN_CTRL_TXQ_ENTRIES = 4,
    153     MIN_RSPQ_ENTRIES     = 32,
    154     MIN_FL_ENTRIES       = 32,
    155     MIN_FL_JUMBO_ENTRIES = 32
    156 };
    157 
    158 struct filter_info {
    159     u32 sip;
    160     u32 sip_mask;
    161     u32 dip;
    162     u16 sport;
    163     u16 dport;
    164     u32 vlan:12;
    165     u32 vlan_prio:3;
    166     u32 mac_hit:1;
    167     u32 mac_idx:4;
    168     u32 mac_vld:1;
    169     u32 pkt_type:2;
    170     u32 report_filter_id:1;
    171     u32 pass:1;
    172     u32 rss:1;
    173     u32 qset:3;
    174     u32 locked:1;
    175     u32 valid:1;
    176 };
    177 
    178 enum { FILTER_NO_VLAN_PRI = 7 };
    179 
    180 #define PORT_MASK ((1 << MAX_NPORTS) - 1)
    181 
    182 /* Table for probing the cards.  The desc field isn't actually used */
    183 struct cxgb_ident {
    184     uint16_t    vendor;
    185     uint16_t    device;
    186     int         index;
    187     const char  *desc;
    188 } cxgb_identifiers[] = {
    189     {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"},
    190     {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"},
    191     {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"},
    192     {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"},
    193     {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"},
    194     {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"},
    195     {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"},
    196     {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"},
    197     {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"},
    198     {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"},
    199     {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"},
    200     {0, 0, 0, NULL}
    201 };
    202 
    203 
    204 static inline char
    205 t3rev2char(struct adapter *adapter)
    206 {
    207     char rev = 'z';
    208 
    209     switch(adapter->params.rev) {
    210     case T3_REV_A:
    211         rev = 'a';
    212         break;
    213     case T3_REV_B:
    214     case T3_REV_B2:
    215         rev = 'b';
    216         break;
    217     case T3_REV_C:
    218         rev = 'c';
    219         break;
    220     }
    221     return rev;
    222 }
    223 
    224 static struct cxgb_ident *cxgb_get_ident(struct pci_attach_args *pa)
    225 {
    226     struct cxgb_ident *id;
    227     int vendorid, deviceid;
    228 
    229     vendorid = PCI_VENDOR(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG));
    230     deviceid = PCI_PRODUCT(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG));
    231 
    232     for (id = cxgb_identifiers; id->desc != NULL; id++) {
    233         if ((id->vendor == vendorid) &&
    234             (id->device == deviceid)) {
    235             return (id);
    236         }
    237     }
    238     return (NULL);
    239 }
    240 
    241 static const struct adapter_info *cxgb_get_adapter_info(struct pci_attach_args *pa)
    242 {
    243     struct cxgb_ident *id;
    244     const struct adapter_info *ai;
    245 
    246     id = cxgb_get_ident(pa);
    247     if (id == NULL)
    248         return (NULL);
    249 
    250     ai = t3_get_adapter_info(id->index);
    251     return (ai);
    252 }
    253 
    254 static int cxgb_controller_match(device_t dev, cfdata_t match, void *context)
    255 {
    256     struct pci_attach_args *pa = context;
    257     const struct adapter_info *ai;
    258 
    259     ai = cxgb_get_adapter_info(pa);
    260     if (ai == NULL)
    261         return (0);
    262 
    263     return (100); // we ARE the best driver for this card!!
    264 }
    265 
    266 #define FW_FNAME "t3fw%d%d%d"
    267 #define TPEEPROM_NAME "t3%ctpe%d%d%d"
    268 #define TPSRAM_NAME "t3%cps%d%d%d"
    269 
    270 int cxgb_cfprint(void *aux, const char *info);
    271 int cxgb_cfprint(void *aux, const char *info)
    272 {
    273     if (info)
    274     {
    275         printf("cxgb_cfprint(%p, \"%s\")\n", aux, info);
    276         INT3;
    277     }
    278 
    279     return (QUIET);
    280 }
    281 
    282 void cxgb_make_task(void *context)
    283 {
    284     struct cxgb_task *w = (struct cxgb_task *)context;
    285 
    286     // we can only use workqueue_create() once the system is up and running
    287     workqueue_create(&w->wq, w->name, w->func, w->context, PRIBIO, IPL_NET, 0);
    288 //  printf("======>> create workqueue for %s %p\n", w->name, w->wq);
    289 }
    290 
    291 static void
    292 cxgb_controller_attach(device_t parent, device_t dev, void *context)
    293 {
    294     device_t child;
    295     const struct adapter_info *ai;
    296     struct adapter *sc;
    297     struct pci_attach_args *pa = context;
    298     struct cxgb_attach_args cxgb_args;
    299     int locs[2];
    300     int i, error = 0;
    301     uint32_t vers;
    302     int port_qsets = 1;
    303     int reg;
    304 #ifdef MSI_SUPPORTED
    305     int msi_needed;
    306 #endif
    307 
    308     sc = device_private(dev);
    309     sc->dev = dev;
    310     memcpy(&sc->pa, pa, sizeof(struct pci_attach_args));
    311     sc->msi_count = 0;
    312     ai = cxgb_get_adapter_info(pa);
    313 
    314     /*
    315      * XXX not really related but a recent addition
    316      */
    317 #ifdef MSI_SUPPORTED
    318     /* find the PCIe link width and set max read request to 4KB*/
    319     if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
    320         uint16_t lnk, pectl;
    321         lnk = pci_read_config(dev, reg + 0x12, 2);
    322         sc->link_width = (lnk >> 4) & 0x3f;
    323 
    324         pectl = pci_read_config(dev, reg + 0x8, 2);
    325         pectl = (pectl & ~0x7000) | (5 << 12);
    326         pci_write_config(dev, reg + 0x8, pectl, 2);
    327     }
    328 
    329     if (sc->link_width != 0 && sc->link_width <= 4 &&
    330         (ai->nports0 + ai->nports1) <= 2) {
    331         device_printf(sc->dev,
    332             "PCIe x%d Link, expect reduced performance\n",
    333             sc->link_width);
    334     }
    335 #endif
    336 
    337     touch_bars(dev);
    338 
    339     pci_enable_busmaster(dev);
    340 
    341     /*
    342      * Allocate the registers and make them available to the driver.
    343      * The registers that we care about for NIC mode are in BAR 0
    344      */
    345 	sc->regs_rid = PCI_MAPREG_START;
    346 	t3_os_pci_read_config_4(sc, PCI_MAPREG_START, &reg);
    347 
    348 	// call bus_space_map
    349 	sc->bar0 = reg&0xFFFFF000;
    350 	bus_space_map(sc->pa.pa_memt, sc->bar0, 4096, 0, &sc->bar0_handle);
    351 
    352     MTX_INIT(&sc->sge.reg_lock, sc->reglockbuf, NULL, MTX_DEF);
    353     MTX_INIT(&sc->mdio_lock, sc->mdiolockbuf, NULL, MTX_DEF);
    354     MTX_INIT(&sc->elmer_lock, sc->elmerlockbuf, NULL, MTX_DEF);
    355 
    356     sc->bt = sc->pa.pa_memt;
    357     sc->bh = sc->bar0_handle;
    358     sc->mmio_len = 4096;
    359 
    360     if (t3_prep_adapter(sc, ai, 1) < 0) {
    361         printf("prep adapter failed\n");
    362         error = ENODEV;
    363         goto out;
    364     }
    365     /* Allocate the BAR for doing MSI-X.  If it succeeds, try to allocate
    366      * enough messages for the queue sets.  If that fails, try falling
    367      * back to MSI.  If that fails, then try falling back to the legacy
    368      * interrupt pin model.
    369      */
    370 #ifdef MSI_SUPPORTED
    371 
    372     sc->msix_regs_rid = 0x20;
    373     if ((msi_allowed >= 2) &&
    374         (sc->msix_regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
    375         &sc->msix_regs_rid, RF_ACTIVE)) != NULL) {
    376 
    377         msi_needed = sc->msi_count = SGE_MSIX_COUNT;
    378 
    379         if (((error = pci_alloc_msix(dev, &sc->msi_count)) != 0) ||
    380             (sc->msi_count != msi_needed)) {
    381             device_printf(dev, "msix allocation failed - msi_count = %d"
    382                 " msi_needed=%d will try msi err=%d\n", sc->msi_count,
    383                 msi_needed, error);
    384             sc->msi_count = 0;
    385             pci_release_msi(dev);
    386             bus_release_resource(dev, SYS_RES_MEMORY,
    387                 sc->msix_regs_rid, sc->msix_regs_res);
    388             sc->msix_regs_res = NULL;
    389         } else {
    390             sc->flags |= USING_MSIX;
    391             sc->cxgb_intr = t3_intr_msix;
    392         }
    393     }
    394 
    395     if ((msi_allowed >= 1) && (sc->msi_count == 0)) {
    396         sc->msi_count = 1;
    397         if (pci_alloc_msi(dev, &sc->msi_count)) {
    398             device_printf(dev, "alloc msi failed - will try INTx\n");
    399             sc->msi_count = 0;
    400             pci_release_msi(dev);
    401         } else {
    402             sc->flags |= USING_MSI;
    403             sc->irq_rid = 1;
    404             sc->cxgb_intr = t3_intr_msi;
    405         }
    406     }
    407 #endif
    408     if (sc->msi_count == 0) {
    409         device_printf(dev, "using line interrupts\n");
    410         sc->irq_rid = 0;
    411         sc->cxgb_intr = t3b_intr;
    412     }
    413 
    414     sc->ext_intr_task.name = "cxgb_ext_intr_handler";
    415     sc->ext_intr_task.func = cxgb_ext_intr_handler;
    416     sc->ext_intr_task.context = sc;
    417     kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &sc->ext_intr_task, NULL, "cxgb_make_task");
    418 
    419     sc->tick_task.name = "cxgb_tick_handler";
    420     sc->tick_task.func = cxgb_tick_handler;
    421     sc->tick_task.context = sc;
    422     kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &sc->tick_task, NULL, "cxgb_make_task");
    423 
    424     /* Create a periodic callout for checking adapter status */
    425     callout_init(&sc->cxgb_tick_ch, 0);
    426 
    427     if (t3_check_fw_version(sc) != 0) {
    428         /*
    429          * Warn user that a firmware update will be attempted in init.
    430          */
    431         device_printf(dev, "firmware needs to be updated to version %d.%d.%d\n",
    432             FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
    433         sc->flags &= ~FW_UPTODATE;
    434     } else {
    435         sc->flags |= FW_UPTODATE;
    436     }
    437 
    438     if (t3_check_tpsram_version(sc) != 0) {
    439         /*
    440          * Warn user that a firmware update will be attempted in init.
    441          */
    442         device_printf(dev, "SRAM needs to be updated to version %c-%d.%d.%d\n",
    443             t3rev2char(sc), TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
    444         sc->flags &= ~TPS_UPTODATE;
    445     } else {
    446         sc->flags |= TPS_UPTODATE;
    447     }
    448 
    449     if ((sc->flags & USING_MSIX) && !singleq)
    450         port_qsets = (SGE_QSETS/(sc)->params.nports);
    451 
    452     /*
    453      * Create a child device for each MAC.  The ethernet attachment
    454      * will be done in these children.
    455      */
    456     for (i = 0; i < (sc)->params.nports; i++) {
    457         struct port_info *pi;
    458 
    459         pi = &sc->port[i];
    460         pi->adapter = sc;
    461         pi->nqsets = port_qsets;
    462         pi->first_qset = i*port_qsets;
    463         pi->port_id = i;
    464         pi->tx_chan = i >= ai->nports0;
    465         pi->txpkt_intf = pi->tx_chan ? 2 * (i - ai->nports0) + 1 : 2 * i;
    466         sc->rxpkt_map[pi->txpkt_intf] = i;
    467         cxgb_args.port = i;
    468         locs[0] = 1;
    469         locs[1] = i;
    470 	printf("\n"); // for cleaner formatting in dmesg
    471         child = config_found(dev, &cxgb_args, cxgb_cfprint,
    472 	    CFARGS(.submatch = config_stdsubmatch,
    473 		   .locators = locs));
    474 	printf("\n"); // for cleaner formatting in dmesg
    475         sc->portdev[i] = child;
    476     }
    477 
    478     /*
    479      * XXX need to poll for link status
    480      */
    481     sc->params.stats_update_period = 1;
    482 
    483     /* initialize sge private state */
    484     t3_sge_init_adapter(sc);
    485 
    486     t3_led_ready(sc);
    487 
    488     error = t3_get_fw_version(sc, &vers);
    489     if (error)
    490         goto out;
    491 
    492     snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d.%d",
    493         G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers),
    494         G_FW_VERSION_MICRO(vers));
    495 out:
    496     if (error)
    497     {
    498         cxgb_free(sc);
    499     }
    500 }
    501 
    502 static int
    503 cxgb_controller_detach(device_t dev, int flags)
    504 {
    505     struct adapter *sc;
    506 
    507     sc = device_private(dev);
    508 
    509     cxgb_free(sc);
    510 
    511     return (0);
    512 }
    513 
    514 static void
    515 cxgb_free(struct adapter *sc)
    516 {
    517     int i;
    518 
    519     ADAPTER_LOCK(sc);
    520     /*
    521      * drops the lock
    522      */
    523     cxgb_down_locked(sc);
    524 
    525 #ifdef MSI_SUPPORTED
    526     if (sc->flags & (USING_MSI | USING_MSIX)) {
    527         device_printf(sc->dev, "releasing msi message(s)\n");
    528         pci_release_msi(sc->dev);
    529     } else {
    530         device_printf(sc->dev, "no msi message to release\n");
    531     }
    532     if (sc->msix_regs_res != NULL) {
    533         bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
    534             sc->msix_regs_res);
    535     }
    536 #endif
    537 
    538     t3_sge_deinit_sw(sc);
    539     /*
    540      * Wait for last callout
    541      */
    542 
    543     tsleep(&sc, 0, "cxgb unload", 3*hz);
    544 
    545     for (i = 0; i < (sc)->params.nports; ++i) {
    546         if (sc->portdev[i] != NULL)
    547 	{
    548 		INT3;
    549 	}
    550     }
    551 
    552 #ifdef notyet
    553     if (is_offload(sc)) {
    554         cxgb_adapter_unofld(sc);
    555         if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
    556             offload_close(&sc->tdev);
    557     }
    558 #endif
    559 
    560     t3_free_sge_resources(sc);
    561     free(sc->filters, M_DEVBUF);
    562     t3_sge_free(sc);
    563 
    564     MTX_DESTROY(&sc->mdio_lock);
    565     MTX_DESTROY(&sc->sge.reg_lock);
    566     MTX_DESTROY(&sc->elmer_lock);
    567     ADAPTER_LOCK_DEINIT(sc);
    568 
    569     return;
    570 }
    571 
    572 /**
    573  *  setup_sge_qsets - configure SGE Tx/Rx/response queues
    574  *  @sc: the controller softc
    575  *
    576  *  Determines how many sets of SGE queues to use and initializes them.
    577  *  We support multiple queue sets per port if we have MSI-X, otherwise
    578  *  just one queue set per port.
    579  */
    580 static int
    581 setup_sge_qsets(adapter_t *sc)
    582 {
    583     int i, j, err, irq_idx = 0, qset_idx = 0;
    584     u_int ntxq = SGE_TXQ_PER_SET;
    585 
    586     if ((err = t3_sge_alloc(sc)) != 0) {
    587         device_printf(sc->dev, "t3_sge_alloc returned %d\n", err);
    588         return (err);
    589     }
    590 
    591     if (sc->params.rev > 0 && !(sc->flags & USING_MSI))
    592         irq_idx = -1;
    593 
    594     for (i = 0; i < (sc)->params.nports; i++) {
    595         struct port_info *pi = &sc->port[i];
    596 
    597         for (j = 0; j < pi->nqsets; j++, qset_idx++) {
    598             err = t3_sge_alloc_qset(sc, qset_idx, (sc)->params.nports,
    599                 (sc->flags & USING_MSIX) ? qset_idx + 1 : irq_idx,
    600                 &sc->params.sge.qset[qset_idx], ntxq, pi);
    601             if (err) {
    602                 t3_free_sge_resources(sc);
    603                 device_printf(sc->dev, "t3_sge_alloc_qset failed with %d\n",
    604                     err);
    605                 return (err);
    606             }
    607         }
    608     }
    609 
    610     return (0);
    611 }
    612 
    613 static void
    614 cxgb_teardown_msix(adapter_t *sc)
    615 {
    616     int i, nqsets;
    617 
    618     for (nqsets = i = 0; i < (sc)->params.nports; i++)
    619         nqsets += sc->port[i].nqsets;
    620 
    621     for (i = 0; i < nqsets; i++) {
    622         if (sc->msix_intr_tag[i] != NULL) {
    623             sc->msix_intr_tag[i] = NULL;
    624         }
    625         if (sc->msix_irq_res[i] != NULL) {
    626             sc->msix_irq_res[i] = NULL;
    627         }
    628     }
    629 }
    630 
    631 static int
    632 cxgb_setup_msix(adapter_t *sc, int msix_count)
    633 {
    634     int i, j, k, nqsets, rid;
    635 
    636     /* The first message indicates link changes and error conditions */
    637     sc->irq_rid = 1;
    638     /* Allocate PCI interrupt resources. */
    639     if (pci_intr_map(&sc->pa, &sc->intr_handle))
    640     {
    641         printf("cxgb_setup_msix(%d): pci_intr_map() failed\n", __LINE__);
    642         return (EINVAL);
    643     }
    644     sc->intr_cookie = pci_intr_establish_xname(sc->pa.pa_pc, sc->intr_handle,
    645                         IPL_NET, cxgb_async_intr, sc, device_xname(sc->dev));
    646     if (sc->intr_cookie == NULL)
    647     {
    648         printf("cxgb_setup_msix(%d): pci_intr_establish() failed\n", __LINE__);
    649         return (EINVAL);
    650     }
    651     for (i = k = 0; i < (sc)->params.nports; i++) {
    652         nqsets = sc->port[i].nqsets;
    653         for (j = 0; j < nqsets; j++, k++) {
    654             rid = k + 2;
    655             if (cxgb_debug)
    656                 printf("rid=%d ", rid);
    657             INT3;
    658         }
    659     }
    660 
    661 
    662     return (0);
    663 }
    664 
    665 static int cxgb_port_match(device_t dev, cfdata_t match, void *context)
    666 {
    667     return (100);
    668 }
    669 
    670 #define IFCAP_HWCSUM (IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx)
    671 #define IFCAP_RXCSUM IFCAP_CSUM_IPv4_Rx
    672 #define IFCAP_TXCSUM IFCAP_CSUM_IPv4_Tx
    673 
    674 #ifdef TSO_SUPPORTED
    675 #define CXGB_CAP (IFCAP_HWCSUM | IFCAP_TSO)
    676 /* Don't enable TSO6 yet */
    677 #define CXGB_CAP_ENABLE (IFCAP_HWCSUM | IFCAP_TSO4)
    678 #else
    679 #define CXGB_CAP (IFCAP_HWCSUM)
    680 /* Don't enable TSO6 yet */
    681 #define CXGB_CAP_ENABLE (IFCAP_HWCSUM)
    682 #define IFCAP_TSO4 0x0
    683 #define IFCAP_TSO6 0x0
    684 #define CSUM_TSO   0x0
    685 #endif
    686 
    687 static void
    688 cxgb_port_attach(device_t parent, device_t self, void *context)
    689 {
    690     struct port_info *p;
    691     struct port_device *pd;
    692     int *port_number = (int *)context;
    693     char buf[32];
    694     struct ifnet *ifp;
    695     int media_flags;
    696     pd = device_private(self);
    697     pd->dev = self;
    698     pd->parent = device_private(parent);
    699     pd->port_number = *port_number;
    700     p = &pd->parent->port[*port_number];
    701     p->pd = pd;
    702 
    703     PORT_LOCK_INIT(p, p->lockbuf);
    704 
    705     /* Allocate an ifnet object and set it up */
    706     ifp = p->ifp = (void *)malloc(sizeof (struct ifnet), M_IFADDR, M_WAITOK);
    707     if (ifp == NULL) {
    708         device_printf(self, "Cannot allocate ifnet\n");
    709         return;
    710     }
    711     memset(ifp, 0, sizeof(struct ifnet));
    712 
    713     /*
    714      * Note that there is currently no watchdog timer.
    715      */
    716     snprintf(buf, sizeof(buf), "cxgb%d", p->port);
    717     strcpy(ifp->if_xname, buf);
    718     ifp->if_init = cxgb_init;
    719     ifp->if_softc = p;
    720     ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    721     ifp->if_ioctl = cxgb_ioctl;
    722     ifp->if_start = cxgb_start;
    723     ifp->if_stop = cxgb_stop;
    724     ifp->if_timer = 0;  /* Disable ifnet watchdog */
    725     ifp->if_watchdog = NULL;
    726 
    727     ifp->if_snd.ifq_maxlen = TX_ETH_Q_SIZE;
    728     IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_maxlen);
    729 
    730     IFQ_SET_READY(&ifp->if_snd);
    731 
    732     ifp->if_capabilities = ifp->if_capenable = 0;
    733     ifp->if_baudrate = 10000000000; // 10 Gbps
    734     /*
    735      * disable TSO on 4-port - it isn't supported by the firmware yet
    736      */
    737     if (p->adapter->params.nports > 2) {
    738         ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
    739         ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6);
    740     }
    741 
    742     if_attach(ifp);
    743     ether_ifattach(ifp, p->hw_addr);
    744     /*
    745      * Only default to jumbo frames on 10GigE
    746      */
    747     if (p->adapter->params.nports <= 2)
    748         ifp->if_mtu = 9000;
    749     ifmedia_init(&p->media, IFM_IMASK, cxgb_media_change,
    750         cxgb_media_status);
    751 
    752     if (!strcmp(p->port_type->desc, "10GBASE-CX4")) {
    753         media_flags = IFM_ETHER | IFM_10G_CX4 | IFM_FDX;
    754     } else if (!strcmp(p->port_type->desc, "10GBASE-SR")) {
    755         media_flags = IFM_ETHER | IFM_10G_SR | IFM_FDX;
    756     } else if (!strcmp(p->port_type->desc, "10GBASE-XR")) {
    757         media_flags = IFM_ETHER | IFM_10G_LR | IFM_FDX;
    758     } else if (!strcmp(p->port_type->desc, "10/100/1000BASE-T")) {
    759         ifmedia_add(&p->media, IFM_ETHER | IFM_10_T, 0, NULL);
    760         ifmedia_add(&p->media, IFM_ETHER | IFM_10_T | IFM_FDX,
    761                 0, NULL);
    762         ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX,
    763                 0, NULL);
    764         ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
    765                 0, NULL);
    766         ifmedia_add(&p->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
    767                 0, NULL);
    768         media_flags = 0;
    769     } else {
    770             printf("unsupported media type %s\n", p->port_type->desc);
    771         return;
    772     }
    773     if (media_flags) {
    774         ifmedia_add(&p->media, media_flags, 0, NULL);
    775         ifmedia_set(&p->media, media_flags);
    776     } else {
    777         ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
    778         ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO);
    779     }
    780 
    781     snprintf(p->taskqbuf, TASKQ_NAME_LEN, "cxgb_port_taskq%d", p->port_id);
    782     p->start_task.name = "cxgb_start_proc";
    783     p->start_task.func = cxgb_start_proc;
    784     p->start_task.context = ifp;
    785     kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &p->start_task, NULL, "cxgb_make_task");
    786 
    787     t3_sge_init_port(p);
    788 }
    789 
    790 static int
    791 cxgb_port_detach(device_t self, int flags)
    792 {
    793     struct port_info *p;
    794 
    795     p = device_private(self);
    796 
    797     PORT_LOCK(p);
    798     if (p->ifp->if_drv_flags & IFF_DRV_RUNNING)
    799         cxgb_stop_locked(p);
    800     PORT_UNLOCK(p);
    801 
    802     if (p->start_task.wq != NULL) {
    803         workqueue_destroy(p->start_task.wq);
    804         p->start_task.wq = NULL;
    805     }
    806 
    807     ether_ifdetach(p->ifp);
    808     /*
    809      * the lock may be acquired in ifdetach
    810      */
    811     PORT_LOCK_DEINIT(p);
    812     if_detach(p->ifp);
    813 
    814     ifmedia_fini(&p->media);
    815 
    816     return (0);
    817 }
    818 
    819 void
    820 t3_fatal_err(struct adapter *sc)
    821 {
    822     u_int fw_status[4];
    823 
    824     if (sc->flags & FULL_INIT_DONE) {
    825         t3_sge_stop(sc);
    826         t3_write_reg(sc, A_XGM_TX_CTRL, 0);
    827         t3_write_reg(sc, A_XGM_RX_CTRL, 0);
    828         t3_write_reg(sc, XGM_REG(A_XGM_TX_CTRL, 1), 0);
    829         t3_write_reg(sc, XGM_REG(A_XGM_RX_CTRL, 1), 0);
    830         t3_intr_disable(sc);
    831     }
    832     device_printf(sc->dev,"encountered fatal error, operation suspended\n");
    833     if (!t3_cim_ctl_blk_read(sc, 0xa0, 4, fw_status))
    834         device_printf(sc->dev, "FW_ status: 0x%x, 0x%x, 0x%x, 0x%x\n",
    835             fw_status[0], fw_status[1], fw_status[2], fw_status[3]);
    836 }
    837 
    838 int
    839 t3_os_find_pci_capability(adapter_t *sc, int cap)
    840 {
    841     device_t dev;
    842     uint32_t status;
    843     uint32_t bhlc;
    844     uint32_t temp;
    845     uint8_t ptr;
    846     dev = sc->dev;
    847     status = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, PCI_COMMAND_STATUS_REG);
    848     if (!(status&PCI_STATUS_CAPLIST_SUPPORT))
    849         return (0);
    850     bhlc = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, PCI_BHLC_REG);
    851     switch (PCI_HDRTYPE(bhlc))
    852     {
    853     case 0:
    854     case 1:
    855         ptr = PCI_CAPLISTPTR_REG;
    856         break;
    857     case 2:
    858         ptr = PCI_CARDBUS_CAPLISTPTR_REG;
    859         break;
    860     default:
    861         return (0);
    862     }
    863     temp = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, ptr);
    864     ptr = PCI_CAPLIST_PTR(temp);
    865     while (ptr != 0) {
    866         temp = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, ptr);
    867         if (PCI_CAPLIST_CAP(temp) == cap)
    868             return (ptr);
    869         ptr = PCI_CAPLIST_NEXT(temp);
    870     }
    871 
    872     return (0);
    873 }
    874 
    875 int
    876 t3_os_pci_save_state(struct adapter *sc)
    877 {
    878     INT3;
    879     return (0);
    880 }
    881 
    882 int
    883 t3_os_pci_restore_state(struct adapter *sc)
    884 {
    885     INT3;
    886     return (0);
    887 }
    888 
    889 /**
    890  *  t3_os_link_changed - handle link status changes
    891  *  @adapter: the adapter associated with the link change
    892  *  @port_id: the port index whose limk status has changed
    893  *  @link_stat: the new status of the link
    894  *  @speed: the new speed setting
    895  *  @duplex: the new duplex setting
    896  *  @fc: the new flow-control setting
    897  *
    898  *  This is the OS-dependent handler for link status changes.  The OS
    899  *  neutral handler takes care of most of the processing for these events,
    900  *  then calls this handler for any OS-specific processing.
    901  */
    902 void
    903 t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
    904      int duplex, int fc)
    905 {
    906     struct port_info *pi = &adapter->port[port_id];
    907     struct cmac *mac = &adapter->port[port_id].mac;
    908 
    909     if ((pi->ifp->if_flags & IFF_UP) == 0)
    910         return;
    911 
    912     if (link_status) {
    913         t3_mac_enable(mac, MAC_DIRECTION_RX);
    914         if_link_state_change(pi->ifp, LINK_STATE_UP);
    915     } else {
    916         if_link_state_change(pi->ifp, LINK_STATE_DOWN);
    917         pi->phy.ops->power_down(&pi->phy, 1);
    918         t3_mac_disable(mac, MAC_DIRECTION_RX);
    919         t3_link_start(&pi->phy, mac, &pi->link_config);
    920     }
    921 }
    922 
    923 /*
    924  * Interrupt-context handler for external (PHY) interrupts.
    925  */
    926 void
    927 t3_os_ext_intr_handler(adapter_t *sc)
    928 {
    929     if (cxgb_debug)
    930         printf("t3_os_ext_intr_handler\n");
    931     /*
    932      * Schedule a task to handle external interrupts as they may be slow
    933      * and we use a mutex to protect MDIO registers.  We disable PHY
    934      * interrupts in the meantime and let the task reenable them when
    935      * it's done.
    936      */
    937     ADAPTER_LOCK(sc);
    938     if (sc->slow_intr_mask) {
    939         sc->slow_intr_mask &= ~F_T3DBG;
    940         t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
    941         workqueue_enqueue(sc->ext_intr_task.wq, &sc->ext_intr_task.w, NULL);
    942     }
    943     ADAPTER_UNLOCK(sc);
    944 }
    945 
    946 void
    947 t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[])
    948 {
    949 
    950     /*
    951      * The ifnet might not be allocated before this gets called,
    952      * as this is called early on in attach by t3_prep_adapter
    953      * save the address off in the port structure
    954      */
    955     if (cxgb_debug)
    956 	printf("set_hw_addr on idx %d addr %02x:%02x:%02x:%02x:%02x:%02x\n",
    957 		port_idx, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
    958     memcpy(adapter->port[port_idx].hw_addr, hw_addr, ETHER_ADDR_LEN);
    959 }
    960 
    961 /**
    962  *  link_start - enable a port
    963  *  @p: the port to enable
    964  *
    965  *  Performs the MAC and PHY actions needed to enable a port.
    966  */
    967 static void
    968 cxgb_link_start(struct port_info *p)
    969 {
    970     struct ifnet *ifp;
    971     struct t3_rx_mode rm;
    972     struct cmac *mac = &p->mac;
    973 
    974     ifp = p->ifp;
    975 
    976     t3_init_rx_mode(&rm, p);
    977     if (!mac->multiport)
    978         t3_mac_reset(mac);
    979     t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
    980     t3_mac_set_address(mac, 0, p->hw_addr);
    981     t3_mac_set_rx_mode(mac, &rm);
    982     t3_link_start(&p->phy, mac, &p->link_config);
    983     t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
    984 }
    985 
    986 /**
    987  *  setup_rss - configure Receive Side Steering (per-queue connection demux)
    988  *  @adap: the adapter
    989  *
    990  *  Sets up RSS to distribute packets to multiple receive queues.  We
    991  *  configure the RSS CPU lookup table to distribute to the number of HW
    992  *  receive queues, and the response queue lookup table to narrow that
    993  *  down to the response queues actually configured for each port.
    994  *  We always configure the RSS mapping for two ports since the mapping
    995  *  table has plenty of entries.
    996  */
    997 static void
    998 setup_rss(adapter_t *adap)
    999 {
   1000     int i;
   1001     u_int nq[2];
   1002     uint8_t cpus[SGE_QSETS + 1];
   1003     uint16_t rspq_map[RSS_TABLE_SIZE];
   1004 
   1005     for (i = 0; i < SGE_QSETS; ++i)
   1006         cpus[i] = i;
   1007     cpus[SGE_QSETS] = 0xff;
   1008 
   1009     nq[0] = nq[1] = 0;
   1010     for_each_port(adap, i) {
   1011         const struct port_info *pi = adap2pinfo(adap, i);
   1012 
   1013         nq[pi->tx_chan] += pi->nqsets;
   1014     }
   1015     nq[0] = uimax(nq[0], 1U);
   1016     nq[1] = uimax(nq[1], 1U);
   1017     for (i = 0; i < RSS_TABLE_SIZE / 2; ++i) {
   1018         rspq_map[i] = i % nq[0];
   1019         rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq[1]) + nq[0];
   1020     }
   1021     /* Calculate the reverse RSS map table */
   1022     for (i = 0; i < RSS_TABLE_SIZE; ++i)
   1023         if (adap->rrss_map[rspq_map[i]] == 0xff)
   1024             adap->rrss_map[rspq_map[i]] = i;
   1025 
   1026     t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
   1027               F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | F_OFDMAPEN |
   1028               V_RRCPLCPUSIZE(6), cpus, rspq_map);
   1029 
   1030 }
   1031 
   1032 /*
   1033  * Sends an mbuf to an offload queue driver
   1034  * after dealing with any active network taps.
   1035  */
   1036 static inline int
   1037 offload_tx(struct toedev *tdev, struct mbuf *m)
   1038 {
   1039     int ret;
   1040 
   1041     critical_enter();
   1042     ret = t3_offload_tx(tdev, m);
   1043     critical_exit();
   1044     return (ret);
   1045 }
   1046 
   1047 static void
   1048 send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
   1049                   int hi, int port)
   1050 {
   1051     struct mbuf *m;
   1052     struct mngt_pktsched_wr *req;
   1053 
   1054     m = m_gethdr(M_DONTWAIT, MT_DATA);
   1055     if (m) {
   1056         req = mtod(m, struct mngt_pktsched_wr *);
   1057         req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
   1058         req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
   1059         req->sched = sched;
   1060         req->idx = qidx;
   1061         req->min = lo;
   1062         req->max = hi;
   1063         req->binding = port;
   1064         m->m_len = m->m_pkthdr.len = sizeof(*req);
   1065         t3_mgmt_tx(adap, m);
   1066     }
   1067 }
   1068 
   1069 static void
   1070 bind_qsets(adapter_t *sc)
   1071 {
   1072     int i, j;
   1073 
   1074     for (i = 0; i < (sc)->params.nports; ++i) {
   1075         const struct port_info *pi = adap2pinfo(sc, i);
   1076 
   1077         for (j = 0; j < pi->nqsets; ++j) {
   1078             send_pktsched_cmd(sc, 1, pi->first_qset + j, -1,
   1079                       -1, pi->tx_chan);
   1080 
   1081         }
   1082     }
   1083 }
   1084 
   1085 /**
   1086  *  cxgb_up - enable the adapter
   1087  *  @adap: adapter being enabled
   1088  *
   1089  *  Called when the first port is enabled, this function performs the
   1090  *  actions necessary to make an adapter operational, such as completing
   1091  *  the initialization of HW modules, and enabling interrupts.
   1092  *
   1093  */
   1094 static int
   1095 cxgb_up(struct adapter *sc)
   1096 {
   1097     int err = 0;
   1098 
   1099     if ((sc->flags & FULL_INIT_DONE) == 0) {
   1100 
   1101         if ((sc->flags & FW_UPTODATE) == 0)
   1102 	    printf("SHOULD UPGRADE FIRMWARE!\n");
   1103         if ((sc->flags & TPS_UPTODATE) == 0)
   1104 	    printf("SHOULD UPDATE TPSRAM\n");
   1105         err = t3_init_hw(sc, 0);
   1106         if (err)
   1107             goto out;
   1108 
   1109         t3_write_reg(sc, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
   1110 
   1111         err = setup_sge_qsets(sc);
   1112         if (err)
   1113             goto out;
   1114 
   1115         setup_rss(sc);
   1116         sc->flags |= FULL_INIT_DONE;
   1117     }
   1118 
   1119     t3_intr_clear(sc);
   1120 
   1121     /* If it's MSI or INTx, allocate a single interrupt for everything */
   1122     if ((sc->flags & USING_MSIX) == 0) {
   1123         if (pci_intr_map(&sc->pa, &sc->intr_handle))
   1124         {
   1125             device_printf(sc->dev, "Cannot allocate interrupt\n");
   1126             err = EINVAL;
   1127             goto out;
   1128         }
   1129         device_printf(sc->dev, "allocated intr_handle=%d\n", sc->intr_handle);
   1130         sc->intr_cookie = pci_intr_establish_xname(sc->pa.pa_pc,
   1131                     sc->intr_handle, IPL_NET,
   1132                     sc->cxgb_intr, sc, device_xname(sc->dev));
   1133         if (sc->intr_cookie == NULL)
   1134         {
   1135             device_printf(sc->dev, "Cannot establish interrupt\n");
   1136             err = EINVAL;
   1137             goto irq_err;
   1138         }
   1139     } else {
   1140         printf("Using MSIX?!?!?!\n");
   1141         INT3;
   1142         cxgb_setup_msix(sc, sc->msi_count);
   1143     }
   1144 
   1145     t3_sge_start(sc);
   1146     t3_intr_enable(sc);
   1147 
   1148     if (!(sc->flags & QUEUES_BOUND)) {
   1149         bind_qsets(sc);
   1150         sc->flags |= QUEUES_BOUND;
   1151     }
   1152 out:
   1153     return (err);
   1154 irq_err:
   1155     CH_ERR(sc, "request_irq failed, err %d\n", err);
   1156     goto out;
   1157 }
   1158 
   1159 
   1160 /*
   1161  * Release resources when all the ports and offloading have been stopped.
   1162  */
   1163 static void
   1164 cxgb_down_locked(struct adapter *sc)
   1165 {
   1166     t3_sge_stop(sc);
   1167     t3_intr_disable(sc);
   1168 
   1169     INT3; // XXXXXXXXXXXXXXXXXX
   1170 
   1171     if (sc->flags & USING_MSIX)
   1172         cxgb_teardown_msix(sc);
   1173     ADAPTER_UNLOCK(sc);
   1174 
   1175     callout_drain(&sc->cxgb_tick_ch);
   1176     callout_drain(&sc->sge_timer_ch);
   1177 
   1178 #ifdef notyet
   1179 
   1180         if (sc->port[i].tq != NULL)
   1181 #endif
   1182 
   1183 }
   1184 
   1185 static int
   1186 cxgb_init(struct ifnet *ifp)
   1187 {
   1188     struct port_info *p = ifp->if_softc;
   1189 
   1190     PORT_LOCK(p);
   1191     cxgb_init_locked(p);
   1192     PORT_UNLOCK(p);
   1193 
   1194     return (0); // ????????????
   1195 }
   1196 
   1197 static void
   1198 cxgb_init_locked(struct port_info *p)
   1199 {
   1200     struct ifnet *ifp;
   1201     adapter_t *sc = p->adapter;
   1202     int err;
   1203 
   1204     PORT_LOCK_ASSERT_OWNED(p);
   1205     ifp = p->ifp;
   1206 
   1207     ADAPTER_LOCK(p->adapter);
   1208     if ((sc->open_device_map == 0) && (err = cxgb_up(sc))) {
   1209         ADAPTER_UNLOCK(p->adapter);
   1210         cxgb_stop_locked(p);
   1211         return;
   1212     }
   1213     if (p->adapter->open_device_map == 0) {
   1214         t3_intr_clear(sc);
   1215         t3_sge_init_adapter(sc);
   1216     }
   1217     setbit(&p->adapter->open_device_map, p->port_id);
   1218     ADAPTER_UNLOCK(p->adapter);
   1219 
   1220     cxgb_link_start(p);
   1221     t3_link_changed(sc, p->port_id);
   1222     ifp->if_baudrate = p->link_config.speed * 1000000;
   1223 
   1224     device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id);
   1225     t3_port_intr_enable(sc, p->port_id);
   1226 
   1227     callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
   1228         cxgb_tick, sc);
   1229 
   1230     ifp->if_drv_flags |= IFF_DRV_RUNNING;
   1231     ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
   1232 }
   1233 
   1234 static void
   1235 cxgb_set_rxmode(struct port_info *p)
   1236 {
   1237     struct t3_rx_mode rm;
   1238     struct cmac *mac = &p->mac;
   1239 
   1240     PORT_LOCK_ASSERT_OWNED(p);
   1241 
   1242     t3_init_rx_mode(&rm, p);
   1243     t3_mac_set_rx_mode(mac, &rm);
   1244 }
   1245 
   1246 static void
   1247 cxgb_stop_locked(struct port_info *p)
   1248 {
   1249     struct ifnet *ifp;
   1250 
   1251     PORT_LOCK_ASSERT_OWNED(p);
   1252     ADAPTER_LOCK_ASSERT_NOTOWNED(p->adapter);
   1253 
   1254     ifp = p->ifp;
   1255 
   1256     t3_port_intr_disable(p->adapter, p->port_id);
   1257     ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
   1258     p->phy.ops->power_down(&p->phy, 1);
   1259     t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
   1260 
   1261     ADAPTER_LOCK(p->adapter);
   1262     clrbit(&p->adapter->open_device_map, p->port_id);
   1263 
   1264 
   1265     if (p->adapter->open_device_map == 0) {
   1266         cxgb_down_locked(p->adapter);
   1267     } else
   1268         ADAPTER_UNLOCK(p->adapter);
   1269 
   1270 }
   1271 
   1272 static int
   1273 cxgb_set_mtu(struct port_info *p, int mtu)
   1274 {
   1275     struct ifnet *ifp = p->ifp;
   1276     struct ifreq ifr;
   1277     int error = 0;
   1278 
   1279     ifr.ifr_mtu = mtu;
   1280 
   1281     if ((mtu < ETHERMIN) || (mtu > ETHER_MAX_LEN_JUMBO))
   1282         error = EINVAL;
   1283     else if ((error = ifioctl_common(ifp, SIOCSIFMTU, &ifr)) == ENETRESET) {
   1284         error = 0;
   1285         PORT_LOCK(p);
   1286         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
   1287             callout_stop(&p->adapter->cxgb_tick_ch);
   1288             cxgb_stop_locked(p);
   1289             cxgb_init_locked(p);
   1290         }
   1291         PORT_UNLOCK(p);
   1292     }
   1293     return (error);
   1294 }
   1295 
   1296 static int
   1297 cxgb_ioctl(struct ifnet *ifp, unsigned long command, void *data)
   1298 {
   1299     struct port_info *p = ifp->if_softc;
   1300     struct ifaddr *ifa = (struct ifaddr *)data;
   1301     struct ifreq *ifr = (struct ifreq *)data;
   1302     int flags, error = 0;
   1303 
   1304     /*
   1305      * XXX need to check that we aren't in the middle of an unload
   1306      */
   1307     printf("cxgb_ioctl(%d): command=%08lx\n", __LINE__, command);
   1308     switch (command) {
   1309     case SIOCSIFMTU:
   1310         error = cxgb_set_mtu(p, ifr->ifr_mtu);
   1311 	printf("SIOCSIFMTU: error=%d\n", error);
   1312         break;
   1313     case SIOCINITIFADDR:
   1314 	printf("SIOCINITIFADDR:\n");
   1315         PORT_LOCK(p);
   1316         if (ifa->ifa_addr->sa_family == AF_INET) {
   1317             ifp->if_flags |= IFF_UP;
   1318             if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
   1319                 cxgb_init_locked(p);
   1320             arp_ifinit(ifp, ifa);
   1321         } else
   1322             error = ether_ioctl(ifp, command, data);
   1323         PORT_UNLOCK(p);
   1324         break;
   1325     case SIOCSIFFLAGS:
   1326 	printf("SIOCSIFFLAGS:\n");
   1327 #if 0
   1328 	if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   1329 		break;
   1330 #endif
   1331         callout_drain(&p->adapter->cxgb_tick_ch);
   1332         PORT_LOCK(p);
   1333         if (ifp->if_flags & IFF_UP) {
   1334             if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
   1335                 flags = p->if_flags;
   1336                 if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
   1337                     ((ifp->if_flags ^ flags) & IFF_ALLMULTI))
   1338                     cxgb_set_rxmode(p);
   1339             } else
   1340                 cxgb_init_locked(p);
   1341             p->if_flags = ifp->if_flags;
   1342         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
   1343             cxgb_stop_locked(p);
   1344 
   1345         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
   1346             adapter_t *sc = p->adapter;
   1347             callout_reset(&sc->cxgb_tick_ch,
   1348                 sc->params.stats_update_period * hz,
   1349                 cxgb_tick, sc);
   1350         }
   1351         PORT_UNLOCK(p);
   1352         break;
   1353     case SIOCSIFMEDIA:
   1354 	printf("SIOCSIFMEDIA:\n");
   1355     case SIOCGIFMEDIA:
   1356         error = ifmedia_ioctl(ifp, ifr, &p->media, command);
   1357 	printf("SIOCGIFMEDIA: error=%d\n", error);
   1358         break;
   1359     default:
   1360 	printf("Dir = %x  Len = %x  Group = '%c'  Num = %x\n",
   1361 		(unsigned int)(command&0xe0000000)>>28, (unsigned int)(command&0x1fff0000)>>16,
   1362 		(unsigned int)(command&0xff00)>>8, (unsigned int)command&0xff);
   1363         if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
   1364 		break;
   1365 	error = 0;
   1366         break;
   1367     }
   1368     return (error);
   1369 }
   1370 
   1371 static int
   1372 cxgb_start_tx(struct ifnet *ifp, uint32_t txmax)
   1373 {
   1374     struct sge_qset *qs;
   1375     struct sge_txq *txq;
   1376     struct port_info *p = ifp->if_softc;
   1377     struct mbuf *m = NULL;
   1378     int err, in_use_init, free_it;
   1379 
   1380     if (!p->link_config.link_ok)
   1381     {
   1382         return (ENXIO);
   1383     }
   1384 
   1385     if (IFQ_IS_EMPTY(&ifp->if_snd))
   1386     {
   1387         return (ENOBUFS);
   1388     }
   1389 
   1390     qs = &p->adapter->sge.qs[p->first_qset];
   1391     txq = &qs->txq[TXQ_ETH];
   1392     err = 0;
   1393 
   1394     if (txq->flags & TXQ_TRANSMITTING)
   1395     {
   1396         return (EINPROGRESS);
   1397     }
   1398 
   1399     mtx_lock(&txq->lock);
   1400     txq->flags |= TXQ_TRANSMITTING;
   1401     in_use_init = txq->in_use;
   1402     while ((txq->in_use - in_use_init < txmax) &&
   1403         (txq->size > txq->in_use + TX_MAX_DESC)) {
   1404         free_it = 0;
   1405         IFQ_DEQUEUE(&ifp->if_snd, m);
   1406         if (m == NULL)
   1407             break;
   1408         /*
   1409          * Convert chain to M_IOVEC
   1410          */
   1411         KASSERT((m->m_flags & M_IOVEC) == 0);
   1412 #ifdef notyet
   1413         m0 = m;
   1414         if (collapse_mbufs && m->m_pkthdr.len > MCLBYTES &&
   1415             m_collapse(m, TX_MAX_SEGS, &m0) == EFBIG) {
   1416             if ((m0 = m_defrag(m, M_NOWAIT)) != NULL) {
   1417                 m = m0;
   1418                 m_collapse(m, TX_MAX_SEGS, &m0);
   1419             } else
   1420                 break;
   1421         }
   1422         m = m0;
   1423 #endif
   1424         if ((err = t3_encap(p, &m, &free_it)) != 0)
   1425         {
   1426             printf("t3_encap() returned %d\n", err);
   1427             break;
   1428         }
   1429 //        bpf_mtap(ifp, m, BPF_D_OUT);
   1430         if (free_it)
   1431 	{
   1432             m_freem(m);
   1433 	}
   1434     }
   1435     txq->flags &= ~TXQ_TRANSMITTING;
   1436     mtx_unlock(&txq->lock);
   1437 
   1438     if (__predict_false(err)) {
   1439         if (err == ENOMEM) {
   1440             ifp->if_drv_flags |= IFF_DRV_OACTIVE;
   1441 	// XXXXXXXXXX lock/unlock??
   1442             IF_PREPEND(&ifp->if_snd, m);
   1443         }
   1444     }
   1445     if (err == 0 && m == NULL)
   1446         err = ENOBUFS;
   1447     else if ((err == 0) &&  (txq->size <= txq->in_use + TX_MAX_DESC) &&
   1448         (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
   1449         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
   1450         err = ENOSPC;
   1451     }
   1452     return (err);
   1453 }
   1454 
   1455 static void
   1456 cxgb_start_proc(struct work *wk, void *arg)
   1457 {
   1458     struct ifnet *ifp = arg;
   1459     struct port_info *pi = ifp->if_softc;
   1460     struct sge_qset *qs;
   1461     struct sge_txq *txq;
   1462     int error;
   1463 
   1464     qs = &pi->adapter->sge.qs[pi->first_qset];
   1465     txq = &qs->txq[TXQ_ETH];
   1466 
   1467     do {
   1468         if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC >> 2)
   1469             workqueue_enqueue(pi->timer_reclaim_task.wq, &pi->timer_reclaim_task.w, NULL);
   1470 
   1471         error = cxgb_start_tx(ifp, TX_START_MAX_DESC);
   1472     } while (error == 0);
   1473 }
   1474 
   1475 static void
   1476 cxgb_start(struct ifnet *ifp)
   1477 {
   1478     struct port_info *pi = ifp->if_softc;
   1479     struct sge_qset *qs;
   1480     struct sge_txq *txq;
   1481     int err;
   1482 
   1483     qs = &pi->adapter->sge.qs[pi->first_qset];
   1484     txq = &qs->txq[TXQ_ETH];
   1485 
   1486     if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC >> 2)
   1487         workqueue_enqueue(pi->timer_reclaim_task.wq, &pi->timer_reclaim_task.w, NULL);
   1488 
   1489     err = cxgb_start_tx(ifp, TX_START_MAX_DESC);
   1490 
   1491     if (err == 0)
   1492         workqueue_enqueue(pi->start_task.wq, &pi->start_task.w, NULL);
   1493 }
   1494 
   1495 static void
   1496 cxgb_stop(struct ifnet *ifp, int reason)
   1497 {
   1498     struct port_info *pi = ifp->if_softc;
   1499 
   1500     printf("cxgb_stop(): pi=%p, reason=%d\n", pi, reason);
   1501     INT3;
   1502 }
   1503 
   1504 static int
   1505 cxgb_media_change(struct ifnet *ifp)
   1506 {
   1507     printf("media change not supported: ifp=%p\n", ifp);
   1508     return (ENXIO);
   1509 }
   1510 
   1511 static void
   1512 cxgb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
   1513 {
   1514     struct port_info *p;
   1515 
   1516     p = ifp->if_softc;
   1517 
   1518     ifmr->ifm_status = IFM_AVALID;
   1519     ifmr->ifm_active = IFM_ETHER;
   1520 
   1521     if (!p->link_config.link_ok)
   1522         return;
   1523 
   1524     ifmr->ifm_status |= IFM_ACTIVE;
   1525 
   1526     switch (p->link_config.speed) {
   1527     case 10:
   1528         ifmr->ifm_active |= IFM_10_T;
   1529         break;
   1530     case 100:
   1531         ifmr->ifm_active |= IFM_100_TX;
   1532             break;
   1533     case 1000:
   1534         ifmr->ifm_active |= IFM_1000_T;
   1535         break;
   1536     }
   1537 
   1538     if (p->link_config.duplex)
   1539         ifmr->ifm_active |= IFM_FDX;
   1540     else
   1541         ifmr->ifm_active |= IFM_HDX;
   1542 }
   1543 
   1544 static int
   1545 cxgb_async_intr(void *data)
   1546 {
   1547     adapter_t *sc = data;
   1548 
   1549     if (cxgb_debug)
   1550         device_printf(sc->dev, "cxgb_async_intr\n");
   1551     /*
   1552      * May need to sleep - defer to taskqueue
   1553      */
   1554     workqueue_enqueue(sc->slow_intr_task.wq, &sc->slow_intr_task.w, NULL);
   1555 
   1556     return (1);
   1557 }
   1558 
   1559 static void
   1560 cxgb_ext_intr_handler(struct work *wk, void *arg)
   1561 {
   1562     adapter_t *sc = (adapter_t *)arg;
   1563 
   1564     if (cxgb_debug)
   1565         printf("cxgb_ext_intr_handler\n");
   1566 
   1567     t3_phy_intr_handler(sc);
   1568 
   1569     /* Now reenable external interrupts */
   1570     ADAPTER_LOCK(sc);
   1571     if (sc->slow_intr_mask) {
   1572         sc->slow_intr_mask |= F_T3DBG;
   1573         t3_write_reg(sc, A_PL_INT_CAUSE0, F_T3DBG);
   1574         t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
   1575     }
   1576     ADAPTER_UNLOCK(sc);
   1577 }
   1578 
   1579 static void
   1580 check_link_status(adapter_t *sc)
   1581 {
   1582     int i;
   1583 
   1584     for (i = 0; i < (sc)->params.nports; ++i) {
   1585         struct port_info *p = &sc->port[i];
   1586 
   1587         if (!(p->port_type->caps & SUPPORTED_IRQ))
   1588             t3_link_changed(sc, i);
   1589         p->ifp->if_baudrate = p->link_config.speed * 1000000;
   1590     }
   1591 }
   1592 
   1593 static void
   1594 check_t3b2_mac(struct adapter *adapter)
   1595 {
   1596     int i;
   1597 
   1598     for_each_port(adapter, i) {
   1599         struct port_info *p = &adapter->port[i];
   1600         struct ifnet *ifp = p->ifp;
   1601         int status;
   1602 
   1603         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
   1604             continue;
   1605 
   1606         status = 0;
   1607         PORT_LOCK(p);
   1608         if ((ifp->if_drv_flags & IFF_DRV_RUNNING))
   1609             status = t3b2_mac_watchdog_task(&p->mac);
   1610         if (status == 1)
   1611             p->mac.stats.num_toggled++;
   1612         else if (status == 2) {
   1613             struct cmac *mac = &p->mac;
   1614 
   1615             t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN
   1616                 + ETHER_VLAN_ENCAP_LEN);
   1617             t3_mac_set_address(mac, 0, p->hw_addr);
   1618             cxgb_set_rxmode(p);
   1619             t3_link_start(&p->phy, mac, &p->link_config);
   1620             t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
   1621             t3_port_intr_enable(adapter, p->port_id);
   1622             p->mac.stats.num_resets++;
   1623         }
   1624         PORT_UNLOCK(p);
   1625     }
   1626 }
   1627 
   1628 static void
   1629 cxgb_tick(void *arg)
   1630 {
   1631     adapter_t *sc = (adapter_t *)arg;
   1632 
   1633     workqueue_enqueue(sc->tick_task.wq, &sc->tick_task.w, NULL);
   1634 
   1635     if (sc->open_device_map != 0)
   1636         callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
   1637             cxgb_tick, sc);
   1638 }
   1639 
   1640 static void
   1641 cxgb_tick_handler(struct work *wk, void *arg)
   1642 {
   1643     adapter_t *sc = (adapter_t *)arg;
   1644     const struct adapter_params *p = &sc->params;
   1645 
   1646     ADAPTER_LOCK(sc);
   1647     if (p->linkpoll_period)
   1648         check_link_status(sc);
   1649 
   1650     /*
   1651      * adapter lock can currently only be acquire after the
   1652      * port lock
   1653      */
   1654     ADAPTER_UNLOCK(sc);
   1655 
   1656     if (p->rev == T3_REV_B2 && p->nports < 4)
   1657         check_t3b2_mac(sc);
   1658 }
   1659 
   1660 static void
   1661 touch_bars(device_t dev)
   1662 {
   1663     /*
   1664      * Don't enable yet
   1665      */
   1666 #if !defined(__LP64__) && 0
   1667     u32 v;
   1668 
   1669     pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, &v);
   1670     pci_write_config_dword(pdev, PCI_BASE_ADDRESS_1, v);
   1671     pci_read_config_dword(pdev, PCI_BASE_ADDRESS_3, &v);
   1672     pci_write_config_dword(pdev, PCI_BASE_ADDRESS_3, v);
   1673     pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &v);
   1674     pci_write_config_dword(pdev, PCI_BASE_ADDRESS_5, v);
   1675 #endif
   1676 }
   1677 
   1678 static __inline void
   1679 reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
   1680     unsigned int end)
   1681 {
   1682     uint32_t *p = (uint32_t *)buf + start;
   1683 
   1684     for ( ; start <= end; start += sizeof(uint32_t))
   1685         *p++ = t3_read_reg(ap, start);
   1686 }
   1687 
   1688