]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bce/if_bce.c
Add a driver for the Broadcom NetXtreme II (BCM5706/BCM5708)
[FreeBSD/FreeBSD.git] / sys / dev / bce / if_bce.c
1 /*-
2  * Copyright (c) 2006 Broadcom Corporation
3  *      David Christensen <davidch@broadcom.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written consent.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 /*
35  * The following controllers are supported by this driver:
36  *   BCM5706C A2, A3
37  *   BCM5708C B1
38  *
39  * The following controllers are not supported by this driver:
40  * (These are not "Production" versions of the controller.)
41  * 
42  *   BCM5706C A0, A1
43  *   BCM5706S A0, A1, A2, A3
44  *   BCM5708C A0, B0
45  *   BCM5708S A0, B0, B1
46  */
47
48 #include <dev/bce/if_bcereg.h>
49 #include <dev/bce/if_bcefw.h>
50
51 /****************************************************************************/
52 /* BCE Driver Version                                                       */
53 /****************************************************************************/
54 char bce_driver_version[] = "v0.9.5";
55
56
57 /****************************************************************************/
58 /* BCE Debug Options                                                        */
59 /****************************************************************************/
60 #ifdef BCE_DEBUG
61         u32 bce_debug = BCE_WARN;
62
63         /*          0 = Never              */
64         /*          1 = 1 in 2,147,483,648 */
65         /*        256 = 1 in     8,388,608 */
66         /*       2048 = 1 in     1,048,576 */
67         /*      65536 = 1 in        32,768 */
68         /*    1048576 = 1 in         2,048 */
69         /*  268435456 = 1 in             8 */
70         /*  536870912 = 1 in             4 */
71         /* 1073741824 = 1 in             2 */
72
73         /* Controls how often the l2_fhdr frame error check will fail. */
74         int bce_debug_l2fhdr_status_check = 0;
75
76         /* Controls how often the unexpected attention check will fail. */
77         int bce_debug_unexpected_attention = 0;
78
79         /* Controls how often to simulate an mbuf allocation failure. */
80         int bce_debug_mbuf_allocation_failure = 0;
81
82         /* Controls how often to simulate a DMA mapping failure. */
83         int bce_debug_dma_map_addr_failure = 0;
84
85         /* Controls how often to simulate a bootcode failure. */
86         int bce_debug_bootcode_running_failure = 0;
87 #endif
88
89
90 /****************************************************************************/
91 /* PCI Device ID Table                                                      */
92 /*                                                                          */
93 /* Used by bce_probe() to identify the devices supported by this driver.    */
94 /****************************************************************************/
95 #define BCE_DEVDESC_MAX         64
96
97 static struct bce_type bce_devs[] = {
98         /* BCM5706C Controllers and OEM boards. */
99         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
100                 "HP NC370T Multifunction Gigabit Server Adapter" },
101         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
102                 "HP NC370i Multifunction Gigabit Server Adapter" },
103         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
104                 "Broadcom NetXtreme II BCM5706 1000Base-T" },
105
106         /* BCM5706S controllers and OEM boards. */
107         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
108                 "HP NC370F Multifunction Gigabit Server Adapter" },
109         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
110                 "Broadcom NetXtreme II BCM5706 1000Base-SX" },
111
112         /* BCM5708C controllers and OEM boards. */
113         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
114                 "Broadcom NetXtreme II BCM5708 1000Base-T" },
115
116         /* BCM5708S controllers and OEM boards. */
117         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
118                 "Broadcom NetXtreme II BCM5708 1000Base-T" },
119         { 0, 0, 0, 0, NULL }
120 };
121
122
123 /****************************************************************************/
124 /* Supported Flash NVRAM device data.                                       */
125 /****************************************************************************/
126 static struct flash_spec flash_table[] =
127 {
128         /* Slow EEPROM */
129         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
130          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
131          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
132          "EEPROM - slow"},
133         /* Expansion entry 0001 */
134         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
135          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
136          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
137          "Entry 0001"},
138         /* Saifun SA25F010 (non-buffered flash) */
139         /* strap, cfg1, & write1 need updates */
140         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
141          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
142          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
143          "Non-buffered flash (128kB)"},
144         /* Saifun SA25F020 (non-buffered flash) */
145         /* strap, cfg1, & write1 need updates */
146         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
147          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
148          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
149          "Non-buffered flash (256kB)"},
150         /* Expansion entry 0100 */
151         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
152          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
153          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
154          "Entry 0100"},
155         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
156         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
157          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
158          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
159          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
160         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
161         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
162          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
163          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
164          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
165         /* Saifun SA25F005 (non-buffered flash) */
166         /* strap, cfg1, & write1 need updates */
167         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
168          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
169          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
170          "Non-buffered flash (64kB)"},
171         /* Fast EEPROM */
172         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
173          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
174          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
175          "EEPROM - fast"},
176         /* Expansion entry 1001 */
177         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
178          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
179          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
180          "Entry 1001"},
181         /* Expansion entry 1010 */
182         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
183          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
184          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
185          "Entry 1010"},
186         /* ATMEL AT45DB011B (buffered flash) */
187         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
188          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
189          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
190          "Buffered flash (128kB)"},
191         /* Expansion entry 1100 */
192         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
193          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
194          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
195          "Entry 1100"},
196         /* Expansion entry 1101 */
197         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
198          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
199          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
200          "Entry 1101"},
201         /* Ateml Expansion entry 1110 */
202         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
203          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
204          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
205          "Entry 1110 (Atmel)"},
206         /* ATMEL AT45DB021B (buffered flash) */
207         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
208          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
209          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
210          "Buffered flash (256kB)"},
211 };
212
213
214 /****************************************************************************/
215 /* FreeBSD device entry points.                                             */
216 /****************************************************************************/
217 static int  bce_probe                           (device_t);
218 static int  bce_attach                          (device_t);
219 static int  bce_detach                          (device_t);
220 static void bce_shutdown                        (device_t);
221
222
223 /****************************************************************************/
224 /* BCE Debug Data Structure Dump Routines                                   */
225 /****************************************************************************/
226 #ifdef BCE_DEBUG
227 static void bce_dump_mbuf                       (struct bce_softc *, struct mbuf *);
228 static void bce_dump_tx_mbuf_chain      (struct bce_softc *, int, int);
229 static void bce_dump_rx_mbuf_chain      (struct bce_softc *, int, int);
230 static void bce_dump_txbd                       (struct bce_softc *, int, struct tx_bd *);
231 static void bce_dump_rxbd                       (struct bce_softc *, int, struct rx_bd *);
232 static void bce_dump_l2fhdr                     (struct bce_softc *, int, struct l2_fhdr *);
233 static void bce_dump_tx_chain           (struct bce_softc *, int, int);
234 static void bce_dump_rx_chain           (struct bce_softc *, int, int);
235 static void bce_dump_status_block       (struct bce_softc *);
236 static void bce_dump_stats_block        (struct bce_softc *);
237 static void bce_dump_driver_state       (struct bce_softc *);
238 static void bce_dump_hw_state           (struct bce_softc *);
239 static void bce_breakpoint                      (struct bce_softc *);
240 #endif
241
242
243 /****************************************************************************/
244 /* BCE Register/Memory Access Routines                                      */
245 /****************************************************************************/
246 static u32  bce_reg_rd_ind                      (struct bce_softc *, u32);
247 static void bce_reg_wr_ind                      (struct bce_softc *, u32, u32);
248 static void bce_ctx_wr                          (struct bce_softc *, u32, u32, u32);
249 static int  bce_miibus_read_reg         (device_t, int, int);
250 static int  bce_miibus_write_reg        (device_t, int, int, int);
251 static void bce_miibus_statchg          (device_t);
252
253
254 /****************************************************************************/
255 /* BCE NVRAM Access Routines                                                */
256 /****************************************************************************/
257 static int  bce_acquire_nvram_lock      (struct bce_softc *);
258 static int  bce_release_nvram_lock      (struct bce_softc *);
259 static void bce_enable_nvram_access     (struct bce_softc *);
260 static void     bce_disable_nvram_access(struct bce_softc *);
261 static int  bce_nvram_read_dword        (struct bce_softc *, u32, u8 *, u32);
262 static int  bce_init_nvram                      (struct bce_softc *);
263 static int  bce_nvram_read                      (struct bce_softc *, u32, u8 *, int);
264 static int  bce_nvram_test                      (struct bce_softc *);
265 #ifdef BCE_NVRAM_WRITE_SUPPORT
266 static int  bce_enable_nvram_write      (struct bce_softc *);
267 static void bce_disable_nvram_write     (struct bce_softc *);
268 static int  bce_nvram_erase_page        (struct bce_softc *, u32);
269 static int  bce_nvram_write_dword       (struct bce_softc *, u32, u8 *, u32);
270 static int  bce_nvram_write                     (struct bce_softc *, u32, u8 *, int);
271 #endif
272
273 /****************************************************************************/
274 /*                                                                          */
275 /****************************************************************************/
276 static void bce_dma_map_addr            (void *, bus_dma_segment_t *, int, int);
277 static void bce_dma_map_tx_desc         (void *, bus_dma_segment_t *, int, bus_size_t, int);
278 static int  bce_dma_alloc                       (device_t);
279 static void bce_dma_free                        (struct bce_softc *);
280 static void bce_release_resources       (struct bce_softc *);
281
282 /****************************************************************************/
283 /* BCE Firmware Synchronization and Load                                    */
284 /****************************************************************************/
285 static int  bce_fw_sync                         (struct bce_softc *, u32);
286 static void bce_load_rv2p_fw            (struct bce_softc *, u32 *, u32, u32);
287 static void bce_load_cpu_fw                     (struct bce_softc *, struct cpu_reg *, struct fw_info *);
288 static void bce_init_cpus                       (struct bce_softc *);
289
290 static void bce_stop                            (struct bce_softc *);
291 static int  bce_reset                           (struct bce_softc *, u32);
292 static int  bce_chipinit                        (struct bce_softc *);
293 static int  bce_blockinit                       (struct bce_softc *);
294 static int  bce_get_buf                         (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
295
296 static int  bce_init_tx_chain           (struct bce_softc *);
297 static int  bce_init_rx_chain           (struct bce_softc *);
298 static void bce_free_rx_chain           (struct bce_softc *);
299 static void bce_free_tx_chain           (struct bce_softc *);
300
301 static int  bce_tx_encap                        (struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
302 static void bce_start_locked            (struct ifnet *);
303 static void bce_start                           (struct ifnet *);
304 static int  bce_ioctl                           (struct ifnet *, u_long, caddr_t);
305 static void bce_watchdog                        (struct ifnet *);
306 static int  bce_ifmedia_upd                     (struct ifnet *);
307 static void bce_ifmedia_sts                     (struct ifnet *, struct ifmediareq *);
308 static void bce_init_locked                     (struct bce_softc *);
309 static void bce_init                            (void *);
310
311 static void bce_init_context            (struct bce_softc *);
312 static void bce_get_mac_addr            (struct bce_softc *);
313 static void bce_set_mac_addr            (struct bce_softc *);
314 static void bce_phy_intr                        (struct bce_softc *);
315 static void bce_rx_intr                         (struct bce_softc *);
316 static void bce_tx_intr                         (struct bce_softc *);
317 static void bce_disable_intr            (struct bce_softc *);
318 static void bce_enable_intr                     (struct bce_softc *);
319
320 #ifdef DEVICE_POLLING
321 static void bce_poll_locked                     (struct ifnet *, enum poll_cmd, int);
322 static void bce_poll                            (struct ifnet *, enum poll_cmd, int);
323 #endif
324 static void bce_intr                            (void *);
325 static void bce_set_rx_mode                     (struct bce_softc *);
326 static void bce_stats_update            (struct bce_softc *);
327 static void bce_tick_locked                     (struct bce_softc *);
328 static void bce_tick                            (void *);
329 static void bce_add_sysctls                     (struct bce_softc *);
330
331
332 /****************************************************************************/
333 /* FreeBSD device dispatch table.                                           */
334 /****************************************************************************/
335 static device_method_t bce_methods[] = {
336         /* Device interface */
337         DEVMETHOD(device_probe,         bce_probe),
338         DEVMETHOD(device_attach,        bce_attach),
339         DEVMETHOD(device_detach,        bce_detach),
340         DEVMETHOD(device_shutdown,      bce_shutdown),
341
342         /* bus interface */
343         DEVMETHOD(bus_print_child,      bus_generic_print_child),
344         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
345
346         /* MII interface */
347         DEVMETHOD(miibus_readreg,       bce_miibus_read_reg),
348         DEVMETHOD(miibus_writereg,      bce_miibus_write_reg),
349         DEVMETHOD(miibus_statchg,       bce_miibus_statchg),
350
351         { 0, 0 }
352 };
353
354 static driver_t bce_driver = {
355         "bce",
356         bce_methods,
357         sizeof(struct bce_softc)
358 };
359
360 static devclass_t bce_devclass;
361
362 MODULE_DEPEND(bce, pci, 1, 1, 1);
363 MODULE_DEPEND(bce, ether, 1, 1, 1);
364 MODULE_DEPEND(bce, miibus, 1, 1, 1);
365
366 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
367 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
368
369
370 /****************************************************************************/
371 /* Device probe function.                                                   */
372 /*                                                                          */
373 /* Compares the device to the driver's list of supported devices and        */
374 /* reports back to the OS whether this is the right driver for the device.  */
375 /*                                                                          */
376 /* Returns:                                                                 */
377 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
378 /****************************************************************************/
379 static int
380 bce_probe(device_t dev)
381 {
382         struct bce_type *t;
383         struct bce_softc *sc;
384         char *descbuf;
385         u16 vid = 0, did = 0, svid = 0, sdid = 0;
386
387         t = bce_devs;
388
389         sc = device_get_softc(dev);
390         bzero(sc, sizeof(struct bce_softc));
391         sc->bce_unit = device_get_unit(dev);
392         sc->bce_dev = dev;
393
394         /* Get the data for the device to be probed. */
395         vid  = pci_get_vendor(dev);
396         did  = pci_get_device(dev);
397         svid = pci_get_subvendor(dev);
398         sdid = pci_get_subdevice(dev);
399
400         DBPRINT(sc, BCE_VERBOSE_LOAD, 
401                 "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
402                 "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
403
404         /* Look through the list of known devices for a match. */
405         while(t->bce_name != NULL) {
406
407                 if ((vid == t->bce_vid) && (did == t->bce_did) && 
408                         ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
409                         ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
410
411                         descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
412
413                         if (descbuf == NULL)
414                                 return(ENOMEM);
415
416                         /* Print out the device identity. */
417                         snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d), %s", 
418                                 t->bce_name,
419                             (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
420                             (pci_read_config(dev, PCIR_REVID, 4) & 0xf),
421                             bce_driver_version);
422
423                         device_set_desc_copy(dev, descbuf);
424                         free(descbuf, M_TEMP);
425                         return(BUS_PROBE_DEFAULT);
426                 }
427                 t++;
428         }
429
430         DBPRINT(sc, BCE_VERBOSE_LOAD, "%s(%d): No IOCTL match found!\n", 
431                 __FILE__, __LINE__);
432
433         return(ENXIO);
434 }
435
436
437 /****************************************************************************/
438 /* Device attach function.                                                  */
439 /*                                                                          */
440 /* Allocates device resources, performs secondary chip identification,      */
441 /* resets and initializes the hardware, and initializes driver instance     */
442 /* variables.                                                               */
443 /*                                                                          */
444 /* Returns:                                                                 */
445 /*   0 on success, positive value on failure.                               */
446 /****************************************************************************/
447 static int
448 bce_attach(device_t dev)
449 {
450         struct bce_softc *sc;
451         struct ifnet *ifp;
452         u32 val;
453         int mbuf, rid, rc = 0;
454
455         sc = device_get_softc(dev);
456         sc->bce_dev = dev;
457
458         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
459
460         mbuf = device_get_unit(dev);
461         sc->bce_unit = mbuf;
462
463         pci_enable_busmaster(dev);
464
465         /* Allocate PCI memory resources. */
466         rid = PCIR_BAR(0);
467         sc->bce_res = bus_alloc_resource_any(
468                 dev,                                                    /* dev */
469                 SYS_RES_MEMORY,                                 /* type */
470                 &rid,                                                   /* rid */
471             RF_ACTIVE | PCI_RF_DENSE);          /* flags */
472
473         if (sc->bce_res == NULL) {
474                 BCE_PRINTF(sc, "%s(%d): PCI memory allocation failed\n", 
475                         __FILE__, __LINE__);
476                 rc = ENXIO;
477                 goto bce_attach_fail;
478         }
479
480         /* Get various resource handles. */
481         sc->bce_btag    = rman_get_bustag(sc->bce_res);
482         sc->bce_bhandle = rman_get_bushandle(sc->bce_res);
483         sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res);
484
485         /* Allocate PCI IRQ resources. */
486         rid = 0;
487         sc->bce_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
488             RF_SHAREABLE | RF_ACTIVE);
489
490         if (sc->bce_irq == NULL) {
491                 BCE_PRINTF(sc, "%s(%d): PCI map interrupt failed\n", 
492                         __FILE__, __LINE__);
493                 rc = ENXIO;
494                 goto bce_attach_fail;
495         }
496
497         /* Initialize mutex for the current device instance. */
498         BCE_LOCK_INIT(sc, device_get_nameunit(dev));
499
500         /*
501          * Configure byte swap and enable indirect register access.
502          * Rely on CPU to do target byte swapping on big endian systems.
503          * Access to registers outside of PCI configurtion space are not
504          * valid until this is done.
505          */
506         pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
507                                BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
508                                BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
509
510         /* Save ASIC revsion info. */
511         sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
512
513         /* Weed out any non-production controller revisions. */
514         switch(BCE_CHIP_ID(sc)) {
515                 case BCE_CHIP_ID_5706_A0:
516                 case BCE_CHIP_ID_5706_A1:
517                 case BCE_CHIP_ID_5708_A0:
518                 case BCE_CHIP_ID_5708_B0:
519                         BCE_PRINTF(sc, "%s(%d): Unsupported controller revision (%c%d)!\n",
520                                 __FILE__, __LINE__, 
521                                 (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
522                             (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
523                         rc = ENODEV;
524                         goto bce_attach_fail;
525         }
526
527         if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT) {
528                 BCE_PRINTF(sc, "%s(%d): SerDes controllers are not supported!\n",
529                         __FILE__, __LINE__);
530                 rc = ENODEV;
531                 goto bce_attach_fail;
532         }
533
534         /* 
535          * The embedded PCIe to PCI-X bridge (EPB) 
536          * in the 5708 cannot address memory above 
537          * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043). 
538          */
539         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
540                 sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
541         else
542                 sc->max_bus_addr = BUS_SPACE_MAXADDR;
543
544         /*
545          * Find the base address for shared memory access.
546          * Newer versions of bootcode use a signature and offset
547          * while older versions use a fixed address.
548          */
549         val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
550         if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
551                 sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0);
552         else
553                 sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
554
555         DBPRINT(sc, BCE_INFO, "bce_shmem_base = 0x%08X\n", sc->bce_shmem_base);
556
557         /* Set initial device and PHY flags */
558         sc->bce_flags = 0;
559         sc->bce_phy_flags = 0;
560
561         /* Get PCI bus information (speed and type). */
562         val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
563         if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
564                 u32 clkreg;
565
566                 sc->bce_flags |= BCE_PCIX_FLAG;
567
568                 clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
569
570                 clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
571                 switch (clkreg) {
572                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
573                         sc->bus_speed_mhz = 133;
574                         break;
575
576                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
577                         sc->bus_speed_mhz = 100;
578                         break;
579
580                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
581                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
582                         sc->bus_speed_mhz = 66;
583                         break;
584
585                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
586                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
587                         sc->bus_speed_mhz = 50;
588                         break;
589
590                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
591                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
592                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
593                         sc->bus_speed_mhz = 33;
594                         break;
595                 }
596         } else {
597                 if (val & BCE_PCICFG_MISC_STATUS_M66EN)
598                         sc->bus_speed_mhz = 66;
599                 else
600                         sc->bus_speed_mhz = 33;
601         }
602
603         if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
604                 sc->bce_flags |= BCE_PCI_32BIT_FLAG;
605
606         BCE_PRINTF(sc, "ASIC ID 0x%08X; Revision (%c%d); PCI%s %s %dMHz\n",
607                 sc->bce_chipid,
608                 ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
609                 ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4),
610                 ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
611                 ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
612                 sc->bus_speed_mhz);
613
614         /* Reset the controller. */
615         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
616                 rc = ENXIO;
617                 goto bce_attach_fail;
618         }
619
620         /* Initialize the controller. */
621         if (bce_chipinit(sc)) {
622                 BCE_PRINTF(sc, "%s(%d): Controller initialization failed!\n",
623                         __FILE__, __LINE__);
624                 rc = ENXIO;
625                 goto bce_attach_fail;
626         }
627
628         /* Perform NVRAM test. */
629         if (bce_nvram_test(sc)) {
630                 BCE_PRINTF(sc, "%s(%d): NVRAM test failed!\n",
631                         __FILE__, __LINE__);
632                 rc = ENXIO;
633                 goto bce_attach_fail;
634         }
635
636         /* Fetch the permanent Ethernet MAC address. */
637         bce_get_mac_addr(sc);
638
639         /*
640          * Trip points control how many BDs
641          * should be ready before generating an
642          * interrupt while ticks control how long
643          * a BD can sit in the chain before
644          * generating an interrupt.  Set the default 
645          * values for the RX and TX rings.
646          */
647
648 #ifdef BCE_DRBUG
649         /* Force more frequent interrupts. */
650         sc->bce_tx_quick_cons_trip_int = 1;
651         sc->bce_tx_quick_cons_trip     = 1;
652         sc->bce_tx_ticks_int           = 0;
653         sc->bce_tx_ticks               = 0;
654
655         sc->bce_rx_quick_cons_trip_int = 1;
656         sc->bce_rx_quick_cons_trip     = 1;
657         sc->bce_rx_ticks_int           = 0;
658         sc->bce_rx_ticks               = 0;
659 #else
660         sc->bce_tx_quick_cons_trip_int = 20;
661         sc->bce_tx_quick_cons_trip     = 20;
662         sc->bce_tx_ticks_int           = 80;
663         sc->bce_tx_ticks               = 80;
664
665         sc->bce_rx_quick_cons_trip_int = 6;
666         sc->bce_rx_quick_cons_trip     = 6;
667         sc->bce_rx_ticks_int           = 18;
668         sc->bce_rx_ticks               = 18;
669 #endif
670
671         /* Update statistics once every second. */
672         sc->bce_stats_ticks = 1000000 & 0xffff00;
673
674         /*
675          * The copper based NetXtreme II controllers
676          * use an integrated PHY at address 1 while
677          * the SerDes controllers use a PHY at
678          * address 2.
679          */
680         sc->bce_phy_addr = 1;
681
682         if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT) {
683                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
684                 sc->bce_flags |= BCE_NO_WOL_FLAG;
685                 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708) {
686                         sc->bce_phy_addr = 2;
687                         val = REG_RD_IND(sc, sc->bce_shmem_base +
688                                          BCE_SHARED_HW_CFG_CONFIG);
689                         if (val & BCE_SHARED_HW_CFG_PHY_2_5G)
690                                 sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
691                 }
692         }
693
694         /* Allocate DMA memory resources. */
695         if (bce_dma_alloc(dev)) {
696                 BCE_PRINTF(sc, "%s(%d): DMA resource allocation failed!\n",
697                     __FILE__, __LINE__);
698                 rc = ENXIO;
699                 goto bce_attach_fail;
700         }
701
702         /* Allocate an ifnet structure. */
703         ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
704         if (ifp == NULL) {
705                 BCE_PRINTF(sc, "%s(%d): Interface allocation failed!\n", 
706                         __FILE__, __LINE__);
707                 rc = ENXIO;
708                 goto bce_attach_fail;
709         }
710
711         /* Initialize the ifnet interface. */
712         ifp->if_softc        = sc;
713         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
714         ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
715         ifp->if_ioctl        = bce_ioctl;
716         ifp->if_start        = bce_start;
717         ifp->if_timer        = 0;
718         ifp->if_watchdog     = bce_watchdog;
719         ifp->if_init         = bce_init;
720         ifp->if_mtu          = ETHERMTU;
721         ifp->if_hwassist     = BCE_IF_HWASSIST;
722         ifp->if_capabilities = BCE_IF_CAPABILITIES;
723         ifp->if_capenable    = ifp->if_capabilities;
724
725         /* Assume a standard 1500 byte MTU size for mbuf allocations. */
726         sc->mbuf_alloc_size  = MCLBYTES;
727 #ifdef DEVICE_POLLING
728         ifp->if_capabilities |= IFCAP_POLLING;
729 #endif
730
731         ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
732         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
733                 ifp->if_baudrate = IF_Gbps(2.5);
734         else
735                 ifp->if_baudrate = IF_Gbps(1);
736
737         IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
738         IFQ_SET_READY(&ifp->if_snd);
739
740         if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
741                 BCE_PRINTF(sc, "%s(%d): SerDes is not supported by this driver!\n", 
742                         __FILE__, __LINE__);
743                 rc = ENODEV;
744                 goto bce_attach_fail;
745         } else {
746                 /* Look for our PHY. */
747                 if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
748                         bce_ifmedia_sts)) {
749                         BCE_PRINTF(sc, "%s(%d): PHY probe failed!\n", 
750                                 __FILE__, __LINE__);
751                         rc = ENXIO;
752                         goto bce_attach_fail;
753                 }
754         }
755
756         /* Attach to the Ethernet interface list. */
757         ether_ifattach(ifp, sc->eaddr);
758
759 #if __FreeBSD_version < 500000
760         callout_init(&sc->bce_stat_ch);
761 #else
762         callout_init(&sc->bce_stat_ch, CALLOUT_MPSAFE);
763 #endif
764
765         /* Hookup IRQ last. */
766         rc = bus_setup_intr(dev, sc->bce_irq, INTR_TYPE_NET | INTR_MPSAFE,
767            bce_intr, sc, &sc->bce_intrhand);
768
769         if (rc) {
770                 BCE_PRINTF(sc, "%s(%d): Failed to setup IRQ!\n", 
771                         __FILE__, __LINE__);
772                 bce_detach(dev);
773                 goto bce_attach_exit;
774         }
775
776         /* Print some important debugging info. */
777         DBRUN(BCE_INFO, bce_dump_driver_state(sc));
778
779         /* Add the supported sysctls to the kernel. */
780         bce_add_sysctls(sc);
781
782         goto bce_attach_exit;
783
784 bce_attach_fail:
785         bce_release_resources(sc);
786
787 bce_attach_exit:
788
789         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
790
791         return(rc);
792 }
793
794
795 /****************************************************************************/
796 /* Device detach function.                                                  */
797 /*                                                                          */
798 /* Stops the controller, resets the controller, and releases resources.     */
799 /*                                                                          */
800 /* Returns:                                                                 */
801 /*   0 on success, positive value on failure.                               */
802 /****************************************************************************/
803 static int
804 bce_detach(device_t dev)
805 {
806         struct bce_softc *sc;
807         struct ifnet *ifp;
808
809         sc = device_get_softc(dev);
810
811         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
812
813         ifp = sc->bce_ifp;
814
815 #ifdef DEVICE_POLLING
816         if (ifp->if_capenable & IFCAP_POLLING)
817                 ether_poll_deregister(ifp);
818 #endif
819
820         /* Stop and reset the controller. */
821         BCE_LOCK(sc);
822         bce_stop(sc);
823         bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
824         BCE_UNLOCK(sc);
825
826         ether_ifdetach(ifp);
827
828         /* If we have a child device on the MII bus remove it too. */
829         if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
830                 ifmedia_removeall(&sc->bce_ifmedia);
831         } else {
832                 bus_generic_detach(dev);
833                 device_delete_child(dev, sc->bce_miibus);
834         }
835
836         /* Release all remaining resources. */
837         bce_release_resources(sc);
838
839         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
840
841         return(0);
842 }
843
844
845 /****************************************************************************/
846 /* Device shutdown function.                                                */
847 /*                                                                          */
848 /* Stops and resets the controller.                                         */
849 /*                                                                          */
850 /* Returns:                                                                 */
851 /*   Nothing                                                                */
852 /****************************************************************************/
853 static void
854 bce_shutdown(device_t dev)
855 {
856         struct bce_softc *sc = device_get_softc(dev);
857
858         BCE_LOCK(sc);
859         bce_stop(sc);
860         bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
861         BCE_UNLOCK(sc);
862 }
863
864
865 /****************************************************************************/
866 /* Indirect register read.                                                  */
867 /*                                                                          */
868 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
869 /* configuration space.  Using this mechanism avoids issues with posted     */
870 /* reads but is much slower than memory-mapped I/O.                         */
871 /*                                                                          */
872 /* Returns:                                                                 */
873 /*   The value of the register.                                             */
874 /****************************************************************************/
875 static u32
876 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
877 {
878         device_t dev;
879         dev = sc->bce_dev;
880
881         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
882 #ifdef BCE_DEBUG
883         {
884                 u32 val;
885                 val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
886                 DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
887                         __FUNCTION__, offset, val);
888                 return val;
889         }
890 #else
891         return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
892 #endif
893 }
894
895
896 /****************************************************************************/
897 /* Indirect register write.                                                 */
898 /*                                                                          */
899 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
900 /* configuration space.  Using this mechanism avoids issues with posted     */
901 /* writes but is muchh slower than memory-mapped I/O.                       */
902 /*                                                                          */
903 /* Returns:                                                                 */
904 /*   Nothing.                                                               */
905 /****************************************************************************/
906 static void
907 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
908 {
909         device_t dev;
910         dev = sc->bce_dev;
911
912         DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
913                 __FUNCTION__, offset, val);
914
915         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
916         pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
917 }
918
919
920 /****************************************************************************/
921 /* Context memory write.                                                    */
922 /*                                                                          */
923 /* The NetXtreme II controller uses context memory to track connection      */
924 /* information for L2 and higher network protocols.                         */
925 /*                                                                          */
926 /* Returns:                                                                 */
927 /*   Nothing.                                                               */
928 /****************************************************************************/
929 static void
930 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 offset, u32 val)
931 {
932
933         DBPRINT(sc, BCE_EXCESSIVE, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
934                 "val = 0x%08X\n", __FUNCTION__, cid_addr, offset, val);
935
936         offset += cid_addr;
937         REG_WR(sc, BCE_CTX_DATA_ADR, offset);
938         REG_WR(sc, BCE_CTX_DATA, val);
939 }
940
941
942 /****************************************************************************/
943 /* PHY register read.                                                       */
944 /*                                                                          */
945 /* Implements register reads on the MII bus.                                */
946 /*                                                                          */
947 /* Returns:                                                                 */
948 /*   The value of the register.                                             */
949 /****************************************************************************/
950 static int
951 bce_miibus_read_reg(device_t dev, int phy, int reg)
952 {
953         struct bce_softc *sc;
954         u32 val;
955         int i;
956
957         sc = device_get_softc(dev);
958
959         /* Make sure we are accessing the correct PHY address. */
960         if (phy != sc->bce_phy_addr) {
961                 DBPRINT(sc, BCE_VERBOSE, "Invalid PHY address %d for PHY read!\n", phy);
962                 return(0);
963         }
964
965         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
966                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
967                 val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
968
969                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
970                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
971
972                 DELAY(40);
973         }
974
975         val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
976                 BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
977                 BCE_EMAC_MDIO_COMM_START_BUSY;
978         REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
979
980         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
981                 DELAY(10);
982
983                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
984                 if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
985                         DELAY(5);
986
987                         val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
988                         val &= BCE_EMAC_MDIO_COMM_DATA;
989
990                         break;
991                 }
992         }
993
994         if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
995                 BCE_PRINTF(sc, "%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
996                         __FILE__, __LINE__, phy, reg);
997                 val = 0x0;
998         } else {
999                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1000         }
1001
1002         DBPRINT(sc, BCE_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1003                 __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);
1004
1005         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1006                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1007                 val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1008
1009                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1010                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1011
1012                 DELAY(40);
1013         }
1014
1015         return (val & 0xffff);
1016
1017 }
1018
1019
1020 /****************************************************************************/
1021 /* PHY register write.                                                      */
1022 /*                                                                          */
1023 /* Implements register writes on the MII bus.                               */
1024 /*                                                                          */
1025 /* Returns:                                                                 */
1026 /*   The value of the register.                                             */
1027 /****************************************************************************/
1028 static int
1029 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1030 {
1031         struct bce_softc *sc;
1032         u32 val1;
1033         int i;
1034
1035         sc = device_get_softc(dev);
1036
1037         /* Make sure we are accessing the correct PHY address. */
1038         if (phy != sc->bce_phy_addr) {
1039                 DBPRINT(sc, BCE_WARN, "Invalid PHY address %d for PHY write!\n", phy);
1040                 return(0);
1041         }
1042
1043         DBPRINT(sc, BCE_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1044                 __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);
1045
1046         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1047                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1048                 val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1049
1050                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1051                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1052
1053                 DELAY(40);
1054         }
1055
1056         val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1057                 BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1058                 BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1059         REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1060
1061         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1062                 DELAY(10);
1063
1064                 val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1065                 if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1066                         DELAY(5);
1067                         break;
1068                 }
1069         }
1070
1071         if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1072                 BCE_PRINTF(sc, "%s(%d): PHY write timeout!\n", 
1073                         __FILE__, __LINE__);
1074
1075         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1076                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1077                 val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1078
1079                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1080                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1081
1082                 DELAY(40);
1083         }
1084
1085         return 0;
1086 }
1087
1088
1089 /****************************************************************************/
1090 /* MII bus status change.                                                   */
1091 /*                                                                          */
1092 /* Called by the MII bus driver when the PHY establishes link to set the    */
1093 /* MAC interface registers.                                                 */
1094 /*                                                                          */
1095 /* Returns:                                                                 */
1096 /*   Nothing.                                                               */
1097 /****************************************************************************/
1098 static void
1099 bce_miibus_statchg(device_t dev)
1100 {
1101         struct bce_softc *sc;
1102         struct mii_data *mii;
1103
1104         sc = device_get_softc(dev);
1105
1106         mii = device_get_softc(sc->bce_miibus);
1107
1108         BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT);
1109
1110         /* Set MII or GMII inerface based on the speed negotiated by the PHY. */
1111         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
1112                 DBPRINT(sc, BCE_INFO, "Setting GMII interface.\n");
1113                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_GMII);
1114         } else {
1115                 DBPRINT(sc, BCE_INFO, "Setting MII interface.\n");
1116                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_MII);
1117         }
1118
1119         /* Set half or full duplex based on the duplicity negotiated by the PHY. */
1120         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1121                 DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1122                 BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1123         } else {
1124                 DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1125                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1126         }
1127 }
1128
1129
1130 /****************************************************************************/
1131 /* Acquire NVRAM lock.                                                      */
1132 /*                                                                          */
1133 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1134 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1135 /* for use by the driver.                                                   */
1136 /*                                                                          */
1137 /* Returns:                                                                 */
1138 /*   0 on success, positive value on failure.                               */
1139 /****************************************************************************/
1140 static int
1141 bce_acquire_nvram_lock(struct bce_softc *sc)
1142 {
1143         u32 val;
1144         int j;
1145
1146         DBPRINT(sc, BCE_VERBOSE, "Acquiring NVRAM lock.\n");
1147
1148         /* Request access to the flash interface. */
1149         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1150         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1151                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1152                 if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1153                         break;
1154
1155                 DELAY(5);
1156         }
1157
1158         if (j >= NVRAM_TIMEOUT_COUNT) {
1159                 DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1160                 return EBUSY;
1161         }
1162
1163         return 0;
1164 }
1165
1166
1167 /****************************************************************************/
1168 /* Release NVRAM lock.                                                      */
1169 /*                                                                          */
1170 /* When the caller is finished accessing NVRAM the lock must be released.   */
1171 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1172 /* for use by the driver.                                                   */
1173 /*                                                                          */
1174 /* Returns:                                                                 */
1175 /*   0 on success, positive value on failure.                               */
1176 /****************************************************************************/
1177 static int
1178 bce_release_nvram_lock(struct bce_softc *sc)
1179 {
1180         int j;
1181         u32 val;
1182
1183         DBPRINT(sc, BCE_VERBOSE, "Releasing NVRAM lock.\n");
1184
1185         /*
1186          * Relinquish nvram interface.
1187          */
1188         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1189
1190         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1191                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1192                 if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1193                         break;
1194
1195                 DELAY(5);
1196         }
1197
1198         if (j >= NVRAM_TIMEOUT_COUNT) {
1199                 DBPRINT(sc, BCE_WARN, "Timeout reeasing NVRAM lock!\n");
1200                 return EBUSY;
1201         }
1202
1203         return 0;
1204 }
1205
1206
1207 #ifdef BCE_NVRAM_WRITE_SUPPORT
1208 /****************************************************************************/
1209 /* Enable NVRAM write access.                                               */
1210 /*                                                                          */
1211 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1212 /*                                                                          */
1213 /* Returns:                                                                 */
1214 /*   0 on success, positive value on failure.                               */
1215 /****************************************************************************/
1216 static int
1217 bce_enable_nvram_write(struct bce_softc *sc)
1218 {
1219         u32 val;
1220
1221         DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM write.\n");
1222
1223         val = REG_RD(sc, BCE_MISC_CFG);
1224         REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1225
1226         if (!sc->bce_flash_info->buffered) {
1227                 int j;
1228
1229                 REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1230                 REG_WR(sc, BCE_NVM_COMMAND,     BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1231
1232                 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1233                         DELAY(5);
1234
1235                         val = REG_RD(sc, BCE_NVM_COMMAND);
1236                         if (val & BCE_NVM_COMMAND_DONE)
1237                                 break;
1238                 }
1239
1240                 if (j >= NVRAM_TIMEOUT_COUNT) {
1241                         DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1242                         return EBUSY;
1243                 }
1244         }
1245         return 0;
1246 }
1247
1248
1249 /****************************************************************************/
1250 /* Disable NVRAM write access.                                              */
1251 /*                                                                          */
1252 /* When the caller is finished writing to NVRAM write access must be        */
1253 /* disabled.                                                                */
1254 /*                                                                          */
1255 /* Returns:                                                                 */
1256 /*   Nothing.                                                               */
1257 /****************************************************************************/
1258 static void
1259 bce_disable_nvram_write(struct bce_softc *sc)
1260 {
1261         u32 val;
1262
1263         DBPRINT(sc, BCE_VERBOSE,  "Disabling NVRAM write.\n");
1264
1265         val = REG_RD(sc, BCE_MISC_CFG);
1266         REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1267 }
1268 #endif
1269
1270
1271 /****************************************************************************/
1272 /* Enable NVRAM access.                                                     */
1273 /*                                                                          */
1274 /* Before accessing NVRAM for read or write operations the caller must      */
1275 /* enabled NVRAM access.                                                    */
1276 /*                                                                          */
1277 /* Returns:                                                                 */
1278 /*   Nothing.                                                               */
1279 /****************************************************************************/
1280 static void
1281 bce_enable_nvram_access(struct bce_softc *sc)
1282 {
1283         u32 val;
1284
1285         DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM access.\n");
1286
1287         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1288         /* Enable both bits, even on read. */
1289         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1290                val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1291 }
1292
1293
1294 /****************************************************************************/
1295 /* Disable NVRAM access.                                                    */
1296 /*                                                                          */
1297 /* When the caller is finished accessing NVRAM access must be disabled.     */
1298 /*                                                                          */
1299 /* Returns:                                                                 */
1300 /*   Nothing.                                                               */
1301 /****************************************************************************/
1302 static void
1303 bce_disable_nvram_access(struct bce_softc *sc)
1304 {
1305         u32 val;
1306
1307         DBPRINT(sc, BCE_VERBOSE, "Disabling NVRAM access.\n");
1308
1309         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1310
1311         /* Disable both bits, even after read. */
1312         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1313                 val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1314                         BCE_NVM_ACCESS_ENABLE_WR_EN));
1315 }
1316
1317
1318 #ifdef BCE_NVRAM_WRITE_SUPPORT
1319 /****************************************************************************/
1320 /* Erase NVRAM page before writing.                                         */
1321 /*                                                                          */
1322 /* Non-buffered flash parts require that a page be erased before it is      */
1323 /* written.                                                                 */
1324 /*                                                                          */
1325 /* Returns:                                                                 */
1326 /*   0 on success, positive value on failure.                               */
1327 /****************************************************************************/
1328 static int
1329 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1330 {
1331         u32 cmd;
1332         int j;
1333
1334         /* Buffered flash doesn't require an erase. */
1335         if (sc->bce_flash_info->buffered)
1336                 return 0;
1337
1338         DBPRINT(sc, BCE_VERBOSE, "Erasing NVRAM page.\n");
1339
1340         /* Build an erase command. */
1341         cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1342               BCE_NVM_COMMAND_DOIT;
1343
1344         /*
1345          * Clear the DONE bit separately, set the NVRAM adress to erase,
1346          * and issue the erase command.
1347          */
1348         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1349         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1350         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1351
1352         /* Wait for completion. */
1353          */
1354         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1355                 u32 val;
1356
1357                 DELAY(5);
1358
1359                 val = REG_RD(sc, BCE_NVM_COMMAND);
1360                 if (val & BCE_NVM_COMMAND_DONE)
1361                         break;
1362         }
1363
1364         if (j >= NVRAM_TIMEOUT_COUNT) {
1365                 DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1366                 return EBUSY;
1367         }
1368
1369         return 0;
1370 }
1371 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1372
1373
1374 /****************************************************************************/
1375 /* Read a dword (32 bits) from NVRAM.                                       */
1376 /*                                                                          */
1377 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1378 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1379 /*                                                                          */
1380 /* Returns:                                                                 */
1381 /*   0 on success and the 32 bit value read, positive value on failure.     */
1382 /****************************************************************************/
1383 static int
1384 bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
1385                                                         u32 cmd_flags)
1386 {
1387         u32 cmd;
1388         int i, rc = 0;
1389
1390         /* Build the command word. */
1391         cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1392
1393         /* Calculate the offset for buffered flash. */
1394         if (sc->bce_flash_info->buffered) {
1395                 offset = ((offset / sc->bce_flash_info->page_size) <<
1396                            sc->bce_flash_info->page_bits) +
1397                           (offset % sc->bce_flash_info->page_size);
1398         }
1399
1400         /*
1401          * Clear the DONE bit separately, set the address to read,
1402          * and issue the read.
1403          */
1404         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1405         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1406         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1407
1408         /* Wait for completion. */
1409         for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1410                 u32 val;
1411
1412                 DELAY(5);
1413
1414                 val = REG_RD(sc, BCE_NVM_COMMAND);
1415                 if (val & BCE_NVM_COMMAND_DONE) {
1416                         val = REG_RD(sc, BCE_NVM_READ);
1417
1418                         val = bce_be32toh(val);
1419                         memcpy(ret_val, &val, 4);
1420                         break;
1421                 }
1422         }
1423
1424         /* Check for errors. */
1425         if (i >= NVRAM_TIMEOUT_COUNT) {
1426                 BCE_PRINTF(sc, "%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
1427                         __FILE__, __LINE__, offset);
1428                 rc = EBUSY;
1429         }
1430
1431         return(rc);
1432 }
1433
1434
1435 #ifdef BCE_NVRAM_WRITE_SUPPORT
1436 /****************************************************************************/
1437 /* Write a dword (32 bits) to NVRAM.                                        */
1438 /*                                                                          */
1439 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1440 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1441 /* enabled NVRAM write access.                                              */
1442 /*                                                                          */
1443 /* Returns:                                                                 */
1444 /*   0 on success, positive value on failure.                               */
1445 /****************************************************************************/
1446 static int
1447 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
1448         u32 cmd_flags)
1449 {
1450         u32 cmd, val32;
1451         int j;
1452
1453         /* Build the command word. */
1454         cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
1455
1456         /* Calculate the offset for buffered flash. */
1457         if (sc->bce_flash_info->buffered) {
1458                 offset = ((offset / sc->bce_flash_info->page_size) <<
1459                           sc->bce_flash_info->page_bits) +
1460                          (offset % sc->bce_flash_info->page_size);
1461         }
1462
1463         /*
1464          * Clear the DONE bit separately, convert NVRAM data to big-endian,
1465          * set the NVRAM address to write, and issue the write command
1466          */
1467         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1468         memcpy(&val32, val, 4);
1469         val32 = htobe32(val32);
1470         REG_WR(sc, BCE_NVM_WRITE, val32);
1471         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1472         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1473
1474         /* Wait for completion. */
1475         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1476                 DELAY(5);
1477
1478                 if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
1479                         break;
1480         }
1481         if (j >= NVRAM_TIMEOUT_COUNT) {
1482                 BCE_PRINTF(sc, "%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
1483                         __FILE__, __LINE__, offset);
1484                 return EBUSY;
1485         }
1486
1487         return 0;
1488 }
1489 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1490
1491
1492 /****************************************************************************/
1493 /* Initialize NVRAM access.                                                 */
1494 /*                                                                          */
1495 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
1496 /* access that device.                                                      */
1497 /*                                                                          */
1498 /* Returns:                                                                 */
1499 /*   0 on success, positive value on failure.                               */
1500 /****************************************************************************/
1501 static int
1502 bce_init_nvram(struct bce_softc *sc)
1503 {
1504         u32 val;
1505         int j, entry_count, rc;
1506         struct flash_spec *flash;
1507
1508         DBPRINT(sc,BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
1509
1510         /* Determine the selected interface. */
1511         val = REG_RD(sc, BCE_NVM_CFG1);
1512
1513         entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
1514
1515         rc = 0;
1516
1517         /*
1518          * Flash reconfiguration is required to support additional
1519          * NVRAM devices not directly supported in hardware.
1520          * Check if the flash interface was reconfigured
1521          * by the bootcode.
1522          */
1523
1524         if (val & 0x40000000) {
1525                 /* Flash interface reconfigured by bootcode. */
1526
1527                 DBPRINT(sc,BCE_INFO_LOAD, 
1528                         "bce_init_nvram(): Flash WAS reconfigured.\n");
1529
1530                 for (j = 0, flash = &flash_table[0]; j < entry_count;
1531                      j++, flash++) {
1532                         if ((val & FLASH_BACKUP_STRAP_MASK) ==
1533                             (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
1534                                 sc->bce_flash_info = flash;
1535                                 break;
1536                         }
1537                 }
1538         } else {
1539                 /* Flash interface not yet reconfigured. */
1540                 u32 mask;
1541
1542                 DBPRINT(sc,BCE_INFO_LOAD, 
1543                         "bce_init_nvram(): Flash was NOT reconfigured.\n");
1544
1545                 if (val & (1 << 23))
1546                         mask = FLASH_BACKUP_STRAP_MASK;
1547                 else
1548                         mask = FLASH_STRAP_MASK;
1549
1550                 /* Look for the matching NVRAM device configuration data. */
1551                 for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
1552
1553                         /* Check if the device matches any of the known devices. */
1554                         if ((val & mask) == (flash->strapping & mask)) {
1555                                 /* Found a device match. */
1556                                 sc->bce_flash_info = flash;
1557
1558                                 /* Request access to the flash interface. */
1559                                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1560                                         return rc;
1561
1562                                 /* Reconfigure the flash interface. */
1563                                 bce_enable_nvram_access(sc);
1564                                 REG_WR(sc, BCE_NVM_CFG1, flash->config1);
1565                                 REG_WR(sc, BCE_NVM_CFG2, flash->config2);
1566                                 REG_WR(sc, BCE_NVM_CFG3, flash->config3);
1567                                 REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
1568                                 bce_disable_nvram_access(sc);
1569                                 bce_release_nvram_lock(sc);
1570
1571                                 break;
1572                         }
1573                 }
1574         }
1575
1576         /* Check if a matching device was found. */
1577         if (j == entry_count) {
1578                 sc->bce_flash_info = NULL;
1579                 BCE_PRINTF(sc, "%s(%d): Unknown Flash NVRAM found!\n", 
1580                         __FILE__, __LINE__);
1581                 rc = ENODEV;
1582         }
1583
1584         /* Write the flash config data to the shared memory interface. */
1585         val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2);
1586         val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
1587         if (val)
1588                 sc->bce_flash_size = val;
1589         else
1590                 sc->bce_flash_size = sc->bce_flash_info->total_size;
1591
1592         DBPRINT(sc, BCE_INFO_LOAD, "bce_init_nvram() flash->total_size = 0x%08X\n",
1593                 sc->bce_flash_info->total_size);
1594
1595         DBPRINT(sc,BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
1596
1597         return rc;
1598 }
1599
1600
1601 /****************************************************************************/
1602 /* Read an arbitrary range of data from NVRAM.                              */
1603 /*                                                                          */
1604 /* Prepares the NVRAM interface for access and reads the requested data     */
1605 /* into the supplied buffer.                                                */
1606 /*                                                                          */
1607 /* Returns:                                                                 */
1608 /*   0 on success and the data read, positive value on failure.             */
1609 /****************************************************************************/
1610 static int
1611 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
1612         int buf_size)
1613 {
1614         int rc = 0;
1615         u32 cmd_flags, offset32, len32, extra;
1616
1617         if (buf_size == 0)
1618                 return 0;
1619
1620         /* Request access to the flash interface. */
1621         if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1622                 return rc;
1623
1624         /* Enable access to flash interface */
1625         bce_enable_nvram_access(sc);
1626
1627         len32 = buf_size;
1628         offset32 = offset;
1629         extra = 0;
1630
1631         cmd_flags = 0;
1632
1633         if (offset32 & 3) {
1634                 u8 buf[4];
1635                 u32 pre_len;
1636
1637                 offset32 &= ~3;
1638                 pre_len = 4 - (offset & 3);
1639
1640                 if (pre_len >= len32) {
1641                         pre_len = len32;
1642                         cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
1643                 }
1644                 else {
1645                         cmd_flags = BCE_NVM_COMMAND_FIRST;
1646                 }
1647
1648                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1649
1650                 if (rc)
1651                         return rc;
1652
1653                 memcpy(ret_buf, buf + (offset & 3), pre_len);
1654
1655                 offset32 += 4;
1656                 ret_buf += pre_len;
1657                 len32 -= pre_len;
1658         }
1659
1660         if (len32 & 3) {
1661                 extra = 4 - (len32 & 3);
1662                 len32 = (len32 + 4) & ~3;
1663         }
1664
1665         if (len32 == 4) {
1666                 u8 buf[4];
1667
1668                 if (cmd_flags)
1669                         cmd_flags = BCE_NVM_COMMAND_LAST;
1670                 else
1671                         cmd_flags = BCE_NVM_COMMAND_FIRST |
1672                                     BCE_NVM_COMMAND_LAST;
1673
1674                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1675
1676                 memcpy(ret_buf, buf, 4 - extra);
1677         }
1678         else if (len32 > 0) {
1679                 u8 buf[4];
1680
1681                 /* Read the first word. */
1682                 if (cmd_flags)
1683                         cmd_flags = 0;
1684                 else
1685                         cmd_flags = BCE_NVM_COMMAND_FIRST;
1686
1687                 rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
1688
1689                 /* Advance to the next dword. */
1690                 offset32 += 4;
1691                 ret_buf += 4;
1692                 len32 -= 4;
1693
1694                 while (len32 > 4 && rc == 0) {
1695                         rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
1696
1697                         /* Advance to the next dword. */
1698                         offset32 += 4;
1699                         ret_buf += 4;
1700                         len32 -= 4;
1701                 }
1702
1703                 if (rc)
1704                         return rc;
1705
1706                 cmd_flags = BCE_NVM_COMMAND_LAST;
1707                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1708
1709                 memcpy(ret_buf, buf, 4 - extra);
1710         }
1711
1712         /* Disable access to flash interface and release the lock. */
1713         bce_disable_nvram_access(sc);
1714         bce_release_nvram_lock(sc);
1715
1716         return rc;
1717 }
1718
1719
1720 #ifdef BCE_NVRAM_WRITE_SUPPORT
1721 /****************************************************************************/
1722 /* Write an arbitrary range of data from NVRAM.                             */
1723 /*                                                                          */
1724 /* Prepares the NVRAM interface for write access and writes the requested   */
1725 /* data from the supplied buffer.  The caller is responsible for            */
1726 /* calculating any appropriate CRCs.                                        */
1727 /*                                                                          */
1728 /* Returns:                                                                 */
1729 /*   0 on success, positive value on failure.                               */
1730 /****************************************************************************/
1731 static int
1732 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
1733         int buf_size)
1734 {
1735         u32 written, offset32, len32;
1736         u8 *buf, start[4], end[4];
1737         int rc = 0;
1738         int align_start, align_end;
1739
1740         buf = data_buf;
1741         offset32 = offset;
1742         len32 = buf_size;
1743         align_start = align_end = 0;
1744
1745         if ((align_start = (offset32 & 3))) {
1746                 offset32 &= ~3;
1747                 len32 += align_start;
1748                 if ((rc = bce_nvram_read(sc, offset32, start, 4)))
1749                         return rc;
1750         }
1751
1752         if (len32 & 3) {
1753                 if ((len32 > 4) || !align_start) {
1754                         align_end = 4 - (len32 & 3);
1755                         len32 += align_end;
1756                         if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
1757                                 end, 4))) {
1758                                 return rc;
1759                         }
1760                 }
1761         }
1762
1763         if (align_start || align_end) {
1764                 buf = malloc(len32, M_DEVBUF, M_NOWAIT);
1765                 if (buf == 0)
1766                         return ENOMEM;
1767                 if (align_start) {
1768                         memcpy(buf, start, 4);
1769                 }
1770                 if (align_end) {
1771                         memcpy(buf + len32 - 4, end, 4);
1772                 }
1773                 memcpy(buf + align_start, data_buf, buf_size);
1774         }
1775
1776         written = 0;
1777         while ((written < len32) && (rc == 0)) {
1778                 u32 page_start, page_end, data_start, data_end;
1779                 u32 addr, cmd_flags;
1780                 int i;
1781                 u8 flash_buffer[264];
1782
1783             /* Find the page_start addr */
1784                 page_start = offset32 + written;
1785                 page_start -= (page_start % sc->bce_flash_info->page_size);
1786                 /* Find the page_end addr */
1787                 page_end = page_start + sc->bce_flash_info->page_size;
1788                 /* Find the data_start addr */
1789                 data_start = (written == 0) ? offset32 : page_start;
1790                 /* Find the data_end addr */
1791                 data_end = (page_end > offset32 + len32) ?
1792                         (offset32 + len32) : page_end;
1793
1794                 /* Request access to the flash interface. */
1795                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1796                         goto nvram_write_end;
1797
1798                 /* Enable access to flash interface */
1799                 bce_enable_nvram_access(sc);
1800
1801                 cmd_flags = BCE_NVM_COMMAND_FIRST;
1802                 if (sc->bce_flash_info->buffered == 0) {
1803                         int j;
1804
1805                         /* Read the whole page into the buffer
1806                          * (non-buffer flash only) */
1807                         for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
1808                                 if (j == (sc->bce_flash_info->page_size - 4)) {
1809                                         cmd_flags |= BCE_NVM_COMMAND_LAST;
1810                                 }
1811                                 rc = bce_nvram_read_dword(sc,
1812                                         page_start + j,
1813                                         &flash_buffer[j],
1814                                         cmd_flags);
1815
1816                                 if (rc)
1817                                         goto nvram_write_end;
1818
1819                                 cmd_flags = 0;
1820                         }
1821                 }
1822
1823                 /* Enable writes to flash interface (unlock write-protect) */
1824                 if ((rc = bce_enable_nvram_write(sc)) != 0)
1825                         goto nvram_write_end;
1826
1827                 /* Erase the page */
1828                 if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
1829                         goto nvram_write_end;
1830
1831                 /* Re-enable the write again for the actual write */
1832                 bce_enable_nvram_write(sc);
1833
1834                 /* Loop to write back the buffer data from page_start to
1835                  * data_start */
1836                 i = 0;
1837                 if (sc->bce_flash_info->buffered == 0) {
1838                         for (addr = page_start; addr < data_start;
1839                                 addr += 4, i += 4) {
1840
1841                                 rc = bce_nvram_write_dword(sc, addr,
1842                                         &flash_buffer[i], cmd_flags);
1843
1844                                 if (rc != 0)
1845                                         goto nvram_write_end;
1846
1847                                 cmd_flags = 0;
1848                         }
1849                 }
1850
1851                 /* Loop to write the new data from data_start to data_end */
1852                 for (addr = data_start; addr < data_end; addr += 4, i++) {
1853                         if ((addr == page_end - 4) ||
1854                                 ((sc->bce_flash_info->buffered) &&
1855                                  (addr == data_end - 4))) {
1856
1857                                 cmd_flags |= BCE_NVM_COMMAND_LAST;
1858                         }
1859                         rc = bce_nvram_write_dword(sc, addr, buf,
1860                                 cmd_flags);
1861
1862                         if (rc != 0)
1863                                 goto nvram_write_end;
1864
1865                         cmd_flags = 0;
1866                         buf += 4;
1867                 }
1868
1869                 /* Loop to write back the buffer data from data_end
1870                  * to page_end */
1871                 if (sc->bce_flash_info->buffered == 0) {
1872                         for (addr = data_end; addr < page_end;
1873                                 addr += 4, i += 4) {
1874
1875                                 if (addr == page_end-4) {
1876                                         cmd_flags = BCE_NVM_COMMAND_LAST;
1877                                 }
1878                                 rc = bce_nvram_write_dword(sc, addr,
1879                                         &flash_buffer[i], cmd_flags);
1880
1881                                 if (rc != 0)
1882                                         goto nvram_write_end;
1883
1884                                 cmd_flags = 0;
1885                         }
1886                 }
1887
1888                 /* Disable writes to flash interface (lock write-protect) */
1889                 bce_disable_nvram_write(sc);
1890
1891                 /* Disable access to flash interface */
1892                 bce_disable_nvram_access(sc);
1893                 bce_release_nvram_lock(sc);
1894
1895                 /* Increment written */
1896                 written += data_end - data_start;
1897         }
1898
1899 nvram_write_end:
1900         if (align_start || align_end)
1901                 free(buf, M_DEVBUF);
1902
1903         return rc;
1904 }
1905 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1906
1907
1908 /****************************************************************************/
1909 /* Verifies that NVRAM is accessible and contains valid data.               */
1910 /*                                                                          */
1911 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
1912 /* correct.                                                                 */
1913 /*                                                                          */
1914 /* Returns:                                                                 */
1915 /*   0 on success, positive value on failure.                               */
1916 /****************************************************************************/
1917 static int
1918 bce_nvram_test(struct bce_softc *sc)
1919 {
1920         u32 buf[BCE_NVRAM_SIZE / 4];
1921         u8 *data = (u8 *) buf;
1922         int rc = 0;
1923         u32 magic, csum;
1924
1925
1926         /*
1927          * Check that the device NVRAM is valid by reading
1928          * the magic value at offset 0.
1929          */
1930         if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0)
1931                 goto bce_nvram_test_done;
1932
1933
1934     magic = bce_be32toh(buf[0]);
1935         if (magic != BCE_NVRAM_MAGIC) {
1936                 rc = ENODEV;
1937                 BCE_PRINTF(sc, "%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
1938                         "Found: 0x%08X\n",
1939                         __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
1940                 goto bce_nvram_test_done;
1941         }
1942
1943         /*
1944          * Verify that the device NVRAM includes valid
1945          * configuration data.
1946          */
1947         if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0)
1948                 goto bce_nvram_test_done;
1949
1950         csum = ether_crc32_le(data, 0x100);
1951         if (csum != BCE_CRC32_RESIDUAL) {
1952                 rc = ENODEV;
1953                 BCE_PRINTF(sc, "%s(%d): Invalid Manufacturing Information NVRAM CRC! "
1954                         "Expected: 0x%08X, Found: 0x%08X\n",
1955                         __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
1956                 goto bce_nvram_test_done;
1957         }
1958
1959         csum = ether_crc32_le(data + 0x100, 0x100);
1960         if (csum != BCE_CRC32_RESIDUAL) {
1961                 BCE_PRINTF(sc, "%s(%d): Invalid Feature Configuration Information "
1962                         "NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
1963                         __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
1964                 rc = ENODEV;
1965         }
1966
1967 bce_nvram_test_done:
1968         return rc;
1969 }
1970
1971
1972 /****************************************************************************/
1973 /* Free any DMA memory owned by the driver.                                 */
1974 /*                                                                          */
1975 /* Scans through each data structre that requires DMA memory and frees      */
1976 /* the memory if allocated.                                                 */
1977 /*                                                                          */
1978 /* Returns:                                                                 */
1979 /*   Nothing.                                                               */
1980 /****************************************************************************/
1981 static void
1982 bce_dma_free(struct bce_softc *sc)
1983 {
1984         int i;
1985
1986         DBPRINT(sc,BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
1987
1988         /* Destroy the status block. */
1989         if (sc->status_block != NULL)
1990                 bus_dmamem_free(
1991                         sc->status_tag,
1992                     sc->status_block,
1993                     sc->status_map);
1994
1995         if (sc->status_map != NULL) {
1996                 bus_dmamap_unload(
1997                         sc->status_tag,
1998                     sc->status_map);
1999                 bus_dmamap_destroy(sc->status_tag,
2000                     sc->status_map);
2001         }
2002
2003         if (sc->status_tag != NULL)
2004                 bus_dma_tag_destroy(sc->status_tag);
2005
2006
2007         /* Destroy the statistics block. */
2008         if (sc->stats_block != NULL)
2009                 bus_dmamem_free(
2010                         sc->stats_tag,
2011                     sc->stats_block,
2012                     sc->stats_map);
2013
2014         if (sc->stats_map != NULL) {
2015                 bus_dmamap_unload(
2016                         sc->stats_tag,
2017                     sc->stats_map);
2018                 bus_dmamap_destroy(sc->stats_tag,
2019                     sc->stats_map);
2020         }
2021
2022         if (sc->stats_tag != NULL)
2023                 bus_dma_tag_destroy(sc->stats_tag);
2024
2025
2026         /* Free, unmap and destroy all TX buffer descriptor chain pages. */
2027         for (i = 0; i < TX_PAGES; i++ ) {
2028                 if (sc->tx_bd_chain[i] != NULL)
2029                         bus_dmamem_free(
2030                                 sc->tx_bd_chain_tag,
2031                             sc->tx_bd_chain[i],
2032                             sc->tx_bd_chain_map[i]);
2033
2034                 if (sc->tx_bd_chain_map[i] != NULL) {
2035                         bus_dmamap_unload(
2036                                 sc->tx_bd_chain_tag,
2037                         sc->tx_bd_chain_map[i]);
2038                         bus_dmamap_destroy(
2039                                 sc->tx_bd_chain_tag,
2040                             sc->tx_bd_chain_map[i]);
2041                 }
2042
2043         }
2044
2045         /* Destroy the TX buffer descriptor tag. */
2046         if (sc->tx_bd_chain_tag != NULL)
2047                 bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2048
2049
2050         /* Free, unmap and destroy all RX buffer descriptor chain pages. */
2051         for (i = 0; i < RX_PAGES; i++ ) {
2052                 if (sc->rx_bd_chain[i] != NULL)
2053                         bus_dmamem_free(
2054                                 sc->rx_bd_chain_tag,
2055                             sc->rx_bd_chain[i],
2056                             sc->rx_bd_chain_map[i]);
2057
2058                 if (sc->rx_bd_chain_map[i] != NULL) {
2059                         bus_dmamap_unload(
2060                                 sc->rx_bd_chain_tag,
2061                         sc->rx_bd_chain_map[i]);
2062                         bus_dmamap_destroy(
2063                                 sc->rx_bd_chain_tag,
2064                             sc->rx_bd_chain_map[i]);
2065                 }
2066         }
2067
2068         /* Destroy the RX buffer descriptor tag. */
2069         if (sc->rx_bd_chain_tag != NULL)
2070                 bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2071
2072
2073         /* Unload and destroy the TX mbuf maps. */
2074         for (i = 0; i < TOTAL_TX_BD; i++) {
2075                 if (sc->tx_mbuf_map[i] != NULL) {
2076                         bus_dmamap_unload(sc->tx_mbuf_tag, 
2077                                 sc->tx_mbuf_map[i]);
2078                         bus_dmamap_destroy(sc->tx_mbuf_tag, 
2079                                 sc->tx_mbuf_map[i]);
2080                 }
2081         }
2082
2083         /* Destroy the TX mbuf tag. */
2084         if (sc->tx_mbuf_tag != NULL)
2085                 bus_dma_tag_destroy(sc->tx_mbuf_tag);
2086
2087
2088         /* Unload and destroy the RX mbuf maps. */
2089         for (i = 0; i < TOTAL_RX_BD; i++) {
2090                 if (sc->rx_mbuf_map[i] != NULL) {
2091                         bus_dmamap_unload(sc->rx_mbuf_tag, 
2092                                 sc->rx_mbuf_map[i]);
2093                         bus_dmamap_destroy(sc->rx_mbuf_tag, 
2094                                 sc->rx_mbuf_map[i]);
2095                 }
2096         }
2097
2098         /* Destroy the RX mbuf tag. */
2099         if (sc->rx_mbuf_tag != NULL)
2100                 bus_dma_tag_destroy(sc->rx_mbuf_tag);
2101
2102
2103         /* Destroy the parent tag */
2104         if (sc->parent_tag != NULL)
2105                 bus_dma_tag_destroy(sc->parent_tag);
2106
2107         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2108
2109 }
2110
2111
2112 /****************************************************************************/
2113 /* Get DMA memory from the OS.                                              */
2114 /*                                                                          */
2115 /* Validates that the OS has provided DMA buffers in response to a          */
2116 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
2117 /* When the callback is used the OS will return 0 for the mapping function  */
2118 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2119 /* failures back to the caller.                                             */
2120 /*                                                                          */
2121 /* Returns:                                                                 */
2122 /*   Nothing.                                                               */
2123 /****************************************************************************/
2124 static void
2125 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2126 {
2127         struct bce_dmamap_arg *map_arg = arg;
2128         struct bce_softc *sc = map_arg->sc;
2129
2130         /* Simulate a mapping failure. */
2131         DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure),
2132                 BCE_PRINTF(sc, "%s(%d): Simulating DMA mapping error.\n",
2133                         __FILE__, __LINE__);
2134                 error = ENOMEM);
2135                 
2136         /* Check for an error and signal the caller that an error occurred. */
2137         if (error || (nseg > map_arg->maxsegs)) {
2138                 BCE_PRINTF(sc, "%s(%d): DMA mapping error! error = %d, "
2139                 "nseg = %d, maxsegs = %d\n",
2140                         __FILE__, __LINE__, error, nseg, map_arg->maxsegs);
2141                 map_arg->maxsegs = 0;
2142                 goto bce_dma_map_addr_exit;
2143         }
2144
2145         map_arg->busaddr = segs->ds_addr;
2146
2147 bce_dma_map_addr_exit:
2148         return;
2149 }
2150
2151
2152 /****************************************************************************/
2153 /* Map TX buffers into TX buffer descriptors.                               */
2154 /*                                                                          */
2155 /* Given a series of DMA memory containting an outgoing frame, map the      */
2156 /* segments into the tx_bd structure used by the hardware.                  */
2157 /*                                                                          */
2158 /* Returns:                                                                 */
2159 /*   Nothing.                                                               */
2160 /****************************************************************************/
2161 static void
2162 bce_dma_map_tx_desc(void *arg, bus_dma_segment_t *segs,
2163         int nseg, bus_size_t mapsize, int error)
2164 {
2165         struct bce_dmamap_arg *map_arg;
2166         struct bce_softc *sc;
2167         struct tx_bd *txbd = NULL;
2168         int i = 0;
2169         u16 prod, chain_prod;
2170         u32     prod_bseq;
2171 #ifdef BCE_DEBUG
2172         u16 debug_prod;
2173 #endif
2174
2175         map_arg = arg;
2176         sc = map_arg->sc;
2177
2178         if (error) {
2179                 DBPRINT(sc, BCE_WARN, "%s(): Called with error = %d\n",
2180                         __FUNCTION__, error);
2181                 return;
2182         }
2183
2184         /* Signal error to caller if there's too many segments */
2185         if (nseg > map_arg->maxsegs) {
2186                 DBPRINT(sc, BCE_WARN,
2187                         "%s(): Mapped TX descriptors: max segs = %d, "
2188                         "actual segs = %d\n",
2189                         __FUNCTION__, map_arg->maxsegs, nseg);
2190
2191                 map_arg->maxsegs = 0;
2192                 return;
2193         }
2194
2195         /* prod points to an empty tx_bd at this point. */
2196         prod       = map_arg->prod;
2197         chain_prod = map_arg->chain_prod;
2198         prod_bseq  = map_arg->prod_bseq;
2199
2200 #ifdef BCE_DEBUG
2201         debug_prod = chain_prod;
2202 #endif
2203
2204         DBPRINT(sc, BCE_INFO_SEND,
2205                 "%s(): Start: prod = 0x%04X, chain_prod = %04X, "
2206                 "prod_bseq = 0x%08X\n",
2207                 __FUNCTION__, prod, chain_prod, prod_bseq);
2208
2209         /*
2210          * Cycle through each mbuf segment that makes up
2211          * the outgoing frame, gathering the mapping info
2212          * for that segment and creating a tx_bd to for
2213          * the mbuf.
2214          */
2215
2216         txbd = &map_arg->tx_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
2217
2218         /* Setup the first tx_bd for the first segment. */
2219         txbd->tx_bd_haddr_lo       = htole32(BCE_ADDR_LO(segs[i].ds_addr));
2220         txbd->tx_bd_haddr_hi       = htole32(BCE_ADDR_HI(segs[i].ds_addr));
2221         txbd->tx_bd_mss_nbytes     = htole16(segs[i].ds_len);
2222         txbd->tx_bd_vlan_tag_flags = htole16(map_arg->tx_flags |
2223                         TX_BD_FLAGS_START);
2224         prod_bseq += segs[i].ds_len;
2225
2226         /* Setup any remaing segments. */
2227         for (i = 1; i < nseg; i++) {
2228                 prod       = NEXT_TX_BD(prod);
2229                 chain_prod = TX_CHAIN_IDX(prod);
2230
2231                 txbd = &map_arg->tx_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
2232
2233                 txbd->tx_bd_haddr_lo       = htole32(BCE_ADDR_LO(segs[i].ds_addr));
2234                 txbd->tx_bd_haddr_hi       = htole32(BCE_ADDR_HI(segs[i].ds_addr));
2235                 txbd->tx_bd_mss_nbytes     = htole16(segs[i].ds_len);
2236                 txbd->tx_bd_vlan_tag_flags = htole16(map_arg->tx_flags);
2237
2238                 prod_bseq += segs[i].ds_len;
2239         }
2240
2241         /* Set the END flag on the last TX buffer descriptor. */
2242         txbd->tx_bd_vlan_tag_flags |= htole16(TX_BD_FLAGS_END);
2243
2244         DBRUN(BCE_INFO_SEND, bce_dump_tx_chain(sc, debug_prod, nseg));
2245
2246         DBPRINT(sc, BCE_INFO_SEND,
2247                 "%s(): End: prod = 0x%04X, chain_prod = %04X, "
2248                 "prod_bseq = 0x%08X\n",
2249                 __FUNCTION__, prod, chain_prod, prod_bseq);
2250
2251         /* prod points to the last tx_bd at this point. */
2252         map_arg->maxsegs    = nseg;
2253         map_arg->prod       = prod;
2254         map_arg->chain_prod = chain_prod;
2255         map_arg->prod_bseq  = prod_bseq;
2256 }
2257
2258
2259 /****************************************************************************/
2260 /* Allocate any DMA memory needed by the driver.                            */
2261 /*                                                                          */
2262 /* Allocates DMA memory needed for the various global structures needed by  */
2263 /* hardware.                                                                */
2264 /*                                                                          */
2265 /* Returns:                                                                 */
2266 /*   0 for success, positive value for failure.                             */
2267 /****************************************************************************/
2268 static int
2269 bce_dma_alloc(device_t dev)
2270 {
2271         struct bce_softc *sc;
2272         int i, error, rc = 0;
2273         struct bce_dmamap_arg map_arg;
2274
2275         sc = device_get_softc(dev);
2276
2277         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
2278
2279         /*
2280          * Allocate the parent bus DMA tag appropriate for PCI.
2281          */
2282         if (bus_dma_tag_create(NULL,            /* parent     */
2283                         BCE_DMA_ALIGN,                          /* alignment  */
2284                         BCE_DMA_BOUNDARY,                       /* boundary   */
2285                         sc->max_bus_addr,                       /* lowaddr    */
2286                         BUS_SPACE_MAXADDR,                      /* highaddr   */
2287                         NULL,                                           /* filterfunc */
2288                         NULL,                                           /* filterarg  */
2289                         MAXBSIZE,                                       /* maxsize    */
2290                         BUS_SPACE_UNRESTRICTED,         /* nsegments  */
2291                         BUS_SPACE_MAXSIZE_32BIT,        /* maxsegsize */
2292                         0,                                                      /* flags      */
2293                         NULL,                                           /* locfunc    */
2294                         NULL,                                           /* lockarg    */
2295                         &sc->parent_tag)) {
2296                 BCE_PRINTF(sc, "%s(%d): Could not allocate parent DMA tag!\n",
2297                         __FILE__, __LINE__);
2298                 rc = ENOMEM;
2299                 goto bce_dma_alloc_exit;
2300         }
2301
2302         /*
2303          * Create a DMA tag for the status block, allocate and clear the
2304          * memory, map the memory into DMA space, and fetch the physical 
2305          * address of the block.
2306          */
2307         if (bus_dma_tag_create(
2308                         sc->parent_tag,                 /* parent      */
2309                 BCE_DMA_ALIGN,                  /* alignment   */
2310                 BCE_DMA_BOUNDARY,               /* boundary    */
2311                 sc->max_bus_addr,               /* lowaddr     */
2312                 BUS_SPACE_MAXADDR,              /* highaddr    */
2313                 NULL,                                   /* filterfunc  */
2314                 NULL,                                   /* filterarg   */
2315                 BCE_STATUS_BLK_SZ,              /* maxsize     */
2316                 1,                                              /* nsegments   */
2317                 BCE_STATUS_BLK_SZ,              /* maxsegsize  */
2318                 0,                                              /* flags       */
2319                 NULL,                                   /* lockfunc    */
2320                 NULL,                                   /* lockarg     */
2321                 &sc->status_tag)) {
2322                 BCE_PRINTF(sc, "%s(%d): Could not allocate status block DMA tag!\n",
2323                         __FILE__, __LINE__);
2324                 rc = ENOMEM;
2325                 goto bce_dma_alloc_exit;
2326         }
2327
2328         if(bus_dmamem_alloc(
2329                         sc->status_tag,                         /* dmat        */
2330                 (void **)&sc->status_block,     /* vaddr       */
2331                 BUS_DMA_NOWAIT,                                 /* flags       */
2332                 &sc->status_map)) {
2333                 BCE_PRINTF(sc, "%s(%d): Could not allocate status block DMA memory!\n",
2334                         __FILE__, __LINE__);
2335                 rc = ENOMEM;
2336                 goto bce_dma_alloc_exit;
2337         }
2338
2339         bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
2340
2341         map_arg.sc = sc;
2342         map_arg.maxsegs = 1;
2343
2344         error = bus_dmamap_load(
2345                         sc->status_tag,                 /* dmat        */
2346                 sc->status_map,                 /* map         */
2347                 sc->status_block,               /* buf         */
2348                 BCE_STATUS_BLK_SZ,              /* buflen      */
2349                 bce_dma_map_addr,               /* callback    */
2350                 &map_arg,                               /* callbackarg */
2351                 BUS_DMA_NOWAIT);                /* flags       */
2352                 
2353         if(error || (map_arg.maxsegs == 0)) {
2354                 BCE_PRINTF(sc, "%s(%d): Could not map status block DMA memory!\n",
2355                         __FILE__, __LINE__);
2356                 rc = ENOMEM;
2357                 goto bce_dma_alloc_exit;
2358         }
2359
2360         sc->status_block_paddr = map_arg.busaddr;
2361         /* DRC - Fix for 64 bit addresses. */
2362         DBPRINT(sc, BCE_INFO, "status_block_paddr = 0x%08X\n",
2363                 (u32) sc->status_block_paddr);
2364
2365         /*
2366          * Create a DMA tag for the statistics block, allocate and clear the
2367          * memory, map the memory into DMA space, and fetch the physical 
2368          * address of the block.
2369          */
2370         if (bus_dma_tag_create(
2371                         sc->parent_tag,                 /* parent      */
2372                 BCE_DMA_ALIGN,                  /* alignment   */
2373                 BCE_DMA_BOUNDARY,               /* boundary    */
2374                 sc->max_bus_addr,               /* lowaddr     */
2375                 BUS_SPACE_MAXADDR,              /* highaddr    */
2376                 NULL,                                   /* filterfunc  */
2377                 NULL,                                   /* filterarg   */
2378                 BCE_STATS_BLK_SZ,               /* maxsize     */
2379                 1,                                              /* nsegments   */
2380                 BCE_STATS_BLK_SZ,               /* maxsegsize  */
2381                 0,                                              /* flags       */
2382                 NULL,                                   /* lockfunc    */
2383                 NULL,                                   /* lockarg     */
2384                 &sc->stats_tag)) {
2385                 BCE_PRINTF(sc, "%s(%d): Could not allocate statistics block DMA tag!\n",
2386                         __FILE__, __LINE__);
2387                 rc = ENOMEM;
2388                 goto bce_dma_alloc_exit;
2389         }
2390
2391         if (bus_dmamem_alloc(
2392                         sc->stats_tag,                          /* dmat        */
2393                 (void **)&sc->stats_block,      /* vaddr       */
2394                 BUS_DMA_NOWAIT,                         /* flags       */
2395                 &sc->stats_map)) {
2396                 BCE_PRINTF(sc, "%s(%d): Could not allocate statistics block DMA memory!\n",
2397                         __FILE__, __LINE__);
2398                 rc = ENOMEM;
2399                 goto bce_dma_alloc_exit;
2400         }
2401
2402         bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
2403
2404         map_arg.sc = sc;
2405         map_arg.maxsegs = 1;
2406
2407         error = bus_dmamap_load(
2408                         sc->stats_tag,          /* dmat        */
2409                 sc->stats_map,          /* map         */
2410                 sc->stats_block,        /* buf         */
2411                 BCE_STATS_BLK_SZ,       /* buflen      */
2412                 bce_dma_map_addr,       /* callback    */
2413                 &map_arg,                       /* callbackarg */
2414                 BUS_DMA_NOWAIT);        /* flags       */
2415
2416         if(error || (map_arg.maxsegs == 0)) {
2417                 BCE_PRINTF(sc, "%s(%d): Could not map statistics block DMA memory!\n",
2418                         __FILE__, __LINE__);
2419                 rc = ENOMEM;
2420                 goto bce_dma_alloc_exit;
2421         }
2422
2423         sc->stats_block_paddr = map_arg.busaddr;
2424         /* DRC - Fix for 64 bit address. */
2425         DBPRINT(sc,BCE_INFO, "stats_block_paddr = 0x%08X\n", 
2426                 (u32) sc->stats_block_paddr);
2427
2428         /*
2429          * Create a DMA tag for the TX buffer descriptor chain,
2430          * allocate and clear the  memory, and fetch the
2431          * physical address of the block.
2432          */
2433         if(bus_dma_tag_create(
2434                         sc->parent_tag,           /* parent      */
2435                 BCM_PAGE_SIZE,            /* alignment   */
2436                 BCE_DMA_BOUNDARY,         /* boundary    */
2437                         sc->max_bus_addr,         /* lowaddr     */
2438                         BUS_SPACE_MAXADDR,        /* highaddr    */
2439                         NULL,                             /* filterfunc  */ 
2440                         NULL,                             /* filterarg   */
2441                         BCE_TX_CHAIN_PAGE_SZ, /* maxsize     */
2442                         1,                                        /* nsegments   */
2443                         BCE_TX_CHAIN_PAGE_SZ, /* maxsegsize  */
2444                         0,                                        /* flags       */
2445                         NULL,                             /* lockfunc    */
2446                         NULL,                             /* lockarg     */
2447                         &sc->tx_bd_chain_tag)) {
2448                 BCE_PRINTF(sc, "%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
2449                         __FILE__, __LINE__);
2450                 rc = ENOMEM;
2451                 goto bce_dma_alloc_exit;
2452         }
2453
2454         for (i = 0; i < TX_PAGES; i++) {
2455
2456                 if(bus_dmamem_alloc(
2457                                 sc->tx_bd_chain_tag,                    /* tag   */
2458                         (void **)&sc->tx_bd_chain[i],   /* vaddr */
2459                         BUS_DMA_NOWAIT,                                 /* flags */
2460                         &sc->tx_bd_chain_map[i])) {
2461                         BCE_PRINTF(sc, "%s(%d): Could not allocate TX descriptor "
2462                                 "chain DMA memory!\n", __FILE__, __LINE__);
2463                         rc = ENOMEM;
2464                         goto bce_dma_alloc_exit;
2465                 }
2466
2467                 map_arg.maxsegs = 1;
2468                 map_arg.sc = sc;
2469
2470                 error = bus_dmamap_load(
2471                                 sc->tx_bd_chain_tag,     /* dmat        */
2472                         sc->tx_bd_chain_map[i],  /* map         */
2473                         sc->tx_bd_chain[i],              /* buf         */
2474                         BCE_TX_CHAIN_PAGE_SZ,    /* buflen      */
2475                         bce_dma_map_addr,                /* callback    */
2476                         &map_arg,                                /* callbackarg */
2477                         BUS_DMA_NOWAIT);                 /* flags       */
2478
2479                 if(error || (map_arg.maxsegs == 0)) {
2480                         BCE_PRINTF(sc, "%s(%d): Could not map TX descriptor chain DMA memory!\n",
2481                                 __FILE__, __LINE__);
2482                         rc = ENOMEM;
2483                         goto bce_dma_alloc_exit;
2484                 }
2485
2486                 sc->tx_bd_chain_paddr[i] = map_arg.busaddr;
2487                 /* DRC - Fix for 64 bit systems. */
2488                 DBPRINT(sc, BCE_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n", 
2489                         i, (u32) sc->tx_bd_chain_paddr[i]);
2490         }
2491
2492         /* Create a DMA tag for TX mbufs. */
2493         if (bus_dma_tag_create(
2494                         sc->parent_tag,                 /* parent      */
2495                 BCE_DMA_ALIGN,                  /* alignment   */
2496                 BCE_DMA_BOUNDARY,               /* boundary    */
2497                         sc->max_bus_addr,               /* lowaddr     */
2498                         BUS_SPACE_MAXADDR,              /* highaddr    */
2499                         NULL,                                   /* filterfunc  */
2500                         NULL,                                   /* filterarg   */
2501                         MCLBYTES * BCE_MAX_SEGMENTS,    /* maxsize     */
2502                         BCE_MAX_SEGMENTS,               /* nsegments   */
2503                         MCLBYTES,                               /* maxsegsize  */
2504                         0,                                              /* flags       */
2505                         NULL,                                   /* lockfunc    */
2506                         NULL,                                   /* lockarg     */
2507                 &sc->tx_mbuf_tag)) {
2508                 BCE_PRINTF(sc, "%s(%d): Could not allocate TX mbuf DMA tag!\n",
2509                         __FILE__, __LINE__);
2510                 rc = ENOMEM;
2511                 goto bce_dma_alloc_exit;
2512         }
2513
2514         /* Create DMA maps for the TX mbufs clusters. */
2515         for (i = 0; i < TOTAL_TX_BD; i++) {
2516                 if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT, 
2517                         &sc->tx_mbuf_map[i])) {
2518                         BCE_PRINTF(sc, "%s(%d): Unable to create TX mbuf DMA map!\n",
2519                                 __FILE__, __LINE__);
2520                         rc = ENOMEM;
2521                         goto bce_dma_alloc_exit;
2522                 }
2523         }
2524
2525         /*
2526          * Create a DMA tag for the RX buffer descriptor chain,
2527          * allocate and clear the  memory, and fetch the physical
2528          * address of the blocks.
2529          */
2530         if (bus_dma_tag_create(
2531                         sc->parent_tag,                 /* parent      */
2532                 BCM_PAGE_SIZE,                  /* alignment   */
2533                 BCE_DMA_BOUNDARY,               /* boundary    */
2534                         BUS_SPACE_MAXADDR,              /* lowaddr     */
2535                         sc->max_bus_addr,               /* lowaddr     */
2536                         NULL,                                   /* filter      */
2537                         NULL,                                   /* filterarg   */
2538                         BCE_RX_CHAIN_PAGE_SZ,   /* maxsize     */
2539                         1,                                              /* nsegments   */
2540                         BCE_RX_CHAIN_PAGE_SZ,   /* maxsegsize  */
2541                         0,                                              /* flags       */
2542                         NULL,                                   /* lockfunc    */
2543                         NULL,                                   /* lockarg     */
2544                         &sc->rx_bd_chain_tag)) {
2545                 BCE_PRINTF(sc, "%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
2546                         __FILE__, __LINE__);
2547                 rc = ENOMEM;
2548                 goto bce_dma_alloc_exit;
2549         }
2550
2551         for (i = 0; i < RX_PAGES; i++) {
2552
2553                 if (bus_dmamem_alloc(
2554                                 sc->rx_bd_chain_tag,                    /* tag   */
2555                         (void **)&sc->rx_bd_chain[i],   /* vaddr */
2556                         BUS_DMA_NOWAIT,                                 /* flags */
2557                         &sc->rx_bd_chain_map[i])) {
2558                         BCE_PRINTF(sc, "%s(%d): Could not allocate RX descriptor chain "
2559                                 "DMA memory!\n", __FILE__, __LINE__);
2560                         rc = ENOMEM;
2561                         goto bce_dma_alloc_exit;
2562                 }
2563
2564                 bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
2565
2566                 map_arg.maxsegs = 1;
2567                 map_arg.sc = sc;
2568
2569                 error = bus_dmamap_load(
2570                                 sc->rx_bd_chain_tag,    /* dmat        */
2571                         sc->rx_bd_chain_map[i], /* map         */
2572                         sc->rx_bd_chain[i],             /* buf         */
2573                         BCE_RX_CHAIN_PAGE_SZ,   /* buflen      */
2574                         bce_dma_map_addr,               /* callback    */
2575                         &map_arg,                               /* callbackarg */
2576                         BUS_DMA_NOWAIT);                /* flags       */
2577
2578                 if(error || (map_arg.maxsegs == 0)) {
2579                         BCE_PRINTF(sc, "%s(%d): Could not map RX descriptor chain DMA memory!\n",
2580                                 __FILE__, __LINE__);
2581                         rc = ENOMEM;
2582                         goto bce_dma_alloc_exit;
2583                 }
2584
2585                 sc->rx_bd_chain_paddr[i] = map_arg.busaddr;
2586                 /* DRC - Fix for 64 bit systems. */
2587                 DBPRINT(sc, BCE_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n",
2588                         i, (u32) sc->rx_bd_chain_paddr[i]);
2589         }
2590
2591         /*
2592          * Create a DMA tag for RX mbufs.
2593          */
2594         if (bus_dma_tag_create(
2595                         sc->parent_tag,                 /* parent      */
2596                 BCE_DMA_ALIGN,                  /* alignment   */
2597                 BCE_DMA_BOUNDARY,               /* boundary    */
2598                         sc->max_bus_addr,               /* lowaddr     */
2599                         BUS_SPACE_MAXADDR,              /* highaddr    */
2600                         NULL,                                   /* filterfunc  */
2601                         NULL,                                   /* filterarg   */
2602                         MJUM9BYTES,                             /* maxsize     */
2603                         BCE_MAX_SEGMENTS,               /* nsegments   */
2604                         MJUM9BYTES,                             /* maxsegsize  */
2605                         0,                                              /* flags       */
2606                         NULL,                                   /* lockfunc    */
2607                         NULL,                                   /* lockarg     */
2608                 &sc->rx_mbuf_tag)) {
2609                 BCE_PRINTF(sc, "%s(%d): Could not allocate RX mbuf DMA tag!\n",
2610                         __FILE__, __LINE__);
2611                 rc = ENOMEM;
2612                 goto bce_dma_alloc_exit;
2613         }
2614
2615         /* Create DMA maps for the RX mbuf clusters. */
2616         for (i = 0; i < TOTAL_RX_BD; i++) {
2617                 if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
2618                                 &sc->rx_mbuf_map[i])) {
2619                         BCE_PRINTF(sc, "%s(%d): Unable to create RX mbuf DMA map!\n",
2620                                 __FILE__, __LINE__);
2621                         rc = ENOMEM;
2622                         goto bce_dma_alloc_exit;
2623                 }
2624         }
2625
2626 bce_dma_alloc_exit:
2627         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2628
2629         return(rc);
2630 }
2631
2632
2633 /****************************************************************************/
2634 /* Release all resources used by the driver.                                */
2635 /*                                                                          */
2636 /* Releases all resources acquired by the driver including interrupts,      */
2637 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
2638 /*                                                                          */
2639 /* Returns:                                                                 */
2640 /*   Nothing.                                                               */
2641 /****************************************************************************/
2642 static void
2643 bce_release_resources(struct bce_softc *sc)
2644 {
2645         device_t dev;
2646
2647         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
2648
2649         dev = sc->bce_dev;
2650
2651         bce_dma_free(sc);
2652
2653         if (sc->bce_intrhand != NULL)
2654                 bus_teardown_intr(dev, sc->bce_irq, sc->bce_intrhand);
2655
2656         if (sc->bce_irq != NULL)
2657                 bus_release_resource(dev,
2658                         SYS_RES_IRQ,
2659                         0,
2660                         sc->bce_irq);
2661
2662         if (sc->bce_res != NULL)
2663                 bus_release_resource(dev,
2664                         SYS_RES_MEMORY,
2665                     PCIR_BAR(0),
2666                     sc->bce_res);
2667
2668         if (sc->bce_ifp != NULL)
2669                 if_free(sc->bce_ifp);
2670
2671
2672         if (mtx_initialized(&sc->bce_mtx))
2673                 BCE_LOCK_DESTROY(sc);
2674
2675         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2676
2677 }
2678
2679
2680 /****************************************************************************/
2681 /* Firmware synchronization.                                                */
2682 /*                                                                          */
2683 /* Before performing certain events such as a chip reset, synchronize with  */
2684 /* the firmware first.                                                      */
2685 /*                                                                          */
2686 /* Returns:                                                                 */
2687 /*   0 for success, positive value for failure.                             */
2688 /****************************************************************************/
2689 static int
2690 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
2691 {
2692         int i, rc = 0;
2693         u32 val;
2694
2695         /* Don't waste any time if we've timed out before. */
2696         if (sc->bce_fw_timed_out) {
2697                 rc = EBUSY;
2698                 goto bce_fw_sync_exit;
2699         }
2700
2701         /* Increment the message sequence number. */
2702         sc->bce_fw_wr_seq++;
2703         msg_data |= sc->bce_fw_wr_seq;
2704
2705         DBPRINT(sc, BCE_VERBOSE, "bce_fw_sync(): msg_data = 0x%08X\n", msg_data);
2706
2707         /* Send the message to the bootcode driver mailbox. */
2708         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2709
2710         /* Wait for the bootcode to acknowledge the message. */
2711         for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
2712                 /* Check for a response in the bootcode firmware mailbox. */
2713                 val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
2714                 if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
2715                         break;
2716                 DELAY(1000);
2717         }
2718
2719         /* If we've timed out, tell the bootcode that we've stopped waiting. */
2720         if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
2721                 ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
2722
2723                 BCE_PRINTF(sc, "%s(%d): Firmware synchronization timeout! "
2724                         "msg_data = 0x%08X\n",
2725                         __FILE__, __LINE__, msg_data);
2726
2727                 msg_data &= ~BCE_DRV_MSG_CODE;
2728                 msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
2729
2730                 REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2731
2732                 sc->bce_fw_timed_out = 1;
2733                 rc = EBUSY;
2734         }
2735
2736 bce_fw_sync_exit:
2737         return (rc);
2738 }
2739
2740
2741 /****************************************************************************/
2742 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
2743 /*                                                                          */
2744 /* Returns:                                                                 */
2745 /*   Nothing.                                                               */
2746 /****************************************************************************/
2747 static void
2748 bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code, 
2749         u32 rv2p_code_len, u32 rv2p_proc)
2750 {
2751         int i;
2752         u32 val;
2753
2754         for (i = 0; i < rv2p_code_len; i += 8) {
2755                 REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
2756                 rv2p_code++;
2757                 REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
2758                 rv2p_code++;
2759
2760                 if (rv2p_proc == RV2P_PROC1) {
2761                         val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
2762                         REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
2763                 }
2764                 else {
2765                         val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
2766                         REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
2767                 }
2768         }
2769
2770         /* Reset the processor, un-stall is done later. */
2771         if (rv2p_proc == RV2P_PROC1) {
2772                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
2773         }
2774         else {
2775                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
2776         }
2777 }
2778
2779
2780 /****************************************************************************/
2781 /* Load RISC processor firmware.                                            */
2782 /*                                                                          */
2783 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
2784 /* associated with a particular processor.                                  */
2785 /*                                                                          */
2786 /* Returns:                                                                 */
2787 /*   Nothing.                                                               */
2788 /****************************************************************************/
2789 static void
2790 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
2791         struct fw_info *fw)
2792 {
2793         u32 offset;
2794         u32 val;
2795
2796         /* Halt the CPU. */
2797         val = REG_RD_IND(sc, cpu_reg->mode);
2798         val |= cpu_reg->mode_value_halt;
2799         REG_WR_IND(sc, cpu_reg->mode, val);
2800         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2801
2802         /* Load the Text area. */
2803         offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2804         if (fw->text) {
2805                 int j;
2806
2807                 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
2808                         REG_WR_IND(sc, offset, fw->text[j]);
2809                 }
2810         }
2811
2812         /* Load the Data area. */
2813         offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
2814         if (fw->data) {
2815                 int j;
2816
2817                 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
2818                         REG_WR_IND(sc, offset, fw->data[j]);
2819                 }
2820         }
2821
2822         /* Load the SBSS area. */
2823         offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
2824         if (fw->sbss) {
2825                 int j;
2826
2827                 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
2828                         REG_WR_IND(sc, offset, fw->sbss[j]);
2829                 }
2830         }
2831
2832         /* Load the BSS area. */
2833         offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
2834         if (fw->bss) {
2835                 int j;
2836
2837                 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
2838                         REG_WR_IND(sc, offset, fw->bss[j]);
2839                 }
2840         }
2841
2842         /* Load the Read-Only area. */
2843         offset = cpu_reg->spad_base +
2844                 (fw->rodata_addr - cpu_reg->mips_view_base);
2845         if (fw->rodata) {
2846                 int j;
2847
2848                 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
2849                         REG_WR_IND(sc, offset, fw->rodata[j]);
2850                 }
2851         }
2852
2853         /* Clear the pre-fetch instruction. */
2854         REG_WR_IND(sc, cpu_reg->inst, 0);
2855         REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
2856
2857         /* Start the CPU. */
2858         val = REG_RD_IND(sc, cpu_reg->mode);
2859         val &= ~cpu_reg->mode_value_halt;
2860         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2861         REG_WR_IND(sc, cpu_reg->mode, val);
2862 }
2863
2864
2865 /****************************************************************************/
2866 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs.                         */
2867 /*                                                                          */
2868 /* Loads the firmware for each CPU and starts the CPU.                      */
2869 /*                                                                          */
2870 /* Returns:                                                                 */
2871 /*   Nothing.                                                               */
2872 /****************************************************************************/
2873 static void
2874 bce_init_cpus(struct bce_softc *sc)
2875 {
2876         struct cpu_reg cpu_reg;
2877         struct fw_info fw;
2878
2879         /* Initialize the RV2P processor. */
2880         bce_load_rv2p_fw(sc, bce_rv2p_proc1, sizeof(bce_rv2p_proc1), RV2P_PROC1);
2881         bce_load_rv2p_fw(sc, bce_rv2p_proc2, sizeof(bce_rv2p_proc2), RV2P_PROC2);
2882
2883         /* Initialize the RX Processor. */
2884         cpu_reg.mode = BCE_RXP_CPU_MODE;
2885         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
2886         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
2887         cpu_reg.state = BCE_RXP_CPU_STATE;
2888         cpu_reg.state_value_clear = 0xffffff;
2889         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
2890         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
2891         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
2892         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
2893         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
2894         cpu_reg.spad_base = BCE_RXP_SCRATCH;
2895         cpu_reg.mips_view_base = 0x8000000;
2896
2897         fw.ver_major = bce_RXP_b06FwReleaseMajor;
2898         fw.ver_minor = bce_RXP_b06FwReleaseMinor;
2899         fw.ver_fix = bce_RXP_b06FwReleaseFix;
2900         fw.start_addr = bce_RXP_b06FwStartAddr;
2901
2902         fw.text_addr = bce_RXP_b06FwTextAddr;
2903         fw.text_len = bce_RXP_b06FwTextLen;
2904         fw.text_index = 0;
2905         fw.text = bce_RXP_b06FwText;
2906
2907         fw.data_addr = bce_RXP_b06FwDataAddr;
2908         fw.data_len = bce_RXP_b06FwDataLen;
2909         fw.data_index = 0;
2910         fw.data = bce_RXP_b06FwData;
2911
2912         fw.sbss_addr = bce_RXP_b06FwSbssAddr;
2913         fw.sbss_len = bce_RXP_b06FwSbssLen;
2914         fw.sbss_index = 0;
2915         fw.sbss = bce_RXP_b06FwSbss;
2916
2917         fw.bss_addr = bce_RXP_b06FwBssAddr;
2918         fw.bss_len = bce_RXP_b06FwBssLen;
2919         fw.bss_index = 0;
2920         fw.bss = bce_RXP_b06FwBss;
2921
2922         fw.rodata_addr = bce_RXP_b06FwRodataAddr;
2923         fw.rodata_len = bce_RXP_b06FwRodataLen;
2924         fw.rodata_index = 0;
2925         fw.rodata = bce_RXP_b06FwRodata;
2926
2927         DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
2928         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2929
2930         /* Initialize the TX Processor. */
2931         cpu_reg.mode = BCE_TXP_CPU_MODE;
2932         cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
2933         cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
2934         cpu_reg.state = BCE_TXP_CPU_STATE;
2935         cpu_reg.state_value_clear = 0xffffff;
2936         cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
2937         cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
2938         cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
2939         cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
2940         cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
2941         cpu_reg.spad_base = BCE_TXP_SCRATCH;
2942         cpu_reg.mips_view_base = 0x8000000;
2943
2944         fw.ver_major = bce_TXP_b06FwReleaseMajor;
2945         fw.ver_minor = bce_TXP_b06FwReleaseMinor;
2946         fw.ver_fix = bce_TXP_b06FwReleaseFix;
2947         fw.start_addr = bce_TXP_b06FwStartAddr;
2948
2949         fw.text_addr = bce_TXP_b06FwTextAddr;
2950         fw.text_len = bce_TXP_b06FwTextLen;
2951         fw.text_index = 0;
2952         fw.text = bce_TXP_b06FwText;
2953
2954         fw.data_addr = bce_TXP_b06FwDataAddr;
2955         fw.data_len = bce_TXP_b06FwDataLen;
2956         fw.data_index = 0;
2957         fw.data = bce_TXP_b06FwData;
2958
2959         fw.sbss_addr = bce_TXP_b06FwSbssAddr;
2960         fw.sbss_len = bce_TXP_b06FwSbssLen;
2961         fw.sbss_index = 0;
2962         fw.sbss = bce_TXP_b06FwSbss;
2963
2964         fw.bss_addr = bce_TXP_b06FwBssAddr;
2965         fw.bss_len = bce_TXP_b06FwBssLen;
2966         fw.bss_index = 0;
2967         fw.bss = bce_TXP_b06FwBss;
2968
2969         fw.rodata_addr = bce_TXP_b06FwRodataAddr;
2970         fw.rodata_len = bce_TXP_b06FwRodataLen;
2971         fw.rodata_index = 0;
2972         fw.rodata = bce_TXP_b06FwRodata;
2973
2974         DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
2975         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2976
2977         /* Initialize the TX Patch-up Processor. */
2978         cpu_reg.mode = BCE_TPAT_CPU_MODE;
2979         cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
2980         cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
2981         cpu_reg.state = BCE_TPAT_CPU_STATE;
2982         cpu_reg.state_value_clear = 0xffffff;
2983         cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
2984         cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
2985         cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
2986         cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
2987         cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
2988         cpu_reg.spad_base = BCE_TPAT_SCRATCH;
2989         cpu_reg.mips_view_base = 0x8000000;
2990
2991         fw.ver_major = bce_TPAT_b06FwReleaseMajor;
2992         fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
2993         fw.ver_fix = bce_TPAT_b06FwReleaseFix;
2994         fw.start_addr = bce_TPAT_b06FwStartAddr;
2995
2996         fw.text_addr = bce_TPAT_b06FwTextAddr;
2997         fw.text_len = bce_TPAT_b06FwTextLen;
2998         fw.text_index = 0;
2999         fw.text = bce_TPAT_b06FwText;
3000
3001         fw.data_addr = bce_TPAT_b06FwDataAddr;
3002         fw.data_len = bce_TPAT_b06FwDataLen;
3003         fw.data_index = 0;
3004         fw.data = bce_TPAT_b06FwData;
3005
3006         fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
3007         fw.sbss_len = bce_TPAT_b06FwSbssLen;
3008         fw.sbss_index = 0;
3009         fw.sbss = bce_TPAT_b06FwSbss;
3010
3011         fw.bss_addr = bce_TPAT_b06FwBssAddr;
3012         fw.bss_len = bce_TPAT_b06FwBssLen;
3013         fw.bss_index = 0;
3014         fw.bss = bce_TPAT_b06FwBss;
3015
3016         fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
3017         fw.rodata_len = bce_TPAT_b06FwRodataLen;
3018         fw.rodata_index = 0;
3019         fw.rodata = bce_TPAT_b06FwRodata;
3020
3021         DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
3022         bce_load_cpu_fw(sc, &cpu_reg, &fw);
3023
3024         /* Initialize the Completion Processor. */
3025         cpu_reg.mode = BCE_COM_CPU_MODE;
3026         cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
3027         cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
3028         cpu_reg.state = BCE_COM_CPU_STATE;
3029         cpu_reg.state_value_clear = 0xffffff;
3030         cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
3031         cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
3032         cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
3033         cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
3034         cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
3035         cpu_reg.spad_base = BCE_COM_SCRATCH;
3036         cpu_reg.mips_view_base = 0x8000000;
3037
3038         fw.ver_major = bce_COM_b06FwReleaseMajor;
3039         fw.ver_minor = bce_COM_b06FwReleaseMinor;
3040         fw.ver_fix = bce_COM_b06FwReleaseFix;
3041         fw.start_addr = bce_COM_b06FwStartAddr;
3042
3043         fw.text_addr = bce_COM_b06FwTextAddr;
3044         fw.text_len = bce_COM_b06FwTextLen;
3045         fw.text_index = 0;
3046         fw.text = bce_COM_b06FwText;
3047
3048         fw.data_addr = bce_COM_b06FwDataAddr;
3049         fw.data_len = bce_COM_b06FwDataLen;
3050         fw.data_index = 0;
3051         fw.data = bce_COM_b06FwData;
3052
3053         fw.sbss_addr = bce_COM_b06FwSbssAddr;
3054         fw.sbss_len = bce_COM_b06FwSbssLen;
3055         fw.sbss_index = 0;
3056         fw.sbss = bce_COM_b06FwSbss;
3057
3058         fw.bss_addr = bce_COM_b06FwBssAddr;
3059         fw.bss_len = bce_COM_b06FwBssLen;
3060         fw.bss_index = 0;
3061         fw.bss = bce_COM_b06FwBss;
3062
3063         fw.rodata_addr = bce_COM_b06FwRodataAddr;
3064         fw.rodata_len = bce_COM_b06FwRodataLen;
3065         fw.rodata_index = 0;
3066         fw.rodata = bce_COM_b06FwRodata;
3067
3068         DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
3069         bce_load_cpu_fw(sc, &cpu_reg, &fw);
3070 }
3071
3072
3073 /****************************************************************************/
3074 /* Initialize context memory.                                               */
3075 /*                                                                          */
3076 /* Clears the memory associated with each Context ID (CID).                 */
3077 /*                                                                          */
3078 /* Returns:                                                                 */
3079 /*   Nothing.                                                               */
3080 /****************************************************************************/
3081 static void
3082 bce_init_context(struct bce_softc *sc)
3083 {
3084         u32 vcid;
3085
3086         vcid = 96;
3087         while (vcid) {
3088                 u32 vcid_addr, pcid_addr, offset;
3089
3090                 vcid--;
3091
3092                 vcid_addr = GET_CID_ADDR(vcid);
3093                 pcid_addr = vcid_addr;
3094
3095                 REG_WR(sc, BCE_CTX_VIRT_ADDR, 0x00);
3096                 REG_WR(sc, BCE_CTX_PAGE_TBL, pcid_addr);
3097
3098                 /* Zero out the context. */
3099                 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
3100                         CTX_WR(sc, 0x00, offset, 0);
3101                 }
3102
3103                 REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
3104                 REG_WR(sc, BCE_CTX_PAGE_TBL, pcid_addr);
3105         }
3106 }
3107
3108
3109 /****************************************************************************/
3110 /* Fetch the permanent MAC address of the controller.                       */
3111 /*                                                                          */
3112 /* Returns:                                                                 */
3113 /*   Nothing.                                                               */
3114 /****************************************************************************/
3115 static void
3116 bce_get_mac_addr(struct bce_softc *sc)
3117 {
3118         u32 mac_lo = 0, mac_hi = 0;
3119
3120         /*
3121          * The NetXtreme II bootcode populates various NIC
3122          * power-on and runtime configuration items in a
3123          * shared memory area.  The factory configured MAC
3124          * address is available from both NVRAM and the
3125          * shared memory area so we'll read the value from
3126          * shared memory for speed.
3127          */
3128
3129         mac_hi = REG_RD_IND(sc, sc->bce_shmem_base +
3130                 BCE_PORT_HW_CFG_MAC_UPPER);
3131         mac_lo = REG_RD_IND(sc, sc->bce_shmem_base +
3132                 BCE_PORT_HW_CFG_MAC_LOWER);
3133
3134         if ((mac_lo == 0) && (mac_hi == 0)) {
3135                 BCE_PRINTF(sc, "%s(%d): Invalid Ethernet address!\n", 
3136                         __FILE__, __LINE__);
3137         } else {
3138                 sc->eaddr[0] = (u_char)(mac_hi >> 8);
3139                 sc->eaddr[1] = (u_char)(mac_hi >> 0);
3140                 sc->eaddr[2] = (u_char)(mac_lo >> 24);
3141                 sc->eaddr[3] = (u_char)(mac_lo >> 16);
3142                 sc->eaddr[4] = (u_char)(mac_lo >> 8);
3143                 sc->eaddr[5] = (u_char)(mac_lo >> 0);
3144         }
3145
3146         DBPRINT(sc, BCE_INFO, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
3147 }
3148
3149
3150 /****************************************************************************/
3151 /* Program the MAC address.                                                 */
3152 /*                                                                          */
3153 /* Returns:                                                                 */
3154 /*   Nothing.                                                               */
3155 /****************************************************************************/
3156 static void
3157 bce_set_mac_addr(struct bce_softc *sc)
3158 {
3159         u32 val;
3160         u8 *mac_addr = sc->eaddr;
3161
3162         DBPRINT(sc, BCE_INFO, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
3163
3164         val = (mac_addr[0] << 8) | mac_addr[1];
3165
3166         REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
3167
3168         val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
3169                 (mac_addr[4] << 8) | mac_addr[5];
3170
3171         REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
3172 }
3173
3174
3175 /****************************************************************************/
3176 /* Stop the controller.                                                     */
3177 /*                                                                          */
3178 /* Returns:                                                                 */
3179 /*   Nothing.                                                               */
3180 /****************************************************************************/
3181 static void
3182 bce_stop(struct bce_softc *sc)
3183 {
3184         struct ifnet *ifp;
3185         struct ifmedia_entry *ifm;
3186         struct mii_data *mii = NULL;
3187         int mtmp, itmp;
3188
3189         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3190
3191         BCE_LOCK_ASSERT(sc);
3192
3193         ifp = sc->bce_ifp;
3194
3195         mii = device_get_softc(sc->bce_miibus);
3196
3197         callout_stop(&sc->bce_stat_ch);
3198
3199         /* Disable the transmit/receive blocks. */
3200         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, 0x5ffffff);
3201         REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
3202         DELAY(20);
3203
3204         bce_disable_intr(sc);
3205
3206         /* Tell firmware that the driver is going away. */
3207         bce_reset(sc, BCE_DRV_MSG_CODE_SUSPEND_NO_WOL);
3208
3209         /* Free the RX lists. */
3210         bce_free_rx_chain(sc);
3211
3212         /* Free TX buffers. */
3213         bce_free_tx_chain(sc);
3214
3215         /*
3216          * Isolate/power down the PHY, but leave the media selection
3217          * unchanged so that things will be put back to normal when
3218          * we bring the interface back up.
3219          */
3220
3221         itmp = ifp->if_flags;
3222         ifp->if_flags |= IFF_UP;
3223         /*
3224          * If we are called from bce_detach(), mii is already NULL.
3225          */
3226         if (mii != NULL) {
3227                 ifm = mii->mii_media.ifm_cur;
3228                 mtmp = ifm->ifm_media;
3229                 ifm->ifm_media = IFM_ETHER | IFM_NONE;
3230                 mii_mediachg(mii);
3231                 ifm->ifm_media = mtmp;
3232         }
3233
3234         ifp->if_flags = itmp;
3235         ifp->if_timer = 0;
3236
3237         sc->bce_link = 0;
3238
3239         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3240
3241         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3242
3243 }
3244
3245
3246 static int
3247 bce_reset(struct bce_softc *sc, u32 reset_code)
3248 {
3249         u32 val;
3250         int i, rc = 0;
3251
3252         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3253
3254         /* Wait for pending PCI transactions to complete. */
3255         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
3256                BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
3257                BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
3258                BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
3259                BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
3260         val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
3261         DELAY(5);
3262
3263         /* Assume bootcode is running. */
3264         sc->bce_fw_timed_out = 0;
3265
3266         /* Give the firmware a chance to prepare for the reset. */
3267         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
3268         if (rc)
3269                 goto bce_reset_exit;
3270
3271         /* Set a firmware reminder that this is a soft reset. */
3272         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
3273                    BCE_DRV_RESET_SIGNATURE_MAGIC);
3274
3275         /* Dummy read to force the chip to complete all current transactions. */
3276         val = REG_RD(sc, BCE_MISC_ID);
3277
3278         /* Chip reset. */
3279         val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3280               BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
3281               BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
3282         REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
3283
3284         /* Allow up to 30us for reset to complete. */
3285         for (i = 0; i < 10; i++) {
3286                 val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
3287                 if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3288                             BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
3289                         break;
3290                 }
3291                 DELAY(10);
3292         }
3293
3294         /* Check that reset completed successfully. */
3295         if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3296                    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
3297                 BCE_PRINTF(sc, "%s(%d): Reset failed!\n", 
3298                         __FILE__, __LINE__);
3299                 rc = EBUSY;
3300                 goto bce_reset_exit;
3301         }
3302
3303         /* Make sure byte swapping is properly configured. */
3304         val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
3305         if (val != 0x01020304) {
3306                 BCE_PRINTF(sc, "%s(%d): Byte swap is incorrect!\n", 
3307                         __FILE__, __LINE__);
3308                 rc = ENODEV;
3309                 goto bce_reset_exit;
3310         }
3311
3312         /* Just completed a reset, assume that firmware is running again. */
3313         sc->bce_fw_timed_out = 0;
3314
3315         /* Wait for the firmware to finish its initialization. */
3316         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
3317         if (rc)
3318                 BCE_PRINTF(sc, "%s(%d): Firmware did not complete initialization!\n",
3319                         __FILE__, __LINE__);
3320
3321 bce_reset_exit:
3322         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3323
3324         return (rc);
3325 }
3326
3327
3328 static int
3329 bce_chipinit(struct bce_softc *sc)
3330 {
3331         u32 val;
3332         int rc = 0;
3333
3334         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3335
3336         /* Make sure the interrupt is not active. */
3337         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
3338
3339         /* Initialize DMA byte/word swapping, configure the number of DMA  */
3340         /* channels and PCI clock compensation delay.                      */
3341         val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
3342               BCE_DMA_CONFIG_DATA_WORD_SWAP |
3343 #if BYTE_ORDER == BIG_ENDIAN
3344               BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
3345 #endif
3346               BCE_DMA_CONFIG_CNTL_WORD_SWAP |
3347               DMA_READ_CHANS << 12 |
3348               DMA_WRITE_CHANS << 16;
3349
3350         val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
3351
3352         if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
3353                 val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
3354
3355         /*
3356          * This setting resolves a problem observed on certain Intel PCI
3357          * chipsets that cannot handle multiple outstanding DMA operations.
3358          * See errata E9_5706A1_65.
3359          */
3360         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
3361             (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
3362             !(sc->bce_flags & BCE_PCIX_FLAG))
3363                 val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
3364
3365         REG_WR(sc, BCE_DMA_CONFIG, val);
3366
3367         /* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
3368         if (sc->bce_flags & BCE_PCIX_FLAG) {
3369                 u16 val;
3370
3371                 val = pci_read_config(sc->bce_dev, BCE_PCI_PCIX_CMD, 2);
3372                 pci_write_config(sc->bce_dev, BCE_PCI_PCIX_CMD, val & ~0x2, 2);
3373         }
3374
3375         /* Enable the RX_V2P and Context state machines before access. */
3376         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
3377                BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
3378                BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
3379                BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
3380
3381         /* Initialize context mapping and zero out the quick contexts. */
3382         bce_init_context(sc);
3383
3384         /* Initialize the on-boards CPUs */
3385         bce_init_cpus(sc);
3386
3387         /* Prepare NVRAM for access. */
3388         if (bce_init_nvram(sc)) {
3389                 rc = ENODEV;
3390                 goto bce_chipinit_exit;
3391         }
3392
3393         /* Set the kernel bypass block size */
3394         val = REG_RD(sc, BCE_MQ_CONFIG);
3395         val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
3396         val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
3397         REG_WR(sc, BCE_MQ_CONFIG, val);
3398
3399         val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
3400         REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
3401         REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
3402
3403         val = (BCM_PAGE_BITS - 8) << 24;
3404         REG_WR(sc, BCE_RV2P_CONFIG, val);
3405
3406         /* Configure page size. */
3407         val = REG_RD(sc, BCE_TBDR_CONFIG);
3408         val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
3409         val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
3410         REG_WR(sc, BCE_TBDR_CONFIG, val);
3411
3412 bce_chipinit_exit:
3413         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3414
3415         return(rc);
3416 }
3417
3418
3419 /****************************************************************************/
3420 /* Initialize the controller in preparation to send/receive traffic.        */
3421 /*                                                                          */
3422 /* Returns:                                                                 */
3423 /*   0 for success, positive value for failure.                             */
3424 /****************************************************************************/
3425 static int
3426 bce_blockinit(struct bce_softc *sc)
3427 {
3428         u32 reg, val;
3429         int rc = 0;
3430
3431         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3432
3433         /* Load the hardware default MAC address. */
3434         bce_set_mac_addr(sc);
3435
3436         /* Set the Ethernet backoff seed value */
3437         val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
3438               (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
3439               (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
3440         REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
3441
3442         sc->last_status_idx = 0;
3443         sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
3444
3445         /* Set up link change interrupt generation. */
3446         REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
3447
3448         /* Program the physical address of the status block. */
3449         REG_WR(sc, BCE_HC_STATUS_ADDR_L,
3450                 BCE_ADDR_LO(sc->status_block_paddr));
3451         REG_WR(sc, BCE_HC_STATUS_ADDR_H,
3452                 BCE_ADDR_HI(sc->status_block_paddr));
3453
3454         /* Program the physical address of the statistics block. */
3455         REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
3456                 BCE_ADDR_LO(sc->stats_block_paddr));
3457         REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
3458                 BCE_ADDR_HI(sc->stats_block_paddr));
3459
3460         /* Program various host coalescing parameters. */
3461         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
3462                 (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
3463         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
3464                 (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
3465         REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
3466                 (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
3467         REG_WR(sc, BCE_HC_TX_TICKS,
3468                 (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
3469         REG_WR(sc, BCE_HC_RX_TICKS,
3470                 (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
3471         REG_WR(sc, BCE_HC_COM_TICKS,
3472                 (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
3473         REG_WR(sc, BCE_HC_CMD_TICKS,
3474                 (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
3475         REG_WR(sc, BCE_HC_STATS_TICKS,
3476                 (sc->bce_stats_ticks & 0xffff00));
3477         REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS,
3478                 0xbb8);  /* 3ms */
3479         REG_WR(sc, BCE_HC_CONFIG,
3480                 (BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
3481                 BCE_HC_CONFIG_COLLECT_STATS));
3482
3483         /* Clear the internal statistics counters. */
3484         REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
3485
3486         /* Verify that bootcode is running. */
3487         reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
3488
3489         DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure),
3490                 BCE_PRINTF(sc, "%s(%d): Simulating bootcode failure.\n",
3491                         __FILE__, __LINE__);
3492                 reg = 0);
3493
3494         if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
3495             BCE_DEV_INFO_SIGNATURE_MAGIC) {
3496                 BCE_PRINTF(sc, "%s(%d): Bootcode not running! Found: 0x%08X, "
3497                         "Expected: 08%08X\n", __FILE__, __LINE__,
3498                         (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
3499                         BCE_DEV_INFO_SIGNATURE_MAGIC);
3500                 rc = ENODEV;
3501                 goto bce_blockinit_exit;
3502         }
3503
3504         /* Check if any management firmware is running. */
3505         reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
3506         if (reg & (BCE_PORT_FEATURE_ASF_ENABLED | BCE_PORT_FEATURE_IMD_ENABLED)) {
3507                 DBPRINT(sc, BCE_INFO, "Management F/W Enabled.\n");
3508                 sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
3509         }
3510
3511         sc->bce_fw_ver = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_BC_REV);
3512         DBPRINT(sc, BCE_INFO, "bootcode rev = 0x%08X\n", sc->bce_fw_ver);
3513
3514         /* Allow bootcode to apply any additional fixes before enabling MAC. */
3515         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
3516
3517         /* Enable link state change interrupt generation. */
3518         REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
3519
3520         /* Enable all remaining blocks in the MAC. */
3521         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 0x5ffffff);
3522         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
3523         DELAY(20);
3524
3525 bce_blockinit_exit:
3526         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3527
3528         return (rc);
3529 }
3530
3531
3532 /****************************************************************************/
3533 /* Encapsulate an mbuf cluster into the rx_bd chain.                        */
3534 /*                                                                          */
3535 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's.     */
3536 /* This routine will map an mbuf cluster into 1 or more rx_bd's as          */
3537 /* necessary.                                                               */
3538 /*                                                                          */
3539 /* Returns:                                                                 */
3540 /*   0 for success, positive value for failure.                             */
3541 /****************************************************************************/
3542 static int
3543 bce_get_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, u16 *chain_prod, 
3544         u32 *prod_bseq)
3545 {
3546         bus_dmamap_t            map;
3547         bus_dma_segment_t       segs[4];
3548         struct mbuf *m_new = NULL;
3549         struct rx_bd            *rxbd;
3550         int i, nsegs, error, rc = 0;
3551 #ifdef BCE_DEBUG
3552         u16 debug_chain_prod = *chain_prod;
3553 #endif
3554
3555         DBPRINT(sc, (BCE_VERBOSE_RESET | BCE_VERBOSE_RECV), "Entering %s()\n", 
3556                 __FUNCTION__);
3557
3558         /* Make sure the inputs are valid. */
3559         DBRUNIF((*chain_prod > MAX_RX_BD),
3560                 BCE_PRINTF(sc, "%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
3561                 __FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
3562
3563         DBPRINT(sc, BCE_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
3564                 "prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
3565
3566         if (m == NULL) {
3567
3568                 DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
3569                         BCE_PRINTF(sc, "%s(%d): Simulating mbuf allocation failure.\n", 
3570                                 __FILE__, __LINE__);
3571                         sc->mbuf_alloc_failed++;
3572                         rc = ENOBUFS;
3573                         goto bce_get_buf_exit);
3574
3575                 /* This is a new mbuf allocation. */
3576                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
3577                 if (m_new == NULL) {
3578
3579                         DBPRINT(sc, BCE_WARN, "%s(%d): RX mbuf header allocation failed!\n", 
3580                                 __FILE__, __LINE__);
3581
3582                         DBRUNIF(1, sc->mbuf_alloc_failed++);
3583
3584                         rc = ENOBUFS;
3585                         goto bce_get_buf_exit;
3586                 }
3587
3588                 DBRUNIF(1, sc->rx_mbuf_alloc++);
3589                 m_cljget(m_new, M_DONTWAIT, sc->mbuf_alloc_size);
3590                 if (!(m_new->m_flags & M_EXT)) {
3591
3592                         DBPRINT(sc, BCE_WARN, "%s(%d): RX mbuf chain allocation failed!\n", 
3593                                 __FILE__, __LINE__);
3594                         
3595                         m_freem(m_new);
3596
3597                         DBRUNIF(1, sc->rx_mbuf_alloc--);
3598                         DBRUNIF(1, sc->mbuf_alloc_failed++);
3599
3600                         rc = ENOBUFS;
3601                         goto bce_get_buf_exit;
3602                 }
3603                         
3604                 m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
3605         } else {
3606                 m_new = m;
3607                 m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
3608                 m_new->m_data = m_new->m_ext.ext_buf;
3609         }
3610
3611         /* Map the mbuf cluster into device memory. */
3612         map = sc->rx_mbuf_map[*chain_prod];
3613         error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
3614             segs, &nsegs, BUS_DMA_NOWAIT);
3615
3616         if (error) {
3617                 BCE_PRINTF(sc, "%s(%d): Error mapping mbuf into RX chain!\n",
3618                         __FILE__, __LINE__);
3619
3620                 m_freem(m_new);
3621
3622                 DBRUNIF(1, sc->rx_mbuf_alloc--);
3623
3624                 rc = ENOBUFS;
3625                 goto bce_get_buf_exit;
3626         }
3627
3628         /* Watch for overflow. */
3629         DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
3630                 BCE_PRINTF(sc, "%s(%d): Too many free rx_bd (0x%04X > 0x%04X)!\n", 
3631                         __FILE__, __LINE__, sc->free_rx_bd, (u16) USABLE_RX_BD));
3632
3633         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark), 
3634                 sc->rx_low_watermark = sc->free_rx_bd);
3635
3636         /* Setup the rx_bd for the first segment. */
3637         rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3638
3639         rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
3640         rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
3641         rxbd->rx_bd_len       = htole32(segs[0].ds_len);
3642         rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START);
3643         *prod_bseq += segs[0].ds_len;
3644
3645         for (i = 1; i < nsegs; i++) {
3646
3647                 *prod = NEXT_RX_BD(*prod);
3648                 *chain_prod = RX_CHAIN_IDX(*prod); 
3649
3650                 rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3651
3652                 rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[i].ds_addr));
3653                 rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[i].ds_addr));
3654                 rxbd->rx_bd_len       = htole32(segs[i].ds_len);
3655                 rxbd->rx_bd_flags     = 0;
3656                 *prod_bseq += segs[i].ds_len;
3657         }
3658
3659         rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END);
3660
3661         /* Save the mbuf and update our counter. */
3662         sc->rx_mbuf_ptr[*chain_prod] = m_new;
3663         sc->free_rx_bd -= nsegs;
3664
3665         DBRUN(BCE_VERBOSE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod, 
3666                 nsegs));
3667
3668         DBPRINT(sc, BCE_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
3669                 "prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
3670
3671 bce_get_buf_exit:
3672         DBPRINT(sc, (BCE_VERBOSE_RESET | BCE_VERBOSE_RECV), "Exiting %s()\n", 
3673                 __FUNCTION__);
3674
3675         return(rc);
3676 }
3677
3678
3679 /****************************************************************************/
3680 /* Allocate memory and initialize the TX data structures.                   */
3681 /*                                                                          */
3682 /* Returns:                                                                 */
3683 /*   0 for success, positive value for failure.                             */
3684 /****************************************************************************/
3685 static int
3686 bce_init_tx_chain(struct bce_softc *sc)
3687 {
3688         struct tx_bd *txbd;
3689         u32 val;
3690         int i, rc = 0;
3691
3692         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3693
3694         /* Set the initial TX producer/consumer indices. */
3695         sc->tx_prod        = 0;
3696         sc->tx_cons        = 0;
3697         sc->tx_prod_bseq   = 0;
3698         sc->used_tx_bd = 0;
3699         DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD);
3700
3701         /*
3702          * The NetXtreme II supports a linked-list structre called
3703          * a Buffer Descriptor Chain (or BD chain).  A BD chain
3704          * consists of a series of 1 or more chain pages, each of which
3705          * consists of a fixed number of BD entries.
3706          * The last BD entry on each page is a pointer to the next page
3707          * in the chain, and the last pointer in the BD chain
3708          * points back to the beginning of the chain.
3709          */
3710
3711         /* Set the TX next pointer chain entries. */
3712         for (i = 0; i < TX_PAGES; i++) {
3713                 int j;
3714
3715                 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
3716
3717                 /* Check if we've reached the last page. */
3718                 if (i == (TX_PAGES - 1))
3719                         j = 0;
3720                 else
3721                         j = i + 1;
3722
3723                 txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
3724                 txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
3725         }
3726
3727         /*
3728          * Initialize the context ID for an L2 TX chain.
3729          */
3730         val = BCE_L2CTX_TYPE_TYPE_L2;
3731         val |= BCE_L2CTX_TYPE_SIZE_L2;
3732         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TYPE, val);
3733
3734         val = BCE_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
3735         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_CMD_TYPE, val);
3736
3737         /* Point the hardware to the first page in the chain. */
3738         val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
3739         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_HI, val);
3740         val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
3741         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_LO, val);
3742
3743         DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
3744
3745         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3746
3747         return(rc);
3748 }
3749
3750
3751 /****************************************************************************/
3752 /* Free memory and clear the TX data structures.                            */
3753 /*                                                                          */
3754 /* Returns:                                                                 */
3755 /*   Nothing.                                                               */
3756 /****************************************************************************/
3757 static void
3758 bce_free_tx_chain(struct bce_softc *sc)
3759 {
3760         int i;
3761
3762         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3763
3764         /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
3765         for (i = 0; i < TOTAL_TX_BD; i++) {
3766                 if (sc->tx_mbuf_ptr[i] != NULL) {
3767                         if (sc->tx_mbuf_map != NULL)
3768                                 bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
3769                                         BUS_DMASYNC_POSTWRITE);
3770                         m_freem(sc->tx_mbuf_ptr[i]);
3771                         sc->tx_mbuf_ptr[i] = NULL;
3772                         DBRUNIF(1, sc->tx_mbuf_alloc--);
3773                 }                       
3774         }
3775
3776         /* Clear each TX chain page. */
3777         for (i = 0; i < TX_PAGES; i++)
3778                 bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
3779
3780         /* Check if we lost any mbufs in the process. */
3781         DBRUNIF((sc->tx_mbuf_alloc),
3782                 BCE_PRINTF(sc, "%s(%d): Memory leak! Lost %d mbufs "
3783                         "from tx chain!\n",
3784                         __FILE__, __LINE__, sc->tx_mbuf_alloc));
3785
3786         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3787 }
3788
3789
3790 /****************************************************************************/
3791 /* Allocate memory and initialize the RX data structures.                   */
3792 /*                                                                          */
3793 /* Returns:                                                                 */
3794 /*   0 for success, positive value for failure.                             */
3795 /****************************************************************************/
3796 static int
3797 bce_init_rx_chain(struct bce_softc *sc)
3798 {
3799         struct rx_bd *rxbd;
3800         int i, rc = 0;
3801         u16 prod, chain_prod;
3802         u32 prod_bseq, val;
3803
3804         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3805
3806         /* Initialize the RX producer and consumer indices. */
3807         sc->rx_prod        = 0;
3808         sc->rx_cons        = 0;
3809         sc->rx_prod_bseq   = 0;
3810         sc->free_rx_bd     = BCE_RX_SLACK_SPACE;
3811         DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
3812
3813         /* Initialize the RX next pointer chain entries. */
3814         for (i = 0; i < RX_PAGES; i++) {
3815                 int j;
3816
3817                 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
3818
3819                 /* Check if we've reached the last page. */
3820                 if (i == (RX_PAGES - 1))
3821                         j = 0;
3822                 else
3823                         j = i + 1;
3824
3825                 /* Setup the chain page pointers. */
3826                 rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
3827                 rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
3828         }
3829
3830         /* Initialize the context ID for an L2 RX chain. */
3831         val = BCE_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
3832         val |= BCE_L2CTX_CTX_TYPE_SIZE_L2;
3833         val |= 0x02 << 8;
3834         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_CTX_TYPE, val);
3835
3836         /* Point the hardware to the first page in the chain. */
3837         val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
3838         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_HI, val);
3839         val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
3840         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_LO, val);
3841
3842         /* Allocate mbuf clusters for the rx_bd chain. */
3843         prod = prod_bseq = 0;
3844         while (prod < BCE_RX_SLACK_SPACE) {
3845                 chain_prod = RX_CHAIN_IDX(prod);
3846                 if (bce_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
3847                         BCE_PRINTF(sc, "%s(%d): Error filling RX chain: rx_bd[0x%04X]!\n",
3848                                 __FILE__, __LINE__, chain_prod);
3849                         rc = ENOBUFS;
3850                         break;
3851                 }
3852                 prod = NEXT_RX_BD(prod);
3853         }
3854
3855         /* Save the RX chain producer index. */
3856         sc->rx_prod      = prod;
3857         sc->rx_prod_bseq = prod_bseq;
3858
3859         for (i = 0; i < RX_PAGES; i++) {
3860                 bus_dmamap_sync(
3861                         sc->rx_bd_chain_tag,
3862                 sc->rx_bd_chain_map[i],
3863                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3864         }
3865
3866         /* Tell the chip about the waiting rx_bd's. */
3867         REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
3868         REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3869
3870         DBRUN(BCE_VERBOSE_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
3871
3872         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3873
3874         return(rc);
3875 }
3876
3877
3878 /****************************************************************************/
3879 /* Free memory and clear the RX data structures.                            */
3880 /*                                                                          */
3881 /* Returns:                                                                 */
3882 /*   Nothing.                                                               */
3883 /****************************************************************************/
3884 static void
3885 bce_free_rx_chain(struct bce_softc *sc)
3886 {
3887         int i;
3888
3889         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3890
3891         /* Free any mbufs still in the RX mbuf chain. */
3892         for (i = 0; i < TOTAL_RX_BD; i++) {
3893                 if (sc->rx_mbuf_ptr[i] != NULL) {
3894                         if (sc->rx_mbuf_map[i] != NULL)
3895                                 bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
3896                                         BUS_DMASYNC_POSTREAD);
3897                         m_freem(sc->rx_mbuf_ptr[i]);
3898                         sc->rx_mbuf_ptr[i] = NULL;
3899                         DBRUNIF(1, sc->rx_mbuf_alloc--);
3900                 }
3901         }
3902
3903         /* Clear each RX chain page. */
3904         for (i = 0; i < RX_PAGES; i++)
3905                 bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3906
3907         /* Check if we lost any mbufs in the process. */
3908         DBRUNIF((sc->rx_mbuf_alloc),
3909                 BCE_PRINTF(sc, "%s(%d): Memory leak! Lost %d mbufs from rx chain!\n",
3910                         __FILE__, __LINE__, sc->rx_mbuf_alloc));
3911
3912         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3913 }
3914
3915
3916 /****************************************************************************/
3917 /* Set media options.                                                       */
3918 /*                                                                          */
3919 /* Returns:                                                                 */
3920 /*   0 for success, positive value for failure.                             */
3921 /****************************************************************************/
3922 static int
3923 bce_ifmedia_upd(struct ifnet *ifp)
3924 {
3925         struct bce_softc *sc;
3926         struct mii_data *mii;
3927         struct ifmedia *ifm;
3928         int rc = 0;
3929
3930         sc = ifp->if_softc;
3931         ifm = &sc->bce_ifmedia;
3932
3933         /* DRC - ToDo: Add SerDes support. */
3934
3935         mii = device_get_softc(sc->bce_miibus);
3936         sc->bce_link = 0;
3937         if (mii->mii_instance) {
3938                 struct mii_softc *miisc;
3939                 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
3940                     miisc = LIST_NEXT(miisc, mii_list))
3941                         mii_phy_reset(miisc);
3942         }
3943         mii_mediachg(mii);
3944
3945         return(rc);
3946 }
3947
3948
3949 /****************************************************************************/
3950 /* Reports current media status.                                            */
3951 /*                                                                          */
3952 /* Returns:                                                                 */
3953 /*   Nothing.                                                               */
3954 /****************************************************************************/
3955 static void
3956 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
3957 {
3958         struct bce_softc *sc;
3959         struct mii_data *mii;
3960
3961         sc = ifp->if_softc;
3962
3963         BCE_LOCK(sc);
3964
3965         mii = device_get_softc(sc->bce_miibus);
3966
3967         /* DRC - ToDo: Add SerDes support. */
3968
3969         mii_pollstat(mii);
3970         ifmr->ifm_active = mii->mii_media_active;
3971         ifmr->ifm_status = mii->mii_media_status;
3972
3973         BCE_UNLOCK(sc);
3974 }
3975
3976
3977 /****************************************************************************/
3978 /* Handles PHY generated interrupt events.                                  */
3979 /*                                                                          */
3980 /* Returns:                                                                 */
3981 /*   Nothing.                                                               */
3982 /****************************************************************************/
3983 static void
3984 bce_phy_intr(struct bce_softc *sc)
3985 {
3986         u32 new_link_state, old_link_state;
3987
3988         new_link_state = sc->status_block->status_attn_bits &
3989                 STATUS_ATTN_BITS_LINK_STATE;
3990         old_link_state = sc->status_block->status_attn_bits_ack &
3991                 STATUS_ATTN_BITS_LINK_STATE;
3992
3993         /* Handle any changes if the link state has changed. */
3994         if (new_link_state != old_link_state) {
3995
3996                 DBRUN(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
3997
3998                 sc->bce_link = 0;
3999                 callout_stop(&sc->bce_stat_ch);
4000                 bce_tick_locked(sc);
4001
4002                 /* Update the status_attn_bits_ack field in the status block. */
4003                 if (new_link_state) {
4004                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
4005                                 STATUS_ATTN_BITS_LINK_STATE);
4006                         DBPRINT(sc, BCE_INFO, "Link is now UP.\n");
4007                 }
4008                 else {
4009                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
4010                                 STATUS_ATTN_BITS_LINK_STATE);
4011                         DBPRINT(sc, BCE_INFO, "Link is now DOWN.\n");
4012                 }
4013
4014         }
4015
4016         /* Acknowledge the link change interrupt. */
4017         REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
4018 }
4019
4020
4021 /****************************************************************************/
4022 /* Handles received frame interrupt events.                                 */
4023 /*                                                                          */
4024 /* Returns:                                                                 */
4025 /*   Nothing.                                                               */
4026 /****************************************************************************/
4027 static void
4028 bce_rx_intr(struct bce_softc *sc)
4029 {
4030         struct status_block *sblk = sc->status_block;
4031         struct ifnet *ifp = sc->bce_ifp;
4032         u16 hw_cons, sw_cons, sw_chain_cons, sw_prod, sw_chain_prod;
4033         u32 sw_prod_bseq;
4034         struct l2_fhdr *l2fhdr;
4035
4036         DBRUNIF(1, sc->rx_interrupts++);
4037
4038         /* Prepare the RX chain pages to be accessed by the host CPU. */
4039         for (int i = 0; i < RX_PAGES; i++)
4040                 bus_dmamap_sync(sc->rx_bd_chain_tag,
4041                     sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
4042
4043         /* Get the hardware's view of the RX consumer index. */
4044         hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
4045         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
4046                 hw_cons++;
4047
4048         /* Get working copies of the driver's view of the RX indices. */
4049         sw_cons = sc->rx_cons;
4050         sw_prod = sc->rx_prod;
4051         sw_prod_bseq = sc->rx_prod_bseq;
4052
4053         DBPRINT(sc, BCE_INFO_RECV, "%s(enter): sw_prod = 0x%04X, "
4054                 "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
4055                 __FUNCTION__, sw_prod, sw_cons, 
4056                 sw_prod_bseq);
4057
4058         /* Prevent speculative reads from getting ahead of the status block. */
4059         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 
4060                 BUS_SPACE_BARRIER_READ);
4061
4062         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
4063                 sc->rx_low_watermark = sc->free_rx_bd);
4064
4065         /* 
4066          * Scan through the receive chain as long 
4067          * as there is work to do.
4068          */
4069         while (sw_cons != hw_cons) {
4070                 struct mbuf *m;
4071                 struct rx_bd *rxbd;
4072                 unsigned int len;
4073                 u32 status;
4074
4075                 /* Convert the producer/consumer indices to an actual rx_bd index. */
4076                 sw_chain_cons = RX_CHAIN_IDX(sw_cons);
4077                 sw_chain_prod = RX_CHAIN_IDX(sw_prod);
4078
4079                 /* Get the used rx_bd. */
4080                 rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)][RX_IDX(sw_chain_cons)];
4081                 sc->free_rx_bd++;
4082         
4083                 DBRUN(BCE_VERBOSE_RECV, 
4084                         BCE_PRINTF(sc, "%s(): ", __FUNCTION__); 
4085                         bce_dump_rxbd(sc, sw_chain_cons, rxbd));
4086
4087 #ifdef DEVICE_POLLING
4088                 if (ifp->if_capenable & IFCAP_POLLING) {
4089                         if (sc->bce_rxcycles <= 0)
4090                                 break;
4091                         sc->rxcycles--;
4092                 }
4093 #endif
4094
4095                 /* The mbuf is stored with the last rx_bd entry of a packet. */
4096                 if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) {
4097
4098                         /* Validate that this is the last rx_bd. */
4099                         DBRUNIF((!(rxbd->rx_bd_flags & RX_BD_FLAGS_END)),
4100                                 BCE_PRINTF(sc, "%s(%d): Unexpected mbuf found in rx_bd[0x%04X]!\n",
4101                                 __FILE__, __LINE__, sw_chain_cons);
4102                                 bce_breakpoint(sc));
4103
4104                         /* DRC - ToDo: If the received packet is small, say less */
4105                         /*             than 128 bytes, allocate a new mbuf here, */
4106                         /*             copy the data to that mbuf, and recycle   */
4107                         /*             the mapped jumbo frame.                   */
4108
4109                         /* Unmap the mbuf from DMA space. */
4110                         bus_dmamap_sync(sc->rx_mbuf_tag, 
4111                             sc->rx_mbuf_map[sw_chain_cons],
4112                         BUS_DMASYNC_POSTREAD);
4113                         bus_dmamap_unload(sc->rx_mbuf_tag,
4114                             sc->rx_mbuf_map[sw_chain_cons]);
4115
4116                         /* Remove the mbuf from the driver's chain. */
4117                         m = sc->rx_mbuf_ptr[sw_chain_cons];
4118                         sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
4119
4120                         /*
4121                          * Frames received on the NetXteme II are prepended 
4122                          * with the l2_fhdr structure which provides status
4123                          * information about the received frame (including
4124                          * VLAN tags and checksum info) and are also
4125                          * automatically adjusted to align the IP header
4126                          * (i.e. two null bytes are inserted before the 
4127                          * Ethernet header).
4128                          */
4129                         l2fhdr = mtod(m, struct l2_fhdr *);
4130
4131                         len    = l2fhdr->l2_fhdr_pkt_len;
4132                         status = l2fhdr->l2_fhdr_status;
4133
4134                         DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check),
4135                                 BCE_PRINTF(sc, "Simulating l2_fhdr status error.\n");
4136                                 status = status | L2_FHDR_ERRORS_PHY_DECODE);
4137
4138                         /* Watch for unusual sized frames. */
4139                         DBRUNIF(((len < BCE_MIN_MTU) || (len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
4140                                 BCE_PRINTF(sc, "%s(%d): Unusual frame size found. "
4141                                         "Min(%d), Actual(%d), Max(%d)\n", 
4142                                         __FILE__, __LINE__, (int) BCE_MIN_MTU, 
4143                                         len, (int) BCE_MAX_JUMBO_ETHER_MTU_VLAN);
4144                                 bce_dump_mbuf(sc, m);
4145                                 bce_breakpoint(sc));
4146
4147                         len -= ETHER_CRC_LEN;
4148
4149                         /* Check the received frame for errors. */
4150                         if (status &  (L2_FHDR_ERRORS_BAD_CRC | 
4151                                 L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT | 
4152                                 L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
4153
4154                                 ifp->if_ierrors++;
4155                                 DBRUNIF(1, sc->l2fhdr_status_errors++);
4156
4157                                 /* Reuse the mbuf for a new frame. */
4158                                 if (bce_get_buf(sc, m, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4159
4160                                         DBRUNIF(1, bce_breakpoint(sc));
4161                                         panic("bce%d: Can't reuse RX mbuf!\n", sc->bce_unit);
4162
4163                                 }
4164                                 goto bce_rx_int_next_rx;
4165                         }
4166
4167                         /* 
4168                          * Get a new mbuf for the rx_bd.   If no new
4169                          * mbufs are available then reuse the current mbuf,
4170                          * log an ierror on the interface, and generate
4171                          * an error in the system log.
4172                          */
4173                         if (bce_get_buf(sc, NULL, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4174
4175                                 DBRUN(BCE_WARN, 
4176                                         BCE_PRINTF(sc, "%s(%d): Failed to allocate "
4177                                         "new mbuf, incoming frame dropped!\n", 
4178                                         __FILE__, __LINE__));
4179
4180                                 ifp->if_ierrors++;
4181
4182                                 /* Try and reuse the exisitng mbuf. */
4183                                 if (bce_get_buf(sc, m, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4184
4185                                         DBRUNIF(1, bce_breakpoint(sc));
4186                                         panic("bce%d: Double mbuf allocation failure!", sc->bce_unit);
4187
4188                                 }
4189                                 goto bce_rx_int_next_rx;
4190                         }
4191
4192                         /* Skip over the l2_fhdr when passing the data up the stack. */
4193                         m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN);
4194
4195                         /* Adjust the packet length to match the received data. */
4196                         m->m_pkthdr.len = m->m_len = len;
4197
4198                         /* Send the packet to the appropriate interface. */
4199                         m->m_pkthdr.rcvif = ifp;
4200
4201                         DBRUN(BCE_VERBOSE_RECV,
4202                                 struct ether_header *eh;
4203                                 eh = mtod(m, struct ether_header *);
4204                                 BCE_PRINTF(sc, "%s(): to: %6D, from: %6D, type: 0x%04X\n",
4205                                         __FUNCTION__, eh->ether_dhost, ":", 
4206                                         eh->ether_shost, ":", htons(eh->ether_type)));
4207
4208                         /* Validate the checksum if offload enabled. */
4209                         if (ifp->if_capenable & IFCAP_RXCSUM) {
4210
4211                                 /* Check for an IP datagram. */
4212                                 if (status & L2_FHDR_STATUS_IP_DATAGRAM) {
4213                                         m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
4214
4215                                         /* Check if the IP checksum is valid. */
4216                                         if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
4217                                                 m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
4218                                         else
4219                                                 DBPRINT(sc, BCE_WARN_SEND, 
4220                                                         "%s(): Invalid IP checksum = 0x%04X!\n",
4221                                                         __FUNCTION__, l2fhdr->l2_fhdr_ip_xsum);
4222                                 }
4223
4224                                 /* Check for a valid TCP/UDP frame. */
4225                                 if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
4226                                         L2_FHDR_STATUS_UDP_DATAGRAM)) {
4227
4228                                         /* Check for a good TCP/UDP checksum. */
4229                                         if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
4230                                                       L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
4231                                                 m->m_pkthdr.csum_data =
4232                                                     l2fhdr->l2_fhdr_tcp_udp_xsum;
4233                                                 m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID 
4234                                                         | CSUM_PSEUDO_HDR);
4235                                         } else
4236                                                 DBPRINT(sc, BCE_WARN_SEND, 
4237                                                         "%s(): Invalid TCP/UDP checksum = 0x%04X!\n",
4238                                                         __FUNCTION__, l2fhdr->l2_fhdr_tcp_udp_xsum);
4239                                 }
4240                         }               
4241
4242
4243                         /*
4244                          * If we received a packet with a vlan tag,
4245                          * attach that information to the packet.
4246                          */
4247                         if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
4248                                 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): VLAN tag = 0x%04X\n",
4249                                         __FUNCTION__, l2fhdr->l2_fhdr_vlan_tag);
4250 #if __FreeBSD_version < 700000
4251                                 VLAN_INPUT_TAG(ifp, m, l2fhdr->l2_fhdr_vlan_tag, continue);
4252 #else
4253                                 VLAN_INPUT_TAG(ifp, m, l2fhdr->l2_fhdr_vlan_tag);
4254                                 if (m == NULL)
4255                                         continue;
4256 #endif  
4257                         }
4258
4259                         /* Pass the mbuf off to the upper layers. */
4260                         ifp->if_ipackets++;
4261                         DBPRINT(sc, BCE_VERBOSE_RECV, "%s(): Passing received frame up.\n",
4262                                 __FUNCTION__);
4263                         BCE_UNLOCK(sc);
4264                         (*ifp->if_input)(ifp, m);
4265                         DBRUNIF(1, sc->rx_mbuf_alloc--);
4266                         BCE_LOCK(sc);
4267
4268 bce_rx_int_next_rx:
4269                         sw_prod = NEXT_RX_BD(sw_prod);
4270                 }
4271
4272                 sw_cons = NEXT_RX_BD(sw_cons);
4273
4274                 /* Refresh hw_cons to see if there's new work */
4275                 if (sw_cons == hw_cons) {
4276                         hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
4277                         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
4278                                 hw_cons++;
4279                 }
4280
4281                 /* Prevent speculative reads from getting ahead of the status block. */
4282                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 
4283                         BUS_SPACE_BARRIER_READ);
4284         }
4285
4286         for (int i = 0; i < RX_PAGES; i++)
4287                 bus_dmamap_sync(sc->rx_bd_chain_tag,
4288                     sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
4289
4290         sc->rx_cons = sw_cons;
4291         sc->rx_prod = sw_prod;
4292         sc->rx_prod_bseq = sw_prod_bseq;
4293
4294         REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
4295         REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
4296
4297         DBPRINT(sc, BCE_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
4298                 "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
4299                 __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
4300 }
4301
4302
4303 /****************************************************************************/
4304 /* Handles transmit completion interrupt events.                            */
4305 /*                                                                          */
4306 /* Returns:                                                                 */
4307 /*   Nothing.                                                               */
4308 /****************************************************************************/
4309 static void
4310 bce_tx_intr(struct bce_softc *sc)
4311 {
4312         struct status_block *sblk = sc->status_block;
4313         struct ifnet *ifp = sc->bce_ifp;
4314         u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
4315
4316         BCE_LOCK_ASSERT(sc);
4317
4318         DBRUNIF(1, sc->tx_interrupts++);
4319
4320         /* Get the hardware's view of the TX consumer index. */
4321         hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
4322
4323         /* Skip to the next entry if this is a chain page pointer. */
4324         if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
4325                 hw_tx_cons++;
4326
4327         sw_tx_cons = sc->tx_cons;
4328
4329         /* Prevent speculative reads from getting ahead of the status block. */
4330         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 
4331                 BUS_SPACE_BARRIER_READ);
4332
4333         /* Cycle through any completed TX chain page entries. */
4334         while (sw_tx_cons != hw_tx_cons) {
4335 #ifdef BCE_DEBUG
4336                 struct tx_bd *txbd = NULL;
4337 #endif
4338                 sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
4339
4340                 DBPRINT(sc, BCE_INFO_SEND,
4341                         "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
4342                         "sw_tx_chain_cons = 0x%04X\n",
4343                         __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
4344
4345                 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
4346                         BCE_PRINTF(sc, "%s(%d): TX chain consumer out of range! "
4347                                 " 0x%04X > 0x%04X\n",
4348                                 __FILE__, __LINE__, sw_tx_chain_cons, 
4349                                 (int) MAX_TX_BD);
4350                         bce_breakpoint(sc));
4351
4352                 DBRUNIF(1,
4353                         txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
4354                                 [TX_IDX(sw_tx_chain_cons)]);
4355                 
4356                 DBRUNIF((txbd == NULL),
4357                         BCE_PRINTF(sc, "%s(%d): Unexpected NULL tx_bd[0x%04X]!\n", 
4358                                 __FILE__, __LINE__, sw_tx_chain_cons);
4359                         bce_breakpoint(sc));
4360
4361                 DBRUN(BCE_INFO_SEND, 
4362                         BCE_PRINTF(sc, "%s(): ", __FUNCTION__);
4363                         bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
4364
4365                 /*
4366                  * Free the associated mbuf. Remember
4367                  * that only the last tx_bd of a packet
4368                  * has an mbuf pointer and DMA map.
4369                  */
4370                 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
4371
4372                         /* Validate that this is the last tx_bd. */
4373                         DBRUNIF((!(txbd->tx_bd_vlan_tag_flags & TX_BD_FLAGS_END)),
4374                                 BCE_PRINTF(sc, "%s(%d): tx_bd END flag not set but "
4375                                 "txmbuf == NULL!\n", __FILE__, __LINE__);
4376                                 bce_breakpoint(sc));
4377
4378                         DBRUN(BCE_INFO_SEND, 
4379                                 BCE_PRINTF(sc, "%s(): Unloading map/freeing mbuf "
4380                                         "from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
4381
4382                         /* Unmap the mbuf. */
4383                         bus_dmamap_unload(sc->tx_mbuf_tag,
4384                             sc->tx_mbuf_map[sw_tx_chain_cons]);
4385         
4386                         /* Free the mbuf. */
4387                         m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
4388                         sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
4389                         DBRUNIF(1, sc->tx_mbuf_alloc--);
4390
4391                         ifp->if_opackets++;
4392                 }
4393
4394                 sc->used_tx_bd--;
4395                 sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
4396
4397                 /* Refresh hw_cons to see if there's new work. */
4398                 hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
4399                 if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
4400                         hw_tx_cons++;
4401
4402                 /* Prevent speculative reads from getting ahead of the status block. */
4403                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 
4404                         BUS_SPACE_BARRIER_READ);
4405         }
4406
4407         /* Clear the TX timeout timer. */
4408         ifp->if_timer = 0;
4409
4410         /* Clear the tx hardware queue full flag. */
4411         if ((sc->used_tx_bd + BCE_TX_SLACK_SPACE) < USABLE_TX_BD) {
4412                 DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
4413                         BCE_PRINTF(sc, "%s(): TX chain is open for business! Used tx_bd = %d\n", 
4414                                 __FUNCTION__, sc->used_tx_bd));
4415                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4416         }
4417
4418         sc->tx_cons = sw_tx_cons;
4419 }
4420
4421
4422 /****************************************************************************/
4423 /* Disables interrupt generation.                                           */
4424 /*                                                                          */
4425 /* Returns:                                                                 */
4426 /*   Nothing.                                                               */
4427 /****************************************************************************/
4428 static void
4429 bce_disable_intr(struct bce_softc *sc)
4430 {
4431         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4432                BCE_PCICFG_INT_ACK_CMD_MASK_INT);
4433         REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
4434 }
4435
4436
4437 /****************************************************************************/
4438 /* Enables interrupt generation.                                            */
4439 /*                                                                          */
4440 /* Returns:                                                                 */
4441 /*   Nothing.                                                               */
4442 /****************************************************************************/
4443 static void
4444 bce_enable_intr(struct bce_softc *sc)
4445 {
4446         u32 val;
4447
4448         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4449                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
4450                BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
4451
4452         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4453                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
4454
4455         val = REG_RD(sc, BCE_HC_COMMAND);
4456         REG_WR(sc, BCE_HC_COMMAND, val | BCE_HC_COMMAND_COAL_NOW);
4457 }
4458
4459
4460 /****************************************************************************/
4461 /* Handles controller initialization.                                       */
4462 /*                                                                          */
4463 /* Must be called from a locked routine.                                    */
4464 /*                                                                          */
4465 /* Returns:                                                                 */
4466 /*   Nothing.                                                               */
4467 /****************************************************************************/
4468 static void
4469 bce_init_locked(struct bce_softc *sc)
4470 {
4471         struct ifnet *ifp;
4472         u32 ether_mtu;
4473
4474         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
4475
4476         BCE_LOCK_ASSERT(sc);
4477
4478         ifp = sc->bce_ifp;
4479
4480         /* Check if the driver is still running and bail out if it is. */
4481         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
4482                 goto bce_init_locked_exit;
4483
4484         bce_stop(sc);
4485
4486         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
4487                 BCE_PRINTF(sc, "%s(%d): Controller reset failed!\n", 
4488                         __FILE__, __LINE__);
4489                 goto bce_init_locked_exit;
4490         }
4491
4492         if (bce_chipinit(sc)) {
4493                 BCE_PRINTF(sc, "%s(%d): Controller initialization failed!\n", 
4494                         __FILE__, __LINE__);
4495                 goto bce_init_locked_exit;
4496         }
4497
4498         if (bce_blockinit(sc)) {
4499                 BCE_PRINTF(sc, "%s(%d): Block initialization failed!\n", 
4500                         __FILE__, __LINE__);
4501                 goto bce_init_locked_exit;
4502         }
4503
4504         /* Load our MAC address. */
4505         bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
4506         bce_set_mac_addr(sc);
4507
4508         /* Calculate and program the Ethernet MTU size. */
4509         ether_mtu = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ifp->if_mtu + 
4510                 ETHER_CRC_LEN;
4511
4512         DBPRINT(sc, BCE_INFO, "%s(): setting mtu = %d\n",__FUNCTION__, ether_mtu);
4513
4514         /* 
4515          * Program the mtu, enabling jumbo frame 
4516          * support if necessary.  Also set the mbuf
4517          * allocation count for RX frames.
4518          */
4519         if (ether_mtu > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) {
4520                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu | 
4521                         BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
4522                 sc->mbuf_alloc_size = MJUM9BYTES;
4523         } else {
4524                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
4525                 sc->mbuf_alloc_size = MCLBYTES;
4526         }
4527
4528         /* Calculate the RX Ethernet frame size for rx_bd's. */
4529         sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8;
4530
4531         DBPRINT(sc, BCE_INFO, 
4532                 "%s(): mclbytes = %d, mbuf_alloc_size = %d, "
4533                 "max_frame_size = %d\n",
4534                 __FUNCTION__, (int) MCLBYTES, sc->mbuf_alloc_size, sc->max_frame_size);
4535
4536         /* Program appropriate promiscuous/multicast filtering. */
4537         bce_set_rx_mode(sc);
4538
4539         /* Init RX buffer descriptor chain. */
4540         bce_init_rx_chain(sc);
4541
4542         /* Init TX buffer descriptor chain. */
4543         bce_init_tx_chain(sc);
4544
4545 #ifdef DEVICE_POLLING
4546         /* Disable interrupts if we are polling. */
4547         if (ifp->if_capenable & IFCAP_POLLING) {
4548                 bce_disable_intr(sc);
4549
4550                 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4551                         (1 << 16) | sc->bce_rx_quick_cons_trip);
4552                 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4553                         (1 << 16) | sc->bce_tx_quick_cons_trip);
4554         } else
4555 #endif
4556         /* Enable host interrupts. */
4557         bce_enable_intr(sc);
4558
4559         bce_ifmedia_upd(ifp);
4560
4561         ifp->if_drv_flags |= IFF_DRV_RUNNING;
4562         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4563
4564         callout_reset(&sc->bce_stat_ch, hz, bce_tick, sc);
4565
4566 bce_init_locked_exit:
4567         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
4568
4569         return;
4570 }
4571
4572
4573 /****************************************************************************/
4574 /* Handles controller initialization when called from an unlocked routine.  */
4575 /*                                                                          */
4576 /* Returns:                                                                 */
4577 /*   Nothing.                                                               */
4578 /****************************************************************************/
4579 static void
4580 bce_init(void *xsc)
4581 {
4582         struct bce_softc *sc = xsc;
4583
4584         BCE_LOCK(sc);
4585         bce_init_locked(sc);
4586         BCE_UNLOCK(sc);
4587 }
4588
4589
4590 /****************************************************************************/
4591 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4592 /* memory visible to the controller.                                        */
4593 /*                                                                          */
4594 /* Returns:                                                                 */
4595 /*   0 for success, positive value for failure.                             */
4596 /****************************************************************************/
4597 static int
4598 bce_tx_encap(struct bce_softc *sc, struct mbuf *m_head, u16 *prod,
4599         u16 *chain_prod, u32 *prod_bseq)
4600 {
4601         u32 vlan_tag_flags = 0;
4602         struct m_tag *mtag;
4603         struct bce_dmamap_arg map_arg;
4604         bus_dmamap_t map;
4605         int i, error, rc = 0;
4606
4607         /* Transfer any checksum offload flags to the bd. */
4608         if (m_head->m_pkthdr.csum_flags) {
4609                 if (m_head->m_pkthdr.csum_flags & CSUM_IP)
4610                         vlan_tag_flags |= TX_BD_FLAGS_IP_CKSUM;
4611                 if (m_head->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
4612                         vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4613         }
4614
4615         /* Transfer any VLAN tags to the bd. */
4616         mtag = VLAN_OUTPUT_TAG(sc->bce_ifp, m_head);
4617         if (mtag != NULL)
4618                 vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG |
4619                         (VLAN_TAG_VALUE(mtag) << 16));
4620
4621         /* Map the mbuf into DMAable memory. */
4622         map = sc->tx_mbuf_map[*chain_prod];
4623         map_arg.sc         = sc;
4624         map_arg.prod       = *prod;
4625         map_arg.chain_prod = *chain_prod;
4626         map_arg.prod_bseq  = *prod_bseq;
4627         map_arg.tx_flags   = vlan_tag_flags;
4628         map_arg.maxsegs    = USABLE_TX_BD - sc->used_tx_bd - 
4629                 BCE_TX_SLACK_SPACE;
4630
4631         KASSERT(map_arg.maxsegs > 0, ("Invalid TX maxsegs value!"));
4632
4633         for (i = 0; i < TX_PAGES; i++)
4634                 map_arg.tx_chain[i] = sc->tx_bd_chain[i];
4635
4636         /* Map the mbuf into our DMA address space. */
4637         error = bus_dmamap_load_mbuf(sc->tx_mbuf_tag, map, m_head,
4638             bce_dma_map_tx_desc, &map_arg, BUS_DMA_NOWAIT);
4639
4640         if (error || map_arg.maxsegs == 0) {
4641                 BCE_PRINTF(sc, "%s(%d): Error mapping mbuf into TX chain!\n",
4642                         __FILE__, __LINE__);
4643                 rc = ENOBUFS;
4644                 goto bce_tx_encap_exit;
4645         }
4646
4647         /*
4648          * Ensure that the map for this transmission
4649          * is placed at the array index of the last
4650          * descriptor in this chain.  This is done
4651          * because a single map is used for all 
4652          * segments of the mbuf and we don't want to
4653          * delete the map before all of the segments
4654          * have been freed.
4655          */
4656         sc->tx_mbuf_map[*chain_prod] = 
4657                 sc->tx_mbuf_map[map_arg.chain_prod];
4658         sc->tx_mbuf_map[map_arg.chain_prod] = map;
4659         sc->tx_mbuf_ptr[map_arg.chain_prod] = m_head;
4660         sc->used_tx_bd += map_arg.maxsegs;
4661
4662         DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark), 
4663                 sc->tx_hi_watermark = sc->used_tx_bd);
4664
4665         DBRUNIF(1, sc->tx_mbuf_alloc++);
4666
4667         DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_mbuf_chain(sc, *chain_prod, 
4668                 map_arg.maxsegs));
4669
4670         /* prod still points the last used tx_bd at this point. */
4671         *prod       = map_arg.prod;
4672         *chain_prod = map_arg.chain_prod;
4673         *prod_bseq  = map_arg.prod_bseq;
4674
4675 bce_tx_encap_exit:
4676
4677         return(rc);
4678 }
4679
4680
4681 /****************************************************************************/
4682 /* Main transmit routine when called from another routine with a lock.      */
4683 /*                                                                          */
4684 /* Returns:                                                                 */
4685 /*   Nothing.                                                               */
4686 /****************************************************************************/
4687 static void
4688 bce_start_locked(struct ifnet *ifp)
4689 {
4690         struct bce_softc *sc = ifp->if_softc;
4691         struct mbuf *m_head = NULL;
4692         int count = 0;
4693         u16 tx_prod, tx_chain_prod;
4694         u32     tx_prod_bseq;
4695
4696         /* If there's no link or the transmit queue is empty then just exit. */
4697         if (!sc->bce_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
4698                 DBPRINT(sc, BCE_INFO_SEND, "%s(): No link or transmit queue empty.\n", 
4699                         __FUNCTION__);
4700                 goto bce_start_locked_exit;
4701         }
4702
4703         /* prod points to the next free tx_bd. */
4704         tx_prod = sc->tx_prod;
4705         tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4706         tx_prod_bseq = sc->tx_prod_bseq;
4707
4708         DBPRINT(sc, BCE_INFO_SEND,
4709                 "%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04X, "
4710                 "tx_prod_bseq = 0x%08X\n",
4711                 __FUNCTION__, tx_prod, tx_chain_prod, tx_prod_bseq);
4712
4713         /* Keep adding entries while there is space in the ring. */
4714         while(sc->tx_mbuf_ptr[tx_chain_prod] == NULL) {
4715
4716                 /* Check for any frames to send. */
4717                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
4718                 if (m_head == NULL)
4719                         break;
4720
4721                 /*
4722                  * Pack the data into the transmit ring. If we
4723                  * don't have room, place the mbuf back at the
4724                  * head of the queue and set the OACTIVE flag
4725                  * to wait for the NIC to drain the chain.
4726                  */
4727                 if (bce_tx_encap(sc, m_head, &tx_prod, &tx_chain_prod, &tx_prod_bseq)) {
4728                         IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
4729                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4730                         DBPRINT(sc, BCE_INFO_SEND,
4731                                 "TX chain is closed for business! Total tx_bd used = %d\n", 
4732                                 sc->used_tx_bd);
4733                         break;
4734                 }
4735
4736                 count++;
4737
4738                 /* Send a copy of the frame to any BPF listeners. */
4739                 BPF_MTAP(ifp, m_head);
4740
4741                 tx_prod = NEXT_TX_BD(tx_prod);
4742                 tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4743         }
4744
4745         if (count == 0) {
4746                 /* no packets were dequeued */
4747                 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n", 
4748                         __FUNCTION__);
4749                 goto bce_start_locked_exit;
4750         }
4751
4752         /* Update the driver's counters. */
4753         sc->tx_prod      = tx_prod;
4754         sc->tx_prod_bseq = tx_prod_bseq;
4755
4756         DBPRINT(sc, BCE_INFO_SEND,
4757                 "%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
4758                 "tx_prod_bseq = 0x%08X\n",
4759                 __FUNCTION__, tx_prod, tx_chain_prod, tx_prod_bseq);
4760
4761         /* Start the transmit. */
4762         REG_WR16(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4763         REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4764
4765         /* Set the tx timeout. */
4766         ifp->if_timer = BCE_TX_TIMEOUT;
4767
4768 bce_start_locked_exit:
4769         return;
4770 }
4771
4772
4773 /****************************************************************************/
4774 /* Main transmit routine when called from another routine without a lock.   */
4775 /*                                                                          */
4776 /* Returns:                                                                 */
4777 /*   Nothing.                                                               */
4778 /****************************************************************************/
4779 static void
4780 bce_start(struct ifnet *ifp)
4781 {
4782         struct bce_softc *sc = ifp->if_softc;
4783
4784         BCE_LOCK(sc);
4785         bce_start_locked(ifp);
4786         BCE_UNLOCK(sc);
4787 }
4788
4789
4790 /****************************************************************************/
4791 /* Handles any IOCTL calls from the operating system.                       */
4792 /*                                                                          */
4793 /* Returns:                                                                 */
4794 /*   0 for success, positive value for failure.                             */
4795 /****************************************************************************/
4796 static int
4797 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
4798 {
4799         struct bce_softc *sc = ifp->if_softc;
4800         struct ifreq *ifr = (struct ifreq *) data;
4801         struct mii_data *mii;
4802         int mask, error = 0;
4803
4804         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
4805
4806         switch(command) {
4807
4808                 /* Set the MTU. */
4809                 case SIOCSIFMTU:
4810                         /* Check that the MTU setting is supported. */
4811                         if ((ifr->ifr_mtu < BCE_MIN_MTU) || 
4812                                 (ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
4813                                 error = EINVAL;
4814                                 break;
4815                         }
4816
4817                         DBPRINT(sc, BCE_INFO, "Setting new MTU of %d\n", ifr->ifr_mtu);
4818
4819                         ifp->if_mtu = ifr->ifr_mtu;
4820                         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
4821                         bce_init(sc);
4822                         break;
4823
4824                 /* Set interface. */
4825                 case SIOCSIFFLAGS:
4826                         DBPRINT(sc, BCE_VERBOSE, "Received SIOCSIFFLAGS\n");
4827
4828                         BCE_LOCK(sc);
4829
4830                         /* Check if the interface is up. */
4831                         if (ifp->if_flags & IFF_UP) {
4832                                 /* Change the promiscuous/multicast flags as necessary. */
4833                                 bce_set_rx_mode(sc);
4834                         } else {
4835                                 /* The interface is down.  Check if the driver is running. */
4836                                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
4837                                         bce_stop(sc);
4838                                 }
4839                         }
4840
4841                         BCE_UNLOCK(sc);
4842                         error = 0;
4843
4844                         break;
4845
4846                 /* Add/Delete multicast address */
4847                 case SIOCADDMULTI:
4848                 case SIOCDELMULTI:
4849                         DBPRINT(sc, BCE_VERBOSE, "Received SIOCADDMULTI/SIOCDELMULTI\n");
4850
4851                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
4852                                 BCE_LOCK(sc);
4853                                 bce_set_rx_mode(sc);
4854                                 BCE_UNLOCK(sc);
4855                                 error = 0;
4856                         }
4857
4858                         break;
4859
4860                 /* Set/Get Interface media */
4861                 case SIOCSIFMEDIA:
4862                 case SIOCGIFMEDIA:
4863                         DBPRINT(sc, BCE_VERBOSE, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
4864
4865                         DBPRINT(sc, BCE_VERBOSE, "bce_phy_flags = 0x%08X\n",
4866                                 sc->bce_phy_flags);
4867
4868                         if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
4869                                 DBPRINT(sc, BCE_VERBOSE, "SerDes media set/get\n");
4870
4871                                 error = ifmedia_ioctl(ifp, ifr,
4872                                     &sc->bce_ifmedia, command);
4873                         } else {
4874                                 DBPRINT(sc, BCE_VERBOSE, "Copper media set/get\n");
4875                                 mii = device_get_softc(sc->bce_miibus);
4876                                 error = ifmedia_ioctl(ifp, ifr,
4877                                     &mii->mii_media, command);
4878                         }
4879                         break;
4880
4881                 /* Set interface capability */
4882                 case SIOCSIFCAP:
4883                         mask = ifr->ifr_reqcap ^ ifp->if_capenable;
4884                         DBPRINT(sc, BCE_INFO, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
4885
4886 #ifdef DEVICE_POLLING
4887                         if (mask & IFCAP_POLLING) {
4888                                 if (ifr->ifr_reqcap & IFCAP_POLLING) {
4889
4890                                         /* Setup the poll routine to call. */
4891                                         error = ether_poll_register(bce_poll, ifp);
4892                                         if (error) {
4893                                                 BCE_PRINTF(sc, "%s(%d): Error registering poll function!\n",
4894                                                         __FILE__, __LINE__);
4895                                                 goto bce_ioctl_exit;
4896                                         }
4897
4898                                         /* Clear the interrupt. */
4899                                         BCE_LOCK(sc);
4900                                         bce_disable_intr(sc);
4901
4902                                         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4903                                                 (1 << 16) | sc->bce_rx_quick_cons_trip);
4904                                         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4905                                                 (1 << 16) | sc->bce_tx_quick_cons_trip);
4906
4907                                         ifp->if_capenable |= IFCAP_POLLING;
4908                                         BCE_UNLOCK(sc);
4909                                 } else {
4910                                         /* Clear the poll routine. */
4911                                         error = ether_poll_deregister(ifp);
4912
4913                                         /* Enable interrupt even in error case */
4914                                         BCE_LOCK(sc);
4915                                         bce_enable_intr(sc);
4916
4917                                         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4918                                                 (sc->bce_tx_quick_cons_trip_int << 16) |
4919                                                 sc->bce_tx_quick_cons_trip);
4920                                         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4921                                                 (sc->bce_rx_quick_cons_trip_int << 16) |
4922                                                 sc->bce_rx_quick_cons_trip);
4923
4924                                         ifp->if_capenable &= ~IFCAP_POLLING;
4925                                         BCE_UNLOCK(sc);
4926                                 }
4927                         }
4928 #endif /*DEVICE_POLLING */
4929
4930                         /* Toggle the TX checksum capabilites enable flag. */                                           
4931                         if (mask & IFCAP_TXCSUM) {
4932                                 ifp->if_capenable ^= IFCAP_TXCSUM;
4933                                 if (IFCAP_TXCSUM & ifp->if_capenable)
4934                                         ifp->if_hwassist = BCE_IF_HWASSIST;
4935                                 else
4936                                         ifp->if_hwassist = 0;
4937                         }
4938
4939                         /* Toggle the RX checksum capabilities enable flag. */
4940                         if (mask & IFCAP_RXCSUM) {
4941                                 ifp->if_capenable ^= IFCAP_RXCSUM;
4942                                 if (IFCAP_RXCSUM & ifp->if_capenable)
4943                                         ifp->if_hwassist = BCE_IF_HWASSIST;
4944                                 else
4945                                         ifp->if_hwassist = 0;
4946                         }
4947
4948                         /* Toggle VLAN_MTU capabilities enable flag. */
4949                         if (mask & IFCAP_VLAN_MTU) {
4950                                 BCE_PRINTF(sc, "%s(%d): Changing VLAN_MTU not supported.\n",
4951                                         __FILE__, __LINE__);
4952                         }
4953
4954                         /* Toggle VLANHWTAG capabilities enabled flag. */
4955                         if (mask & IFCAP_VLAN_HWTAGGING) {
4956                                 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
4957                                         BCE_PRINTF(sc, "%s(%d): Cannot change VLAN_HWTAGGING while "
4958                                                 "management firmware (ASF/IPMI/UMP) is running!\n",
4959                                                 __FILE__, __LINE__);
4960                                 else
4961                                         BCE_PRINTF(sc, "%s(%d): Changing VLAN_HWTAGGING not supported!\n",
4962                                                 __FILE__, __LINE__);
4963                         }
4964
4965                         break;
4966                 default:
4967                         DBPRINT(sc, BCE_INFO, "Received unsupported IOCTL: 0x%08X\n",
4968                                 (u32) command);
4969
4970                         /* We don't know how to handle the IOCTL, pass it on. */
4971                         error = ether_ioctl(ifp, command, data);
4972                         break;
4973         }
4974
4975         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
4976
4977         return(error);
4978 }
4979
4980
4981 /****************************************************************************/
4982 /* Transmit timeout handler.                                                */
4983 /*                                                                          */
4984 /* Returns:                                                                 */
4985 /*   Nothing.                                                               */
4986 /****************************************************************************/
4987 static void
4988 bce_watchdog(struct ifnet *ifp)
4989 {
4990         struct bce_softc *sc = ifp->if_softc;
4991
4992         DBRUN(BCE_WARN_SEND, 
4993                 bce_dump_driver_state(sc);
4994                 bce_dump_status_block(sc));
4995
4996         BCE_PRINTF(sc, "%s(%d): Watchdog timeout occurred, resetting!\n", 
4997                 __FILE__, __LINE__);
4998
4999         /* DBRUN(BCE_FATAL, bce_breakpoint(sc)); */
5000
5001         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
5002
5003         bce_init(sc);
5004         ifp->if_oerrors++;
5005
5006 }
5007
5008
5009 #ifdef DEVICE_POLLING
5010 static void
5011 bce_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
5012 {
5013         struct bce_softc *sc = ifp->if_softc;
5014
5015         BCE_LOCK_ASSERT(sc);
5016
5017         sc->bce_rxcycles = count;
5018
5019         bus_dmamap_sync(sc->status_tag, sc->status_map,
5020             BUS_DMASYNC_POSTWRITE);
5021
5022         /* Check for any completed RX frames. */
5023         if (sc->status_block->status_rx_quick_consumer_index0 != 
5024                 sc->hw_rx_cons)
5025                 bce_rx_intr(sc);
5026
5027         /* Check for any completed TX frames. */
5028         if (sc->status_block->status_tx_quick_consumer_index0 != 
5029                 sc->hw_tx_cons)
5030                 bce_tx_intr(sc);
5031
5032         /* Check for new frames to transmit. */
5033         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5034                 bce_start_locked(ifp);
5035
5036 }
5037
5038
5039 static void
5040 bce_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
5041 {
5042         struct bce_softc *sc = ifp->if_softc;
5043
5044         BCE_LOCK(sc);
5045         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
5046                 bce_poll_locked(ifp, cmd, count);
5047         BCE_UNLOCK(sc);
5048 }
5049 #endif /* DEVICE_POLLING */
5050
5051
5052 #if 0
5053 static inline int
5054 bce_has_work(struct bce_softc *sc)
5055 {
5056         struct status_block *stat = sc->status_block;
5057
5058         if ((stat->status_rx_quick_consumer_index0 != sc->hw_rx_cons) ||
5059             (stat->status_tx_quick_consumer_index0 != sc->hw_tx_cons))
5060                 return 1;
5061
5062         if (((stat->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
5063             bp->link_up)
5064                 return 1;
5065
5066         return 0;
5067 }
5068 #endif
5069
5070
5071 /*
5072  * Interrupt handler.
5073  */
5074 /****************************************************************************/
5075 /* Main interrupt entry point.  Verifies that the controller generated the  */
5076 /* interrupt and then calls a separate routine for handle the various       */
5077 /* interrupt causes (PHY, TX, RX).                                          */
5078 /*                                                                          */
5079 /* Returns:                                                                 */
5080 /*   0 for success, positive value for failure.                             */
5081 /****************************************************************************/
5082 static void
5083 bce_intr(void *xsc)
5084 {
5085         struct bce_softc *sc;
5086         struct ifnet *ifp;
5087         u32 status_attn_bits;
5088
5089         sc = xsc;
5090         ifp = sc->bce_ifp;
5091
5092         BCE_LOCK(sc);
5093
5094         DBRUNIF(1, sc->interrupts_generated++);
5095
5096 #ifdef DEVICE_POLLING
5097         if (ifp->if_capenable & IFCAP_POLLING) {
5098                 DBPRINT(sc, BCE_INFO, "Polling enabled!\n");
5099                 goto bce_intr_exit;
5100         }
5101 #endif
5102
5103         bus_dmamap_sync(sc->status_tag, sc->status_map,
5104             BUS_DMASYNC_POSTWRITE);
5105
5106         /*
5107          * If the hardware status block index
5108          * matches the last value read by the
5109          * driver and we haven't asserted our
5110          * interrupt then there's nothing to do.
5111          */
5112         if ((sc->status_block->status_idx == sc->last_status_idx) && 
5113                 (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE))
5114                 goto bce_intr_exit;
5115
5116         /* Ack the interrupt and stop others from occuring. */
5117         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5118                 BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
5119                 BCE_PCICFG_INT_ACK_CMD_MASK_INT);
5120
5121         /* Keep processing data as long as there is work to do. */
5122         for (;;) {
5123
5124                 status_attn_bits = sc->status_block->status_attn_bits;
5125
5126                 DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
5127                         BCE_PRINTF(sc, "Simulating unexpected status attention bit set.");
5128                         status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
5129
5130                 /* Was it a link change interrupt? */
5131                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
5132                         (sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
5133                         bce_phy_intr(sc);
5134
5135                 /* If any other attention is asserted then the chip is toast. */
5136                 if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
5137                         (sc->status_block->status_attn_bits_ack & 
5138                         ~STATUS_ATTN_BITS_LINK_STATE))) {
5139
5140                         DBRUN(1, sc->unexpected_attentions++);
5141
5142                         BCE_PRINTF(sc, "%s(%d): Fatal attention detected: 0x%08X\n", 
5143                                 __FILE__, __LINE__, sc->status_block->status_attn_bits);
5144
5145                         DBRUN(BCE_FATAL, 
5146                                 if (bce_debug_unexpected_attention == 0)
5147                                         bce_breakpoint(sc));
5148
5149                         bce_init_locked(sc);
5150                         goto bce_intr_exit;
5151                 }
5152
5153                 /* Check for any completed RX frames. */
5154                 if (sc->status_block->status_rx_quick_consumer_index0 != sc->hw_rx_cons)
5155                         bce_rx_intr(sc);
5156
5157                 /* Check for any completed TX frames. */
5158                 if (sc->status_block->status_tx_quick_consumer_index0 != sc->hw_tx_cons)
5159                         bce_tx_intr(sc);
5160
5161                 /* Save the status block index value for use during the next interrupt. */
5162                 sc->last_status_idx = sc->status_block->status_idx;
5163
5164                 /* Prevent speculative reads from getting ahead of the status block. */
5165                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 
5166                         BUS_SPACE_BARRIER_READ);
5167
5168                 /* If there's no work left then exit the interrupt service routine. */
5169                 if ((sc->status_block->status_rx_quick_consumer_index0 == sc->hw_rx_cons) &&
5170                 (sc->status_block->status_tx_quick_consumer_index0 == sc->hw_tx_cons))
5171                         break;
5172         
5173         }
5174
5175         bus_dmamap_sync(sc->status_tag, sc->status_map,
5176             BUS_DMASYNC_PREWRITE);
5177
5178         /* Re-enable interrupts. */
5179         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5180                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
5181                BCE_PCICFG_INT_ACK_CMD_MASK_INT);
5182         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5183                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
5184
5185         /* Handle any frames that arrived while handling the interrupt. */
5186         if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5187                 bce_start_locked(ifp);
5188
5189 bce_intr_exit:
5190         BCE_UNLOCK(sc);
5191 }
5192
5193
5194 /****************************************************************************/
5195 /* Programs the various packet receive modes (broadcast and multicast).     */
5196 /*                                                                          */
5197 /* Returns:                                                                 */
5198 /*   Nothing.                                                               */
5199 /****************************************************************************/
5200 static void
5201 bce_set_rx_mode(struct bce_softc *sc)
5202 {
5203         struct ifnet *ifp;
5204         struct ifmultiaddr *ifma;
5205         u32 hashes[4] = { 0, 0, 0, 0 };
5206         u32 rx_mode, sort_mode;
5207         int h, i;
5208
5209         BCE_LOCK_ASSERT(sc);
5210
5211         ifp = sc->bce_ifp;
5212
5213         /* Initialize receive mode default settings. */
5214         rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
5215                             BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
5216         sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
5217
5218         /*
5219          * ASF/IPMI/UMP firmware requires that VLAN tag stripping
5220          * be enbled.
5221          */
5222         if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
5223                 (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
5224                 rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
5225
5226         /*
5227          * Check for promiscuous, all multicast, or selected
5228          * multicast address filtering.
5229          */
5230         if (ifp->if_flags & IFF_PROMISC) {
5231                 DBPRINT(sc, BCE_INFO, "Enabling promiscuous mode.\n");
5232
5233                 /* Enable promiscuous mode. */
5234                 rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
5235                 sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
5236         } else if (ifp->if_flags & IFF_ALLMULTI) {
5237                 DBPRINT(sc, BCE_INFO, "Enabling all multicast mode.\n");
5238
5239                 /* Enable all multicast addresses. */
5240                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
5241                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
5242         }
5243                 sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
5244         } else {
5245                 /* Accept one or more multicast(s). */
5246                 DBPRINT(sc, BCE_INFO, "Enabling selective multicast mode.\n");
5247
5248                 IF_ADDR_LOCK(ifp);
5249                 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
5250                         if (ifma->ifma_addr->sa_family != AF_LINK)
5251                                 continue;
5252                         h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
5253                         ifma->ifma_addr), ETHER_ADDR_LEN) & 0x7F;
5254                         hashes[(h & 0x60) >> 5] |= 1 << (h & 0x1F);
5255                 }
5256                 IF_ADDR_UNLOCK(ifp);
5257
5258                 for (i = 0; i < 4; i++)
5259                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
5260
5261                 sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
5262         }
5263
5264         /* Only make changes if the recive mode has actually changed. */
5265         if (rx_mode != sc->rx_mode) {
5266                 DBPRINT(sc, BCE_VERBOSE, "Enabling new receive mode: 0x%08X\n", 
5267                         rx_mode);
5268
5269                 sc->rx_mode = rx_mode;
5270                 REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
5271         }
5272
5273         /* Disable and clear the exisitng sort before enabling a new sort. */
5274         REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
5275         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
5276         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
5277 }
5278
5279
5280 /****************************************************************************/
5281 /* Called periodically to updates statistics from the controllers           */
5282 /* statistics block.                                                        */
5283 /*                                                                          */
5284 /* Returns:                                                                 */
5285 /*   Nothing.                                                               */
5286 /****************************************************************************/
5287 static void
5288 bce_stats_update(struct bce_softc *sc)
5289 {
5290         struct ifnet *ifp;
5291         struct statistics_block *stats;
5292
5293         DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __FUNCTION__);
5294
5295         ifp = sc->bce_ifp;
5296
5297         stats = (struct statistics_block *) sc->stats_block;
5298
5299         /* 
5300          * Update the interface statistics from the
5301          * hardware statistics.
5302          */
5303         ifp->if_collisions = (u_long) stats->stat_EtherStatsCollisions;
5304
5305         ifp->if_ibytes  = BCE_STATS(IfHCInOctets);
5306
5307         ifp->if_obytes  = BCE_STATS(IfHCOutOctets);
5308
5309         ifp->if_imcasts = BCE_STATS(IfHCInMulticastPkts);
5310
5311         ifp->if_omcasts = BCE_STATS(IfHCOutMulticastPkts);
5312
5313         ifp->if_ierrors = (u_long) stats->stat_EtherStatsUndersizePkts +
5314                                       (u_long) stats->stat_EtherStatsOverrsizePkts +
5315                                           (u_long) stats->stat_IfInMBUFDiscards +
5316                                           (u_long) stats->stat_Dot3StatsAlignmentErrors +
5317                                           (u_long) stats->stat_Dot3StatsFCSErrors;
5318
5319         ifp->if_oerrors = (u_long) stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
5320                                           (u_long) stats->stat_Dot3StatsExcessiveCollisions +
5321                                           (u_long) stats->stat_Dot3StatsLateCollisions;
5322
5323         /* 
5324          * Certain controllers don't report 
5325          * carrier sense errors correctly.
5326          * See errata E11_5708CA0_1165. 
5327          */
5328         if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
5329             !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
5330                 ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
5331
5332         /*
5333          * Update the sysctl statistics from the
5334          * hardware statistics.
5335          */
5336         sc->stat_IfHCInOctets = 
5337                 ((u64) stats->stat_IfHCInOctets_hi << 32) + 
5338                  (u64) stats->stat_IfHCInOctets_lo;
5339
5340         sc->stat_IfHCInBadOctets =
5341                 ((u64) stats->stat_IfHCInBadOctets_hi << 32) + 
5342                  (u64) stats->stat_IfHCInBadOctets_lo;
5343
5344         sc->stat_IfHCOutOctets =
5345                 ((u64) stats->stat_IfHCOutOctets_hi << 32) +
5346                  (u64) stats->stat_IfHCOutOctets_lo;
5347
5348         sc->stat_IfHCOutBadOctets =
5349                 ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
5350                  (u64) stats->stat_IfHCOutBadOctets_lo;
5351
5352         sc->stat_IfHCInUcastPkts =
5353                 ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
5354                  (u64) stats->stat_IfHCInUcastPkts_lo;
5355
5356         sc->stat_IfHCInMulticastPkts =
5357                 ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
5358                  (u64) stats->stat_IfHCInMulticastPkts_lo;
5359
5360         sc->stat_IfHCInBroadcastPkts =
5361                 ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
5362                  (u64) stats->stat_IfHCInBroadcastPkts_lo;
5363
5364         sc->stat_IfHCOutUcastPkts =
5365                 ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
5366                  (u64) stats->stat_IfHCOutUcastPkts_lo;
5367
5368         sc->stat_IfHCOutMulticastPkts =
5369                 ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
5370                  (u64) stats->stat_IfHCOutMulticastPkts_lo;
5371
5372         sc->stat_IfHCOutBroadcastPkts =
5373                 ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
5374                  (u64) stats->stat_IfHCOutBroadcastPkts_lo;
5375
5376         sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
5377                 stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
5378
5379         sc->stat_Dot3StatsCarrierSenseErrors =
5380                 stats->stat_Dot3StatsCarrierSenseErrors;
5381
5382         sc->stat_Dot3StatsFCSErrors = 
5383                 stats->stat_Dot3StatsFCSErrors;
5384
5385         sc->stat_Dot3StatsAlignmentErrors =
5386                 stats->stat_Dot3StatsAlignmentErrors;
5387
5388         sc->stat_Dot3StatsSingleCollisionFrames =
5389                 stats->stat_Dot3StatsSingleCollisionFrames;
5390
5391         sc->stat_Dot3StatsMultipleCollisionFrames =
5392                 stats->stat_Dot3StatsMultipleCollisionFrames;
5393
5394         sc->stat_Dot3StatsDeferredTransmissions =
5395                 stats->stat_Dot3StatsDeferredTransmissions;
5396
5397         sc->stat_Dot3StatsExcessiveCollisions =
5398                 stats->stat_Dot3StatsExcessiveCollisions;
5399
5400         sc->stat_Dot3StatsLateCollisions =
5401                 stats->stat_Dot3StatsLateCollisions;
5402
5403         sc->stat_EtherStatsCollisions =
5404                 stats->stat_EtherStatsCollisions;
5405
5406         sc->stat_EtherStatsFragments =
5407                 stats->stat_EtherStatsFragments;
5408
5409         sc->stat_EtherStatsJabbers =
5410                 stats->stat_EtherStatsJabbers;
5411
5412         sc->stat_EtherStatsUndersizePkts =
5413                 stats->stat_EtherStatsUndersizePkts;
5414
5415         sc->stat_EtherStatsOverrsizePkts =
5416                 stats->stat_EtherStatsOverrsizePkts;
5417
5418         sc->stat_EtherStatsPktsRx64Octets =
5419                 stats->stat_EtherStatsPktsRx64Octets;
5420
5421         sc->stat_EtherStatsPktsRx65Octetsto127Octets =
5422                 stats->stat_EtherStatsPktsRx65Octetsto127Octets;
5423
5424         sc->stat_EtherStatsPktsRx128Octetsto255Octets =
5425                 stats->stat_EtherStatsPktsRx128Octetsto255Octets;
5426
5427         sc->stat_EtherStatsPktsRx256Octetsto511Octets =
5428                 stats->stat_EtherStatsPktsRx256Octetsto511Octets;
5429
5430         sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
5431                 stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
5432
5433         sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
5434                 stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
5435
5436         sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
5437                 stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
5438
5439         sc->stat_EtherStatsPktsTx64Octets =
5440                 stats->stat_EtherStatsPktsTx64Octets;
5441
5442         sc->stat_EtherStatsPktsTx65Octetsto127Octets =
5443                 stats->stat_EtherStatsPktsTx65Octetsto127Octets;
5444
5445         sc->stat_EtherStatsPktsTx128Octetsto255Octets =
5446                 stats->stat_EtherStatsPktsTx128Octetsto255Octets;
5447
5448         sc->stat_EtherStatsPktsTx256Octetsto511Octets =
5449                 stats->stat_EtherStatsPktsTx256Octetsto511Octets;
5450
5451         sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
5452                 stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
5453
5454         sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
5455                 stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
5456
5457         sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
5458                 stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
5459
5460         sc->stat_XonPauseFramesReceived =
5461                 stats->stat_XonPauseFramesReceived;
5462
5463         sc->stat_XoffPauseFramesReceived =
5464                 stats->stat_XoffPauseFramesReceived;
5465
5466         sc->stat_OutXonSent =
5467                 stats->stat_OutXonSent;
5468
5469         sc->stat_OutXoffSent =
5470                 stats->stat_OutXoffSent;
5471
5472         sc->stat_FlowControlDone =
5473                 stats->stat_FlowControlDone;
5474
5475         sc->stat_MacControlFramesReceived =
5476                 stats->stat_MacControlFramesReceived;
5477
5478         sc->stat_XoffStateEntered =
5479                 stats->stat_XoffStateEntered;
5480
5481         sc->stat_IfInFramesL2FilterDiscards =
5482                 stats->stat_IfInFramesL2FilterDiscards;
5483
5484         sc->stat_IfInRuleCheckerDiscards =
5485                 stats->stat_IfInRuleCheckerDiscards;
5486
5487         sc->stat_IfInFTQDiscards =
5488                 stats->stat_IfInFTQDiscards;
5489
5490         sc->stat_IfInMBUFDiscards =
5491                 stats->stat_IfInMBUFDiscards;
5492
5493         sc->stat_IfInRuleCheckerP4Hit =
5494                 stats->stat_IfInRuleCheckerP4Hit;
5495
5496         sc->stat_CatchupInRuleCheckerDiscards =
5497                 stats->stat_CatchupInRuleCheckerDiscards;
5498
5499         sc->stat_CatchupInFTQDiscards =
5500                 stats->stat_CatchupInFTQDiscards;
5501
5502         sc->stat_CatchupInMBUFDiscards =
5503                 stats->stat_CatchupInMBUFDiscards;
5504
5505         sc->stat_CatchupInRuleCheckerP4Hit =
5506                 stats->stat_CatchupInRuleCheckerP4Hit;
5507
5508         DBPRINT(sc, BCE_EXCESSIVE, "Exiting %s()\n", __FUNCTION__);
5509 }
5510
5511
5512 static void
5513 bce_tick_locked(struct bce_softc *sc)
5514 {
5515         struct mii_data *mii = NULL;
5516         struct ifnet *ifp;
5517         u32 msg;
5518
5519         ifp = sc->bce_ifp;
5520
5521         BCE_LOCK_ASSERT(sc);
5522
5523         /* Tell the firmware that the driver is still running. */
5524 #ifdef BCE_DEBUG
5525         msg = (u32) BCE_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE;
5526 #else
5527         msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
5528 #endif
5529         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
5530
5531         /* Update the statistics from the hardware statistics block. */
5532         bce_stats_update(sc);
5533
5534         /* Schedule the next tick. */
5535         callout_reset(
5536                 &sc->bce_stat_ch,               /* callout */
5537                 hz,                                     /* ticks */
5538                 bce_tick,                               /* function */
5539                 sc);                                    /* function argument */
5540
5541         /* If link is up already up then we're done. */
5542         if (sc->bce_link)
5543                 goto bce_tick_locked_exit;
5544
5545         /* DRC - ToDo: Add SerDes support and check SerDes link here. */
5546
5547         mii = device_get_softc(sc->bce_miibus);
5548         mii_tick(mii);
5549
5550         /* Check if the link has come up. */
5551         if (!sc->bce_link && mii->mii_media_status & IFM_ACTIVE &&
5552             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
5553                 sc->bce_link++;
5554                 if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
5555                     IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
5556                     bootverbose)
5557                         BCE_PRINTF(sc, "Gigabit link up\n");
5558                 /* Now that link is up, handle any outstanding TX traffic. */
5559                 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5560                         bce_start_locked(ifp);
5561         }
5562
5563 bce_tick_locked_exit:
5564         return;
5565 }
5566
5567
5568 static void
5569 bce_tick(void *xsc)
5570 {
5571         struct bce_softc *sc;
5572
5573         sc = xsc;
5574
5575         BCE_LOCK(sc);
5576         bce_tick_locked(sc);
5577         BCE_UNLOCK(sc);
5578 }
5579
5580
5581 #ifdef BCE_DEBUG
5582 /****************************************************************************/
5583 /* Allows the driver state to be dumped through the sysctl interface.       */
5584 /*                                                                          */
5585 /* Returns:                                                                 */
5586 /*   0 for success, positive value for failure.                             */
5587 /****************************************************************************/
5588 static int
5589 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
5590 {
5591         int error;
5592         int result;
5593         struct bce_softc *sc;
5594
5595         result = -1;
5596         error = sysctl_handle_int(oidp, &result, 0, req);
5597
5598         if (error || !req->newptr)
5599                 return (error);
5600
5601         if (result == 1) {
5602                 sc = (struct bce_softc *)arg1;
5603                 bce_dump_driver_state(sc);
5604         }
5605
5606         return error;
5607 }
5608
5609
5610 /****************************************************************************/
5611 /* Allows the hardware state to be dumped through the sysctl interface.     */
5612 /*                                                                          */
5613 /* Returns:                                                                 */
5614 /*   0 for success, positive value for failure.                             */
5615 /****************************************************************************/
5616 static int
5617 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
5618 {
5619         int error;
5620         int result;
5621         struct bce_softc *sc;
5622
5623         result = -1;
5624         error = sysctl_handle_int(oidp, &result, 0, req);
5625
5626         if (error || !req->newptr)
5627                 return (error);
5628
5629         if (result == 1) {
5630                 sc = (struct bce_softc *)arg1;
5631                 bce_dump_hw_state(sc);
5632         }
5633
5634         return error;
5635 }
5636
5637
5638 /****************************************************************************/
5639 /*                                                                          */
5640 /*                                                                          */
5641 /* Returns:                                                                 */
5642 /*   0 for success, positive value for failure.                             */
5643 /****************************************************************************/
5644 static int
5645 bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
5646 {
5647         int error;
5648         int result;
5649         struct bce_softc *sc;
5650
5651         result = -1;
5652         error = sysctl_handle_int(oidp, &result, 0, req);
5653
5654         if (error || !req->newptr)
5655                 return (error);
5656
5657         if (result == 1) {
5658                 sc = (struct bce_softc *)arg1;
5659                 bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
5660         }
5661
5662         return error;
5663 }
5664
5665
5666 /****************************************************************************/
5667 /*                                                                          */
5668 /*                                                                          */
5669 /* Returns:                                                                 */
5670 /*   0 for success, positive value for failure.                             */
5671 /****************************************************************************/
5672 static int
5673 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
5674 {
5675         int error;
5676         int result;
5677         struct bce_softc *sc;
5678
5679         result = -1;
5680         error = sysctl_handle_int(oidp, &result, 0, req);
5681
5682         if (error || !req->newptr)
5683                 return (error);
5684
5685         if (result == 1) {
5686                 sc = (struct bce_softc *)arg1;
5687                 bce_breakpoint(sc);
5688         }
5689
5690         return error;
5691 }
5692 #endif
5693
5694
5695 /****************************************************************************/
5696 /* Adds any sysctl parameters for tuning or debugging purposes.             */
5697 /*                                                                          */
5698 /* Returns:                                                                 */
5699 /*   0 for success, positive value for failure.                             */
5700 /****************************************************************************/
5701 static void
5702 bce_add_sysctls(struct bce_softc *sc)
5703 {
5704         struct sysctl_ctx_list *ctx;
5705         struct sysctl_oid_list *children;
5706
5707         ctx = device_get_sysctl_ctx(sc->bce_dev);
5708         children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
5709
5710         SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
5711                 "driver_version",
5712                 CTLFLAG_RD, &bce_driver_version,
5713                 0, "bce driver version");
5714
5715 #ifdef BCE_DEBUG
5716         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5717                 "rx_low_watermark",
5718                 CTLFLAG_RD, &sc->rx_low_watermark,
5719                 0, "Lowest level of free rx_bd's");
5720
5721         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5722                 "tx_hi_watermark",
5723                 CTLFLAG_RD, &sc->tx_hi_watermark,
5724                 0, "Highest level of used tx_bd's");
5725
5726         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5727                 "l2fhdr_status_errors",
5728                 CTLFLAG_RD, &sc->l2fhdr_status_errors,
5729                 0, "l2_fhdr status errors");
5730
5731         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5732                 "unexpected_attentions",
5733                 CTLFLAG_RD, &sc->unexpected_attentions,
5734                 0, "unexpected attentions");
5735
5736         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5737                 "lost_status_block_updates",
5738                 CTLFLAG_RD, &sc->lost_status_block_updates,
5739                 0, "lost status block updates");
5740
5741         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5742                 "mbuf_alloc_failed",
5743                 CTLFLAG_RD, &sc->mbuf_alloc_failed,
5744                 0, "mbuf cluster allocation failures");
5745 #endif 
5746
5747         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5748                 "stat_IfHcInOctets",
5749                 CTLFLAG_RD, &sc->stat_IfHCInOctets,
5750                 "Bytes received");
5751
5752         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5753                 "stat_IfHCInBadOctets",
5754                 CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
5755                 "Bad bytes received");
5756
5757         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5758                 "stat_IfHCOutOctets",
5759                 CTLFLAG_RD, &sc->stat_IfHCOutOctets,
5760                 "Bytes sent");
5761
5762         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5763                 "stat_IfHCOutBadOctets",
5764                 CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
5765                 "Bad bytes sent");
5766
5767         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5768                 "stat_IfHCInUcastPkts",
5769                 CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
5770                 "Unicast packets received");
5771
5772         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5773                 "stat_IfHCInMulticastPkts",
5774                 CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
5775                 "Multicast packets received");
5776
5777         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5778                 "stat_IfHCInBroadcastPkts",
5779                 CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
5780                 "Broadcast packets received");
5781
5782         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5783                 "stat_IfHCOutUcastPkts",
5784                 CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
5785                 "Unicast packets sent");
5786
5787         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5788                 "stat_IfHCOutMulticastPkts",
5789                 CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
5790                 "Multicast packets sent");
5791
5792         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5793                 "stat_IfHCOutBroadcastPkts",
5794                 CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
5795                 "Broadcast packets sent");
5796
5797         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5798                 "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
5799                 CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
5800                 0, "Internal MAC transmit errors");
5801
5802         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5803                 "stat_Dot3StatsCarrierSenseErrors",
5804                 CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
5805                 0, "Carrier sense errors");
5806
5807         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5808                 "stat_Dot3StatsFCSErrors",
5809                 CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
5810                 0, "Frame check sequence errors");
5811
5812         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5813                 "stat_Dot3StatsAlignmentErrors",
5814                 CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
5815                 0, "Alignment errors");
5816
5817         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5818                 "stat_Dot3StatsSingleCollisionFrames",
5819                 CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
5820                 0, "Single Collision Frames");
5821
5822         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5823                 "stat_Dot3StatsMultipleCollisionFrames",
5824                 CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
5825                 0, "Multiple Collision Frames");
5826
5827         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5828                 "stat_Dot3StatsDeferredTransmissions",
5829                 CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
5830                 0, "Deferred Transmissions");
5831
5832         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5833                 "stat_Dot3StatsExcessiveCollisions",
5834                 CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
5835                 0, "Excessive Collisions");
5836
5837         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5838                 "stat_Dot3StatsLateCollisions",
5839                 CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
5840                 0, "Late Collisions");
5841
5842         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5843                 "stat_EtherStatsCollisions",
5844                 CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
5845                 0, "Collisions");
5846
5847         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5848                 "stat_EtherStatsFragments",
5849                 CTLFLAG_RD, &sc->stat_EtherStatsFragments,
5850                 0, "Fragments");
5851
5852         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5853                 "stat_EtherStatsJabbers",
5854                 CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
5855                 0, "Jabbers");
5856
5857         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5858                 "stat_EtherStatsUndersizePkts",
5859                 CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
5860                 0, "Undersize packets");
5861
5862         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5863                 "stat_EtherStatsOverrsizePkts",
5864                 CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts,
5865                 0, "stat_EtherStatsOverrsizePkts");
5866
5867         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5868                 "stat_EtherStatsPktsRx64Octets",
5869                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
5870                 0, "Bytes received in 64 byte packets");
5871
5872         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5873                 "stat_EtherStatsPktsRx65Octetsto127Octets",
5874                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
5875                 0, "Bytes received in 65 to 127 byte packets");
5876
5877         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5878                 "stat_EtherStatsPktsRx128Octetsto255Octets",
5879                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
5880                 0, "Bytes received in 128 to 255 byte packets");
5881
5882         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5883                 "stat_EtherStatsPktsRx256Octetsto511Octets",
5884                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
5885                 0, "Bytes received in 256 to 511 byte packets");
5886
5887         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5888                 "stat_EtherStatsPktsRx512Octetsto1023Octets",
5889                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
5890                 0, "Bytes received in 512 to 1023 byte packets");
5891
5892         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5893                 "stat_EtherStatsPktsRx1024Octetsto1522Octets",
5894                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
5895                 0, "Bytes received in 1024 t0 1522 byte packets");
5896
5897         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5898                 "stat_EtherStatsPktsRx1523Octetsto9022Octets",
5899                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
5900                 0, "Bytes received in 1523 to 9022 byte packets");
5901
5902         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5903                 "stat_EtherStatsPktsTx64Octets",
5904                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
5905                 0, "Bytes sent in 64 byte packets");
5906
5907         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5908                 "stat_EtherStatsPktsTx65Octetsto127Octets",
5909                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
5910                 0, "Bytes sent in 65 to 127 byte packets");
5911
5912         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5913                 "stat_EtherStatsPktsTx128Octetsto255Octets",
5914                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
5915                 0, "Bytes sent in 128 to 255 byte packets");
5916
5917         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5918                 "stat_EtherStatsPktsTx256Octetsto511Octets",
5919                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
5920                 0, "Bytes sent in 256 to 511 byte packets");
5921
5922         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5923                 "stat_EtherStatsPktsTx512Octetsto1023Octets",
5924                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
5925                 0, "Bytes sent in 512 to 1023 byte packets");
5926
5927         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5928                 "stat_EtherStatsPktsTx1024Octetsto1522Octets",
5929                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
5930                 0, "Bytes sent in 1024 to 1522 byte packets");
5931
5932         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5933                 "stat_EtherStatsPktsTx1523Octetsto9022Octets",
5934                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
5935                 0, "Bytes sent in 1523 to 9022 byte packets");
5936
5937         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5938                 "stat_XonPauseFramesReceived",
5939                 CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
5940                 0, "XON pause frames receved");
5941
5942         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5943                 "stat_XoffPauseFramesReceived",
5944                 CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
5945                 0, "XOFF pause frames received");
5946
5947         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5948                 "stat_OutXonSent",
5949                 CTLFLAG_RD, &sc->stat_OutXonSent,
5950                 0, "XON pause frames sent");
5951
5952         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5953                 "stat_OutXoffSent",
5954                 CTLFLAG_RD, &sc->stat_OutXoffSent,
5955                 0, "XOFF pause frames sent");
5956
5957         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5958                 "stat_FlowControlDone",
5959                 CTLFLAG_RD, &sc->stat_FlowControlDone,
5960                 0, "Flow control done");
5961
5962         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5963                 "stat_MacControlFramesReceived",
5964                 CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
5965                 0, "MAC control frames received");
5966
5967         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5968                 "stat_XoffStateEntered",
5969                 CTLFLAG_RD, &sc->stat_XoffStateEntered,
5970                 0, "XOFF state entered");
5971
5972         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5973                 "stat_IfInFramesL2FilterDiscards",
5974                 CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
5975                 0, "Received L2 packets discarded");
5976
5977         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5978                 "stat_IfInRuleCheckerDiscards",
5979                 CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
5980                 0, "Received packets discarded by rule");
5981
5982         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5983                 "stat_IfInFTQDiscards",
5984                 CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
5985                 0, "Received packet FTQ discards");
5986
5987         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5988                 "stat_IfInMBUFDiscards",
5989                 CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
5990                 0, "Received packets discarded due to lack of controller buffer memory");
5991
5992         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5993                 "stat_IfInRuleCheckerP4Hit",
5994                 CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
5995                 0, "Received packets rule checker hits");
5996
5997         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5998                 "stat_CatchupInRuleCheckerDiscards",
5999                 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
6000                 0, "Received packets discarded in Catchup path");
6001
6002         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
6003                 "stat_CatchupInFTQDiscards",
6004                 CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
6005                 0, "Received packets discarded in FTQ in Catchup path");
6006
6007         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
6008                 "stat_CatchupInMBUFDiscards",
6009                 CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
6010                 0, "Received packets discarded in controller buffer memory in Catchup path");
6011
6012         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
6013                 "stat_CatchupInRuleCheckerP4Hit",
6014                 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
6015                 0, "Received packets rule checker hits in Catchup path");
6016
6017 #ifdef BCE_DEBUG
6018         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6019                 "driver_state", CTLTYPE_INT | CTLFLAG_RW,
6020                 (void *)sc, 0,
6021                 bce_sysctl_driver_state, "I", "Drive state information");
6022
6023         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6024                 "hw_state", CTLTYPE_INT | CTLFLAG_RW,
6025                 (void *)sc, 0,
6026                 bce_sysctl_hw_state, "I", "Hardware state information");
6027
6028         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6029                 "dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
6030                 (void *)sc, 0,
6031                 bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
6032
6033         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6034                 "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
6035                 (void *)sc, 0,
6036                 bce_sysctl_breakpoint, "I", "Driver breakpoint");
6037 #endif
6038
6039 }
6040
6041
6042 /****************************************************************************/
6043 /* BCE Debug Routines                                                       */
6044 /****************************************************************************/
6045 #ifdef BCE_DEBUG
6046
6047 /****************************************************************************/
6048 /* Prints out information about an mbuf.                                    */
6049 /*                                                                          */
6050 /* Returns:                                                                 */
6051 /*   Nothing.                                                               */
6052 /****************************************************************************/
6053 static void
6054 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
6055 {
6056         u32 val_hi, val_lo;
6057         struct mbuf *mp = m;
6058
6059         if (m == NULL) {
6060                 /* Index out of range. */
6061                 printf("mbuf ptr is null!\n");
6062                 return;
6063         }
6064
6065         while (mp) {
6066                 val_hi = BCE_ADDR_HI(mp);
6067                 val_lo = BCE_ADDR_LO(mp);
6068                 BCE_PRINTF(sc, "mbuf: vaddr = 0x%08X:%08X, m_len = %d, m_flags = ", 
6069                            val_hi, val_lo, mp->m_len);
6070
6071                 if (mp->m_flags & M_EXT)
6072                         printf("M_EXT ");
6073                 if (mp->m_flags & M_PKTHDR)
6074                         printf("M_PKTHDR ");
6075                 printf("\n");
6076
6077                 if (mp->m_flags & M_EXT) {
6078                         val_hi = BCE_ADDR_HI(mp->m_ext.ext_buf);
6079                         val_lo = BCE_ADDR_LO(mp->m_ext.ext_buf);
6080                         BCE_PRINTF(sc, "- m_ext: vaddr = 0x%08X:%08X, ext_size = 0x%04X\n", 
6081                                 val_hi, val_lo, mp->m_ext.ext_size);
6082                 }
6083
6084                 mp = mp->m_next;
6085         }
6086
6087
6088 }
6089
6090
6091 /****************************************************************************/
6092 /* Prints out the mbufs in the TX mbuf chain.                               */
6093 /*                                                                          */
6094 /* Returns:                                                                 */
6095 /*   Nothing.                                                               */
6096 /****************************************************************************/
6097 static void
6098 bce_dump_tx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6099 {
6100         struct mbuf *m;
6101
6102         BCE_PRINTF(sc,
6103                 "----------------------------"
6104                 "  tx mbuf data  "
6105                 "----------------------------\n");
6106
6107         for (int i = 0; i < count; i++) {
6108                 m = sc->tx_mbuf_ptr[chain_prod];
6109                 BCE_PRINTF(sc, "txmbuf[%d]\n", chain_prod);
6110                 bce_dump_mbuf(sc, m);
6111                 chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
6112         }
6113
6114         BCE_PRINTF(sc,
6115                 "----------------------------"
6116                 "----------------"
6117                 "----------------------------\n");
6118 }
6119
6120
6121 /*
6122  * This routine prints the RX mbuf chain.
6123  */
6124 static void
6125 bce_dump_rx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6126 {
6127         struct mbuf *m;
6128
6129         BCE_PRINTF(sc,
6130                 "----------------------------"
6131                 "  rx mbuf data  "
6132                 "----------------------------\n");
6133
6134         for (int i = 0; i < count; i++) {
6135                 m = sc->rx_mbuf_ptr[chain_prod];
6136                 BCE_PRINTF(sc, "rxmbuf[0x%04X]\n", chain_prod);
6137                 bce_dump_mbuf(sc, m);
6138                 chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
6139         }
6140
6141
6142         BCE_PRINTF(sc,
6143                 "----------------------------"
6144                 "----------------"
6145                 "----------------------------\n");
6146 }
6147
6148
6149 static void
6150 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
6151 {
6152         if (idx > MAX_TX_BD)
6153                 /* Index out of range. */
6154                 BCE_PRINTF(sc, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
6155         else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6156                 /* TX Chain page pointer. */
6157                 BCE_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n", 
6158                         idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
6159         else
6160                 /* Normal tx_bd entry. */
6161                 BCE_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
6162                         "flags = 0x%08X\n", idx, 
6163                         txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
6164                         txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag_flags);
6165 }
6166
6167
6168 static void
6169 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
6170 {
6171         if (idx > MAX_RX_BD)
6172                 /* Index out of range. */
6173                 BCE_PRINTF(sc, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
6174         else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
6175                 /* TX Chain page pointer. */
6176                 BCE_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n", 
6177                         idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
6178         else
6179                 /* Normal tx_bd entry. */
6180                 BCE_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
6181                         "flags = 0x%08X\n", idx, 
6182                         rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
6183                         rxbd->rx_bd_len, rxbd->rx_bd_flags);
6184 }
6185
6186
6187 static void
6188 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
6189 {
6190         BCE_PRINTF(sc, "l2_fhdr[0x%04X]: status = 0x%08X, "
6191                 "pkt_len = 0x%04X, vlan = 0x%04x, ip_xsum = 0x%04X, "
6192                 "tcp_udp_xsum = 0x%04X\n", idx,
6193                 l2fhdr->l2_fhdr_status, l2fhdr->l2_fhdr_pkt_len,
6194                 l2fhdr->l2_fhdr_vlan_tag, l2fhdr->l2_fhdr_ip_xsum,
6195                 l2fhdr->l2_fhdr_tcp_udp_xsum);
6196 }
6197
6198
6199 /*
6200  * This routine prints the TX chain.
6201  */
6202 static void
6203 bce_dump_tx_chain(struct bce_softc *sc, int tx_prod, int count)
6204 {
6205         struct tx_bd *txbd;
6206
6207         /* First some info about the tx_bd chain structure. */
6208         BCE_PRINTF(sc,
6209                 "----------------------------"
6210                 "  tx_bd  chain  "
6211                 "----------------------------\n");
6212
6213         BCE_PRINTF(sc, "page size      = 0x%08X, tx chain pages        = 0x%08X\n",
6214                 (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
6215
6216         BCE_PRINTF(sc, "tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
6217                 (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
6218
6219         BCE_PRINTF(sc, "total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
6220
6221         BCE_PRINTF(sc, ""
6222                 "-----------------------------"
6223                 "   tx_bd data   "
6224                 "-----------------------------\n");
6225
6226         /* Now print out the tx_bd's themselves. */
6227         for (int i = 0; i < count; i++) {
6228                 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
6229                 bce_dump_txbd(sc, tx_prod, txbd);
6230                 tx_prod = TX_CHAIN_IDX(NEXT_TX_BD(tx_prod));
6231         }
6232
6233         BCE_PRINTF(sc,
6234                 "-----------------------------"
6235                 "--------------"
6236                 "-----------------------------\n");
6237 }
6238
6239
6240 /*
6241  * This routine prints the RX chain.
6242  */
6243 static void
6244 bce_dump_rx_chain(struct bce_softc *sc, int rx_prod, int count)
6245 {
6246         struct rx_bd *rxbd;
6247
6248         /* First some info about the tx_bd chain structure. */
6249         BCE_PRINTF(sc,
6250                 "----------------------------"
6251                 "  rx_bd  chain  "
6252                 "----------------------------\n");
6253
6254         BCE_PRINTF(sc, "----- RX_BD Chain -----\n");
6255
6256         BCE_PRINTF(sc, "page size      = 0x%08X, rx chain pages        = 0x%08X\n",
6257                 (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
6258
6259         BCE_PRINTF(sc, "rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
6260                 (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
6261
6262         BCE_PRINTF(sc, "total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
6263
6264         BCE_PRINTF(sc,
6265                 "----------------------------"
6266                 "   rx_bd data   "
6267                 "----------------------------\n");
6268
6269         /* Now print out the rx_bd's themselves. */
6270         for (int i = 0; i < count; i++) {
6271                 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
6272                 bce_dump_rxbd(sc, rx_prod, rxbd);
6273                 rx_prod = RX_CHAIN_IDX(NEXT_RX_BD(rx_prod));
6274         }
6275
6276         BCE_PRINTF(sc,
6277                 "----------------------------"
6278                 "--------------"
6279                 "----------------------------\n");
6280 }
6281
6282
6283 /*
6284  * This routine prints the status block.
6285  */
6286 static void
6287 bce_dump_status_block(struct bce_softc *sc)
6288 {
6289         struct status_block *sblk;
6290
6291         sblk = sc->status_block;
6292
6293         BCE_PRINTF(sc, "----------------------------- Status Block "
6294                 "-----------------------------\n");
6295
6296         BCE_PRINTF(sc, "attn_bits  = 0x%08X, attn_bits_ack = 0x%08X, index = 0x%04X\n",
6297                 sblk->status_attn_bits, sblk->status_attn_bits_ack,
6298                 sblk->status_idx);
6299
6300         BCE_PRINTF(sc, "rx_cons0   = 0x%08X, tx_cons0      = 0x%08X\n",
6301                 sblk->status_rx_quick_consumer_index0,
6302                 sblk->status_tx_quick_consumer_index0);
6303
6304         BCE_PRINTF(sc, "status_idx = 0x%04X\n", sblk->status_idx);
6305
6306         /* Theses indices are not used for normal L2 drivers. */
6307         if (sblk->status_rx_quick_consumer_index1 || 
6308                 sblk->status_tx_quick_consumer_index1)
6309                 BCE_PRINTF(sc, "rx_cons1  = 0x%08X, tx_cons1      = 0x%08X\n",
6310                         sblk->status_rx_quick_consumer_index1,
6311                         sblk->status_tx_quick_consumer_index1);
6312
6313         if (sblk->status_rx_quick_consumer_index2 || 
6314                 sblk->status_tx_quick_consumer_index2)
6315                 BCE_PRINTF(sc, "rx_cons2  = 0x%08X, tx_cons2      = 0x%08X\n",
6316                         sblk->status_rx_quick_consumer_index2,
6317                         sblk->status_tx_quick_consumer_index2);
6318
6319         if (sblk->status_rx_quick_consumer_index3 || 
6320                 sblk->status_tx_quick_consumer_index3)
6321                 BCE_PRINTF(sc, "rx_cons3  = 0x%08X, tx_cons3      = 0x%08X\n",
6322                         sblk->status_rx_quick_consumer_index3,
6323                         sblk->status_tx_quick_consumer_index3);
6324
6325         if (sblk->status_rx_quick_consumer_index4 || 
6326                 sblk->status_rx_quick_consumer_index5)
6327                 BCE_PRINTF(sc, "rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
6328                         sblk->status_rx_quick_consumer_index4,
6329                         sblk->status_rx_quick_consumer_index5);
6330
6331         if (sblk->status_rx_quick_consumer_index6 || 
6332                 sblk->status_rx_quick_consumer_index7)
6333                 BCE_PRINTF(sc, "rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
6334                         sblk->status_rx_quick_consumer_index6,
6335                         sblk->status_rx_quick_consumer_index7);
6336
6337         if (sblk->status_rx_quick_consumer_index8 || 
6338                 sblk->status_rx_quick_consumer_index9)
6339                 BCE_PRINTF(sc, "rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
6340                         sblk->status_rx_quick_consumer_index8,
6341                         sblk->status_rx_quick_consumer_index9);
6342
6343         if (sblk->status_rx_quick_consumer_index10 || 
6344                 sblk->status_rx_quick_consumer_index11)
6345                 BCE_PRINTF(sc, "rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
6346                         sblk->status_rx_quick_consumer_index10,
6347                         sblk->status_rx_quick_consumer_index11);
6348
6349         if (sblk->status_rx_quick_consumer_index12 || 
6350                 sblk->status_rx_quick_consumer_index13)
6351                 BCE_PRINTF(sc, "rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
6352                         sblk->status_rx_quick_consumer_index12,
6353                         sblk->status_rx_quick_consumer_index13);
6354
6355         if (sblk->status_rx_quick_consumer_index14 || 
6356                 sblk->status_rx_quick_consumer_index15)
6357                 BCE_PRINTF(sc, "rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
6358                         sblk->status_rx_quick_consumer_index14,
6359                         sblk->status_rx_quick_consumer_index15);
6360
6361         if (sblk->status_completion_producer_index || 
6362                 sblk->status_cmd_consumer_index)
6363                 BCE_PRINTF(sc, "com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
6364                         sblk->status_completion_producer_index,
6365                         sblk->status_cmd_consumer_index);
6366
6367         BCE_PRINTF(sc, "-------------------------------------------"
6368                 "-----------------------------\n");
6369 }
6370
6371
6372 /*
6373  * This routine prints the statistics block.
6374  */
6375 static void
6376 bce_dump_stats_block(struct bce_softc *sc)
6377 {
6378         struct statistics_block *sblk;
6379
6380         sblk = sc->stats_block;
6381
6382         BCE_PRINTF(sc, ""
6383                 "-----------------------------"
6384                 " Stats  Block "
6385                 "-----------------------------\n");
6386
6387         BCE_PRINTF(sc, "IfHcInOctets         = 0x%08X:%08X, "
6388                 "IfHcInBadOctets      = 0x%08X:%08X\n",
6389                 sblk->stat_IfHCInOctets_hi, sblk->stat_IfHCInOctets_lo,
6390                 sblk->stat_IfHCInBadOctets_hi, sblk->stat_IfHCInBadOctets_lo);
6391
6392         BCE_PRINTF(sc, "IfHcOutOctets        = 0x%08X:%08X, "
6393                 "IfHcOutBadOctets     = 0x%08X:%08X\n",
6394                 sblk->stat_IfHCOutOctets_hi, sblk->stat_IfHCOutOctets_lo,
6395                 sblk->stat_IfHCOutBadOctets_hi, sblk->stat_IfHCOutBadOctets_lo);
6396
6397         BCE_PRINTF(sc, "IfHcInUcastPkts      = 0x%08X:%08X, "
6398                 "IfHcInMulticastPkts  = 0x%08X:%08X\n",
6399                 sblk->stat_IfHCInUcastPkts_hi, sblk->stat_IfHCInUcastPkts_lo,
6400                 sblk->stat_IfHCInMulticastPkts_hi, sblk->stat_IfHCInMulticastPkts_lo);
6401
6402         BCE_PRINTF(sc, "IfHcInBroadcastPkts  = 0x%08X:%08X, "
6403                 "IfHcOutUcastPkts     = 0x%08X:%08X\n",
6404                 sblk->stat_IfHCInBroadcastPkts_hi, sblk->stat_IfHCInBroadcastPkts_lo,
6405                 sblk->stat_IfHCOutUcastPkts_hi, sblk->stat_IfHCOutUcastPkts_lo);
6406
6407         BCE_PRINTF(sc, "IfHcOutMulticastPkts = 0x%08X:%08X, IfHcOutBroadcastPkts = 0x%08X:%08X\n",
6408                 sblk->stat_IfHCOutMulticastPkts_hi, sblk->stat_IfHCOutMulticastPkts_lo,
6409                 sblk->stat_IfHCOutBroadcastPkts_hi, sblk->stat_IfHCOutBroadcastPkts_lo);
6410
6411         if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
6412                 BCE_PRINTF(sc, "0x%08X : "
6413                 "emac_tx_stat_dot3statsinternalmactransmiterrors\n", 
6414                 sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
6415
6416         if (sblk->stat_Dot3StatsCarrierSenseErrors)
6417                 BCE_PRINTF(sc, "0x%08X : Dot3StatsCarrierSenseErrors\n",
6418                         sblk->stat_Dot3StatsCarrierSenseErrors);
6419
6420         if (sblk->stat_Dot3StatsFCSErrors)
6421                 BCE_PRINTF(sc, "0x%08X : Dot3StatsFCSErrors\n",
6422                         sblk->stat_Dot3StatsFCSErrors);
6423
6424         if (sblk->stat_Dot3StatsAlignmentErrors)
6425                 BCE_PRINTF(sc, "0x%08X : Dot3StatsAlignmentErrors\n",
6426                         sblk->stat_Dot3StatsAlignmentErrors);
6427
6428         if (sblk->stat_Dot3StatsSingleCollisionFrames)
6429                 BCE_PRINTF(sc, "0x%08X : Dot3StatsSingleCollisionFrames\n",
6430                         sblk->stat_Dot3StatsSingleCollisionFrames);
6431
6432         if (sblk->stat_Dot3StatsMultipleCollisionFrames)
6433                 BCE_PRINTF(sc, "0x%08X : Dot3StatsMultipleCollisionFrames\n",
6434                         sblk->stat_Dot3StatsMultipleCollisionFrames);
6435         
6436         if (sblk->stat_Dot3StatsDeferredTransmissions)
6437                 BCE_PRINTF(sc, "0x%08X : Dot3StatsDeferredTransmissions\n",
6438                         sblk->stat_Dot3StatsDeferredTransmissions);
6439
6440         if (sblk->stat_Dot3StatsExcessiveCollisions)
6441                 BCE_PRINTF(sc, "0x%08X : Dot3StatsExcessiveCollisions\n",
6442                         sblk->stat_Dot3StatsExcessiveCollisions);
6443
6444         if (sblk->stat_Dot3StatsLateCollisions)
6445                 BCE_PRINTF(sc, "0x%08X : Dot3StatsLateCollisions\n",
6446                         sblk->stat_Dot3StatsLateCollisions);
6447
6448         if (sblk->stat_EtherStatsCollisions)
6449                 BCE_PRINTF(sc, "0x%08X : EtherStatsCollisions\n",
6450                         sblk->stat_EtherStatsCollisions);
6451
6452         if (sblk->stat_EtherStatsFragments) 
6453                 BCE_PRINTF(sc, "0x%08X : EtherStatsFragments\n",
6454                         sblk->stat_EtherStatsFragments);
6455
6456         if (sblk->stat_EtherStatsJabbers)
6457                 BCE_PRINTF(sc, "0x%08X : EtherStatsJabbers\n",
6458                         sblk->stat_EtherStatsJabbers);
6459
6460         if (sblk->stat_EtherStatsUndersizePkts)
6461                 BCE_PRINTF(sc, "0x%08X : EtherStatsUndersizePkts\n",
6462                         sblk->stat_EtherStatsUndersizePkts);
6463
6464         if (sblk->stat_EtherStatsOverrsizePkts)
6465                 BCE_PRINTF(sc, "0x%08X : EtherStatsOverrsizePkts\n",
6466                         sblk->stat_EtherStatsOverrsizePkts);
6467
6468         if (sblk->stat_EtherStatsPktsRx64Octets)
6469                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx64Octets\n",
6470                         sblk->stat_EtherStatsPktsRx64Octets);
6471
6472         if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
6473                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
6474                         sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
6475
6476         if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
6477                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
6478                         sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
6479
6480         if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
6481                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
6482                         sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
6483
6484         if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
6485                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
6486                         sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
6487
6488         if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
6489                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
6490                         sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
6491
6492         if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
6493                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
6494                         sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
6495
6496         if (sblk->stat_EtherStatsPktsTx64Octets)
6497                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx64Octets\n",
6498                         sblk->stat_EtherStatsPktsTx64Octets);
6499
6500         if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
6501                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
6502                         sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
6503
6504         if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
6505                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
6506                         sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
6507
6508         if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
6509                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
6510                         sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
6511
6512         if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
6513                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
6514                         sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
6515
6516         if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
6517                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
6518                         sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
6519
6520         if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
6521                 BCE_PRINTF(sc, "0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
6522                         sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
6523
6524         if (sblk->stat_XonPauseFramesReceived)
6525                 BCE_PRINTF(sc, "0x%08X : XonPauseFramesReceived\n",
6526                         sblk->stat_XonPauseFramesReceived);
6527
6528         if (sblk->stat_XoffPauseFramesReceived)
6529            BCE_PRINTF(sc, "0x%08X : XoffPauseFramesReceived\n",
6530                         sblk->stat_XoffPauseFramesReceived);
6531
6532         if (sblk->stat_OutXonSent)
6533                 BCE_PRINTF(sc, "0x%08X : OutXonSent\n",
6534                         sblk->stat_OutXonSent);
6535
6536         if (sblk->stat_OutXoffSent)
6537                 BCE_PRINTF(sc, "0x%08X : OutXoffSent\n",
6538                         sblk->stat_OutXoffSent);
6539
6540         if (sblk->stat_FlowControlDone)
6541                 BCE_PRINTF(sc, "0x%08X : FlowControlDone\n",
6542                         sblk->stat_FlowControlDone);
6543
6544         if (sblk->stat_MacControlFramesReceived)
6545                 BCE_PRINTF(sc, "0x%08X : MacControlFramesReceived\n",
6546                         sblk->stat_MacControlFramesReceived);
6547
6548         if (sblk->stat_XoffStateEntered)
6549                 BCE_PRINTF(sc, "0x%08X : XoffStateEntered\n",
6550                         sblk->stat_XoffStateEntered);
6551
6552         if (sblk->stat_IfInFramesL2FilterDiscards)
6553                 BCE_PRINTF(sc, "0x%08X : IfInFramesL2FilterDiscards\n",
6554                         sblk->stat_IfInFramesL2FilterDiscards);
6555
6556         if (sblk->stat_IfInRuleCheckerDiscards)
6557                 BCE_PRINTF(sc, "0x%08X : IfInRuleCheckerDiscards\n",
6558                         sblk->stat_IfInRuleCheckerDiscards);
6559
6560         if (sblk->stat_IfInFTQDiscards)
6561                 BCE_PRINTF(sc, "0x%08X : IfInFTQDiscards\n",
6562                         sblk->stat_IfInFTQDiscards);
6563
6564         if (sblk->stat_IfInMBUFDiscards)
6565                 BCE_PRINTF(sc, "0x%08X : IfInMBUFDiscards\n",
6566                         sblk->stat_IfInMBUFDiscards);
6567
6568         if (sblk->stat_IfInRuleCheckerP4Hit)
6569                 BCE_PRINTF(sc, "0x%08X : IfInRuleCheckerP4Hit\n",
6570                         sblk->stat_IfInRuleCheckerP4Hit);
6571
6572         if (sblk->stat_CatchupInRuleCheckerDiscards)
6573                 BCE_PRINTF(sc, "0x%08X : CatchupInRuleCheckerDiscards\n",
6574                         sblk->stat_CatchupInRuleCheckerDiscards);
6575
6576         if (sblk->stat_CatchupInFTQDiscards)
6577                 BCE_PRINTF(sc, "0x%08X : CatchupInFTQDiscards\n",
6578                         sblk->stat_CatchupInFTQDiscards);
6579
6580         if (sblk->stat_CatchupInMBUFDiscards)
6581                 BCE_PRINTF(sc, "0x%08X : CatchupInMBUFDiscards\n",
6582                         sblk->stat_CatchupInMBUFDiscards);
6583
6584         if (sblk->stat_CatchupInRuleCheckerP4Hit)
6585                 BCE_PRINTF(sc, "0x%08X : CatchupInRuleCheckerP4Hit\n",
6586                         sblk->stat_CatchupInRuleCheckerP4Hit);
6587
6588         BCE_PRINTF(sc,
6589                 "-----------------------------"
6590                 "--------------"
6591                 "-----------------------------\n");
6592 }
6593
6594
6595 static void
6596 bce_dump_driver_state(struct bce_softc *sc)
6597 {
6598         u32 val_hi, val_lo;
6599
6600         BCE_PRINTF(sc,
6601                 "-----------------------------"
6602                 " Driver State "
6603                 "-----------------------------\n");
6604
6605         val_hi = BCE_ADDR_HI(sc);
6606         val_lo = BCE_ADDR_LO(sc);
6607         BCE_PRINTF(sc, "0x%08X:%08X - (sc) driver softc structure virtual address\n",
6608                 val_hi, val_lo);
6609
6610         val_hi = BCE_ADDR_HI(sc->bce_vhandle);
6611         val_lo = BCE_ADDR_LO(sc->bce_vhandle);
6612         BCE_PRINTF(sc, "0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
6613                 val_hi, val_lo);
6614
6615         val_hi = BCE_ADDR_HI(sc->status_block);
6616         val_lo = BCE_ADDR_LO(sc->status_block);
6617         BCE_PRINTF(sc, "0x%08X:%08X - (sc->status_block) status block virtual address\n",
6618                 val_hi, val_lo);
6619
6620         val_hi = BCE_ADDR_HI(sc->stats_block);
6621         val_lo = BCE_ADDR_LO(sc->stats_block);
6622         BCE_PRINTF(sc, "0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
6623                 val_hi, val_lo);
6624
6625         val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
6626         val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
6627         BCE_PRINTF(sc,
6628                 "0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
6629                 val_hi, val_lo);
6630
6631         val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
6632         val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
6633         BCE_PRINTF(sc,
6634                 "0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
6635                 val_hi, val_lo);
6636
6637         val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
6638         val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
6639         BCE_PRINTF(sc,
6640                 "0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
6641                 val_hi, val_lo);
6642
6643         val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
6644         val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
6645         BCE_PRINTF(sc, 
6646                 "0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
6647                 val_hi, val_lo);
6648
6649         BCE_PRINTF(sc, "         0x%08X - (sc->interrupts_generated) h/w intrs\n",
6650                 sc->interrupts_generated);
6651         
6652         BCE_PRINTF(sc, "         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
6653                 sc->rx_interrupts);
6654
6655         BCE_PRINTF(sc, "         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
6656                 sc->tx_interrupts);
6657
6658         BCE_PRINTF(sc, "         0x%08X - (sc->last_status_idx) status block index\n",
6659                 sc->last_status_idx);
6660
6661         BCE_PRINTF(sc, "         0x%08X - (sc->tx_prod) tx producer index\n",
6662                 sc->tx_prod);
6663
6664         BCE_PRINTF(sc, "         0x%08X - (sc->tx_cons) tx consumer index\n",
6665                 sc->tx_cons);
6666
6667         BCE_PRINTF(sc, "         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
6668                 sc->tx_prod_bseq);
6669
6670         BCE_PRINTF(sc, "         0x%08X - (sc->rx_prod) rx producer index\n",
6671                 sc->rx_prod);
6672
6673         BCE_PRINTF(sc, "         0x%08X - (sc->rx_cons) rx consumer index\n",
6674                 sc->rx_cons);
6675
6676         BCE_PRINTF(sc, "         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
6677                 sc->rx_prod_bseq);
6678
6679         BCE_PRINTF(sc, "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
6680                 sc->rx_mbuf_alloc);
6681
6682         BCE_PRINTF(sc, "         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
6683                 sc->free_rx_bd);
6684
6685         BCE_PRINTF(sc, "0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
6686                 sc->rx_low_watermark, (u32) USABLE_RX_BD);
6687
6688         BCE_PRINTF(sc, "         0x%08X - (sc->txmbuf_alloc) tx mbufs allocated\n",
6689                 sc->tx_mbuf_alloc);
6690
6691         BCE_PRINTF(sc, "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
6692                 sc->rx_mbuf_alloc);
6693
6694         BCE_PRINTF(sc, "         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
6695                 sc->used_tx_bd);
6696
6697         BCE_PRINTF(sc, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
6698                 sc->tx_hi_watermark, (u32) USABLE_TX_BD);
6699
6700         BCE_PRINTF(sc, "         0x%08X - (sc->mbuf_alloc_failed) failed mbuf alloc\n",
6701                 sc->mbuf_alloc_failed);
6702
6703         BCE_PRINTF(sc,
6704                 "-----------------------------"
6705                 "--------------"
6706                 "-----------------------------\n");
6707 }
6708
6709
6710 static void
6711 bce_dump_hw_state(struct bce_softc *sc)
6712 {
6713         u32 val1;
6714
6715         BCE_PRINTF(sc,
6716                 "----------------------------"
6717                 " Hardware State "
6718                 "----------------------------\n");
6719
6720         BCE_PRINTF(sc, "0x%08X : bootcode version\n", sc->bce_fw_ver);
6721
6722         val1 = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
6723         BCE_PRINTF(sc, "0x%08X : (0x%04X) misc_enable_status_bits\n",
6724                 val1, BCE_MISC_ENABLE_STATUS_BITS);
6725
6726         val1 = REG_RD(sc, BCE_DMA_STATUS);
6727         BCE_PRINTF(sc, "0x%08X : (0x%04X) dma_status\n", val1, BCE_DMA_STATUS);
6728
6729         val1 = REG_RD(sc, BCE_CTX_STATUS);
6730         BCE_PRINTF(sc, "0x%08X : (0x%04X) ctx_status\n", val1, BCE_CTX_STATUS);
6731
6732         val1 = REG_RD(sc, BCE_EMAC_STATUS);
6733         BCE_PRINTF(sc, "0x%08X : (0x%04X) emac_status\n", val1, BCE_EMAC_STATUS);
6734
6735         val1 = REG_RD(sc, BCE_RPM_STATUS);
6736         BCE_PRINTF(sc, "0x%08X : (0x%04X) rpm_status\n", val1, BCE_RPM_STATUS);
6737
6738         val1 = REG_RD(sc, BCE_TBDR_STATUS);
6739         BCE_PRINTF(sc, "0x%08X : (0x%04X) tbdr_status\n", val1, BCE_TBDR_STATUS);
6740
6741         val1 = REG_RD(sc, BCE_TDMA_STATUS);
6742         BCE_PRINTF(sc, "0x%08X : (0x%04X) tdma_status\n", val1, BCE_TDMA_STATUS);
6743
6744         val1 = REG_RD(sc, BCE_HC_STATUS);
6745         BCE_PRINTF(sc, "0x%08X : (0x%04X) hc_status\n", val1, BCE_HC_STATUS);
6746
6747         BCE_PRINTF(sc, 
6748                 "----------------------------"
6749                 "----------------"
6750                 "----------------------------\n");
6751
6752         BCE_PRINTF(sc, 
6753                 "----------------------------"
6754                 " Register  Dump "
6755                 "----------------------------\n");
6756
6757         for (int i = 0x400; i < 0x8000; i += 0x10)
6758                 BCE_PRINTF(sc, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
6759                         i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
6760                         REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
6761
6762         BCE_PRINTF(sc, 
6763                 "----------------------------"
6764                 "----------------"
6765                 "----------------------------\n");
6766 }
6767
6768
6769 static void
6770 bce_breakpoint(struct bce_softc *sc)
6771 {
6772
6773         /* Unreachable code to shut the compiler up about unused functions. */
6774         if (0) {
6775                 bce_dump_txbd(sc, 0, NULL);
6776                 bce_dump_rxbd(sc, 0, NULL);
6777                 bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
6778                 bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
6779                 bce_dump_l2fhdr(sc, 0, NULL);
6780                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
6781                 bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
6782                 bce_dump_status_block(sc);
6783                 bce_dump_stats_block(sc);
6784                 bce_dump_driver_state(sc);
6785                 bce_dump_hw_state(sc);
6786         }
6787
6788         bce_dump_driver_state(sc);
6789         /* Print the important status block fields. */
6790         bce_dump_status_block(sc);
6791
6792         /* Call the debugger. */
6793         breakpoint();
6794
6795         return;
6796 }
6797 #endif