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