Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bce/if_bce.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2006-2014 QLogic Corporation
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26
* THE POSSIBILITY OF SUCH DAMAGE.
27
*/
28
29
#include <sys/cdefs.h>
30
/*
31
* The following controllers are supported by this driver:
32
* BCM5706C A2, A3
33
* BCM5706S A2, A3
34
* BCM5708C B1, B2
35
* BCM5708S B1, B2
36
* BCM5709C A1, C0
37
* BCM5709S A1, C0
38
* BCM5716C C0
39
* BCM5716S C0
40
*
41
* The following controllers are not supported by this driver:
42
* BCM5706C A0, A1 (pre-production)
43
* BCM5706S A0, A1 (pre-production)
44
* BCM5708C A0, B0 (pre-production)
45
* BCM5708S A0, B0 (pre-production)
46
* BCM5709C A0 B0, B1, B2 (pre-production)
47
* BCM5709S A0, B0, B1, B2 (pre-production)
48
*/
49
50
#include "opt_bce.h"
51
52
#include <sys/param.h>
53
#include <sys/endian.h>
54
#include <sys/systm.h>
55
#include <sys/sockio.h>
56
#include <sys/lock.h>
57
#include <sys/mbuf.h>
58
#include <sys/malloc.h>
59
#include <sys/mutex.h>
60
#include <sys/kernel.h>
61
#include <sys/module.h>
62
#include <sys/socket.h>
63
#include <sys/sysctl.h>
64
#include <sys/queue.h>
65
66
#include <net/bpf.h>
67
#include <net/ethernet.h>
68
#include <net/if.h>
69
#include <net/if_var.h>
70
#include <net/if_arp.h>
71
#include <net/if_dl.h>
72
#include <net/if_media.h>
73
74
#include <net/if_types.h>
75
#include <net/if_vlan_var.h>
76
77
#include <netinet/in_systm.h>
78
#include <netinet/in.h>
79
#include <netinet/if_ether.h>
80
#include <netinet/ip.h>
81
#include <netinet/ip6.h>
82
#include <netinet/tcp.h>
83
#include <netinet/udp.h>
84
85
#include <machine/bus.h>
86
#include <machine/resource.h>
87
#include <sys/bus.h>
88
#include <sys/rman.h>
89
90
#include <dev/mii/mii.h>
91
#include <dev/mii/miivar.h>
92
#include "miidevs.h"
93
#include <dev/mii/brgphyreg.h>
94
95
#include <dev/pci/pcireg.h>
96
#include <dev/pci/pcivar.h>
97
98
#include "miibus_if.h"
99
100
#include <dev/bce/if_bcereg.h>
101
#include <dev/bce/if_bcefw.h>
102
103
/****************************************************************************/
104
/* BCE Debug Options */
105
/****************************************************************************/
106
#ifdef BCE_DEBUG
107
u32 bce_debug = BCE_WARN;
108
109
/* 0 = Never */
110
/* 1 = 1 in 2,147,483,648 */
111
/* 256 = 1 in 8,388,608 */
112
/* 2048 = 1 in 1,048,576 */
113
/* 65536 = 1 in 32,768 */
114
/* 1048576 = 1 in 2,048 */
115
/* 268435456 = 1 in 8 */
116
/* 536870912 = 1 in 4 */
117
/* 1073741824 = 1 in 2 */
118
119
/* Controls how often the l2_fhdr frame error check will fail. */
120
int l2fhdr_error_sim_control = 0;
121
122
/* Controls how often the unexpected attention check will fail. */
123
int unexpected_attention_sim_control = 0;
124
125
/* Controls how often to simulate an mbuf allocation failure. */
126
int mbuf_alloc_failed_sim_control = 0;
127
128
/* Controls how often to simulate a DMA mapping failure. */
129
int dma_map_addr_failed_sim_control = 0;
130
131
/* Controls how often to simulate a bootcode failure. */
132
int bootcode_running_failure_sim_control = 0;
133
#endif
134
135
/****************************************************************************/
136
/* PCI Device ID Table */
137
/* */
138
/* Used by bce_probe() to identify the devices supported by this driver. */
139
/****************************************************************************/
140
#define BCE_DEVDESC_MAX 64
141
142
static const struct bce_type bce_devs[] = {
143
/* BCM5706C Controllers and OEM boards. */
144
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3101,
145
"HP NC370T Multifunction Gigabit Server Adapter" },
146
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3106,
147
"HP NC370i Multifunction Gigabit Server Adapter" },
148
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3070,
149
"HP NC380T PCIe DP Multifunc Gig Server Adapter" },
150
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x1709,
151
"HP NC371i Multifunction Gigabit Server Adapter" },
152
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, PCI_ANY_ID, PCI_ANY_ID,
153
"QLogic NetXtreme II BCM5706 1000Base-T" },
154
155
/* BCM5706S controllers and OEM boards. */
156
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
157
"HP NC370F Multifunction Gigabit Server Adapter" },
158
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID, PCI_ANY_ID,
159
"QLogic NetXtreme II BCM5706 1000Base-SX" },
160
161
/* BCM5708C controllers and OEM boards. */
162
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7037,
163
"HP NC373T PCIe Multifunction Gig Server Adapter" },
164
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7038,
165
"HP NC373i Multifunction Gigabit Server Adapter" },
166
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7045,
167
"HP NC374m PCIe Multifunction Adapter" },
168
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708, PCI_ANY_ID, PCI_ANY_ID,
169
"QLogic NetXtreme II BCM5708 1000Base-T" },
170
171
/* BCM5708S controllers and OEM boards. */
172
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x1706,
173
"HP NC373m Multifunction Gigabit Server Adapter" },
174
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703b,
175
"HP NC373i Multifunction Gigabit Server Adapter" },
176
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703d,
177
"HP NC373F PCIe Multifunc Giga Server Adapter" },
178
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, PCI_ANY_ID, PCI_ANY_ID,
179
"QLogic NetXtreme II BCM5708 1000Base-SX" },
180
181
/* BCM5709C controllers and OEM boards. */
182
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7055,
183
"HP NC382i DP Multifunction Gigabit Server Adapter" },
184
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7059,
185
"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
186
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709, PCI_ANY_ID, PCI_ANY_ID,
187
"QLogic NetXtreme II BCM5709 1000Base-T" },
188
189
/* BCM5709S controllers and OEM boards. */
190
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x171d,
191
"HP NC382m DP 1GbE Multifunction BL-c Adapter" },
192
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x7056,
193
"HP NC382i DP Multifunction Gigabit Server Adapter" },
194
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, PCI_ANY_ID, PCI_ANY_ID,
195
"QLogic NetXtreme II BCM5709 1000Base-SX" },
196
197
/* BCM5716 controllers and OEM boards. */
198
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716, PCI_ANY_ID, PCI_ANY_ID,
199
"QLogic NetXtreme II BCM5716 1000Base-T" },
200
{ 0, 0, 0, 0, NULL }
201
};
202
203
/****************************************************************************/
204
/* Supported Flash NVRAM device data. */
205
/****************************************************************************/
206
static const struct flash_spec flash_table[] =
207
{
208
#define BUFFERED_FLAGS (BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
209
#define NONBUFFERED_FLAGS (BCE_NV_WREN)
210
211
/* Slow EEPROM */
212
{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
213
BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
214
SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
215
"EEPROM - slow"},
216
/* Expansion entry 0001 */
217
{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
218
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
219
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
220
"Entry 0001"},
221
/* Saifun SA25F010 (non-buffered flash) */
222
/* strap, cfg1, & write1 need updates */
223
{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
224
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
225
SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
226
"Non-buffered flash (128kB)"},
227
/* Saifun SA25F020 (non-buffered flash) */
228
/* strap, cfg1, & write1 need updates */
229
{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
230
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
231
SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
232
"Non-buffered flash (256kB)"},
233
/* Expansion entry 0100 */
234
{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
235
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
236
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
237
"Entry 0100"},
238
/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
239
{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
240
NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
241
ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
242
"Entry 0101: ST M45PE10 (128kB non-buffered)"},
243
/* Entry 0110: ST M45PE20 (non-buffered flash)*/
244
{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
245
NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
246
ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
247
"Entry 0110: ST M45PE20 (256kB non-buffered)"},
248
/* Saifun SA25F005 (non-buffered flash) */
249
/* strap, cfg1, & write1 need updates */
250
{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
251
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
252
SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
253
"Non-buffered flash (64kB)"},
254
/* Fast EEPROM */
255
{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
256
BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
257
SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
258
"EEPROM - fast"},
259
/* Expansion entry 1001 */
260
{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
261
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
262
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
263
"Entry 1001"},
264
/* Expansion entry 1010 */
265
{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
266
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
267
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
268
"Entry 1010"},
269
/* ATMEL AT45DB011B (buffered flash) */
270
{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
271
BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
272
BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
273
"Buffered flash (128kB)"},
274
/* Expansion entry 1100 */
275
{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
276
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
277
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
278
"Entry 1100"},
279
/* Expansion entry 1101 */
280
{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
281
NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
282
SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
283
"Entry 1101"},
284
/* Ateml Expansion entry 1110 */
285
{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
286
BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
287
BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
288
"Entry 1110 (Atmel)"},
289
/* ATMEL AT45DB021B (buffered flash) */
290
{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
291
BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
292
BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
293
"Buffered flash (256kB)"},
294
};
295
296
/*
297
* The BCM5709 controllers transparently handle the
298
* differences between Atmel 264 byte pages and all
299
* flash devices which use 256 byte pages, so no
300
* logical-to-physical mapping is required in the
301
* driver.
302
*/
303
static const struct flash_spec flash_5709 = {
304
.flags = BCE_NV_BUFFERED,
305
.page_bits = BCM5709_FLASH_PAGE_BITS,
306
.page_size = BCM5709_FLASH_PAGE_SIZE,
307
.addr_mask = BCM5709_FLASH_BYTE_ADDR_MASK,
308
.total_size = BUFFERED_FLASH_TOTAL_SIZE * 2,
309
.name = "5709/5716 buffered flash (256kB)",
310
};
311
312
/****************************************************************************/
313
/* FreeBSD device entry points. */
314
/****************************************************************************/
315
static int bce_probe (device_t);
316
static int bce_attach (device_t);
317
static int bce_detach (device_t);
318
static int bce_shutdown (device_t);
319
320
/****************************************************************************/
321
/* BCE Debug Data Structure Dump Routines */
322
/****************************************************************************/
323
#ifdef BCE_DEBUG
324
static u32 bce_reg_rd (struct bce_softc *, u32);
325
static void bce_reg_wr (struct bce_softc *, u32, u32);
326
static void bce_reg_wr16 (struct bce_softc *, u32, u16);
327
static u32 bce_ctx_rd (struct bce_softc *, u32, u32);
328
static void bce_dump_enet (struct bce_softc *, struct mbuf *);
329
static void bce_dump_mbuf (struct bce_softc *, struct mbuf *);
330
static void bce_dump_tx_mbuf_chain (struct bce_softc *, u16, int);
331
static void bce_dump_rx_mbuf_chain (struct bce_softc *, u16, int);
332
static void bce_dump_pg_mbuf_chain (struct bce_softc *, u16, int);
333
static void bce_dump_txbd (struct bce_softc *,
334
int, struct tx_bd *);
335
static void bce_dump_rxbd (struct bce_softc *,
336
int, struct rx_bd *);
337
static void bce_dump_pgbd (struct bce_softc *,
338
int, struct rx_bd *);
339
static void bce_dump_l2fhdr (struct bce_softc *,
340
int, struct l2_fhdr *);
341
static void bce_dump_ctx (struct bce_softc *, u16);
342
static void bce_dump_ftqs (struct bce_softc *);
343
static void bce_dump_tx_chain (struct bce_softc *, u16, int);
344
static void bce_dump_rx_bd_chain (struct bce_softc *, u16, int);
345
static void bce_dump_pg_chain (struct bce_softc *, u16, int);
346
static void bce_dump_status_block (struct bce_softc *);
347
static void bce_dump_stats_block (struct bce_softc *);
348
static void bce_dump_driver_state (struct bce_softc *);
349
static void bce_dump_hw_state (struct bce_softc *);
350
static void bce_dump_shmem_state (struct bce_softc *);
351
static void bce_dump_mq_regs (struct bce_softc *);
352
static void bce_dump_bc_state (struct bce_softc *);
353
static void bce_dump_txp_state (struct bce_softc *, int);
354
static void bce_dump_rxp_state (struct bce_softc *, int);
355
static void bce_dump_tpat_state (struct bce_softc *, int);
356
static void bce_dump_cp_state (struct bce_softc *, int);
357
static void bce_dump_com_state (struct bce_softc *, int);
358
static void bce_dump_rv2p_state (struct bce_softc *);
359
static void bce_breakpoint (struct bce_softc *);
360
#endif /*BCE_DEBUG */
361
362
/****************************************************************************/
363
/* BCE Register/Memory Access Routines */
364
/****************************************************************************/
365
static u32 bce_reg_rd_ind (struct bce_softc *, u32);
366
static void bce_reg_wr_ind (struct bce_softc *, u32, u32);
367
static void bce_shmem_wr (struct bce_softc *, u32, u32);
368
static u32 bce_shmem_rd (struct bce_softc *, u32);
369
static void bce_ctx_wr (struct bce_softc *, u32, u32, u32);
370
static int bce_miibus_read_reg (device_t, int, int);
371
static int bce_miibus_write_reg (device_t, int, int, int);
372
static void bce_miibus_statchg (device_t);
373
374
#ifdef BCE_DEBUG
375
static int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
376
#ifdef BCE_NVRAM_WRITE_SUPPORT
377
static int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
378
#endif
379
#endif
380
381
/****************************************************************************/
382
/* BCE NVRAM Access Routines */
383
/****************************************************************************/
384
static int bce_acquire_nvram_lock (struct bce_softc *);
385
static int bce_release_nvram_lock (struct bce_softc *);
386
static void bce_enable_nvram_access(struct bce_softc *);
387
static void bce_disable_nvram_access(struct bce_softc *);
388
static int bce_nvram_read_dword (struct bce_softc *, u32, u8 *, u32);
389
static int bce_init_nvram (struct bce_softc *);
390
static int bce_nvram_read (struct bce_softc *, u32, u8 *, int);
391
static int bce_nvram_test (struct bce_softc *);
392
#ifdef BCE_NVRAM_WRITE_SUPPORT
393
static int bce_enable_nvram_write (struct bce_softc *);
394
static void bce_disable_nvram_write(struct bce_softc *);
395
static int bce_nvram_erase_page (struct bce_softc *, u32);
396
static int bce_nvram_write_dword (struct bce_softc *, u32, u8 *, u32);
397
static int bce_nvram_write (struct bce_softc *, u32, u8 *, int);
398
#endif
399
400
/****************************************************************************/
401
/* */
402
/****************************************************************************/
403
static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
404
static void bce_get_media (struct bce_softc *);
405
static void bce_init_media (struct bce_softc *);
406
static u32 bce_get_rphy_link (struct bce_softc *);
407
static void bce_dma_map_addr (void *, bus_dma_segment_t *, int, int);
408
static int bce_dma_alloc (device_t);
409
static void bce_dma_free (struct bce_softc *);
410
static void bce_release_resources (struct bce_softc *);
411
412
/****************************************************************************/
413
/* BCE Firmware Synchronization and Load */
414
/****************************************************************************/
415
static void bce_fw_cap_init (struct bce_softc *);
416
static int bce_fw_sync (struct bce_softc *, u32);
417
static void bce_load_rv2p_fw (struct bce_softc *, const u32 *, u32,
418
u32);
419
static void bce_load_cpu_fw (struct bce_softc *,
420
struct cpu_reg *, struct fw_info *);
421
static void bce_start_cpu (struct bce_softc *, struct cpu_reg *);
422
static void bce_halt_cpu (struct bce_softc *, struct cpu_reg *);
423
static void bce_start_rxp_cpu (struct bce_softc *);
424
static void bce_init_rxp_cpu (struct bce_softc *);
425
static void bce_init_txp_cpu (struct bce_softc *);
426
static void bce_init_tpat_cpu (struct bce_softc *);
427
static void bce_init_cp_cpu (struct bce_softc *);
428
static void bce_init_com_cpu (struct bce_softc *);
429
static void bce_init_cpus (struct bce_softc *);
430
431
static void bce_print_adapter_info (struct bce_softc *);
432
static void bce_probe_pci_caps (device_t, struct bce_softc *);
433
static void bce_stop (struct bce_softc *);
434
static int bce_reset (struct bce_softc *, u32);
435
static int bce_chipinit (struct bce_softc *);
436
static int bce_blockinit (struct bce_softc *);
437
438
static int bce_init_tx_chain (struct bce_softc *);
439
static void bce_free_tx_chain (struct bce_softc *);
440
441
static int bce_get_rx_buf (struct bce_softc *, u16, u16, u32 *);
442
static int bce_init_rx_chain (struct bce_softc *);
443
static void bce_fill_rx_chain (struct bce_softc *);
444
static void bce_free_rx_chain (struct bce_softc *);
445
446
static int bce_get_pg_buf (struct bce_softc *, u16, u16);
447
static int bce_init_pg_chain (struct bce_softc *);
448
static void bce_fill_pg_chain (struct bce_softc *);
449
static void bce_free_pg_chain (struct bce_softc *);
450
451
static struct mbuf *bce_tso_setup (struct bce_softc *,
452
struct mbuf **, u16 *);
453
static int bce_tx_encap (struct bce_softc *, struct mbuf **);
454
static void bce_start_locked (if_t);
455
static void bce_start (if_t);
456
static int bce_ioctl (if_t, u_long, caddr_t);
457
static uint64_t bce_get_counter (if_t, ift_counter);
458
static void bce_watchdog (struct bce_softc *);
459
static int bce_ifmedia_upd (if_t);
460
static int bce_ifmedia_upd_locked (if_t);
461
static void bce_ifmedia_sts (if_t, struct ifmediareq *);
462
static void bce_ifmedia_sts_rphy (struct bce_softc *, struct ifmediareq *);
463
static void bce_init_locked (struct bce_softc *);
464
static void bce_init (void *);
465
static void bce_mgmt_init_locked (struct bce_softc *sc);
466
467
static int bce_init_ctx (struct bce_softc *);
468
static void bce_get_mac_addr (struct bce_softc *);
469
static void bce_set_mac_addr (struct bce_softc *);
470
static void bce_phy_intr (struct bce_softc *);
471
static inline u16 bce_get_hw_rx_cons (struct bce_softc *);
472
static void bce_rx_intr (struct bce_softc *);
473
static void bce_tx_intr (struct bce_softc *);
474
static void bce_disable_intr (struct bce_softc *);
475
static void bce_enable_intr (struct bce_softc *, int);
476
477
static void bce_intr (void *);
478
static void bce_set_rx_mode (struct bce_softc *);
479
static void bce_stats_update (struct bce_softc *);
480
static void bce_tick (void *);
481
static void bce_pulse (void *);
482
static void bce_add_sysctls (struct bce_softc *);
483
484
/****************************************************************************/
485
/* FreeBSD device dispatch table. */
486
/****************************************************************************/
487
static device_method_t bce_methods[] = {
488
/* Device interface (device_if.h) */
489
DEVMETHOD(device_probe, bce_probe),
490
DEVMETHOD(device_attach, bce_attach),
491
DEVMETHOD(device_detach, bce_detach),
492
DEVMETHOD(device_shutdown, bce_shutdown),
493
/* Supported by device interface but not used here. */
494
/* DEVMETHOD(device_identify, bce_identify), */
495
/* DEVMETHOD(device_suspend, bce_suspend), */
496
/* DEVMETHOD(device_resume, bce_resume), */
497
/* DEVMETHOD(device_quiesce, bce_quiesce), */
498
499
/* MII interface (miibus_if.h) */
500
DEVMETHOD(miibus_readreg, bce_miibus_read_reg),
501
DEVMETHOD(miibus_writereg, bce_miibus_write_reg),
502
DEVMETHOD(miibus_statchg, bce_miibus_statchg),
503
/* Supported by MII interface but not used here. */
504
/* DEVMETHOD(miibus_linkchg, bce_miibus_linkchg), */
505
/* DEVMETHOD(miibus_mediainit, bce_miibus_mediainit), */
506
507
DEVMETHOD_END
508
};
509
510
static driver_t bce_driver = {
511
"bce",
512
bce_methods,
513
sizeof(struct bce_softc)
514
};
515
516
MODULE_DEPEND(bce, pci, 1, 1, 1);
517
MODULE_DEPEND(bce, ether, 1, 1, 1);
518
MODULE_DEPEND(bce, miibus, 1, 1, 1);
519
520
DRIVER_MODULE(bce, pci, bce_driver, NULL, NULL);
521
DRIVER_MODULE(miibus, bce, miibus_driver, NULL, NULL);
522
MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce,
523
bce_devs, nitems(bce_devs) - 1);
524
525
/****************************************************************************/
526
/* Tunable device values */
527
/****************************************************************************/
528
static SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
529
"bce driver parameters");
530
531
/* Allowable values are TRUE or FALSE */
532
static int bce_verbose = TRUE;
533
SYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
534
"Verbose output enable/disable");
535
536
/* Allowable values are TRUE or FALSE */
537
static int bce_tso_enable = TRUE;
538
SYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
539
"TSO Enable/Disable");
540
541
/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
542
/* ToDo: Add MSI-X support. */
543
static int bce_msi_enable = 1;
544
SYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
545
"MSI-X|MSI|INTx selector");
546
547
/* Allowable values are 1, 2, 4, 8. */
548
static int bce_rx_pages = DEFAULT_RX_PAGES;
549
SYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
550
"Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
551
552
/* Allowable values are 1, 2, 4, 8. */
553
static int bce_tx_pages = DEFAULT_TX_PAGES;
554
SYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
555
"Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
556
557
/* Allowable values are TRUE or FALSE. */
558
static int bce_hdr_split = TRUE;
559
SYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
560
"Frame header/payload splitting Enable/Disable");
561
562
/* Allowable values are TRUE or FALSE. */
563
static int bce_strict_rx_mtu = FALSE;
564
SYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN,
565
&bce_strict_rx_mtu, 0,
566
"Enable/Disable strict RX frame size checking");
567
568
/* Allowable values are 0 ... 100 */
569
#ifdef BCE_DEBUG
570
/* Generate 1 interrupt for every transmit completion. */
571
static int bce_tx_quick_cons_trip_int = 1;
572
#else
573
/* Generate 1 interrupt for every 20 transmit completions. */
574
static int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
575
#endif
576
SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
577
&bce_tx_quick_cons_trip_int, 0,
578
"Transmit BD trip point during interrupts");
579
580
/* Allowable values are 0 ... 100 */
581
/* Generate 1 interrupt for every transmit completion. */
582
#ifdef BCE_DEBUG
583
static int bce_tx_quick_cons_trip = 1;
584
#else
585
/* Generate 1 interrupt for every 20 transmit completions. */
586
static int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
587
#endif
588
SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
589
&bce_tx_quick_cons_trip, 0,
590
"Transmit BD trip point");
591
592
/* Allowable values are 0 ... 100 */
593
#ifdef BCE_DEBUG
594
/* Generate an interrupt if 0us have elapsed since the last TX completion. */
595
static int bce_tx_ticks_int = 0;
596
#else
597
/* Generate an interrupt if 80us have elapsed since the last TX completion. */
598
static int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
599
#endif
600
SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
601
&bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
602
603
/* Allowable values are 0 ... 100 */
604
#ifdef BCE_DEBUG
605
/* Generate an interrupt if 0us have elapsed since the last TX completion. */
606
static int bce_tx_ticks = 0;
607
#else
608
/* Generate an interrupt if 80us have elapsed since the last TX completion. */
609
static int bce_tx_ticks = DEFAULT_TX_TICKS;
610
#endif
611
SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
612
&bce_tx_ticks, 0, "Transmit ticks count");
613
614
/* Allowable values are 1 ... 100 */
615
#ifdef BCE_DEBUG
616
/* Generate 1 interrupt for every received frame. */
617
static int bce_rx_quick_cons_trip_int = 1;
618
#else
619
/* Generate 1 interrupt for every 6 received frames. */
620
static int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
621
#endif
622
SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
623
&bce_rx_quick_cons_trip_int, 0,
624
"Receive BD trip point during interrupts");
625
626
/* Allowable values are 1 ... 100 */
627
#ifdef BCE_DEBUG
628
/* Generate 1 interrupt for every received frame. */
629
static int bce_rx_quick_cons_trip = 1;
630
#else
631
/* Generate 1 interrupt for every 6 received frames. */
632
static int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
633
#endif
634
SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
635
&bce_rx_quick_cons_trip, 0,
636
"Receive BD trip point");
637
638
/* Allowable values are 0 ... 100 */
639
#ifdef BCE_DEBUG
640
/* Generate an int. if 0us have elapsed since the last received frame. */
641
static int bce_rx_ticks_int = 0;
642
#else
643
/* Generate an int. if 18us have elapsed since the last received frame. */
644
static int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
645
#endif
646
SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
647
&bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
648
649
/* Allowable values are 0 ... 100 */
650
#ifdef BCE_DEBUG
651
/* Generate an int. if 0us have elapsed since the last received frame. */
652
static int bce_rx_ticks = 0;
653
#else
654
/* Generate an int. if 18us have elapsed since the last received frame. */
655
static int bce_rx_ticks = DEFAULT_RX_TICKS;
656
#endif
657
SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
658
&bce_rx_ticks, 0, "Receive ticks count");
659
660
/****************************************************************************/
661
/* Device probe function. */
662
/* */
663
/* Compares the device to the driver's list of supported devices and */
664
/* reports back to the OS whether this is the right driver for the device. */
665
/* */
666
/* Returns: */
667
/* BUS_PROBE_DEFAULT on success, positive value on failure. */
668
/****************************************************************************/
669
static int
670
bce_probe(device_t dev)
671
{
672
const struct bce_type *t;
673
struct bce_softc *sc;
674
u16 vid = 0, did = 0, svid = 0, sdid = 0;
675
676
t = bce_devs;
677
678
sc = device_get_softc(dev);
679
sc->bce_unit = device_get_unit(dev);
680
sc->bce_dev = dev;
681
682
/* Get the data for the device to be probed. */
683
vid = pci_get_vendor(dev);
684
did = pci_get_device(dev);
685
svid = pci_get_subvendor(dev);
686
sdid = pci_get_subdevice(dev);
687
688
DBPRINT(sc, BCE_EXTREME_LOAD,
689
"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
690
"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
691
692
/* Look through the list of known devices for a match. */
693
while(t->bce_name != NULL) {
694
if ((vid == t->bce_vid) && (did == t->bce_did) &&
695
((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
696
((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
697
device_set_descf(dev, "%s (%c%d)",
698
t->bce_name, (((pci_read_config(dev,
699
PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
700
(pci_read_config(dev, PCIR_REVID, 4) & 0xf));
701
return(BUS_PROBE_DEFAULT);
702
}
703
t++;
704
}
705
706
return(ENXIO);
707
}
708
709
/****************************************************************************/
710
/* PCI Capabilities Probe Function. */
711
/* */
712
/* Walks the PCI capabiites list for the device to find what features are */
713
/* supported. */
714
/* */
715
/* Returns: */
716
/* None. */
717
/****************************************************************************/
718
static void
719
bce_print_adapter_info(struct bce_softc *sc)
720
{
721
int i = 0;
722
723
DBENTER(BCE_VERBOSE_LOAD);
724
725
if (bce_verbose || bootverbose) {
726
BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
727
printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
728
12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
729
730
/* Bus info. */
731
if (sc->bce_flags & BCE_PCIE_FLAG) {
732
printf("Bus (PCIe x%d, ", sc->link_width);
733
switch (sc->link_speed) {
734
case 1: printf("2.5Gbps); "); break;
735
case 2: printf("5Gbps); "); break;
736
default: printf("Unknown link speed); ");
737
}
738
} else {
739
printf("Bus (PCI%s, %s, %dMHz); ",
740
((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
741
((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
742
"32-bit" : "64-bit"), sc->bus_speed_mhz);
743
}
744
745
/* Firmware version and device features. */
746
printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
747
sc->bce_bc_ver, sc->rx_pages, sc->tx_pages,
748
(bce_hdr_split == TRUE ? sc->pg_pages: 0));
749
750
if (bce_hdr_split == TRUE) {
751
printf("SPLT");
752
i++;
753
}
754
755
if (sc->bce_flags & BCE_USING_MSI_FLAG) {
756
if (i > 0) printf("|");
757
printf("MSI"); i++;
758
}
759
760
if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
761
if (i > 0) printf("|");
762
printf("MSI-X"); i++;
763
}
764
765
if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
766
if (i > 0) printf("|");
767
printf("2.5G"); i++;
768
}
769
770
if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
771
if (i > 0) printf("|");
772
printf("Remote PHY(%s)",
773
sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
774
"FIBER" : "TP"); i++;
775
}
776
777
if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
778
if (i > 0) printf("|");
779
printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
780
} else {
781
printf(")\n");
782
}
783
784
printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
785
sc->bce_rx_quick_cons_trip_int,
786
sc->bce_rx_quick_cons_trip,
787
sc->bce_rx_ticks_int,
788
sc->bce_rx_ticks,
789
sc->bce_tx_quick_cons_trip_int,
790
sc->bce_tx_quick_cons_trip,
791
sc->bce_tx_ticks_int,
792
sc->bce_tx_ticks);
793
}
794
795
DBEXIT(BCE_VERBOSE_LOAD);
796
}
797
798
/****************************************************************************/
799
/* PCI Capabilities Probe Function. */
800
/* */
801
/* Walks the PCI capabiites list for the device to find what features are */
802
/* supported. */
803
/* */
804
/* Returns: */
805
/* None. */
806
/****************************************************************************/
807
static void
808
bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
809
{
810
u32 reg;
811
812
DBENTER(BCE_VERBOSE_LOAD);
813
814
/* Check if PCI-X capability is enabled. */
815
if (pci_find_cap(dev, PCIY_PCIX, &reg) == 0) {
816
if (reg != 0)
817
sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
818
}
819
820
/* Check if PCIe capability is enabled. */
821
if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
822
if (reg != 0) {
823
u16 link_status = pci_read_config(dev, reg + 0x12, 2);
824
DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
825
"0x%08X\n", link_status);
826
sc->link_speed = link_status & 0xf;
827
sc->link_width = (link_status >> 4) & 0x3f;
828
sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
829
sc->bce_flags |= BCE_PCIE_FLAG;
830
}
831
}
832
833
/* Check if MSI capability is enabled. */
834
if (pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
835
if (reg != 0)
836
sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
837
}
838
839
/* Check if MSI-X capability is enabled. */
840
if (pci_find_cap(dev, PCIY_MSIX, &reg) == 0) {
841
if (reg != 0)
842
sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
843
}
844
845
DBEXIT(BCE_VERBOSE_LOAD);
846
}
847
848
/****************************************************************************/
849
/* Load and validate user tunable settings. */
850
/* */
851
/* Returns: */
852
/* Nothing. */
853
/****************************************************************************/
854
static void
855
bce_set_tunables(struct bce_softc *sc)
856
{
857
/* Set sysctl values for RX page count. */
858
switch (bce_rx_pages) {
859
case 1:
860
/* fall-through */
861
case 2:
862
/* fall-through */
863
case 4:
864
/* fall-through */
865
case 8:
866
sc->rx_pages = bce_rx_pages;
867
break;
868
default:
869
sc->rx_pages = DEFAULT_RX_PAGES;
870
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
871
"hw.bce.rx_pages! Setting default of %d.\n",
872
__FILE__, __LINE__, bce_rx_pages, DEFAULT_RX_PAGES);
873
}
874
875
/* ToDo: Consider allowing user setting for pg_pages. */
876
sc->pg_pages = min((sc->rx_pages * 4), MAX_PG_PAGES);
877
878
/* Set sysctl values for TX page count. */
879
switch (bce_tx_pages) {
880
case 1:
881
/* fall-through */
882
case 2:
883
/* fall-through */
884
case 4:
885
/* fall-through */
886
case 8:
887
sc->tx_pages = bce_tx_pages;
888
break;
889
default:
890
sc->tx_pages = DEFAULT_TX_PAGES;
891
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
892
"hw.bce.tx_pages! Setting default of %d.\n",
893
__FILE__, __LINE__, bce_tx_pages, DEFAULT_TX_PAGES);
894
}
895
896
/*
897
* Validate the TX trip point (i.e. the number of
898
* TX completions before a status block update is
899
* generated and an interrupt is asserted.
900
*/
901
if (bce_tx_quick_cons_trip_int <= 100) {
902
sc->bce_tx_quick_cons_trip_int =
903
bce_tx_quick_cons_trip_int;
904
} else {
905
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
906
"hw.bce.tx_quick_cons_trip_int! Setting default of %d.\n",
907
__FILE__, __LINE__, bce_tx_quick_cons_trip_int,
908
DEFAULT_TX_QUICK_CONS_TRIP_INT);
909
sc->bce_tx_quick_cons_trip_int =
910
DEFAULT_TX_QUICK_CONS_TRIP_INT;
911
}
912
913
if (bce_tx_quick_cons_trip <= 100) {
914
sc->bce_tx_quick_cons_trip =
915
bce_tx_quick_cons_trip;
916
} else {
917
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
918
"hw.bce.tx_quick_cons_trip! Setting default of %d.\n",
919
__FILE__, __LINE__, bce_tx_quick_cons_trip,
920
DEFAULT_TX_QUICK_CONS_TRIP);
921
sc->bce_tx_quick_cons_trip =
922
DEFAULT_TX_QUICK_CONS_TRIP;
923
}
924
925
/*
926
* Validate the TX ticks count (i.e. the maximum amount
927
* of time to wait after the last TX completion has
928
* occurred before a status block update is generated
929
* and an interrupt is asserted.
930
*/
931
if (bce_tx_ticks_int <= 100) {
932
sc->bce_tx_ticks_int =
933
bce_tx_ticks_int;
934
} else {
935
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
936
"hw.bce.tx_ticks_int! Setting default of %d.\n",
937
__FILE__, __LINE__, bce_tx_ticks_int,
938
DEFAULT_TX_TICKS_INT);
939
sc->bce_tx_ticks_int =
940
DEFAULT_TX_TICKS_INT;
941
}
942
943
if (bce_tx_ticks <= 100) {
944
sc->bce_tx_ticks =
945
bce_tx_ticks;
946
} else {
947
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
948
"hw.bce.tx_ticks! Setting default of %d.\n",
949
__FILE__, __LINE__, bce_tx_ticks,
950
DEFAULT_TX_TICKS);
951
sc->bce_tx_ticks =
952
DEFAULT_TX_TICKS;
953
}
954
955
/*
956
* Validate the RX trip point (i.e. the number of
957
* RX frames received before a status block update is
958
* generated and an interrupt is asserted.
959
*/
960
if (bce_rx_quick_cons_trip_int <= 100) {
961
sc->bce_rx_quick_cons_trip_int =
962
bce_rx_quick_cons_trip_int;
963
} else {
964
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
965
"hw.bce.rx_quick_cons_trip_int! Setting default of %d.\n",
966
__FILE__, __LINE__, bce_rx_quick_cons_trip_int,
967
DEFAULT_RX_QUICK_CONS_TRIP_INT);
968
sc->bce_rx_quick_cons_trip_int =
969
DEFAULT_RX_QUICK_CONS_TRIP_INT;
970
}
971
972
if (bce_rx_quick_cons_trip <= 100) {
973
sc->bce_rx_quick_cons_trip =
974
bce_rx_quick_cons_trip;
975
} else {
976
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
977
"hw.bce.rx_quick_cons_trip! Setting default of %d.\n",
978
__FILE__, __LINE__, bce_rx_quick_cons_trip,
979
DEFAULT_RX_QUICK_CONS_TRIP);
980
sc->bce_rx_quick_cons_trip =
981
DEFAULT_RX_QUICK_CONS_TRIP;
982
}
983
984
/*
985
* Validate the RX ticks count (i.e. the maximum amount
986
* of time to wait after the last RX frame has been
987
* received before a status block update is generated
988
* and an interrupt is asserted.
989
*/
990
if (bce_rx_ticks_int <= 100) {
991
sc->bce_rx_ticks_int = bce_rx_ticks_int;
992
} else {
993
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
994
"hw.bce.rx_ticks_int! Setting default of %d.\n",
995
__FILE__, __LINE__, bce_rx_ticks_int,
996
DEFAULT_RX_TICKS_INT);
997
sc->bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
998
}
999
1000
if (bce_rx_ticks <= 100) {
1001
sc->bce_rx_ticks = bce_rx_ticks;
1002
} else {
1003
BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1004
"hw.bce.rx_ticks! Setting default of %d.\n",
1005
__FILE__, __LINE__, bce_rx_ticks,
1006
DEFAULT_RX_TICKS);
1007
sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1008
}
1009
1010
/* Disabling both RX ticks and RX trips will prevent interrupts. */
1011
if ((bce_rx_quick_cons_trip == 0) && (bce_rx_ticks == 0)) {
1012
BCE_PRINTF("%s(%d): Cannot set both hw.bce.rx_ticks and "
1013
"hw.bce.rx_quick_cons_trip to 0. Setting default values.\n",
1014
__FILE__, __LINE__);
1015
sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1016
sc->bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
1017
}
1018
1019
/* Disabling both TX ticks and TX trips will prevent interrupts. */
1020
if ((bce_tx_quick_cons_trip == 0) && (bce_tx_ticks == 0)) {
1021
BCE_PRINTF("%s(%d): Cannot set both hw.bce.tx_ticks and "
1022
"hw.bce.tx_quick_cons_trip to 0. Setting default values.\n",
1023
__FILE__, __LINE__);
1024
sc->bce_tx_ticks = DEFAULT_TX_TICKS;
1025
sc->bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
1026
}
1027
}
1028
1029
/****************************************************************************/
1030
/* Device attach function. */
1031
/* */
1032
/* Allocates device resources, performs secondary chip identification, */
1033
/* resets and initializes the hardware, and initializes driver instance */
1034
/* variables. */
1035
/* */
1036
/* Returns: */
1037
/* 0 on success, positive value on failure. */
1038
/****************************************************************************/
1039
static int
1040
bce_attach(device_t dev)
1041
{
1042
struct bce_softc *sc;
1043
if_t ifp;
1044
u32 val;
1045
int count, error, rc = 0, rid;
1046
1047
sc = device_get_softc(dev);
1048
sc->bce_dev = dev;
1049
1050
DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1051
1052
sc->bce_unit = device_get_unit(dev);
1053
1054
/* Set initial device and PHY flags */
1055
sc->bce_flags = 0;
1056
sc->bce_phy_flags = 0;
1057
1058
bce_set_tunables(sc);
1059
1060
pci_enable_busmaster(dev);
1061
1062
/* Allocate PCI memory resources. */
1063
rid = PCIR_BAR(0);
1064
sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1065
&rid, RF_ACTIVE);
1066
1067
if (sc->bce_res_mem == NULL) {
1068
BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
1069
__FILE__, __LINE__);
1070
rc = ENXIO;
1071
goto bce_attach_fail;
1072
}
1073
1074
/* Get various resource handles. */
1075
sc->bce_btag = rman_get_bustag(sc->bce_res_mem);
1076
sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
1077
sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
1078
1079
bce_probe_pci_caps(dev, sc);
1080
1081
rid = 1;
1082
count = 0;
1083
#if 0
1084
/* Try allocating MSI-X interrupts. */
1085
if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
1086
(bce_msi_enable >= 2) &&
1087
((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1088
&rid, RF_ACTIVE)) != NULL)) {
1089
msi_needed = count = 1;
1090
1091
if (((error = pci_alloc_msix(dev, &count)) != 0) ||
1092
(count != msi_needed)) {
1093
BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
1094
"Received = %d, error = %d\n", __FILE__, __LINE__,
1095
msi_needed, count, error);
1096
count = 0;
1097
pci_release_msi(dev);
1098
bus_release_resource(dev, SYS_RES_MEMORY, rid,
1099
sc->bce_res_irq);
1100
sc->bce_res_irq = NULL;
1101
} else {
1102
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
1103
__FUNCTION__);
1104
sc->bce_flags |= BCE_USING_MSIX_FLAG;
1105
}
1106
}
1107
#endif
1108
1109
/* Try allocating a MSI interrupt. */
1110
if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
1111
(bce_msi_enable >= 1) && (count == 0)) {
1112
count = 1;
1113
if ((error = pci_alloc_msi(dev, &count)) != 0) {
1114
BCE_PRINTF("%s(%d): MSI allocation failed! "
1115
"error = %d\n", __FILE__, __LINE__, error);
1116
count = 0;
1117
pci_release_msi(dev);
1118
} else {
1119
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
1120
"interrupt.\n", __FUNCTION__);
1121
sc->bce_flags |= BCE_USING_MSI_FLAG;
1122
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
1123
sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
1124
rid = 1;
1125
}
1126
}
1127
1128
/* Try allocating a legacy interrupt. */
1129
if (count == 0) {
1130
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
1131
__FUNCTION__);
1132
rid = 0;
1133
}
1134
1135
sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1136
&rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE));
1137
1138
/* Report any IRQ allocation errors. */
1139
if (sc->bce_res_irq == NULL) {
1140
BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
1141
__FILE__, __LINE__);
1142
rc = ENXIO;
1143
goto bce_attach_fail;
1144
}
1145
1146
/* Initialize mutex for the current device instance. */
1147
BCE_LOCK_INIT(sc, device_get_nameunit(dev));
1148
1149
/*
1150
* Configure byte swap and enable indirect register access.
1151
* Rely on CPU to do target byte swapping on big endian systems.
1152
* Access to registers outside of PCI configurtion space are not
1153
* valid until this is done.
1154
*/
1155
pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
1156
BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
1157
BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
1158
1159
/* Save ASIC revsion info. */
1160
sc->bce_chipid = REG_RD(sc, BCE_MISC_ID);
1161
1162
/* Weed out any non-production controller revisions. */
1163
switch(BCE_CHIP_ID(sc)) {
1164
case BCE_CHIP_ID_5706_A0:
1165
case BCE_CHIP_ID_5706_A1:
1166
case BCE_CHIP_ID_5708_A0:
1167
case BCE_CHIP_ID_5708_B0:
1168
case BCE_CHIP_ID_5709_A0:
1169
case BCE_CHIP_ID_5709_B0:
1170
case BCE_CHIP_ID_5709_B1:
1171
case BCE_CHIP_ID_5709_B2:
1172
BCE_PRINTF("%s(%d): Unsupported controller "
1173
"revision (%c%d)!\n", __FILE__, __LINE__,
1174
(((pci_read_config(dev, PCIR_REVID, 4) &
1175
0xf0) >> 4) + 'A'), (pci_read_config(dev,
1176
PCIR_REVID, 4) & 0xf));
1177
rc = ENODEV;
1178
goto bce_attach_fail;
1179
}
1180
1181
/*
1182
* The embedded PCIe to PCI-X bridge (EPB)
1183
* in the 5708 cannot address memory above
1184
* 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
1185
*/
1186
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
1187
sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
1188
else
1189
sc->max_bus_addr = BUS_SPACE_MAXADDR;
1190
1191
/*
1192
* Find the base address for shared memory access.
1193
* Newer versions of bootcode use a signature and offset
1194
* while older versions use a fixed address.
1195
*/
1196
val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
1197
if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
1198
/* Multi-port devices use different offsets in shared memory. */
1199
sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
1200
(pci_get_function(sc->bce_dev) << 2));
1201
else
1202
sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
1203
1204
DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
1205
__FUNCTION__, sc->bce_shmem_base);
1206
1207
/* Fetch the bootcode revision. */
1208
val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
1209
for (int i = 0, j = 0; i < 3; i++) {
1210
u8 num;
1211
1212
num = (u8) (val >> (24 - (i * 8)));
1213
for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
1214
if (num >= k || !skip0 || k == 1) {
1215
sc->bce_bc_ver[j++] = (num / k) + '0';
1216
skip0 = 0;
1217
}
1218
}
1219
1220
if (i != 2)
1221
sc->bce_bc_ver[j++] = '.';
1222
}
1223
1224
/* Check if any management firmware is enabled. */
1225
val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
1226
if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
1227
sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
1228
1229
/* Allow time for firmware to enter the running state. */
1230
for (int i = 0; i < 30; i++) {
1231
val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1232
if (val & BCE_CONDITION_MFW_RUN_MASK)
1233
break;
1234
DELAY(10000);
1235
}
1236
1237
/* Check if management firmware is running. */
1238
val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1239
val &= BCE_CONDITION_MFW_RUN_MASK;
1240
if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
1241
(val != BCE_CONDITION_MFW_RUN_NONE)) {
1242
u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
1243
int i = 0;
1244
1245
/* Read the management firmware version string. */
1246
for (int j = 0; j < 3; j++) {
1247
val = bce_reg_rd_ind(sc, addr + j * 4);
1248
val = bswap32(val);
1249
memcpy(&sc->bce_mfw_ver[i], &val, 4);
1250
i += 4;
1251
}
1252
} else {
1253
/* May cause firmware synchronization timeouts. */
1254
BCE_PRINTF("%s(%d): Management firmware enabled "
1255
"but not running!\n", __FILE__, __LINE__);
1256
strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
1257
1258
/* ToDo: Any action the driver should take? */
1259
}
1260
}
1261
1262
/* Get PCI bus information (speed and type). */
1263
val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
1264
if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
1265
u32 clkreg;
1266
1267
sc->bce_flags |= BCE_PCIX_FLAG;
1268
1269
clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
1270
1271
clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
1272
switch (clkreg) {
1273
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
1274
sc->bus_speed_mhz = 133;
1275
break;
1276
1277
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
1278
sc->bus_speed_mhz = 100;
1279
break;
1280
1281
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
1282
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
1283
sc->bus_speed_mhz = 66;
1284
break;
1285
1286
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
1287
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
1288
sc->bus_speed_mhz = 50;
1289
break;
1290
1291
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
1292
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
1293
case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
1294
sc->bus_speed_mhz = 33;
1295
break;
1296
}
1297
} else {
1298
if (val & BCE_PCICFG_MISC_STATUS_M66EN)
1299
sc->bus_speed_mhz = 66;
1300
else
1301
sc->bus_speed_mhz = 33;
1302
}
1303
1304
if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
1305
sc->bce_flags |= BCE_PCI_32BIT_FLAG;
1306
1307
/* Find the media type for the adapter. */
1308
bce_get_media(sc);
1309
1310
/* Reset controller and announce to bootcode that driver is present. */
1311
if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
1312
BCE_PRINTF("%s(%d): Controller reset failed!\n",
1313
__FILE__, __LINE__);
1314
rc = ENXIO;
1315
goto bce_attach_fail;
1316
}
1317
1318
/* Initialize the controller. */
1319
if (bce_chipinit(sc)) {
1320
BCE_PRINTF("%s(%d): Controller initialization failed!\n",
1321
__FILE__, __LINE__);
1322
rc = ENXIO;
1323
goto bce_attach_fail;
1324
}
1325
1326
/* Perform NVRAM test. */
1327
if (bce_nvram_test(sc)) {
1328
BCE_PRINTF("%s(%d): NVRAM test failed!\n",
1329
__FILE__, __LINE__);
1330
rc = ENXIO;
1331
goto bce_attach_fail;
1332
}
1333
1334
/* Fetch the permanent Ethernet MAC address. */
1335
bce_get_mac_addr(sc);
1336
1337
/* Update statistics once every second. */
1338
sc->bce_stats_ticks = 1000000 & 0xffff00;
1339
1340
/* Store data needed by PHY driver for backplane applications */
1341
sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1342
sc->bce_port_hw_cfg = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1343
1344
/* Allocate DMA memory resources. */
1345
if (bce_dma_alloc(dev)) {
1346
BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1347
__FILE__, __LINE__);
1348
rc = ENXIO;
1349
goto bce_attach_fail;
1350
}
1351
1352
/* Allocate an ifnet structure. */
1353
ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1354
1355
/* Initialize the ifnet interface. */
1356
if_setsoftc(ifp, sc);
1357
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1358
if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
1359
if_setioctlfn(ifp, bce_ioctl);
1360
if_setstartfn(ifp, bce_start);
1361
if_setgetcounterfn(ifp, bce_get_counter);
1362
if_setinitfn(ifp, bce_init);
1363
if_setmtu(ifp, ETHERMTU);
1364
1365
if (bce_tso_enable) {
1366
if_sethwassist(ifp, BCE_IF_HWASSIST | CSUM_TSO);
1367
if_setcapabilities(ifp, BCE_IF_CAPABILITIES | IFCAP_TSO4 |
1368
IFCAP_VLAN_HWTSO);
1369
} else {
1370
if_sethwassist(ifp, BCE_IF_HWASSIST);
1371
if_setcapabilities(ifp, BCE_IF_CAPABILITIES);
1372
}
1373
1374
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1375
if_setcapabilitiesbit(ifp, IFCAP_LINKSTATE, 0);
1376
1377
if_setcapenable(ifp, if_getcapabilities(ifp));
1378
1379
/*
1380
* Assume standard mbuf sizes for buffer allocation.
1381
* This may change later if the MTU size is set to
1382
* something other than 1500.
1383
*/
1384
bce_get_rx_buffer_sizes(sc,
1385
(ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN));
1386
1387
/* Recalculate our buffer allocation sizes. */
1388
if_setsendqlen(ifp, USABLE_TX_BD_ALLOC);
1389
if_setsendqready(ifp);
1390
1391
if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1392
if_setbaudrate(ifp, IF_Mbps(2500ULL));
1393
else
1394
if_setbaudrate(ifp, IF_Mbps(1000));
1395
1396
/* Handle any special PHY initialization for SerDes PHYs. */
1397
bce_init_media(sc);
1398
1399
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
1400
ifmedia_init(&sc->bce_ifmedia, IFM_IMASK, bce_ifmedia_upd,
1401
bce_ifmedia_sts);
1402
/*
1403
* We can't manually override remote PHY's link and assume
1404
* PHY port configuration(Fiber or TP) is not changed after
1405
* device attach. This may not be correct though.
1406
*/
1407
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0) {
1408
if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
1409
ifmedia_add(&sc->bce_ifmedia,
1410
IFM_ETHER | IFM_2500_SX, 0, NULL);
1411
ifmedia_add(&sc->bce_ifmedia,
1412
IFM_ETHER | IFM_2500_SX | IFM_FDX, 0, NULL);
1413
}
1414
ifmedia_add(&sc->bce_ifmedia,
1415
IFM_ETHER | IFM_1000_SX, 0, NULL);
1416
ifmedia_add(&sc->bce_ifmedia,
1417
IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL);
1418
} else {
1419
ifmedia_add(&sc->bce_ifmedia,
1420
IFM_ETHER | IFM_10_T, 0, NULL);
1421
ifmedia_add(&sc->bce_ifmedia,
1422
IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
1423
ifmedia_add(&sc->bce_ifmedia,
1424
IFM_ETHER | IFM_100_TX, 0, NULL);
1425
ifmedia_add(&sc->bce_ifmedia,
1426
IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
1427
ifmedia_add(&sc->bce_ifmedia,
1428
IFM_ETHER | IFM_1000_T, 0, NULL);
1429
ifmedia_add(&sc->bce_ifmedia,
1430
IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
1431
}
1432
ifmedia_add(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
1433
ifmedia_set(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO);
1434
sc->bce_ifmedia.ifm_media = sc->bce_ifmedia.ifm_cur->ifm_media;
1435
} else {
1436
/* MII child bus by attaching the PHY. */
1437
rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
1438
bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
1439
MII_OFFSET_ANY, MIIF_DOPAUSE);
1440
if (rc != 0) {
1441
BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
1442
__LINE__);
1443
goto bce_attach_fail;
1444
}
1445
}
1446
1447
/* Attach to the Ethernet interface list. */
1448
ether_ifattach(ifp, sc->eaddr);
1449
1450
callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1451
callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1452
1453
/* Hookup IRQ last. */
1454
rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1455
NULL, bce_intr, sc, &sc->bce_intrhand);
1456
1457
if (rc) {
1458
BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1459
__FILE__, __LINE__);
1460
bce_detach(dev);
1461
goto bce_attach_exit;
1462
}
1463
1464
/*
1465
* At this point we've acquired all the resources
1466
* we need to run so there's no turning back, we're
1467
* cleared for launch.
1468
*/
1469
1470
/* Print some important debugging info. */
1471
DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1472
1473
/* Add the supported sysctls to the kernel. */
1474
bce_add_sysctls(sc);
1475
1476
BCE_LOCK(sc);
1477
1478
/*
1479
* The chip reset earlier notified the bootcode that
1480
* a driver is present. We now need to start our pulse
1481
* routine so that the bootcode is reminded that we're
1482
* still running.
1483
*/
1484
bce_pulse(sc);
1485
1486
bce_mgmt_init_locked(sc);
1487
BCE_UNLOCK(sc);
1488
1489
/* Finally, print some useful adapter info */
1490
bce_print_adapter_info(sc);
1491
DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1492
__FUNCTION__, sc);
1493
1494
goto bce_attach_exit;
1495
1496
bce_attach_fail:
1497
bce_release_resources(sc);
1498
1499
bce_attach_exit:
1500
1501
DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1502
1503
return(rc);
1504
}
1505
1506
/****************************************************************************/
1507
/* Device detach function. */
1508
/* */
1509
/* Stops the controller, resets the controller, and releases resources. */
1510
/* */
1511
/* Returns: */
1512
/* 0 on success, positive value on failure. */
1513
/****************************************************************************/
1514
static int
1515
bce_detach(device_t dev)
1516
{
1517
struct bce_softc *sc = device_get_softc(dev);
1518
if_t ifp;
1519
u32 msg;
1520
1521
DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1522
1523
ifp = sc->bce_ifp;
1524
1525
/* Stop and reset the controller. */
1526
BCE_LOCK(sc);
1527
1528
/* Stop the pulse so the bootcode can go to driver absent state. */
1529
callout_stop(&sc->bce_pulse_callout);
1530
1531
bce_stop(sc);
1532
if (sc->bce_flags & BCE_NO_WOL_FLAG)
1533
msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1534
else
1535
msg = BCE_DRV_MSG_CODE_UNLOAD;
1536
bce_reset(sc, msg);
1537
1538
BCE_UNLOCK(sc);
1539
1540
ether_ifdetach(ifp);
1541
1542
/* If we have a child device on the MII bus remove it too. */
1543
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1544
ifmedia_removeall(&sc->bce_ifmedia);
1545
else {
1546
bus_generic_detach(dev);
1547
}
1548
1549
/* Release all remaining resources. */
1550
bce_release_resources(sc);
1551
1552
DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1553
1554
return(0);
1555
}
1556
1557
/****************************************************************************/
1558
/* Device shutdown function. */
1559
/* */
1560
/* Stops and resets the controller. */
1561
/* */
1562
/* Returns: */
1563
/* 0 on success, positive value on failure. */
1564
/****************************************************************************/
1565
static int
1566
bce_shutdown(device_t dev)
1567
{
1568
struct bce_softc *sc = device_get_softc(dev);
1569
u32 msg;
1570
1571
DBENTER(BCE_VERBOSE);
1572
1573
BCE_LOCK(sc);
1574
bce_stop(sc);
1575
if (sc->bce_flags & BCE_NO_WOL_FLAG)
1576
msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1577
else
1578
msg = BCE_DRV_MSG_CODE_UNLOAD;
1579
bce_reset(sc, msg);
1580
BCE_UNLOCK(sc);
1581
1582
DBEXIT(BCE_VERBOSE);
1583
1584
return (0);
1585
}
1586
1587
#ifdef BCE_DEBUG
1588
/****************************************************************************/
1589
/* Register read. */
1590
/* */
1591
/* Returns: */
1592
/* The value of the register. */
1593
/****************************************************************************/
1594
static u32
1595
bce_reg_rd(struct bce_softc *sc, u32 offset)
1596
{
1597
u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1598
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1599
__FUNCTION__, offset, val);
1600
return val;
1601
}
1602
1603
/****************************************************************************/
1604
/* Register write (16 bit). */
1605
/* */
1606
/* Returns: */
1607
/* Nothing. */
1608
/****************************************************************************/
1609
static void
1610
bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1611
{
1612
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1613
__FUNCTION__, offset, val);
1614
bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1615
}
1616
1617
/****************************************************************************/
1618
/* Register write. */
1619
/* */
1620
/* Returns: */
1621
/* Nothing. */
1622
/****************************************************************************/
1623
static void
1624
bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1625
{
1626
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1627
__FUNCTION__, offset, val);
1628
bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1629
}
1630
#endif
1631
1632
/****************************************************************************/
1633
/* Indirect register read. */
1634
/* */
1635
/* Reads NetXtreme II registers using an index/data register pair in PCI */
1636
/* configuration space. Using this mechanism avoids issues with posted */
1637
/* reads but is much slower than memory-mapped I/O. */
1638
/* */
1639
/* Returns: */
1640
/* The value of the register. */
1641
/****************************************************************************/
1642
static u32
1643
bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1644
{
1645
device_t dev;
1646
dev = sc->bce_dev;
1647
1648
pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1649
#ifdef BCE_DEBUG
1650
{
1651
u32 val;
1652
val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1653
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1654
__FUNCTION__, offset, val);
1655
return val;
1656
}
1657
#else
1658
return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1659
#endif
1660
}
1661
1662
/****************************************************************************/
1663
/* Indirect register write. */
1664
/* */
1665
/* Writes NetXtreme II registers using an index/data register pair in PCI */
1666
/* configuration space. Using this mechanism avoids issues with posted */
1667
/* writes but is muchh slower than memory-mapped I/O. */
1668
/* */
1669
/* Returns: */
1670
/* Nothing. */
1671
/****************************************************************************/
1672
static void
1673
bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1674
{
1675
device_t dev;
1676
dev = sc->bce_dev;
1677
1678
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1679
__FUNCTION__, offset, val);
1680
1681
pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1682
pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1683
}
1684
1685
/****************************************************************************/
1686
/* Shared memory write. */
1687
/* */
1688
/* Writes NetXtreme II shared memory region. */
1689
/* */
1690
/* Returns: */
1691
/* Nothing. */
1692
/****************************************************************************/
1693
static void
1694
bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1695
{
1696
DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Writing 0x%08X to "
1697
"0x%08X\n", __FUNCTION__, val, offset);
1698
1699
bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1700
}
1701
1702
/****************************************************************************/
1703
/* Shared memory read. */
1704
/* */
1705
/* Reads NetXtreme II shared memory region. */
1706
/* */
1707
/* Returns: */
1708
/* The 32 bit value read. */
1709
/****************************************************************************/
1710
static u32
1711
bce_shmem_rd(struct bce_softc *sc, u32 offset)
1712
{
1713
u32 val = bce_reg_rd_ind(sc, sc->bce_shmem_base + offset);
1714
1715
DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Reading 0x%08X from "
1716
"0x%08X\n", __FUNCTION__, val, offset);
1717
1718
return val;
1719
}
1720
1721
#ifdef BCE_DEBUG
1722
/****************************************************************************/
1723
/* Context memory read. */
1724
/* */
1725
/* The NetXtreme II controller uses context memory to track connection */
1726
/* information for L2 and higher network protocols. */
1727
/* */
1728
/* Returns: */
1729
/* The requested 32 bit value of context memory. */
1730
/****************************************************************************/
1731
static u32
1732
bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1733
{
1734
u32 idx, offset, retry_cnt = 5, val;
1735
1736
DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 ||
1737
cid_addr & CTX_MASK), BCE_PRINTF("%s(): Invalid CID "
1738
"address: 0x%08X.\n", __FUNCTION__, cid_addr));
1739
1740
offset = ctx_offset + cid_addr;
1741
1742
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1743
REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1744
1745
for (idx = 0; idx < retry_cnt; idx++) {
1746
val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1747
if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1748
break;
1749
DELAY(5);
1750
}
1751
1752
if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1753
BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1754
"cid_addr = 0x%08X, offset = 0x%08X!\n",
1755
__FILE__, __LINE__, cid_addr, ctx_offset);
1756
1757
val = REG_RD(sc, BCE_CTX_CTX_DATA);
1758
} else {
1759
REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1760
val = REG_RD(sc, BCE_CTX_DATA);
1761
}
1762
1763
DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1764
"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1765
1766
return(val);
1767
}
1768
#endif
1769
1770
/****************************************************************************/
1771
/* Context memory write. */
1772
/* */
1773
/* The NetXtreme II controller uses context memory to track connection */
1774
/* information for L2 and higher network protocols. */
1775
/* */
1776
/* Returns: */
1777
/* Nothing. */
1778
/****************************************************************************/
1779
static void
1780
bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1781
{
1782
u32 idx, offset = ctx_offset + cid_addr;
1783
u32 val, retry_cnt = 5;
1784
1785
DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1786
"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1787
1788
DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1789
BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1790
__FUNCTION__, cid_addr));
1791
1792
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1793
REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1794
REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1795
1796
for (idx = 0; idx < retry_cnt; idx++) {
1797
val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1798
if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1799
break;
1800
DELAY(5);
1801
}
1802
1803
if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1804
BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1805
"cid_addr = 0x%08X, offset = 0x%08X!\n",
1806
__FILE__, __LINE__, cid_addr, ctx_offset);
1807
1808
} else {
1809
REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1810
REG_WR(sc, BCE_CTX_DATA, ctx_val);
1811
}
1812
}
1813
1814
/****************************************************************************/
1815
/* PHY register read. */
1816
/* */
1817
/* Implements register reads on the MII bus. */
1818
/* */
1819
/* Returns: */
1820
/* The value of the register. */
1821
/****************************************************************************/
1822
static int
1823
bce_miibus_read_reg(device_t dev, int phy, int reg)
1824
{
1825
struct bce_softc *sc;
1826
u32 val;
1827
int i;
1828
1829
sc = device_get_softc(dev);
1830
1831
/*
1832
* The 5709S PHY is an IEEE Clause 45 PHY
1833
* with special mappings to work with IEEE
1834
* Clause 22 register accesses.
1835
*/
1836
if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1837
if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1838
reg += 0x10;
1839
}
1840
1841
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1842
val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1843
val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1844
1845
REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1846
REG_RD(sc, BCE_EMAC_MDIO_MODE);
1847
1848
DELAY(40);
1849
}
1850
1851
val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1852
BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1853
BCE_EMAC_MDIO_COMM_START_BUSY;
1854
REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1855
1856
for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1857
DELAY(10);
1858
1859
val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1860
if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1861
DELAY(5);
1862
1863
val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1864
val &= BCE_EMAC_MDIO_COMM_DATA;
1865
1866
break;
1867
}
1868
}
1869
1870
if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1871
BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
1872
"reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
1873
val = 0x0;
1874
} else {
1875
val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1876
}
1877
1878
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1879
val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1880
val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1881
1882
REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1883
REG_RD(sc, BCE_EMAC_MDIO_MODE);
1884
1885
DELAY(40);
1886
}
1887
1888
DB_PRINT_PHY_REG(reg, val);
1889
return (val & 0xffff);
1890
}
1891
1892
/****************************************************************************/
1893
/* PHY register write. */
1894
/* */
1895
/* Implements register writes on the MII bus. */
1896
/* */
1897
/* Returns: */
1898
/* The value of the register. */
1899
/****************************************************************************/
1900
static int
1901
bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1902
{
1903
struct bce_softc *sc;
1904
u32 val1;
1905
int i;
1906
1907
sc = device_get_softc(dev);
1908
1909
DB_PRINT_PHY_REG(reg, val);
1910
1911
/*
1912
* The 5709S PHY is an IEEE Clause 45 PHY
1913
* with special mappings to work with IEEE
1914
* Clause 22 register accesses.
1915
*/
1916
if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1917
if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1918
reg += 0x10;
1919
}
1920
1921
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1922
val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1923
val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1924
1925
REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1926
REG_RD(sc, BCE_EMAC_MDIO_MODE);
1927
1928
DELAY(40);
1929
}
1930
1931
val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1932
BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1933
BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1934
REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1935
1936
for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1937
DELAY(10);
1938
1939
val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1940
if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1941
DELAY(5);
1942
break;
1943
}
1944
}
1945
1946
if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1947
BCE_PRINTF("%s(%d): PHY write timeout!\n",
1948
__FILE__, __LINE__);
1949
1950
if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1951
val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1952
val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1953
1954
REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1955
REG_RD(sc, BCE_EMAC_MDIO_MODE);
1956
1957
DELAY(40);
1958
}
1959
1960
return 0;
1961
}
1962
1963
/****************************************************************************/
1964
/* MII bus status change. */
1965
/* */
1966
/* Called by the MII bus driver when the PHY establishes link to set the */
1967
/* MAC interface registers. */
1968
/* */
1969
/* Returns: */
1970
/* Nothing. */
1971
/****************************************************************************/
1972
static void
1973
bce_miibus_statchg(device_t dev)
1974
{
1975
struct bce_softc *sc;
1976
struct mii_data *mii;
1977
struct ifmediareq ifmr;
1978
int media_active, media_status, val;
1979
1980
sc = device_get_softc(dev);
1981
1982
DBENTER(BCE_VERBOSE_PHY);
1983
1984
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
1985
bzero(&ifmr, sizeof(ifmr));
1986
bce_ifmedia_sts_rphy(sc, &ifmr);
1987
media_active = ifmr.ifm_active;
1988
media_status = ifmr.ifm_status;
1989
} else {
1990
mii = device_get_softc(sc->bce_miibus);
1991
media_active = mii->mii_media_active;
1992
media_status = mii->mii_media_status;
1993
}
1994
1995
/* Ignore invalid media status. */
1996
if ((media_status & (IFM_ACTIVE | IFM_AVALID)) !=
1997
(IFM_ACTIVE | IFM_AVALID))
1998
goto bce_miibus_statchg_exit;
1999
2000
val = REG_RD(sc, BCE_EMAC_MODE);
2001
val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
2002
BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
2003
BCE_EMAC_MODE_25G);
2004
2005
/* Set MII or GMII interface based on the PHY speed. */
2006
switch (IFM_SUBTYPE(media_active)) {
2007
case IFM_10_T:
2008
if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2009
DBPRINT(sc, BCE_INFO_PHY,
2010
"Enabling 10Mb interface.\n");
2011
val |= BCE_EMAC_MODE_PORT_MII_10;
2012
break;
2013
}
2014
/* fall-through */
2015
case IFM_100_TX:
2016
DBPRINT(sc, BCE_INFO_PHY, "Enabling MII interface.\n");
2017
val |= BCE_EMAC_MODE_PORT_MII;
2018
break;
2019
case IFM_2500_SX:
2020
DBPRINT(sc, BCE_INFO_PHY, "Enabling 2.5G MAC mode.\n");
2021
val |= BCE_EMAC_MODE_25G;
2022
/* fall-through */
2023
case IFM_1000_T:
2024
case IFM_1000_SX:
2025
DBPRINT(sc, BCE_INFO_PHY, "Enabling GMII interface.\n");
2026
val |= BCE_EMAC_MODE_PORT_GMII;
2027
break;
2028
default:
2029
DBPRINT(sc, BCE_INFO_PHY, "Unknown link speed, enabling "
2030
"default GMII interface.\n");
2031
val |= BCE_EMAC_MODE_PORT_GMII;
2032
}
2033
2034
/* Set half or full duplex based on PHY settings. */
2035
if ((IFM_OPTIONS(media_active) & IFM_FDX) == 0) {
2036
DBPRINT(sc, BCE_INFO_PHY,
2037
"Setting Half-Duplex interface.\n");
2038
val |= BCE_EMAC_MODE_HALF_DUPLEX;
2039
} else
2040
DBPRINT(sc, BCE_INFO_PHY,
2041
"Setting Full-Duplex interface.\n");
2042
2043
REG_WR(sc, BCE_EMAC_MODE, val);
2044
2045
if ((IFM_OPTIONS(media_active) & IFM_ETH_RXPAUSE) != 0) {
2046
DBPRINT(sc, BCE_INFO_PHY,
2047
"%s(): Enabling RX flow control.\n", __FUNCTION__);
2048
BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2049
sc->bce_flags |= BCE_USING_RX_FLOW_CONTROL;
2050
} else {
2051
DBPRINT(sc, BCE_INFO_PHY,
2052
"%s(): Disabling RX flow control.\n", __FUNCTION__);
2053
BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2054
sc->bce_flags &= ~BCE_USING_RX_FLOW_CONTROL;
2055
}
2056
2057
if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
2058
DBPRINT(sc, BCE_INFO_PHY,
2059
"%s(): Enabling TX flow control.\n", __FUNCTION__);
2060
BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2061
sc->bce_flags |= BCE_USING_TX_FLOW_CONTROL;
2062
} else {
2063
DBPRINT(sc, BCE_INFO_PHY,
2064
"%s(): Disabling TX flow control.\n", __FUNCTION__);
2065
BCE_CLRBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2066
sc->bce_flags &= ~BCE_USING_TX_FLOW_CONTROL;
2067
}
2068
2069
/* ToDo: Update watermarks in bce_init_rx_context(). */
2070
2071
bce_miibus_statchg_exit:
2072
DBEXIT(BCE_VERBOSE_PHY);
2073
}
2074
2075
/****************************************************************************/
2076
/* Acquire NVRAM lock. */
2077
/* */
2078
/* Before the NVRAM can be accessed the caller must acquire an NVRAM lock. */
2079
/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */
2080
/* for use by the driver. */
2081
/* */
2082
/* Returns: */
2083
/* 0 on success, positive value on failure. */
2084
/****************************************************************************/
2085
static int
2086
bce_acquire_nvram_lock(struct bce_softc *sc)
2087
{
2088
u32 val;
2089
int j, rc = 0;
2090
2091
DBENTER(BCE_VERBOSE_NVRAM);
2092
2093
/* Request access to the flash interface. */
2094
REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
2095
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2096
val = REG_RD(sc, BCE_NVM_SW_ARB);
2097
if (val & BCE_NVM_SW_ARB_ARB_ARB2)
2098
break;
2099
2100
DELAY(5);
2101
}
2102
2103
if (j >= NVRAM_TIMEOUT_COUNT) {
2104
DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
2105
rc = EBUSY;
2106
}
2107
2108
DBEXIT(BCE_VERBOSE_NVRAM);
2109
return (rc);
2110
}
2111
2112
/****************************************************************************/
2113
/* Release NVRAM lock. */
2114
/* */
2115
/* When the caller is finished accessing NVRAM the lock must be released. */
2116
/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */
2117
/* for use by the driver. */
2118
/* */
2119
/* Returns: */
2120
/* 0 on success, positive value on failure. */
2121
/****************************************************************************/
2122
static int
2123
bce_release_nvram_lock(struct bce_softc *sc)
2124
{
2125
u32 val;
2126
int j, rc = 0;
2127
2128
DBENTER(BCE_VERBOSE_NVRAM);
2129
2130
/*
2131
* Relinquish nvram interface.
2132
*/
2133
REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
2134
2135
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2136
val = REG_RD(sc, BCE_NVM_SW_ARB);
2137
if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
2138
break;
2139
2140
DELAY(5);
2141
}
2142
2143
if (j >= NVRAM_TIMEOUT_COUNT) {
2144
DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
2145
rc = EBUSY;
2146
}
2147
2148
DBEXIT(BCE_VERBOSE_NVRAM);
2149
return (rc);
2150
}
2151
2152
#ifdef BCE_NVRAM_WRITE_SUPPORT
2153
/****************************************************************************/
2154
/* Enable NVRAM write access. */
2155
/* */
2156
/* Before writing to NVRAM the caller must enable NVRAM writes. */
2157
/* */
2158
/* Returns: */
2159
/* 0 on success, positive value on failure. */
2160
/****************************************************************************/
2161
static int
2162
bce_enable_nvram_write(struct bce_softc *sc)
2163
{
2164
u32 val;
2165
int rc = 0;
2166
2167
DBENTER(BCE_VERBOSE_NVRAM);
2168
2169
val = REG_RD(sc, BCE_MISC_CFG);
2170
REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
2171
2172
if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2173
int j;
2174
2175
REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2176
REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
2177
2178
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2179
DELAY(5);
2180
2181
val = REG_RD(sc, BCE_NVM_COMMAND);
2182
if (val & BCE_NVM_COMMAND_DONE)
2183
break;
2184
}
2185
2186
if (j >= NVRAM_TIMEOUT_COUNT) {
2187
DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
2188
rc = EBUSY;
2189
}
2190
}
2191
2192
DBENTER(BCE_VERBOSE_NVRAM);
2193
return (rc);
2194
}
2195
2196
/****************************************************************************/
2197
/* Disable NVRAM write access. */
2198
/* */
2199
/* When the caller is finished writing to NVRAM write access must be */
2200
/* disabled. */
2201
/* */
2202
/* Returns: */
2203
/* Nothing. */
2204
/****************************************************************************/
2205
static void
2206
bce_disable_nvram_write(struct bce_softc *sc)
2207
{
2208
u32 val;
2209
2210
DBENTER(BCE_VERBOSE_NVRAM);
2211
2212
val = REG_RD(sc, BCE_MISC_CFG);
2213
REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
2214
2215
DBEXIT(BCE_VERBOSE_NVRAM);
2216
2217
}
2218
#endif
2219
2220
/****************************************************************************/
2221
/* Enable NVRAM access. */
2222
/* */
2223
/* Before accessing NVRAM for read or write operations the caller must */
2224
/* enabled NVRAM access. */
2225
/* */
2226
/* Returns: */
2227
/* Nothing. */
2228
/****************************************************************************/
2229
static void
2230
bce_enable_nvram_access(struct bce_softc *sc)
2231
{
2232
u32 val;
2233
2234
DBENTER(BCE_VERBOSE_NVRAM);
2235
2236
val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2237
/* Enable both bits, even on read. */
2238
REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val |
2239
BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
2240
2241
DBEXIT(BCE_VERBOSE_NVRAM);
2242
}
2243
2244
/****************************************************************************/
2245
/* Disable NVRAM access. */
2246
/* */
2247
/* When the caller is finished accessing NVRAM access must be disabled. */
2248
/* */
2249
/* Returns: */
2250
/* Nothing. */
2251
/****************************************************************************/
2252
static void
2253
bce_disable_nvram_access(struct bce_softc *sc)
2254
{
2255
u32 val;
2256
2257
DBENTER(BCE_VERBOSE_NVRAM);
2258
2259
val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2260
2261
/* Disable both bits, even after read. */
2262
REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val &
2263
~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
2264
2265
DBEXIT(BCE_VERBOSE_NVRAM);
2266
}
2267
2268
#ifdef BCE_NVRAM_WRITE_SUPPORT
2269
/****************************************************************************/
2270
/* Erase NVRAM page before writing. */
2271
/* */
2272
/* Non-buffered flash parts require that a page be erased before it is */
2273
/* written. */
2274
/* */
2275
/* Returns: */
2276
/* 0 on success, positive value on failure. */
2277
/****************************************************************************/
2278
static int
2279
bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
2280
{
2281
u32 cmd;
2282
int j, rc = 0;
2283
2284
DBENTER(BCE_VERBOSE_NVRAM);
2285
2286
/* Buffered flash doesn't require an erase. */
2287
if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
2288
goto bce_nvram_erase_page_exit;
2289
2290
/* Build an erase command. */
2291
cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
2292
BCE_NVM_COMMAND_DOIT;
2293
2294
/*
2295
* Clear the DONE bit separately, set the NVRAM address to erase,
2296
* and issue the erase command.
2297
*/
2298
REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2299
REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2300
REG_WR(sc, BCE_NVM_COMMAND, cmd);
2301
2302
/* Wait for completion. */
2303
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2304
u32 val;
2305
2306
DELAY(5);
2307
2308
val = REG_RD(sc, BCE_NVM_COMMAND);
2309
if (val & BCE_NVM_COMMAND_DONE)
2310
break;
2311
}
2312
2313
if (j >= NVRAM_TIMEOUT_COUNT) {
2314
DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
2315
rc = EBUSY;
2316
}
2317
2318
bce_nvram_erase_page_exit:
2319
DBEXIT(BCE_VERBOSE_NVRAM);
2320
return (rc);
2321
}
2322
#endif /* BCE_NVRAM_WRITE_SUPPORT */
2323
2324
/****************************************************************************/
2325
/* Read a dword (32 bits) from NVRAM. */
2326
/* */
2327
/* Read a 32 bit word from NVRAM. The caller is assumed to have already */
2328
/* obtained the NVRAM lock and enabled the controller for NVRAM access. */
2329
/* */
2330
/* Returns: */
2331
/* 0 on success and the 32 bit value read, positive value on failure. */
2332
/****************************************************************************/
2333
static int
2334
bce_nvram_read_dword(struct bce_softc *sc,
2335
u32 offset, u8 *ret_val, u32 cmd_flags)
2336
{
2337
u32 cmd;
2338
int i, rc = 0;
2339
2340
DBENTER(BCE_EXTREME_NVRAM);
2341
2342
/* Build the command word. */
2343
cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
2344
2345
/* Calculate the offset for buffered flash if translation is used. */
2346
if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2347
offset = ((offset / sc->bce_flash_info->page_size) <<
2348
sc->bce_flash_info->page_bits) +
2349
(offset % sc->bce_flash_info->page_size);
2350
}
2351
2352
/*
2353
* Clear the DONE bit separately, set the address to read,
2354
* and issue the read.
2355
*/
2356
REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2357
REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2358
REG_WR(sc, BCE_NVM_COMMAND, cmd);
2359
2360
/* Wait for completion. */
2361
for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2362
u32 val;
2363
2364
DELAY(5);
2365
2366
val = REG_RD(sc, BCE_NVM_COMMAND);
2367
if (val & BCE_NVM_COMMAND_DONE) {
2368
val = REG_RD(sc, BCE_NVM_READ);
2369
2370
val = bce_be32toh(val);
2371
memcpy(ret_val, &val, 4);
2372
break;
2373
}
2374
}
2375
2376
/* Check for errors. */
2377
if (i >= NVRAM_TIMEOUT_COUNT) {
2378
BCE_PRINTF("%s(%d): Timeout error reading NVRAM at "
2379
"offset 0x%08X!\n", __FILE__, __LINE__, offset);
2380
rc = EBUSY;
2381
}
2382
2383
DBEXIT(BCE_EXTREME_NVRAM);
2384
return(rc);
2385
}
2386
2387
#ifdef BCE_NVRAM_WRITE_SUPPORT
2388
/****************************************************************************/
2389
/* Write a dword (32 bits) to NVRAM. */
2390
/* */
2391
/* Write a 32 bit word to NVRAM. The caller is assumed to have already */
2392
/* obtained the NVRAM lock, enabled the controller for NVRAM access, and */
2393
/* enabled NVRAM write access. */
2394
/* */
2395
/* Returns: */
2396
/* 0 on success, positive value on failure. */
2397
/****************************************************************************/
2398
static int
2399
bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2400
u32 cmd_flags)
2401
{
2402
u32 cmd, val32;
2403
int j, rc = 0;
2404
2405
DBENTER(BCE_VERBOSE_NVRAM);
2406
2407
/* Build the command word. */
2408
cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2409
2410
/* Calculate the offset for buffered flash if translation is used. */
2411
if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2412
offset = ((offset / sc->bce_flash_info->page_size) <<
2413
sc->bce_flash_info->page_bits) +
2414
(offset % sc->bce_flash_info->page_size);
2415
}
2416
2417
/*
2418
* Clear the DONE bit separately, convert NVRAM data to big-endian,
2419
* set the NVRAM address to write, and issue the write command
2420
*/
2421
REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2422
memcpy(&val32, val, 4);
2423
val32 = htobe32(val32);
2424
REG_WR(sc, BCE_NVM_WRITE, val32);
2425
REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2426
REG_WR(sc, BCE_NVM_COMMAND, cmd);
2427
2428
/* Wait for completion. */
2429
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2430
DELAY(5);
2431
2432
if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2433
break;
2434
}
2435
if (j >= NVRAM_TIMEOUT_COUNT) {
2436
BCE_PRINTF("%s(%d): Timeout error writing NVRAM at "
2437
"offset 0x%08X\n", __FILE__, __LINE__, offset);
2438
rc = EBUSY;
2439
}
2440
2441
DBEXIT(BCE_VERBOSE_NVRAM);
2442
return (rc);
2443
}
2444
#endif /* BCE_NVRAM_WRITE_SUPPORT */
2445
2446
/****************************************************************************/
2447
/* Initialize NVRAM access. */
2448
/* */
2449
/* Identify the NVRAM device in use and prepare the NVRAM interface to */
2450
/* access that device. */
2451
/* */
2452
/* Returns: */
2453
/* 0 on success, positive value on failure. */
2454
/****************************************************************************/
2455
static int
2456
bce_init_nvram(struct bce_softc *sc)
2457
{
2458
u32 val;
2459
int j, entry_count, rc = 0;
2460
const struct flash_spec *flash;
2461
2462
DBENTER(BCE_VERBOSE_NVRAM);
2463
2464
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2465
sc->bce_flash_info = &flash_5709;
2466
goto bce_init_nvram_get_flash_size;
2467
}
2468
2469
/* Determine the selected interface. */
2470
val = REG_RD(sc, BCE_NVM_CFG1);
2471
2472
entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2473
2474
/*
2475
* Flash reconfiguration is required to support additional
2476
* NVRAM devices not directly supported in hardware.
2477
* Check if the flash interface was reconfigured
2478
* by the bootcode.
2479
*/
2480
2481
if (val & 0x40000000) {
2482
/* Flash interface reconfigured by bootcode. */
2483
2484
DBPRINT(sc,BCE_INFO_LOAD,
2485
"bce_init_nvram(): Flash WAS reconfigured.\n");
2486
2487
for (j = 0, flash = &flash_table[0]; j < entry_count;
2488
j++, flash++) {
2489
if ((val & FLASH_BACKUP_STRAP_MASK) ==
2490
(flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2491
sc->bce_flash_info = flash;
2492
break;
2493
}
2494
}
2495
} else {
2496
/* Flash interface not yet reconfigured. */
2497
u32 mask;
2498
2499
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2500
__FUNCTION__);
2501
2502
if (val & (1 << 23))
2503
mask = FLASH_BACKUP_STRAP_MASK;
2504
else
2505
mask = FLASH_STRAP_MASK;
2506
2507
/* Look for the matching NVRAM device configuration data. */
2508
for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2509
/* Check if the device matches any of the known devices. */
2510
if ((val & mask) == (flash->strapping & mask)) {
2511
/* Found a device match. */
2512
sc->bce_flash_info = flash;
2513
2514
/* Request access to the flash interface. */
2515
if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2516
return rc;
2517
2518
/* Reconfigure the flash interface. */
2519
bce_enable_nvram_access(sc);
2520
REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2521
REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2522
REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2523
REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2524
bce_disable_nvram_access(sc);
2525
bce_release_nvram_lock(sc);
2526
2527
break;
2528
}
2529
}
2530
}
2531
2532
/* Check if a matching device was found. */
2533
if (j == entry_count) {
2534
sc->bce_flash_info = NULL;
2535
BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2536
__FILE__, __LINE__);
2537
DBEXIT(BCE_VERBOSE_NVRAM);
2538
return (ENODEV);
2539
}
2540
2541
bce_init_nvram_get_flash_size:
2542
/* Write the flash config data to the shared memory interface. */
2543
val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2544
val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2545
if (val)
2546
sc->bce_flash_size = val;
2547
else
2548
sc->bce_flash_size = sc->bce_flash_info->total_size;
2549
2550
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2551
__FUNCTION__, sc->bce_flash_info->name,
2552
sc->bce_flash_info->total_size);
2553
2554
DBEXIT(BCE_VERBOSE_NVRAM);
2555
return rc;
2556
}
2557
2558
/****************************************************************************/
2559
/* Read an arbitrary range of data from NVRAM. */
2560
/* */
2561
/* Prepares the NVRAM interface for access and reads the requested data */
2562
/* into the supplied buffer. */
2563
/* */
2564
/* Returns: */
2565
/* 0 on success and the data read, positive value on failure. */
2566
/****************************************************************************/
2567
static int
2568
bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2569
int buf_size)
2570
{
2571
int rc = 0;
2572
u32 cmd_flags, offset32, len32, extra;
2573
2574
DBENTER(BCE_VERBOSE_NVRAM);
2575
2576
if (buf_size == 0)
2577
goto bce_nvram_read_exit;
2578
2579
/* Request access to the flash interface. */
2580
if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2581
goto bce_nvram_read_exit;
2582
2583
/* Enable access to flash interface */
2584
bce_enable_nvram_access(sc);
2585
2586
len32 = buf_size;
2587
offset32 = offset;
2588
extra = 0;
2589
2590
cmd_flags = 0;
2591
2592
if (offset32 & 3) {
2593
u8 buf[4];
2594
u32 pre_len;
2595
2596
offset32 &= ~3;
2597
pre_len = 4 - (offset & 3);
2598
2599
if (pre_len >= len32) {
2600
pre_len = len32;
2601
cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2602
}
2603
else {
2604
cmd_flags = BCE_NVM_COMMAND_FIRST;
2605
}
2606
2607
rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2608
2609
if (rc)
2610
return rc;
2611
2612
memcpy(ret_buf, buf + (offset & 3), pre_len);
2613
2614
offset32 += 4;
2615
ret_buf += pre_len;
2616
len32 -= pre_len;
2617
}
2618
2619
if (len32 & 3) {
2620
extra = 4 - (len32 & 3);
2621
len32 = (len32 + 4) & ~3;
2622
}
2623
2624
if (len32 == 4) {
2625
u8 buf[4];
2626
2627
if (cmd_flags)
2628
cmd_flags = BCE_NVM_COMMAND_LAST;
2629
else
2630
cmd_flags = BCE_NVM_COMMAND_FIRST |
2631
BCE_NVM_COMMAND_LAST;
2632
2633
rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2634
2635
memcpy(ret_buf, buf, 4 - extra);
2636
}
2637
else if (len32 > 0) {
2638
u8 buf[4];
2639
2640
/* Read the first word. */
2641
if (cmd_flags)
2642
cmd_flags = 0;
2643
else
2644
cmd_flags = BCE_NVM_COMMAND_FIRST;
2645
2646
rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2647
2648
/* Advance to the next dword. */
2649
offset32 += 4;
2650
ret_buf += 4;
2651
len32 -= 4;
2652
2653
while (len32 > 4 && rc == 0) {
2654
rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2655
2656
/* Advance to the next dword. */
2657
offset32 += 4;
2658
ret_buf += 4;
2659
len32 -= 4;
2660
}
2661
2662
if (rc)
2663
goto bce_nvram_read_locked_exit;
2664
2665
cmd_flags = BCE_NVM_COMMAND_LAST;
2666
rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2667
2668
memcpy(ret_buf, buf, 4 - extra);
2669
}
2670
2671
bce_nvram_read_locked_exit:
2672
/* Disable access to flash interface and release the lock. */
2673
bce_disable_nvram_access(sc);
2674
bce_release_nvram_lock(sc);
2675
2676
bce_nvram_read_exit:
2677
DBEXIT(BCE_VERBOSE_NVRAM);
2678
return rc;
2679
}
2680
2681
#ifdef BCE_NVRAM_WRITE_SUPPORT
2682
/****************************************************************************/
2683
/* Write an arbitrary range of data from NVRAM. */
2684
/* */
2685
/* Prepares the NVRAM interface for write access and writes the requested */
2686
/* data from the supplied buffer. The caller is responsible for */
2687
/* calculating any appropriate CRCs. */
2688
/* */
2689
/* Returns: */
2690
/* 0 on success, positive value on failure. */
2691
/****************************************************************************/
2692
static int
2693
bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2694
int buf_size)
2695
{
2696
u32 written, offset32, len32;
2697
u8 *buf, start[4], end[4];
2698
int rc = 0;
2699
int align_start, align_end;
2700
2701
DBENTER(BCE_VERBOSE_NVRAM);
2702
2703
buf = data_buf;
2704
offset32 = offset;
2705
len32 = buf_size;
2706
align_start = align_end = 0;
2707
2708
if ((align_start = (offset32 & 3))) {
2709
offset32 &= ~3;
2710
len32 += align_start;
2711
if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2712
goto bce_nvram_write_exit;
2713
}
2714
2715
if (len32 & 3) {
2716
if ((len32 > 4) || !align_start) {
2717
align_end = 4 - (len32 & 3);
2718
len32 += align_end;
2719
if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2720
end, 4))) {
2721
goto bce_nvram_write_exit;
2722
}
2723
}
2724
}
2725
2726
if (align_start || align_end) {
2727
buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2728
if (buf == NULL) {
2729
rc = ENOMEM;
2730
goto bce_nvram_write_exit;
2731
}
2732
2733
if (align_start) {
2734
memcpy(buf, start, 4);
2735
}
2736
2737
if (align_end) {
2738
memcpy(buf + len32 - 4, end, 4);
2739
}
2740
memcpy(buf + align_start, data_buf, buf_size);
2741
}
2742
2743
written = 0;
2744
while ((written < len32) && (rc == 0)) {
2745
u32 page_start, page_end, data_start, data_end;
2746
u32 addr, cmd_flags;
2747
int i;
2748
u8 flash_buffer[264];
2749
2750
/* Find the page_start addr */
2751
page_start = offset32 + written;
2752
page_start -= (page_start % sc->bce_flash_info->page_size);
2753
/* Find the page_end addr */
2754
page_end = page_start + sc->bce_flash_info->page_size;
2755
/* Find the data_start addr */
2756
data_start = (written == 0) ? offset32 : page_start;
2757
/* Find the data_end addr */
2758
data_end = (page_end > offset32 + len32) ?
2759
(offset32 + len32) : page_end;
2760
2761
/* Request access to the flash interface. */
2762
if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2763
goto bce_nvram_write_exit;
2764
2765
/* Enable access to flash interface */
2766
bce_enable_nvram_access(sc);
2767
2768
cmd_flags = BCE_NVM_COMMAND_FIRST;
2769
if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2770
int j;
2771
2772
/* Read the whole page into the buffer
2773
* (non-buffer flash only) */
2774
for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2775
if (j == (sc->bce_flash_info->page_size - 4)) {
2776
cmd_flags |= BCE_NVM_COMMAND_LAST;
2777
}
2778
rc = bce_nvram_read_dword(sc,
2779
page_start + j,
2780
&flash_buffer[j],
2781
cmd_flags);
2782
2783
if (rc)
2784
goto bce_nvram_write_locked_exit;
2785
2786
cmd_flags = 0;
2787
}
2788
}
2789
2790
/* Enable writes to flash interface (unlock write-protect) */
2791
if ((rc = bce_enable_nvram_write(sc)) != 0)
2792
goto bce_nvram_write_locked_exit;
2793
2794
/* Erase the page */
2795
if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2796
goto bce_nvram_write_locked_exit;
2797
2798
/* Re-enable the write again for the actual write */
2799
bce_enable_nvram_write(sc);
2800
2801
/* Loop to write back the buffer data from page_start to
2802
* data_start */
2803
i = 0;
2804
if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2805
for (addr = page_start; addr < data_start;
2806
addr += 4, i += 4) {
2807
rc = bce_nvram_write_dword(sc, addr,
2808
&flash_buffer[i], cmd_flags);
2809
2810
if (rc != 0)
2811
goto bce_nvram_write_locked_exit;
2812
2813
cmd_flags = 0;
2814
}
2815
}
2816
2817
/* Loop to write the new data from data_start to data_end */
2818
for (addr = data_start; addr < data_end; addr += 4, i++) {
2819
if ((addr == page_end - 4) ||
2820
((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2821
(addr == data_end - 4))) {
2822
cmd_flags |= BCE_NVM_COMMAND_LAST;
2823
}
2824
rc = bce_nvram_write_dword(sc, addr, buf,
2825
cmd_flags);
2826
2827
if (rc != 0)
2828
goto bce_nvram_write_locked_exit;
2829
2830
cmd_flags = 0;
2831
buf += 4;
2832
}
2833
2834
/* Loop to write back the buffer data from data_end
2835
* to page_end */
2836
if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2837
for (addr = data_end; addr < page_end;
2838
addr += 4, i += 4) {
2839
if (addr == page_end-4) {
2840
cmd_flags = BCE_NVM_COMMAND_LAST;
2841
}
2842
rc = bce_nvram_write_dword(sc, addr,
2843
&flash_buffer[i], cmd_flags);
2844
2845
if (rc != 0)
2846
goto bce_nvram_write_locked_exit;
2847
2848
cmd_flags = 0;
2849
}
2850
}
2851
2852
/* Disable writes to flash interface (lock write-protect) */
2853
bce_disable_nvram_write(sc);
2854
2855
/* Disable access to flash interface */
2856
bce_disable_nvram_access(sc);
2857
bce_release_nvram_lock(sc);
2858
2859
/* Increment written */
2860
written += data_end - data_start;
2861
}
2862
2863
goto bce_nvram_write_exit;
2864
2865
bce_nvram_write_locked_exit:
2866
bce_disable_nvram_write(sc);
2867
bce_disable_nvram_access(sc);
2868
bce_release_nvram_lock(sc);
2869
2870
bce_nvram_write_exit:
2871
if (align_start || align_end)
2872
free(buf, M_DEVBUF);
2873
2874
DBEXIT(BCE_VERBOSE_NVRAM);
2875
return (rc);
2876
}
2877
#endif /* BCE_NVRAM_WRITE_SUPPORT */
2878
2879
/****************************************************************************/
2880
/* Verifies that NVRAM is accessible and contains valid data. */
2881
/* */
2882
/* Reads the configuration data from NVRAM and verifies that the CRC is */
2883
/* correct. */
2884
/* */
2885
/* Returns: */
2886
/* 0 on success, positive value on failure. */
2887
/****************************************************************************/
2888
static int
2889
bce_nvram_test(struct bce_softc *sc)
2890
{
2891
u32 buf[BCE_NVRAM_SIZE / 4];
2892
u8 *data = (u8 *) buf;
2893
int rc = 0;
2894
u32 magic, csum;
2895
2896
DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2897
2898
/*
2899
* Check that the device NVRAM is valid by reading
2900
* the magic value at offset 0.
2901
*/
2902
if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2903
BCE_PRINTF("%s(%d): Unable to read NVRAM!\n",
2904
__FILE__, __LINE__);
2905
goto bce_nvram_test_exit;
2906
}
2907
2908
/*
2909
* Verify that offset 0 of the NVRAM contains
2910
* a valid magic number.
2911
*/
2912
magic = bce_be32toh(buf[0]);
2913
if (magic != BCE_NVRAM_MAGIC) {
2914
rc = ENODEV;
2915
BCE_PRINTF("%s(%d): Invalid NVRAM magic value! "
2916
"Expected: 0x%08X, Found: 0x%08X\n",
2917
__FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2918
goto bce_nvram_test_exit;
2919
}
2920
2921
/*
2922
* Verify that the device NVRAM includes valid
2923
* configuration data.
2924
*/
2925
if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2926
BCE_PRINTF("%s(%d): Unable to read manufacturing "
2927
"Information from NVRAM!\n", __FILE__, __LINE__);
2928
goto bce_nvram_test_exit;
2929
}
2930
2931
csum = ether_crc32_le(data, 0x100);
2932
if (csum != BCE_CRC32_RESIDUAL) {
2933
rc = ENODEV;
2934
BCE_PRINTF("%s(%d): Invalid manufacturing information "
2935
"NVRAM CRC! Expected: 0x%08X, Found: 0x%08X\n",
2936
__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2937
goto bce_nvram_test_exit;
2938
}
2939
2940
csum = ether_crc32_le(data + 0x100, 0x100);
2941
if (csum != BCE_CRC32_RESIDUAL) {
2942
rc = ENODEV;
2943
BCE_PRINTF("%s(%d): Invalid feature configuration "
2944
"information NVRAM CRC! Expected: 0x%08X, "
2945
"Found: 08%08X\n", __FILE__, __LINE__,
2946
BCE_CRC32_RESIDUAL, csum);
2947
}
2948
2949
bce_nvram_test_exit:
2950
DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2951
return rc;
2952
}
2953
2954
/****************************************************************************/
2955
/* Calculates the size of the buffers to allocate based on the MTU. */
2956
/* */
2957
/* Returns: */
2958
/* Nothing. */
2959
/****************************************************************************/
2960
static void
2961
bce_get_rx_buffer_sizes(struct bce_softc *sc, int mtu)
2962
{
2963
DBENTER(BCE_VERBOSE_LOAD);
2964
2965
/* Use a single allocation type when header splitting enabled. */
2966
if (bce_hdr_split == TRUE) {
2967
sc->rx_bd_mbuf_alloc_size = MHLEN;
2968
/* Make sure offset is 16 byte aligned for hardware. */
2969
sc->rx_bd_mbuf_align_pad =
2970
roundup2(MSIZE - MHLEN, 16) - (MSIZE - MHLEN);
2971
sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
2972
sc->rx_bd_mbuf_align_pad;
2973
} else {
2974
if ((mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
2975
ETHER_CRC_LEN) > MCLBYTES) {
2976
/* Setup for jumbo RX buffer allocations. */
2977
sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
2978
sc->rx_bd_mbuf_align_pad =
2979
roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
2980
sc->rx_bd_mbuf_data_len =
2981
sc->rx_bd_mbuf_alloc_size -
2982
sc->rx_bd_mbuf_align_pad;
2983
} else {
2984
/* Setup for standard RX buffer allocations. */
2985
sc->rx_bd_mbuf_alloc_size = MCLBYTES;
2986
sc->rx_bd_mbuf_align_pad =
2987
roundup2(MCLBYTES, 16) - MCLBYTES;
2988
sc->rx_bd_mbuf_data_len =
2989
sc->rx_bd_mbuf_alloc_size -
2990
sc->rx_bd_mbuf_align_pad;
2991
}
2992
}
2993
2994
// DBPRINT(sc, BCE_INFO_LOAD,
2995
DBPRINT(sc, BCE_WARN,
2996
"%s(): rx_bd_mbuf_alloc_size = %d, rx_bd_mbuf_data_len = %d, "
2997
"rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
2998
sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
2999
sc->rx_bd_mbuf_align_pad);
3000
3001
DBEXIT(BCE_VERBOSE_LOAD);
3002
}
3003
3004
/****************************************************************************/
3005
/* Identifies the current media type of the controller and sets the PHY */
3006
/* address. */
3007
/* */
3008
/* Returns: */
3009
/* Nothing. */
3010
/****************************************************************************/
3011
static void
3012
bce_get_media(struct bce_softc *sc)
3013
{
3014
u32 val;
3015
3016
DBENTER(BCE_VERBOSE_PHY);
3017
3018
/* Assume PHY address for copper controllers. */
3019
sc->bce_phy_addr = 1;
3020
3021
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3022
u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
3023
u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
3024
u32 strap;
3025
3026
/*
3027
* The BCM5709S is software configurable
3028
* for Copper or SerDes operation.
3029
*/
3030
if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
3031
DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3032
"for copper.\n");
3033
goto bce_get_media_exit;
3034
} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
3035
DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3036
"for dual media.\n");
3037
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3038
goto bce_get_media_exit;
3039
}
3040
3041
if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
3042
strap = (val &
3043
BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
3044
else
3045
strap = (val &
3046
BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
3047
3048
if (pci_get_function(sc->bce_dev) == 0) {
3049
switch (strap) {
3050
case 0x4:
3051
case 0x5:
3052
case 0x6:
3053
DBPRINT(sc, BCE_INFO_LOAD,
3054
"BCM5709 s/w configured for SerDes.\n");
3055
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3056
break;
3057
default:
3058
DBPRINT(sc, BCE_INFO_LOAD,
3059
"BCM5709 s/w configured for Copper.\n");
3060
break;
3061
}
3062
} else {
3063
switch (strap) {
3064
case 0x1:
3065
case 0x2:
3066
case 0x4:
3067
DBPRINT(sc, BCE_INFO_LOAD,
3068
"BCM5709 s/w configured for SerDes.\n");
3069
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3070
break;
3071
default:
3072
DBPRINT(sc, BCE_INFO_LOAD,
3073
"BCM5709 s/w configured for Copper.\n");
3074
break;
3075
}
3076
}
3077
3078
} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
3079
sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3080
3081
if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
3082
sc->bce_flags |= BCE_NO_WOL_FLAG;
3083
3084
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
3085
sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
3086
3087
if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
3088
/* 5708S/09S/16S use a separate PHY for SerDes. */
3089
sc->bce_phy_addr = 2;
3090
3091
val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
3092
if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
3093
sc->bce_phy_flags |=
3094
BCE_PHY_2_5G_CAPABLE_FLAG;
3095
DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
3096
"capable adapter\n");
3097
}
3098
}
3099
} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
3100
(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
3101
sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
3102
3103
bce_get_media_exit:
3104
DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
3105
"Using PHY address %d.\n", sc->bce_phy_addr);
3106
3107
DBEXIT(BCE_VERBOSE_PHY);
3108
}
3109
3110
/****************************************************************************/
3111
/* Performs PHY initialization required before MII drivers access the */
3112
/* device. */
3113
/* */
3114
/* Returns: */
3115
/* Nothing. */
3116
/****************************************************************************/
3117
static void
3118
bce_init_media(struct bce_softc *sc)
3119
{
3120
if ((sc->bce_phy_flags & (BCE_PHY_IEEE_CLAUSE_45_FLAG |
3121
BCE_PHY_REMOTE_CAP_FLAG)) == BCE_PHY_IEEE_CLAUSE_45_FLAG) {
3122
/*
3123
* Configure 5709S/5716S PHYs to use traditional IEEE
3124
* Clause 22 method. Otherwise we have no way to attach
3125
* the PHY in mii(4) layer. PHY specific configuration
3126
* is done in mii layer.
3127
*/
3128
3129
/* Select auto-negotiation MMD of the PHY. */
3130
bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3131
BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
3132
bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3133
BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
3134
3135
/* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
3136
bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3137
BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
3138
}
3139
}
3140
3141
/****************************************************************************/
3142
/* Free any DMA memory owned by the driver. */
3143
/* */
3144
/* Scans through each data structure that requires DMA memory and frees */
3145
/* the memory if allocated. */
3146
/* */
3147
/* Returns: */
3148
/* Nothing. */
3149
/****************************************************************************/
3150
static void
3151
bce_dma_free(struct bce_softc *sc)
3152
{
3153
int i;
3154
3155
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3156
3157
/* Free, unmap, and destroy the status block. */
3158
if (sc->status_block_paddr != 0) {
3159
bus_dmamap_unload(
3160
sc->status_tag,
3161
sc->status_map);
3162
sc->status_block_paddr = 0;
3163
}
3164
3165
if (sc->status_block != NULL) {
3166
bus_dmamem_free(
3167
sc->status_tag,
3168
sc->status_block,
3169
sc->status_map);
3170
sc->status_block = NULL;
3171
}
3172
3173
if (sc->status_tag != NULL) {
3174
bus_dma_tag_destroy(sc->status_tag);
3175
sc->status_tag = NULL;
3176
}
3177
3178
/* Free, unmap, and destroy the statistics block. */
3179
if (sc->stats_block_paddr != 0) {
3180
bus_dmamap_unload(
3181
sc->stats_tag,
3182
sc->stats_map);
3183
sc->stats_block_paddr = 0;
3184
}
3185
3186
if (sc->stats_block != NULL) {
3187
bus_dmamem_free(
3188
sc->stats_tag,
3189
sc->stats_block,
3190
sc->stats_map);
3191
sc->stats_block = NULL;
3192
}
3193
3194
if (sc->stats_tag != NULL) {
3195
bus_dma_tag_destroy(sc->stats_tag);
3196
sc->stats_tag = NULL;
3197
}
3198
3199
/* Free, unmap and destroy all context memory pages. */
3200
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3201
for (i = 0; i < sc->ctx_pages; i++ ) {
3202
if (sc->ctx_paddr[i] != 0) {
3203
bus_dmamap_unload(
3204
sc->ctx_tag,
3205
sc->ctx_map[i]);
3206
sc->ctx_paddr[i] = 0;
3207
}
3208
3209
if (sc->ctx_block[i] != NULL) {
3210
bus_dmamem_free(
3211
sc->ctx_tag,
3212
sc->ctx_block[i],
3213
sc->ctx_map[i]);
3214
sc->ctx_block[i] = NULL;
3215
}
3216
}
3217
3218
/* Destroy the context memory tag. */
3219
if (sc->ctx_tag != NULL) {
3220
bus_dma_tag_destroy(sc->ctx_tag);
3221
sc->ctx_tag = NULL;
3222
}
3223
}
3224
3225
/* Free, unmap and destroy all TX buffer descriptor chain pages. */
3226
for (i = 0; i < sc->tx_pages; i++ ) {
3227
if (sc->tx_bd_chain_paddr[i] != 0) {
3228
bus_dmamap_unload(
3229
sc->tx_bd_chain_tag,
3230
sc->tx_bd_chain_map[i]);
3231
sc->tx_bd_chain_paddr[i] = 0;
3232
}
3233
3234
if (sc->tx_bd_chain[i] != NULL) {
3235
bus_dmamem_free(
3236
sc->tx_bd_chain_tag,
3237
sc->tx_bd_chain[i],
3238
sc->tx_bd_chain_map[i]);
3239
sc->tx_bd_chain[i] = NULL;
3240
}
3241
}
3242
3243
/* Destroy the TX buffer descriptor tag. */
3244
if (sc->tx_bd_chain_tag != NULL) {
3245
bus_dma_tag_destroy(sc->tx_bd_chain_tag);
3246
sc->tx_bd_chain_tag = NULL;
3247
}
3248
3249
/* Free, unmap and destroy all RX buffer descriptor chain pages. */
3250
for (i = 0; i < sc->rx_pages; i++ ) {
3251
if (sc->rx_bd_chain_paddr[i] != 0) {
3252
bus_dmamap_unload(
3253
sc->rx_bd_chain_tag,
3254
sc->rx_bd_chain_map[i]);
3255
sc->rx_bd_chain_paddr[i] = 0;
3256
}
3257
3258
if (sc->rx_bd_chain[i] != NULL) {
3259
bus_dmamem_free(
3260
sc->rx_bd_chain_tag,
3261
sc->rx_bd_chain[i],
3262
sc->rx_bd_chain_map[i]);
3263
sc->rx_bd_chain[i] = NULL;
3264
}
3265
}
3266
3267
/* Destroy the RX buffer descriptor tag. */
3268
if (sc->rx_bd_chain_tag != NULL) {
3269
bus_dma_tag_destroy(sc->rx_bd_chain_tag);
3270
sc->rx_bd_chain_tag = NULL;
3271
}
3272
3273
/* Free, unmap and destroy all page buffer descriptor chain pages. */
3274
if (bce_hdr_split == TRUE) {
3275
for (i = 0; i < sc->pg_pages; i++ ) {
3276
if (sc->pg_bd_chain_paddr[i] != 0) {
3277
bus_dmamap_unload(
3278
sc->pg_bd_chain_tag,
3279
sc->pg_bd_chain_map[i]);
3280
sc->pg_bd_chain_paddr[i] = 0;
3281
}
3282
3283
if (sc->pg_bd_chain[i] != NULL) {
3284
bus_dmamem_free(
3285
sc->pg_bd_chain_tag,
3286
sc->pg_bd_chain[i],
3287
sc->pg_bd_chain_map[i]);
3288
sc->pg_bd_chain[i] = NULL;
3289
}
3290
}
3291
3292
/* Destroy the page buffer descriptor tag. */
3293
if (sc->pg_bd_chain_tag != NULL) {
3294
bus_dma_tag_destroy(sc->pg_bd_chain_tag);
3295
sc->pg_bd_chain_tag = NULL;
3296
}
3297
}
3298
3299
/* Unload and destroy the TX mbuf maps. */
3300
for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
3301
if (sc->tx_mbuf_map[i] != NULL) {
3302
bus_dmamap_unload(sc->tx_mbuf_tag,
3303
sc->tx_mbuf_map[i]);
3304
bus_dmamap_destroy(sc->tx_mbuf_tag,
3305
sc->tx_mbuf_map[i]);
3306
sc->tx_mbuf_map[i] = NULL;
3307
}
3308
}
3309
3310
/* Destroy the TX mbuf tag. */
3311
if (sc->tx_mbuf_tag != NULL) {
3312
bus_dma_tag_destroy(sc->tx_mbuf_tag);
3313
sc->tx_mbuf_tag = NULL;
3314
}
3315
3316
/* Unload and destroy the RX mbuf maps. */
3317
for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
3318
if (sc->rx_mbuf_map[i] != NULL) {
3319
bus_dmamap_unload(sc->rx_mbuf_tag,
3320
sc->rx_mbuf_map[i]);
3321
bus_dmamap_destroy(sc->rx_mbuf_tag,
3322
sc->rx_mbuf_map[i]);
3323
sc->rx_mbuf_map[i] = NULL;
3324
}
3325
}
3326
3327
/* Destroy the RX mbuf tag. */
3328
if (sc->rx_mbuf_tag != NULL) {
3329
bus_dma_tag_destroy(sc->rx_mbuf_tag);
3330
sc->rx_mbuf_tag = NULL;
3331
}
3332
3333
/* Unload and destroy the page mbuf maps. */
3334
if (bce_hdr_split == TRUE) {
3335
for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
3336
if (sc->pg_mbuf_map[i] != NULL) {
3337
bus_dmamap_unload(sc->pg_mbuf_tag,
3338
sc->pg_mbuf_map[i]);
3339
bus_dmamap_destroy(sc->pg_mbuf_tag,
3340
sc->pg_mbuf_map[i]);
3341
sc->pg_mbuf_map[i] = NULL;
3342
}
3343
}
3344
3345
/* Destroy the page mbuf tag. */
3346
if (sc->pg_mbuf_tag != NULL) {
3347
bus_dma_tag_destroy(sc->pg_mbuf_tag);
3348
sc->pg_mbuf_tag = NULL;
3349
}
3350
}
3351
3352
/* Destroy the parent tag */
3353
if (sc->parent_tag != NULL) {
3354
bus_dma_tag_destroy(sc->parent_tag);
3355
sc->parent_tag = NULL;
3356
}
3357
3358
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3359
}
3360
3361
/****************************************************************************/
3362
/* Get DMA memory from the OS. */
3363
/* */
3364
/* Validates that the OS has provided DMA buffers in response to a */
3365
/* bus_dmamap_load() call and saves the physical address of those buffers. */
3366
/* When the callback is used the OS will return 0 for the mapping function */
3367
/* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any */
3368
/* failures back to the caller. */
3369
/* */
3370
/* Returns: */
3371
/* Nothing. */
3372
/****************************************************************************/
3373
static void
3374
bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
3375
{
3376
bus_addr_t *busaddr = arg;
3377
3378
KASSERT(nseg == 1, ("%s(): Too many segments returned (%d)!",
3379
__FUNCTION__, nseg));
3380
/* Simulate a mapping failure. */
3381
DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
3382
error = ENOMEM);
3383
3384
/* ToDo: How to increment debug sim_count variable here? */
3385
3386
/* Check for an error and signal the caller that an error occurred. */
3387
if (error) {
3388
*busaddr = 0;
3389
} else {
3390
*busaddr = segs->ds_addr;
3391
}
3392
}
3393
3394
/****************************************************************************/
3395
/* Allocate any DMA memory needed by the driver. */
3396
/* */
3397
/* Allocates DMA memory needed for the various global structures needed by */
3398
/* hardware. */
3399
/* */
3400
/* Memory alignment requirements: */
3401
/* +-----------------+----------+----------+----------+----------+ */
3402
/* | | 5706 | 5708 | 5709 | 5716 | */
3403
/* +-----------------+----------+----------+----------+----------+ */
3404
/* |Status Block | 8 bytes | 8 bytes | 16 bytes | 16 bytes | */
3405
/* |Statistics Block | 8 bytes | 8 bytes | 16 bytes | 16 bytes | */
3406
/* |RX Buffers | 16 bytes | 16 bytes | 16 bytes | 16 bytes | */
3407
/* |PG Buffers | none | none | none | none | */
3408
/* |TX Buffers | none | none | none | none | */
3409
/* |Chain Pages(1) | 4KiB | 4KiB | 4KiB | 4KiB | */
3410
/* |Context Memory | | | | | */
3411
/* +-----------------+----------+----------+----------+----------+ */
3412
/* */
3413
/* (1) Must align with CPU page size (BCM_PAGE_SZIE). */
3414
/* */
3415
/* Returns: */
3416
/* 0 for success, positive value for failure. */
3417
/****************************************************************************/
3418
static int
3419
bce_dma_alloc(device_t dev)
3420
{
3421
struct bce_softc *sc;
3422
int i, error, rc = 0;
3423
bus_size_t max_size, max_seg_size;
3424
int max_segments;
3425
3426
sc = device_get_softc(dev);
3427
3428
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3429
3430
/*
3431
* Allocate the parent bus DMA tag appropriate for PCI.
3432
*/
3433
if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, BCE_DMA_BOUNDARY,
3434
sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3435
BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
3436
&sc->parent_tag)) {
3437
BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3438
__FILE__, __LINE__);
3439
rc = ENOMEM;
3440
goto bce_dma_alloc_exit;
3441
}
3442
3443
/*
3444
* Create a DMA tag for the status block, allocate and clear the
3445
* memory, map the memory into DMA space, and fetch the physical
3446
* address of the block.
3447
*/
3448
if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3449
BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3450
NULL, NULL, BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
3451
0, NULL, NULL, &sc->status_tag)) {
3452
BCE_PRINTF("%s(%d): Could not allocate status block "
3453
"DMA tag!\n", __FILE__, __LINE__);
3454
rc = ENOMEM;
3455
goto bce_dma_alloc_exit;
3456
}
3457
3458
if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
3459
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3460
&sc->status_map)) {
3461
BCE_PRINTF("%s(%d): Could not allocate status block "
3462
"DMA memory!\n", __FILE__, __LINE__);
3463
rc = ENOMEM;
3464
goto bce_dma_alloc_exit;
3465
}
3466
3467
error = bus_dmamap_load(sc->status_tag, sc->status_map,
3468
sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
3469
&sc->status_block_paddr, BUS_DMA_NOWAIT);
3470
3471
if (error || sc->status_block_paddr == 0) {
3472
BCE_PRINTF("%s(%d): Could not map status block "
3473
"DMA memory!\n", __FILE__, __LINE__);
3474
rc = ENOMEM;
3475
goto bce_dma_alloc_exit;
3476
}
3477
3478
DBPRINT(sc, BCE_INFO_LOAD, "%s(): status_block_paddr = 0x%jX\n",
3479
__FUNCTION__, (uintmax_t) sc->status_block_paddr);
3480
3481
/*
3482
* Create a DMA tag for the statistics block, allocate and clear the
3483
* memory, map the memory into DMA space, and fetch the physical
3484
* address of the block.
3485
*/
3486
if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3487
BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3488
NULL, NULL, BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
3489
0, NULL, NULL, &sc->stats_tag)) {
3490
BCE_PRINTF("%s(%d): Could not allocate statistics block "
3491
"DMA tag!\n", __FILE__, __LINE__);
3492
rc = ENOMEM;
3493
goto bce_dma_alloc_exit;
3494
}
3495
3496
if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
3497
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sc->stats_map)) {
3498
BCE_PRINTF("%s(%d): Could not allocate statistics block "
3499
"DMA memory!\n", __FILE__, __LINE__);
3500
rc = ENOMEM;
3501
goto bce_dma_alloc_exit;
3502
}
3503
3504
error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
3505
sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
3506
&sc->stats_block_paddr, BUS_DMA_NOWAIT);
3507
3508
if (error || sc->stats_block_paddr == 0) {
3509
BCE_PRINTF("%s(%d): Could not map statistics block "
3510
"DMA memory!\n", __FILE__, __LINE__);
3511
rc = ENOMEM;
3512
goto bce_dma_alloc_exit;
3513
}
3514
3515
DBPRINT(sc, BCE_INFO_LOAD, "%s(): stats_block_paddr = 0x%jX\n",
3516
__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3517
3518
/* BCM5709 uses host memory as cache for context memory. */
3519
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3520
sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3521
if (sc->ctx_pages == 0)
3522
sc->ctx_pages = 1;
3523
3524
DBRUNIF((sc->ctx_pages > 512),
3525
BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3526
__FILE__, __LINE__, sc->ctx_pages));
3527
3528
/*
3529
* Create a DMA tag for the context pages,
3530
* allocate and clear the memory, map the
3531
* memory into DMA space, and fetch the
3532
* physical address of the block.
3533
*/
3534
if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3535
BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3536
NULL, NULL, BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
3537
0, NULL, NULL, &sc->ctx_tag)) {
3538
BCE_PRINTF("%s(%d): Could not allocate CTX "
3539
"DMA tag!\n", __FILE__, __LINE__);
3540
rc = ENOMEM;
3541
goto bce_dma_alloc_exit;
3542
}
3543
3544
for (i = 0; i < sc->ctx_pages; i++) {
3545
if(bus_dmamem_alloc(sc->ctx_tag,
3546
(void **)&sc->ctx_block[i],
3547
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3548
&sc->ctx_map[i])) {
3549
BCE_PRINTF("%s(%d): Could not allocate CTX "
3550
"DMA memory!\n", __FILE__, __LINE__);
3551
rc = ENOMEM;
3552
goto bce_dma_alloc_exit;
3553
}
3554
3555
error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
3556
sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
3557
&sc->ctx_paddr[i], BUS_DMA_NOWAIT);
3558
3559
if (error || sc->ctx_paddr[i] == 0) {
3560
BCE_PRINTF("%s(%d): Could not map CTX "
3561
"DMA memory!\n", __FILE__, __LINE__);
3562
rc = ENOMEM;
3563
goto bce_dma_alloc_exit;
3564
}
3565
3566
DBPRINT(sc, BCE_INFO_LOAD, "%s(): ctx_paddr[%d] "
3567
"= 0x%jX\n", __FUNCTION__, i,
3568
(uintmax_t) sc->ctx_paddr[i]);
3569
}
3570
}
3571
3572
/*
3573
* Create a DMA tag for the TX buffer descriptor chain,
3574
* allocate and clear the memory, and fetch the
3575
* physical address of the block.
3576
*/
3577
if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
3578
sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3579
BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
3580
NULL, NULL, &sc->tx_bd_chain_tag)) {
3581
BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3582
"chain DMA tag!\n", __FILE__, __LINE__);
3583
rc = ENOMEM;
3584
goto bce_dma_alloc_exit;
3585
}
3586
3587
for (i = 0; i < sc->tx_pages; i++) {
3588
if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3589
(void **)&sc->tx_bd_chain[i],
3590
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3591
&sc->tx_bd_chain_map[i])) {
3592
BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3593
"chain DMA memory!\n", __FILE__, __LINE__);
3594
rc = ENOMEM;
3595
goto bce_dma_alloc_exit;
3596
}
3597
3598
error = bus_dmamap_load(sc->tx_bd_chain_tag,
3599
sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
3600
BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3601
&sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3602
3603
if (error || sc->tx_bd_chain_paddr[i] == 0) {
3604
BCE_PRINTF("%s(%d): Could not map TX descriptor "
3605
"chain DMA memory!\n", __FILE__, __LINE__);
3606
rc = ENOMEM;
3607
goto bce_dma_alloc_exit;
3608
}
3609
3610
DBPRINT(sc, BCE_INFO_LOAD, "%s(): tx_bd_chain_paddr[%d] = "
3611
"0x%jX\n", __FUNCTION__, i,
3612
(uintmax_t) sc->tx_bd_chain_paddr[i]);
3613
}
3614
3615
/* Check the required size before mapping to conserve resources. */
3616
if (bce_tso_enable) {
3617
max_size = BCE_TSO_MAX_SIZE;
3618
max_segments = BCE_MAX_SEGMENTS;
3619
max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3620
} else {
3621
max_size = MCLBYTES * BCE_MAX_SEGMENTS;
3622
max_segments = BCE_MAX_SEGMENTS;
3623
max_seg_size = MCLBYTES;
3624
}
3625
3626
/* Create a DMA tag for TX mbufs. */
3627
if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3628
sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3629
max_segments, max_seg_size, 0, NULL, NULL, &sc->tx_mbuf_tag)) {
3630
BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3631
__FILE__, __LINE__);
3632
rc = ENOMEM;
3633
goto bce_dma_alloc_exit;
3634
}
3635
3636
/* Create DMA maps for the TX mbufs clusters. */
3637
for (i = 0; i < TOTAL_TX_BD_ALLOC; i++) {
3638
if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3639
&sc->tx_mbuf_map[i])) {
3640
BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
3641
"map!\n", __FILE__, __LINE__);
3642
rc = ENOMEM;
3643
goto bce_dma_alloc_exit;
3644
}
3645
}
3646
3647
/*
3648
* Create a DMA tag for the RX buffer descriptor chain,
3649
* allocate and clear the memory, and fetch the physical
3650
* address of the blocks.
3651
*/
3652
if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3653
BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
3654
sc->max_bus_addr, NULL, NULL,
3655
BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
3656
0, NULL, NULL, &sc->rx_bd_chain_tag)) {
3657
BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3658
"DMA tag!\n", __FILE__, __LINE__);
3659
rc = ENOMEM;
3660
goto bce_dma_alloc_exit;
3661
}
3662
3663
for (i = 0; i < sc->rx_pages; i++) {
3664
if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3665
(void **)&sc->rx_bd_chain[i],
3666
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3667
&sc->rx_bd_chain_map[i])) {
3668
BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
3669
"chain DMA memory!\n", __FILE__, __LINE__);
3670
rc = ENOMEM;
3671
goto bce_dma_alloc_exit;
3672
}
3673
3674
error = bus_dmamap_load(sc->rx_bd_chain_tag,
3675
sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
3676
BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3677
&sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3678
3679
if (error || sc->rx_bd_chain_paddr[i] == 0) {
3680
BCE_PRINTF("%s(%d): Could not map RX descriptor "
3681
"chain DMA memory!\n", __FILE__, __LINE__);
3682
rc = ENOMEM;
3683
goto bce_dma_alloc_exit;
3684
}
3685
3686
DBPRINT(sc, BCE_INFO_LOAD, "%s(): rx_bd_chain_paddr[%d] = "
3687
"0x%jX\n", __FUNCTION__, i,
3688
(uintmax_t) sc->rx_bd_chain_paddr[i]);
3689
}
3690
3691
/*
3692
* Create a DMA tag for RX mbufs.
3693
*/
3694
if (bce_hdr_split == TRUE)
3695
max_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3696
MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3697
else
3698
max_size = MJUM9BYTES;
3699
3700
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
3701
"(max size = 0x%jX)\n", __FUNCTION__, (uintmax_t)max_size);
3702
3703
if (bus_dma_tag_create(sc->parent_tag, BCE_RX_BUF_ALIGN,
3704
BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3705
max_size, 1, max_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
3706
BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3707
__FILE__, __LINE__);
3708
rc = ENOMEM;
3709
goto bce_dma_alloc_exit;
3710
}
3711
3712
/* Create DMA maps for the RX mbuf clusters. */
3713
for (i = 0; i < TOTAL_RX_BD_ALLOC; i++) {
3714
if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3715
&sc->rx_mbuf_map[i])) {
3716
BCE_PRINTF("%s(%d): Unable to create RX mbuf "
3717
"DMA map!\n", __FILE__, __LINE__);
3718
rc = ENOMEM;
3719
goto bce_dma_alloc_exit;
3720
}
3721
}
3722
3723
if (bce_hdr_split == TRUE) {
3724
/*
3725
* Create a DMA tag for the page buffer descriptor chain,
3726
* allocate and clear the memory, and fetch the physical
3727
* address of the blocks.
3728
*/
3729
if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3730
BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
3731
NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
3732
0, NULL, NULL, &sc->pg_bd_chain_tag)) {
3733
BCE_PRINTF("%s(%d): Could not allocate page descriptor "
3734
"chain DMA tag!\n", __FILE__, __LINE__);
3735
rc = ENOMEM;
3736
goto bce_dma_alloc_exit;
3737
}
3738
3739
for (i = 0; i < sc->pg_pages; i++) {
3740
if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3741
(void **)&sc->pg_bd_chain[i],
3742
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3743
&sc->pg_bd_chain_map[i])) {
3744
BCE_PRINTF("%s(%d): Could not allocate page "
3745
"descriptor chain DMA memory!\n",
3746
__FILE__, __LINE__);
3747
rc = ENOMEM;
3748
goto bce_dma_alloc_exit;
3749
}
3750
3751
error = bus_dmamap_load(sc->pg_bd_chain_tag,
3752
sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
3753
BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
3754
&sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3755
3756
if (error || sc->pg_bd_chain_paddr[i] == 0) {
3757
BCE_PRINTF("%s(%d): Could not map page descriptor "
3758
"chain DMA memory!\n", __FILE__, __LINE__);
3759
rc = ENOMEM;
3760
goto bce_dma_alloc_exit;
3761
}
3762
3763
DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
3764
"0x%jX\n", __FUNCTION__, i,
3765
(uintmax_t) sc->pg_bd_chain_paddr[i]);
3766
}
3767
3768
/*
3769
* Create a DMA tag for page mbufs.
3770
*/
3771
if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3772
sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
3773
1, MCLBYTES, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
3774
BCE_PRINTF("%s(%d): Could not allocate page mbuf "
3775
"DMA tag!\n", __FILE__, __LINE__);
3776
rc = ENOMEM;
3777
goto bce_dma_alloc_exit;
3778
}
3779
3780
/* Create DMA maps for the page mbuf clusters. */
3781
for (i = 0; i < TOTAL_PG_BD_ALLOC; i++) {
3782
if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3783
&sc->pg_mbuf_map[i])) {
3784
BCE_PRINTF("%s(%d): Unable to create page mbuf "
3785
"DMA map!\n", __FILE__, __LINE__);
3786
rc = ENOMEM;
3787
goto bce_dma_alloc_exit;
3788
}
3789
}
3790
}
3791
3792
bce_dma_alloc_exit:
3793
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3794
return(rc);
3795
}
3796
3797
/****************************************************************************/
3798
/* Release all resources used by the driver. */
3799
/* */
3800
/* Releases all resources acquired by the driver including interrupts, */
3801
/* interrupt handler, interfaces, mutexes, and DMA memory. */
3802
/* */
3803
/* Returns: */
3804
/* Nothing. */
3805
/****************************************************************************/
3806
static void
3807
bce_release_resources(struct bce_softc *sc)
3808
{
3809
device_t dev;
3810
3811
DBENTER(BCE_VERBOSE_RESET);
3812
3813
dev = sc->bce_dev;
3814
3815
bce_dma_free(sc);
3816
3817
if (sc->bce_intrhand != NULL) {
3818
DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3819
bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3820
}
3821
3822
if (sc->bce_res_irq != NULL) {
3823
DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3824
bus_release_resource(dev, SYS_RES_IRQ,
3825
rman_get_rid(sc->bce_res_irq), sc->bce_res_irq);
3826
}
3827
3828
if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3829
DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3830
pci_release_msi(dev);
3831
}
3832
3833
if (sc->bce_res_mem != NULL) {
3834
DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3835
bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
3836
sc->bce_res_mem);
3837
}
3838
3839
if (sc->bce_ifp != NULL) {
3840
DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3841
if_free(sc->bce_ifp);
3842
}
3843
3844
if (mtx_initialized(&sc->bce_mtx))
3845
BCE_LOCK_DESTROY(sc);
3846
3847
DBEXIT(BCE_VERBOSE_RESET);
3848
}
3849
3850
/****************************************************************************/
3851
/* Firmware synchronization. */
3852
/* */
3853
/* Before performing certain events such as a chip reset, synchronize with */
3854
/* the firmware first. */
3855
/* */
3856
/* Returns: */
3857
/* 0 for success, positive value for failure. */
3858
/****************************************************************************/
3859
static int
3860
bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3861
{
3862
int i, rc = 0;
3863
u32 val;
3864
3865
DBENTER(BCE_VERBOSE_RESET);
3866
3867
/* Don't waste any time if we've timed out before. */
3868
if (sc->bce_fw_timed_out == TRUE) {
3869
rc = EBUSY;
3870
goto bce_fw_sync_exit;
3871
}
3872
3873
/* Increment the message sequence number. */
3874
sc->bce_fw_wr_seq++;
3875
msg_data |= sc->bce_fw_wr_seq;
3876
3877
DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
3878
"0x%08X\n", msg_data);
3879
3880
/* Send the message to the bootcode driver mailbox. */
3881
bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3882
3883
/* Wait for the bootcode to acknowledge the message. */
3884
for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3885
/* Check for a response in the bootcode firmware mailbox. */
3886
val = bce_shmem_rd(sc, BCE_FW_MB);
3887
if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3888
break;
3889
DELAY(1000);
3890
}
3891
3892
/* If we've timed out, tell bootcode that we've stopped waiting. */
3893
if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3894
((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3895
BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3896
"msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
3897
3898
msg_data &= ~BCE_DRV_MSG_CODE;
3899
msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3900
3901
bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3902
3903
sc->bce_fw_timed_out = TRUE;
3904
rc = EBUSY;
3905
}
3906
3907
bce_fw_sync_exit:
3908
DBEXIT(BCE_VERBOSE_RESET);
3909
return (rc);
3910
}
3911
3912
/****************************************************************************/
3913
/* Load Receive Virtual 2 Physical (RV2P) processor firmware. */
3914
/* */
3915
/* Returns: */
3916
/* Nothing. */
3917
/****************************************************************************/
3918
static void
3919
bce_load_rv2p_fw(struct bce_softc *sc, const u32 *rv2p_code,
3920
u32 rv2p_code_len, u32 rv2p_proc)
3921
{
3922
int i;
3923
u32 val;
3924
3925
DBENTER(BCE_VERBOSE_RESET);
3926
3927
/* Set the page size used by RV2P. */
3928
if (rv2p_proc == RV2P_PROC2) {
3929
BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3930
}
3931
3932
for (i = 0; i < rv2p_code_len; i += 8) {
3933
REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3934
rv2p_code++;
3935
REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3936
rv2p_code++;
3937
3938
if (rv2p_proc == RV2P_PROC1) {
3939
val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3940
REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3941
}
3942
else {
3943
val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3944
REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3945
}
3946
}
3947
3948
/* Reset the processor, un-stall is done later. */
3949
if (rv2p_proc == RV2P_PROC1) {
3950
REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3951
}
3952
else {
3953
REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3954
}
3955
3956
DBEXIT(BCE_VERBOSE_RESET);
3957
}
3958
3959
/****************************************************************************/
3960
/* Load RISC processor firmware. */
3961
/* */
3962
/* Loads firmware from the file if_bcefw.h into the scratchpad memory */
3963
/* associated with a particular processor. */
3964
/* */
3965
/* Returns: */
3966
/* Nothing. */
3967
/****************************************************************************/
3968
static void
3969
bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3970
struct fw_info *fw)
3971
{
3972
u32 offset;
3973
3974
DBENTER(BCE_VERBOSE_RESET);
3975
3976
bce_halt_cpu(sc, cpu_reg);
3977
3978
/* Load the Text area. */
3979
offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3980
if (fw->text) {
3981
int j;
3982
3983
for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3984
REG_WR_IND(sc, offset, fw->text[j]);
3985
}
3986
}
3987
3988
/* Load the Data area. */
3989
offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3990
if (fw->data) {
3991
int j;
3992
3993
for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3994
REG_WR_IND(sc, offset, fw->data[j]);
3995
}
3996
}
3997
3998
/* Load the SBSS area. */
3999
offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
4000
if (fw->sbss) {
4001
int j;
4002
4003
for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
4004
REG_WR_IND(sc, offset, fw->sbss[j]);
4005
}
4006
}
4007
4008
/* Load the BSS area. */
4009
offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
4010
if (fw->bss) {
4011
int j;
4012
4013
for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
4014
REG_WR_IND(sc, offset, fw->bss[j]);
4015
}
4016
}
4017
4018
/* Load the Read-Only area. */
4019
offset = cpu_reg->spad_base +
4020
(fw->rodata_addr - cpu_reg->mips_view_base);
4021
if (fw->rodata) {
4022
int j;
4023
4024
for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
4025
REG_WR_IND(sc, offset, fw->rodata[j]);
4026
}
4027
}
4028
4029
/* Clear the pre-fetch instruction and set the FW start address. */
4030
REG_WR_IND(sc, cpu_reg->inst, 0);
4031
REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
4032
4033
DBEXIT(BCE_VERBOSE_RESET);
4034
}
4035
4036
/****************************************************************************/
4037
/* Starts the RISC processor. */
4038
/* */
4039
/* Assumes the CPU starting address has already been set. */
4040
/* */
4041
/* Returns: */
4042
/* Nothing. */
4043
/****************************************************************************/
4044
static void
4045
bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4046
{
4047
u32 val;
4048
4049
DBENTER(BCE_VERBOSE_RESET);
4050
4051
/* Start the CPU. */
4052
val = REG_RD_IND(sc, cpu_reg->mode);
4053
val &= ~cpu_reg->mode_value_halt;
4054
REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4055
REG_WR_IND(sc, cpu_reg->mode, val);
4056
4057
DBEXIT(BCE_VERBOSE_RESET);
4058
}
4059
4060
/****************************************************************************/
4061
/* Halts the RISC processor. */
4062
/* */
4063
/* Returns: */
4064
/* Nothing. */
4065
/****************************************************************************/
4066
static void
4067
bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4068
{
4069
u32 val;
4070
4071
DBENTER(BCE_VERBOSE_RESET);
4072
4073
/* Halt the CPU. */
4074
val = REG_RD_IND(sc, cpu_reg->mode);
4075
val |= cpu_reg->mode_value_halt;
4076
REG_WR_IND(sc, cpu_reg->mode, val);
4077
REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4078
4079
DBEXIT(BCE_VERBOSE_RESET);
4080
}
4081
4082
/****************************************************************************/
4083
/* Initialize the RX CPU. */
4084
/* */
4085
/* Returns: */
4086
/* Nothing. */
4087
/****************************************************************************/
4088
static void
4089
bce_start_rxp_cpu(struct bce_softc *sc)
4090
{
4091
struct cpu_reg cpu_reg;
4092
4093
DBENTER(BCE_VERBOSE_RESET);
4094
4095
cpu_reg.mode = BCE_RXP_CPU_MODE;
4096
cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4097
cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4098
cpu_reg.state = BCE_RXP_CPU_STATE;
4099
cpu_reg.state_value_clear = 0xffffff;
4100
cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4101
cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4102
cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4103
cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4104
cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4105
cpu_reg.spad_base = BCE_RXP_SCRATCH;
4106
cpu_reg.mips_view_base = 0x8000000;
4107
4108
DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
4109
bce_start_cpu(sc, &cpu_reg);
4110
4111
DBEXIT(BCE_VERBOSE_RESET);
4112
}
4113
4114
/****************************************************************************/
4115
/* Initialize the RX CPU. */
4116
/* */
4117
/* Returns: */
4118
/* Nothing. */
4119
/****************************************************************************/
4120
static void
4121
bce_init_rxp_cpu(struct bce_softc *sc)
4122
{
4123
struct cpu_reg cpu_reg;
4124
struct fw_info fw;
4125
4126
DBENTER(BCE_VERBOSE_RESET);
4127
4128
cpu_reg.mode = BCE_RXP_CPU_MODE;
4129
cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4130
cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4131
cpu_reg.state = BCE_RXP_CPU_STATE;
4132
cpu_reg.state_value_clear = 0xffffff;
4133
cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4134
cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4135
cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4136
cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4137
cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4138
cpu_reg.spad_base = BCE_RXP_SCRATCH;
4139
cpu_reg.mips_view_base = 0x8000000;
4140
4141
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4142
fw.ver_major = bce_RXP_b09FwReleaseMajor;
4143
fw.ver_minor = bce_RXP_b09FwReleaseMinor;
4144
fw.ver_fix = bce_RXP_b09FwReleaseFix;
4145
fw.start_addr = bce_RXP_b09FwStartAddr;
4146
4147
fw.text_addr = bce_RXP_b09FwTextAddr;
4148
fw.text_len = bce_RXP_b09FwTextLen;
4149
fw.text_index = 0;
4150
fw.text = bce_RXP_b09FwText;
4151
4152
fw.data_addr = bce_RXP_b09FwDataAddr;
4153
fw.data_len = bce_RXP_b09FwDataLen;
4154
fw.data_index = 0;
4155
fw.data = bce_RXP_b09FwData;
4156
4157
fw.sbss_addr = bce_RXP_b09FwSbssAddr;
4158
fw.sbss_len = bce_RXP_b09FwSbssLen;
4159
fw.sbss_index = 0;
4160
fw.sbss = bce_RXP_b09FwSbss;
4161
4162
fw.bss_addr = bce_RXP_b09FwBssAddr;
4163
fw.bss_len = bce_RXP_b09FwBssLen;
4164
fw.bss_index = 0;
4165
fw.bss = bce_RXP_b09FwBss;
4166
4167
fw.rodata_addr = bce_RXP_b09FwRodataAddr;
4168
fw.rodata_len = bce_RXP_b09FwRodataLen;
4169
fw.rodata_index = 0;
4170
fw.rodata = bce_RXP_b09FwRodata;
4171
} else {
4172
fw.ver_major = bce_RXP_b06FwReleaseMajor;
4173
fw.ver_minor = bce_RXP_b06FwReleaseMinor;
4174
fw.ver_fix = bce_RXP_b06FwReleaseFix;
4175
fw.start_addr = bce_RXP_b06FwStartAddr;
4176
4177
fw.text_addr = bce_RXP_b06FwTextAddr;
4178
fw.text_len = bce_RXP_b06FwTextLen;
4179
fw.text_index = 0;
4180
fw.text = bce_RXP_b06FwText;
4181
4182
fw.data_addr = bce_RXP_b06FwDataAddr;
4183
fw.data_len = bce_RXP_b06FwDataLen;
4184
fw.data_index = 0;
4185
fw.data = bce_RXP_b06FwData;
4186
4187
fw.sbss_addr = bce_RXP_b06FwSbssAddr;
4188
fw.sbss_len = bce_RXP_b06FwSbssLen;
4189
fw.sbss_index = 0;
4190
fw.sbss = bce_RXP_b06FwSbss;
4191
4192
fw.bss_addr = bce_RXP_b06FwBssAddr;
4193
fw.bss_len = bce_RXP_b06FwBssLen;
4194
fw.bss_index = 0;
4195
fw.bss = bce_RXP_b06FwBss;
4196
4197
fw.rodata_addr = bce_RXP_b06FwRodataAddr;
4198
fw.rodata_len = bce_RXP_b06FwRodataLen;
4199
fw.rodata_index = 0;
4200
fw.rodata = bce_RXP_b06FwRodata;
4201
}
4202
4203
DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
4204
bce_load_cpu_fw(sc, &cpu_reg, &fw);
4205
4206
/* Delay RXP start until initialization is complete. */
4207
4208
DBEXIT(BCE_VERBOSE_RESET);
4209
}
4210
4211
/****************************************************************************/
4212
/* Initialize the TX CPU. */
4213
/* */
4214
/* Returns: */
4215
/* Nothing. */
4216
/****************************************************************************/
4217
static void
4218
bce_init_txp_cpu(struct bce_softc *sc)
4219
{
4220
struct cpu_reg cpu_reg;
4221
struct fw_info fw;
4222
4223
DBENTER(BCE_VERBOSE_RESET);
4224
4225
cpu_reg.mode = BCE_TXP_CPU_MODE;
4226
cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
4227
cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
4228
cpu_reg.state = BCE_TXP_CPU_STATE;
4229
cpu_reg.state_value_clear = 0xffffff;
4230
cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
4231
cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
4232
cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
4233
cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
4234
cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
4235
cpu_reg.spad_base = BCE_TXP_SCRATCH;
4236
cpu_reg.mips_view_base = 0x8000000;
4237
4238
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4239
fw.ver_major = bce_TXP_b09FwReleaseMajor;
4240
fw.ver_minor = bce_TXP_b09FwReleaseMinor;
4241
fw.ver_fix = bce_TXP_b09FwReleaseFix;
4242
fw.start_addr = bce_TXP_b09FwStartAddr;
4243
4244
fw.text_addr = bce_TXP_b09FwTextAddr;
4245
fw.text_len = bce_TXP_b09FwTextLen;
4246
fw.text_index = 0;
4247
fw.text = bce_TXP_b09FwText;
4248
4249
fw.data_addr = bce_TXP_b09FwDataAddr;
4250
fw.data_len = bce_TXP_b09FwDataLen;
4251
fw.data_index = 0;
4252
fw.data = bce_TXP_b09FwData;
4253
4254
fw.sbss_addr = bce_TXP_b09FwSbssAddr;
4255
fw.sbss_len = bce_TXP_b09FwSbssLen;
4256
fw.sbss_index = 0;
4257
fw.sbss = bce_TXP_b09FwSbss;
4258
4259
fw.bss_addr = bce_TXP_b09FwBssAddr;
4260
fw.bss_len = bce_TXP_b09FwBssLen;
4261
fw.bss_index = 0;
4262
fw.bss = bce_TXP_b09FwBss;
4263
4264
fw.rodata_addr = bce_TXP_b09FwRodataAddr;
4265
fw.rodata_len = bce_TXP_b09FwRodataLen;
4266
fw.rodata_index = 0;
4267
fw.rodata = bce_TXP_b09FwRodata;
4268
} else {
4269
fw.ver_major = bce_TXP_b06FwReleaseMajor;
4270
fw.ver_minor = bce_TXP_b06FwReleaseMinor;
4271
fw.ver_fix = bce_TXP_b06FwReleaseFix;
4272
fw.start_addr = bce_TXP_b06FwStartAddr;
4273
4274
fw.text_addr = bce_TXP_b06FwTextAddr;
4275
fw.text_len = bce_TXP_b06FwTextLen;
4276
fw.text_index = 0;
4277
fw.text = bce_TXP_b06FwText;
4278
4279
fw.data_addr = bce_TXP_b06FwDataAddr;
4280
fw.data_len = bce_TXP_b06FwDataLen;
4281
fw.data_index = 0;
4282
fw.data = bce_TXP_b06FwData;
4283
4284
fw.sbss_addr = bce_TXP_b06FwSbssAddr;
4285
fw.sbss_len = bce_TXP_b06FwSbssLen;
4286
fw.sbss_index = 0;
4287
fw.sbss = bce_TXP_b06FwSbss;
4288
4289
fw.bss_addr = bce_TXP_b06FwBssAddr;
4290
fw.bss_len = bce_TXP_b06FwBssLen;
4291
fw.bss_index = 0;
4292
fw.bss = bce_TXP_b06FwBss;
4293
4294
fw.rodata_addr = bce_TXP_b06FwRodataAddr;
4295
fw.rodata_len = bce_TXP_b06FwRodataLen;
4296
fw.rodata_index = 0;
4297
fw.rodata = bce_TXP_b06FwRodata;
4298
}
4299
4300
DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4301
bce_load_cpu_fw(sc, &cpu_reg, &fw);
4302
bce_start_cpu(sc, &cpu_reg);
4303
4304
DBEXIT(BCE_VERBOSE_RESET);
4305
}
4306
4307
/****************************************************************************/
4308
/* Initialize the TPAT CPU. */
4309
/* */
4310
/* Returns: */
4311
/* Nothing. */
4312
/****************************************************************************/
4313
static void
4314
bce_init_tpat_cpu(struct bce_softc *sc)
4315
{
4316
struct cpu_reg cpu_reg;
4317
struct fw_info fw;
4318
4319
DBENTER(BCE_VERBOSE_RESET);
4320
4321
cpu_reg.mode = BCE_TPAT_CPU_MODE;
4322
cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4323
cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4324
cpu_reg.state = BCE_TPAT_CPU_STATE;
4325
cpu_reg.state_value_clear = 0xffffff;
4326
cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4327
cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4328
cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4329
cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4330
cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4331
cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4332
cpu_reg.mips_view_base = 0x8000000;
4333
4334
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4335
fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4336
fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4337
fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4338
fw.start_addr = bce_TPAT_b09FwStartAddr;
4339
4340
fw.text_addr = bce_TPAT_b09FwTextAddr;
4341
fw.text_len = bce_TPAT_b09FwTextLen;
4342
fw.text_index = 0;
4343
fw.text = bce_TPAT_b09FwText;
4344
4345
fw.data_addr = bce_TPAT_b09FwDataAddr;
4346
fw.data_len = bce_TPAT_b09FwDataLen;
4347
fw.data_index = 0;
4348
fw.data = bce_TPAT_b09FwData;
4349
4350
fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4351
fw.sbss_len = bce_TPAT_b09FwSbssLen;
4352
fw.sbss_index = 0;
4353
fw.sbss = bce_TPAT_b09FwSbss;
4354
4355
fw.bss_addr = bce_TPAT_b09FwBssAddr;
4356
fw.bss_len = bce_TPAT_b09FwBssLen;
4357
fw.bss_index = 0;
4358
fw.bss = bce_TPAT_b09FwBss;
4359
4360
fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4361
fw.rodata_len = bce_TPAT_b09FwRodataLen;
4362
fw.rodata_index = 0;
4363
fw.rodata = bce_TPAT_b09FwRodata;
4364
} else {
4365
fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4366
fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4367
fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4368
fw.start_addr = bce_TPAT_b06FwStartAddr;
4369
4370
fw.text_addr = bce_TPAT_b06FwTextAddr;
4371
fw.text_len = bce_TPAT_b06FwTextLen;
4372
fw.text_index = 0;
4373
fw.text = bce_TPAT_b06FwText;
4374
4375
fw.data_addr = bce_TPAT_b06FwDataAddr;
4376
fw.data_len = bce_TPAT_b06FwDataLen;
4377
fw.data_index = 0;
4378
fw.data = bce_TPAT_b06FwData;
4379
4380
fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4381
fw.sbss_len = bce_TPAT_b06FwSbssLen;
4382
fw.sbss_index = 0;
4383
fw.sbss = bce_TPAT_b06FwSbss;
4384
4385
fw.bss_addr = bce_TPAT_b06FwBssAddr;
4386
fw.bss_len = bce_TPAT_b06FwBssLen;
4387
fw.bss_index = 0;
4388
fw.bss = bce_TPAT_b06FwBss;
4389
4390
fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4391
fw.rodata_len = bce_TPAT_b06FwRodataLen;
4392
fw.rodata_index = 0;
4393
fw.rodata = bce_TPAT_b06FwRodata;
4394
}
4395
4396
DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4397
bce_load_cpu_fw(sc, &cpu_reg, &fw);
4398
bce_start_cpu(sc, &cpu_reg);
4399
4400
DBEXIT(BCE_VERBOSE_RESET);
4401
}
4402
4403
/****************************************************************************/
4404
/* Initialize the CP CPU. */
4405
/* */
4406
/* Returns: */
4407
/* Nothing. */
4408
/****************************************************************************/
4409
static void
4410
bce_init_cp_cpu(struct bce_softc *sc)
4411
{
4412
struct cpu_reg cpu_reg;
4413
struct fw_info fw;
4414
4415
DBENTER(BCE_VERBOSE_RESET);
4416
4417
cpu_reg.mode = BCE_CP_CPU_MODE;
4418
cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4419
cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4420
cpu_reg.state = BCE_CP_CPU_STATE;
4421
cpu_reg.state_value_clear = 0xffffff;
4422
cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4423
cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4424
cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4425
cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4426
cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4427
cpu_reg.spad_base = BCE_CP_SCRATCH;
4428
cpu_reg.mips_view_base = 0x8000000;
4429
4430
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4431
fw.ver_major = bce_CP_b09FwReleaseMajor;
4432
fw.ver_minor = bce_CP_b09FwReleaseMinor;
4433
fw.ver_fix = bce_CP_b09FwReleaseFix;
4434
fw.start_addr = bce_CP_b09FwStartAddr;
4435
4436
fw.text_addr = bce_CP_b09FwTextAddr;
4437
fw.text_len = bce_CP_b09FwTextLen;
4438
fw.text_index = 0;
4439
fw.text = bce_CP_b09FwText;
4440
4441
fw.data_addr = bce_CP_b09FwDataAddr;
4442
fw.data_len = bce_CP_b09FwDataLen;
4443
fw.data_index = 0;
4444
fw.data = bce_CP_b09FwData;
4445
4446
fw.sbss_addr = bce_CP_b09FwSbssAddr;
4447
fw.sbss_len = bce_CP_b09FwSbssLen;
4448
fw.sbss_index = 0;
4449
fw.sbss = bce_CP_b09FwSbss;
4450
4451
fw.bss_addr = bce_CP_b09FwBssAddr;
4452
fw.bss_len = bce_CP_b09FwBssLen;
4453
fw.bss_index = 0;
4454
fw.bss = bce_CP_b09FwBss;
4455
4456
fw.rodata_addr = bce_CP_b09FwRodataAddr;
4457
fw.rodata_len = bce_CP_b09FwRodataLen;
4458
fw.rodata_index = 0;
4459
fw.rodata = bce_CP_b09FwRodata;
4460
} else {
4461
fw.ver_major = bce_CP_b06FwReleaseMajor;
4462
fw.ver_minor = bce_CP_b06FwReleaseMinor;
4463
fw.ver_fix = bce_CP_b06FwReleaseFix;
4464
fw.start_addr = bce_CP_b06FwStartAddr;
4465
4466
fw.text_addr = bce_CP_b06FwTextAddr;
4467
fw.text_len = bce_CP_b06FwTextLen;
4468
fw.text_index = 0;
4469
fw.text = bce_CP_b06FwText;
4470
4471
fw.data_addr = bce_CP_b06FwDataAddr;
4472
fw.data_len = bce_CP_b06FwDataLen;
4473
fw.data_index = 0;
4474
fw.data = bce_CP_b06FwData;
4475
4476
fw.sbss_addr = bce_CP_b06FwSbssAddr;
4477
fw.sbss_len = bce_CP_b06FwSbssLen;
4478
fw.sbss_index = 0;
4479
fw.sbss = bce_CP_b06FwSbss;
4480
4481
fw.bss_addr = bce_CP_b06FwBssAddr;
4482
fw.bss_len = bce_CP_b06FwBssLen;
4483
fw.bss_index = 0;
4484
fw.bss = bce_CP_b06FwBss;
4485
4486
fw.rodata_addr = bce_CP_b06FwRodataAddr;
4487
fw.rodata_len = bce_CP_b06FwRodataLen;
4488
fw.rodata_index = 0;
4489
fw.rodata = bce_CP_b06FwRodata;
4490
}
4491
4492
DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4493
bce_load_cpu_fw(sc, &cpu_reg, &fw);
4494
bce_start_cpu(sc, &cpu_reg);
4495
4496
DBEXIT(BCE_VERBOSE_RESET);
4497
}
4498
4499
/****************************************************************************/
4500
/* Initialize the COM CPU. */
4501
/* */
4502
/* Returns: */
4503
/* Nothing. */
4504
/****************************************************************************/
4505
static void
4506
bce_init_com_cpu(struct bce_softc *sc)
4507
{
4508
struct cpu_reg cpu_reg;
4509
struct fw_info fw;
4510
4511
DBENTER(BCE_VERBOSE_RESET);
4512
4513
cpu_reg.mode = BCE_COM_CPU_MODE;
4514
cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4515
cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4516
cpu_reg.state = BCE_COM_CPU_STATE;
4517
cpu_reg.state_value_clear = 0xffffff;
4518
cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4519
cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4520
cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4521
cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4522
cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4523
cpu_reg.spad_base = BCE_COM_SCRATCH;
4524
cpu_reg.mips_view_base = 0x8000000;
4525
4526
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4527
fw.ver_major = bce_COM_b09FwReleaseMajor;
4528
fw.ver_minor = bce_COM_b09FwReleaseMinor;
4529
fw.ver_fix = bce_COM_b09FwReleaseFix;
4530
fw.start_addr = bce_COM_b09FwStartAddr;
4531
4532
fw.text_addr = bce_COM_b09FwTextAddr;
4533
fw.text_len = bce_COM_b09FwTextLen;
4534
fw.text_index = 0;
4535
fw.text = bce_COM_b09FwText;
4536
4537
fw.data_addr = bce_COM_b09FwDataAddr;
4538
fw.data_len = bce_COM_b09FwDataLen;
4539
fw.data_index = 0;
4540
fw.data = bce_COM_b09FwData;
4541
4542
fw.sbss_addr = bce_COM_b09FwSbssAddr;
4543
fw.sbss_len = bce_COM_b09FwSbssLen;
4544
fw.sbss_index = 0;
4545
fw.sbss = bce_COM_b09FwSbss;
4546
4547
fw.bss_addr = bce_COM_b09FwBssAddr;
4548
fw.bss_len = bce_COM_b09FwBssLen;
4549
fw.bss_index = 0;
4550
fw.bss = bce_COM_b09FwBss;
4551
4552
fw.rodata_addr = bce_COM_b09FwRodataAddr;
4553
fw.rodata_len = bce_COM_b09FwRodataLen;
4554
fw.rodata_index = 0;
4555
fw.rodata = bce_COM_b09FwRodata;
4556
} else {
4557
fw.ver_major = bce_COM_b06FwReleaseMajor;
4558
fw.ver_minor = bce_COM_b06FwReleaseMinor;
4559
fw.ver_fix = bce_COM_b06FwReleaseFix;
4560
fw.start_addr = bce_COM_b06FwStartAddr;
4561
4562
fw.text_addr = bce_COM_b06FwTextAddr;
4563
fw.text_len = bce_COM_b06FwTextLen;
4564
fw.text_index = 0;
4565
fw.text = bce_COM_b06FwText;
4566
4567
fw.data_addr = bce_COM_b06FwDataAddr;
4568
fw.data_len = bce_COM_b06FwDataLen;
4569
fw.data_index = 0;
4570
fw.data = bce_COM_b06FwData;
4571
4572
fw.sbss_addr = bce_COM_b06FwSbssAddr;
4573
fw.sbss_len = bce_COM_b06FwSbssLen;
4574
fw.sbss_index = 0;
4575
fw.sbss = bce_COM_b06FwSbss;
4576
4577
fw.bss_addr = bce_COM_b06FwBssAddr;
4578
fw.bss_len = bce_COM_b06FwBssLen;
4579
fw.bss_index = 0;
4580
fw.bss = bce_COM_b06FwBss;
4581
4582
fw.rodata_addr = bce_COM_b06FwRodataAddr;
4583
fw.rodata_len = bce_COM_b06FwRodataLen;
4584
fw.rodata_index = 0;
4585
fw.rodata = bce_COM_b06FwRodata;
4586
}
4587
4588
DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4589
bce_load_cpu_fw(sc, &cpu_reg, &fw);
4590
bce_start_cpu(sc, &cpu_reg);
4591
4592
DBEXIT(BCE_VERBOSE_RESET);
4593
}
4594
4595
/****************************************************************************/
4596
/* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs. */
4597
/* */
4598
/* Loads the firmware for each CPU and starts the CPU. */
4599
/* */
4600
/* Returns: */
4601
/* Nothing. */
4602
/****************************************************************************/
4603
static void
4604
bce_init_cpus(struct bce_softc *sc)
4605
{
4606
DBENTER(BCE_VERBOSE_RESET);
4607
4608
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4609
if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4610
bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
4611
sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4612
bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
4613
sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4614
} else {
4615
bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
4616
sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4617
bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
4618
sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4619
}
4620
4621
} else {
4622
bce_load_rv2p_fw(sc, bce_rv2p_proc1,
4623
sizeof(bce_rv2p_proc1), RV2P_PROC1);
4624
bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4625
sizeof(bce_rv2p_proc2), RV2P_PROC2);
4626
}
4627
4628
bce_init_rxp_cpu(sc);
4629
bce_init_txp_cpu(sc);
4630
bce_init_tpat_cpu(sc);
4631
bce_init_com_cpu(sc);
4632
bce_init_cp_cpu(sc);
4633
4634
DBEXIT(BCE_VERBOSE_RESET);
4635
}
4636
4637
/****************************************************************************/
4638
/* Initialize context memory. */
4639
/* */
4640
/* Clears the memory associated with each Context ID (CID). */
4641
/* */
4642
/* Returns: */
4643
/* Nothing. */
4644
/****************************************************************************/
4645
static int
4646
bce_init_ctx(struct bce_softc *sc)
4647
{
4648
u32 offset, val, vcid_addr;
4649
int i, j, rc, retry_cnt;
4650
4651
rc = 0;
4652
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4653
4654
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4655
retry_cnt = CTX_INIT_RETRY_COUNT;
4656
4657
DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4658
4659
/*
4660
* BCM5709 context memory may be cached
4661
* in host memory so prepare the host memory
4662
* for access.
4663
*/
4664
val = BCE_CTX_COMMAND_ENABLED |
4665
BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4666
val |= (BCM_PAGE_BITS - 8) << 16;
4667
REG_WR(sc, BCE_CTX_COMMAND, val);
4668
4669
/* Wait for mem init command to complete. */
4670
for (i = 0; i < retry_cnt; i++) {
4671
val = REG_RD(sc, BCE_CTX_COMMAND);
4672
if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4673
break;
4674
DELAY(2);
4675
}
4676
if ((val & BCE_CTX_COMMAND_MEM_INIT) != 0) {
4677
BCE_PRINTF("%s(): Context memory initialization failed!\n",
4678
__FUNCTION__);
4679
rc = EBUSY;
4680
goto init_ctx_fail;
4681
}
4682
4683
for (i = 0; i < sc->ctx_pages; i++) {
4684
/* Set the physical address of the context memory. */
4685
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4686
BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4687
BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4688
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4689
BCE_ADDR_HI(sc->ctx_paddr[i]));
4690
REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4691
BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4692
4693
/* Verify the context memory write was successful. */
4694
for (j = 0; j < retry_cnt; j++) {
4695
val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4696
if ((val &
4697
BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4698
break;
4699
DELAY(5);
4700
}
4701
if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) != 0) {
4702
BCE_PRINTF("%s(): Failed to initialize "
4703
"context page %d!\n", __FUNCTION__, i);
4704
rc = EBUSY;
4705
goto init_ctx_fail;
4706
}
4707
}
4708
} else {
4709
DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4710
4711
/*
4712
* For the 5706/5708, context memory is local to
4713
* the controller, so initialize the controller
4714
* context memory.
4715
*/
4716
4717
vcid_addr = GET_CID_ADDR(96);
4718
while (vcid_addr) {
4719
vcid_addr -= PHY_CTX_SIZE;
4720
4721
REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4722
REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4723
4724
for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4725
CTX_WR(sc, 0x00, offset, 0);
4726
}
4727
4728
REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4729
REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4730
}
4731
}
4732
init_ctx_fail:
4733
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4734
return (rc);
4735
}
4736
4737
/****************************************************************************/
4738
/* Fetch the permanent MAC address of the controller. */
4739
/* */
4740
/* Returns: */
4741
/* Nothing. */
4742
/****************************************************************************/
4743
static void
4744
bce_get_mac_addr(struct bce_softc *sc)
4745
{
4746
u32 mac_lo = 0, mac_hi = 0;
4747
4748
DBENTER(BCE_VERBOSE_RESET);
4749
4750
/*
4751
* The NetXtreme II bootcode populates various NIC
4752
* power-on and runtime configuration items in a
4753
* shared memory area. The factory configured MAC
4754
* address is available from both NVRAM and the
4755
* shared memory area so we'll read the value from
4756
* shared memory for speed.
4757
*/
4758
4759
mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4760
mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4761
4762
if ((mac_lo == 0) && (mac_hi == 0)) {
4763
BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4764
__FILE__, __LINE__);
4765
} else {
4766
sc->eaddr[0] = (u_char)(mac_hi >> 8);
4767
sc->eaddr[1] = (u_char)(mac_hi >> 0);
4768
sc->eaddr[2] = (u_char)(mac_lo >> 24);
4769
sc->eaddr[3] = (u_char)(mac_lo >> 16);
4770
sc->eaddr[4] = (u_char)(mac_lo >> 8);
4771
sc->eaddr[5] = (u_char)(mac_lo >> 0);
4772
}
4773
4774
DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet "
4775
"address = %6D\n", sc->eaddr, ":");
4776
DBEXIT(BCE_VERBOSE_RESET);
4777
}
4778
4779
/****************************************************************************/
4780
/* Program the MAC address. */
4781
/* */
4782
/* Returns: */
4783
/* Nothing. */
4784
/****************************************************************************/
4785
static void
4786
bce_set_mac_addr(struct bce_softc *sc)
4787
{
4788
u32 val;
4789
u8 *mac_addr = sc->eaddr;
4790
4791
/* ToDo: Add support for setting multiple MAC addresses. */
4792
4793
DBENTER(BCE_VERBOSE_RESET);
4794
DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = "
4795
"%6D\n", sc->eaddr, ":");
4796
4797
val = (mac_addr[0] << 8) | mac_addr[1];
4798
4799
REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4800
4801
val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4802
(mac_addr[4] << 8) | mac_addr[5];
4803
4804
REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4805
4806
DBEXIT(BCE_VERBOSE_RESET);
4807
}
4808
4809
/****************************************************************************/
4810
/* Stop the controller. */
4811
/* */
4812
/* Returns: */
4813
/* Nothing. */
4814
/****************************************************************************/
4815
static void
4816
bce_stop(struct bce_softc *sc)
4817
{
4818
if_t ifp;
4819
4820
DBENTER(BCE_VERBOSE_RESET);
4821
4822
BCE_LOCK_ASSERT(sc);
4823
4824
ifp = sc->bce_ifp;
4825
4826
callout_stop(&sc->bce_tick_callout);
4827
4828
/* Disable the transmit/receive blocks. */
4829
REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4830
REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4831
DELAY(20);
4832
4833
bce_disable_intr(sc);
4834
4835
/* Free RX buffers. */
4836
if (bce_hdr_split == TRUE) {
4837
bce_free_pg_chain(sc);
4838
}
4839
bce_free_rx_chain(sc);
4840
4841
/* Free TX buffers. */
4842
bce_free_tx_chain(sc);
4843
4844
sc->watchdog_timer = 0;
4845
4846
sc->bce_link_up = FALSE;
4847
4848
if_setdrvflagbits(ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE));
4849
4850
DBEXIT(BCE_VERBOSE_RESET);
4851
}
4852
4853
static int
4854
bce_reset(struct bce_softc *sc, u32 reset_code)
4855
{
4856
u32 emac_mode_save, val;
4857
int i, rc = 0;
4858
static const u32 emac_mode_mask = BCE_EMAC_MODE_PORT |
4859
BCE_EMAC_MODE_HALF_DUPLEX | BCE_EMAC_MODE_25G;
4860
4861
DBENTER(BCE_VERBOSE_RESET);
4862
4863
DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4864
__FUNCTION__, reset_code);
4865
4866
/*
4867
* If ASF/IPMI is operational, then the EMAC Mode register already
4868
* contains appropriate values for the link settings that have
4869
* been auto-negotiated. Resetting the chip will clobber those
4870
* values. Save the important bits so we can restore them after
4871
* the reset.
4872
*/
4873
emac_mode_save = REG_RD(sc, BCE_EMAC_MODE) & emac_mode_mask;
4874
4875
/* Wait for pending PCI transactions to complete. */
4876
REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4877
BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4878
BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4879
BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4880
BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4881
val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4882
DELAY(5);
4883
4884
/* Disable DMA */
4885
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4886
val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4887
val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4888
REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4889
}
4890
4891
/* Assume bootcode is running. */
4892
sc->bce_fw_timed_out = FALSE;
4893
sc->bce_drv_cardiac_arrest = FALSE;
4894
4895
/* Give the firmware a chance to prepare for the reset. */
4896
rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4897
if (rc)
4898
goto bce_reset_exit;
4899
4900
/* Set a firmware reminder that this is a soft reset. */
4901
bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
4902
4903
/* Dummy read to force the chip to complete all current transactions. */
4904
val = REG_RD(sc, BCE_MISC_ID);
4905
4906
/* Chip reset. */
4907
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4908
REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4909
REG_RD(sc, BCE_MISC_COMMAND);
4910
DELAY(5);
4911
4912
val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4913
BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4914
4915
pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4916
} else {
4917
val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4918
BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4919
BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4920
REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4921
4922
/* Allow up to 30us for reset to complete. */
4923
for (i = 0; i < 10; i++) {
4924
val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4925
if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4926
BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4927
break;
4928
}
4929
DELAY(10);
4930
}
4931
4932
/* Check that reset completed successfully. */
4933
if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4934
BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4935
BCE_PRINTF("%s(%d): Reset failed!\n",
4936
__FILE__, __LINE__);
4937
rc = EBUSY;
4938
goto bce_reset_exit;
4939
}
4940
}
4941
4942
/* Make sure byte swapping is properly configured. */
4943
val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4944
if (val != 0x01020304) {
4945
BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4946
__FILE__, __LINE__);
4947
rc = ENODEV;
4948
goto bce_reset_exit;
4949
}
4950
4951
/* Just completed a reset, assume that firmware is running again. */
4952
sc->bce_fw_timed_out = FALSE;
4953
sc->bce_drv_cardiac_arrest = FALSE;
4954
4955
/* Wait for the firmware to finish its initialization. */
4956
rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4957
if (rc)
4958
BCE_PRINTF("%s(%d): Firmware did not complete "
4959
"initialization!\n", __FILE__, __LINE__);
4960
/* Get firmware capabilities. */
4961
bce_fw_cap_init(sc);
4962
4963
bce_reset_exit:
4964
/* Restore EMAC Mode bits needed to keep ASF/IPMI running. */
4965
if (reset_code == BCE_DRV_MSG_CODE_RESET) {
4966
val = REG_RD(sc, BCE_EMAC_MODE);
4967
val = (val & ~emac_mode_mask) | emac_mode_save;
4968
REG_WR(sc, BCE_EMAC_MODE, val);
4969
}
4970
4971
DBEXIT(BCE_VERBOSE_RESET);
4972
return (rc);
4973
}
4974
4975
static int
4976
bce_chipinit(struct bce_softc *sc)
4977
{
4978
u32 val;
4979
int rc = 0;
4980
4981
DBENTER(BCE_VERBOSE_RESET);
4982
4983
bce_disable_intr(sc);
4984
4985
/*
4986
* Initialize DMA byte/word swapping, configure the number of DMA
4987
* channels and PCI clock compensation delay.
4988
*/
4989
val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4990
BCE_DMA_CONFIG_DATA_WORD_SWAP |
4991
#if BYTE_ORDER == BIG_ENDIAN
4992
BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4993
#endif
4994
BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4995
DMA_READ_CHANS << 12 |
4996
DMA_WRITE_CHANS << 16;
4997
4998
val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4999
5000
if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
5001
val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
5002
5003
/*
5004
* This setting resolves a problem observed on certain Intel PCI
5005
* chipsets that cannot handle multiple outstanding DMA operations.
5006
* See errata E9_5706A1_65.
5007
*/
5008
if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
5009
(BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
5010
!(sc->bce_flags & BCE_PCIX_FLAG))
5011
val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
5012
5013
REG_WR(sc, BCE_DMA_CONFIG, val);
5014
5015
/* Enable the RX_V2P and Context state machines before access. */
5016
REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5017
BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
5018
BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
5019
BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
5020
5021
/* Initialize context mapping and zero out the quick contexts. */
5022
if ((rc = bce_init_ctx(sc)) != 0)
5023
goto bce_chipinit_exit;
5024
5025
/* Initialize the on-boards CPUs */
5026
bce_init_cpus(sc);
5027
5028
/* Enable management frames (NC-SI) to flow to the MCP. */
5029
if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5030
val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5031
REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5032
}
5033
5034
/* Prepare NVRAM for access. */
5035
if ((rc = bce_init_nvram(sc)) != 0)
5036
goto bce_chipinit_exit;
5037
5038
/* Set the kernel bypass block size */
5039
val = REG_RD(sc, BCE_MQ_CONFIG);
5040
val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
5041
val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
5042
5043
/* Enable bins used on the 5709. */
5044
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5045
val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
5046
if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
5047
val |= BCE_MQ_CONFIG_HALT_DIS;
5048
}
5049
5050
REG_WR(sc, BCE_MQ_CONFIG, val);
5051
5052
val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
5053
REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
5054
REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
5055
5056
/* Set the page size and clear the RV2P processor stall bits. */
5057
val = (BCM_PAGE_BITS - 8) << 24;
5058
REG_WR(sc, BCE_RV2P_CONFIG, val);
5059
5060
/* Configure page size. */
5061
val = REG_RD(sc, BCE_TBDR_CONFIG);
5062
val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
5063
val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
5064
REG_WR(sc, BCE_TBDR_CONFIG, val);
5065
5066
/* Set the perfect match control register to default. */
5067
REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
5068
5069
bce_chipinit_exit:
5070
DBEXIT(BCE_VERBOSE_RESET);
5071
5072
return(rc);
5073
}
5074
5075
/****************************************************************************/
5076
/* Initialize the controller in preparation to send/receive traffic. */
5077
/* */
5078
/* Returns: */
5079
/* 0 for success, positive value for failure. */
5080
/****************************************************************************/
5081
static int
5082
bce_blockinit(struct bce_softc *sc)
5083
{
5084
u32 reg, val;
5085
int rc = 0;
5086
5087
DBENTER(BCE_VERBOSE_RESET);
5088
5089
/* Load the hardware default MAC address. */
5090
bce_set_mac_addr(sc);
5091
5092
/* Set the Ethernet backoff seed value */
5093
val = sc->eaddr[0] + (sc->eaddr[1] << 8) +
5094
(sc->eaddr[2] << 16) + (sc->eaddr[3] ) +
5095
(sc->eaddr[4] << 8) + (sc->eaddr[5] << 16);
5096
REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
5097
5098
sc->last_status_idx = 0;
5099
sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
5100
5101
/* Set up link change interrupt generation. */
5102
REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
5103
5104
/* Program the physical address of the status block. */
5105
REG_WR(sc, BCE_HC_STATUS_ADDR_L,
5106
BCE_ADDR_LO(sc->status_block_paddr));
5107
REG_WR(sc, BCE_HC_STATUS_ADDR_H,
5108
BCE_ADDR_HI(sc->status_block_paddr));
5109
5110
/* Program the physical address of the statistics block. */
5111
REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
5112
BCE_ADDR_LO(sc->stats_block_paddr));
5113
REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
5114
BCE_ADDR_HI(sc->stats_block_paddr));
5115
5116
/*
5117
* Program various host coalescing parameters.
5118
* Trip points control how many BDs should be ready before generating
5119
* an interrupt while ticks control how long a BD can sit in the chain
5120
* before generating an interrupt.
5121
*/
5122
REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
5123
(sc->bce_tx_quick_cons_trip_int << 16) |
5124
sc->bce_tx_quick_cons_trip);
5125
REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
5126
(sc->bce_rx_quick_cons_trip_int << 16) |
5127
sc->bce_rx_quick_cons_trip);
5128
REG_WR(sc, BCE_HC_TX_TICKS,
5129
(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
5130
REG_WR(sc, BCE_HC_RX_TICKS,
5131
(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
5132
REG_WR(sc, BCE_HC_STATS_TICKS, sc->bce_stats_ticks & 0xffff00);
5133
REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
5134
/* Not used for L2. */
5135
REG_WR(sc, BCE_HC_COMP_PROD_TRIP, 0);
5136
REG_WR(sc, BCE_HC_COM_TICKS, 0);
5137
REG_WR(sc, BCE_HC_CMD_TICKS, 0);
5138
5139
/* Configure the Host Coalescing block. */
5140
val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
5141
BCE_HC_CONFIG_COLLECT_STATS;
5142
5143
#if 0
5144
/* ToDo: Add MSI-X support. */
5145
if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
5146
u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
5147
BCE_HC_SB_CONFIG_1;
5148
5149
REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
5150
5151
REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
5152
BCE_HC_SB_CONFIG_1_ONE_SHOT);
5153
5154
REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
5155
(sc->tx_quick_cons_trip_int << 16) |
5156
sc->tx_quick_cons_trip);
5157
5158
REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
5159
(sc->tx_ticks_int << 16) | sc->tx_ticks);
5160
5161
val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5162
}
5163
5164
/*
5165
* Tell the HC block to automatically set the
5166
* INT_MASK bit after an MSI/MSI-X interrupt
5167
* is generated so the driver doesn't have to.
5168
*/
5169
if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
5170
val |= BCE_HC_CONFIG_ONE_SHOT;
5171
5172
/* Set the MSI-X status blocks to 128 byte boundaries. */
5173
if (sc->bce_flags & BCE_USING_MSIX_FLAG)
5174
val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5175
#endif
5176
5177
REG_WR(sc, BCE_HC_CONFIG, val);
5178
5179
/* Clear the internal statistics counters. */
5180
REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
5181
5182
/* Verify that bootcode is running. */
5183
reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
5184
5185
DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
5186
BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
5187
__FILE__, __LINE__);
5188
reg = 0);
5189
5190
if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
5191
BCE_DEV_INFO_SIGNATURE_MAGIC) {
5192
BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
5193
"Expected: 08%08X\n", __FILE__, __LINE__,
5194
(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
5195
BCE_DEV_INFO_SIGNATURE_MAGIC);
5196
rc = ENODEV;
5197
goto bce_blockinit_exit;
5198
}
5199
5200
/* Enable DMA */
5201
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5202
val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
5203
val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
5204
REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
5205
}
5206
5207
/* Allow bootcode to apply additional fixes before enabling MAC. */
5208
rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
5209
BCE_DRV_MSG_CODE_RESET);
5210
5211
/* Enable link state change interrupt generation. */
5212
REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
5213
5214
/* Enable the RXP. */
5215
bce_start_rxp_cpu(sc);
5216
5217
/* Disable management frames (NC-SI) from flowing to the MCP. */
5218
if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5219
val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
5220
~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5221
REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5222
}
5223
5224
/* Enable all remaining blocks in the MAC. */
5225
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
5226
REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5227
BCE_MISC_ENABLE_DEFAULT_XI);
5228
else
5229
REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5230
BCE_MISC_ENABLE_DEFAULT);
5231
5232
REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
5233
DELAY(20);
5234
5235
/* Save the current host coalescing block settings. */
5236
sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
5237
5238
bce_blockinit_exit:
5239
DBEXIT(BCE_VERBOSE_RESET);
5240
5241
return (rc);
5242
}
5243
5244
/****************************************************************************/
5245
/* Encapsulate an mbuf into the rx_bd chain. */
5246
/* */
5247
/* Returns: */
5248
/* 0 for success, positive value for failure. */
5249
/****************************************************************************/
5250
static int
5251
bce_get_rx_buf(struct bce_softc *sc, u16 prod, u16 chain_prod, u32 *prod_bseq)
5252
{
5253
bus_dma_segment_t segs[1];
5254
struct mbuf *m_new = NULL;
5255
struct rx_bd *rxbd;
5256
int nsegs, error, rc = 0;
5257
#ifdef BCE_DEBUG
5258
u16 debug_chain_prod = chain_prod;
5259
#endif
5260
5261
DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5262
5263
/* Make sure the inputs are valid. */
5264
DBRUNIF((chain_prod > MAX_RX_BD_ALLOC),
5265
BCE_PRINTF("%s(%d): RX producer out of range: "
5266
"0x%04X > 0x%04X\n", __FILE__, __LINE__,
5267
chain_prod, (u16)MAX_RX_BD_ALLOC));
5268
5269
DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5270
"chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
5271
prod, chain_prod, *prod_bseq);
5272
5273
/* Update some debug statistic counters */
5274
DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5275
sc->rx_low_watermark = sc->free_rx_bd);
5276
DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
5277
sc->rx_empty_count++);
5278
5279
/* Simulate an mbuf allocation failure. */
5280
DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5281
sc->mbuf_alloc_failed_count++;
5282
sc->mbuf_alloc_failed_sim_count++;
5283
rc = ENOBUFS;
5284
goto bce_get_rx_buf_exit);
5285
5286
/* This is a new mbuf allocation. */
5287
if (bce_hdr_split == TRUE)
5288
MGETHDR(m_new, M_NOWAIT, MT_DATA);
5289
else
5290
m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
5291
sc->rx_bd_mbuf_alloc_size);
5292
5293
if (m_new == NULL) {
5294
sc->mbuf_alloc_failed_count++;
5295
rc = ENOBUFS;
5296
goto bce_get_rx_buf_exit;
5297
}
5298
5299
DBRUN(sc->debug_rx_mbuf_alloc++);
5300
5301
/* Make sure we have a valid packet header. */
5302
M_ASSERTPKTHDR(m_new);
5303
5304
/* Initialize the mbuf size and pad if necessary for alignment. */
5305
m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5306
m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5307
5308
/* ToDo: Consider calling m_fragment() to test error handling. */
5309
5310
/* Map the mbuf cluster into device memory. */
5311
error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag,
5312
sc->rx_mbuf_map[chain_prod], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5313
5314
/* Handle any mapping errors. */
5315
if (error) {
5316
BCE_PRINTF("%s(%d): Error mapping mbuf into RX "
5317
"chain (%d)!\n", __FILE__, __LINE__, error);
5318
5319
sc->dma_map_addr_rx_failed_count++;
5320
m_freem(m_new);
5321
5322
DBRUN(sc->debug_rx_mbuf_alloc--);
5323
5324
rc = ENOBUFS;
5325
goto bce_get_rx_buf_exit;
5326
}
5327
5328
/* All mbufs must map to a single segment. */
5329
KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5330
__FUNCTION__, nsegs));
5331
5332
/* Setup the rx_bd for the segment. */
5333
rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)];
5334
5335
rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5336
rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5337
rxbd->rx_bd_len = htole32(segs[0].ds_len);
5338
rxbd->rx_bd_flags = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5339
*prod_bseq += segs[0].ds_len;
5340
5341
/* Save the mbuf and update our counter. */
5342
sc->rx_mbuf_ptr[chain_prod] = m_new;
5343
sc->free_rx_bd -= nsegs;
5344
5345
DBRUNMSG(BCE_INSANE_RECV,
5346
bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
5347
5348
DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5349
"chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, prod,
5350
chain_prod, *prod_bseq);
5351
5352
bce_get_rx_buf_exit:
5353
DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5354
5355
return(rc);
5356
}
5357
5358
/****************************************************************************/
5359
/* Encapsulate an mbuf cluster into the page chain. */
5360
/* */
5361
/* Returns: */
5362
/* 0 for success, positive value for failure. */
5363
/****************************************************************************/
5364
static int
5365
bce_get_pg_buf(struct bce_softc *sc, u16 prod, u16 prod_idx)
5366
{
5367
bus_dma_segment_t segs[1];
5368
struct mbuf *m_new = NULL;
5369
struct rx_bd *pgbd;
5370
int error, nsegs, rc = 0;
5371
#ifdef BCE_DEBUG
5372
u16 debug_prod_idx = prod_idx;
5373
#endif
5374
5375
DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5376
5377
/* Make sure the inputs are valid. */
5378
DBRUNIF((prod_idx > MAX_PG_BD_ALLOC),
5379
BCE_PRINTF("%s(%d): page producer out of range: "
5380
"0x%04X > 0x%04X\n", __FILE__, __LINE__,
5381
prod_idx, (u16)MAX_PG_BD_ALLOC));
5382
5383
DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5384
"chain_prod = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5385
5386
/* Update counters if we've hit a new low or run out of pages. */
5387
DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5388
sc->pg_low_watermark = sc->free_pg_bd);
5389
DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5390
5391
/* Simulate an mbuf allocation failure. */
5392
DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5393
sc->mbuf_alloc_failed_count++;
5394
sc->mbuf_alloc_failed_sim_count++;
5395
rc = ENOBUFS;
5396
goto bce_get_pg_buf_exit);
5397
5398
/* This is a new mbuf allocation. */
5399
m_new = m_getcl(M_NOWAIT, MT_DATA, 0);
5400
if (m_new == NULL) {
5401
sc->mbuf_alloc_failed_count++;
5402
rc = ENOBUFS;
5403
goto bce_get_pg_buf_exit;
5404
}
5405
5406
DBRUN(sc->debug_pg_mbuf_alloc++);
5407
5408
m_new->m_len = MCLBYTES;
5409
5410
/* ToDo: Consider calling m_fragment() to test error handling. */
5411
5412
/* Map the mbuf cluster into device memory. */
5413
error = bus_dmamap_load_mbuf_sg(sc->pg_mbuf_tag,
5414
sc->pg_mbuf_map[prod_idx], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5415
5416
/* Handle any mapping errors. */
5417
if (error) {
5418
BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5419
__FILE__, __LINE__);
5420
5421
m_freem(m_new);
5422
DBRUN(sc->debug_pg_mbuf_alloc--);
5423
5424
rc = ENOBUFS;
5425
goto bce_get_pg_buf_exit;
5426
}
5427
5428
/* All mbufs must map to a single segment. */
5429
KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5430
__FUNCTION__, nsegs));
5431
5432
/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5433
5434
/*
5435
* The page chain uses the same rx_bd data structure
5436
* as the receive chain but doesn't require a byte sequence (bseq).
5437
*/
5438
pgbd = &sc->pg_bd_chain[PG_PAGE(prod_idx)][PG_IDX(prod_idx)];
5439
5440
pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5441
pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5442
pgbd->rx_bd_len = htole32(MCLBYTES);
5443
pgbd->rx_bd_flags = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5444
5445
/* Save the mbuf and update our counter. */
5446
sc->pg_mbuf_ptr[prod_idx] = m_new;
5447
sc->free_pg_bd--;
5448
5449
DBRUNMSG(BCE_INSANE_RECV,
5450
bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
5451
5452
DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5453
"prod_idx = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5454
5455
bce_get_pg_buf_exit:
5456
DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5457
5458
return(rc);
5459
}
5460
5461
/****************************************************************************/
5462
/* Initialize the TX context memory. */
5463
/* */
5464
/* Returns: */
5465
/* Nothing */
5466
/****************************************************************************/
5467
static void
5468
bce_init_tx_context(struct bce_softc *sc)
5469
{
5470
u32 val;
5471
5472
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5473
5474
/* Initialize the context ID for an L2 TX chain. */
5475
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5476
/* Set the CID type to support an L2 connection. */
5477
val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
5478
BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5479
CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5480
val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5481
CTX_WR(sc, GET_CID_ADDR(TX_CID),
5482
BCE_L2CTX_TX_CMD_TYPE_XI, val);
5483
5484
/* Point the hardware to the first page in the chain. */
5485
val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5486
CTX_WR(sc, GET_CID_ADDR(TX_CID),
5487
BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5488
val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5489
CTX_WR(sc, GET_CID_ADDR(TX_CID),
5490
BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5491
} else {
5492
/* Set the CID type to support an L2 connection. */
5493
val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5494
CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5495
val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5496
CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5497
5498
/* Point the hardware to the first page in the chain. */
5499
val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5500
CTX_WR(sc, GET_CID_ADDR(TX_CID),
5501
BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5502
val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5503
CTX_WR(sc, GET_CID_ADDR(TX_CID),
5504
BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5505
}
5506
5507
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5508
}
5509
5510
/****************************************************************************/
5511
/* Allocate memory and initialize the TX data structures. */
5512
/* */
5513
/* Returns: */
5514
/* 0 for success, positive value for failure. */
5515
/****************************************************************************/
5516
static int
5517
bce_init_tx_chain(struct bce_softc *sc)
5518
{
5519
struct tx_bd *txbd;
5520
int i, rc = 0;
5521
5522
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5523
5524
/* Set the initial TX producer/consumer indices. */
5525
sc->tx_prod = 0;
5526
sc->tx_cons = 0;
5527
sc->tx_prod_bseq = 0;
5528
sc->used_tx_bd = 0;
5529
sc->max_tx_bd = USABLE_TX_BD_ALLOC;
5530
DBRUN(sc->tx_hi_watermark = 0);
5531
DBRUN(sc->tx_full_count = 0);
5532
5533
/*
5534
* The NetXtreme II supports a linked-list structure called
5535
* a Buffer Descriptor Chain (or BD chain). A BD chain
5536
* consists of a series of 1 or more chain pages, each of which
5537
* consists of a fixed number of BD entries.
5538
* The last BD entry on each page is a pointer to the next page
5539
* in the chain, and the last pointer in the BD chain
5540
* points back to the beginning of the chain.
5541
*/
5542
5543
/* Set the TX next pointer chain entries. */
5544
for (i = 0; i < sc->tx_pages; i++) {
5545
int j;
5546
5547
txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5548
5549
/* Check if we've reached the last page. */
5550
if (i == (sc->tx_pages - 1))
5551
j = 0;
5552
else
5553
j = i + 1;
5554
5555
txbd->tx_bd_haddr_hi =
5556
htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5557
txbd->tx_bd_haddr_lo =
5558
htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5559
}
5560
5561
bce_init_tx_context(sc);
5562
5563
DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC));
5564
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5565
5566
return(rc);
5567
}
5568
5569
/****************************************************************************/
5570
/* Free memory and clear the TX data structures. */
5571
/* */
5572
/* Returns: */
5573
/* Nothing. */
5574
/****************************************************************************/
5575
static void
5576
bce_free_tx_chain(struct bce_softc *sc)
5577
{
5578
int i;
5579
5580
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5581
5582
/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5583
for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
5584
if (sc->tx_mbuf_ptr[i] != NULL) {
5585
if (sc->tx_mbuf_map[i] != NULL)
5586
bus_dmamap_sync(sc->tx_mbuf_tag,
5587
sc->tx_mbuf_map[i],
5588
BUS_DMASYNC_POSTWRITE);
5589
m_freem(sc->tx_mbuf_ptr[i]);
5590
sc->tx_mbuf_ptr[i] = NULL;
5591
DBRUN(sc->debug_tx_mbuf_alloc--);
5592
}
5593
}
5594
5595
/* Clear each TX chain page. */
5596
for (i = 0; i < sc->tx_pages; i++)
5597
bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5598
5599
sc->used_tx_bd = 0;
5600
5601
/* Check if we lost any mbufs in the process. */
5602
DBRUNIF((sc->debug_tx_mbuf_alloc),
5603
BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5604
"from tx chain!\n", __FILE__, __LINE__,
5605
sc->debug_tx_mbuf_alloc));
5606
5607
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5608
}
5609
5610
/****************************************************************************/
5611
/* Initialize the RX context memory. */
5612
/* */
5613
/* Returns: */
5614
/* Nothing */
5615
/****************************************************************************/
5616
static void
5617
bce_init_rx_context(struct bce_softc *sc)
5618
{
5619
u32 val;
5620
5621
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5622
5623
/* Init the type, size, and BD cache levels for the RX context. */
5624
val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5625
BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5626
(0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5627
5628
/*
5629
* Set the level for generating pause frames
5630
* when the number of available rx_bd's gets
5631
* too low (the low watermark) and the level
5632
* when pause frames can be stopped (the high
5633
* watermark).
5634
*/
5635
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5636
u32 lo_water, hi_water;
5637
5638
if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) {
5639
lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5640
} else {
5641
lo_water = 0;
5642
}
5643
5644
if (lo_water >= USABLE_RX_BD_ALLOC) {
5645
lo_water = 0;
5646
}
5647
5648
hi_water = USABLE_RX_BD_ALLOC / 4;
5649
5650
if (hi_water <= lo_water) {
5651
lo_water = 0;
5652
}
5653
5654
lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5655
hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5656
5657
if (hi_water > 0xf)
5658
hi_water = 0xf;
5659
else if (hi_water == 0)
5660
lo_water = 0;
5661
5662
val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5663
(hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5664
}
5665
5666
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5667
5668
/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5669
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5670
val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5671
REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5672
}
5673
5674
/* Point the hardware to the first page in the chain. */
5675
val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5676
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5677
val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5678
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5679
5680
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5681
}
5682
5683
/****************************************************************************/
5684
/* Allocate memory and initialize the RX data structures. */
5685
/* */
5686
/* Returns: */
5687
/* 0 for success, positive value for failure. */
5688
/****************************************************************************/
5689
static int
5690
bce_init_rx_chain(struct bce_softc *sc)
5691
{
5692
struct rx_bd *rxbd;
5693
int i, rc = 0;
5694
5695
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5696
BCE_VERBOSE_CTX);
5697
5698
/* Initialize the RX producer and consumer indices. */
5699
sc->rx_prod = 0;
5700
sc->rx_cons = 0;
5701
sc->rx_prod_bseq = 0;
5702
sc->free_rx_bd = USABLE_RX_BD_ALLOC;
5703
sc->max_rx_bd = USABLE_RX_BD_ALLOC;
5704
5705
/* Initialize the RX next pointer chain entries. */
5706
for (i = 0; i < sc->rx_pages; i++) {
5707
int j;
5708
5709
rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5710
5711
/* Check if we've reached the last page. */
5712
if (i == (sc->rx_pages - 1))
5713
j = 0;
5714
else
5715
j = i + 1;
5716
5717
/* Setup the chain page pointers. */
5718
rxbd->rx_bd_haddr_hi =
5719
htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5720
rxbd->rx_bd_haddr_lo =
5721
htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5722
}
5723
5724
/* Fill up the RX chain. */
5725
bce_fill_rx_chain(sc);
5726
5727
DBRUN(sc->rx_low_watermark = USABLE_RX_BD_ALLOC);
5728
DBRUN(sc->rx_empty_count = 0);
5729
for (i = 0; i < sc->rx_pages; i++) {
5730
bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5731
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5732
}
5733
5734
bce_init_rx_context(sc);
5735
5736
DBRUNMSG(BCE_EXTREME_RECV,
5737
bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC));
5738
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5739
BCE_VERBOSE_CTX);
5740
5741
/* ToDo: Are there possible failure modes here? */
5742
5743
return(rc);
5744
}
5745
5746
/****************************************************************************/
5747
/* Add mbufs to the RX chain until its full or an mbuf allocation error */
5748
/* occurs. */
5749
/* */
5750
/* Returns: */
5751
/* Nothing */
5752
/****************************************************************************/
5753
static void
5754
bce_fill_rx_chain(struct bce_softc *sc)
5755
{
5756
u16 prod, prod_idx;
5757
u32 prod_bseq;
5758
5759
DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5760
BCE_VERBOSE_CTX);
5761
5762
/* Get the RX chain producer indices. */
5763
prod = sc->rx_prod;
5764
prod_bseq = sc->rx_prod_bseq;
5765
5766
/* Keep filling the RX chain until it's full. */
5767
while (sc->free_rx_bd > 0) {
5768
prod_idx = RX_CHAIN_IDX(prod);
5769
if (bce_get_rx_buf(sc, prod, prod_idx, &prod_bseq)) {
5770
/* Bail out if we can't add an mbuf to the chain. */
5771
break;
5772
}
5773
prod = NEXT_RX_BD(prod);
5774
}
5775
5776
/* Save the RX chain producer indices. */
5777
sc->rx_prod = prod;
5778
sc->rx_prod_bseq = prod_bseq;
5779
5780
/* We should never end up pointing to a next page pointer. */
5781
DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5782
BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5783
__FUNCTION__, sc->rx_prod));
5784
5785
/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5786
REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, prod);
5787
REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, prod_bseq);
5788
5789
DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5790
BCE_VERBOSE_CTX);
5791
}
5792
5793
/****************************************************************************/
5794
/* Free memory and clear the RX data structures. */
5795
/* */
5796
/* Returns: */
5797
/* Nothing. */
5798
/****************************************************************************/
5799
static void
5800
bce_free_rx_chain(struct bce_softc *sc)
5801
{
5802
int i;
5803
5804
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5805
5806
/* Free any mbufs still in the RX mbuf chain. */
5807
for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
5808
if (sc->rx_mbuf_ptr[i] != NULL) {
5809
if (sc->rx_mbuf_map[i] != NULL)
5810
bus_dmamap_sync(sc->rx_mbuf_tag,
5811
sc->rx_mbuf_map[i],
5812
BUS_DMASYNC_POSTREAD);
5813
m_freem(sc->rx_mbuf_ptr[i]);
5814
sc->rx_mbuf_ptr[i] = NULL;
5815
DBRUN(sc->debug_rx_mbuf_alloc--);
5816
}
5817
}
5818
5819
/* Clear each RX chain page. */
5820
for (i = 0; i < sc->rx_pages; i++)
5821
if (sc->rx_bd_chain[i] != NULL)
5822
bzero((char *)sc->rx_bd_chain[i],
5823
BCE_RX_CHAIN_PAGE_SZ);
5824
5825
sc->free_rx_bd = sc->max_rx_bd;
5826
5827
/* Check if we lost any mbufs in the process. */
5828
DBRUNIF((sc->debug_rx_mbuf_alloc),
5829
BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5830
__FUNCTION__, sc->debug_rx_mbuf_alloc));
5831
5832
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5833
}
5834
5835
/****************************************************************************/
5836
/* Allocate memory and initialize the page data structures. */
5837
/* Assumes that bce_init_rx_chain() has not already been called. */
5838
/* */
5839
/* Returns: */
5840
/* 0 for success, positive value for failure. */
5841
/****************************************************************************/
5842
static int
5843
bce_init_pg_chain(struct bce_softc *sc)
5844
{
5845
struct rx_bd *pgbd;
5846
int i, rc = 0;
5847
u32 val;
5848
5849
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5850
BCE_VERBOSE_CTX);
5851
5852
/* Initialize the page producer and consumer indices. */
5853
sc->pg_prod = 0;
5854
sc->pg_cons = 0;
5855
sc->free_pg_bd = USABLE_PG_BD_ALLOC;
5856
sc->max_pg_bd = USABLE_PG_BD_ALLOC;
5857
DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5858
DBRUN(sc->pg_empty_count = 0);
5859
5860
/* Initialize the page next pointer chain entries. */
5861
for (i = 0; i < sc->pg_pages; i++) {
5862
int j;
5863
5864
pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5865
5866
/* Check if we've reached the last page. */
5867
if (i == (sc->pg_pages - 1))
5868
j = 0;
5869
else
5870
j = i + 1;
5871
5872
/* Setup the chain page pointers. */
5873
pgbd->rx_bd_haddr_hi =
5874
htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5875
pgbd->rx_bd_haddr_lo =
5876
htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5877
}
5878
5879
/* Setup the MQ BIN mapping for host_pg_bidx. */
5880
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
5881
REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5882
5883
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5884
5885
/* Configure the rx_bd and page chain mbuf cluster size. */
5886
val = (sc->rx_bd_mbuf_data_len << 16) | MCLBYTES;
5887
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5888
5889
/* Configure the context reserved for jumbo support. */
5890
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5891
BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5892
5893
/* Point the hardware to the first page in the page chain. */
5894
val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5895
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5896
val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5897
CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5898
5899
/* Fill up the page chain. */
5900
bce_fill_pg_chain(sc);
5901
5902
for (i = 0; i < sc->pg_pages; i++) {
5903
bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
5904
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5905
}
5906
5907
DBRUNMSG(BCE_EXTREME_RECV,
5908
bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC));
5909
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5910
BCE_VERBOSE_CTX);
5911
return(rc);
5912
}
5913
5914
/****************************************************************************/
5915
/* Add mbufs to the page chain until its full or an mbuf allocation error */
5916
/* occurs. */
5917
/* */
5918
/* Returns: */
5919
/* Nothing */
5920
/****************************************************************************/
5921
static void
5922
bce_fill_pg_chain(struct bce_softc *sc)
5923
{
5924
u16 prod, prod_idx;
5925
5926
DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5927
BCE_VERBOSE_CTX);
5928
5929
/* Get the page chain prodcuer index. */
5930
prod = sc->pg_prod;
5931
5932
/* Keep filling the page chain until it's full. */
5933
while (sc->free_pg_bd > 0) {
5934
prod_idx = PG_CHAIN_IDX(prod);
5935
if (bce_get_pg_buf(sc, prod, prod_idx)) {
5936
/* Bail out if we can't add an mbuf to the chain. */
5937
break;
5938
}
5939
prod = NEXT_PG_BD(prod);
5940
}
5941
5942
/* Save the page chain producer index. */
5943
sc->pg_prod = prod;
5944
5945
DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5946
BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5947
__FUNCTION__, sc->pg_prod));
5948
5949
/*
5950
* Write the mailbox and tell the chip about
5951
* the new rx_bd's in the page chain.
5952
*/
5953
REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5954
prod);
5955
5956
DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5957
BCE_VERBOSE_CTX);
5958
}
5959
5960
/****************************************************************************/
5961
/* Free memory and clear the RX data structures. */
5962
/* */
5963
/* Returns: */
5964
/* Nothing. */
5965
/****************************************************************************/
5966
static void
5967
bce_free_pg_chain(struct bce_softc *sc)
5968
{
5969
int i;
5970
5971
DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5972
5973
/* Free any mbufs still in the mbuf page chain. */
5974
for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
5975
if (sc->pg_mbuf_ptr[i] != NULL) {
5976
if (sc->pg_mbuf_map[i] != NULL)
5977
bus_dmamap_sync(sc->pg_mbuf_tag,
5978
sc->pg_mbuf_map[i],
5979
BUS_DMASYNC_POSTREAD);
5980
m_freem(sc->pg_mbuf_ptr[i]);
5981
sc->pg_mbuf_ptr[i] = NULL;
5982
DBRUN(sc->debug_pg_mbuf_alloc--);
5983
}
5984
}
5985
5986
/* Clear each page chain pages. */
5987
for (i = 0; i < sc->pg_pages; i++)
5988
bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5989
5990
sc->free_pg_bd = sc->max_pg_bd;
5991
5992
/* Check if we lost any mbufs in the process. */
5993
DBRUNIF((sc->debug_pg_mbuf_alloc),
5994
BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5995
__FUNCTION__, sc->debug_pg_mbuf_alloc));
5996
5997
DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5998
}
5999
6000
static u32
6001
bce_get_rphy_link(struct bce_softc *sc)
6002
{
6003
u32 advertise, link;
6004
int fdpx;
6005
6006
advertise = 0;
6007
fdpx = 0;
6008
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0)
6009
link = bce_shmem_rd(sc, BCE_RPHY_SERDES_LINK);
6010
else
6011
link = bce_shmem_rd(sc, BCE_RPHY_COPPER_LINK);
6012
if (link & BCE_NETLINK_ANEG_ENB)
6013
advertise |= BCE_NETLINK_ANEG_ENB;
6014
if (link & BCE_NETLINK_SPEED_10HALF)
6015
advertise |= BCE_NETLINK_SPEED_10HALF;
6016
if (link & BCE_NETLINK_SPEED_10FULL) {
6017
advertise |= BCE_NETLINK_SPEED_10FULL;
6018
fdpx++;
6019
}
6020
if (link & BCE_NETLINK_SPEED_100HALF)
6021
advertise |= BCE_NETLINK_SPEED_100HALF;
6022
if (link & BCE_NETLINK_SPEED_100FULL) {
6023
advertise |= BCE_NETLINK_SPEED_100FULL;
6024
fdpx++;
6025
}
6026
if (link & BCE_NETLINK_SPEED_1000HALF)
6027
advertise |= BCE_NETLINK_SPEED_1000HALF;
6028
if (link & BCE_NETLINK_SPEED_1000FULL) {
6029
advertise |= BCE_NETLINK_SPEED_1000FULL;
6030
fdpx++;
6031
}
6032
if (link & BCE_NETLINK_SPEED_2500HALF)
6033
advertise |= BCE_NETLINK_SPEED_2500HALF;
6034
if (link & BCE_NETLINK_SPEED_2500FULL) {
6035
advertise |= BCE_NETLINK_SPEED_2500FULL;
6036
fdpx++;
6037
}
6038
if (fdpx)
6039
advertise |= BCE_NETLINK_FC_PAUSE_SYM |
6040
BCE_NETLINK_FC_PAUSE_ASYM;
6041
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6042
advertise |= BCE_NETLINK_PHY_APP_REMOTE |
6043
BCE_NETLINK_ETH_AT_WIRESPEED;
6044
6045
return (advertise);
6046
}
6047
6048
/****************************************************************************/
6049
/* Set media options. */
6050
/* */
6051
/* Returns: */
6052
/* 0 for success, positive value for failure. */
6053
/****************************************************************************/
6054
static int
6055
bce_ifmedia_upd(if_t ifp)
6056
{
6057
struct bce_softc *sc = if_getsoftc(ifp);
6058
int error;
6059
6060
DBENTER(BCE_VERBOSE);
6061
6062
BCE_LOCK(sc);
6063
error = bce_ifmedia_upd_locked(ifp);
6064
BCE_UNLOCK(sc);
6065
6066
DBEXIT(BCE_VERBOSE);
6067
return (error);
6068
}
6069
6070
/****************************************************************************/
6071
/* Set media options. */
6072
/* */
6073
/* Returns: */
6074
/* Nothing. */
6075
/****************************************************************************/
6076
static int
6077
bce_ifmedia_upd_locked(if_t ifp)
6078
{
6079
struct bce_softc *sc = if_getsoftc(ifp);
6080
struct mii_data *mii;
6081
struct mii_softc *miisc;
6082
struct ifmedia *ifm;
6083
u32 link;
6084
int error, fdx;
6085
6086
DBENTER(BCE_VERBOSE_PHY);
6087
6088
error = 0;
6089
BCE_LOCK_ASSERT(sc);
6090
6091
sc->bce_link_up = FALSE;
6092
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6093
ifm = &sc->bce_ifmedia;
6094
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
6095
return (EINVAL);
6096
link = 0;
6097
fdx = IFM_OPTIONS(ifm->ifm_media) & IFM_FDX;
6098
switch(IFM_SUBTYPE(ifm->ifm_media)) {
6099
case IFM_AUTO:
6100
/*
6101
* Check advertised link of remote PHY by reading
6102
* BCE_RPHY_SERDES_LINK or BCE_RPHY_COPPER_LINK.
6103
* Always use the same link type of remote PHY.
6104
*/
6105
link = bce_get_rphy_link(sc);
6106
break;
6107
case IFM_2500_SX:
6108
if ((sc->bce_phy_flags &
6109
(BCE_PHY_REMOTE_PORT_FIBER_FLAG |
6110
BCE_PHY_2_5G_CAPABLE_FLAG)) == 0)
6111
return (EINVAL);
6112
/*
6113
* XXX
6114
* Have to enable forced 2.5Gbps configuration.
6115
*/
6116
if (fdx != 0)
6117
link |= BCE_NETLINK_SPEED_2500FULL;
6118
else
6119
link |= BCE_NETLINK_SPEED_2500HALF;
6120
break;
6121
case IFM_1000_SX:
6122
if ((sc->bce_phy_flags &
6123
BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6124
return (EINVAL);
6125
/*
6126
* XXX
6127
* Have to disable 2.5Gbps configuration.
6128
*/
6129
if (fdx != 0)
6130
link = BCE_NETLINK_SPEED_1000FULL;
6131
else
6132
link = BCE_NETLINK_SPEED_1000HALF;
6133
break;
6134
case IFM_1000_T:
6135
if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6136
return (EINVAL);
6137
if (fdx != 0)
6138
link = BCE_NETLINK_SPEED_1000FULL;
6139
else
6140
link = BCE_NETLINK_SPEED_1000HALF;
6141
break;
6142
case IFM_100_TX:
6143
if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6144
return (EINVAL);
6145
if (fdx != 0)
6146
link = BCE_NETLINK_SPEED_100FULL;
6147
else
6148
link = BCE_NETLINK_SPEED_100HALF;
6149
break;
6150
case IFM_10_T:
6151
if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6152
return (EINVAL);
6153
if (fdx != 0)
6154
link = BCE_NETLINK_SPEED_10FULL;
6155
else
6156
link = BCE_NETLINK_SPEED_10HALF;
6157
break;
6158
default:
6159
return (EINVAL);
6160
}
6161
if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
6162
/*
6163
* XXX
6164
* Advertise pause capability for full-duplex media.
6165
*/
6166
if (fdx != 0)
6167
link |= BCE_NETLINK_FC_PAUSE_SYM |
6168
BCE_NETLINK_FC_PAUSE_ASYM;
6169
if ((sc->bce_phy_flags &
6170
BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6171
link |= BCE_NETLINK_PHY_APP_REMOTE |
6172
BCE_NETLINK_ETH_AT_WIRESPEED;
6173
}
6174
6175
bce_shmem_wr(sc, BCE_MB_ARGS_0, link);
6176
error = bce_fw_sync(sc, BCE_DRV_MSG_CODE_CMD_SET_LINK);
6177
} else {
6178
mii = device_get_softc(sc->bce_miibus);
6179
6180
/* Make sure the MII bus has been enumerated. */
6181
if (mii) {
6182
LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
6183
PHY_RESET(miisc);
6184
error = mii_mediachg(mii);
6185
}
6186
}
6187
6188
DBEXIT(BCE_VERBOSE_PHY);
6189
return (error);
6190
}
6191
6192
static void
6193
bce_ifmedia_sts_rphy(struct bce_softc *sc, struct ifmediareq *ifmr)
6194
{
6195
if_t ifp;
6196
u32 link;
6197
6198
ifp = sc->bce_ifp;
6199
BCE_LOCK_ASSERT(sc);
6200
6201
ifmr->ifm_status = IFM_AVALID;
6202
ifmr->ifm_active = IFM_ETHER;
6203
link = bce_shmem_rd(sc, BCE_LINK_STATUS);
6204
/* XXX Handle heart beat status? */
6205
if ((link & BCE_LINK_STATUS_LINK_UP) != 0)
6206
ifmr->ifm_status |= IFM_ACTIVE;
6207
else {
6208
ifmr->ifm_active |= IFM_NONE;
6209
if_setbaudrate(ifp, 0);
6210
return;
6211
}
6212
switch (link & BCE_LINK_STATUS_SPEED_MASK) {
6213
case BCE_LINK_STATUS_10HALF:
6214
ifmr->ifm_active |= IFM_10_T | IFM_HDX;
6215
if_setbaudrate(ifp, IF_Mbps(10UL));
6216
break;
6217
case BCE_LINK_STATUS_10FULL:
6218
ifmr->ifm_active |= IFM_10_T | IFM_FDX;
6219
if_setbaudrate(ifp, IF_Mbps(10UL));
6220
break;
6221
case BCE_LINK_STATUS_100HALF:
6222
ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
6223
if_setbaudrate(ifp, IF_Mbps(100UL));
6224
break;
6225
case BCE_LINK_STATUS_100FULL:
6226
ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
6227
if_setbaudrate(ifp, IF_Mbps(100UL));
6228
break;
6229
case BCE_LINK_STATUS_1000HALF:
6230
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6231
ifmr->ifm_active |= IFM_1000_T | IFM_HDX;
6232
else
6233
ifmr->ifm_active |= IFM_1000_SX | IFM_HDX;
6234
if_setbaudrate(ifp, IF_Mbps(1000UL));
6235
break;
6236
case BCE_LINK_STATUS_1000FULL:
6237
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6238
ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
6239
else
6240
ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
6241
if_setbaudrate(ifp, IF_Mbps(1000UL));
6242
break;
6243
case BCE_LINK_STATUS_2500HALF:
6244
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6245
ifmr->ifm_active |= IFM_NONE;
6246
return;
6247
} else
6248
ifmr->ifm_active |= IFM_2500_SX | IFM_HDX;
6249
if_setbaudrate(ifp, IF_Mbps(2500UL));
6250
break;
6251
case BCE_LINK_STATUS_2500FULL:
6252
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6253
ifmr->ifm_active |= IFM_NONE;
6254
return;
6255
} else
6256
ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
6257
if_setbaudrate(ifp, IF_Mbps(2500UL));
6258
break;
6259
default:
6260
ifmr->ifm_active |= IFM_NONE;
6261
return;
6262
}
6263
6264
if ((link & BCE_LINK_STATUS_RX_FC_ENABLED) != 0)
6265
ifmr->ifm_active |= IFM_ETH_RXPAUSE;
6266
if ((link & BCE_LINK_STATUS_TX_FC_ENABLED) != 0)
6267
ifmr->ifm_active |= IFM_ETH_TXPAUSE;
6268
}
6269
6270
/****************************************************************************/
6271
/* Reports current media status. */
6272
/* */
6273
/* Returns: */
6274
/* Nothing. */
6275
/****************************************************************************/
6276
static void
6277
bce_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
6278
{
6279
struct bce_softc *sc = if_getsoftc(ifp);
6280
struct mii_data *mii;
6281
6282
DBENTER(BCE_VERBOSE_PHY);
6283
6284
BCE_LOCK(sc);
6285
6286
if ((if_getflags(ifp) & IFF_UP) == 0) {
6287
BCE_UNLOCK(sc);
6288
return;
6289
}
6290
6291
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
6292
bce_ifmedia_sts_rphy(sc, ifmr);
6293
else {
6294
mii = device_get_softc(sc->bce_miibus);
6295
mii_pollstat(mii);
6296
ifmr->ifm_active = mii->mii_media_active;
6297
ifmr->ifm_status = mii->mii_media_status;
6298
}
6299
6300
BCE_UNLOCK(sc);
6301
6302
DBEXIT(BCE_VERBOSE_PHY);
6303
}
6304
6305
/****************************************************************************/
6306
/* Handles PHY generated interrupt events. */
6307
/* */
6308
/* Returns: */
6309
/* Nothing. */
6310
/****************************************************************************/
6311
static void
6312
bce_phy_intr(struct bce_softc *sc)
6313
{
6314
u32 new_link_state, old_link_state;
6315
6316
DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6317
6318
DBRUN(sc->phy_interrupts++);
6319
6320
new_link_state = sc->status_block->status_attn_bits &
6321
STATUS_ATTN_BITS_LINK_STATE;
6322
old_link_state = sc->status_block->status_attn_bits_ack &
6323
STATUS_ATTN_BITS_LINK_STATE;
6324
6325
/* Handle any changes if the link state has changed. */
6326
if (new_link_state != old_link_state) {
6327
/* Update the status_attn_bits_ack field. */
6328
if (new_link_state) {
6329
REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
6330
STATUS_ATTN_BITS_LINK_STATE);
6331
DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
6332
__FUNCTION__);
6333
} else {
6334
REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
6335
STATUS_ATTN_BITS_LINK_STATE);
6336
DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
6337
__FUNCTION__);
6338
}
6339
6340
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6341
if (new_link_state) {
6342
if (bootverbose)
6343
if_printf(sc->bce_ifp, "link UP\n");
6344
if_link_state_change(sc->bce_ifp,
6345
LINK_STATE_UP);
6346
} else {
6347
if (bootverbose)
6348
if_printf(sc->bce_ifp, "link DOWN\n");
6349
if_link_state_change(sc->bce_ifp,
6350
LINK_STATE_DOWN);
6351
}
6352
}
6353
/*
6354
* Assume link is down and allow
6355
* tick routine to update the state
6356
* based on the actual media state.
6357
*/
6358
sc->bce_link_up = FALSE;
6359
callout_stop(&sc->bce_tick_callout);
6360
bce_tick(sc);
6361
}
6362
6363
/* Acknowledge the link change interrupt. */
6364
REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
6365
6366
DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6367
}
6368
6369
/****************************************************************************/
6370
/* Reads the receive consumer value from the status block (skipping over */
6371
/* chain page pointer if necessary). */
6372
/* */
6373
/* Returns: */
6374
/* hw_cons */
6375
/****************************************************************************/
6376
static inline u16
6377
bce_get_hw_rx_cons(struct bce_softc *sc)
6378
{
6379
u16 hw_cons;
6380
6381
rmb();
6382
hw_cons = sc->status_block->status_rx_quick_consumer_index0;
6383
if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
6384
hw_cons++;
6385
6386
return hw_cons;
6387
}
6388
6389
/****************************************************************************/
6390
/* Handles received frame interrupt events. */
6391
/* */
6392
/* Returns: */
6393
/* Nothing. */
6394
/****************************************************************************/
6395
static void
6396
bce_rx_intr(struct bce_softc *sc)
6397
{
6398
if_t ifp = sc->bce_ifp;
6399
struct l2_fhdr *l2fhdr;
6400
struct ether_vlan_header *vh;
6401
unsigned int pkt_len;
6402
u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
6403
u32 status;
6404
unsigned int rem_len;
6405
u16 sw_pg_cons, sw_pg_cons_idx;
6406
6407
DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6408
DBRUN(sc->interrupts_rx++);
6409
DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
6410
"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6411
__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6412
6413
/* Prepare the RX chain pages to be accessed by the host CPU. */
6414
for (int i = 0; i < sc->rx_pages; i++)
6415
bus_dmamap_sync(sc->rx_bd_chain_tag,
6416
sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6417
6418
/* Prepare the page chain pages to be accessed by the host CPU. */
6419
if (bce_hdr_split == TRUE) {
6420
for (int i = 0; i < sc->pg_pages; i++)
6421
bus_dmamap_sync(sc->pg_bd_chain_tag,
6422
sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6423
}
6424
6425
/* Get the hardware's view of the RX consumer index. */
6426
hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6427
6428
/* Get working copies of the driver's view of the consumer indices. */
6429
sw_rx_cons = sc->rx_cons;
6430
sw_pg_cons = sc->pg_cons;
6431
6432
/* Update some debug statistics counters */
6433
DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
6434
sc->rx_low_watermark = sc->free_rx_bd);
6435
DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
6436
sc->rx_empty_count++);
6437
6438
/* Scan through the receive chain as long as there is work to do */
6439
/* ToDo: Consider setting a limit on the number of packets processed. */
6440
rmb();
6441
while (sw_rx_cons != hw_rx_cons) {
6442
struct mbuf *m0;
6443
6444
/* Convert the producer/consumer indices to an actual rx_bd index. */
6445
sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
6446
6447
/* Unmap the mbuf from DMA space. */
6448
bus_dmamap_sync(sc->rx_mbuf_tag,
6449
sc->rx_mbuf_map[sw_rx_cons_idx],
6450
BUS_DMASYNC_POSTREAD);
6451
bus_dmamap_unload(sc->rx_mbuf_tag,
6452
sc->rx_mbuf_map[sw_rx_cons_idx]);
6453
6454
/* Remove the mbuf from the RX chain. */
6455
m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
6456
sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
6457
DBRUN(sc->debug_rx_mbuf_alloc--);
6458
sc->free_rx_bd++;
6459
6460
/*
6461
* Frames received on the NetXteme II are prepended
6462
* with an l2_fhdr structure which provides status
6463
* information about the received frame (including
6464
* VLAN tags and checksum info). The frames are
6465
* also automatically adjusted to word align the IP
6466
* header (i.e. two null bytes are inserted before
6467
* the Ethernet header). As a result the data
6468
* DMA'd by the controller into the mbuf looks
6469
* like this:
6470
*
6471
* +---------+-----+---------------------+-----+
6472
* | l2_fhdr | pad | packet data | FCS |
6473
* +---------+-----+---------------------+-----+
6474
*
6475
* The l2_fhdr needs to be checked and skipped and
6476
* the FCS needs to be stripped before sending the
6477
* packet up the stack.
6478
*/
6479
l2fhdr = mtod(m0, struct l2_fhdr *);
6480
6481
/* Get the packet data + FCS length and the status. */
6482
pkt_len = l2fhdr->l2_fhdr_pkt_len;
6483
status = l2fhdr->l2_fhdr_status;
6484
6485
/*
6486
* Skip over the l2_fhdr and pad, resulting in the
6487
* following data in the mbuf:
6488
* +---------------------+-----+
6489
* | packet data | FCS |
6490
* +---------------------+-----+
6491
*/
6492
m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
6493
6494
/*
6495
* When split header mode is used, an ethernet frame
6496
* may be split across the receive chain and the
6497
* page chain. If that occurs an mbuf cluster must be
6498
* reassembled from the individual mbuf pieces.
6499
*/
6500
if (bce_hdr_split == TRUE) {
6501
/*
6502
* Check whether the received frame fits in a single
6503
* mbuf or not (i.e. packet data + FCS <=
6504
* sc->rx_bd_mbuf_data_len bytes).
6505
*/
6506
if (pkt_len > m0->m_len) {
6507
/*
6508
* The received frame is larger than a single mbuf.
6509
* If the frame was a TCP frame then only the TCP
6510
* header is placed in the mbuf, the remaining
6511
* payload (including FCS) is placed in the page
6512
* chain, the SPLIT flag is set, and the header
6513
* length is placed in the IP checksum field.
6514
* If the frame is not a TCP frame then the mbuf
6515
* is filled and the remaining bytes are placed
6516
* in the page chain.
6517
*/
6518
6519
DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
6520
"packet.\n", __FUNCTION__);
6521
DBRUN(sc->split_header_frames_rcvd++);
6522
6523
/*
6524
* When the page chain is enabled and the TCP
6525
* header has been split from the TCP payload,
6526
* the ip_xsum structure will reflect the length
6527
* of the TCP header, not the IP checksum. Set
6528
* the packet length of the mbuf accordingly.
6529
*/
6530
if (status & L2_FHDR_STATUS_SPLIT) {
6531
m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6532
DBRUN(sc->split_header_tcp_frames_rcvd++);
6533
}
6534
6535
rem_len = pkt_len - m0->m_len;
6536
6537
/* Pull mbufs off the page chain for any remaining data. */
6538
while (rem_len > 0) {
6539
struct mbuf *m_pg;
6540
6541
sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6542
6543
/* Remove the mbuf from the page chain. */
6544
m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6545
sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6546
DBRUN(sc->debug_pg_mbuf_alloc--);
6547
sc->free_pg_bd++;
6548
6549
/* Unmap the page chain mbuf from DMA space. */
6550
bus_dmamap_sync(sc->pg_mbuf_tag,
6551
sc->pg_mbuf_map[sw_pg_cons_idx],
6552
BUS_DMASYNC_POSTREAD);
6553
bus_dmamap_unload(sc->pg_mbuf_tag,
6554
sc->pg_mbuf_map[sw_pg_cons_idx]);
6555
6556
/* Adjust the mbuf length. */
6557
if (rem_len < m_pg->m_len) {
6558
/* The mbuf chain is complete. */
6559
m_pg->m_len = rem_len;
6560
rem_len = 0;
6561
} else {
6562
/* More packet data is waiting. */
6563
rem_len -= m_pg->m_len;
6564
}
6565
6566
/* Concatenate the mbuf cluster to the mbuf. */
6567
m_cat(m0, m_pg);
6568
6569
sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6570
}
6571
6572
/* Set the total packet length. */
6573
m0->m_pkthdr.len = pkt_len;
6574
6575
} else {
6576
/*
6577
* The received packet is small and fits in a
6578
* single mbuf (i.e. the l2_fhdr + pad + packet +
6579
* FCS <= MHLEN). In other words, the packet is
6580
* 154 bytes or less in size.
6581
*/
6582
6583
DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
6584
"packet.\n", __FUNCTION__);
6585
6586
/* Set the total packet length. */
6587
m0->m_pkthdr.len = m0->m_len = pkt_len;
6588
}
6589
} else
6590
/* Set the total packet length. */
6591
m0->m_pkthdr.len = m0->m_len = pkt_len;
6592
6593
/* Remove the trailing Ethernet FCS. */
6594
m_adj(m0, -ETHER_CRC_LEN);
6595
6596
/* Check that the resulting mbuf chain is valid. */
6597
DBRUN(m_sanity(m0, FALSE));
6598
DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6599
(m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6600
BCE_PRINTF("Invalid Ethernet frame size!\n");
6601
m_print(m0, 128));
6602
6603
DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6604
sc->l2fhdr_error_sim_count++;
6605
status = status | L2_FHDR_ERRORS_PHY_DECODE);
6606
6607
/* Check the received frame for errors. */
6608
if (status & (L2_FHDR_ERRORS_BAD_CRC |
6609
L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6610
L2_FHDR_ERRORS_TOO_SHORT | L2_FHDR_ERRORS_GIANT_FRAME)) {
6611
/* Log the error and release the mbuf. */
6612
sc->l2fhdr_error_count++;
6613
m_freem(m0);
6614
m0 = NULL;
6615
goto bce_rx_intr_next_rx;
6616
}
6617
6618
/* Send the packet to the appropriate interface. */
6619
m0->m_pkthdr.rcvif = ifp;
6620
6621
/* Assume no hardware checksum. */
6622
m0->m_pkthdr.csum_flags = 0;
6623
6624
/* Validate the checksum if offload enabled. */
6625
if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
6626
/* Check for an IP datagram. */
6627
if (!(status & L2_FHDR_STATUS_SPLIT) &&
6628
(status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6629
m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6630
DBRUN(sc->csum_offload_ip++);
6631
/* Check if the IP checksum is valid. */
6632
if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6633
m0->m_pkthdr.csum_flags |=
6634
CSUM_IP_VALID;
6635
}
6636
6637
/* Check for a valid TCP/UDP frame. */
6638
if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6639
L2_FHDR_STATUS_UDP_DATAGRAM)) {
6640
/* Check for a good TCP/UDP checksum. */
6641
if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6642
L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6643
DBRUN(sc->csum_offload_tcp_udp++);
6644
m0->m_pkthdr.csum_data =
6645
l2fhdr->l2_fhdr_tcp_udp_xsum;
6646
m0->m_pkthdr.csum_flags |=
6647
(CSUM_DATA_VALID
6648
| CSUM_PSEUDO_HDR);
6649
}
6650
}
6651
}
6652
6653
/* Attach the VLAN tag. */
6654
if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
6655
!(sc->rx_mode & BCE_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
6656
DBRUN(sc->vlan_tagged_frames_rcvd++);
6657
if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) {
6658
DBRUN(sc->vlan_tagged_frames_stripped++);
6659
m0->m_pkthdr.ether_vtag =
6660
l2fhdr->l2_fhdr_vlan_tag;
6661
m0->m_flags |= M_VLANTAG;
6662
} else {
6663
/*
6664
* bce(4) controllers can't disable VLAN
6665
* tag stripping if management firmware
6666
* (ASF/IPMI/UMP) is running. So we always
6667
* strip VLAN tag and manually reconstruct
6668
* the VLAN frame by appending stripped
6669
* VLAN tag in driver if VLAN tag stripping
6670
* was disabled.
6671
*
6672
* TODO: LLC SNAP handling.
6673
*/
6674
bcopy(mtod(m0, uint8_t *),
6675
mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6676
ETHER_ADDR_LEN * 2);
6677
m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6678
vh = mtod(m0, struct ether_vlan_header *);
6679
vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6680
vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6681
m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6682
m0->m_len += ETHER_VLAN_ENCAP_LEN;
6683
}
6684
}
6685
6686
/* Increment received packet statistics. */
6687
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
6688
6689
bce_rx_intr_next_rx:
6690
sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6691
6692
/* If we have a packet, pass it up the stack */
6693
if (m0) {
6694
/* Make sure we don't lose our place when we release the lock. */
6695
sc->rx_cons = sw_rx_cons;
6696
sc->pg_cons = sw_pg_cons;
6697
6698
BCE_UNLOCK(sc);
6699
if_input(ifp, m0);
6700
BCE_LOCK(sc);
6701
6702
/* Recover our place. */
6703
sw_rx_cons = sc->rx_cons;
6704
sw_pg_cons = sc->pg_cons;
6705
}
6706
6707
/* Refresh hw_cons to see if there's new work */
6708
if (sw_rx_cons == hw_rx_cons)
6709
hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6710
}
6711
6712
/* No new packets. Refill the page chain. */
6713
if (bce_hdr_split == TRUE) {
6714
sc->pg_cons = sw_pg_cons;
6715
bce_fill_pg_chain(sc);
6716
}
6717
6718
/* No new packets. Refill the RX chain. */
6719
sc->rx_cons = sw_rx_cons;
6720
bce_fill_rx_chain(sc);
6721
6722
/* Prepare the page chain pages to be accessed by the NIC. */
6723
for (int i = 0; i < sc->rx_pages; i++)
6724
bus_dmamap_sync(sc->rx_bd_chain_tag,
6725
sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6726
6727
if (bce_hdr_split == TRUE) {
6728
for (int i = 0; i < sc->pg_pages; i++)
6729
bus_dmamap_sync(sc->pg_bd_chain_tag,
6730
sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6731
}
6732
6733
DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6734
"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6735
__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6736
DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6737
}
6738
6739
/****************************************************************************/
6740
/* Reads the transmit consumer value from the status block (skipping over */
6741
/* chain page pointer if necessary). */
6742
/* */
6743
/* Returns: */
6744
/* hw_cons */
6745
/****************************************************************************/
6746
static inline u16
6747
bce_get_hw_tx_cons(struct bce_softc *sc)
6748
{
6749
u16 hw_cons;
6750
6751
mb();
6752
hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6753
if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6754
hw_cons++;
6755
6756
return hw_cons;
6757
}
6758
6759
/****************************************************************************/
6760
/* Handles transmit completion interrupt events. */
6761
/* */
6762
/* Returns: */
6763
/* Nothing. */
6764
/****************************************************************************/
6765
static void
6766
bce_tx_intr(struct bce_softc *sc)
6767
{
6768
if_t ifp = sc->bce_ifp;
6769
u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6770
6771
DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6772
DBRUN(sc->interrupts_tx++);
6773
DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6774
"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6775
__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6776
6777
BCE_LOCK_ASSERT(sc);
6778
6779
/* Get the hardware's view of the TX consumer index. */
6780
hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6781
sw_tx_cons = sc->tx_cons;
6782
6783
/* Prevent speculative reads of the status block. */
6784
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6785
BUS_SPACE_BARRIER_READ);
6786
6787
/* Cycle through any completed TX chain page entries. */
6788
while (sw_tx_cons != hw_tx_cons) {
6789
#ifdef BCE_DEBUG
6790
struct tx_bd *txbd = NULL;
6791
#endif
6792
sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6793
6794
DBPRINT(sc, BCE_INFO_SEND,
6795
"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6796
"sw_tx_chain_cons = 0x%04X\n",
6797
__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6798
6799
DBRUNIF((sw_tx_chain_cons > MAX_TX_BD_ALLOC),
6800
BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6801
" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6802
(int) MAX_TX_BD_ALLOC);
6803
bce_breakpoint(sc));
6804
6805
DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6806
[TX_IDX(sw_tx_chain_cons)]);
6807
6808
DBRUNIF((txbd == NULL),
6809
BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6810
__FILE__, __LINE__, sw_tx_chain_cons);
6811
bce_breakpoint(sc));
6812
6813
DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6814
bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6815
6816
/*
6817
* Free the associated mbuf. Remember
6818
* that only the last tx_bd of a packet
6819
* has an mbuf pointer and DMA map.
6820
*/
6821
if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6822
/* Validate that this is the last tx_bd. */
6823
DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6824
BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6825
"txmbuf == NULL!\n", __FILE__, __LINE__);
6826
bce_breakpoint(sc));
6827
6828
DBRUNMSG(BCE_INFO_SEND,
6829
BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6830
"from tx_bd[0x%04X]\n", __FUNCTION__,
6831
sw_tx_chain_cons));
6832
6833
/* Unmap the mbuf. */
6834
bus_dmamap_unload(sc->tx_mbuf_tag,
6835
sc->tx_mbuf_map[sw_tx_chain_cons]);
6836
6837
/* Free the mbuf. */
6838
m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6839
sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6840
DBRUN(sc->debug_tx_mbuf_alloc--);
6841
6842
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
6843
}
6844
6845
sc->used_tx_bd--;
6846
sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6847
6848
/* Refresh hw_cons to see if there's new work. */
6849
hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6850
6851
/* Prevent speculative reads of the status block. */
6852
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6853
BUS_SPACE_BARRIER_READ);
6854
}
6855
6856
/* Clear the TX timeout timer. */
6857
sc->watchdog_timer = 0;
6858
6859
/* Clear the tx hardware queue full flag. */
6860
if (sc->used_tx_bd < sc->max_tx_bd) {
6861
DBRUNIF((if_getdrvflags(ifp) & IFF_DRV_OACTIVE),
6862
DBPRINT(sc, BCE_INFO_SEND,
6863
"%s(): Open TX chain! %d/%d (used/total)\n",
6864
__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6865
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
6866
}
6867
6868
sc->tx_cons = sw_tx_cons;
6869
6870
DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6871
"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6872
__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6873
DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6874
}
6875
6876
/****************************************************************************/
6877
/* Disables interrupt generation. */
6878
/* */
6879
/* Returns: */
6880
/* Nothing. */
6881
/****************************************************************************/
6882
static void
6883
bce_disable_intr(struct bce_softc *sc)
6884
{
6885
DBENTER(BCE_VERBOSE_INTR);
6886
6887
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6888
REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6889
6890
DBEXIT(BCE_VERBOSE_INTR);
6891
}
6892
6893
/****************************************************************************/
6894
/* Enables interrupt generation. */
6895
/* */
6896
/* Returns: */
6897
/* Nothing. */
6898
/****************************************************************************/
6899
static void
6900
bce_enable_intr(struct bce_softc *sc, int coal_now)
6901
{
6902
DBENTER(BCE_VERBOSE_INTR);
6903
6904
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6905
BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6906
BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6907
6908
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6909
BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6910
6911
/* Force an immediate interrupt (whether there is new data or not). */
6912
if (coal_now)
6913
REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6914
6915
DBEXIT(BCE_VERBOSE_INTR);
6916
}
6917
6918
/****************************************************************************/
6919
/* Handles controller initialization. */
6920
/* */
6921
/* Returns: */
6922
/* Nothing. */
6923
/****************************************************************************/
6924
static void
6925
bce_init_locked(struct bce_softc *sc)
6926
{
6927
if_t ifp;
6928
u32 ether_mtu = 0;
6929
6930
DBENTER(BCE_VERBOSE_RESET);
6931
6932
BCE_LOCK_ASSERT(sc);
6933
6934
ifp = sc->bce_ifp;
6935
6936
/* Check if the driver is still running and bail out if it is. */
6937
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
6938
goto bce_init_locked_exit;
6939
6940
bce_stop(sc);
6941
6942
if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6943
BCE_PRINTF("%s(%d): Controller reset failed!\n",
6944
__FILE__, __LINE__);
6945
goto bce_init_locked_exit;
6946
}
6947
6948
if (bce_chipinit(sc)) {
6949
BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6950
__FILE__, __LINE__);
6951
goto bce_init_locked_exit;
6952
}
6953
6954
if (bce_blockinit(sc)) {
6955
BCE_PRINTF("%s(%d): Block initialization failed!\n",
6956
__FILE__, __LINE__);
6957
goto bce_init_locked_exit;
6958
}
6959
6960
/* Load our MAC address. */
6961
bcopy(if_getlladdr(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6962
bce_set_mac_addr(sc);
6963
6964
if (bce_hdr_split == FALSE)
6965
bce_get_rx_buffer_sizes(sc, if_getmtu(ifp));
6966
/*
6967
* Calculate and program the hardware Ethernet MTU
6968
* size. Be generous on the receive if we have room
6969
* and allowed by the user.
6970
*/
6971
if (bce_strict_rx_mtu == TRUE)
6972
ether_mtu = if_getmtu(ifp);
6973
else {
6974
if (bce_hdr_split == TRUE) {
6975
if (if_getmtu(ifp) <= sc->rx_bd_mbuf_data_len + MCLBYTES)
6976
ether_mtu = sc->rx_bd_mbuf_data_len +
6977
MCLBYTES;
6978
else
6979
ether_mtu = if_getmtu(ifp);
6980
} else {
6981
if (if_getmtu(ifp) <= sc->rx_bd_mbuf_data_len)
6982
ether_mtu = sc->rx_bd_mbuf_data_len;
6983
else
6984
ether_mtu = if_getmtu(ifp);
6985
}
6986
}
6987
6988
ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6989
6990
DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
6991
__FUNCTION__, ether_mtu);
6992
6993
/* Program the mtu, enabling jumbo frame support if necessary. */
6994
if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6995
REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6996
min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6997
BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6998
else
6999
REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
7000
7001
/* Program appropriate promiscuous/multicast filtering. */
7002
bce_set_rx_mode(sc);
7003
7004
if (bce_hdr_split == TRUE) {
7005
/* Init page buffer descriptor chain. */
7006
bce_init_pg_chain(sc);
7007
}
7008
7009
/* Init RX buffer descriptor chain. */
7010
bce_init_rx_chain(sc);
7011
7012
/* Init TX buffer descriptor chain. */
7013
bce_init_tx_chain(sc);
7014
7015
/* Enable host interrupts. */
7016
bce_enable_intr(sc, 1);
7017
7018
bce_ifmedia_upd_locked(ifp);
7019
7020
/* Let the OS know the driver is up and running. */
7021
if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0);
7022
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
7023
7024
callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7025
7026
bce_init_locked_exit:
7027
DBEXIT(BCE_VERBOSE_RESET);
7028
}
7029
7030
/****************************************************************************/
7031
/* Initialize the controller just enough so that any management firmware */
7032
/* running on the device will continue to operate correctly. */
7033
/* */
7034
/* Returns: */
7035
/* Nothing. */
7036
/****************************************************************************/
7037
static void
7038
bce_mgmt_init_locked(struct bce_softc *sc)
7039
{
7040
if_t ifp;
7041
7042
DBENTER(BCE_VERBOSE_RESET);
7043
7044
BCE_LOCK_ASSERT(sc);
7045
7046
/* Bail out if management firmware is not running. */
7047
if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
7048
DBPRINT(sc, BCE_VERBOSE_SPECIAL,
7049
"No management firmware running...\n");
7050
goto bce_mgmt_init_locked_exit;
7051
}
7052
7053
ifp = sc->bce_ifp;
7054
7055
/* Enable all critical blocks in the MAC. */
7056
REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
7057
REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
7058
DELAY(20);
7059
7060
bce_ifmedia_upd_locked(ifp);
7061
7062
bce_mgmt_init_locked_exit:
7063
DBEXIT(BCE_VERBOSE_RESET);
7064
}
7065
7066
/****************************************************************************/
7067
/* Handles controller initialization when called from an unlocked routine. */
7068
/* */
7069
/* Returns: */
7070
/* Nothing. */
7071
/****************************************************************************/
7072
static void
7073
bce_init(void *xsc)
7074
{
7075
struct bce_softc *sc = xsc;
7076
7077
DBENTER(BCE_VERBOSE_RESET);
7078
7079
BCE_LOCK(sc);
7080
bce_init_locked(sc);
7081
BCE_UNLOCK(sc);
7082
7083
DBEXIT(BCE_VERBOSE_RESET);
7084
}
7085
7086
/****************************************************************************/
7087
/* Modifies an mbuf for TSO on the hardware. */
7088
/* */
7089
/* Returns: */
7090
/* Pointer to a modified mbuf. */
7091
/****************************************************************************/
7092
static struct mbuf *
7093
bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
7094
{
7095
struct mbuf *m;
7096
struct ether_header *eh;
7097
struct ip *ip;
7098
struct tcphdr *th;
7099
u16 etype;
7100
int hdr_len __unused, ip_len __unused, ip_hlen = 0, tcp_hlen = 0;
7101
7102
DBRUN(sc->tso_frames_requested++);
7103
7104
ip_len = 0;
7105
/* Controller may modify mbuf chains. */
7106
if (M_WRITABLE(*m_head) == 0) {
7107
m = m_dup(*m_head, M_NOWAIT);
7108
m_freem(*m_head);
7109
if (m == NULL) {
7110
sc->mbuf_alloc_failed_count++;
7111
*m_head = NULL;
7112
return (NULL);
7113
}
7114
*m_head = m;
7115
}
7116
7117
/*
7118
* For TSO the controller needs two pieces of info,
7119
* the MSS and the IP+TCP options length.
7120
*/
7121
m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
7122
if (m == NULL) {
7123
*m_head = NULL;
7124
return (NULL);
7125
}
7126
eh = mtod(m, struct ether_header *);
7127
etype = ntohs(eh->ether_type);
7128
7129
/* Check for supported TSO Ethernet types (only IPv4 for now) */
7130
switch (etype) {
7131
case ETHERTYPE_IP:
7132
ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7133
/* TSO only supported for TCP protocol. */
7134
if (ip->ip_p != IPPROTO_TCP) {
7135
BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
7136
__FILE__, __LINE__);
7137
m_freem(*m_head);
7138
*m_head = NULL;
7139
return (NULL);
7140
}
7141
7142
/* Get IP header length in bytes (min 20) */
7143
ip_hlen = ip->ip_hl << 2;
7144
m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
7145
sizeof(struct tcphdr));
7146
if (m == NULL) {
7147
*m_head = NULL;
7148
return (NULL);
7149
}
7150
7151
/* Get the TCP header length in bytes (min 20) */
7152
ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7153
th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
7154
tcp_hlen = (th->th_off << 2);
7155
7156
/* Make sure all IP/TCP options live in the same buffer. */
7157
m = m_pullup(*m_head, sizeof(struct ether_header)+ ip_hlen +
7158
tcp_hlen);
7159
if (m == NULL) {
7160
*m_head = NULL;
7161
return (NULL);
7162
}
7163
7164
/* Clear IP header length and checksum, will be calc'd by h/w. */
7165
ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7166
ip_len = ip->ip_len;
7167
ip->ip_len = 0;
7168
ip->ip_sum = 0;
7169
break;
7170
case ETHERTYPE_IPV6:
7171
BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
7172
__FILE__, __LINE__);
7173
m_freem(*m_head);
7174
*m_head = NULL;
7175
return (NULL);
7176
/* NOT REACHED */
7177
default:
7178
BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
7179
__FILE__, __LINE__);
7180
m_freem(*m_head);
7181
*m_head = NULL;
7182
return (NULL);
7183
}
7184
7185
hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
7186
7187
DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
7188
"ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
7189
__FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
7190
tcp_hlen, ip_len);
7191
7192
/* Set the LSO flag in the TX BD */
7193
*flags |= TX_BD_FLAGS_SW_LSO;
7194
7195
/* Set the length of IP + TCP options (in 32 bit words) */
7196
*flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
7197
sizeof(struct tcphdr)) >> 2) << 8);
7198
7199
DBRUN(sc->tso_frames_completed++);
7200
return (*m_head);
7201
}
7202
7203
/****************************************************************************/
7204
/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
7205
/* memory visible to the controller. */
7206
/* */
7207
/* Returns: */
7208
/* 0 for success, positive value for failure. */
7209
/* Modified: */
7210
/* m_head: May be set to NULL if MBUF is excessively fragmented. */
7211
/****************************************************************************/
7212
static int
7213
bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
7214
{
7215
bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
7216
bus_dmamap_t map;
7217
struct tx_bd *txbd = NULL;
7218
struct mbuf *m0;
7219
u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
7220
u32 prod_bseq;
7221
7222
#ifdef BCE_DEBUG
7223
u16 debug_prod;
7224
#endif
7225
7226
int i, error, nsegs, rc = 0;
7227
7228
DBENTER(BCE_VERBOSE_SEND);
7229
7230
/* Make sure we have room in the TX chain. */
7231
if (sc->used_tx_bd >= sc->max_tx_bd)
7232
goto bce_tx_encap_exit;
7233
7234
/* Transfer any checksum offload flags to the bd. */
7235
m0 = *m_head;
7236
if (m0->m_pkthdr.csum_flags) {
7237
if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
7238
m0 = bce_tso_setup(sc, m_head, &flags);
7239
if (m0 == NULL) {
7240
DBRUN(sc->tso_frames_failed++);
7241
goto bce_tx_encap_exit;
7242
}
7243
mss = htole16(m0->m_pkthdr.tso_segsz);
7244
} else {
7245
if (m0->m_pkthdr.csum_flags & CSUM_IP)
7246
flags |= TX_BD_FLAGS_IP_CKSUM;
7247
if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
7248
flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
7249
}
7250
}
7251
7252
/* Transfer any VLAN tags to the bd. */
7253
if (m0->m_flags & M_VLANTAG) {
7254
flags |= TX_BD_FLAGS_VLAN_TAG;
7255
vlan_tag = m0->m_pkthdr.ether_vtag;
7256
}
7257
7258
/* Map the mbuf into DMAable memory. */
7259
prod = sc->tx_prod;
7260
chain_prod = TX_CHAIN_IDX(prod);
7261
map = sc->tx_mbuf_map[chain_prod];
7262
7263
/* Map the mbuf into our DMA address space. */
7264
error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
7265
segs, &nsegs, BUS_DMA_NOWAIT);
7266
7267
/* Check if the DMA mapping was successful */
7268
if (error == EFBIG) {
7269
sc->mbuf_frag_count++;
7270
7271
/* Try to defrag the mbuf. */
7272
m0 = m_collapse(*m_head, M_NOWAIT, BCE_MAX_SEGMENTS);
7273
if (m0 == NULL) {
7274
/* Defrag was unsuccessful */
7275
m_freem(*m_head);
7276
*m_head = NULL;
7277
sc->mbuf_alloc_failed_count++;
7278
rc = ENOBUFS;
7279
goto bce_tx_encap_exit;
7280
}
7281
7282
/* Defrag was successful, try mapping again */
7283
*m_head = m0;
7284
error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag,
7285
map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
7286
7287
/* Still getting an error after a defrag. */
7288
if (error == ENOMEM) {
7289
/* Insufficient DMA buffers available. */
7290
sc->dma_map_addr_tx_failed_count++;
7291
rc = error;
7292
goto bce_tx_encap_exit;
7293
} else if (error != 0) {
7294
/* Release it and return an error. */
7295
BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
7296
"TX chain!\n", __FILE__, __LINE__);
7297
m_freem(m0);
7298
*m_head = NULL;
7299
sc->dma_map_addr_tx_failed_count++;
7300
rc = ENOBUFS;
7301
goto bce_tx_encap_exit;
7302
}
7303
} else if (error == ENOMEM) {
7304
/* Insufficient DMA buffers available. */
7305
sc->dma_map_addr_tx_failed_count++;
7306
rc = error;
7307
goto bce_tx_encap_exit;
7308
} else if (error != 0) {
7309
m_freem(m0);
7310
*m_head = NULL;
7311
sc->dma_map_addr_tx_failed_count++;
7312
rc = error;
7313
goto bce_tx_encap_exit;
7314
}
7315
7316
/* Make sure there's room in the chain */
7317
if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
7318
bus_dmamap_unload(sc->tx_mbuf_tag, map);
7319
rc = ENOBUFS;
7320
goto bce_tx_encap_exit;
7321
}
7322
7323
/* prod points to an empty tx_bd at this point. */
7324
prod_bseq = sc->tx_prod_bseq;
7325
7326
#ifdef BCE_DEBUG
7327
debug_prod = chain_prod;
7328
#endif
7329
7330
DBPRINT(sc, BCE_INFO_SEND,
7331
"%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
7332
"prod_bseq = 0x%08X\n",
7333
__FUNCTION__, prod, chain_prod, prod_bseq);
7334
7335
/*
7336
* Cycle through each mbuf segment that makes up
7337
* the outgoing frame, gathering the mapping info
7338
* for that segment and creating a tx_bd for
7339
* the mbuf.
7340
*/
7341
for (i = 0; i < nsegs ; i++) {
7342
chain_prod = TX_CHAIN_IDX(prod);
7343
txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
7344
[TX_IDX(chain_prod)];
7345
7346
txbd->tx_bd_haddr_lo =
7347
htole32(BCE_ADDR_LO(segs[i].ds_addr));
7348
txbd->tx_bd_haddr_hi =
7349
htole32(BCE_ADDR_HI(segs[i].ds_addr));
7350
txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
7351
htole16(segs[i].ds_len);
7352
txbd->tx_bd_vlan_tag = htole16(vlan_tag);
7353
txbd->tx_bd_flags = htole16(flags);
7354
prod_bseq += segs[i].ds_len;
7355
if (i == 0)
7356
txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
7357
prod = NEXT_TX_BD(prod);
7358
}
7359
7360
/* Set the END flag on the last TX buffer descriptor. */
7361
txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
7362
7363
DBRUNMSG(BCE_EXTREME_SEND,
7364
bce_dump_tx_chain(sc, debug_prod, nsegs));
7365
7366
/*
7367
* Ensure that the mbuf pointer for this transmission
7368
* is placed at the array index of the last
7369
* descriptor in this chain. This is done
7370
* because a single map is used for all
7371
* segments of the mbuf and we don't want to
7372
* unload the map before all of the segments
7373
* have been freed.
7374
*/
7375
sc->tx_mbuf_ptr[chain_prod] = m0;
7376
sc->used_tx_bd += nsegs;
7377
7378
/* Update some debug statistic counters */
7379
DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
7380
sc->tx_hi_watermark = sc->used_tx_bd);
7381
DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
7382
DBRUNIF(sc->debug_tx_mbuf_alloc++);
7383
7384
DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
7385
7386
/* prod points to the next free tx_bd at this point. */
7387
sc->tx_prod = prod;
7388
sc->tx_prod_bseq = prod_bseq;
7389
7390
/* Tell the chip about the waiting TX frames. */
7391
REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
7392
BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
7393
REG_WR(sc, MB_GET_CID_ADDR(TX_CID) +
7394
BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
7395
7396
bce_tx_encap_exit:
7397
DBEXIT(BCE_VERBOSE_SEND);
7398
return(rc);
7399
}
7400
7401
/****************************************************************************/
7402
/* Main transmit routine when called from another routine with a lock. */
7403
/* */
7404
/* Returns: */
7405
/* Nothing. */
7406
/****************************************************************************/
7407
static void
7408
bce_start_locked(if_t ifp)
7409
{
7410
struct bce_softc *sc = if_getsoftc(ifp);
7411
struct mbuf *m_head = NULL;
7412
int count = 0;
7413
u16 tx_prod, tx_chain_prod __unused;
7414
7415
DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7416
7417
BCE_LOCK_ASSERT(sc);
7418
7419
/* prod points to the next free tx_bd. */
7420
tx_prod = sc->tx_prod;
7421
tx_chain_prod = TX_CHAIN_IDX(tx_prod);
7422
7423
DBPRINT(sc, BCE_INFO_SEND,
7424
"%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
7425
"tx_prod_bseq = 0x%08X\n",
7426
__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
7427
7428
/* If there's no link or the transmit queue is empty then just exit. */
7429
if (sc->bce_link_up == FALSE) {
7430
DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
7431
__FUNCTION__);
7432
goto bce_start_locked_exit;
7433
}
7434
7435
if (if_sendq_empty(ifp)) {
7436
DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
7437
__FUNCTION__);
7438
goto bce_start_locked_exit;
7439
}
7440
7441
/*
7442
* Keep adding entries while there is space in the ring.
7443
*/
7444
while (sc->used_tx_bd < sc->max_tx_bd) {
7445
/* Check for any frames to send. */
7446
m_head = if_dequeue(ifp);
7447
7448
/* Stop when the transmit queue is empty. */
7449
if (m_head == NULL)
7450
break;
7451
7452
/*
7453
* Pack the data into the transmit ring. If we
7454
* don't have room, place the mbuf back at the
7455
* head of the queue and set the OACTIVE flag
7456
* to wait for the NIC to drain the chain.
7457
*/
7458
if (bce_tx_encap(sc, &m_head)) {
7459
if (m_head != NULL)
7460
if_sendq_prepend(ifp, m_head);
7461
if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
7462
DBPRINT(sc, BCE_INFO_SEND,
7463
"TX chain is closed for business! Total "
7464
"tx_bd used = %d\n", sc->used_tx_bd);
7465
break;
7466
}
7467
7468
count++;
7469
7470
/* Send a copy of the frame to any BPF listeners. */
7471
ETHER_BPF_MTAP(ifp, m_head);
7472
}
7473
7474
/* Exit if no packets were dequeued. */
7475
if (count == 0) {
7476
DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
7477
"dequeued\n", __FUNCTION__);
7478
goto bce_start_locked_exit;
7479
}
7480
7481
DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
7482
"send queue.\n", __FUNCTION__, count);
7483
7484
/* Set the tx timeout. */
7485
sc->watchdog_timer = BCE_TX_TIMEOUT;
7486
7487
DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
7488
DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
7489
7490
bce_start_locked_exit:
7491
DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7492
}
7493
7494
/****************************************************************************/
7495
/* Main transmit routine when called from another routine without a lock. */
7496
/* */
7497
/* Returns: */
7498
/* Nothing. */
7499
/****************************************************************************/
7500
static void
7501
bce_start(if_t ifp)
7502
{
7503
struct bce_softc *sc = if_getsoftc(ifp);
7504
7505
DBENTER(BCE_VERBOSE_SEND);
7506
7507
BCE_LOCK(sc);
7508
bce_start_locked(ifp);
7509
BCE_UNLOCK(sc);
7510
7511
DBEXIT(BCE_VERBOSE_SEND);
7512
}
7513
7514
/****************************************************************************/
7515
/* Handles any IOCTL calls from the operating system. */
7516
/* */
7517
/* Returns: */
7518
/* 0 for success, positive value for failure. */
7519
/****************************************************************************/
7520
static int
7521
bce_ioctl(if_t ifp, u_long command, caddr_t data)
7522
{
7523
struct bce_softc *sc = if_getsoftc(ifp);
7524
struct ifreq *ifr = (struct ifreq *) data;
7525
struct mii_data *mii;
7526
int mask, error = 0;
7527
7528
DBENTER(BCE_VERBOSE_MISC);
7529
7530
switch(command) {
7531
/* Set the interface MTU. */
7532
case SIOCSIFMTU:
7533
/* Check that the MTU setting is supported. */
7534
if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7535
(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7536
error = EINVAL;
7537
break;
7538
}
7539
7540
DBPRINT(sc, BCE_INFO_MISC,
7541
"SIOCSIFMTU: Changing MTU from %d to %d\n",
7542
(int) if_getmtu(ifp), (int) ifr->ifr_mtu);
7543
7544
BCE_LOCK(sc);
7545
if_setmtu(ifp, ifr->ifr_mtu);
7546
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7547
if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
7548
bce_init_locked(sc);
7549
}
7550
BCE_UNLOCK(sc);
7551
break;
7552
7553
/* Set interface flags. */
7554
case SIOCSIFFLAGS:
7555
DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7556
7557
BCE_LOCK(sc);
7558
7559
/* Check if the interface is up. */
7560
if (if_getflags(ifp) & IFF_UP) {
7561
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7562
/* Change promiscuous/multicast flags as necessary. */
7563
bce_set_rx_mode(sc);
7564
} else {
7565
/* Start the HW */
7566
bce_init_locked(sc);
7567
}
7568
} else {
7569
/* The interface is down, check if driver is running. */
7570
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7571
bce_stop(sc);
7572
7573
/* If MFW is running, restart the controller a bit. */
7574
if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7575
bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7576
bce_chipinit(sc);
7577
bce_mgmt_init_locked(sc);
7578
}
7579
}
7580
}
7581
7582
BCE_UNLOCK(sc);
7583
break;
7584
7585
/* Add/Delete multicast address */
7586
case SIOCADDMULTI:
7587
case SIOCDELMULTI:
7588
DBPRINT(sc, BCE_VERBOSE_MISC,
7589
"Received SIOCADDMULTI/SIOCDELMULTI\n");
7590
7591
BCE_LOCK(sc);
7592
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
7593
bce_set_rx_mode(sc);
7594
BCE_UNLOCK(sc);
7595
7596
break;
7597
7598
/* Set/Get Interface media */
7599
case SIOCSIFMEDIA:
7600
case SIOCGIFMEDIA:
7601
DBPRINT(sc, BCE_VERBOSE_MISC,
7602
"Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7603
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
7604
error = ifmedia_ioctl(ifp, ifr, &sc->bce_ifmedia,
7605
command);
7606
else {
7607
mii = device_get_softc(sc->bce_miibus);
7608
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
7609
command);
7610
}
7611
break;
7612
7613
/* Set interface capability */
7614
case SIOCSIFCAP:
7615
mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
7616
DBPRINT(sc, BCE_INFO_MISC,
7617
"Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7618
7619
/* Toggle the TX checksum capabilities enable flag. */
7620
if (mask & IFCAP_TXCSUM &&
7621
if_getcapabilities(ifp) & IFCAP_TXCSUM) {
7622
if_togglecapenable(ifp, IFCAP_TXCSUM);
7623
if (IFCAP_TXCSUM & if_getcapenable(ifp))
7624
if_sethwassistbits(ifp, BCE_IF_HWASSIST, 0);
7625
else
7626
if_sethwassistbits(ifp, 0, BCE_IF_HWASSIST);
7627
}
7628
7629
/* Toggle the RX checksum capabilities enable flag. */
7630
if (mask & IFCAP_RXCSUM &&
7631
if_getcapabilities(ifp) & IFCAP_RXCSUM)
7632
if_togglecapenable(ifp, IFCAP_RXCSUM);
7633
7634
/* Toggle the TSO capabilities enable flag. */
7635
if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7636
if_getcapabilities(ifp) & IFCAP_TSO4) {
7637
if_togglecapenable(ifp, IFCAP_TSO4);
7638
if (IFCAP_TSO4 & if_getcapenable(ifp))
7639
if_sethwassistbits(ifp, CSUM_TSO, 0);
7640
else
7641
if_sethwassistbits(ifp, 0, CSUM_TSO);
7642
}
7643
7644
if (mask & IFCAP_VLAN_HWCSUM &&
7645
if_getcapabilities(ifp) & IFCAP_VLAN_HWCSUM)
7646
if_togglecapenable(ifp, IFCAP_VLAN_HWCSUM);
7647
7648
if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
7649
(if_getcapabilities(ifp) & IFCAP_VLAN_HWTSO) != 0)
7650
if_togglecapenable(ifp, IFCAP_VLAN_HWTSO);
7651
/*
7652
* Don't actually disable VLAN tag stripping as
7653
* management firmware (ASF/IPMI/UMP) requires the
7654
* feature. If VLAN tag stripping is disabled driver
7655
* will manually reconstruct the VLAN frame by
7656
* appending stripped VLAN tag.
7657
*/
7658
if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7659
(if_getcapabilities(ifp) & IFCAP_VLAN_HWTAGGING)) {
7660
if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING);
7661
if ((if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING)
7662
== 0)
7663
if_setcapenablebit(ifp, 0, IFCAP_VLAN_HWTSO);
7664
}
7665
VLAN_CAPABILITIES(ifp);
7666
break;
7667
default:
7668
/* We don't know how to handle the IOCTL, pass it on. */
7669
error = ether_ioctl(ifp, command, data);
7670
break;
7671
}
7672
7673
DBEXIT(BCE_VERBOSE_MISC);
7674
return(error);
7675
}
7676
7677
/****************************************************************************/
7678
/* Transmit timeout handler. */
7679
/* */
7680
/* Returns: */
7681
/* Nothing. */
7682
/****************************************************************************/
7683
static void
7684
bce_watchdog(struct bce_softc *sc)
7685
{
7686
uint32_t status;
7687
7688
DBENTER(BCE_EXTREME_SEND);
7689
7690
BCE_LOCK_ASSERT(sc);
7691
7692
status = 0;
7693
/* If the watchdog timer hasn't expired then just exit. */
7694
if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7695
goto bce_watchdog_exit;
7696
7697
status = REG_RD(sc, BCE_EMAC_RX_STATUS);
7698
/* If pause frames are active then don't reset the hardware. */
7699
if ((sc->bce_flags & BCE_USING_RX_FLOW_CONTROL) != 0) {
7700
if ((status & BCE_EMAC_RX_STATUS_FFED) != 0) {
7701
/*
7702
* If link partner has us in XOFF state then wait for
7703
* the condition to clear.
7704
*/
7705
sc->watchdog_timer = BCE_TX_TIMEOUT;
7706
goto bce_watchdog_exit;
7707
} else if ((status & BCE_EMAC_RX_STATUS_FF_RECEIVED) != 0 &&
7708
(status & BCE_EMAC_RX_STATUS_N_RECEIVED) != 0) {
7709
/*
7710
* If we're not currently XOFF'ed but have recently
7711
* been XOFF'd/XON'd then assume that's delaying TX
7712
* this time around.
7713
*/
7714
sc->watchdog_timer = BCE_TX_TIMEOUT;
7715
goto bce_watchdog_exit;
7716
}
7717
/*
7718
* Any other condition is unexpected and the controller
7719
* should be reset.
7720
*/
7721
}
7722
7723
BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7724
__FILE__, __LINE__);
7725
7726
DBRUNMSG(BCE_INFO,
7727
bce_dump_driver_state(sc);
7728
bce_dump_status_block(sc);
7729
bce_dump_stats_block(sc);
7730
bce_dump_ftqs(sc);
7731
bce_dump_txp_state(sc, 0);
7732
bce_dump_rxp_state(sc, 0);
7733
bce_dump_tpat_state(sc, 0);
7734
bce_dump_cp_state(sc, 0);
7735
bce_dump_com_state(sc, 0));
7736
7737
DBRUN(bce_breakpoint(sc));
7738
7739
if_setdrvflagbits(sc->bce_ifp, 0, IFF_DRV_RUNNING);
7740
7741
bce_init_locked(sc);
7742
sc->watchdog_timeouts++;
7743
7744
bce_watchdog_exit:
7745
REG_WR(sc, BCE_EMAC_RX_STATUS, status);
7746
DBEXIT(BCE_EXTREME_SEND);
7747
}
7748
7749
/*
7750
* Interrupt handler.
7751
*/
7752
/****************************************************************************/
7753
/* Main interrupt entry point. Verifies that the controller generated the */
7754
/* interrupt and then calls a separate routine for handle the various */
7755
/* interrupt causes (PHY, TX, RX). */
7756
/* */
7757
/* Returns: */
7758
/* Nothing. */
7759
/****************************************************************************/
7760
static void
7761
bce_intr(void *xsc)
7762
{
7763
struct bce_softc *sc;
7764
if_t ifp;
7765
u32 status_attn_bits;
7766
u16 hw_rx_cons, hw_tx_cons;
7767
7768
sc = xsc;
7769
ifp = sc->bce_ifp;
7770
7771
DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7772
DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7773
DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
7774
7775
BCE_LOCK(sc);
7776
7777
DBRUN(sc->interrupts_generated++);
7778
7779
/* Synchnorize before we read from interface's status block */
7780
bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
7781
7782
/*
7783
* If the hardware status block index matches the last value read
7784
* by the driver and we haven't asserted our interrupt then there's
7785
* nothing to do. This may only happen in case of INTx due to the
7786
* interrupt arriving at the CPU before the status block is updated.
7787
*/
7788
if ((sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) == 0 &&
7789
sc->status_block->status_idx == sc->last_status_idx &&
7790
(REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
7791
BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7792
DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7793
__FUNCTION__);
7794
goto bce_intr_exit;
7795
}
7796
7797
/* Ack the interrupt and stop others from occurring. */
7798
REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7799
BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7800
BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7801
7802
/* Check if the hardware has finished any work. */
7803
hw_rx_cons = bce_get_hw_rx_cons(sc);
7804
hw_tx_cons = bce_get_hw_tx_cons(sc);
7805
7806
/* Keep processing data as long as there is work to do. */
7807
for (;;) {
7808
status_attn_bits = sc->status_block->status_attn_bits;
7809
7810
DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7811
BCE_PRINTF("Simulating unexpected status attention "
7812
"bit set.");
7813
sc->unexpected_attention_sim_count++;
7814
status_attn_bits = status_attn_bits |
7815
STATUS_ATTN_BITS_PARITY_ERROR);
7816
7817
/* Was it a link change interrupt? */
7818
if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7819
(sc->status_block->status_attn_bits_ack &
7820
STATUS_ATTN_BITS_LINK_STATE)) {
7821
bce_phy_intr(sc);
7822
7823
/* Clear transient updates during link state change. */
7824
REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
7825
BCE_HC_COMMAND_COAL_NOW_WO_INT);
7826
REG_RD(sc, BCE_HC_COMMAND);
7827
}
7828
7829
/* If any other attention is asserted, the chip is toast. */
7830
if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7831
(sc->status_block->status_attn_bits_ack &
7832
~STATUS_ATTN_BITS_LINK_STATE))) {
7833
sc->unexpected_attention_count++;
7834
7835
BCE_PRINTF("%s(%d): Fatal attention detected: "
7836
"0x%08X\n", __FILE__, __LINE__,
7837
sc->status_block->status_attn_bits);
7838
7839
DBRUNMSG(BCE_FATAL,
7840
if (unexpected_attention_sim_control == 0)
7841
bce_breakpoint(sc));
7842
7843
bce_init_locked(sc);
7844
goto bce_intr_exit;
7845
}
7846
7847
/* Check for any completed RX frames. */
7848
if (hw_rx_cons != sc->hw_rx_cons)
7849
bce_rx_intr(sc);
7850
7851
/* Check for any completed TX frames. */
7852
if (hw_tx_cons != sc->hw_tx_cons)
7853
bce_tx_intr(sc);
7854
7855
/* Save status block index value for the next interrupt. */
7856
sc->last_status_idx = sc->status_block->status_idx;
7857
7858
/*
7859
* Prevent speculative reads from getting
7860
* ahead of the status block.
7861
*/
7862
bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7863
BUS_SPACE_BARRIER_READ);
7864
7865
/*
7866
* If there's no work left then exit the
7867
* interrupt service routine.
7868
*/
7869
hw_rx_cons = bce_get_hw_rx_cons(sc);
7870
hw_tx_cons = bce_get_hw_tx_cons(sc);
7871
7872
if ((hw_rx_cons == sc->hw_rx_cons) &&
7873
(hw_tx_cons == sc->hw_tx_cons))
7874
break;
7875
}
7876
7877
bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_PREREAD);
7878
7879
/* Re-enable interrupts. */
7880
bce_enable_intr(sc, 0);
7881
7882
/* Handle any frames that arrived while handling the interrupt. */
7883
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING &&
7884
!if_sendq_empty(ifp))
7885
bce_start_locked(ifp);
7886
7887
bce_intr_exit:
7888
BCE_UNLOCK(sc);
7889
7890
DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7891
}
7892
7893
/****************************************************************************/
7894
/* Programs the various packet receive modes (broadcast and multicast). */
7895
/* */
7896
/* Returns: */
7897
/* Nothing. */
7898
/****************************************************************************/
7899
static u_int
7900
bce_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
7901
{
7902
u32 *hashes = arg;
7903
int h;
7904
7905
h = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0xFF;
7906
hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7907
7908
return (1);
7909
}
7910
7911
static void
7912
bce_set_rx_mode(struct bce_softc *sc)
7913
{
7914
if_t ifp;
7915
u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7916
u32 rx_mode, sort_mode;
7917
int i;
7918
7919
DBENTER(BCE_VERBOSE_MISC);
7920
7921
BCE_LOCK_ASSERT(sc);
7922
7923
ifp = sc->bce_ifp;
7924
7925
/* Initialize receive mode default settings. */
7926
rx_mode = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7927
BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7928
sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7929
7930
/*
7931
* ASF/IPMI/UMP firmware requires that VLAN tag stripping
7932
* be enbled.
7933
*/
7934
if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7935
(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7936
rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7937
7938
/*
7939
* Check for promiscuous, all multicast, or selected
7940
* multicast address filtering.
7941
*/
7942
if (if_getflags(ifp) & IFF_PROMISC) {
7943
DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7944
7945
/* Enable promiscuous mode. */
7946
rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7947
sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7948
} else if (if_getflags(ifp) & IFF_ALLMULTI) {
7949
DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7950
7951
/* Enable all multicast addresses. */
7952
for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7953
REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
7954
0xffffffff);
7955
}
7956
sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7957
} else {
7958
/* Accept one or more multicast(s). */
7959
DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7960
if_foreach_llmaddr(ifp, bce_hash_maddr, hashes);
7961
7962
for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7963
REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7964
7965
sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7966
}
7967
7968
/* Only make changes if the recive mode has actually changed. */
7969
if (rx_mode != sc->rx_mode) {
7970
DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
7971
"0x%08X\n", rx_mode);
7972
7973
sc->rx_mode = rx_mode;
7974
REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7975
}
7976
7977
/* Disable and clear the existing sort before enabling a new sort. */
7978
REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7979
REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7980
REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7981
7982
DBEXIT(BCE_VERBOSE_MISC);
7983
}
7984
7985
/****************************************************************************/
7986
/* Called periodically to updates statistics from the controllers */
7987
/* statistics block. */
7988
/* */
7989
/* Returns: */
7990
/* Nothing. */
7991
/****************************************************************************/
7992
static void
7993
bce_stats_update(struct bce_softc *sc)
7994
{
7995
struct statistics_block *stats;
7996
7997
DBENTER(BCE_EXTREME_MISC);
7998
7999
bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
8000
8001
stats = (struct statistics_block *) sc->stats_block;
8002
8003
/*
8004
* Update the sysctl statistics from the
8005
* hardware statistics.
8006
*/
8007
sc->stat_IfHCInOctets =
8008
((u64) stats->stat_IfHCInOctets_hi << 32) +
8009
(u64) stats->stat_IfHCInOctets_lo;
8010
8011
sc->stat_IfHCInBadOctets =
8012
((u64) stats->stat_IfHCInBadOctets_hi << 32) +
8013
(u64) stats->stat_IfHCInBadOctets_lo;
8014
8015
sc->stat_IfHCOutOctets =
8016
((u64) stats->stat_IfHCOutOctets_hi << 32) +
8017
(u64) stats->stat_IfHCOutOctets_lo;
8018
8019
sc->stat_IfHCOutBadOctets =
8020
((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
8021
(u64) stats->stat_IfHCOutBadOctets_lo;
8022
8023
sc->stat_IfHCInUcastPkts =
8024
((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
8025
(u64) stats->stat_IfHCInUcastPkts_lo;
8026
8027
sc->stat_IfHCInMulticastPkts =
8028
((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
8029
(u64) stats->stat_IfHCInMulticastPkts_lo;
8030
8031
sc->stat_IfHCInBroadcastPkts =
8032
((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
8033
(u64) stats->stat_IfHCInBroadcastPkts_lo;
8034
8035
sc->stat_IfHCOutUcastPkts =
8036
((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
8037
(u64) stats->stat_IfHCOutUcastPkts_lo;
8038
8039
sc->stat_IfHCOutMulticastPkts =
8040
((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
8041
(u64) stats->stat_IfHCOutMulticastPkts_lo;
8042
8043
sc->stat_IfHCOutBroadcastPkts =
8044
((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
8045
(u64) stats->stat_IfHCOutBroadcastPkts_lo;
8046
8047
/* ToDo: Preserve counters beyond 32 bits? */
8048
/* ToDo: Read the statistics from auto-clear regs? */
8049
8050
sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
8051
stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
8052
8053
sc->stat_Dot3StatsCarrierSenseErrors =
8054
stats->stat_Dot3StatsCarrierSenseErrors;
8055
8056
sc->stat_Dot3StatsFCSErrors =
8057
stats->stat_Dot3StatsFCSErrors;
8058
8059
sc->stat_Dot3StatsAlignmentErrors =
8060
stats->stat_Dot3StatsAlignmentErrors;
8061
8062
sc->stat_Dot3StatsSingleCollisionFrames =
8063
stats->stat_Dot3StatsSingleCollisionFrames;
8064
8065
sc->stat_Dot3StatsMultipleCollisionFrames =
8066
stats->stat_Dot3StatsMultipleCollisionFrames;
8067
8068
sc->stat_Dot3StatsDeferredTransmissions =
8069
stats->stat_Dot3StatsDeferredTransmissions;
8070
8071
sc->stat_Dot3StatsExcessiveCollisions =
8072
stats->stat_Dot3StatsExcessiveCollisions;
8073
8074
sc->stat_Dot3StatsLateCollisions =
8075
stats->stat_Dot3StatsLateCollisions;
8076
8077
sc->stat_EtherStatsCollisions =
8078
stats->stat_EtherStatsCollisions;
8079
8080
sc->stat_EtherStatsFragments =
8081
stats->stat_EtherStatsFragments;
8082
8083
sc->stat_EtherStatsJabbers =
8084
stats->stat_EtherStatsJabbers;
8085
8086
sc->stat_EtherStatsUndersizePkts =
8087
stats->stat_EtherStatsUndersizePkts;
8088
8089
sc->stat_EtherStatsOversizePkts =
8090
stats->stat_EtherStatsOversizePkts;
8091
8092
sc->stat_EtherStatsPktsRx64Octets =
8093
stats->stat_EtherStatsPktsRx64Octets;
8094
8095
sc->stat_EtherStatsPktsRx65Octetsto127Octets =
8096
stats->stat_EtherStatsPktsRx65Octetsto127Octets;
8097
8098
sc->stat_EtherStatsPktsRx128Octetsto255Octets =
8099
stats->stat_EtherStatsPktsRx128Octetsto255Octets;
8100
8101
sc->stat_EtherStatsPktsRx256Octetsto511Octets =
8102
stats->stat_EtherStatsPktsRx256Octetsto511Octets;
8103
8104
sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
8105
stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
8106
8107
sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
8108
stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
8109
8110
sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
8111
stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
8112
8113
sc->stat_EtherStatsPktsTx64Octets =
8114
stats->stat_EtherStatsPktsTx64Octets;
8115
8116
sc->stat_EtherStatsPktsTx65Octetsto127Octets =
8117
stats->stat_EtherStatsPktsTx65Octetsto127Octets;
8118
8119
sc->stat_EtherStatsPktsTx128Octetsto255Octets =
8120
stats->stat_EtherStatsPktsTx128Octetsto255Octets;
8121
8122
sc->stat_EtherStatsPktsTx256Octetsto511Octets =
8123
stats->stat_EtherStatsPktsTx256Octetsto511Octets;
8124
8125
sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
8126
stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
8127
8128
sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
8129
stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
8130
8131
sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
8132
stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
8133
8134
sc->stat_XonPauseFramesReceived =
8135
stats->stat_XonPauseFramesReceived;
8136
8137
sc->stat_XoffPauseFramesReceived =
8138
stats->stat_XoffPauseFramesReceived;
8139
8140
sc->stat_OutXonSent =
8141
stats->stat_OutXonSent;
8142
8143
sc->stat_OutXoffSent =
8144
stats->stat_OutXoffSent;
8145
8146
sc->stat_FlowControlDone =
8147
stats->stat_FlowControlDone;
8148
8149
sc->stat_MacControlFramesReceived =
8150
stats->stat_MacControlFramesReceived;
8151
8152
sc->stat_XoffStateEntered =
8153
stats->stat_XoffStateEntered;
8154
8155
sc->stat_IfInFramesL2FilterDiscards =
8156
stats->stat_IfInFramesL2FilterDiscards;
8157
8158
sc->stat_IfInRuleCheckerDiscards =
8159
stats->stat_IfInRuleCheckerDiscards;
8160
8161
sc->stat_IfInFTQDiscards =
8162
stats->stat_IfInFTQDiscards;
8163
8164
sc->stat_IfInMBUFDiscards =
8165
stats->stat_IfInMBUFDiscards;
8166
8167
sc->stat_IfInRuleCheckerP4Hit =
8168
stats->stat_IfInRuleCheckerP4Hit;
8169
8170
sc->stat_CatchupInRuleCheckerDiscards =
8171
stats->stat_CatchupInRuleCheckerDiscards;
8172
8173
sc->stat_CatchupInFTQDiscards =
8174
stats->stat_CatchupInFTQDiscards;
8175
8176
sc->stat_CatchupInMBUFDiscards =
8177
stats->stat_CatchupInMBUFDiscards;
8178
8179
sc->stat_CatchupInRuleCheckerP4Hit =
8180
stats->stat_CatchupInRuleCheckerP4Hit;
8181
8182
sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
8183
8184
/* ToDo: Add additional statistics? */
8185
8186
DBEXIT(BCE_EXTREME_MISC);
8187
}
8188
8189
static uint64_t
8190
bce_get_counter(if_t ifp, ift_counter cnt)
8191
{
8192
struct bce_softc *sc;
8193
uint64_t rv;
8194
8195
sc = if_getsoftc(ifp);
8196
8197
switch (cnt) {
8198
case IFCOUNTER_COLLISIONS:
8199
return (sc->stat_EtherStatsCollisions);
8200
case IFCOUNTER_IERRORS:
8201
return (sc->stat_EtherStatsUndersizePkts +
8202
sc->stat_EtherStatsOversizePkts +
8203
sc->stat_IfInMBUFDiscards +
8204
sc->stat_Dot3StatsAlignmentErrors +
8205
sc->stat_Dot3StatsFCSErrors +
8206
sc->stat_IfInRuleCheckerDiscards +
8207
sc->stat_IfInFTQDiscards +
8208
sc->l2fhdr_error_count +
8209
sc->com_no_buffers);
8210
case IFCOUNTER_OERRORS:
8211
rv = sc->stat_Dot3StatsExcessiveCollisions +
8212
sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
8213
sc->stat_Dot3StatsLateCollisions +
8214
sc->watchdog_timeouts;
8215
/*
8216
* Certain controllers don't report
8217
* carrier sense errors correctly.
8218
* See errata E11_5708CA0_1165.
8219
*/
8220
if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
8221
!(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
8222
rv += sc->stat_Dot3StatsCarrierSenseErrors;
8223
return (rv);
8224
default:
8225
return (if_get_counter_default(ifp, cnt));
8226
}
8227
}
8228
8229
/****************************************************************************/
8230
/* Periodic function to notify the bootcode that the driver is still */
8231
/* present. */
8232
/* */
8233
/* Returns: */
8234
/* Nothing. */
8235
/****************************************************************************/
8236
static void
8237
bce_pulse(void *xsc)
8238
{
8239
struct bce_softc *sc = xsc;
8240
u32 msg;
8241
8242
DBENTER(BCE_EXTREME_MISC);
8243
8244
BCE_LOCK_ASSERT(sc);
8245
8246
/* Tell the firmware that the driver is still running. */
8247
msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
8248
bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
8249
8250
/* Update the bootcode condition. */
8251
sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
8252
8253
/* Report whether the bootcode still knows the driver is running. */
8254
if (bce_verbose || bootverbose) {
8255
if (sc->bce_drv_cardiac_arrest == FALSE) {
8256
if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
8257
sc->bce_drv_cardiac_arrest = TRUE;
8258
BCE_PRINTF("%s(): Warning: bootcode "
8259
"thinks driver is absent! "
8260
"(bc_state = 0x%08X)\n",
8261
__FUNCTION__, sc->bc_state);
8262
}
8263
} else {
8264
/*
8265
* Not supported by all bootcode versions.
8266
* (v5.0.11+ and v5.2.1+) Older bootcode
8267
* will require the driver to reset the
8268
* controller to clear this condition.
8269
*/
8270
if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
8271
sc->bce_drv_cardiac_arrest = FALSE;
8272
BCE_PRINTF("%s(): Bootcode found the "
8273
"driver pulse! (bc_state = 0x%08X)\n",
8274
__FUNCTION__, sc->bc_state);
8275
}
8276
}
8277
}
8278
8279
/* Schedule the next pulse. */
8280
callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
8281
8282
DBEXIT(BCE_EXTREME_MISC);
8283
}
8284
8285
/****************************************************************************/
8286
/* Periodic function to perform maintenance tasks. */
8287
/* */
8288
/* Returns: */
8289
/* Nothing. */
8290
/****************************************************************************/
8291
static void
8292
bce_tick(void *xsc)
8293
{
8294
struct bce_softc *sc = xsc;
8295
struct mii_data *mii;
8296
if_t ifp;
8297
struct ifmediareq ifmr;
8298
8299
ifp = sc->bce_ifp;
8300
8301
DBENTER(BCE_EXTREME_MISC);
8302
8303
BCE_LOCK_ASSERT(sc);
8304
8305
/* Schedule the next tick. */
8306
callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
8307
8308
/* Update the statistics from the hardware statistics block. */
8309
bce_stats_update(sc);
8310
8311
/* Ensure page and RX chains get refilled in low-memory situations. */
8312
if (bce_hdr_split == TRUE)
8313
bce_fill_pg_chain(sc);
8314
bce_fill_rx_chain(sc);
8315
8316
/* Check that chip hasn't hung. */
8317
bce_watchdog(sc);
8318
8319
/* If link is up already up then we're done. */
8320
if (sc->bce_link_up == TRUE)
8321
goto bce_tick_exit;
8322
8323
/* Link is down. Check what the PHY's doing. */
8324
if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
8325
bzero(&ifmr, sizeof(ifmr));
8326
bce_ifmedia_sts_rphy(sc, &ifmr);
8327
if ((ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
8328
(IFM_ACTIVE | IFM_AVALID)) {
8329
sc->bce_link_up = TRUE;
8330
bce_miibus_statchg(sc->bce_dev);
8331
}
8332
} else {
8333
mii = device_get_softc(sc->bce_miibus);
8334
mii_tick(mii);
8335
/* Check if the link has come up. */
8336
if ((mii->mii_media_status & IFM_ACTIVE) &&
8337
(IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
8338
DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n",
8339
__FUNCTION__);
8340
sc->bce_link_up = TRUE;
8341
if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
8342
IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
8343
IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
8344
(bce_verbose || bootverbose))
8345
BCE_PRINTF("Gigabit link up!\n");
8346
}
8347
}
8348
if (sc->bce_link_up == TRUE) {
8349
/* Now that link is up, handle any outstanding TX traffic. */
8350
if (!if_sendq_empty(ifp)) {
8351
DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
8352
"pending TX traffic.\n", __FUNCTION__);
8353
bce_start_locked(ifp);
8354
}
8355
}
8356
8357
bce_tick_exit:
8358
DBEXIT(BCE_EXTREME_MISC);
8359
}
8360
8361
static void
8362
bce_fw_cap_init(struct bce_softc *sc)
8363
{
8364
u32 ack, cap, link;
8365
8366
ack = 0;
8367
cap = bce_shmem_rd(sc, BCE_FW_CAP_MB);
8368
if ((cap & BCE_FW_CAP_SIGNATURE_MAGIC_MASK) !=
8369
BCE_FW_CAP_SIGNATURE_MAGIC)
8370
return;
8371
if ((cap & (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN)) ==
8372
(BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN))
8373
ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8374
BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN;
8375
if ((sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) != 0 &&
8376
(cap & BCE_FW_CAP_REMOTE_PHY_CAP) != 0) {
8377
sc->bce_phy_flags &= ~BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8378
sc->bce_phy_flags |= BCE_PHY_REMOTE_CAP_FLAG;
8379
link = bce_shmem_rd(sc, BCE_LINK_STATUS);
8380
if ((link & BCE_LINK_STATUS_SERDES_LINK) != 0)
8381
sc->bce_phy_flags |= BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8382
ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8383
BCE_FW_CAP_REMOTE_PHY_CAP;
8384
}
8385
8386
if (ack != 0)
8387
bce_shmem_wr(sc, BCE_DRV_ACK_CAP_MB, ack);
8388
}
8389
8390
#ifdef BCE_DEBUG
8391
/****************************************************************************/
8392
/* Allows the driver state to be dumped through the sysctl interface. */
8393
/* */
8394
/* Returns: */
8395
/* 0 for success, positive value for failure. */
8396
/****************************************************************************/
8397
static int
8398
bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
8399
{
8400
int error;
8401
int result;
8402
struct bce_softc *sc;
8403
8404
result = -1;
8405
error = sysctl_handle_int(oidp, &result, 0, req);
8406
8407
if (error || !req->newptr)
8408
return (error);
8409
8410
if (result == 1) {
8411
sc = (struct bce_softc *)arg1;
8412
bce_dump_driver_state(sc);
8413
}
8414
8415
return error;
8416
}
8417
8418
/****************************************************************************/
8419
/* Allows the hardware state to be dumped through the sysctl interface. */
8420
/* */
8421
/* Returns: */
8422
/* 0 for success, positive value for failure. */
8423
/****************************************************************************/
8424
static int
8425
bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
8426
{
8427
int error;
8428
int result;
8429
struct bce_softc *sc;
8430
8431
result = -1;
8432
error = sysctl_handle_int(oidp, &result, 0, req);
8433
8434
if (error || !req->newptr)
8435
return (error);
8436
8437
if (result == 1) {
8438
sc = (struct bce_softc *)arg1;
8439
bce_dump_hw_state(sc);
8440
}
8441
8442
return error;
8443
}
8444
8445
/****************************************************************************/
8446
/* Allows the status block to be dumped through the sysctl interface. */
8447
/* */
8448
/* Returns: */
8449
/* 0 for success, positive value for failure. */
8450
/****************************************************************************/
8451
static int
8452
bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
8453
{
8454
int error;
8455
int result;
8456
struct bce_softc *sc;
8457
8458
result = -1;
8459
error = sysctl_handle_int(oidp, &result, 0, req);
8460
8461
if (error || !req->newptr)
8462
return (error);
8463
8464
if (result == 1) {
8465
sc = (struct bce_softc *)arg1;
8466
bce_dump_status_block(sc);
8467
}
8468
8469
return error;
8470
}
8471
8472
/****************************************************************************/
8473
/* Allows the stats block to be dumped through the sysctl interface. */
8474
/* */
8475
/* Returns: */
8476
/* 0 for success, positive value for failure. */
8477
/****************************************************************************/
8478
static int
8479
bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
8480
{
8481
int error;
8482
int result;
8483
struct bce_softc *sc;
8484
8485
result = -1;
8486
error = sysctl_handle_int(oidp, &result, 0, req);
8487
8488
if (error || !req->newptr)
8489
return (error);
8490
8491
if (result == 1) {
8492
sc = (struct bce_softc *)arg1;
8493
bce_dump_stats_block(sc);
8494
}
8495
8496
return error;
8497
}
8498
8499
/****************************************************************************/
8500
/* Allows the stat counters to be cleared without unloading/reloading the */
8501
/* driver. */
8502
/* */
8503
/* Returns: */
8504
/* 0 for success, positive value for failure. */
8505
/****************************************************************************/
8506
static int
8507
bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS)
8508
{
8509
int error;
8510
int result;
8511
struct bce_softc *sc;
8512
8513
result = -1;
8514
error = sysctl_handle_int(oidp, &result, 0, req);
8515
8516
if (error || !req->newptr)
8517
return (error);
8518
8519
if (result == 1) {
8520
sc = (struct bce_softc *)arg1;
8521
struct statistics_block *stats;
8522
8523
stats = (struct statistics_block *) sc->stats_block;
8524
bzero(stats, sizeof(struct statistics_block));
8525
bus_dmamap_sync(sc->stats_tag, sc->stats_map,
8526
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
8527
8528
/* Clear the internal H/W statistics counters. */
8529
REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
8530
8531
/* Reset the driver maintained statistics. */
8532
sc->interrupts_rx =
8533
sc->interrupts_tx = 0;
8534
sc->tso_frames_requested =
8535
sc->tso_frames_completed =
8536
sc->tso_frames_failed = 0;
8537
sc->rx_empty_count =
8538
sc->tx_full_count = 0;
8539
sc->rx_low_watermark = USABLE_RX_BD_ALLOC;
8540
sc->tx_hi_watermark = 0;
8541
sc->l2fhdr_error_count =
8542
sc->l2fhdr_error_sim_count = 0;
8543
sc->mbuf_alloc_failed_count =
8544
sc->mbuf_alloc_failed_sim_count = 0;
8545
sc->dma_map_addr_rx_failed_count =
8546
sc->dma_map_addr_tx_failed_count = 0;
8547
sc->mbuf_frag_count = 0;
8548
sc->csum_offload_tcp_udp =
8549
sc->csum_offload_ip = 0;
8550
sc->vlan_tagged_frames_rcvd =
8551
sc->vlan_tagged_frames_stripped = 0;
8552
sc->split_header_frames_rcvd =
8553
sc->split_header_tcp_frames_rcvd = 0;
8554
8555
/* Clear firmware maintained statistics. */
8556
REG_WR_IND(sc, 0x120084, 0);
8557
}
8558
8559
return error;
8560
}
8561
8562
/****************************************************************************/
8563
/* Allows the shared memory contents to be dumped through the sysctl . */
8564
/* interface. */
8565
/* */
8566
/* Returns: */
8567
/* 0 for success, positive value for failure. */
8568
/****************************************************************************/
8569
static int
8570
bce_sysctl_shmem_state(SYSCTL_HANDLER_ARGS)
8571
{
8572
int error;
8573
int result;
8574
struct bce_softc *sc;
8575
8576
result = -1;
8577
error = sysctl_handle_int(oidp, &result, 0, req);
8578
8579
if (error || !req->newptr)
8580
return (error);
8581
8582
if (result == 1) {
8583
sc = (struct bce_softc *)arg1;
8584
bce_dump_shmem_state(sc);
8585
}
8586
8587
return error;
8588
}
8589
8590
/****************************************************************************/
8591
/* Allows the bootcode state to be dumped through the sysctl interface. */
8592
/* */
8593
/* Returns: */
8594
/* 0 for success, positive value for failure. */
8595
/****************************************************************************/
8596
static int
8597
bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
8598
{
8599
int error;
8600
int result;
8601
struct bce_softc *sc;
8602
8603
result = -1;
8604
error = sysctl_handle_int(oidp, &result, 0, req);
8605
8606
if (error || !req->newptr)
8607
return (error);
8608
8609
if (result == 1) {
8610
sc = (struct bce_softc *)arg1;
8611
bce_dump_bc_state(sc);
8612
}
8613
8614
return error;
8615
}
8616
8617
/****************************************************************************/
8618
/* Provides a sysctl interface to allow dumping the RX BD chain. */
8619
/* */
8620
/* Returns: */
8621
/* 0 for success, positive value for failure. */
8622
/****************************************************************************/
8623
static int
8624
bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
8625
{
8626
int error;
8627
int result;
8628
struct bce_softc *sc;
8629
8630
result = -1;
8631
error = sysctl_handle_int(oidp, &result, 0, req);
8632
8633
if (error || !req->newptr)
8634
return (error);
8635
8636
if (result == 1) {
8637
sc = (struct bce_softc *)arg1;
8638
bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC);
8639
}
8640
8641
return error;
8642
}
8643
8644
/****************************************************************************/
8645
/* Provides a sysctl interface to allow dumping the RX MBUF chain. */
8646
/* */
8647
/* Returns: */
8648
/* 0 for success, positive value for failure. */
8649
/****************************************************************************/
8650
static int
8651
bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
8652
{
8653
int error;
8654
int result;
8655
struct bce_softc *sc;
8656
8657
result = -1;
8658
error = sysctl_handle_int(oidp, &result, 0, req);
8659
8660
if (error || !req->newptr)
8661
return (error);
8662
8663
if (result == 1) {
8664
sc = (struct bce_softc *)arg1;
8665
bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
8666
}
8667
8668
return error;
8669
}
8670
8671
/****************************************************************************/
8672
/* Provides a sysctl interface to allow dumping the TX chain. */
8673
/* */
8674
/* Returns: */
8675
/* 0 for success, positive value for failure. */
8676
/****************************************************************************/
8677
static int
8678
bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
8679
{
8680
int error;
8681
int result;
8682
struct bce_softc *sc;
8683
8684
result = -1;
8685
error = sysctl_handle_int(oidp, &result, 0, req);
8686
8687
if (error || !req->newptr)
8688
return (error);
8689
8690
if (result == 1) {
8691
sc = (struct bce_softc *)arg1;
8692
bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC);
8693
}
8694
8695
return error;
8696
}
8697
8698
/****************************************************************************/
8699
/* Provides a sysctl interface to allow dumping the page chain. */
8700
/* */
8701
/* Returns: */
8702
/* 0 for success, positive value for failure. */
8703
/****************************************************************************/
8704
static int
8705
bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
8706
{
8707
int error;
8708
int result;
8709
struct bce_softc *sc;
8710
8711
result = -1;
8712
error = sysctl_handle_int(oidp, &result, 0, req);
8713
8714
if (error || !req->newptr)
8715
return (error);
8716
8717
if (result == 1) {
8718
sc = (struct bce_softc *)arg1;
8719
bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC);
8720
}
8721
8722
return error;
8723
}
8724
8725
/****************************************************************************/
8726
/* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in */
8727
/* the device. DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8728
/* */
8729
/* Returns: */
8730
/* 0 for success, positive value for failure. */
8731
/****************************************************************************/
8732
static int
8733
bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
8734
{
8735
struct bce_softc *sc = (struct bce_softc *)arg1;
8736
int error;
8737
u32 result;
8738
u32 val[1];
8739
u8 *data = (u8 *) val;
8740
8741
result = -1;
8742
error = sysctl_handle_int(oidp, &result, 0, req);
8743
if (error || (req->newptr == NULL))
8744
return (error);
8745
8746
error = bce_nvram_read(sc, result, data, 4);
8747
8748
BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
8749
8750
return (error);
8751
}
8752
8753
/****************************************************************************/
8754
/* Provides a sysctl interface to allow reading arbitrary registers in the */
8755
/* device. DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8756
/* */
8757
/* Returns: */
8758
/* 0 for success, positive value for failure. */
8759
/****************************************************************************/
8760
static int
8761
bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
8762
{
8763
struct bce_softc *sc = (struct bce_softc *)arg1;
8764
int error;
8765
u32 val, result;
8766
8767
result = -1;
8768
error = sysctl_handle_int(oidp, &result, 0, req);
8769
if (error || (req->newptr == NULL))
8770
return (error);
8771
8772
/* Make sure the register is accessible. */
8773
if (result < 0x8000) {
8774
val = REG_RD(sc, result);
8775
BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8776
} else if (result < 0x0280000) {
8777
val = REG_RD_IND(sc, result);
8778
BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8779
}
8780
8781
return (error);
8782
}
8783
8784
/****************************************************************************/
8785
/* Provides a sysctl interface to allow reading arbitrary PHY registers in */
8786
/* the device. DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8787
/* */
8788
/* Returns: */
8789
/* 0 for success, positive value for failure. */
8790
/****************************************************************************/
8791
static int
8792
bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
8793
{
8794
struct bce_softc *sc;
8795
device_t dev;
8796
int error, result;
8797
u16 val;
8798
8799
result = -1;
8800
error = sysctl_handle_int(oidp, &result, 0, req);
8801
if (error || (req->newptr == NULL))
8802
return (error);
8803
8804
/* Make sure the register is accessible. */
8805
if (result < 0x20) {
8806
sc = (struct bce_softc *)arg1;
8807
dev = sc->bce_dev;
8808
val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8809
BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8810
}
8811
return (error);
8812
}
8813
8814
/****************************************************************************/
8815
/* Provides a sysctl interface for dumping the nvram contents. */
8816
/* DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8817
/* */
8818
/* Returns: */
8819
/* 0 for success, positive errno for failure. */
8820
/****************************************************************************/
8821
static int
8822
bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
8823
{
8824
struct bce_softc *sc = (struct bce_softc *)arg1;
8825
int error, i;
8826
8827
if (sc->nvram_buf == NULL)
8828
sc->nvram_buf = malloc(sc->bce_flash_size,
8829
M_TEMP, M_ZERO | M_WAITOK);
8830
8831
error = 0;
8832
if (req->oldlen == sc->bce_flash_size) {
8833
for (i = 0; i < sc->bce_flash_size && error == 0; i++)
8834
error = bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
8835
}
8836
8837
if (error == 0)
8838
error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
8839
8840
return error;
8841
}
8842
8843
#ifdef BCE_NVRAM_WRITE_SUPPORT
8844
/****************************************************************************/
8845
/* Provides a sysctl interface for writing to nvram. */
8846
/* DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8847
/* */
8848
/* Returns: */
8849
/* 0 for success, positive errno for failure. */
8850
/****************************************************************************/
8851
static int
8852
bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
8853
{
8854
struct bce_softc *sc = (struct bce_softc *)arg1;
8855
int error;
8856
8857
if (sc->nvram_buf == NULL)
8858
sc->nvram_buf = malloc(sc->bce_flash_size,
8859
M_TEMP, M_ZERO | M_WAITOK);
8860
else
8861
bzero(sc->nvram_buf, sc->bce_flash_size);
8862
8863
error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
8864
if (error == 0)
8865
return (error);
8866
8867
if (req->newlen == sc->bce_flash_size)
8868
error = bce_nvram_write(sc, 0, sc->nvram_buf,
8869
sc->bce_flash_size);
8870
8871
return error;
8872
}
8873
#endif
8874
8875
/****************************************************************************/
8876
/* Provides a sysctl interface to allow reading a CID. */
8877
/* */
8878
/* Returns: */
8879
/* 0 for success, positive value for failure. */
8880
/****************************************************************************/
8881
static int
8882
bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
8883
{
8884
struct bce_softc *sc;
8885
int error, result;
8886
8887
result = -1;
8888
error = sysctl_handle_int(oidp, &result, 0, req);
8889
if (error || (req->newptr == NULL))
8890
return (error);
8891
8892
/* Make sure the register is accessible. */
8893
if (result <= TX_CID) {
8894
sc = (struct bce_softc *)arg1;
8895
bce_dump_ctx(sc, result);
8896
}
8897
8898
return (error);
8899
}
8900
8901
/****************************************************************************/
8902
/* Provides a sysctl interface to forcing the driver to dump state and */
8903
/* enter the debugger. DO NOT ENABLE ON PRODUCTION SYSTEMS! */
8904
/* */
8905
/* Returns: */
8906
/* 0 for success, positive value for failure. */
8907
/****************************************************************************/
8908
static int
8909
bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
8910
{
8911
int error;
8912
int result;
8913
struct bce_softc *sc;
8914
8915
result = -1;
8916
error = sysctl_handle_int(oidp, &result, 0, req);
8917
8918
if (error || !req->newptr)
8919
return (error);
8920
8921
if (result == 1) {
8922
sc = (struct bce_softc *)arg1;
8923
bce_breakpoint(sc);
8924
}
8925
8926
return error;
8927
}
8928
#endif
8929
8930
/****************************************************************************/
8931
/* Adds any sysctl parameters for tuning or debugging purposes. */
8932
/* */
8933
/* Returns: */
8934
/* 0 for success, positive value for failure. */
8935
/****************************************************************************/
8936
static void
8937
bce_add_sysctls(struct bce_softc *sc)
8938
{
8939
struct sysctl_ctx_list *ctx;
8940
struct sysctl_oid_list *children;
8941
8942
DBENTER(BCE_VERBOSE_MISC);
8943
8944
ctx = device_get_sysctl_ctx(sc->bce_dev);
8945
children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
8946
8947
#ifdef BCE_DEBUG
8948
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8949
"l2fhdr_error_sim_control",
8950
CTLFLAG_RW, &l2fhdr_error_sim_control,
8951
0, "Debug control to force l2fhdr errors");
8952
8953
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8954
"l2fhdr_error_sim_count",
8955
CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
8956
0, "Number of simulated l2_fhdr errors");
8957
#endif
8958
8959
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8960
"l2fhdr_error_count",
8961
CTLFLAG_RD, &sc->l2fhdr_error_count,
8962
0, "Number of l2_fhdr errors");
8963
8964
#ifdef BCE_DEBUG
8965
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8966
"mbuf_alloc_failed_sim_control",
8967
CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
8968
0, "Debug control to force mbuf allocation failures");
8969
8970
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8971
"mbuf_alloc_failed_sim_count",
8972
CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
8973
0, "Number of simulated mbuf cluster allocation failures");
8974
#endif
8975
8976
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8977
"mbuf_alloc_failed_count",
8978
CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
8979
0, "Number of mbuf allocation failures");
8980
8981
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8982
"mbuf_frag_count",
8983
CTLFLAG_RD, &sc->mbuf_frag_count,
8984
0, "Number of fragmented mbufs");
8985
8986
#ifdef BCE_DEBUG
8987
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8988
"dma_map_addr_failed_sim_control",
8989
CTLFLAG_RW, &dma_map_addr_failed_sim_control,
8990
0, "Debug control to force DMA mapping failures");
8991
8992
/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
8993
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8994
"dma_map_addr_failed_sim_count",
8995
CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
8996
0, "Number of simulated DMA mapping failures");
8997
8998
#endif
8999
9000
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9001
"dma_map_addr_rx_failed_count",
9002
CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
9003
0, "Number of RX DMA mapping failures");
9004
9005
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9006
"dma_map_addr_tx_failed_count",
9007
CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
9008
0, "Number of TX DMA mapping failures");
9009
9010
#ifdef BCE_DEBUG
9011
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9012
"unexpected_attention_sim_control",
9013
CTLFLAG_RW, &unexpected_attention_sim_control,
9014
0, "Debug control to simulate unexpected attentions");
9015
9016
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9017
"unexpected_attention_sim_count",
9018
CTLFLAG_RW, &sc->unexpected_attention_sim_count,
9019
0, "Number of simulated unexpected attentions");
9020
#endif
9021
9022
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9023
"unexpected_attention_count",
9024
CTLFLAG_RW, &sc->unexpected_attention_count,
9025
0, "Number of unexpected attentions");
9026
9027
#ifdef BCE_DEBUG
9028
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9029
"debug_bootcode_running_failure",
9030
CTLFLAG_RW, &bootcode_running_failure_sim_control,
9031
0, "Debug control to force bootcode running failures");
9032
9033
SYSCTL_ADD_U16(ctx, children, OID_AUTO,
9034
"rx_low_watermark",
9035
CTLFLAG_RD, &sc->rx_low_watermark,
9036
0, "Lowest level of free rx_bd's");
9037
9038
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9039
"rx_empty_count",
9040
CTLFLAG_RD, &sc->rx_empty_count,
9041
"Number of times the RX chain was empty");
9042
9043
SYSCTL_ADD_U16(ctx, children, OID_AUTO,
9044
"tx_hi_watermark",
9045
CTLFLAG_RD, &sc->tx_hi_watermark,
9046
0, "Highest level of used tx_bd's");
9047
9048
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9049
"tx_full_count",
9050
CTLFLAG_RD, &sc->tx_full_count,
9051
"Number of times the TX chain was full");
9052
9053
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9054
"tso_frames_requested",
9055
CTLFLAG_RD, &sc->tso_frames_requested,
9056
"Number of TSO frames requested");
9057
9058
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9059
"tso_frames_completed",
9060
CTLFLAG_RD, &sc->tso_frames_completed,
9061
"Number of TSO frames completed");
9062
9063
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9064
"tso_frames_failed",
9065
CTLFLAG_RD, &sc->tso_frames_failed,
9066
"Number of TSO frames failed");
9067
9068
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9069
"csum_offload_ip",
9070
CTLFLAG_RD, &sc->csum_offload_ip,
9071
"Number of IP checksum offload frames");
9072
9073
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9074
"csum_offload_tcp_udp",
9075
CTLFLAG_RD, &sc->csum_offload_tcp_udp,
9076
"Number of TCP/UDP checksum offload frames");
9077
9078
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9079
"vlan_tagged_frames_rcvd",
9080
CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd,
9081
"Number of VLAN tagged frames received");
9082
9083
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9084
"vlan_tagged_frames_stripped",
9085
CTLFLAG_RD, &sc->vlan_tagged_frames_stripped,
9086
"Number of VLAN tagged frames stripped");
9087
9088
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9089
"interrupts_rx",
9090
CTLFLAG_RD, &sc->interrupts_rx,
9091
"Number of RX interrupts");
9092
9093
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9094
"interrupts_tx",
9095
CTLFLAG_RD, &sc->interrupts_tx,
9096
"Number of TX interrupts");
9097
9098
if (bce_hdr_split == TRUE) {
9099
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9100
"split_header_frames_rcvd",
9101
CTLFLAG_RD, &sc->split_header_frames_rcvd,
9102
"Number of split header frames received");
9103
9104
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9105
"split_header_tcp_frames_rcvd",
9106
CTLFLAG_RD, &sc->split_header_tcp_frames_rcvd,
9107
"Number of split header TCP frames received");
9108
}
9109
9110
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9111
"nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
9112
(void *)sc, 0,
9113
bce_sysctl_nvram_dump, "S", "");
9114
9115
#ifdef BCE_NVRAM_WRITE_SUPPORT
9116
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9117
"nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
9118
(void *)sc, 0,
9119
bce_sysctl_nvram_write, "S", "");
9120
#endif
9121
#endif /* BCE_DEBUG */
9122
9123
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9124
"stat_IfHcInOctets",
9125
CTLFLAG_RD, &sc->stat_IfHCInOctets,
9126
"Bytes received");
9127
9128
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9129
"stat_IfHCInBadOctets",
9130
CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
9131
"Bad bytes received");
9132
9133
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9134
"stat_IfHCOutOctets",
9135
CTLFLAG_RD, &sc->stat_IfHCOutOctets,
9136
"Bytes sent");
9137
9138
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9139
"stat_IfHCOutBadOctets",
9140
CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
9141
"Bad bytes sent");
9142
9143
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9144
"stat_IfHCInUcastPkts",
9145
CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
9146
"Unicast packets received");
9147
9148
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9149
"stat_IfHCInMulticastPkts",
9150
CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
9151
"Multicast packets received");
9152
9153
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9154
"stat_IfHCInBroadcastPkts",
9155
CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
9156
"Broadcast packets received");
9157
9158
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9159
"stat_IfHCOutUcastPkts",
9160
CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
9161
"Unicast packets sent");
9162
9163
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9164
"stat_IfHCOutMulticastPkts",
9165
CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
9166
"Multicast packets sent");
9167
9168
SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9169
"stat_IfHCOutBroadcastPkts",
9170
CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
9171
"Broadcast packets sent");
9172
9173
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9174
"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
9175
CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
9176
0, "Internal MAC transmit errors");
9177
9178
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9179
"stat_Dot3StatsCarrierSenseErrors",
9180
CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
9181
0, "Carrier sense errors");
9182
9183
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9184
"stat_Dot3StatsFCSErrors",
9185
CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
9186
0, "Frame check sequence errors");
9187
9188
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9189
"stat_Dot3StatsAlignmentErrors",
9190
CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
9191
0, "Alignment errors");
9192
9193
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9194
"stat_Dot3StatsSingleCollisionFrames",
9195
CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
9196
0, "Single Collision Frames");
9197
9198
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9199
"stat_Dot3StatsMultipleCollisionFrames",
9200
CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
9201
0, "Multiple Collision Frames");
9202
9203
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9204
"stat_Dot3StatsDeferredTransmissions",
9205
CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
9206
0, "Deferred Transmissions");
9207
9208
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9209
"stat_Dot3StatsExcessiveCollisions",
9210
CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
9211
0, "Excessive Collisions");
9212
9213
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9214
"stat_Dot3StatsLateCollisions",
9215
CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
9216
0, "Late Collisions");
9217
9218
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9219
"stat_EtherStatsCollisions",
9220
CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
9221
0, "Collisions");
9222
9223
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9224
"stat_EtherStatsFragments",
9225
CTLFLAG_RD, &sc->stat_EtherStatsFragments,
9226
0, "Fragments");
9227
9228
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9229
"stat_EtherStatsJabbers",
9230
CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
9231
0, "Jabbers");
9232
9233
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9234
"stat_EtherStatsUndersizePkts",
9235
CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
9236
0, "Undersize packets");
9237
9238
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9239
"stat_EtherStatsOversizePkts",
9240
CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
9241
0, "stat_EtherStatsOversizePkts");
9242
9243
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9244
"stat_EtherStatsPktsRx64Octets",
9245
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
9246
0, "Bytes received in 64 byte packets");
9247
9248
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9249
"stat_EtherStatsPktsRx65Octetsto127Octets",
9250
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
9251
0, "Bytes received in 65 to 127 byte packets");
9252
9253
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9254
"stat_EtherStatsPktsRx128Octetsto255Octets",
9255
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
9256
0, "Bytes received in 128 to 255 byte packets");
9257
9258
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9259
"stat_EtherStatsPktsRx256Octetsto511Octets",
9260
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
9261
0, "Bytes received in 256 to 511 byte packets");
9262
9263
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9264
"stat_EtherStatsPktsRx512Octetsto1023Octets",
9265
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
9266
0, "Bytes received in 512 to 1023 byte packets");
9267
9268
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9269
"stat_EtherStatsPktsRx1024Octetsto1522Octets",
9270
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
9271
0, "Bytes received in 1024 t0 1522 byte packets");
9272
9273
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9274
"stat_EtherStatsPktsRx1523Octetsto9022Octets",
9275
CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
9276
0, "Bytes received in 1523 to 9022 byte packets");
9277
9278
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9279
"stat_EtherStatsPktsTx64Octets",
9280
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
9281
0, "Bytes sent in 64 byte packets");
9282
9283
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9284
"stat_EtherStatsPktsTx65Octetsto127Octets",
9285
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
9286
0, "Bytes sent in 65 to 127 byte packets");
9287
9288
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9289
"stat_EtherStatsPktsTx128Octetsto255Octets",
9290
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
9291
0, "Bytes sent in 128 to 255 byte packets");
9292
9293
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9294
"stat_EtherStatsPktsTx256Octetsto511Octets",
9295
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
9296
0, "Bytes sent in 256 to 511 byte packets");
9297
9298
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9299
"stat_EtherStatsPktsTx512Octetsto1023Octets",
9300
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
9301
0, "Bytes sent in 512 to 1023 byte packets");
9302
9303
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9304
"stat_EtherStatsPktsTx1024Octetsto1522Octets",
9305
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
9306
0, "Bytes sent in 1024 to 1522 byte packets");
9307
9308
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9309
"stat_EtherStatsPktsTx1523Octetsto9022Octets",
9310
CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
9311
0, "Bytes sent in 1523 to 9022 byte packets");
9312
9313
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9314
"stat_XonPauseFramesReceived",
9315
CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
9316
0, "XON pause frames receved");
9317
9318
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9319
"stat_XoffPauseFramesReceived",
9320
CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
9321
0, "XOFF pause frames received");
9322
9323
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9324
"stat_OutXonSent",
9325
CTLFLAG_RD, &sc->stat_OutXonSent,
9326
0, "XON pause frames sent");
9327
9328
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9329
"stat_OutXoffSent",
9330
CTLFLAG_RD, &sc->stat_OutXoffSent,
9331
0, "XOFF pause frames sent");
9332
9333
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9334
"stat_FlowControlDone",
9335
CTLFLAG_RD, &sc->stat_FlowControlDone,
9336
0, "Flow control done");
9337
9338
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9339
"stat_MacControlFramesReceived",
9340
CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
9341
0, "MAC control frames received");
9342
9343
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9344
"stat_XoffStateEntered",
9345
CTLFLAG_RD, &sc->stat_XoffStateEntered,
9346
0, "XOFF state entered");
9347
9348
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9349
"stat_IfInFramesL2FilterDiscards",
9350
CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
9351
0, "Received L2 packets discarded");
9352
9353
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9354
"stat_IfInRuleCheckerDiscards",
9355
CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
9356
0, "Received packets discarded by rule");
9357
9358
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9359
"stat_IfInFTQDiscards",
9360
CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
9361
0, "Received packet FTQ discards");
9362
9363
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9364
"stat_IfInMBUFDiscards",
9365
CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
9366
0, "Received packets discarded due to lack "
9367
"of controller buffer memory");
9368
9369
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9370
"stat_IfInRuleCheckerP4Hit",
9371
CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
9372
0, "Received packets rule checker hits");
9373
9374
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9375
"stat_CatchupInRuleCheckerDiscards",
9376
CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
9377
0, "Received packets discarded in Catchup path");
9378
9379
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9380
"stat_CatchupInFTQDiscards",
9381
CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
9382
0, "Received packets discarded in FTQ in Catchup path");
9383
9384
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9385
"stat_CatchupInMBUFDiscards",
9386
CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
9387
0, "Received packets discarded in controller "
9388
"buffer memory in Catchup path");
9389
9390
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9391
"stat_CatchupInRuleCheckerP4Hit",
9392
CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
9393
0, "Received packets rule checker hits in Catchup path");
9394
9395
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9396
"com_no_buffers",
9397
CTLFLAG_RD, &sc->com_no_buffers,
9398
0, "Valid packets received but no RX buffers available");
9399
9400
#ifdef BCE_DEBUG
9401
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9402
"driver_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9403
(void *)sc, 0,
9404
bce_sysctl_driver_state, "I", "Drive state information");
9405
9406
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9407
"hw_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9408
(void *)sc, 0,
9409
bce_sysctl_hw_state, "I", "Hardware state information");
9410
9411
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9412
"status_block", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9413
(void *)sc, 0,
9414
bce_sysctl_status_block, "I", "Dump status block");
9415
9416
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9417
"stats_block", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9418
(void *)sc, 0,
9419
bce_sysctl_stats_block, "I", "Dump statistics block");
9420
9421
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9422
"stats_clear", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9423
(void *)sc, 0,
9424
bce_sysctl_stats_clear, "I", "Clear statistics block");
9425
9426
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9427
"shmem_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9428
(void *)sc, 0,
9429
bce_sysctl_shmem_state, "I", "Shared memory state information");
9430
9431
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9432
"bc_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9433
(void *)sc, 0,
9434
bce_sysctl_bc_state, "I", "Bootcode state information");
9435
9436
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9437
"dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9438
(void *)sc, 0,
9439
bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
9440
9441
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9442
"dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9443
(void *)sc, 0,
9444
bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
9445
9446
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9447
"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9448
(void *)sc, 0,
9449
bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
9450
9451
if (bce_hdr_split == TRUE) {
9452
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9453
"dump_pg_chain",
9454
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9455
(void *)sc, 0,
9456
bce_sysctl_dump_pg_chain, "I", "Dump page chain");
9457
}
9458
9459
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9460
"dump_ctx", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9461
(void *)sc, 0,
9462
bce_sysctl_dump_ctx, "I", "Dump context memory");
9463
9464
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9465
"breakpoint", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9466
(void *)sc, 0,
9467
bce_sysctl_breakpoint, "I", "Driver breakpoint");
9468
9469
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9470
"reg_read", CTLTYPE_INT | CTLFLAG_RW| CTLFLAG_NEEDGIANT,
9471
(void *)sc, 0,
9472
bce_sysctl_reg_read, "I", "Register read");
9473
9474
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9475
"nvram_read", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9476
(void *)sc, 0,
9477
bce_sysctl_nvram_read, "I", "NVRAM read");
9478
9479
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9480
"phy_read", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9481
(void *)sc, 0,
9482
bce_sysctl_phy_read, "I", "PHY register read");
9483
9484
#endif
9485
9486
DBEXIT(BCE_VERBOSE_MISC);
9487
}
9488
9489
/****************************************************************************/
9490
/* BCE Debug Routines */
9491
/****************************************************************************/
9492
#ifdef BCE_DEBUG
9493
9494
/****************************************************************************/
9495
/* Freezes the controller to allow for a cohesive state dump. */
9496
/* */
9497
/* Returns: */
9498
/* Nothing. */
9499
/****************************************************************************/
9500
static __attribute__ ((noinline)) void
9501
bce_freeze_controller(struct bce_softc *sc)
9502
{
9503
u32 val;
9504
val = REG_RD(sc, BCE_MISC_COMMAND);
9505
val |= BCE_MISC_COMMAND_DISABLE_ALL;
9506
REG_WR(sc, BCE_MISC_COMMAND, val);
9507
}
9508
9509
/****************************************************************************/
9510
/* Unfreezes the controller after a freeze operation. This may not always */
9511
/* work and the controller will require a reset! */
9512
/* */
9513
/* Returns: */
9514
/* Nothing. */
9515
/****************************************************************************/
9516
static __attribute__ ((noinline)) void
9517
bce_unfreeze_controller(struct bce_softc *sc)
9518
{
9519
u32 val;
9520
val = REG_RD(sc, BCE_MISC_COMMAND);
9521
val |= BCE_MISC_COMMAND_ENABLE_ALL;
9522
REG_WR(sc, BCE_MISC_COMMAND, val);
9523
}
9524
9525
/****************************************************************************/
9526
/* Prints out Ethernet frame information from an mbuf. */
9527
/* */
9528
/* Partially decode an Ethernet frame to look at some important headers. */
9529
/* */
9530
/* Returns: */
9531
/* Nothing. */
9532
/****************************************************************************/
9533
static __attribute__ ((noinline)) void
9534
bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
9535
{
9536
struct ether_vlan_header *eh;
9537
u16 etype;
9538
int ehlen;
9539
struct ip *ip;
9540
struct tcphdr *th;
9541
struct udphdr *uh;
9542
struct arphdr *ah;
9543
9544
BCE_PRINTF(
9545
"-----------------------------"
9546
" Frame Decode "
9547
"-----------------------------\n");
9548
9549
eh = mtod(m, struct ether_vlan_header *);
9550
9551
/* Handle VLAN encapsulation if present. */
9552
if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
9553
etype = ntohs(eh->evl_proto);
9554
ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
9555
} else {
9556
etype = ntohs(eh->evl_encap_proto);
9557
ehlen = ETHER_HDR_LEN;
9558
}
9559
9560
/* ToDo: Add VLAN output. */
9561
BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
9562
eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
9563
9564
switch (etype) {
9565
case ETHERTYPE_IP:
9566
ip = (struct ip *)(m->m_data + ehlen);
9567
BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
9568
"len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
9569
ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
9570
ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
9571
9572
switch (ip->ip_p) {
9573
case IPPROTO_TCP:
9574
th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9575
BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = "
9576
"%d bytes, flags = 0x%b, csum = 0x%04X\n",
9577
ntohs(th->th_dport), ntohs(th->th_sport),
9578
(th->th_off << 2), th->th_flags,
9579
"\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
9580
"\02SYN\01FIN", ntohs(th->th_sum));
9581
break;
9582
case IPPROTO_UDP:
9583
uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9584
BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
9585
"bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
9586
ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
9587
ntohs(uh->uh_sum));
9588
break;
9589
case IPPROTO_ICMP:
9590
BCE_PRINTF("icmp:\n");
9591
break;
9592
default:
9593
BCE_PRINTF("----: Other IP protocol.\n");
9594
}
9595
break;
9596
case ETHERTYPE_IPV6:
9597
BCE_PRINTF("ipv6: No decode supported.\n");
9598
break;
9599
case ETHERTYPE_ARP:
9600
BCE_PRINTF("-arp: ");
9601
ah = (struct arphdr *) (m->m_data + ehlen);
9602
switch (ntohs(ah->ar_op)) {
9603
case ARPOP_REVREQUEST:
9604
printf("reverse ARP request\n");
9605
break;
9606
case ARPOP_REVREPLY:
9607
printf("reverse ARP reply\n");
9608
break;
9609
case ARPOP_REQUEST:
9610
printf("ARP request\n");
9611
break;
9612
case ARPOP_REPLY:
9613
printf("ARP reply\n");
9614
break;
9615
default:
9616
printf("other ARP operation\n");
9617
}
9618
break;
9619
default:
9620
BCE_PRINTF("----: Other protocol.\n");
9621
}
9622
9623
BCE_PRINTF(
9624
"-----------------------------"
9625
"--------------"
9626
"-----------------------------\n");
9627
}
9628
9629
/****************************************************************************/
9630
/* Prints out information about an mbuf. */
9631
/* */
9632
/* Returns: */
9633
/* Nothing. */
9634
/****************************************************************************/
9635
static __attribute__ ((noinline)) void
9636
bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
9637
{
9638
struct mbuf *mp = m;
9639
9640
if (m == NULL) {
9641
BCE_PRINTF("mbuf: null pointer\n");
9642
return;
9643
}
9644
9645
while (mp) {
9646
BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
9647
"m_data = %p\n", mp, mp->m_len, mp->m_flags,
9648
"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
9649
9650
if (mp->m_flags & M_PKTHDR) {
9651
BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
9652
"csum_flags = %b\n", mp->m_pkthdr.len,
9653
mp->m_flags, M_FLAG_PRINTF,
9654
mp->m_pkthdr.csum_flags, CSUM_BITS);
9655
}
9656
9657
if (mp->m_flags & M_EXT) {
9658
BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
9659
mp->m_ext.ext_buf, mp->m_ext.ext_size);
9660
switch (mp->m_ext.ext_type) {
9661
case EXT_CLUSTER:
9662
printf("EXT_CLUSTER\n"); break;
9663
case EXT_SFBUF:
9664
printf("EXT_SFBUF\n"); break;
9665
case EXT_JUMBO9:
9666
printf("EXT_JUMBO9\n"); break;
9667
case EXT_JUMBO16:
9668
printf("EXT_JUMBO16\n"); break;
9669
case EXT_PACKET:
9670
printf("EXT_PACKET\n"); break;
9671
case EXT_MBUF:
9672
printf("EXT_MBUF\n"); break;
9673
case EXT_NET_DRV:
9674
printf("EXT_NET_DRV\n"); break;
9675
case EXT_MOD_TYPE:
9676
printf("EXT_MDD_TYPE\n"); break;
9677
case EXT_DISPOSABLE:
9678
printf("EXT_DISPOSABLE\n"); break;
9679
case EXT_EXTREF:
9680
printf("EXT_EXTREF\n"); break;
9681
default:
9682
printf("UNKNOWN\n");
9683
}
9684
}
9685
9686
mp = mp->m_next;
9687
}
9688
}
9689
9690
/****************************************************************************/
9691
/* Prints out the mbufs in the TX mbuf chain. */
9692
/* */
9693
/* Returns: */
9694
/* Nothing. */
9695
/****************************************************************************/
9696
static __attribute__ ((noinline)) void
9697
bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9698
{
9699
struct mbuf *m;
9700
9701
BCE_PRINTF(
9702
"----------------------------"
9703
" tx mbuf data "
9704
"----------------------------\n");
9705
9706
for (int i = 0; i < count; i++) {
9707
m = sc->tx_mbuf_ptr[chain_prod];
9708
BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
9709
bce_dump_mbuf(sc, m);
9710
chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
9711
}
9712
9713
BCE_PRINTF(
9714
"----------------------------"
9715
"----------------"
9716
"----------------------------\n");
9717
}
9718
9719
/****************************************************************************/
9720
/* Prints out the mbufs in the RX mbuf chain. */
9721
/* */
9722
/* Returns: */
9723
/* Nothing. */
9724
/****************************************************************************/
9725
static __attribute__ ((noinline)) void
9726
bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9727
{
9728
struct mbuf *m;
9729
9730
BCE_PRINTF(
9731
"----------------------------"
9732
" rx mbuf data "
9733
"----------------------------\n");
9734
9735
for (int i = 0; i < count; i++) {
9736
m = sc->rx_mbuf_ptr[chain_prod];
9737
BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
9738
bce_dump_mbuf(sc, m);
9739
chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
9740
}
9741
9742
BCE_PRINTF(
9743
"----------------------------"
9744
"----------------"
9745
"----------------------------\n");
9746
}
9747
9748
/****************************************************************************/
9749
/* Prints out the mbufs in the mbuf page chain. */
9750
/* */
9751
/* Returns: */
9752
/* Nothing. */
9753
/****************************************************************************/
9754
static __attribute__ ((noinline)) void
9755
bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9756
{
9757
struct mbuf *m;
9758
9759
BCE_PRINTF(
9760
"----------------------------"
9761
" pg mbuf data "
9762
"----------------------------\n");
9763
9764
for (int i = 0; i < count; i++) {
9765
m = sc->pg_mbuf_ptr[chain_prod];
9766
BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
9767
bce_dump_mbuf(sc, m);
9768
chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
9769
}
9770
9771
BCE_PRINTF(
9772
"----------------------------"
9773
"----------------"
9774
"----------------------------\n");
9775
}
9776
9777
/****************************************************************************/
9778
/* Prints out a tx_bd structure. */
9779
/* */
9780
/* Returns: */
9781
/* Nothing. */
9782
/****************************************************************************/
9783
static __attribute__ ((noinline)) void
9784
bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
9785
{
9786
int i = 0;
9787
9788
if (idx > MAX_TX_BD_ALLOC)
9789
/* Index out of range. */
9790
BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
9791
else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
9792
/* TX Chain page pointer. */
9793
BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9794
"pointer\n", idx, txbd->tx_bd_haddr_hi,
9795
txbd->tx_bd_haddr_lo);
9796
else {
9797
/* Normal tx_bd entry. */
9798
BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
9799
"mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
9800
"0x%04X (", idx, txbd->tx_bd_haddr_hi,
9801
txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
9802
txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
9803
9804
if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
9805
if (i>0)
9806
printf("|");
9807
printf("CONN_FAULT");
9808
i++;
9809
}
9810
9811
if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
9812
if (i>0)
9813
printf("|");
9814
printf("TCP_UDP_CKSUM");
9815
i++;
9816
}
9817
9818
if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
9819
if (i>0)
9820
printf("|");
9821
printf("IP_CKSUM");
9822
i++;
9823
}
9824
9825
if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
9826
if (i>0)
9827
printf("|");
9828
printf("VLAN");
9829
i++;
9830
}
9831
9832
if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
9833
if (i>0)
9834
printf("|");
9835
printf("COAL_NOW");
9836
i++;
9837
}
9838
9839
if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
9840
if (i>0)
9841
printf("|");
9842
printf("DONT_GEN_CRC");
9843
i++;
9844
}
9845
9846
if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
9847
if (i>0)
9848
printf("|");
9849
printf("START");
9850
i++;
9851
}
9852
9853
if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
9854
if (i>0)
9855
printf("|");
9856
printf("END");
9857
i++;
9858
}
9859
9860
if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
9861
if (i>0)
9862
printf("|");
9863
printf("LSO");
9864
i++;
9865
}
9866
9867
if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
9868
if (i>0)
9869
printf("|");
9870
printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
9871
TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
9872
}
9873
9874
if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
9875
if (i>0)
9876
printf("|");
9877
printf("SW_FLAGS");
9878
i++;
9879
}
9880
9881
if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
9882
if (i>0)
9883
printf("|");
9884
printf("SNAP)");
9885
} else {
9886
printf(")\n");
9887
}
9888
}
9889
}
9890
9891
/****************************************************************************/
9892
/* Prints out a rx_bd structure. */
9893
/* */
9894
/* Returns: */
9895
/* Nothing. */
9896
/****************************************************************************/
9897
static __attribute__ ((noinline)) void
9898
bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
9899
{
9900
if (idx > MAX_RX_BD_ALLOC)
9901
/* Index out of range. */
9902
BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
9903
else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
9904
/* RX Chain page pointer. */
9905
BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9906
"pointer\n", idx, rxbd->rx_bd_haddr_hi,
9907
rxbd->rx_bd_haddr_lo);
9908
else
9909
/* Normal rx_bd entry. */
9910
BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
9911
"0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
9912
rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
9913
rxbd->rx_bd_flags);
9914
}
9915
9916
/****************************************************************************/
9917
/* Prints out a rx_bd structure in the page chain. */
9918
/* */
9919
/* Returns: */
9920
/* Nothing. */
9921
/****************************************************************************/
9922
static __attribute__ ((noinline)) void
9923
bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
9924
{
9925
if (idx > MAX_PG_BD_ALLOC)
9926
/* Index out of range. */
9927
BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
9928
else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
9929
/* Page Chain page pointer. */
9930
BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
9931
idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
9932
else
9933
/* Normal rx_bd entry. */
9934
BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
9935
"flags = 0x%08X\n", idx,
9936
pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
9937
pgbd->rx_bd_len, pgbd->rx_bd_flags);
9938
}
9939
9940
/****************************************************************************/
9941
/* Prints out a l2_fhdr structure. */
9942
/* */
9943
/* Returns: */
9944
/* Nothing. */
9945
/****************************************************************************/
9946
static __attribute__ ((noinline)) void
9947
bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
9948
{
9949
BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
9950
"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
9951
"tcp_udp_xsum = 0x%04X\n", idx,
9952
l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
9953
l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
9954
l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
9955
}
9956
9957
/****************************************************************************/
9958
/* Prints out context memory info. (Only useful for CID 0 to 16.) */
9959
/* */
9960
/* Returns: */
9961
/* Nothing. */
9962
/****************************************************************************/
9963
static __attribute__ ((noinline)) void
9964
bce_dump_ctx(struct bce_softc *sc, u16 cid)
9965
{
9966
if (cid > TX_CID) {
9967
BCE_PRINTF(" Unknown CID\n");
9968
return;
9969
}
9970
9971
BCE_PRINTF(
9972
"----------------------------"
9973
" CTX Data "
9974
"----------------------------\n");
9975
9976
BCE_PRINTF(" 0x%04X - (CID) Context ID\n", cid);
9977
9978
if (cid == RX_CID) {
9979
BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
9980
"producer index\n",
9981
CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
9982
BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
9983
"byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9984
BCE_L2CTX_RX_HOST_BSEQ));
9985
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
9986
CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
9987
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
9988
"descriptor address\n",
9989
CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
9990
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
9991
"descriptor address\n",
9992
CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
9993
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
9994
"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9995
BCE_L2CTX_RX_NX_BDIDX));
9996
BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
9997
"producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9998
BCE_L2CTX_RX_HOST_PG_BDIDX));
9999
BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
10000
"buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
10001
BCE_L2CTX_RX_PG_BUF_SIZE));
10002
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
10003
"chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10004
BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
10005
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
10006
"chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10007
BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
10008
BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
10009
"consumer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10010
BCE_L2CTX_RX_NX_PG_BDIDX));
10011
} else if (cid == TX_CID) {
10012
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10013
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
10014
CTX_RD(sc, GET_CID_ADDR(cid),
10015
BCE_L2CTX_TX_TYPE_XI));
10016
BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
10017
"cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
10018
BCE_L2CTX_TX_CMD_TYPE_XI));
10019
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
10020
"h/w buffer descriptor address\n",
10021
CTX_RD(sc, GET_CID_ADDR(cid),
10022
BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
10023
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
10024
"h/w buffer descriptor address\n",
10025
CTX_RD(sc, GET_CID_ADDR(cid),
10026
BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
10027
BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
10028
"host producer index\n",
10029
CTX_RD(sc, GET_CID_ADDR(cid),
10030
BCE_L2CTX_TX_HOST_BIDX_XI));
10031
BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
10032
"host byte sequence\n",
10033
CTX_RD(sc, GET_CID_ADDR(cid),
10034
BCE_L2CTX_TX_HOST_BSEQ_XI));
10035
} else {
10036
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
10037
CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
10038
BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
10039
CTX_RD(sc, GET_CID_ADDR(cid),
10040
BCE_L2CTX_TX_CMD_TYPE));
10041
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
10042
"h/w buffer descriptor address\n",
10043
CTX_RD(sc, GET_CID_ADDR(cid),
10044
BCE_L2CTX_TX_TBDR_BHADDR_HI));
10045
BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
10046
"h/w buffer descriptor address\n",
10047
CTX_RD(sc, GET_CID_ADDR(cid),
10048
BCE_L2CTX_TX_TBDR_BHADDR_LO));
10049
BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
10050
"producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10051
BCE_L2CTX_TX_HOST_BIDX));
10052
BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
10053
"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10054
BCE_L2CTX_TX_HOST_BSEQ));
10055
}
10056
}
10057
10058
BCE_PRINTF(
10059
"----------------------------"
10060
" Raw CTX "
10061
"----------------------------\n");
10062
10063
for (int i = 0x0; i < 0x300; i += 0x10) {
10064
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
10065
CTX_RD(sc, GET_CID_ADDR(cid), i),
10066
CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
10067
CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
10068
CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
10069
}
10070
10071
BCE_PRINTF(
10072
"----------------------------"
10073
"----------------"
10074
"----------------------------\n");
10075
}
10076
10077
/****************************************************************************/
10078
/* Prints out the FTQ data. */
10079
/* */
10080
/* Returns: */
10081
/* Nothing. */
10082
/****************************************************************************/
10083
static __attribute__ ((noinline)) void
10084
bce_dump_ftqs(struct bce_softc *sc)
10085
{
10086
u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
10087
10088
BCE_PRINTF(
10089
"----------------------------"
10090
" FTQ Data "
10091
"----------------------------\n");
10092
10093
BCE_PRINTF(" FTQ Command Control Depth_Now "
10094
"Max_Depth Valid_Cnt \n");
10095
BCE_PRINTF(" ------- ---------- ---------- ---------- "
10096
"---------- ----------\n");
10097
10098
/* Setup the generic statistic counters for the FTQ valid count. */
10099
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
10100
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT << 16) |
10101
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT << 8) |
10102
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
10103
REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10104
10105
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT << 24) |
10106
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT << 16) |
10107
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT << 8) |
10108
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
10109
REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
10110
10111
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT << 24) |
10112
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT << 16) |
10113
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT << 8) |
10114
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
10115
REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
10116
10117
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT << 24) |
10118
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT << 16) |
10119
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT << 8) |
10120
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
10121
REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
10122
10123
/* Input queue to the Receive Lookup state machine */
10124
cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
10125
ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
10126
cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
10127
max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
10128
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10129
BCE_PRINTF(" RLUP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10130
cmd, ctl, cur_depth, max_depth, valid_cnt);
10131
10132
/* Input queue to the Receive Processor */
10133
cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
10134
ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
10135
cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
10136
max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
10137
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10138
BCE_PRINTF(" RXP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10139
cmd, ctl, cur_depth, max_depth, valid_cnt);
10140
10141
/* Input queue to the Recevie Processor */
10142
cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
10143
ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
10144
cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
10145
max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
10146
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10147
BCE_PRINTF(" RXPC 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10148
cmd, ctl, cur_depth, max_depth, valid_cnt);
10149
10150
/* Input queue to the Receive Virtual to Physical state machine */
10151
cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
10152
ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
10153
cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
10154
max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
10155
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10156
BCE_PRINTF(" RV2PP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10157
cmd, ctl, cur_depth, max_depth, valid_cnt);
10158
10159
/* Input queue to the Recevie Virtual to Physical state machine */
10160
cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
10161
ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
10162
cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
10163
max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
10164
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
10165
BCE_PRINTF(" RV2PM 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10166
cmd, ctl, cur_depth, max_depth, valid_cnt);
10167
10168
/* Input queue to the Receive Virtual to Physical state machine */
10169
cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
10170
ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
10171
cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
10172
max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
10173
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
10174
BCE_PRINTF(" RV2PT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10175
cmd, ctl, cur_depth, max_depth, valid_cnt);
10176
10177
/* Input queue to the Receive DMA state machine */
10178
cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
10179
ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
10180
cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10181
max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10182
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
10183
BCE_PRINTF(" RDMA 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10184
cmd, ctl, cur_depth, max_depth, valid_cnt);
10185
10186
/* Input queue to the Transmit Scheduler state machine */
10187
cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
10188
ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
10189
cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
10190
max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
10191
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
10192
BCE_PRINTF(" TSCH 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10193
cmd, ctl, cur_depth, max_depth, valid_cnt);
10194
10195
/* Input queue to the Transmit Buffer Descriptor state machine */
10196
cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
10197
ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
10198
cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
10199
max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
10200
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
10201
BCE_PRINTF(" TBDR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10202
cmd, ctl, cur_depth, max_depth, valid_cnt);
10203
10204
/* Input queue to the Transmit Processor */
10205
cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
10206
ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
10207
cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
10208
max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
10209
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
10210
BCE_PRINTF(" TXP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10211
cmd, ctl, cur_depth, max_depth, valid_cnt);
10212
10213
/* Input queue to the Transmit DMA state machine */
10214
cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
10215
ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
10216
cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10217
max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10218
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
10219
BCE_PRINTF(" TDMA 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10220
cmd, ctl, cur_depth, max_depth, valid_cnt);
10221
10222
/* Input queue to the Transmit Patch-Up Processor */
10223
cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
10224
ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
10225
cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
10226
max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
10227
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
10228
BCE_PRINTF(" TPAT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10229
cmd, ctl, cur_depth, max_depth, valid_cnt);
10230
10231
/* Input queue to the Transmit Assembler state machine */
10232
cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
10233
ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
10234
cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
10235
max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
10236
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
10237
BCE_PRINTF(" TAS 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10238
cmd, ctl, cur_depth, max_depth, valid_cnt);
10239
10240
/* Input queue to the Completion Processor */
10241
cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
10242
ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
10243
cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
10244
max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
10245
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
10246
BCE_PRINTF(" COMX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10247
cmd, ctl, cur_depth, max_depth, valid_cnt);
10248
10249
/* Input queue to the Completion Processor */
10250
cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
10251
ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
10252
cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
10253
max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
10254
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
10255
BCE_PRINTF(" COMT 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10256
cmd, ctl, cur_depth, max_depth, valid_cnt);
10257
10258
/* Input queue to the Completion Processor */
10259
cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
10260
ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
10261
cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
10262
max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
10263
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
10264
BCE_PRINTF(" COMX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10265
cmd, ctl, cur_depth, max_depth, valid_cnt);
10266
10267
/* Setup the generic statistic counters for the FTQ valid count. */
10268
val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT << 16) |
10269
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT << 8) |
10270
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
10271
10272
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
10273
val = val |
10274
(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
10275
24);
10276
REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10277
10278
/* Input queue to the Management Control Processor */
10279
cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
10280
ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
10281
cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10282
max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10283
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10284
BCE_PRINTF(" MCP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10285
cmd, ctl, cur_depth, max_depth, valid_cnt);
10286
10287
/* Input queue to the Command Processor */
10288
cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
10289
ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
10290
cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10291
max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10292
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10293
BCE_PRINTF(" CP 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10294
cmd, ctl, cur_depth, max_depth, valid_cnt);
10295
10296
/* Input queue to the Completion Scheduler state machine */
10297
cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
10298
ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
10299
cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
10300
max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
10301
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10302
BCE_PRINTF(" CS 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10303
cmd, ctl, cur_depth, max_depth, valid_cnt);
10304
10305
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10306
/* Input queue to the RV2P Command Scheduler */
10307
cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
10308
ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
10309
cur_depth = (ctl & 0xFFC00000) >> 22;
10310
max_depth = (ctl & 0x003FF000) >> 12;
10311
valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10312
BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10313
cmd, ctl, cur_depth, max_depth, valid_cnt);
10314
}
10315
10316
BCE_PRINTF(
10317
"----------------------------"
10318
"----------------"
10319
"----------------------------\n");
10320
}
10321
10322
/****************************************************************************/
10323
/* Prints out the TX chain. */
10324
/* */
10325
/* Returns: */
10326
/* Nothing. */
10327
/****************************************************************************/
10328
static __attribute__ ((noinline)) void
10329
bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
10330
{
10331
struct tx_bd *txbd;
10332
10333
/* First some info about the tx_bd chain structure. */
10334
BCE_PRINTF(
10335
"----------------------------"
10336
" tx_bd chain "
10337
"----------------------------\n");
10338
10339
BCE_PRINTF("page size = 0x%08X, tx chain pages = 0x%08X\n",
10340
(u32) BCM_PAGE_SIZE, (u32) sc->tx_pages);
10341
BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
10342
(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
10343
BCE_PRINTF("total tx_bd = 0x%08X\n", (u32) TOTAL_TX_BD_ALLOC);
10344
10345
BCE_PRINTF(
10346
"----------------------------"
10347
" tx_bd data "
10348
"----------------------------\n");
10349
10350
/* Now print out a decoded list of TX buffer descriptors. */
10351
for (int i = 0; i < count; i++) {
10352
txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
10353
bce_dump_txbd(sc, tx_prod, txbd);
10354
tx_prod++;
10355
}
10356
10357
BCE_PRINTF(
10358
"----------------------------"
10359
"----------------"
10360
"----------------------------\n");
10361
}
10362
10363
/****************************************************************************/
10364
/* Prints out the RX chain. */
10365
/* */
10366
/* Returns: */
10367
/* Nothing. */
10368
/****************************************************************************/
10369
static __attribute__ ((noinline)) void
10370
bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
10371
{
10372
struct rx_bd *rxbd;
10373
10374
/* First some info about the rx_bd chain structure. */
10375
BCE_PRINTF(
10376
"----------------------------"
10377
" rx_bd chain "
10378
"----------------------------\n");
10379
10380
BCE_PRINTF("page size = 0x%08X, rx chain pages = 0x%08X\n",
10381
(u32) BCM_PAGE_SIZE, (u32) sc->rx_pages);
10382
10383
BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10384
(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
10385
10386
BCE_PRINTF("total rx_bd = 0x%08X\n", (u32) TOTAL_RX_BD_ALLOC);
10387
10388
BCE_PRINTF(
10389
"----------------------------"
10390
" rx_bd data "
10391
"----------------------------\n");
10392
10393
/* Now print out the rx_bd's themselves. */
10394
for (int i = 0; i < count; i++) {
10395
rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
10396
bce_dump_rxbd(sc, rx_prod, rxbd);
10397
rx_prod = RX_CHAIN_IDX(rx_prod + 1);
10398
}
10399
10400
BCE_PRINTF(
10401
"----------------------------"
10402
"----------------"
10403
"----------------------------\n");
10404
}
10405
10406
/****************************************************************************/
10407
/* Prints out the page chain. */
10408
/* */
10409
/* Returns: */
10410
/* Nothing. */
10411
/****************************************************************************/
10412
static __attribute__ ((noinline)) void
10413
bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
10414
{
10415
struct rx_bd *pgbd;
10416
10417
/* First some info about the page chain structure. */
10418
BCE_PRINTF(
10419
"----------------------------"
10420
" page chain "
10421
"----------------------------\n");
10422
10423
BCE_PRINTF("page size = 0x%08X, pg chain pages = 0x%08X\n",
10424
(u32) BCM_PAGE_SIZE, (u32) sc->pg_pages);
10425
10426
BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10427
(u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
10428
10429
BCE_PRINTF("total pg_bd = 0x%08X\n", (u32) TOTAL_PG_BD_ALLOC);
10430
10431
BCE_PRINTF(
10432
"----------------------------"
10433
" page data "
10434
"----------------------------\n");
10435
10436
/* Now print out the rx_bd's themselves. */
10437
for (int i = 0; i < count; i++) {
10438
pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
10439
bce_dump_pgbd(sc, pg_prod, pgbd);
10440
pg_prod = PG_CHAIN_IDX(pg_prod + 1);
10441
}
10442
10443
BCE_PRINTF(
10444
"----------------------------"
10445
"----------------"
10446
"----------------------------\n");
10447
}
10448
10449
#define BCE_PRINT_RX_CONS(arg) \
10450
if (sblk->status_rx_quick_consumer_index##arg) \
10451
BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n", \
10452
sblk->status_rx_quick_consumer_index##arg, (u16) \
10453
RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg), \
10454
arg);
10455
10456
#define BCE_PRINT_TX_CONS(arg) \
10457
if (sblk->status_tx_quick_consumer_index##arg) \
10458
BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n", \
10459
sblk->status_tx_quick_consumer_index##arg, (u16) \
10460
TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg), \
10461
arg);
10462
10463
/****************************************************************************/
10464
/* Prints out the status block from host memory. */
10465
/* */
10466
/* Returns: */
10467
/* Nothing. */
10468
/****************************************************************************/
10469
static __attribute__ ((noinline)) void
10470
bce_dump_status_block(struct bce_softc *sc)
10471
{
10472
struct status_block *sblk;
10473
10474
bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
10475
10476
sblk = sc->status_block;
10477
10478
BCE_PRINTF(
10479
"----------------------------"
10480
" Status Block "
10481
"----------------------------\n");
10482
10483
/* Theses indices are used for normal L2 drivers. */
10484
BCE_PRINTF(" 0x%08X - attn_bits\n",
10485
sblk->status_attn_bits);
10486
10487
BCE_PRINTF(" 0x%08X - attn_bits_ack\n",
10488
sblk->status_attn_bits_ack);
10489
10490
BCE_PRINT_RX_CONS(0);
10491
BCE_PRINT_TX_CONS(0)
10492
10493
BCE_PRINTF(" 0x%04X - status_idx\n", sblk->status_idx);
10494
10495
/* Theses indices are not used for normal L2 drivers. */
10496
BCE_PRINT_RX_CONS(1); BCE_PRINT_RX_CONS(2); BCE_PRINT_RX_CONS(3);
10497
BCE_PRINT_RX_CONS(4); BCE_PRINT_RX_CONS(5); BCE_PRINT_RX_CONS(6);
10498
BCE_PRINT_RX_CONS(7); BCE_PRINT_RX_CONS(8); BCE_PRINT_RX_CONS(9);
10499
BCE_PRINT_RX_CONS(10); BCE_PRINT_RX_CONS(11); BCE_PRINT_RX_CONS(12);
10500
BCE_PRINT_RX_CONS(13); BCE_PRINT_RX_CONS(14); BCE_PRINT_RX_CONS(15);
10501
10502
BCE_PRINT_TX_CONS(1); BCE_PRINT_TX_CONS(2); BCE_PRINT_TX_CONS(3);
10503
10504
if (sblk->status_completion_producer_index ||
10505
sblk->status_cmd_consumer_index)
10506
BCE_PRINTF("com_prod = 0x%08X, cmd_cons = 0x%08X\n",
10507
sblk->status_completion_producer_index,
10508
sblk->status_cmd_consumer_index);
10509
10510
BCE_PRINTF(
10511
"----------------------------"
10512
"----------------"
10513
"----------------------------\n");
10514
}
10515
10516
#define BCE_PRINT_64BIT_STAT(arg) \
10517
if (sblk->arg##_lo || sblk->arg##_hi) \
10518
BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi, \
10519
sblk->arg##_lo, #arg);
10520
10521
#define BCE_PRINT_32BIT_STAT(arg) \
10522
if (sblk->arg) \
10523
BCE_PRINTF(" 0x%08X : %s\n", \
10524
sblk->arg, #arg);
10525
10526
/****************************************************************************/
10527
/* Prints out the statistics block from host memory. */
10528
/* */
10529
/* Returns: */
10530
/* Nothing. */
10531
/****************************************************************************/
10532
static __attribute__ ((noinline)) void
10533
bce_dump_stats_block(struct bce_softc *sc)
10534
{
10535
struct statistics_block *sblk;
10536
10537
bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
10538
10539
sblk = sc->stats_block;
10540
10541
BCE_PRINTF(
10542
"---------------"
10543
" Stats Block (All Stats Not Shown Are 0) "
10544
"---------------\n");
10545
10546
BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
10547
BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
10548
BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
10549
BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
10550
BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
10551
BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
10552
BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
10553
BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
10554
BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
10555
BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
10556
BCE_PRINT_32BIT_STAT(
10557
stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
10558
BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
10559
BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
10560
BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
10561
BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
10562
BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
10563
BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
10564
BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
10565
BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
10566
BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
10567
BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
10568
BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
10569
BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
10570
BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
10571
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
10572
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
10573
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
10574
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
10575
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
10576
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
10577
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
10578
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
10579
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
10580
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
10581
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
10582
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
10583
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
10584
BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
10585
BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
10586
BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
10587
BCE_PRINT_32BIT_STAT(stat_OutXonSent);
10588
BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
10589
BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
10590
BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
10591
BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
10592
BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
10593
BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
10594
BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
10595
BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
10596
BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
10597
BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
10598
BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
10599
BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
10600
BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
10601
10602
BCE_PRINTF(
10603
"----------------------------"
10604
"----------------"
10605
"----------------------------\n");
10606
}
10607
10608
/****************************************************************************/
10609
/* Prints out a summary of the driver state. */
10610
/* */
10611
/* Returns: */
10612
/* Nothing. */
10613
/****************************************************************************/
10614
static __attribute__ ((noinline)) void
10615
bce_dump_driver_state(struct bce_softc *sc)
10616
{
10617
u32 val_hi, val_lo;
10618
10619
BCE_PRINTF(
10620
"-----------------------------"
10621
" Driver State "
10622
"-----------------------------\n");
10623
10624
val_hi = BCE_ADDR_HI(sc);
10625
val_lo = BCE_ADDR_LO(sc);
10626
BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
10627
"address\n", val_hi, val_lo);
10628
10629
val_hi = BCE_ADDR_HI(sc->bce_vhandle);
10630
val_lo = BCE_ADDR_LO(sc->bce_vhandle);
10631
BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
10632
"address\n", val_hi, val_lo);
10633
10634
val_hi = BCE_ADDR_HI(sc->status_block);
10635
val_lo = BCE_ADDR_LO(sc->status_block);
10636
BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
10637
"virtual address\n", val_hi, val_lo);
10638
10639
val_hi = BCE_ADDR_HI(sc->stats_block);
10640
val_lo = BCE_ADDR_LO(sc->stats_block);
10641
BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
10642
"virtual address\n", val_hi, val_lo);
10643
10644
val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
10645
val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
10646
BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
10647
"virtual address\n", val_hi, val_lo);
10648
10649
val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
10650
val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
10651
BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
10652
"virtual address\n", val_hi, val_lo);
10653
10654
if (bce_hdr_split == TRUE) {
10655
val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
10656
val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
10657
BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10658
"virtual address\n", val_hi, val_lo);
10659
}
10660
10661
val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10662
val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10663
BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10664
"virtual address\n", val_hi, val_lo);
10665
10666
val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10667
val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10668
BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10669
"virtual address\n", val_hi, val_lo);
10670
10671
if (bce_hdr_split == TRUE) {
10672
val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10673
val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10674
BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10675
"virtual address\n", val_hi, val_lo);
10676
}
10677
10678
BCE_PRINTF(" 0x%016llX - (sc->interrupts_generated) "
10679
"h/w intrs\n",
10680
(long long unsigned int) sc->interrupts_generated);
10681
10682
BCE_PRINTF(" 0x%016llX - (sc->interrupts_rx) "
10683
"rx interrupts handled\n",
10684
(long long unsigned int) sc->interrupts_rx);
10685
10686
BCE_PRINTF(" 0x%016llX - (sc->interrupts_tx) "
10687
"tx interrupts handled\n",
10688
(long long unsigned int) sc->interrupts_tx);
10689
10690
BCE_PRINTF(" 0x%016llX - (sc->phy_interrupts) "
10691
"phy interrupts handled\n",
10692
(long long unsigned int) sc->phy_interrupts);
10693
10694
BCE_PRINTF(" 0x%08X - (sc->last_status_idx) "
10695
"status block index\n", sc->last_status_idx);
10696
10697
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10698
"index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10699
10700
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10701
"index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10702
10703
BCE_PRINTF(" 0x%08X - (sc->tx_prod_bseq) tx producer "
10704
"byte seq index\n", sc->tx_prod_bseq);
10705
10706
BCE_PRINTF(" 0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10707
"mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10708
10709
BCE_PRINTF(" 0x%08X - (sc->used_tx_bd) used "
10710
"tx_bd's\n", sc->used_tx_bd);
10711
10712
BCE_PRINTF(" 0x%04X/0x%04X - (sc->tx_hi_watermark)/"
10713
"(sc->max_tx_bd)\n", sc->tx_hi_watermark, sc->max_tx_bd);
10714
10715
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10716
"index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10717
10718
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10719
"index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10720
10721
BCE_PRINTF(" 0x%08X - (sc->rx_prod_bseq) rx producer "
10722
"byte seq index\n", sc->rx_prod_bseq);
10723
10724
BCE_PRINTF(" 0x%04X/0x%04X - (sc->rx_low_watermark)/"
10725
"(sc->max_rx_bd)\n", sc->rx_low_watermark, sc->max_rx_bd);
10726
10727
BCE_PRINTF(" 0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10728
"mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10729
10730
BCE_PRINTF(" 0x%08X - (sc->free_rx_bd) free "
10731
"rx_bd's\n", sc->free_rx_bd);
10732
10733
if (bce_hdr_split == TRUE) {
10734
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_prod) page producer "
10735
"index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10736
10737
BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10738
"index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10739
10740
BCE_PRINTF(" 0x%08X - (sc->debug_pg_mbuf_alloc) page "
10741
"mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10742
}
10743
10744
BCE_PRINTF(" 0x%08X - (sc->free_pg_bd) free page "
10745
"rx_bd's\n", sc->free_pg_bd);
10746
10747
BCE_PRINTF(" 0x%04X/0x%04X - (sc->pg_low_watermark)/"
10748
"(sc->max_pg_bd)\n", sc->pg_low_watermark, sc->max_pg_bd);
10749
10750
BCE_PRINTF(" 0x%08X - (sc->mbuf_alloc_failed_count) "
10751
"mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10752
10753
BCE_PRINTF(" 0x%08X - (sc->bce_flags) "
10754
"bce mac flags\n", sc->bce_flags);
10755
10756
BCE_PRINTF(" 0x%08X - (sc->bce_phy_flags) "
10757
"bce phy flags\n", sc->bce_phy_flags);
10758
10759
BCE_PRINTF(
10760
"----------------------------"
10761
"----------------"
10762
"----------------------------\n");
10763
}
10764
10765
/****************************************************************************/
10766
/* Prints out the hardware state through a summary of important register, */
10767
/* followed by a complete register dump. */
10768
/* */
10769
/* Returns: */
10770
/* Nothing. */
10771
/****************************************************************************/
10772
static __attribute__ ((noinline)) void
10773
bce_dump_hw_state(struct bce_softc *sc)
10774
{
10775
u32 val;
10776
10777
BCE_PRINTF(
10778
"----------------------------"
10779
" Hardware State "
10780
"----------------------------\n");
10781
10782
BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10783
10784
val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10785
BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10786
val, BCE_MISC_ENABLE_STATUS_BITS);
10787
10788
val = REG_RD(sc, BCE_DMA_STATUS);
10789
BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
10790
val, BCE_DMA_STATUS);
10791
10792
val = REG_RD(sc, BCE_CTX_STATUS);
10793
BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
10794
val, BCE_CTX_STATUS);
10795
10796
val = REG_RD(sc, BCE_EMAC_STATUS);
10797
BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
10798
val, BCE_EMAC_STATUS);
10799
10800
val = REG_RD(sc, BCE_RPM_STATUS);
10801
BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
10802
val, BCE_RPM_STATUS);
10803
10804
/* ToDo: Create a #define for this constant. */
10805
val = REG_RD(sc, 0x2004);
10806
BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
10807
val, 0x2004);
10808
10809
val = REG_RD(sc, BCE_RV2P_STATUS);
10810
BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
10811
val, BCE_RV2P_STATUS);
10812
10813
/* ToDo: Create a #define for this constant. */
10814
val = REG_RD(sc, 0x2c04);
10815
BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
10816
val, 0x2c04);
10817
10818
val = REG_RD(sc, BCE_TBDR_STATUS);
10819
BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
10820
val, BCE_TBDR_STATUS);
10821
10822
val = REG_RD(sc, BCE_TDMA_STATUS);
10823
BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
10824
val, BCE_TDMA_STATUS);
10825
10826
val = REG_RD(sc, BCE_HC_STATUS);
10827
BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
10828
val, BCE_HC_STATUS);
10829
10830
val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10831
BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
10832
val, BCE_TXP_CPU_STATE);
10833
10834
val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10835
BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
10836
val, BCE_TPAT_CPU_STATE);
10837
10838
val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10839
BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
10840
val, BCE_RXP_CPU_STATE);
10841
10842
val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10843
BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
10844
val, BCE_COM_CPU_STATE);
10845
10846
val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
10847
BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
10848
val, BCE_MCP_CPU_STATE);
10849
10850
val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10851
BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
10852
val, BCE_CP_CPU_STATE);
10853
10854
BCE_PRINTF(
10855
"----------------------------"
10856
"----------------"
10857
"----------------------------\n");
10858
10859
BCE_PRINTF(
10860
"----------------------------"
10861
" Register Dump "
10862
"----------------------------\n");
10863
10864
for (int i = 0x400; i < 0x8000; i += 0x10) {
10865
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10866
i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10867
REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10868
}
10869
10870
BCE_PRINTF(
10871
"----------------------------"
10872
"----------------"
10873
"----------------------------\n");
10874
}
10875
10876
/****************************************************************************/
10877
/* Prints out the contentst of shared memory which is used for host driver */
10878
/* to bootcode firmware communication. */
10879
/* */
10880
/* Returns: */
10881
/* Nothing. */
10882
/****************************************************************************/
10883
static __attribute__ ((noinline)) void
10884
bce_dump_shmem_state(struct bce_softc *sc)
10885
{
10886
BCE_PRINTF(
10887
"----------------------------"
10888
" Hardware State "
10889
"----------------------------\n");
10890
10891
BCE_PRINTF("0x%08X - Shared memory base address\n",
10892
sc->bce_shmem_base);
10893
BCE_PRINTF("%s - bootcode version\n",
10894
sc->bce_bc_ver);
10895
10896
BCE_PRINTF(
10897
"----------------------------"
10898
" Shared Mem "
10899
"----------------------------\n");
10900
10901
for (int i = 0x0; i < 0x200; i += 0x10) {
10902
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10903
i, bce_shmem_rd(sc, i), bce_shmem_rd(sc, i + 0x4),
10904
bce_shmem_rd(sc, i + 0x8), bce_shmem_rd(sc, i + 0xC));
10905
}
10906
10907
BCE_PRINTF(
10908
"----------------------------"
10909
"----------------"
10910
"----------------------------\n");
10911
}
10912
10913
/****************************************************************************/
10914
/* Prints out the mailbox queue registers. */
10915
/* */
10916
/* Returns: */
10917
/* Nothing. */
10918
/****************************************************************************/
10919
static __attribute__ ((noinline)) void
10920
bce_dump_mq_regs(struct bce_softc *sc)
10921
{
10922
BCE_PRINTF(
10923
"----------------------------"
10924
" MQ Regs "
10925
"----------------------------\n");
10926
10927
BCE_PRINTF(
10928
"----------------------------"
10929
"----------------"
10930
"----------------------------\n");
10931
10932
for (int i = 0x3c00; i < 0x4000; i += 0x10) {
10933
BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10934
i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10935
REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10936
}
10937
10938
BCE_PRINTF(
10939
"----------------------------"
10940
"----------------"
10941
"----------------------------\n");
10942
}
10943
10944
/****************************************************************************/
10945
/* Prints out the bootcode state. */
10946
/* */
10947
/* Returns: */
10948
/* Nothing. */
10949
/****************************************************************************/
10950
static __attribute__ ((noinline)) void
10951
bce_dump_bc_state(struct bce_softc *sc)
10952
{
10953
u32 val;
10954
10955
BCE_PRINTF(
10956
"----------------------------"
10957
" Bootcode State "
10958
"----------------------------\n");
10959
10960
BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10961
10962
val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
10963
BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
10964
val, BCE_BC_RESET_TYPE);
10965
10966
val = bce_shmem_rd(sc, BCE_BC_STATE);
10967
BCE_PRINTF("0x%08X - (0x%06X) state\n",
10968
val, BCE_BC_STATE);
10969
10970
val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
10971
BCE_PRINTF("0x%08X - (0x%06X) condition\n",
10972
val, BCE_BC_STATE_CONDITION);
10973
10974
val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
10975
BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
10976
val, BCE_BC_STATE_DEBUG_CMD);
10977
10978
BCE_PRINTF(
10979
"----------------------------"
10980
"----------------"
10981
"----------------------------\n");
10982
}
10983
10984
/****************************************************************************/
10985
/* Prints out the TXP processor state. */
10986
/* */
10987
/* Returns: */
10988
/* Nothing. */
10989
/****************************************************************************/
10990
static __attribute__ ((noinline)) void
10991
bce_dump_txp_state(struct bce_softc *sc, int regs)
10992
{
10993
u32 val;
10994
u32 fw_version[3];
10995
10996
BCE_PRINTF(
10997
"----------------------------"
10998
" TXP State "
10999
"----------------------------\n");
11000
11001
for (int i = 0; i < 3; i++)
11002
fw_version[i] = htonl(REG_RD_IND(sc,
11003
(BCE_TXP_SCRATCH + 0x10 + i * 4)));
11004
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11005
11006
val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
11007
BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
11008
val, BCE_TXP_CPU_MODE);
11009
11010
val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11011
BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11012
val, BCE_TXP_CPU_STATE);
11013
11014
val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
11015
BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
11016
val, BCE_TXP_CPU_EVENT_MASK);
11017
11018
if (regs) {
11019
BCE_PRINTF(
11020
"----------------------------"
11021
" Register Dump "
11022
"----------------------------\n");
11023
11024
for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
11025
/* Skip the big blank spaces */
11026
if (i < 0x454000 && i > 0x5ffff)
11027
BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11028
"0x%08X 0x%08X\n", i,
11029
REG_RD_IND(sc, i),
11030
REG_RD_IND(sc, i + 0x4),
11031
REG_RD_IND(sc, i + 0x8),
11032
REG_RD_IND(sc, i + 0xC));
11033
}
11034
}
11035
11036
BCE_PRINTF(
11037
"----------------------------"
11038
"----------------"
11039
"----------------------------\n");
11040
}
11041
11042
/****************************************************************************/
11043
/* Prints out the RXP processor state. */
11044
/* */
11045
/* Returns: */
11046
/* Nothing. */
11047
/****************************************************************************/
11048
static __attribute__ ((noinline)) void
11049
bce_dump_rxp_state(struct bce_softc *sc, int regs)
11050
{
11051
u32 val;
11052
u32 fw_version[3];
11053
11054
BCE_PRINTF(
11055
"----------------------------"
11056
" RXP State "
11057
"----------------------------\n");
11058
11059
for (int i = 0; i < 3; i++)
11060
fw_version[i] = htonl(REG_RD_IND(sc,
11061
(BCE_RXP_SCRATCH + 0x10 + i * 4)));
11062
11063
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11064
11065
val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
11066
BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
11067
val, BCE_RXP_CPU_MODE);
11068
11069
val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11070
BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11071
val, BCE_RXP_CPU_STATE);
11072
11073
val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
11074
BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
11075
val, BCE_RXP_CPU_EVENT_MASK);
11076
11077
if (regs) {
11078
BCE_PRINTF(
11079
"----------------------------"
11080
" Register Dump "
11081
"----------------------------\n");
11082
11083
for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
11084
/* Skip the big blank sapces */
11085
if (i < 0xc5400 || i > 0xdffff)
11086
BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11087
"0x%08X 0x%08X\n", i,
11088
REG_RD_IND(sc, i),
11089
REG_RD_IND(sc, i + 0x4),
11090
REG_RD_IND(sc, i + 0x8),
11091
REG_RD_IND(sc, i + 0xC));
11092
}
11093
}
11094
11095
BCE_PRINTF(
11096
"----------------------------"
11097
"----------------"
11098
"----------------------------\n");
11099
}
11100
11101
/****************************************************************************/
11102
/* Prints out the TPAT processor state. */
11103
/* */
11104
/* Returns: */
11105
/* Nothing. */
11106
/****************************************************************************/
11107
static __attribute__ ((noinline)) void
11108
bce_dump_tpat_state(struct bce_softc *sc, int regs)
11109
{
11110
u32 val;
11111
u32 fw_version[3];
11112
11113
BCE_PRINTF(
11114
"----------------------------"
11115
" TPAT State "
11116
"----------------------------\n");
11117
11118
for (int i = 0; i < 3; i++)
11119
fw_version[i] = htonl(REG_RD_IND(sc,
11120
(BCE_TPAT_SCRATCH + 0x410 + i * 4)));
11121
11122
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11123
11124
val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
11125
BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
11126
val, BCE_TPAT_CPU_MODE);
11127
11128
val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11129
BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11130
val, BCE_TPAT_CPU_STATE);
11131
11132
val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
11133
BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
11134
val, BCE_TPAT_CPU_EVENT_MASK);
11135
11136
if (regs) {
11137
BCE_PRINTF(
11138
"----------------------------"
11139
" Register Dump "
11140
"----------------------------\n");
11141
11142
for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
11143
/* Skip the big blank spaces */
11144
if (i < 0x854000 && i > 0x9ffff)
11145
BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11146
"0x%08X 0x%08X\n", i,
11147
REG_RD_IND(sc, i),
11148
REG_RD_IND(sc, i + 0x4),
11149
REG_RD_IND(sc, i + 0x8),
11150
REG_RD_IND(sc, i + 0xC));
11151
}
11152
}
11153
11154
BCE_PRINTF(
11155
"----------------------------"
11156
"----------------"
11157
"----------------------------\n");
11158
}
11159
11160
/****************************************************************************/
11161
/* Prints out the Command Procesor (CP) state. */
11162
/* */
11163
/* Returns: */
11164
/* Nothing. */
11165
/****************************************************************************/
11166
static __attribute__ ((noinline)) void
11167
bce_dump_cp_state(struct bce_softc *sc, int regs)
11168
{
11169
u32 val;
11170
u32 fw_version[3];
11171
11172
BCE_PRINTF(
11173
"----------------------------"
11174
" CP State "
11175
"----------------------------\n");
11176
11177
for (int i = 0; i < 3; i++)
11178
fw_version[i] = htonl(REG_RD_IND(sc,
11179
(BCE_CP_SCRATCH + 0x10 + i * 4)));
11180
11181
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11182
11183
val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
11184
BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
11185
val, BCE_CP_CPU_MODE);
11186
11187
val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11188
BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11189
val, BCE_CP_CPU_STATE);
11190
11191
val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
11192
BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
11193
BCE_CP_CPU_EVENT_MASK);
11194
11195
if (regs) {
11196
BCE_PRINTF(
11197
"----------------------------"
11198
" Register Dump "
11199
"----------------------------\n");
11200
11201
for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
11202
/* Skip the big blank spaces */
11203
if (i < 0x185400 || i > 0x19ffff)
11204
BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11205
"0x%08X 0x%08X\n", i,
11206
REG_RD_IND(sc, i),
11207
REG_RD_IND(sc, i + 0x4),
11208
REG_RD_IND(sc, i + 0x8),
11209
REG_RD_IND(sc, i + 0xC));
11210
}
11211
}
11212
11213
BCE_PRINTF(
11214
"----------------------------"
11215
"----------------"
11216
"----------------------------\n");
11217
}
11218
11219
/****************************************************************************/
11220
/* Prints out the Completion Procesor (COM) state. */
11221
/* */
11222
/* Returns: */
11223
/* Nothing. */
11224
/****************************************************************************/
11225
static __attribute__ ((noinline)) void
11226
bce_dump_com_state(struct bce_softc *sc, int regs)
11227
{
11228
u32 val;
11229
u32 fw_version[4];
11230
11231
BCE_PRINTF(
11232
"----------------------------"
11233
" COM State "
11234
"----------------------------\n");
11235
11236
for (int i = 0; i < 3; i++)
11237
fw_version[i] = htonl(REG_RD_IND(sc,
11238
(BCE_COM_SCRATCH + 0x10 + i * 4)));
11239
11240
BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11241
11242
val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
11243
BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
11244
val, BCE_COM_CPU_MODE);
11245
11246
val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11247
BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11248
val, BCE_COM_CPU_STATE);
11249
11250
val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
11251
BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
11252
BCE_COM_CPU_EVENT_MASK);
11253
11254
if (regs) {
11255
BCE_PRINTF(
11256
"----------------------------"
11257
" Register Dump "
11258
"----------------------------\n");
11259
11260
for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
11261
BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11262
"0x%08X 0x%08X\n", i,
11263
REG_RD_IND(sc, i),
11264
REG_RD_IND(sc, i + 0x4),
11265
REG_RD_IND(sc, i + 0x8),
11266
REG_RD_IND(sc, i + 0xC));
11267
}
11268
}
11269
11270
BCE_PRINTF(
11271
"----------------------------"
11272
"----------------"
11273
"----------------------------\n");
11274
}
11275
11276
/****************************************************************************/
11277
/* Prints out the Receive Virtual 2 Physical (RV2P) state. */
11278
/* */
11279
/* Returns: */
11280
/* Nothing. */
11281
/****************************************************************************/
11282
static __attribute__ ((noinline)) void
11283
bce_dump_rv2p_state(struct bce_softc *sc)
11284
{
11285
u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
11286
11287
BCE_PRINTF(
11288
"----------------------------"
11289
" RV2P State "
11290
"----------------------------\n");
11291
11292
/* Stall the RV2P processors. */
11293
val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11294
val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
11295
REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11296
11297
/* Read the firmware version. */
11298
val = 0x00000001;
11299
REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
11300
fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11301
fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11302
BCE_RV2P_INSTR_HIGH_HIGH;
11303
BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
11304
fw_ver_high, fw_ver_low);
11305
11306
val = 0x00000001;
11307
REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
11308
fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11309
fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11310
BCE_RV2P_INSTR_HIGH_HIGH;
11311
BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
11312
fw_ver_high, fw_ver_low);
11313
11314
/* Resume the RV2P processors. */
11315
val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11316
val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
11317
REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11318
11319
/* Fetch the program counter value. */
11320
val = 0x68007800;
11321
REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11322
val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11323
pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11324
pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11325
BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
11326
BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
11327
11328
/* Fetch the program counter value again to see if it is advancing. */
11329
val = 0x68007800;
11330
REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11331
val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11332
pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11333
pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11334
BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
11335
BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
11336
11337
BCE_PRINTF(
11338
"----------------------------"
11339
"----------------"
11340
"----------------------------\n");
11341
}
11342
11343
/****************************************************************************/
11344
/* Prints out the driver state and then enters the debugger. */
11345
/* */
11346
/* Returns: */
11347
/* Nothing. */
11348
/****************************************************************************/
11349
static __attribute__ ((noinline)) void
11350
bce_breakpoint(struct bce_softc *sc)
11351
{
11352
11353
/*
11354
* Unreachable code to silence compiler warnings
11355
* about unused functions.
11356
*/
11357
if (0) {
11358
bce_freeze_controller(sc);
11359
bce_unfreeze_controller(sc);
11360
bce_dump_enet(sc, NULL);
11361
bce_dump_txbd(sc, 0, NULL);
11362
bce_dump_rxbd(sc, 0, NULL);
11363
bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD_ALLOC);
11364
bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
11365
bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD_ALLOC);
11366
bce_dump_l2fhdr(sc, 0, NULL);
11367
bce_dump_ctx(sc, RX_CID);
11368
bce_dump_ftqs(sc);
11369
bce_dump_tx_chain(sc, 0, USABLE_TX_BD_ALLOC);
11370
bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD_ALLOC);
11371
bce_dump_pg_chain(sc, 0, USABLE_PG_BD_ALLOC);
11372
bce_dump_status_block(sc);
11373
bce_dump_stats_block(sc);
11374
bce_dump_driver_state(sc);
11375
bce_dump_hw_state(sc);
11376
bce_dump_bc_state(sc);
11377
bce_dump_txp_state(sc, 0);
11378
bce_dump_rxp_state(sc, 0);
11379
bce_dump_tpat_state(sc, 0);
11380
bce_dump_cp_state(sc, 0);
11381
bce_dump_com_state(sc, 0);
11382
bce_dump_rv2p_state(sc);
11383
bce_dump_pgbd(sc, 0, NULL);
11384
}
11385
11386
bce_dump_status_block(sc);
11387
bce_dump_driver_state(sc);
11388
11389
/* Call the debugger. */
11390
breakpoint();
11391
}
11392
#endif
11393
11394