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