This source file includes following definitions.
- nxe_match
- nxe_attach
- nxe_pci_map
- nxe_pci_unmap
- nxe_intr
- nxe_ioctl
- nxe_up
- nxe_up_fw
- nxe_lladdr
- nxe_iff
- nxe_down
- nxe_start
- nxe_coalesce_m
- nxe_load_pkt
- nxe_watchdog
- nxe_media_change
- nxe_media_status
- nxe_link_state
- nxe_board_info
- nxe_user_info
- nxe_init
- nxe_uninit
- nxe_mountroot
- nxe_tick
- nxe_ring_alloc
- nxe_ring_sync
- nxe_ring_free
- nxe_ring_readable
- nxe_ring_writeable
- nxe_ring_cur
- nxe_ring_next
- nxe_pkt_alloc
- nxe_pkt_free
- nxe_pkt_get
- nxe_pkt_put
- nxe_pkt_used
- nxe_dmamem_alloc
- nxe_dmamem_free
- nxe_read
- nxe_write
- nxe_wait
- nxe_crb_set
- nxe_crb_read
- nxe_crb_write
- nxe_crb_wait
- nxe_rom_lock
- nxe_rom_unlock
- nxe_rom_read
- nxe_rom_read_region
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include "bpfilter.h"
20
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/sockio.h>
24 #include <sys/mbuf.h>
25 #include <sys/kernel.h>
26 #include <sys/socket.h>
27 #include <sys/malloc.h>
28 #include <sys/device.h>
29 #include <sys/proc.h>
30 #include <sys/queue.h>
31 #include <sys/timeout.h>
32 #include <sys/sensors.h>
33 #include <sys/rwlock.h>
34
35 #include <machine/bus.h>
36
37 #include <dev/pci/pcireg.h>
38 #include <dev/pci/pcivar.h>
39 #include <dev/pci/pcidevs.h>
40
41 #include <net/if.h>
42 #include <net/if_dl.h>
43 #include <net/if_media.h>
44 #include <net/if_types.h>
45
46 #if NBPFILTER > 0
47 #include <net/bpf.h>
48 #endif
49
50 #ifdef INET
51 #include <netinet/in.h>
52 #include <netinet/if_ether.h>
53 #endif
54
55 #ifdef NXE_DEBUG
56 int nxedebug = 0;
57
58 #define DPRINTF(l, f...) do { if (nxedebug & (l)) printf(f); } while (0)
59 #define DASSERT(_a) assert(_a)
60 #else
61 #define DPRINTF(l, f...)
62 #define DASSERT(_a)
63 #endif
64
65
66 #define NXE_VERSION_MAJOR 3
67 #define NXE_VERSION_MINOR 4
68 #define NXE_VERSION_BUILD 31
69 #define NXE_VERSION \
70 ((NXE_VERSION_MAJOR << 16)|(NXE_VERSION_MINOR << 8)|(NXE_VERSION_BUILD))
71
72
73
74
75
76
77 #define NXE_PCI_BAR_MEM 0x10
78 #define NXE_PCI_BAR_MEM_128MB (128 * 1024 * 1024)
79 #define NXE_PCI_BAR_DOORBELL 0x20
80
81
82
83
84
85 #define NXE_DB 0x00000000
86 #define NXE_DB_PEGID 0x00000003
87 #define NXE_DB_PEGID_RX 0x00000001
88 #define NXE_DB_PEGID_TX 0x00000002
89 #define NXE_DB_PRIVID 0x00000004
90 #define NXE_DB_COUNT(_c) ((_c)<<3)
91 #define NXE_DB_CTXID(_c) ((_c)<<18)
92 #define NXE_DB_OPCODE_RX_PROD 0x00000000
93 #define NXE_DB_OPCODE_RX_JUMBO_PROD 0x10000000
94 #define NXE_DB_OPCODE_RX_LRO_PROD 0x20000000
95 #define NXE_DB_OPCODE_CMD_PROD 0x30000000
96 #define NXE_DB_OPCODE_UPD_CONS 0x40000000
97 #define NXE_DB_OPCODE_RESET_CTX 0x50000000
98
99
100
101
102
103
104 #define _F(_f) ((_f) * 0x20)
105
106
107
108
109
110
111
112
113
114
115
116 #define NXE_MAP_DDR_NET 0x00000000
117 #define NXE_MAP_DDR_MD 0x02000000
118 #define NXE_MAP_QDR_NET 0x04000000
119 #define NXE_MAP_DIRECT_CRB 0x04400000
120 #define NXE_MAP_OCM0 0x05000000
121 #define NXE_MAP_OCM1 0x05100000
122 #define NXE_MAP_CRB 0x06000000
123
124
125
126
127
128
129
130
131
132 #define NXE_WIN_CRB(_f) (0x06110210 + _F(_f))
133 #define NXE_WIN_CRB_0 (0<<25)
134 #define NXE_WIN_CRB_1 (1<<25)
135
136
137
138
139
140
141
142
143
144 #define NXE_W0_PCIE 0x00100000
145 #define NXE_W0_NIU 0x00600000
146 #define NXE_W0_PPE_0 0x01100000
147 #define NXE_W0_PPE_1 0x01200000
148 #define NXE_W0_PPE_2 0x01300000
149 #define NXE_W0_PPE_3 0x01400000
150 #define NXE_W0_PPE_D 0x01500000
151 #define NXE_W0_PPE_I 0x01600000
152
153
154
155
156
157 #define NXE_W1_PCIE 0x00100000
158 #define NXE_W1_SW 0x00200000
159 #define NXE_W1_SIR 0x01200000
160 #define NXE_W1_ROMUSB 0x01300000
161
162
163
164
165 #define NXE_BOOTLD_START 0x00010000
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 #define NXE_ISR_VECTOR 0x06110100
184 #define NXE_ISR_VECTOR_FUNC(_f) (0x08 << (_f))
185 #define NXE_ISR_MASK 0x06110104
186 #define NXE_ISR_TARGET_STATUS 0x06110118
187 #define NXE_ISR_TARGET_MASK 0x06110128
188
189
190 #define NXE_SEM_ROM_LOCK 0x0611c010
191 #define NXE_SEM_ROM_UNLOCK 0x0611c014
192 #define NXE_SEM_PHY_LOCK 0x0611c018
193 #define NXE_SEM_PHY_UNLOCK 0x0611c01c
194 #define NXE_SEM_DONE 0x1
195
196
197
198
199
200 #define NXE_0_NIU_MODE 0x00600000
201 #define NXE_0_NIU_MODE_XGE (1<<2)
202 #define NXE_0_NIU_MODE_GBE (1<<1)
203 #define NXE_0_NIU_SINGLE_TERM 0x00600004
204
205 #define NXE_0_NIU_RESET_XG 0x0060001c
206 #define NXE_0_NIU_RESET_FIFO 0x00600088
207
208 #define _P(_p) ((_p) * 0x10000)
209
210 #define NXE_0_XG_CFG0(_p) (0x00670000 + _P(_p))
211 #define NXE_0_XG_CFG0_TX_EN (1<<0)
212 #define NXE_0_XG_CFG0_TX_SYNC (1<<1)
213 #define NXE_0_XG_CFG0_RX_EN (1<<2)
214 #define NXE_0_XG_CFG0_RX_SYNC (1<<3)
215 #define NXE_0_XG_CFG0_TX_FLOWCTL (1<<4)
216 #define NXE_0_XG_CFG0_RX_FLOWCTL (1<<5)
217 #define NXE_0_XG_CFG0_LOOPBACK (1<<8)
218 #define NXE_0_XG_CFG0_TX_RST_PB (1<<15)
219 #define NXE_0_XG_CFG0_RX_RST_PB (1<<16)
220 #define NXE_0_XG_CFG0_TX_RST_MAC (1<<17)
221 #define NXE_0_XG_CFG0_RX_RST_MAC (1<<18)
222 #define NXE_0_XG_CFG0_SOFT_RST (1<<31)
223 #define NXE_0_XG_CFG1(_p) (0x00670004 + _P(_p))
224 #define NXE_0_XG_CFG1_REM_CRC (1<<0)
225 #define NXE_0_XG_CFG1_CRC_EN (1<<1)
226 #define NXE_0_XG_CFG1_NO_MAX (1<<5)
227 #define NXE_0_XG_CFG1_WIRE_LO_ERR (1<<6)
228 #define NXE_0_XG_CFG1_PAUSE_FR_DIS (1<<8)
229 #define NXE_0_XG_CFG1_SEQ_ERR_EN (1<<10)
230 #define NXE_0_XG_CFG1_MULTICAST (1<<12)
231 #define NXE_0_XG_CFG1_PROMISC (1<<13)
232 #define NXE_0_XG_MAC_LO(_p) (0x00670010 + _P(_p))
233 #define NXE_0_XG_MAC_HI(_p) (0x0067000c + _P(_p))
234
235
236
237
238
239
240 #define NXE_1_SW_ROM_LOCK_ID 0x00202100
241 #define NXE_1_SW_ROM_LOCK_ID_DRV 0x0d417340
242 #define NXE_1_SW_PHY_LOCK_ID 0x00202120
243 #define NXE_1_SW_PHY_LOCK_ID_DRV 0x44524956
244
245
246 #define NXE_1_SW_FWVER_MAJOR 0x00202150
247 #define NXE_1_SW_FWVER_MINOR 0x00202154
248 #define NXE_1_SW_FWVER_BUILD 0x00202158
249
250
251 #define NXE_1_SW_CMD_ADDR_HI 0x00202218
252 #define NXE_1_SW_CMD_ADDR_LO 0x0020221c
253 #define NXE_1_SW_CMD_SIZE 0x002022c8
254 #define NXE_1_SW_DUMMY_ADDR_HI 0x0020223c
255 #define NXE_1_SW_DUMMY_ADDR_LO 0x00202240
256 #define NXE_1_SW_DUMMY_ADDR_LEN 1024
257
258 static const u_int32_t nxe_regmap[][4] = {
259 #define NXE_1_SW_CMD_PRODUCER(_f) (nxe_regmap[0][(_f)])
260 { 0x00202208, 0x002023ac, 0x002023b8, 0x002023d0 },
261 #define NXE_1_SW_CMD_CONSUMER(_f) (nxe_regmap[1][(_f)])
262 { 0x0020220c, 0x002023b0, 0x002023bc, 0x002023d4 },
263
264 #define NXE_1_SW_CONTEXT(_p) (nxe_regmap[2][(_p)])
265 #define NXE_1_SW_CONTEXT_SIG(_p) (0xdee0 | (_p))
266 { 0x0020238c, 0x00202390, 0x0020239c, 0x002023a4 },
267 #define NXE_1_SW_CONTEXT_ADDR_LO(_p) (nxe_regmap[3][(_p)])
268 { 0x00202388, 0x00202390, 0x00202398, 0x002023a0 },
269 #define NXE_1_SW_CONTEXT_ADDR_HI(_p) (nxe_regmap[4][(_p)])
270 { 0x002023c0, 0x002023c4, 0x002023c8, 0x002023cc },
271
272 #define NXE_1_SW_INT_MASK(_p) (nxe_regmap[5][(_p)])
273 { 0x002023d8, 0x082023e0, 0x082023e4, 0x082023e8 },
274
275 #define NXE_1_SW_RX_PRODUCER(_c) (nxe_regmap[6][(_c)])
276 { 0x00202300, 0x00202344, 0x002023d8, 0x0020242c },
277 #define NXE_1_SW_RX_CONSUMER(_c) (nxe_regmap[7][(_c)])
278 { 0x00202304, 0x00202348, 0x002023dc, 0x00202430 },
279 #define NXE_1_SW_RX_RING(_c) (nxe_regmap[8][(_c)])
280 { 0x00202308, 0x0020234c, 0x002023f0, 0x00202434 },
281 #define NXE_1_SW_RX_SIZE(_c) (nxe_regmap[9][(_c)])
282 { 0x0020230c, 0x00202350, 0x002023f4, 0x00202438 },
283
284 #define NXE_1_SW_RX_JUMBO_PRODUCER(_c) (nxe_regmap[10][(_c)])
285 { 0x00202310, 0x00202354, 0x002023f8, 0x0020243c },
286 #define NXE_1_SW_RX_JUMBO_CONSUMER(_c) (nxe_regmap[11][(_c)])
287 { 0x00202314, 0x00202358, 0x002023fc, 0x00202440 },
288 #define NXE_1_SW_RX_JUMBO_RING(_c) (nxe_regmap[12][(_c)])
289 { 0x00202318, 0x0020235c, 0x00202400, 0x00202444 },
290 #define NXE_1_SW_RX_JUMBO_SIZE(_c) (nxe_regmap[13][(_c)])
291 { 0x0020231c, 0x00202360, 0x00202404, 0x00202448 },
292
293 #define NXE_1_SW_RX_LRO_PRODUCER(_c) (nxe_regmap[14][(_c)])
294 { 0x00202320, 0x00202364, 0x00202408, 0x0020244c },
295 #define NXE_1_SW_RX_LRO_CONSUMER(_c) (nxe_regmap[15][(_c)])
296 { 0x00202324, 0x00202368, 0x0020240c, 0x00202450 },
297 #define NXE_1_SW_RX_LRO_RING(_c) (nxe_regmap[16][(_c)])
298 { 0x00202328, 0x0020236c, 0x00202410, 0x00202454 },
299 #define NXE_1_SW_RX_LRO_SIZE(_c) (nxe_regmap[17][(_c)])
300 { 0x0020232c, 0x00202370, 0x00202414, 0x00202458 },
301
302 #define NXE_1_SW_STATUS_RING(_c) (nxe_regmap[18][(_c)])
303 { 0x00202330, 0x00202374, 0x00202418, 0x0020245c },
304 #define NXE_1_SW_STATUS_PRODUCER(_c) (nxe_regmap[19][(_c)])
305 { 0x00202334, 0x00202378, 0x0020241c, 0x00202460 },
306 #define NXE_1_SW_STATUS_CONSUMER(_c) (nxe_regmap[20][(_c)])
307 { 0x00202338, 0x0020237c, 0x00202420, 0x00202464 },
308 #define NXE_1_SW_STATUS_STATE(_c) (nxe_regmap[21][(_c)])
309 #define NXE_1_SW_STATUS_STATE_READY 0x0000ff01
310 { 0x0020233c, 0x00202380, 0x00202424, 0x00202468 },
311 #define NXE_1_SW_STATUS_SIZE(_c) (nxe_regmap[22][(_c)])
312 { 0x00202340, 0x00202384, 0x00202428, 0x0020246c }
313 };
314
315
316 #define NXE_1_SW_BOOTLD_CONFIG 0x002021fc
317 #define NXE_1_SW_BOOTLD_CONFIG_ROM 0x00000000
318 #define NXE_1_SW_BOOTLD_CONFIG_RAM 0x12345678
319
320 #define NXE_1_SW_CMDPEG_STATE 0x00202250
321 #define NXE_1_SW_CMDPEG_STATE_START 0xff00
322 #define NXE_1_SW_CMDPEG_STATE_DONE 0xff01
323 #define NXE_1_SW_CMDPEG_STATE_ACK 0xf00f
324 #define NXE_1_SW_CMDPEG_STATE_ERROR 0xffff
325
326 #define NXE_1_SW_XG_STATE 0x00202294
327 #define NXE_1_SW_XG_STATE_PORT(_r, _p) (((_r)>>8*(_p))&0xff)
328 #define NXE_1_SW_XG_STATE_UP (1<<4)
329 #define NXE_1_SW_XG_STATE_DOWN (1<<5)
330
331 #define NXE_1_SW_MPORT_MODE 0x002022c4
332 #define NXE_1_SW_MPORT_MODE_SINGLE 0x1111
333 #define NXE_1_SW_MPORT_MODE_MULTI 0x2222
334
335 #define NXE_1_SW_NIC_CAP_HOST 0x002023a8
336 #define NXE_1_SW_NIC_CAP_HOST_DEF 0x1
337
338 #define NXE_1_SW_DRIVER_VER 0x002024a0
339
340
341 #define NXE_1_SW_TEMP 0x002023b4
342 #define NXE_1_SW_TEMP_STATE(_x) ((_x)&0xffff)
343 #define NXE_1_SW_TEMP_STATE_NONE 0x0000
344 #define NXE_1_SW_TEMP_STATE_OK 0x0001
345 #define NXE_1_SW_TEMP_STATE_WARN 0x0002
346 #define NXE_1_SW_TEMP_STATE_CRIT 0x0003
347 #define NXE_1_SW_TEMP_VAL(_x) (((_x)>>16)&0xffff)
348
349 #define NXE_1_SW_V2P(_f) (0x00202490+((_f)*4))
350
351
352
353
354 #define NXE_1_ROMUSB_STATUS 0x01300004
355 #define NXE_1_ROMUSB_STATUS_DONE (1<<1)
356 #define NXE_1_ROMUSB_SW_RESET 0x01300008
357 #define NXE_1_ROMUSB_SW_RESET_DEF 0xffffffff
358 #define NXE_1_ROMUSB_SW_RESET_BOOT 0x0080000f
359
360 #define NXE_1_CASPER_RESET 0x01300038
361 #define NXE_1_CASPER_RESET_ENABLE 0x1
362 #define NXE_1_CASPER_RESET_DISABLE 0x1
363
364 #define NXE_1_GLB_PEGTUNE 0x0130005c
365 #define NXE_1_GLB_PEGTUNE_DONE 0x00000001
366
367 #define NXE_1_GLB_CHIPCLKCTL 0x013000a8
368 #define NXE_1_GLB_CHIPCLKCTL_ON 0x00003fff
369
370
371 #define NXE_1_ROM_CONTROL 0x01310000
372 #define NXE_1_ROM_OPCODE 0x01310004
373 #define NXE_1_ROM_OPCODE_READ 0x0000000b
374 #define NXE_1_ROM_ADDR 0x01310008
375 #define NXE_1_ROM_WDATA 0x0131000c
376 #define NXE_1_ROM_ABYTE_CNT 0x01310010
377 #define NXE_1_ROM_DBYTE_CNT 0x01310014
378 #define NXE_1_ROM_RDATA 0x01310018
379 #define NXE_1_ROM_AGT_TAG 0x0131001c
380 #define NXE_1_ROM_TIME_PARM 0x01310020
381 #define NXE_1_ROM_CLK_DIV 0x01310024
382 #define NXE_1_ROM_MISS_INSTR 0x01310028
383
384
385
386
387
388
389 #define NXE_FLASH_CRBINIT 0x00000000
390 #define NXE_FLASH_BRDCFG 0x00004000
391 #define NXE_FLASH_INITCODE 0x00006000
392 #define NXE_FLASH_BOOTLD 0x00010000
393 #define NXE_FLASH_IMAGE 0x00043000
394 #define NXE_FLASH_SECONDARY 0x00200000
395 #define NXE_FLASH_PXE 0x003d0000
396 #define NXE_FLASH_USER 0x003e8000
397 #define NXE_FLASH_VPD 0x003e8c00
398 #define NXE_FLASH_LICENSE 0x003e9000
399 #define NXE_FLASH_FIXED 0x003f0000
400
401
402
403
404
405 #define NXE_MAX_PORTS 4
406 #define NXE_MAX_PORT_LLADDRS 32
407 #define NXE_MAX_PKTLEN (64 * 1024)
408
409
410
411
412
413
414 struct nxe_info {
415 u_int32_t ni_hdrver;
416 #define NXE_INFO_HDRVER_1 0x00000001
417
418 u_int32_t ni_board_mfg;
419 u_int32_t ni_board_type;
420 #define NXE_BRDTYPE_P1_BD 0x0000
421 #define NXE_BRDTYPE_P1_SB 0x0001
422 #define NXE_BRDTYPE_P1_SMAX 0x0002
423 #define NXE_BRDTYPE_P1_SOCK 0x0003
424 #define NXE_BRDTYPE_P2_SOCK_31 0x0008
425 #define NXE_BRDTYPE_P2_SOCK_35 0x0009
426 #define NXE_BRDTYPE_P2_SB35_4G 0x000a
427 #define NXE_BRDTYPE_P2_SB31_10G 0x000b
428 #define NXE_BRDTYPE_P2_SB31_2G 0x000c
429 #define NXE_BRDTYPE_P2_SB31_10G_IMEZ 0x000d
430 #define NXE_BRDTYPE_P2_SB31_10G_HMEZ 0x000e
431 #define NXE_BRDTYPE_P2_SB31_10G_CX4 0x000f
432 u_int32_t ni_board_num;
433
434 u_int32_t ni_chip_id;
435 u_int32_t ni_chip_minor;
436 u_int32_t ni_chip_major;
437 u_int32_t ni_chip_pkg;
438 u_int32_t ni_chip_lot;
439
440 u_int32_t ni_port_mask;
441 u_int32_t ni_peg_mask;
442 u_int32_t ni_icache;
443 u_int32_t ni_dcache;
444 u_int32_t ni_casper;
445
446 u_int32_t ni_lladdr0_low;
447 u_int32_t ni_lladdr1_low;
448 u_int32_t ni_lladdr2_low;
449 u_int32_t ni_lladdr3_low;
450
451 u_int32_t ni_mnsync_mode;
452 u_int32_t ni_mnsync_shift_cclk;
453 u_int32_t ni_mnsync_shift_mclk;
454 u_int32_t ni_mnwb_enable;
455 u_int32_t ni_mnfreq_crystal;
456 u_int32_t ni_mnfreq_speed;
457 u_int32_t ni_mnorg;
458 u_int32_t ni_mndepth;
459 u_int32_t ni_mnranks0;
460 u_int32_t ni_mnranks1;
461 u_int32_t ni_mnrd_latency0;
462 u_int32_t ni_mnrd_latency1;
463 u_int32_t ni_mnrd_latency2;
464 u_int32_t ni_mnrd_latency3;
465 u_int32_t ni_mnrd_latency4;
466 u_int32_t ni_mnrd_latency5;
467 u_int32_t ni_mnrd_latency6;
468 u_int32_t ni_mnrd_latency7;
469 u_int32_t ni_mnrd_latency8;
470 u_int32_t ni_mndll[18];
471 u_int32_t ni_mnddr_mode;
472 u_int32_t ni_mnddr_extmode;
473 u_int32_t ni_mntiming0;
474 u_int32_t ni_mntiming1;
475 u_int32_t ni_mntiming2;
476
477 u_int32_t ni_snsync_mode;
478 u_int32_t ni_snpt_mode;
479 u_int32_t ni_snecc_enable;
480 u_int32_t ni_snwb_enable;
481 u_int32_t ni_snfreq_crystal;
482 u_int32_t ni_snfreq_speed;
483 u_int32_t ni_snorg;
484 u_int32_t ni_sndepth;
485 u_int32_t ni_sndll;
486 u_int32_t ni_snrd_latency;
487
488 u_int32_t ni_lladdr0_high;
489 u_int32_t ni_lladdr1_high;
490 u_int32_t ni_lladdr2_high;
491 u_int32_t ni_lladdr3_high;
492
493 u_int32_t ni_magic;
494 #define NXE_INFO_MAGIC 0x12345678
495
496 u_int32_t ni_mnrd_imm;
497 u_int32_t ni_mndll_override;
498 } __packed;
499
500 struct nxe_imageinfo {
501 u_int32_t nim_bootld_ver;
502 u_int32_t nim_bootld_size;
503
504 u_int8_t nim_img_ver_major;
505 u_int8_t nim_img_ver_minor;
506 u_int16_t nim_img_ver_build;
507
508 u_int32_t min_img_size;
509 } __packed;
510
511 struct nxe_lladdr {
512 u_int8_t pad[2];
513 u_int8_t lladdr[6];
514 } __packed;
515
516 struct nxe_userinfo {
517 u_int8_t nu_flash_md5[1024];
518
519 struct nxe_imageinfo nu_imageinfo;
520
521 u_int32_t nu_primary;
522 u_int32_t nu_secondary;
523
524 u_int64_t nu_lladdr[NXE_MAX_PORTS][NXE_MAX_PORT_LLADDRS];
525
526 u_int32_t nu_subsys_id;
527
528 u_int8_t nu_serial[32];
529
530 u_int32_t nu_bios_ver;
531 } __packed;
532
533
534
535 struct nxe_ctx_ring {
536 u_int64_t r_addr;
537 u_int32_t r_size;
538 u_int32_t r_reserved;
539 };
540
541 #define NXE_RING_RX 0
542 #define NXE_RING_RX_JUMBO 1
543 #define NXE_RING_RX_LRO 2
544 #define NXE_NRING 3
545
546 struct nxe_ctx {
547 u_int64_t ctx_cmd_consumer_addr;
548
549 struct nxe_ctx_ring ctx_cmd_ring;
550
551 struct nxe_ctx_ring ctx_rx_rings[NXE_NRING];
552
553 u_int64_t ctx_status_ring_addr;
554 u_int32_t ctx_status_ring_size;
555
556 u_int32_t ctx_id;
557 } __packed;
558
559 struct nxe_tx_desc {
560 u_int8_t tx_tcp_offset;
561 u_int8_t tx_ip_offset;
562 u_int16_t tx_flags;
563 #define NXE_TXD_F_OPCODE_TX (0x01 << 7)
564
565 u_int8_t tx_nbufs;
566 u_int16_t tx_length;
567 u_int8_t tx_length_hi;
568
569 u_int64_t tx_addr_2;
570
571 u_int16_t tx_id;
572 u_int16_t tx_mss;
573
574 u_int8_t tx_port;
575 u_int8_t tx_tso_hdr_len;
576 u_int16_t tx_ipsec_id;
577
578 u_int64_t tx_addr_3;
579
580 u_int64_t tx_addr_1;
581
582 u_int16_t tx_slen_1;
583 u_int16_t tx_slen_2;
584 u_int16_t tx_slen_3;
585 u_int16_t tx_slen_4;
586
587 u_int64_t tx_addr_4;
588
589 u_int64_t tx_reserved;
590 } __packed;
591 #define NXE_TXD_SEGS 4
592 #define NXE_TXD_DESCS 8
593 #define NXE_TXD_MAX_SEGS (NXE_TXD_SEGS * NXE_TXD_DESCS)
594
595 struct nxe_rx_desc {
596 u_int16_t rx_id;
597 u_int16_t rx_flags;
598 u_int32_t rx_len;
599 u_int64_t rx_addr;
600 } __packed;
601 #define NXE_RXD_MAX_SEGS 1
602
603 struct nxe_status_desc {
604 u_int8_t st_lro;
605 u_int8_t st_owner;
606 u_int16_t st_id;
607 u_int16_t st_len;
608 u_int16_t st_flags;
609 } __packed;
610
611
612
613
614
615 struct nxe_board {
616 u_int32_t brd_type;
617 u_int brd_mode;
618 };
619
620 struct nxe_dmamem {
621 bus_dmamap_t ndm_map;
622 bus_dma_segment_t ndm_seg;
623 size_t ndm_size;
624 caddr_t ndm_kva;
625 };
626 #define NXE_DMA_MAP(_ndm) ((_ndm)->ndm_map)
627 #define NXE_DMA_LEN(_ndm) ((_ndm)->ndm_size)
628 #define NXE_DMA_DVA(_ndm) ((_ndm)->ndm_map->dm_segs[0].ds_addr)
629 #define NXE_DMA_KVA(_ndm) ((void *)(_ndm)->ndm_kva)
630
631 struct nxe_pkt {
632 u_int16_t pkt_id;
633 bus_dmamap_t pkt_dmap;
634 struct mbuf *pkt_m;
635 TAILQ_ENTRY(nxe_pkt) pkt_link;
636 };
637
638 struct nxe_pkt_list {
639 struct nxe_pkt *npl_pkts;
640 TAILQ_HEAD(, nxe_pkt) npl_free;
641 TAILQ_HEAD(, nxe_pkt) npl_used;
642 };
643
644 struct nxe_ring {
645 struct nxe_dmamem *nr_dmamem;
646 u_int8_t *nr_pos;
647
648 u_int nr_slot;
649 int nr_ready;
650
651 size_t nr_desclen;
652 u_int nr_nentries;
653 };
654
655
656
657
658
659 struct nxe_softc {
660 struct device sc_dev;
661
662 bus_dma_tag_t sc_dmat;
663
664 bus_space_tag_t sc_memt;
665 bus_space_handle_t sc_memh;
666 bus_size_t sc_mems;
667 bus_space_handle_t sc_crbh;
668 bus_space_tag_t sc_dbt;
669 bus_space_handle_t sc_dbh;
670 bus_size_t sc_dbs;
671
672 void *sc_ih;
673
674 int sc_function;
675 int sc_port;
676 int sc_window;
677
678 const struct nxe_board *sc_board;
679 u_int sc_fw_major;
680 u_int sc_fw_minor;
681 u_int sc_fw_build;
682
683 struct arpcom sc_ac;
684 struct ifmedia sc_media;
685
686 struct nxe_pkt_list *sc_tx_pkts;
687 struct nxe_pkt_list *sc_rx_pkts;
688
689
690 struct nxe_dmamem *sc_dummy_dma;
691
692 struct nxe_dmamem *sc_ctx;
693 u_int32_t *sc_cmd_consumer;
694
695 struct nxe_ring *sc_cmd_ring;
696 struct nxe_ring *sc_rx_rings[NXE_NRING];
697 struct nxe_ring *sc_status_ring;
698
699
700 struct timeout sc_tick;
701 struct ksensor sc_sensor;
702 struct ksensordev sc_sensor_dev;
703
704
705 struct rwlock sc_lock;
706 };
707
708 int nxe_match(struct device *, void *, void *);
709 void nxe_attach(struct device *, struct device *, void *);
710 int nxe_intr(void *);
711
712 struct cfattach nxe_ca = {
713 sizeof(struct nxe_softc),
714 nxe_match,
715 nxe_attach
716 };
717
718 struct cfdriver nxe_cd = {
719 NULL,
720 "nxe",
721 DV_IFNET
722 };
723
724
725 int nxe_pci_map(struct nxe_softc *,
726 struct pci_attach_args *);
727 void nxe_pci_unmap(struct nxe_softc *);
728
729 int nxe_board_info(struct nxe_softc *);
730 int nxe_user_info(struct nxe_softc *);
731 int nxe_init(struct nxe_softc *);
732 void nxe_uninit(struct nxe_softc *);
733 void nxe_mountroot(void *);
734
735
736 void nxe_tick(void *);
737 void nxe_link_state(struct nxe_softc *);
738
739
740 int nxe_ioctl(struct ifnet *, u_long, caddr_t);
741 void nxe_start(struct ifnet *);
742 void nxe_watchdog(struct ifnet *);
743
744 void nxe_up(struct nxe_softc *);
745 void nxe_lladdr(struct nxe_softc *);
746 void nxe_iff(struct nxe_softc *);
747 void nxe_down(struct nxe_softc *);
748
749 int nxe_up_fw(struct nxe_softc *);
750
751
752 int nxe_media_change(struct ifnet *);
753 void nxe_media_status(struct ifnet *, struct ifmediareq *);
754
755
756
757 struct nxe_ring *nxe_ring_alloc(struct nxe_softc *, size_t, u_int);
758 void nxe_ring_sync(struct nxe_softc *, struct nxe_ring *,
759 int);
760 void nxe_ring_free(struct nxe_softc *, struct nxe_ring *);
761 int nxe_ring_readable(struct nxe_ring *, int);
762 int nxe_ring_writeable(struct nxe_ring *, int);
763 void *nxe_ring_cur(struct nxe_softc *, struct nxe_ring *);
764 void *nxe_ring_next(struct nxe_softc *, struct nxe_ring *);
765
766 struct mbuf *nxe_load_pkt(struct nxe_softc *, bus_dmamap_t,
767 struct mbuf *);
768 struct mbuf *nxe_coalesce_m(struct mbuf *);
769
770
771 struct nxe_pkt_list *nxe_pkt_alloc(struct nxe_softc *, u_int, int);
772 void nxe_pkt_free(struct nxe_softc *,
773 struct nxe_pkt_list *);
774 void nxe_pkt_put(struct nxe_pkt_list *, struct nxe_pkt *);
775 struct nxe_pkt *nxe_pkt_get(struct nxe_pkt_list *);
776 struct nxe_pkt *nxe_pkt_used(struct nxe_pkt_list *);
777
778
779
780 struct nxe_dmamem *nxe_dmamem_alloc(struct nxe_softc *, bus_size_t,
781 bus_size_t);
782 void nxe_dmamem_free(struct nxe_softc *,
783 struct nxe_dmamem *);
784
785
786 u_int32_t nxe_read(struct nxe_softc *, bus_size_t);
787 void nxe_write(struct nxe_softc *, bus_size_t, u_int32_t);
788 int nxe_wait(struct nxe_softc *, bus_size_t, u_int32_t,
789 u_int32_t, u_int);
790
791 int nxe_crb_set(struct nxe_softc *, int);
792 u_int32_t nxe_crb_read(struct nxe_softc *, bus_size_t);
793 void nxe_crb_write(struct nxe_softc *, bus_size_t,
794 u_int32_t);
795 int nxe_crb_wait(struct nxe_softc *, bus_size_t,
796 u_int32_t, u_int32_t, u_int);
797
798 int nxe_rom_lock(struct nxe_softc *);
799 void nxe_rom_unlock(struct nxe_softc *);
800 int nxe_rom_read(struct nxe_softc *, u_int32_t,
801 u_int32_t *);
802 int nxe_rom_read_region(struct nxe_softc *, u_int32_t,
803 void *, size_t);
804
805
806
807 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
808 #define sizeofa(_a) (sizeof(_a) / sizeof((_a)[0]))
809
810
811
812 const struct pci_matchid nxe_devices[] = {
813 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_10GXxR },
814 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_10GCX4 },
815 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_4GCU },
816 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_IMEZ },
817 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_HMEZ },
818 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_IMEZ_2 },
819 { PCI_VENDOR_NETXEN, PCI_PRODUCT_NETXEN_NXB_HMEZ_2 }
820 };
821
822 const struct nxe_board nxe_boards[] = {
823 { NXE_BRDTYPE_P2_SB35_4G, NXE_0_NIU_MODE_GBE },
824 { NXE_BRDTYPE_P2_SB31_10G, NXE_0_NIU_MODE_XGE },
825 { NXE_BRDTYPE_P2_SB31_2G, NXE_0_NIU_MODE_GBE },
826 { NXE_BRDTYPE_P2_SB31_10G_IMEZ, NXE_0_NIU_MODE_XGE },
827 { NXE_BRDTYPE_P2_SB31_10G_HMEZ, NXE_0_NIU_MODE_XGE },
828 { NXE_BRDTYPE_P2_SB31_10G_CX4, NXE_0_NIU_MODE_XGE }
829 };
830
831 int
832 nxe_match(struct device *parent, void *match, void *aux)
833 {
834 struct pci_attach_args *pa = aux;
835
836 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_NETWORK)
837 return (0);
838
839 return (pci_matchbyid(pa, nxe_devices, sizeofa(nxe_devices)));
840 }
841
842 void
843 nxe_attach(struct device *parent, struct device *self, void *aux)
844 {
845 struct nxe_softc *sc = (struct nxe_softc *)self;
846 struct pci_attach_args *pa = aux;
847 pci_intr_handle_t ih;
848 struct ifnet *ifp;
849
850 sc->sc_dmat = pa->pa_dmat;
851 sc->sc_function = pa->pa_function;
852 sc->sc_window = -1;
853
854 rw_init(&sc->sc_lock, NULL);
855
856 if (nxe_pci_map(sc, pa) != 0) {
857
858 return;
859 }
860
861 nxe_crb_set(sc, 1);
862
863 if (nxe_board_info(sc) != 0) {
864
865 goto unmap;
866 }
867
868 if (nxe_user_info(sc) != 0) {
869
870 goto unmap;
871 }
872
873 if (nxe_init(sc) != 0) {
874
875 goto unmap;
876 }
877
878 if (pci_intr_map(pa, &ih) != 0) {
879 printf(": unable to map interrupt\n");
880 goto uninit;
881 }
882 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET,
883 nxe_intr, sc, DEVNAME(sc));
884 if (sc->sc_ih == NULL) {
885 printf(": unable to establish interrupt\n");
886 goto uninit;
887 }
888
889 ifp = &sc->sc_ac.ac_if;
890 ifp->if_softc = sc;
891 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
892 ifp->if_capabilities = IFCAP_VLAN_MTU;
893 ifp->if_ioctl = nxe_ioctl;
894 ifp->if_start = nxe_start;
895 ifp->if_watchdog = nxe_watchdog;
896 ifp->if_hardmtu = MCLBYTES - ETHER_HDR_LEN - ETHER_CRC_LEN;
897 strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
898 IFQ_SET_MAXLEN(&ifp->if_snd, 512);
899 IFQ_SET_READY(&ifp->if_snd);
900
901 ifmedia_init(&sc->sc_media, 0, nxe_media_change, nxe_media_status);
902 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_AUTO, 0, NULL);
903 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
904
905 if_attach(ifp);
906 ether_ifattach(ifp);
907
908 printf(": %s firmware %d.%d.%d address %s\n",
909 pci_intr_string(pa->pa_pc, ih),
910 sc->sc_fw_major, sc->sc_fw_minor, sc->sc_fw_build,
911 ether_sprintf(sc->sc_ac.ac_enaddr));
912 return;
913
914 uninit:
915 nxe_uninit(sc);
916 unmap:
917 nxe_pci_unmap(sc);
918 }
919
920 int
921 nxe_pci_map(struct nxe_softc *sc, struct pci_attach_args *pa)
922 {
923 pcireg_t memtype;
924
925 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NXE_PCI_BAR_MEM);
926 if (pci_mapreg_map(pa, NXE_PCI_BAR_MEM, memtype, 0, &sc->sc_memt,
927 &sc->sc_memh, NULL, &sc->sc_mems, 0) != 0) {
928 printf(": unable to map host registers\n");
929 return (1);
930 }
931 if (sc->sc_mems != NXE_PCI_BAR_MEM_128MB) {
932 printf(": unexpected register map size\n");
933 goto unmap_mem;
934 }
935
936
937 if (bus_space_subregion(sc->sc_memt, sc->sc_memh, NXE_MAP_CRB,
938 sc->sc_mems - NXE_MAP_CRB, &sc->sc_crbh) != 0) {
939 printf(": unable to create CRB window\n");
940 goto unmap_mem;
941 }
942
943 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NXE_PCI_BAR_DOORBELL);
944 if (pci_mapreg_map(pa, NXE_PCI_BAR_DOORBELL, memtype, 0, &sc->sc_dbt,
945 &sc->sc_dbh, NULL, &sc->sc_dbs, 0) != 0) {
946 printf(": unable to map doorbell registers\n");
947
948 goto unmap_mem;
949 }
950
951 mountroothook_establish(nxe_mountroot, sc);
952 return (0);
953
954 unmap_mem:
955 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
956 sc->sc_mems = 0;
957 return (1);
958 }
959
960 void
961 nxe_pci_unmap(struct nxe_softc *sc)
962 {
963 bus_space_unmap(sc->sc_dbt, sc->sc_dbh, sc->sc_dbs);
964 sc->sc_dbs = 0;
965
966 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
967 sc->sc_mems = 0;
968 }
969
970 int
971 nxe_intr(void *xsc)
972 {
973 return (0);
974 }
975
976 int
977 nxe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
978 {
979 struct nxe_softc *sc = ifp->if_softc;
980 struct ifreq *ifr = (struct ifreq *)addr;
981 struct ifaddr *ifa;
982 int error;
983 int s;
984
985 rw_enter_write(&sc->sc_lock);
986 s = splnet();
987
988 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
989 if (error > 0)
990 goto err;
991
992 timeout_del(&sc->sc_tick);
993
994 switch (cmd) {
995 case SIOCSIFADDR:
996 SET(ifp->if_flags, IFF_UP);
997 #ifdef INET
998 ifa = (struct ifaddr *)addr;
999 if (ifa->ifa_addr->sa_family == AF_INET)
1000 arp_ifinit(&sc->sc_ac, ifa);
1001 #endif
1002
1003 case SIOCSIFFLAGS:
1004 if (ISSET(ifp->if_flags, IFF_UP)) {
1005 if (ISSET(ifp->if_flags, IFF_RUNNING))
1006 error = ENETRESET;
1007 else
1008 nxe_up(sc);
1009 } else {
1010 if (ISSET(ifp->if_flags, IFF_RUNNING))
1011 nxe_down(sc);
1012 }
1013 break;
1014
1015 case SIOCGIFMEDIA:
1016 case SIOCSIFMEDIA:
1017 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1018 break;
1019
1020 default:
1021 error = ENOTTY;
1022 break;
1023 }
1024
1025 if (error == ENETRESET) {
1026 if (ISSET(ifp->if_flags, IFF_RUNNING)) {
1027 nxe_crb_set(sc, 0);
1028 nxe_iff(sc);
1029 nxe_crb_set(sc, 1);
1030 }
1031 error = 0;
1032 }
1033
1034 nxe_tick(sc);
1035
1036 err:
1037 splx(s);
1038 rw_exit_write(&sc->sc_lock);
1039 return (error);
1040 }
1041
1042 void
1043 nxe_up(struct nxe_softc *sc)
1044 {
1045 struct ifnet *ifp = &sc->sc_ac.ac_if;
1046 static const u_int rx_ring_sizes[] = { 16384, 1024, 128 };
1047 struct {
1048 struct nxe_ctx ctx;
1049 u_int32_t cmd_consumer;
1050 } __packed *dmamem;
1051 struct nxe_ctx *ctx;
1052 struct nxe_ctx_ring *ring;
1053 struct nxe_ring *nr;
1054 u_int64_t dva;
1055 int i;
1056
1057 if (nxe_up_fw(sc) != 0)
1058 return;
1059
1060
1061 sc->sc_tx_pkts = nxe_pkt_alloc(sc, 128, NXE_TXD_MAX_SEGS);
1062 if (sc->sc_tx_pkts == NULL)
1063 return;
1064 sc->sc_rx_pkts = nxe_pkt_alloc(sc, 128, NXE_RXD_MAX_SEGS);
1065 if (sc->sc_rx_pkts == NULL)
1066 goto free_tx_pkts;
1067
1068
1069 sc->sc_ctx = nxe_dmamem_alloc(sc, sizeof(*dmamem), PAGE_SIZE);
1070 if (sc->sc_ctx == NULL)
1071 goto free_rx_pkts;
1072
1073 dmamem = NXE_DMA_KVA(sc->sc_ctx);
1074 dva = NXE_DMA_DVA(sc->sc_ctx);
1075
1076 ctx = &dmamem->ctx;
1077 ctx->ctx_cmd_consumer_addr = htole64(dva + sizeof(dmamem->ctx));
1078 ctx->ctx_id = htole32(sc->sc_function);
1079
1080 sc->sc_cmd_consumer = &dmamem->cmd_consumer;
1081
1082
1083 sc->sc_cmd_ring = nxe_ring_alloc(sc,
1084 sizeof(struct nxe_tx_desc), 1024 );
1085 if (sc->sc_cmd_ring == NULL)
1086 goto free_ctx;
1087
1088 ctx->ctx_cmd_ring.r_addr =
1089 htole64(NXE_DMA_DVA(sc->sc_cmd_ring->nr_dmamem));
1090 ctx->ctx_cmd_ring.r_size = htole64(sc->sc_cmd_ring->nr_nentries);
1091
1092
1093 sc->sc_status_ring = nxe_ring_alloc(sc,
1094 sizeof(struct nxe_status_desc), 16384 );
1095 if (sc->sc_status_ring == NULL)
1096 goto free_cmd_ring;
1097
1098 ctx->ctx_status_ring_addr =
1099 htole64(NXE_DMA_DVA(sc->sc_status_ring->nr_dmamem));
1100 ctx->ctx_status_ring_size = htole64(sc->sc_status_ring->nr_nentries);
1101
1102
1103 for (i = 0; i < NXE_NRING; i++) {
1104 ring = &ctx->ctx_rx_rings[i];
1105 nr = nxe_ring_alloc(sc, sizeof(struct nxe_rx_desc),
1106 rx_ring_sizes[i]);
1107 if (nr == NULL)
1108 goto free_rx_rings;
1109
1110 ring->r_addr = htole64(NXE_DMA_DVA(nr->nr_dmamem));
1111 ring->r_size = htole32(nr->nr_nentries);
1112
1113 sc->sc_rx_rings[i] = nr;
1114 nxe_ring_sync(sc, sc->sc_rx_rings[i], BUS_DMASYNC_PREWRITE);
1115 }
1116
1117
1118 nxe_ring_sync(sc, sc->sc_status_ring, BUS_DMASYNC_PREREAD);
1119 nxe_ring_sync(sc, sc->sc_cmd_ring, BUS_DMASYNC_PREWRITE);
1120 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(sc->sc_ctx),
1121 0, NXE_DMA_LEN(sc->sc_ctx),
1122 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1123
1124 nxe_crb_write(sc, NXE_1_SW_CONTEXT_ADDR_LO(sc->sc_function),
1125 (u_int32_t)dva);
1126 nxe_crb_write(sc, NXE_1_SW_CONTEXT_ADDR_HI(sc->sc_function),
1127 (u_int32_t)(dva >> 32));
1128 nxe_crb_write(sc, NXE_1_SW_CONTEXT(sc->sc_port),
1129 NXE_1_SW_CONTEXT_SIG(sc->sc_port));
1130
1131 nxe_crb_set(sc, 0);
1132 nxe_lladdr(sc);
1133 nxe_iff(sc);
1134 nxe_crb_set(sc, 1);
1135
1136 SET(ifp->if_flags, IFF_RUNNING);
1137 CLR(ifp->if_flags, IFF_OACTIVE);
1138
1139
1140
1141 return;
1142
1143 free_rx_rings:
1144 while (i > 0) {
1145 i--;
1146 nxe_ring_sync(sc, sc->sc_rx_rings[i], BUS_DMASYNC_POSTWRITE);
1147 nxe_ring_free(sc, sc->sc_rx_rings[i]);
1148 }
1149
1150 nxe_ring_free(sc, sc->sc_status_ring);
1151 free_cmd_ring:
1152 nxe_ring_free(sc, sc->sc_cmd_ring);
1153 free_ctx:
1154 nxe_dmamem_free(sc, sc->sc_ctx);
1155 free_rx_pkts:
1156 nxe_pkt_free(sc, sc->sc_rx_pkts);
1157 free_tx_pkts:
1158 nxe_pkt_free(sc, sc->sc_tx_pkts);
1159 }
1160
1161 int
1162 nxe_up_fw(struct nxe_softc *sc)
1163 {
1164 u_int32_t r;
1165
1166 r = nxe_crb_read(sc, NXE_1_SW_CMDPEG_STATE);
1167 if (r == NXE_1_SW_CMDPEG_STATE_ACK)
1168 return (0);
1169
1170 if (r != NXE_1_SW_CMDPEG_STATE_DONE)
1171 return (1);
1172
1173 nxe_crb_write(sc, NXE_1_SW_NIC_CAP_HOST, NXE_1_SW_NIC_CAP_HOST_DEF);
1174 nxe_crb_write(sc, NXE_1_SW_MPORT_MODE, NXE_1_SW_MPORT_MODE_MULTI);
1175 nxe_crb_write(sc, NXE_1_SW_CMDPEG_STATE, NXE_1_SW_CMDPEG_STATE_ACK);
1176
1177
1178 if (!nxe_crb_wait(sc, NXE_1_SW_STATUS_STATE(sc->sc_function),
1179 0xffffffff, NXE_1_SW_STATUS_STATE_READY, 1000))
1180 return (1);
1181
1182 return (0);
1183 }
1184
1185 void
1186 nxe_lladdr(struct nxe_softc *sc)
1187 {
1188 u_int8_t *lladdr = sc->sc_ac.ac_enaddr;
1189
1190 DASSERT(sc->sc_window == 0);
1191
1192 nxe_crb_write(sc, NXE_0_XG_MAC_LO(sc->sc_port),
1193 (lladdr[0] << 24) | (lladdr[1] << 16));
1194 nxe_crb_write(sc, NXE_0_XG_MAC_HI(sc->sc_port),
1195 (lladdr[2] << 24) | (lladdr[3] << 16) |
1196 (lladdr[4] << 8) | (lladdr[5] << 0));
1197 }
1198
1199 void
1200 nxe_iff(struct nxe_softc *sc)
1201 {
1202 struct ifnet *ifp = &sc->sc_ac.ac_if;
1203 u_int32_t cfg1 = 0x1447;
1204
1205 DASSERT(sc->sc_window == 0);
1206
1207 CLR(ifp->if_flags, IFF_ALLMULTI);
1208 if (sc->sc_ac.ac_multirangecnt > 0 || sc->sc_ac.ac_multicnt > 0) {
1209 cfg1 |= NXE_0_XG_CFG1_MULTICAST;
1210 SET(ifp->if_flags, IFF_ALLMULTI);
1211 }
1212
1213 if (ISSET(ifp->if_flags, IFF_PROMISC))
1214 cfg1 |= NXE_0_XG_CFG1_PROMISC;
1215
1216 nxe_crb_write(sc, NXE_0_XG_CFG0(sc->sc_port),
1217 NXE_0_XG_CFG0_TX_EN | NXE_0_XG_CFG0_RX_EN);
1218 nxe_crb_write(sc, NXE_0_XG_CFG1(sc->sc_port), cfg1);
1219 }
1220
1221 void
1222 nxe_down(struct nxe_softc *sc)
1223 {
1224 struct ifnet *ifp = &sc->sc_ac.ac_if;
1225 int i;
1226
1227 CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE | IFF_ALLMULTI);
1228
1229
1230
1231 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(sc->sc_ctx),
1232 0, NXE_DMA_LEN(sc->sc_ctx),
1233 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1234 nxe_ring_sync(sc, sc->sc_cmd_ring, BUS_DMASYNC_POSTWRITE);
1235 nxe_ring_sync(sc, sc->sc_status_ring, BUS_DMASYNC_POSTREAD);
1236
1237 for (i = 0; i < NXE_NRING; i++) {
1238 nxe_ring_sync(sc, sc->sc_rx_rings[i], BUS_DMASYNC_POSTWRITE);
1239 nxe_ring_free(sc, sc->sc_rx_rings[i]);
1240 }
1241 nxe_ring_free(sc, sc->sc_status_ring);
1242 nxe_ring_free(sc, sc->sc_cmd_ring);
1243 nxe_dmamem_free(sc, sc->sc_ctx);
1244 nxe_pkt_free(sc, sc->sc_rx_pkts);
1245 nxe_pkt_free(sc, sc->sc_tx_pkts);
1246 }
1247
1248 void
1249 nxe_start(struct ifnet *ifp)
1250 {
1251 struct nxe_softc *sc = ifp->if_softc;
1252 struct nxe_ring *nr = sc->sc_cmd_ring;
1253 struct nxe_tx_desc *txd;
1254 struct nxe_pkt *pkt;
1255 struct mbuf *m;
1256 bus_dmamap_t dmap;
1257 bus_dma_segment_t *segs;
1258 int nsegs;
1259
1260 if (!ISSET(ifp->if_flags, IFF_RUNNING) ||
1261 ISSET(ifp->if_flags, IFF_OACTIVE) ||
1262 IFQ_IS_EMPTY(&ifp->if_snd))
1263 return;
1264
1265 if (nxe_ring_writeable(nr, 0 ) < NXE_TXD_DESCS) {
1266 SET(ifp->if_flags, IFF_OACTIVE);
1267 return;
1268 }
1269
1270 nxe_ring_sync(sc, nr, BUS_DMASYNC_POSTWRITE);
1271 txd = nxe_ring_cur(sc, nr);
1272 bzero(txd, sizeof(struct nxe_tx_desc));
1273
1274 do {
1275 IFQ_POLL(&ifp->if_snd, m);
1276 if (m == NULL)
1277 break;
1278
1279 pkt = nxe_pkt_get(sc->sc_tx_pkts);
1280 if (pkt == NULL) {
1281 SET(ifp->if_flags, IFF_OACTIVE);
1282 break;
1283 }
1284
1285 IFQ_DEQUEUE(&ifp->if_snd, m);
1286
1287 dmap = pkt->pkt_dmap;
1288 m = nxe_load_pkt(sc, dmap, m);
1289 if (m == NULL) {
1290 nxe_pkt_put(sc->sc_tx_pkts, pkt);
1291 ifp->if_oerrors++;
1292 break;
1293 }
1294
1295 #if NBPFILTER > 0
1296 if (ifp->if_bpf)
1297 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1298 #endif
1299
1300 pkt->pkt_m = m;
1301
1302 txd->tx_flags = htole16(NXE_TXD_F_OPCODE_TX);
1303 txd->tx_nbufs = dmap->dm_nsegs;
1304 txd->tx_length = htole16(dmap->dm_mapsize);
1305 txd->tx_id = pkt->pkt_id;
1306 txd->tx_port = sc->sc_port;
1307
1308 segs = dmap->dm_segs;
1309 nsegs = dmap->dm_nsegs;
1310 do {
1311 switch ((nsegs > NXE_TXD_SEGS) ?
1312 NXE_TXD_SEGS : nsegs) {
1313 case 4:
1314 txd->tx_addr_4 = htole64(segs[3].ds_addr);
1315 txd->tx_slen_4 = htole32(segs[3].ds_len);
1316 case 3:
1317 txd->tx_addr_3 = htole64(segs[2].ds_addr);
1318 txd->tx_slen_3 = htole32(segs[2].ds_len);
1319 case 2:
1320 txd->tx_addr_2 = htole64(segs[1].ds_addr);
1321 txd->tx_slen_2 = htole32(segs[1].ds_len);
1322 case 1:
1323 txd->tx_addr_1 = htole64(segs[0].ds_addr);
1324 txd->tx_slen_1 = htole32(segs[0].ds_len);
1325 break;
1326 default:
1327 panic("%s: unexpected segments in tx map",
1328 DEVNAME(sc));
1329 }
1330
1331 nsegs -= NXE_TXD_SEGS;
1332 segs += NXE_TXD_SEGS;
1333
1334 txd = nxe_ring_next(sc, nr);
1335 bzero(txd, sizeof(struct nxe_tx_desc));
1336 } while (nsegs > 0);
1337
1338 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1339 BUS_DMASYNC_PREWRITE);
1340
1341 ifp->if_opackets++;
1342 } while (nr->nr_ready >= NXE_TXD_DESCS);
1343
1344 nxe_ring_sync(sc, nr, BUS_DMASYNC_PREWRITE);
1345 nxe_crb_write(sc, NXE_1_SW_CMD_PRODUCER(sc->sc_function), nr->nr_slot);
1346 }
1347
1348 struct mbuf *
1349 nxe_coalesce_m(struct mbuf *m)
1350 {
1351 struct mbuf *m0;
1352
1353 MGETHDR(m0, M_DONTWAIT, MT_DATA);
1354 if (m0 == NULL)
1355 goto err;
1356
1357 if (m->m_pkthdr.len > MHLEN) {
1358 MCLGET(m0, M_DONTWAIT);
1359 if (!(m0->m_flags & M_EXT)) {
1360 m_freem(m0);
1361 m0 = NULL;
1362 goto err;
1363 }
1364 }
1365
1366 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
1367 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
1368
1369 err:
1370 m_freem(m);
1371 return (m0);
1372 }
1373
1374 struct mbuf *
1375 nxe_load_pkt(struct nxe_softc *sc, bus_dmamap_t dmap, struct mbuf *m)
1376 {
1377 switch (bus_dmamap_load_mbuf(sc->sc_dmat, dmap, m, BUS_DMA_NOWAIT)) {
1378 case 0:
1379 break;
1380
1381 case EFBIG:
1382 m = nxe_coalesce_m(m);
1383 if (m == NULL)
1384 break;
1385
1386 if (bus_dmamap_load_mbuf(sc->sc_dmat, dmap, m,
1387 BUS_DMA_NOWAIT) == 0)
1388 break;
1389
1390
1391
1392 default:
1393 m_freem(m);
1394 m = NULL;
1395 break;
1396 }
1397
1398 return (m);
1399 }
1400
1401 void
1402 nxe_watchdog(struct ifnet *ifp)
1403 {
1404
1405 }
1406
1407 int
1408 nxe_media_change(struct ifnet *ifp)
1409 {
1410
1411 return (0);
1412 }
1413
1414 void
1415 nxe_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1416 {
1417 struct nxe_softc *sc = ifp->if_softc;
1418
1419 imr->ifm_active = IFM_ETHER | IFM_AUTO;
1420 imr->ifm_status = IFM_AVALID;
1421
1422 nxe_link_state(sc);
1423 if (LINK_STATE_IS_UP(ifp->if_link_state))
1424 imr->ifm_status |= IFM_ACTIVE;
1425 }
1426
1427 void
1428 nxe_link_state(struct nxe_softc *sc)
1429 {
1430 struct ifnet *ifp = &sc->sc_ac.ac_if;
1431 int link_state = LINK_STATE_DOWN;
1432 u_int32_t r;
1433
1434 DASSERT(sc->sc_window == 1);
1435
1436 r = nxe_crb_read(sc, NXE_1_SW_XG_STATE);
1437 if (NXE_1_SW_XG_STATE_PORT(r, sc->sc_function) & NXE_1_SW_XG_STATE_UP)
1438 link_state = LINK_STATE_UP;
1439
1440 if (ifp->if_link_state != link_state) {
1441 ifp->if_link_state = link_state;
1442 if_link_state_change(ifp);
1443 }
1444 }
1445
1446 int
1447 nxe_board_info(struct nxe_softc *sc)
1448 {
1449 struct nxe_info *ni;
1450 int rv = 1;
1451 int i;
1452
1453 ni = malloc(sizeof(struct nxe_info), M_NOWAIT, M_TEMP);
1454 if (ni == NULL) {
1455 printf(": unable to allocate temporary memory\n");
1456 return (1);
1457 }
1458
1459 if (nxe_rom_read_region(sc, NXE_FLASH_BRDCFG, ni,
1460 sizeof(struct nxe_info)) != 0) {
1461 printf(": unable to read board info\n");
1462 goto out;
1463 }
1464
1465 if (ni->ni_hdrver != NXE_INFO_HDRVER_1) {
1466 printf(": unexpected board info header version 0x%08x\n",
1467 ni->ni_hdrver);
1468 goto out;
1469 }
1470 if (ni->ni_magic != NXE_INFO_MAGIC) {
1471 printf(": board info magic is invalid\n");
1472 goto out;
1473 }
1474
1475 for (i = 0; i < sizeofa(nxe_boards); i++) {
1476 if (ni->ni_board_type == nxe_boards[i].brd_type) {
1477 sc->sc_board = &nxe_boards[i];
1478 break;
1479 }
1480 }
1481 if (sc->sc_board == NULL) {
1482 printf(": unknown board type %04x\n", ni->ni_board_type);
1483 goto out;
1484 }
1485
1486 rv = 0;
1487 out:
1488 free(ni, M_TEMP);
1489 return (rv);
1490 }
1491
1492 int
1493 nxe_user_info(struct nxe_softc *sc)
1494 {
1495 struct nxe_userinfo *nu;
1496 u_int64_t lladdr;
1497 struct nxe_lladdr *la;
1498 int rv = 1;
1499
1500 nu = malloc(sizeof(struct nxe_userinfo), M_NOWAIT, M_TEMP);
1501 if (nu == NULL) {
1502 printf(": unable to allocate temp memory\n");
1503 return (1);
1504 }
1505 if (nxe_rom_read_region(sc, NXE_FLASH_USER, nu,
1506 sizeof(struct nxe_userinfo)) != 0) {
1507 printf(": unable to read user info\n");
1508 goto out;
1509 }
1510
1511 sc->sc_fw_major = nu->nu_imageinfo.nim_img_ver_major;
1512 sc->sc_fw_minor = nu->nu_imageinfo.nim_img_ver_minor;
1513 sc->sc_fw_build = letoh16(nu->nu_imageinfo.nim_img_ver_build);
1514
1515 if (sc->sc_fw_major > NXE_VERSION_MAJOR ||
1516 sc->sc_fw_major < NXE_VERSION_MAJOR ||
1517 sc->sc_fw_minor > NXE_VERSION_MINOR ||
1518 sc->sc_fw_minor < NXE_VERSION_MINOR) {
1519 printf(": firmware %d.%d.%d is unsupported by this driver\n",
1520 sc->sc_fw_major, sc->sc_fw_minor, sc->sc_fw_build);
1521 goto out;
1522 }
1523
1524 lladdr = swap64(nu->nu_lladdr[sc->sc_function][0]);
1525 la = (struct nxe_lladdr *)&lladdr;
1526 bcopy(la->lladdr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
1527
1528 rv = 0;
1529 out:
1530 free(nu, M_TEMP);
1531 return (rv);
1532 }
1533
1534 int
1535 nxe_init(struct nxe_softc *sc)
1536 {
1537 u_int64_t dva;
1538 u_int32_t r;
1539
1540
1541 nxe_crb_write(sc, NXE_1_SW_CMD_PRODUCER(sc->sc_function), 0);
1542 nxe_crb_write(sc, NXE_1_SW_CMD_CONSUMER(sc->sc_function), 0);
1543 nxe_crb_write(sc, NXE_1_SW_CMD_ADDR_HI, 0);
1544 nxe_crb_write(sc, NXE_1_SW_CMD_ADDR_LO, 0);
1545
1546
1547
1548
1549
1550 if (sc->sc_function == 0) {
1551
1552 sc->sc_dummy_dma = nxe_dmamem_alloc(sc,
1553 NXE_1_SW_DUMMY_ADDR_LEN, PAGE_SIZE);
1554 if (sc->sc_dummy_dma == NULL) {
1555 printf(": unable to allocate dummy memory\n");
1556 return (1);
1557 }
1558
1559 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(sc->sc_dummy_dma),
1560 0, NXE_DMA_LEN(sc->sc_dummy_dma), BUS_DMASYNC_PREREAD);
1561
1562 dva = NXE_DMA_DVA(sc->sc_dummy_dma);
1563 nxe_crb_write(sc, NXE_1_SW_DUMMY_ADDR_HI, dva >> 32);
1564 nxe_crb_write(sc, NXE_1_SW_DUMMY_ADDR_LO, dva);
1565
1566 r = nxe_crb_read(sc, NXE_1_SW_BOOTLD_CONFIG);
1567 if (r == 0x55555555) {
1568 r = nxe_crb_read(sc, NXE_1_ROMUSB_SW_RESET);
1569 if (r != NXE_1_ROMUSB_SW_RESET_BOOT) {
1570 printf(": unexpected boot state\n");
1571 goto err;
1572 }
1573
1574
1575 nxe_crb_write(sc, NXE_1_SW_BOOTLD_CONFIG, 0);
1576 }
1577
1578
1579 nxe_crb_write(sc, NXE_1_SW_DRIVER_VER, NXE_VERSION);
1580 nxe_crb_write(sc, NXE_1_GLB_PEGTUNE, NXE_1_GLB_PEGTUNE_DONE);
1581
1582
1583
1584
1585
1586 }
1587
1588 return (0);
1589
1590 err:
1591 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(sc->sc_dummy_dma),
1592 0, NXE_DMA_LEN(sc->sc_dummy_dma), BUS_DMASYNC_POSTREAD);
1593 nxe_dmamem_free(sc, sc->sc_dummy_dma);
1594 return (1);
1595 }
1596
1597 void
1598 nxe_uninit(struct nxe_softc *sc)
1599 {
1600 if (sc->sc_function == 0) {
1601 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(sc->sc_dummy_dma),
1602 0, NXE_DMA_LEN(sc->sc_dummy_dma), BUS_DMASYNC_POSTREAD);
1603 nxe_dmamem_free(sc, sc->sc_dummy_dma);
1604 }
1605 }
1606
1607 void
1608 nxe_mountroot(void *arg)
1609 {
1610 struct nxe_softc *sc = arg;
1611
1612 DASSERT(sc->sc_window == 1);
1613
1614 if (!nxe_crb_wait(sc, NXE_1_SW_CMDPEG_STATE, 0xffffffff,
1615 NXE_1_SW_CMDPEG_STATE_DONE, 10000)) {
1616 printf("%s: firmware bootstrap failed, code 0x%08x\n",
1617 DEVNAME(sc), nxe_crb_read(sc, NXE_1_SW_CMDPEG_STATE));
1618 return;
1619 }
1620
1621 sc->sc_port = nxe_crb_read(sc, NXE_1_SW_V2P(sc->sc_function));
1622 if (sc->sc_port == 0x55555555)
1623 sc->sc_port = sc->sc_function;
1624
1625 nxe_crb_write(sc, NXE_1_SW_NIC_CAP_HOST, NXE_1_SW_NIC_CAP_HOST_DEF);
1626 nxe_crb_write(sc, NXE_1_SW_MPORT_MODE, NXE_1_SW_MPORT_MODE_MULTI);
1627 nxe_crb_write(sc, NXE_1_SW_CMDPEG_STATE, NXE_1_SW_CMDPEG_STATE_ACK);
1628
1629 sc->sc_sensor.type = SENSOR_TEMP;
1630 strlcpy(sc->sc_sensor_dev.xname, DEVNAME(sc),
1631 sizeof(sc->sc_sensor_dev.xname));
1632 sensor_attach(&sc->sc_sensor_dev, &sc->sc_sensor);
1633 sensordev_install(&sc->sc_sensor_dev);
1634
1635 timeout_set(&sc->sc_tick, nxe_tick, sc);
1636 nxe_tick(sc);
1637 }
1638
1639 void
1640 nxe_tick(void *xsc)
1641 {
1642 struct nxe_softc *sc = xsc;
1643 u_int32_t temp;
1644 int window;
1645 int s;
1646
1647 s = splnet();
1648 window = nxe_crb_set(sc, 1);
1649 temp = nxe_crb_read(sc, NXE_1_SW_TEMP);
1650 nxe_link_state(sc);
1651 nxe_crb_set(sc, window);
1652 splx(s);
1653
1654 sc->sc_sensor.value = NXE_1_SW_TEMP_VAL(temp) * 1000000 + 273150000;
1655 sc->sc_sensor.flags = 0;
1656
1657 switch (NXE_1_SW_TEMP_STATE(temp)) {
1658 case NXE_1_SW_TEMP_STATE_NONE:
1659 sc->sc_sensor.status = SENSOR_S_UNSPEC;
1660 break;
1661 case NXE_1_SW_TEMP_STATE_OK:
1662 sc->sc_sensor.status = SENSOR_S_OK;
1663 break;
1664 case NXE_1_SW_TEMP_STATE_WARN:
1665 sc->sc_sensor.status = SENSOR_S_WARN;
1666 break;
1667 case NXE_1_SW_TEMP_STATE_CRIT:
1668
1669 sc->sc_sensor.status = SENSOR_S_CRIT;
1670 break;
1671 default:
1672 sc->sc_sensor.flags = SENSOR_FUNKNOWN;
1673 break;
1674 }
1675
1676 timeout_add(&sc->sc_tick, hz * 5);
1677 }
1678
1679
1680 struct nxe_ring *
1681 nxe_ring_alloc(struct nxe_softc *sc, size_t desclen, u_int nentries)
1682 {
1683 struct nxe_ring *nr;
1684
1685 nr = malloc(sizeof(struct nxe_ring), M_DEVBUF, M_WAITOK);
1686
1687 nr->nr_dmamem = nxe_dmamem_alloc(sc, desclen * nentries, PAGE_SIZE);
1688 if (nr->nr_dmamem == NULL) {
1689 free(nr, M_DEVBUF);
1690 return (NULL);
1691 }
1692
1693 nr->nr_pos = NXE_DMA_KVA(nr->nr_dmamem);
1694 nr->nr_slot = 0;
1695 nr->nr_desclen = desclen;
1696 nr->nr_nentries = nentries;
1697
1698 return (nr);
1699 }
1700
1701 void
1702 nxe_ring_sync(struct nxe_softc *sc, struct nxe_ring *nr, int flags)
1703 {
1704 bus_dmamap_sync(sc->sc_dmat, NXE_DMA_MAP(nr->nr_dmamem),
1705 0, NXE_DMA_LEN(nr->nr_dmamem), flags);
1706 }
1707
1708 void
1709 nxe_ring_free(struct nxe_softc *sc, struct nxe_ring *nr)
1710 {
1711 nxe_dmamem_free(sc, nr->nr_dmamem);
1712 free(nr, M_DEVBUF);
1713 }
1714
1715 int
1716 nxe_ring_readable(struct nxe_ring *nr, int producer)
1717 {
1718 nr->nr_ready = producer - nr->nr_slot;
1719 if (nr->nr_ready < 0)
1720 nr->nr_ready += nr->nr_nentries;
1721
1722 return (nr->nr_ready);
1723 }
1724
1725 int
1726 nxe_ring_writeable(struct nxe_ring *nr, int consumer)
1727 {
1728 nr->nr_ready = consumer - nr->nr_slot;
1729 if (nr->nr_ready <= 0)
1730 nr->nr_ready += nr->nr_nentries;
1731
1732 return (nr->nr_ready);
1733 }
1734
1735 void *
1736 nxe_ring_cur(struct nxe_softc *sc, struct nxe_ring *nr)
1737 {
1738 return (nr->nr_pos);
1739 }
1740
1741 void *
1742 nxe_ring_next(struct nxe_softc *sc, struct nxe_ring *nr)
1743 {
1744 if (++nr->nr_slot >= nr->nr_nentries) {
1745 nr->nr_slot = 0;
1746 nr->nr_pos = NXE_DMA_KVA(nr->nr_dmamem);
1747 } else
1748 nr->nr_pos += nr->nr_desclen;
1749
1750 nr->nr_ready--;
1751
1752 return (nr->nr_pos);
1753 }
1754
1755 struct nxe_pkt_list *
1756 nxe_pkt_alloc(struct nxe_softc *sc, u_int npkts, int nsegs)
1757 {
1758 struct nxe_pkt_list *npl;
1759 struct nxe_pkt *pkt;
1760 int i;
1761
1762 npl = malloc(sizeof(struct nxe_pkt_list), M_DEVBUF, M_WAITOK);
1763 bzero(npl, sizeof(struct nxe_pkt_list));
1764
1765 pkt = malloc(sizeof(struct nxe_pkt) * npkts, M_DEVBUF, M_WAITOK);
1766 bzero(pkt, sizeof(struct nxe_pkt) * npkts);
1767
1768 npl->npl_pkts = pkt;
1769 TAILQ_INIT(&npl->npl_free);
1770 TAILQ_INIT(&npl->npl_used);
1771 for (i = 0; i < npkts; i++) {
1772 pkt = &npl->npl_pkts[i];
1773
1774 pkt->pkt_id = i;
1775 if (bus_dmamap_create(sc->sc_dmat, NXE_MAX_PKTLEN, nsegs,
1776 NXE_MAX_PKTLEN, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
1777 &pkt->pkt_dmap) != 0) {
1778 nxe_pkt_free(sc, npl);
1779 return (NULL);
1780 }
1781
1782 TAILQ_INSERT_TAIL(&npl->npl_free, pkt, pkt_link);
1783 }
1784
1785 return (npl);
1786 }
1787
1788 void
1789 nxe_pkt_free(struct nxe_softc *sc, struct nxe_pkt_list *npl)
1790 {
1791 struct nxe_pkt *pkt;
1792
1793 while ((pkt = nxe_pkt_get(npl)) != NULL)
1794 bus_dmamap_destroy(sc->sc_dmat, pkt->pkt_dmap);
1795
1796 free(npl->npl_pkts, M_DEVBUF);
1797 free(npl, M_DEVBUF);
1798 }
1799
1800 struct nxe_pkt *
1801 nxe_pkt_get(struct nxe_pkt_list *npl)
1802 {
1803 struct nxe_pkt *pkt;
1804
1805 pkt = TAILQ_FIRST(&npl->npl_free);
1806 if (pkt != NULL) {
1807 TAILQ_REMOVE(&npl->npl_free, pkt, pkt_link);
1808 TAILQ_INSERT_TAIL(&npl->npl_used, pkt, pkt_link);
1809 }
1810
1811 return (pkt);
1812 }
1813
1814 void
1815 nxe_pkt_put(struct nxe_pkt_list *npl, struct nxe_pkt *pkt)
1816 {
1817 TAILQ_REMOVE(&npl->npl_used, pkt, pkt_link);
1818 TAILQ_INSERT_TAIL(&npl->npl_free, pkt, pkt_link);
1819
1820 }
1821
1822 struct nxe_pkt *
1823 nxe_pkt_used(struct nxe_pkt_list *npl)
1824 {
1825 return (TAILQ_FIRST(&npl->npl_used));
1826 }
1827
1828 struct nxe_dmamem *
1829 nxe_dmamem_alloc(struct nxe_softc *sc, bus_size_t size, bus_size_t align)
1830 {
1831 struct nxe_dmamem *ndm;
1832 int nsegs;
1833
1834 ndm = malloc(sizeof(struct nxe_dmamem), M_DEVBUF, M_WAITOK);
1835 bzero(ndm, sizeof(struct nxe_dmamem));
1836 ndm->ndm_size = size;
1837
1838 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
1839 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &ndm->ndm_map) != 0)
1840 goto ndmfree;
1841
1842 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &ndm->ndm_seg, 1,
1843 &nsegs, BUS_DMA_WAITOK) != 0)
1844 goto destroy;
1845
1846 if (bus_dmamem_map(sc->sc_dmat, &ndm->ndm_seg, nsegs, size,
1847 &ndm->ndm_kva, BUS_DMA_WAITOK) != 0)
1848 goto free;
1849
1850 if (bus_dmamap_load(sc->sc_dmat, ndm->ndm_map, ndm->ndm_kva, size,
1851 NULL, BUS_DMA_WAITOK) != 0)
1852 goto unmap;
1853
1854 bzero(ndm->ndm_kva, size);
1855
1856 return (ndm);
1857
1858 unmap:
1859 bus_dmamem_unmap(sc->sc_dmat, ndm->ndm_kva, size);
1860 free:
1861 bus_dmamem_free(sc->sc_dmat, &ndm->ndm_seg, 1);
1862 destroy:
1863 bus_dmamap_destroy(sc->sc_dmat, ndm->ndm_map);
1864 ndmfree:
1865 free(ndm, M_DEVBUF);
1866
1867 return (NULL);
1868 }
1869
1870 void
1871 nxe_dmamem_free(struct nxe_softc *sc, struct nxe_dmamem *ndm)
1872 {
1873 bus_dmamem_unmap(sc->sc_dmat, ndm->ndm_kva, ndm->ndm_size);
1874 bus_dmamem_free(sc->sc_dmat, &ndm->ndm_seg, 1);
1875 bus_dmamap_destroy(sc->sc_dmat, ndm->ndm_map);
1876 free(ndm, M_DEVBUF);
1877 }
1878
1879 u_int32_t
1880 nxe_read(struct nxe_softc *sc, bus_size_t r)
1881 {
1882 bus_space_barrier(sc->sc_memt, sc->sc_memh, r, 4,
1883 BUS_SPACE_BARRIER_READ);
1884 return (bus_space_read_4(sc->sc_memt, sc->sc_memh, r));
1885 }
1886
1887 void
1888 nxe_write(struct nxe_softc *sc, bus_size_t r, u_int32_t v)
1889 {
1890 bus_space_write_4(sc->sc_memt, sc->sc_memh, r, v);
1891 bus_space_barrier(sc->sc_memt, sc->sc_memh, r, 4,
1892 BUS_SPACE_BARRIER_WRITE);
1893 }
1894
1895 int
1896 nxe_wait(struct nxe_softc *sc, bus_size_t r, u_int32_t m, u_int32_t v,
1897 u_int timeout)
1898 {
1899 while ((nxe_read(sc, r) & m) != v) {
1900 if (timeout == 0)
1901 return (0);
1902
1903 delay(1000);
1904 timeout--;
1905 }
1906
1907 return (1);
1908 }
1909
1910 int
1911 nxe_crb_set(struct nxe_softc *sc, int window)
1912 {
1913 int oldwindow = sc->sc_window;
1914
1915 if (sc->sc_window != window) {
1916 sc->sc_window = window;
1917
1918 nxe_write(sc, NXE_WIN_CRB(sc->sc_function),
1919 window ? NXE_WIN_CRB_1 : NXE_WIN_CRB_0);
1920 }
1921
1922 return (oldwindow);
1923 }
1924
1925 u_int32_t
1926 nxe_crb_read(struct nxe_softc *sc, bus_size_t r)
1927 {
1928 bus_space_barrier(sc->sc_memt, sc->sc_crbh, r, 4,
1929 BUS_SPACE_BARRIER_READ);
1930 return (bus_space_read_4(sc->sc_memt, sc->sc_crbh, r));
1931 }
1932
1933 void
1934 nxe_crb_write(struct nxe_softc *sc, bus_size_t r, u_int32_t v)
1935 {
1936 bus_space_write_4(sc->sc_memt, sc->sc_crbh, r, v);
1937 bus_space_barrier(sc->sc_memt, sc->sc_crbh, r, 4,
1938 BUS_SPACE_BARRIER_WRITE);
1939 }
1940
1941 int
1942 nxe_crb_wait(struct nxe_softc *sc, bus_size_t r, u_int32_t m, u_int32_t v,
1943 u_int timeout)
1944 {
1945 while ((nxe_crb_read(sc, r) & m) != v) {
1946 if (timeout == 0)
1947 return (0);
1948
1949 delay(1000);
1950 timeout--;
1951 }
1952
1953 return (1);
1954 }
1955
1956 int
1957 nxe_rom_lock(struct nxe_softc *sc)
1958 {
1959 if (!nxe_wait(sc, NXE_SEM_ROM_LOCK, 0xffffffff,
1960 NXE_SEM_DONE, 10000))
1961 return (1);
1962 nxe_crb_write(sc, NXE_1_SW_ROM_LOCK_ID, NXE_1_SW_ROM_LOCK_ID);
1963
1964 return (0);
1965 }
1966
1967 void
1968 nxe_rom_unlock(struct nxe_softc *sc)
1969 {
1970 nxe_read(sc, NXE_SEM_ROM_UNLOCK);
1971 }
1972
1973 int
1974 nxe_rom_read(struct nxe_softc *sc, u_int32_t r, u_int32_t *v)
1975 {
1976 int rv = 1;
1977
1978 DASSERT(sc->sc_window == 1);
1979
1980 if (nxe_rom_lock(sc) != 0)
1981 return (1);
1982
1983
1984 nxe_crb_write(sc, NXE_1_ROM_ADDR, r);
1985
1986
1987 nxe_crb_write(sc, NXE_1_ROM_ABYTE_CNT, 3);
1988 delay(100);
1989 nxe_crb_write(sc, NXE_1_ROM_DBYTE_CNT, 0);
1990
1991
1992 nxe_crb_write(sc, NXE_1_ROM_OPCODE, NXE_1_ROM_OPCODE_READ);
1993 if (!nxe_crb_wait(sc, NXE_1_ROMUSB_STATUS, NXE_1_ROMUSB_STATUS_DONE,
1994 NXE_1_ROMUSB_STATUS_DONE, 100))
1995 goto err;
1996
1997
1998 nxe_crb_write(sc, NXE_1_ROM_ABYTE_CNT, 0);
1999 delay(100);
2000 nxe_crb_write(sc, NXE_1_ROM_DBYTE_CNT, 0);
2001
2002 *v = nxe_crb_read(sc, NXE_1_ROM_RDATA);
2003
2004 rv = 0;
2005 err:
2006 nxe_rom_unlock(sc);
2007 return (rv);
2008 }
2009
2010 int
2011 nxe_rom_read_region(struct nxe_softc *sc, u_int32_t r, void *buf,
2012 size_t buflen)
2013 {
2014 u_int32_t *databuf = buf;
2015 int i;
2016
2017 #ifdef NXE_DEBUG
2018 if ((buflen % 4) != 0)
2019 panic("nxe_read_rom_region: buflen is wrong (%d)", buflen);
2020 #endif
2021
2022 buflen = buflen / 4;
2023 for (i = 0; i < buflen; i++) {
2024 if (nxe_rom_read(sc, r, &databuf[i]) != 0)
2025 return (1);
2026
2027 r += sizeof(u_int32_t);
2028 }
2029
2030 return (0);
2031 }