1c2fa353ps/*-
2ebda8d9pfg * SPDX-License-Identifier: BSD-2-Clause
3ebda8d9pfg *
48095e01davidcs * Copyright (c) 2006-2014 QLogic Corporation
5c2fa353ps *
6c2fa353ps * Redistribution and use in source and binary forms, with or without
7c2fa353ps * modification, are permitted provided that the following conditions
8c2fa353ps * are met:
9c2fa353ps *
10c2fa353ps * 1. Redistributions of source code must retain the above copyright
11c2fa353ps *    notice, this list of conditions and the following disclaimer.
12c2fa353ps * 2. Redistributions in binary form must reproduce the above copyright
13c2fa353ps *    notice, this list of conditions and the following disclaimer in the
14c2fa353ps *    documentation and/or other materials provided with the distribution.
15c2fa353ps *
16c2fa353ps * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17c2fa353ps * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18c2fa353ps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19c2fa353ps * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20c2fa353ps * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21c2fa353ps * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22c2fa353ps * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23c2fa353ps * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24c2fa353ps * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25c2fa353ps * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26c2fa353ps * THE POSSIBILITY OF SUCH DAMAGE.
27c2fa353ps */
28c2fa353ps
29c2fa353ps#include <sys/cdefs.h>
30c2fa353ps__FBSDID("$FreeBSD$");
31c2fa353ps
32c2fa353ps/*
33c2fa353ps * The following controllers are supported by this driver:
34c2fa353ps *   BCM5706C A2, A3
35179a317davidch *   BCM5706S A2, A3
366ab1aa7davidch *   BCM5708C B1, B2
37179a317davidch *   BCM5708S B1, B2
38fecec6adavidch *   BCM5709C A1, C0
3950b21e3davidch *   BCM5709S A1, C0
40d037577davidch *   BCM5716C C0
41d037577davidch *   BCM5716S C0
42c2fa353ps *
43c2fa353ps * The following controllers are not supported by this driver:
44179a317davidch *   BCM5706C A0, A1 (pre-production)
45179a317davidch *   BCM5706S A0, A1 (pre-production)
46179a317davidch *   BCM5708C A0, B0 (pre-production)
47179a317davidch *   BCM5708S A0, B0 (pre-production)
482156989davidch *   BCM5709C A0  B0, B1, B2 (pre-production)
4950b21e3davidch *   BCM5709S A0, B0, B1, B2 (pre-production)
50c2fa353ps */
51c2fa353ps
52cc2c59eps#include "opt_bce.h"
53cc2c59eps
54b86044bglebius#include <sys/param.h>
55b86044bglebius#include <sys/endian.h>
56b86044bglebius#include <sys/systm.h>
57b86044bglebius#include <sys/sockio.h>
58b86044bglebius#include <sys/lock.h>
59b86044bglebius#include <sys/mbuf.h>
60b86044bglebius#include <sys/malloc.h>
61b86044bglebius#include <sys/mutex.h>
62b86044bglebius#include <sys/kernel.h>
63b86044bglebius#include <sys/module.h>
64b86044bglebius#include <sys/socket.h>
65b86044bglebius#include <sys/sysctl.h>
66b86044bglebius#include <sys/queue.h>
67b86044bglebius
68b86044bglebius#include <net/bpf.h>
69b86044bglebius#include <net/ethernet.h>
70b86044bglebius#include <net/if.h>
71b86044bglebius#include <net/if_var.h>
72b86044bglebius#include <net/if_arp.h>
73b86044bglebius#include <net/if_dl.h>
74b86044bglebius#include <net/if_media.h>
75b86044bglebius
76b86044bglebius#include <net/if_types.h>
77b86044bglebius#include <net/if_vlan_var.h>
78b86044bglebius
79b86044bglebius#include <netinet/in_systm.h>
80b86044bglebius#include <netinet/in.h>
81b86044bglebius#include <netinet/if_ether.h>
82b86044bglebius#include <netinet/ip.h>
83b86044bglebius#include <netinet/ip6.h>
84b86044bglebius#include <netinet/tcp.h>
85b86044bglebius#include <netinet/udp.h>
86b86044bglebius
87b86044bglebius#include <machine/bus.h>
88b86044bglebius#include <machine/resource.h>
89b86044bglebius#include <sys/bus.h>
90b86044bglebius#include <sys/rman.h>
91b86044bglebius
92b86044bglebius#include <dev/mii/mii.h>
93b86044bglebius#include <dev/mii/miivar.h>
94b86044bglebius#include "miidevs.h"
95b86044bglebius#include <dev/mii/brgphyreg.h>
96b86044bglebius
97b86044bglebius#include <dev/pci/pcireg.h>
98b86044bglebius#include <dev/pci/pcivar.h>
99b86044bglebius
100b86044bglebius#include "miibus_if.h"
101b86044bglebius
102c2fa353ps#include <dev/bce/if_bcereg.h>
103c2fa353ps#include <dev/bce/if_bcefw.h>
104c2fa353ps
105c2fa353ps/****************************************************************************/
106c2fa353ps/* BCE Debug Options                                                        */
107c2fa353ps/****************************************************************************/
108c2fa353ps#ifdef BCE_DEBUG
109c2fa353ps	u32 bce_debug = BCE_WARN;
110c2fa353ps
111c2fa353ps	/*          0 = Never              */
112c2fa353ps	/*          1 = 1 in 2,147,483,648 */
113c2fa353ps	/*        256 = 1 in     8,388,608 */
114c2fa353ps	/*       2048 = 1 in     1,048,576 */
115c2fa353ps	/*      65536 = 1 in        32,768 */
116c2fa353ps	/*    1048576 = 1 in         2,048 */
117c2fa353ps	/*  268435456 =	1 in             8 */
118c2fa353ps	/*  536870912 = 1 in             4 */
119c2fa353ps	/* 1073741824 = 1 in             2 */
120c2fa353ps
121c2fa353ps	/* Controls how often the l2_fhdr frame error check will fail. */
1223b8bffcdavidch	int l2fhdr_error_sim_control = 0;
123c2fa353ps
124c2fa353ps	/* Controls how often the unexpected attention check will fail. */
1253b8bffcdavidch	int unexpected_attention_sim_control = 0;
126c2fa353ps
127c2fa353ps	/* Controls how often to simulate an mbuf allocation failure. */
1283b8bffcdavidch	int mbuf_alloc_failed_sim_control = 0;
129c2fa353ps
130c2fa353ps	/* Controls how often to simulate a DMA mapping failure. */
1313b8bffcdavidch	int dma_map_addr_failed_sim_control = 0;
132c2fa353ps
133c2fa353ps	/* Controls how often to simulate a bootcode failure. */
1343b8bffcdavidch	int bootcode_running_failure_sim_control = 0;
135c2fa353ps#endif
1360f2382bdavidch
1371a7f080davidch/****************************************************************************/
138c2fa353ps/* PCI Device ID Table                                                      */
139c2fa353ps/*                                                                          */
140c2fa353ps/* Used by bce_probe() to identify the devices supported by this driver.    */
141c2fa353ps/****************************************************************************/
142c2fa353ps#define BCE_DEVDESC_MAX		64
143c2fa353ps
1448dc4f9cmariusstatic const struct bce_type bce_devs[] = {
145c2fa353ps	/* BCM5706C Controllers and OEM boards. */
146c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
147c2fa353ps		"HP NC370T Multifunction Gigabit Server Adapter" },
148c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
149c2fa353ps		"HP NC370i Multifunction Gigabit Server Adapter" },
150b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
151b531710delphij		"HP NC380T PCIe DP Multifunc Gig Server Adapter" },
152b531710delphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
153b531710delphij		"HP NC371i Multifunction Gigabit Server Adapter" },
154c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
1558095e01davidcs		"QLogic NetXtreme II BCM5706 1000Base-T" },
156c2fa353ps
157c2fa353ps	/* BCM5706S controllers and OEM boards. */
158c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
159c2fa353ps		"HP NC370F Multifunction Gigabit Server Adapter" },
160c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
1618095e01davidcs		"QLogic NetXtreme II BCM5706 1000Base-SX" },
162c2fa353ps
163c2fa353ps	/* BCM5708C controllers and OEM boards. */
164b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
165b531710delphij		"HP NC373T PCIe Multifunction Gig Server Adapter" },
166b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
167b531710delphij		"HP NC373i Multifunction Gigabit Server Adapter" },
168b531710delphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
169b531710delphij		"HP NC374m PCIe Multifunction Adapter" },
170c2fa353ps	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
1718095e01davidcs		"QLogic NetXtreme II BCM5708 1000Base-T" },
172c2fa353ps
173c2fa353ps	/* BCM5708S controllers and OEM boards. */
174b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
175b531710delphij		"HP NC373m Multifunction Gigabit Server Adapter" },
176b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
177b531710delphij		"HP NC373i Multifunction Gigabit Server Adapter" },
178b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
179b531710delphij		"HP NC373F PCIe Multifunc Giga Server Adapter" },
18021803eascottl	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
1818095e01davidcs		"QLogic NetXtreme II BCM5708 1000Base-SX" },
1822156989davidch
1832156989davidch	/* BCM5709C controllers and OEM boards. */
184b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
185b531710delphij		"HP NC382i DP Multifunction Gigabit Server Adapter" },
186b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
187b531710delphij		"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
1882156989davidch	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
1898095e01davidcs		"QLogic NetXtreme II BCM5709 1000Base-T" },
1902156989davidch
1912156989davidch	/* BCM5709S controllers and OEM boards. */
192b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
193b531710delphij		"HP NC382m DP 1GbE Multifunction BL-c Adapter" },
194b997fbddelphij	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
195b531710delphij		"HP NC382i DP Multifunction Gigabit Server Adapter" },
1962156989davidch	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
1978095e01davidcs		"QLogic NetXtreme II BCM5709 1000Base-SX" },
1982156989davidch
1992156989davidch	/* BCM5716 controllers and OEM boards. */
2002156989davidch	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
2018095e01davidcs		"QLogic NetXtreme II BCM5716 1000Base-T" },
202c2fa353ps	{ 0, 0, 0, 0, NULL }
203c2fa353ps};
204c2fa353ps
205c2fa353ps/****************************************************************************/
206c2fa353ps/* Supported Flash NVRAM device data.                                       */
207c2fa353ps/****************************************************************************/
2088dc4f9cmariusstatic const struct flash_spec flash_table[] =
209c2fa353ps{
2102156989davidch#define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
2112156989davidch#define NONBUFFERED_FLAGS	(BCE_NV_WREN)
2122156989davidch
213c2fa353ps	/* Slow EEPROM */
214c2fa353ps	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
2152156989davidch	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
216c2fa353ps	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
217c2fa353ps	 "EEPROM - slow"},
218c2fa353ps	/* Expansion entry 0001 */
219c2fa353ps	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
2202156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
221c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
222c2fa353ps	 "Entry 0001"},
223c2fa353ps	/* Saifun SA25F010 (non-buffered flash) */
224c2fa353ps	/* strap, cfg1, & write1 need updates */
225c2fa353ps	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
2262156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
227c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
228c2fa353ps	 "Non-buffered flash (128kB)"},
229c2fa353ps	/* Saifun SA25F020 (non-buffered flash) */
230c2fa353ps	/* strap, cfg1, & write1 need updates */
231c2fa353ps	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
2322156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
233c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
234c2fa353ps	 "Non-buffered flash (256kB)"},
235c2fa353ps	/* Expansion entry 0100 */
236c2fa353ps	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
2372156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
238c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
239c2fa353ps	 "Entry 0100"},
240c2fa353ps	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
241c2fa353ps	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
2422156989davidch	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
243c2fa353ps	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
244c2fa353ps	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
245c2fa353ps	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
246c2fa353ps	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
2472156989davidch	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
248c2fa353ps	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
249c2fa353ps	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
250c2fa353ps	/* Saifun SA25F005 (non-buffered flash) */
251c2fa353ps	/* strap, cfg1, & write1 need updates */
252c2fa353ps	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
2532156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
254c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
255c2fa353ps	 "Non-buffered flash (64kB)"},
256c2fa353ps	/* Fast EEPROM */
257c2fa353ps	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
2582156989davidch	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
259c2fa353ps	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
260c2fa353ps	 "EEPROM - fast"},
261c2fa353ps	/* Expansion entry 1001 */
262c2fa353ps	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
2632156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
264c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
265c2fa353ps	 "Entry 1001"},
266c2fa353ps	/* Expansion entry 1010 */
267c2fa353ps	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
2682156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
269c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
270c2fa353ps	 "Entry 1010"},
271c2fa353ps	/* ATMEL AT45DB011B (buffered flash) */
272c2fa353ps	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
2732156989davidch	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
274c2fa353ps	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
275c2fa353ps	 "Buffered flash (128kB)"},
276c2fa353ps	/* Expansion entry 1100 */
277c2fa353ps	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
2782156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
279c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
280c2fa353ps	 "Entry 1100"},
281c2fa353ps	/* Expansion entry 1101 */
282c2fa353ps	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
2832156989davidch	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
284c2fa353ps	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
285c2fa353ps	 "Entry 1101"},
286c2fa353ps	/* Ateml Expansion entry 1110 */
287c2fa353ps	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
2882156989davidch	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
289c2fa353ps	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
290c2fa353ps	 "Entry 1110 (Atmel)"},
291c2fa353ps	/* ATMEL AT45DB021B (buffered flash) */
292c2fa353ps	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
2932156989davidch	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
294c2fa353ps	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
295c2fa353ps	 "Buffered flash (256kB)"},
296c2fa353ps};
297c2fa353ps
2982156989davidch/*
2992156989davidch * The BCM5709 controllers transparently handle the
3002156989davidch * differences between Atmel 264 byte pages and all
3012156989davidch * flash devices which use 256 byte pages, so no
3022156989davidch * logical-to-physical mapping is required in the
3032156989davidch * driver.
3042156989davidch */
3058dc4f9cmariusstatic const struct flash_spec flash_5709 = {
3062156989davidch	.flags		= BCE_NV_BUFFERED,
3072156989davidch	.page_bits	= BCM5709_FLASH_PAGE_BITS,
3082156989davidch	.page_size	= BCM5709_FLASH_PAGE_SIZE,
3092156989davidch	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
3102156989davidch	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
311fecec6adavidch	.name		= "5709/5716 buffered flash (256kB)",
3122156989davidch};
3132156989davidch
314c2fa353ps/****************************************************************************/
315c2fa353ps/* FreeBSD device entry points.                                             */
316c2fa353ps/****************************************************************************/
317d037577davidchstatic int  bce_probe			(device_t);
318d037577davidchstatic int  bce_attach			(device_t);
319d037577davidchstatic int  bce_detach			(device_t);
320d037577davidchstatic int  bce_shutdown		(device_t);
321c2fa353ps
322c2fa353ps/****************************************************************************/
323c2fa353ps/* BCE Debug Data Structure Dump Routines                                   */
324c2fa353ps/****************************************************************************/
325c2fa353ps#ifdef BCE_DEBUG
32693acd8bdavidchstatic u32  bce_reg_rd				(struct bce_softc *, u32);
32793acd8bdavidchstatic void bce_reg_wr				(struct bce_softc *, u32, u32);
32893acd8bdavidchstatic void bce_reg_wr16			(struct bce_softc *, u32, u16);
32993acd8bdavidchstatic u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
33093acd8bdavidchstatic void bce_dump_enet			(struct bce_softc *, struct mbuf *);
33193acd8bdavidchstatic void bce_dump_mbuf			(struct bce_softc *, struct mbuf *);
332179a317davidchstatic void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
333179a317davidchstatic void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
3342156989davidchstatic void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
33593acd8bdavidchstatic void bce_dump_txbd			(struct bce_softc *,
336d037577davidch    int, struct tx_bd *);
33793acd8bdavidchstatic void bce_dump_rxbd			(struct bce_softc *,
338d037577davidch    int, struct rx_bd *);
33993acd8bdavidchstatic void bce_dump_pgbd			(struct bce_softc *,
340d037577davidch    int, struct rx_bd *);
341d037577davidchstatic void bce_dump_l2fhdr		(struct bce_softc *,
342d037577davidch    int, struct l2_fhdr *);
34393acd8bdavidchstatic void bce_dump_ctx			(struct bce_softc *, u16);
34493acd8bdavidchstatic void bce_dump_ftqs			(struct bce_softc *);
345179a317davidchstatic void bce_dump_tx_chain		(struct bce_softc *, u16, int);
346d037577davidchstatic void bce_dump_rx_bd_chain	(struct bce_softc *, u16, int);
3472156989davidchstatic void bce_dump_pg_chain		(struct bce_softc *, u16, int);
348c2fa353psstatic void bce_dump_status_block	(struct bce_softc *);
349c2fa353psstatic void bce_dump_stats_block	(struct bce_softc *);
350c2fa353psstatic void bce_dump_driver_state	(struct bce_softc *);
351c2fa353psstatic void bce_dump_hw_state		(struct bce_softc *);
35293acd8bdavidchstatic void bce_dump_shmem_state	(struct bce_softc *);
353d037577davidchstatic void bce_dump_mq_regs		(struct bce_softc *);
354f35e9ebdavidchstatic void bce_dump_bc_state		(struct bce_softc *);
3552156989davidchstatic void bce_dump_txp_state		(struct bce_softc *, int);
3562156989davidchstatic void bce_dump_rxp_state		(struct bce_softc *, int);
35793acd8bdavidchstatic void bce_dump_tpat_state	(struct bce_softc *, int);
3582156989davidchstatic void bce_dump_cp_state		(struct bce_softc *, int);
3592156989davidchstatic void bce_dump_com_state		(struct bce_softc *, int);
36093acd8bdavidchstatic void bce_dump_rv2p_state	(struct bce_softc *);
36193acd8bdavidchstatic void bce_breakpoint			(struct bce_softc *);
36293acd8bdavidch#endif /*BCE_DEBUG */
363c2fa353ps
364c2fa353ps/****************************************************************************/
365c2fa353ps/* BCE Register/Memory Access Routines                                      */
366c2fa353ps/****************************************************************************/
367d037577davidchstatic u32  bce_reg_rd_ind		(struct bce_softc *, u32);
368d037577davidchstatic void bce_reg_wr_ind		(struct bce_softc *, u32, u32);
369d037577davidchstatic void bce_shmem_wr		(struct bce_softc *, u32, u32);
370d037577davidchstatic u32  bce_shmem_rd		(struct bce_softc *, u32);
371d037577davidchstatic void bce_ctx_wr			(struct bce_softc *, u32, u32, u32);
372c2fa353psstatic int  bce_miibus_read_reg		(device_t, int, int);
373c2fa353psstatic int  bce_miibus_write_reg	(device_t, int, int, int);
374c2fa353psstatic void bce_miibus_statchg		(device_t);
375c2fa353ps
37681421f8ambrisko#ifdef BCE_DEBUG
3776bdddc8davidchstatic int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
37881421f8ambrisko#ifdef BCE_NVRAM_WRITE_SUPPORT
3796bdddc8davidchstatic int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
38081421f8ambrisko#endif
38181421f8ambrisko#endif
382c2fa353ps
383c2fa353ps/****************************************************************************/
384c2fa353ps/* BCE NVRAM Access Routines                                                */
385c2fa353ps/****************************************************************************/
386c2fa353psstatic int  bce_acquire_nvram_lock	(struct bce_softc *);
387c2fa353psstatic int  bce_release_nvram_lock	(struct bce_softc *);
38893acd8bdavidchstatic void bce_enable_nvram_access(struct bce_softc *);
38993acd8bdavidchstatic void bce_disable_nvram_access(struct bce_softc *);
390c2fa353psstatic int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
39193acd8bdavidchstatic int  bce_init_nvram			(struct bce_softc *);
39293acd8bdavidchstatic int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
39393acd8bdavidchstatic int  bce_nvram_test			(struct bce_softc *);
394c2fa353ps#ifdef BCE_NVRAM_WRITE_SUPPORT
395c2fa353psstatic int  bce_enable_nvram_write	(struct bce_softc *);
39693acd8bdavidchstatic void bce_disable_nvram_write(struct bce_softc *);
397c2fa353psstatic int  bce_nvram_erase_page	(struct bce_softc *, u32);
398c2fa353psstatic int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
399d037577davidchstatic int  bce_nvram_write		(struct bce_softc *, u32, u8 *, int);
400c2fa353ps#endif
401c2fa353ps
402c2fa353ps/****************************************************************************/
403c2fa353ps/*                                                                          */
404c2fa353ps/****************************************************************************/
40593acd8bdavidchstatic void bce_get_rx_buffer_sizes(struct bce_softc *, int);
40693acd8bdavidchstatic void bce_get_media			(struct bce_softc *);
40793acd8bdavidchstatic void bce_init_media			(struct bce_softc *);
40862a2488yongaristatic u32 bce_get_rphy_link		(struct bce_softc *);
40993acd8bdavidchstatic void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
41093acd8bdavidchstatic int  bce_dma_alloc			(device_t);
41193acd8bdavidchstatic void bce_dma_free			(struct bce_softc *);
412c2fa353psstatic void bce_release_resources	(struct bce_softc *);
413c2fa353ps
414c2fa353ps/****************************************************************************/
415c2fa353ps/* BCE Firmware Synchronization and Load                                    */
416c2fa353ps/****************************************************************************/
41762a2488yongaristatic void bce_fw_cap_init			(struct bce_softc *);
418d037577davidchstatic int  bce_fw_sync			(struct bce_softc *, u32);
419c9d284cmariusstatic void bce_load_rv2p_fw		(struct bce_softc *, const u32 *, u32,
420c9d284cmarius    u32);
4215724de4davidchstatic void bce_load_cpu_fw		(struct bce_softc *,
422d037577davidch    struct cpu_reg *, struct fw_info *);
42393acd8bdavidchstatic void bce_start_cpu			(struct bce_softc *, struct cpu_reg *);
42493acd8bdavidchstatic void bce_halt_cpu			(struct bce_softc *, struct cpu_reg *);
425d037577davidchstatic void bce_start_rxp_cpu		(struct bce_softc *);
4262156989davidchstatic void bce_init_rxp_cpu		(struct bce_softc *);
4272156989davidchstatic void bce_init_txp_cpu 		(struct bce_softc *);
4282156989davidchstatic void bce_init_tpat_cpu		(struct bce_softc *);
429d037577davidchstatic void bce_init_cp_cpu	  	(struct bce_softc *);
4302156989davidchstatic void bce_init_com_cpu	  	(struct bce_softc *);
43193acd8bdavidchstatic void bce_init_cpus			(struct bce_softc *);
432c2fa353ps
43393acd8bdavidchstatic void bce_print_adapter_info	(struct bce_softc *);
4342156989davidchstatic void bce_probe_pci_caps		(device_t, struct bce_softc *);
43593acd8bdavidchstatic void bce_stop				(struct bce_softc *);
43693acd8bdavidchstatic int  bce_reset				(struct bce_softc *, u32);
43793acd8bdavidchstatic int  bce_chipinit 			(struct bce_softc *);
43893acd8bdavidchstatic int  bce_blockinit 			(struct bce_softc *);
439c2fa353ps
440c2fa353psstatic int  bce_init_tx_chain		(struct bce_softc *);
441179a317davidchstatic void bce_free_tx_chain		(struct bce_softc *);
442179a317davidch
443910939cmariusstatic int  bce_get_rx_buf		(struct bce_softc *, u16, u16, u32 *);
444c2fa353psstatic int  bce_init_rx_chain		(struct bce_softc *);
445179a317davidchstatic void bce_fill_rx_chain		(struct bce_softc *);
446c2fa353psstatic void bce_free_rx_chain		(struct bce_softc *);
4472156989davidch
448910939cmariusstatic int  bce_get_pg_buf		(struct bce_softc *, u16, u16);
449179a317davidchstatic int  bce_init_pg_chain		(struct bce_softc *);
450179a317davidchstatic void bce_fill_pg_chain		(struct bce_softc *);
4512156989davidchstatic void bce_free_pg_chain		(struct bce_softc *);
452c2fa353ps
4535724de4davidchstatic struct mbuf *bce_tso_setup	(struct bce_softc *,
454d037577davidch    struct mbuf **, u16 *);
45593acd8bdavidchstatic int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
456c2fa353psstatic void bce_start_locked		(struct ifnet *);
457fe82580glebiusstatic void bce_start			(struct ifnet *);
458fe82580glebiusstatic int  bce_ioctl			(struct ifnet *, u_long, caddr_t);
459fe82580glebiusstatic uint64_t bce_get_counter		(struct ifnet *, ift_counter);
460fe82580glebiusstatic void bce_watchdog		(struct bce_softc *);
461d037577davidchstatic int  bce_ifmedia_upd		(struct ifnet *);
4620e81d4dyongaristatic int  bce_ifmedia_upd_locked	(struct ifnet *);
463d037577davidchstatic void bce_ifmedia_sts		(struct ifnet *, struct ifmediareq *);
46462a2488yongaristatic void bce_ifmedia_sts_rphy	(struct bce_softc *, struct ifmediareq *);
465d037577davidchstatic void bce_init_locked		(struct bce_softc *);
46693acd8bdavidchstatic void bce_init				(void *);
467788fd40davidchstatic void bce_mgmt_init_locked	(struct bce_softc *sc);
468c2fa353ps
46993acd8bdavidchstatic int  bce_init_ctx			(struct bce_softc *);
470c2fa353psstatic void bce_get_mac_addr		(struct bce_softc *);
471c2fa353psstatic void bce_set_mac_addr		(struct bce_softc *);
47293acd8bdavidchstatic void bce_phy_intr			(struct bce_softc *);
473d037577davidchstatic inline u16 bce_get_hw_rx_cons	(struct bce_softc *);
474d037577davidchstatic void bce_rx_intr			(struct bce_softc *);
475d037577davidchstatic void bce_tx_intr			(struct bce_softc *);
476c2fa353psstatic void bce_disable_intr		(struct bce_softc *);
477d037577davidchstatic void bce_enable_intr		(struct bce_softc *, int);
4782156989davidch
47993acd8bdavidchstatic void bce_intr				(void *);
480d037577davidchstatic void bce_set_rx_mode		(struct bce_softc *);
481c2fa353psstatic void bce_stats_update		(struct bce_softc *);
48293acd8bdavidchstatic void bce_tick				(void *);
48393acd8bdavidchstatic void bce_pulse				(void *);
484d037577davidchstatic void bce_add_sysctls		(struct bce_softc *);
485c2fa353ps
486c2fa353ps/****************************************************************************/
487c2fa353ps/* FreeBSD device dispatch table.                                           */
488c2fa353ps/****************************************************************************/
489c2fa353psstatic device_method_t bce_methods[] = {
490179a317davidch	/* Device interface (device_if.h) */
491c2fa353ps	DEVMETHOD(device_probe,		bce_probe),
492c2fa353ps	DEVMETHOD(device_attach,	bce_attach),
493c2fa353ps	DEVMETHOD(device_detach,	bce_detach),
494c2fa353ps	DEVMETHOD(device_shutdown,	bce_shutdown),
4950f2382bdavidch/* Supported by device interface but not used here. */
496179a317davidch/*	DEVMETHOD(device_identify,	bce_identify),      */
497179a317davidch/*	DEVMETHOD(device_suspend,	bce_suspend),       */
498179a317davidch/*	DEVMETHOD(device_resume,	bce_resume),        */
499179a317davidch/*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
500c2fa353ps
501179a317davidch	/* MII interface (miibus_if.h) */
502c2fa353ps	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
503c2fa353ps	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
504c2fa353ps	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
5050f2382bdavidch/* Supported by MII interface but not used here.       */
506179a317davidch/*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
507179a317davidch/*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
508c2fa353ps
50917e14c6marius	DEVMETHOD_END
510c2fa353ps};
511c2fa353ps
512c2fa353psstatic driver_t bce_driver = {
513c2fa353ps	"bce",
514c2fa353ps	bce_methods,
515c2fa353ps	sizeof(struct bce_softc)
516c2fa353ps};
517c2fa353ps
518c2fa353psstatic devclass_t bce_devclass;
519c2fa353ps
520c2fa353psMODULE_DEPEND(bce, pci, 1, 1, 1);
521c2fa353psMODULE_DEPEND(bce, ether, 1, 1, 1);
522c2fa353psMODULE_DEPEND(bce, miibus, 1, 1, 1);
523c2fa353ps
5248dc4f9cmariusDRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL);
5258dc4f9cmariusDRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL);
526b0ccb12impMODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce,
5278efc2b3imp    bce_devs, nitems(bce_devs) - 1);
528d5a0460davidch
5290dfe831davidch/****************************************************************************/
5300dfe831davidch/* Tunable device values                                                    */
5310dfe831davidch/****************************************************************************/
532ad355b0kaktusstatic SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
533ad355b0kaktus    "bce driver parameters");
534179a317davidch
535d5a0460davidch/* Allowable values are TRUE or FALSE */
53693acd8bdavidchstatic int bce_verbose = TRUE;
53793acd8bdavidchSYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
53893acd8bdavidch    "Verbose output enable/disable");
53993acd8bdavidch
54093acd8bdavidch/* Allowable values are TRUE or FALSE */
5412156989davidchstatic int bce_tso_enable = TRUE;
5428045b08mdfSYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
54393acd8bdavidch    "TSO Enable/Disable");
544179a317davidch
5452156989davidch/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
5462156989davidch/* ToDo: Add MSI-X support. */
5472156989davidchstatic int bce_msi_enable = 1;
5488045b08mdfSYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
54993acd8bdavidch    "MSI-X|MSI|INTx selector");
55093acd8bdavidch
55193acd8bdavidch/* Allowable values are 1, 2, 4, 8. */
55293acd8bdavidchstatic int bce_rx_pages = DEFAULT_RX_PAGES;
55393acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
55493acd8bdavidch    "Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
55593acd8bdavidch
55693acd8bdavidch/* Allowable values are 1, 2, 4, 8. */
55793acd8bdavidchstatic int bce_tx_pages = DEFAULT_TX_PAGES;
55893acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
55993acd8bdavidch    "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
56093acd8bdavidch
56193acd8bdavidch/* Allowable values are TRUE or FALSE. */
56293acd8bdavidchstatic int bce_hdr_split = TRUE;
56393acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
56493acd8bdavidch    "Frame header/payload splitting Enable/Disable");
56593acd8bdavidch
56693acd8bdavidch/* Allowable values are TRUE or FALSE. */
56793acd8bdavidchstatic int bce_strict_rx_mtu = FALSE;
568680cd1fdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN,
56993acd8bdavidch    &bce_strict_rx_mtu, 0,
57093acd8bdavidch    "Enable/Disable strict RX frame size checking");
57193acd8bdavidch
57293acd8bdavidch/* Allowable values are 0 ... 100 */
57393acd8bdavidch#ifdef BCE_DEBUG
57493acd8bdavidch/* Generate 1 interrupt for every transmit completion. */
57593acd8bdavidchstatic int bce_tx_quick_cons_trip_int = 1;
57693acd8bdavidch#else
57793acd8bdavidch/* Generate 1 interrupt for every 20 transmit completions. */
57893acd8bdavidchstatic int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
57993acd8bdavidch#endif
58093acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
58193acd8bdavidch    &bce_tx_quick_cons_trip_int, 0,
58293acd8bdavidch    "Transmit BD trip point during interrupts");
5830f2382bdavidch
58493acd8bdavidch/* Allowable values are 0 ... 100 */
58593acd8bdavidch/* Generate 1 interrupt for every transmit completion. */
58693acd8bdavidch#ifdef BCE_DEBUG
58793acd8bdavidchstatic int bce_tx_quick_cons_trip = 1;
58893acd8bdavidch#else
58993acd8bdavidch/* Generate 1 interrupt for every 20 transmit completions. */
59093acd8bdavidchstatic int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
59193acd8bdavidch#endif
59293acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
59393acd8bdavidch    &bce_tx_quick_cons_trip, 0,
59493acd8bdavidch    "Transmit BD trip point");
59593acd8bdavidch
59693acd8bdavidch/* Allowable values are 0 ... 100 */
59793acd8bdavidch#ifdef BCE_DEBUG
59893acd8bdavidch/* Generate an interrupt if 0us have elapsed since the last TX completion. */
59993acd8bdavidchstatic int bce_tx_ticks_int = 0;
60093acd8bdavidch#else
60193acd8bdavidch/* Generate an interrupt if 80us have elapsed since the last TX completion. */
60293acd8bdavidchstatic int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
60393acd8bdavidch#endif
60493acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
60593acd8bdavidch    &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
60693acd8bdavidch
60793acd8bdavidch/* Allowable values are 0 ... 100 */
60893acd8bdavidch#ifdef BCE_DEBUG
60993acd8bdavidch/* Generate an interrupt if 0us have elapsed since the last TX completion. */
61093acd8bdavidchstatic int bce_tx_ticks = 0;
61193acd8bdavidch#else
61293acd8bdavidch/* Generate an interrupt if 80us have elapsed since the last TX completion. */
61393acd8bdavidchstatic int bce_tx_ticks = DEFAULT_TX_TICKS;
61493acd8bdavidch#endif
61593acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
61693acd8bdavidch    &bce_tx_ticks, 0, "Transmit ticks count");
61793acd8bdavidch
61893acd8bdavidch/* Allowable values are 1 ... 100 */
61993acd8bdavidch#ifdef BCE_DEBUG
62093acd8bdavidch/* Generate 1 interrupt for every received frame. */
62193acd8bdavidchstatic int bce_rx_quick_cons_trip_int = 1;
62293acd8bdavidch#else
62393acd8bdavidch/* Generate 1 interrupt for every 6 received frames. */
62493acd8bdavidchstatic int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
62593acd8bdavidch#endif
62693acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
62793acd8bdavidch    &bce_rx_quick_cons_trip_int, 0,
62893acd8bdavidch    "Receive BD trip point duirng interrupts");
62993acd8bdavidch
63093acd8bdavidch/* Allowable values are 1 ... 100 */
63193acd8bdavidch#ifdef BCE_DEBUG
63293acd8bdavidch/* Generate 1 interrupt for every received frame. */
63393acd8bdavidchstatic int bce_rx_quick_cons_trip = 1;
63493acd8bdavidch#else
63593acd8bdavidch/* Generate 1 interrupt for every 6 received frames. */
63693acd8bdavidchstatic int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
63793acd8bdavidch#endif
63893acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
63993acd8bdavidch    &bce_rx_quick_cons_trip, 0,
64093acd8bdavidch    "Receive BD trip point");
64193acd8bdavidch
64293acd8bdavidch/* Allowable values are 0 ... 100 */
64393acd8bdavidch#ifdef BCE_DEBUG
64493acd8bdavidch/* Generate an int. if 0us have elapsed since the last received frame. */
64593acd8bdavidchstatic int bce_rx_ticks_int = 0;
64693acd8bdavidch#else
64793acd8bdavidch/* Generate an int. if 18us have elapsed since the last received frame. */
64893acd8bdavidchstatic int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
64993acd8bdavidch#endif
65093acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
65193acd8bdavidch    &bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
65293acd8bdavidch
65393acd8bdavidch/* Allowable values are 0 ... 100 */
65493acd8bdavidch#ifdef BCE_DEBUG
65593acd8bdavidch/* Generate an int. if 0us have elapsed since the last received frame. */
65693acd8bdavidchstatic int bce_rx_ticks = 0;
65793acd8bdavidch#else
65893acd8bdavidch/* Generate an int. if 18us have elapsed since the last received frame. */
65993acd8bdavidchstatic int bce_rx_ticks = DEFAULT_RX_TICKS;
66093acd8bdavidch#endif
66193acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
66293acd8bdavidch    &bce_rx_ticks, 0, "Receive ticks count");
663d5a0460davidch
664c2fa353ps/****************************************************************************/
665c2fa353ps/* Device probe function.                                                   */
666c2fa353ps/*                                                                          */
667c2fa353ps/* Compares the device to the driver's list of supported devices and        */
668c2fa353ps/* reports back to the OS whether this is the right driver for the device.  */
669c2fa353ps/*                                                                          */
670c2fa353ps/* Returns:                                                                 */
671c2fa353ps/*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
672c2fa353ps/****************************************************************************/
673c2fa353psstatic int
674c2fa353psbce_probe(device_t dev)
675c2fa353ps{
6768dc4f9cmarius	const struct bce_type *t;
677c2fa353ps	struct bce_softc *sc;
678c2fa353ps	char *descbuf;
679c2fa353ps	u16 vid = 0, did = 0, svid = 0, sdid = 0;
680c2fa353ps
681c2fa353ps	t = bce_devs;
682c2fa353ps
683c2fa353ps	sc = device_get_softc(dev);
684c2fa353ps	sc->bce_unit = device_get_unit(dev);
685c2fa353ps	sc->bce_dev = dev;
686c2fa353ps
687c2fa353ps	/* Get the data for the device to be probed. */
688c2fa353ps	vid  = pci_get_vendor(dev);
689c2fa353ps	did  = pci_get_device(dev);
690c2fa353ps	svid = pci_get_subvendor(dev);
691c2fa353ps	sdid = pci_get_subdevice(dev);
692c2fa353ps
6932156989davidch	DBPRINT(sc, BCE_EXTREME_LOAD,
694d037577davidch	    "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
695d037577davidch	    "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
696c2fa353ps
697c2fa353ps	/* Look through the list of known devices for a match. */
698c2fa353ps	while(t->bce_name != NULL) {
6992156989davidch		if ((vid == t->bce_vid) && (did == t->bce_did) &&
700d037577davidch		    ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
701d037577davidch		    ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
702c2fa353ps			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
703c2fa353ps
704c2fa353ps			if (descbuf == NULL)
705c2fa353ps				return(ENOMEM);
706c2fa353ps
707c2fa353ps			/* Print out the device identity. */
7082156989davidch			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
7095724de4davidch			    t->bce_name, (((pci_read_config(dev,
710d037577davidch			    PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
7116ab1aa7davidch			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
712c2fa353ps
713c2fa353ps			device_set_desc_copy(dev, descbuf);
714c2fa353ps			free(descbuf, M_TEMP);
715c2fa353ps			return(BUS_PROBE_DEFAULT);
716c2fa353ps		}
717c2fa353ps		t++;
718c2fa353ps	}
719c2fa353ps
720c2fa353ps	return(ENXIO);
721c2fa353ps}
722c2fa353ps
723c2fa353ps/****************************************************************************/
7242156989davidch/* PCI Capabilities Probe Function.                                         */
7252156989davidch/*                                                                          */
7262156989davidch/* Walks the PCI capabiites list for the device to find what features are   */
7272156989davidch/* supported.                                                               */
7282156989davidch/*                                                                          */
7292156989davidch/* Returns:                                                                 */
7302156989davidch/*   None.                                                                  */
7312156989davidch/****************************************************************************/
7322156989davidchstatic void
7332156989davidchbce_print_adapter_info(struct bce_softc *sc)
7342156989davidch{
7355724de4davidch	int i = 0;
736daf61e7davidch
7372156989davidch	DBENTER(BCE_VERBOSE_LOAD);
7382156989davidch
73993acd8bdavidch	if (bce_verbose || bootverbose) {
7405724de4davidch		BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
7415724de4davidch		printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
7425724de4davidch		    12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
7435724de4davidch
7445724de4davidch		/* Bus info. */
7455724de4davidch		if (sc->bce_flags & BCE_PCIE_FLAG) {
7465724de4davidch			printf("Bus (PCIe x%d, ", sc->link_width);
7475724de4davidch			switch (sc->link_speed) {
7485724de4davidch			case 1: printf("2.5Gbps); "); break;
7495724de4davidch			case 2:	printf("5Gbps); "); break;
7505724de4davidch			default: printf("Unknown link speed); ");
7515724de4davidch			}
7525724de4davidch		} else {
7535724de4davidch			printf("Bus (PCI%s, %s, %dMHz); ",
7545724de4davidch			    ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
7555724de4davidch			    ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
7565724de4davidch			    "32-bit" : "64-bit"), sc->bus_speed_mhz);
7572156989davidch		}
7582156989davidch
7595724de4davidch		/* Firmware version and device features. */
76093acd8bdavidch		printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
76193acd8bdavidch		    sc->bce_bc_ver,	sc->rx_pages, sc->tx_pages,
76293acd8bdavidch		    (bce_hdr_split == TRUE ? sc->pg_pages: 0));
763daf61e7davidch
76493acd8bdavidch		if (bce_hdr_split == TRUE) {
76593acd8bdavidch			printf("SPLT");
76693acd8bdavidch			i++;
76793acd8bdavidch		}
768569289cdavidch
7695724de4davidch		if (sc->bce_flags & BCE_USING_MSI_FLAG) {
7705724de4davidch			if (i > 0) printf("|");
7715724de4davidch			printf("MSI"); i++;
7725724de4davidch		}
773daf61e7davidch
7745724de4davidch		if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
7755724de4davidch			if (i > 0) printf("|");
7765724de4davidch			printf("MSI-X"); i++;
7775724de4davidch		}
778daf61e7davidch
7795724de4davidch		if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
7805724de4davidch			if (i > 0) printf("|");
7815724de4davidch			printf("2.5G"); i++;
7825724de4davidch		}
783daf61e7davidch
78462a2488yongari		if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
78562a2488yongari			if (i > 0) printf("|");
78662a2488yongari			printf("Remote PHY(%s)",
78762a2488yongari			    sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
78862a2488yongari			    "FIBER" : "TP"); i++;
78962a2488yongari		}
79062a2488yongari
7915724de4davidch		if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7925724de4davidch			if (i > 0) printf("|");
7935724de4davidch			printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
7945724de4davidch		} else {
7955724de4davidch			printf(")\n");
7965724de4davidch		}
79793acd8bdavidch
79893acd8bdavidch		printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
79993acd8bdavidch		    sc->bce_rx_quick_cons_trip_int,
80093acd8bdavidch		    sc->bce_rx_quick_cons_trip,
80193acd8bdavidch		    sc->bce_rx_ticks_int,
80293acd8bdavidch		    sc->bce_rx_ticks,
80393acd8bdavidch		    sc->bce_tx_quick_cons_trip_int,
80493acd8bdavidch		    sc->bce_tx_quick_cons_trip,
80593acd8bdavidch		    sc->bce_tx_ticks_int,
80693acd8bdavidch		    sc->bce_tx_ticks);
807d037577davidch	}
8082156989davidch
8095297261phk	DBEXIT(BCE_VERBOSE_LOAD);
8102156989davidch}
8112156989davidch
8122156989davidch/****************************************************************************/
8132156989davidch/* PCI Capabilities Probe Function.                                         */
8142156989davidch/*                                                                          */
8152156989davidch/* Walks the PCI capabiites list for the device to find what features are   */
8162156989davidch/* supported.                                                               */
8172156989davidch/*                                                                          */
8182156989davidch/* Returns:                                                                 */
8192156989davidch/*   None.                                                                  */
8202156989davidch/****************************************************************************/
8212156989davidchstatic void
8222156989davidchbce_probe_pci_caps(device_t dev, struct bce_softc *sc)
8232156989davidch{
8242156989davidch	u32 reg;
8252156989davidch
8262156989davidch	DBENTER(BCE_VERBOSE_LOAD);
8272156989davidch
8282156989davidch	/* Check if PCI-X capability is enabled. */
82900c3c01jhb	if (pci_find_cap(dev, PCIY_PCIX, &reg) == 0) {
8302156989davidch		if (reg != 0)
8312156989davidch			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
8322156989davidch	}
8332156989davidch
8342156989davidch	/* Check if PCIe capability is enabled. */
83500c3c01jhb	if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
8362156989davidch		if (reg != 0) {
8372156989davidch			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
838d037577davidch			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
839d037577davidch			    "0x%08X\n",	link_status);
8402156989davidch			sc->link_speed = link_status & 0xf;
8412156989davidch			sc->link_width = (link_status >> 4) & 0x3f;
8422156989davidch			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
8432156989davidch			sc->bce_flags |= BCE_PCIE_FLAG;
8442156989davidch		}
8452156989davidch	}
8462156989davidch
8472156989