Annotation of sys/dev/pci/if_nxe.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_nxe.c,v 1.40 2007/08/15 10:24:54 dlg Exp $ */
2:
3: /*
4: * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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: /* this driver likes firmwares around this version */
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: * PCI configuration space registers
75: */
76:
77: #define NXE_PCI_BAR_MEM 0x10 /* bar 0 */
78: #define NXE_PCI_BAR_MEM_128MB (128 * 1024 * 1024)
79: #define NXE_PCI_BAR_DOORBELL 0x20 /* bar 4 */
80:
81: /*
82: * doorbell register space
83: */
84:
85: #define NXE_DB 0x00000000
86: #define NXE_DB_PEGID 0x00000003
87: #define NXE_DB_PEGID_RX 0x00000001 /* rx unit */
88: #define NXE_DB_PEGID_TX 0x00000002 /* tx unit */
89: #define NXE_DB_PRIVID 0x00000004 /* must be set */
90: #define NXE_DB_COUNT(_c) ((_c)<<3) /* count */
91: #define NXE_DB_CTXID(_c) ((_c)<<18) /* context id */
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: * register space
101: */
102:
103: /* different PCI functions use different registers sometimes */
104: #define _F(_f) ((_f) * 0x20)
105:
106: /*
107: * driver ref section 4.2
108: *
109: * All the hardware registers are mapped in memory. Apart from the registers
110: * for the individual hardware blocks, the memory map includes a large number
111: * of software definable registers.
112: *
113: * The following table gives the memory map in the PCI address space.
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: * Since there are a large number of registers they do not fit in a single
126: * PCI addressing range. Hence two windows are defined. The window starts at
127: * NXE_MAP_CRB, and extends to the end of the register map. The window is set
128: * using the NXE_REG_WINDOW_CRB register. The format of the NXE_REG_WINDOW_CRB
129: * register is as follows:
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: * The memory map inside the register windows are divided into a set of blocks.
138: * Each register block is owned by one hardware agent. The following table
139: * gives the memory map of the various register blocks in window 0. These
140: * registers are all in the CRB register space, so the offsets given here are
141: * relative to the base of the CRB offset region (NXE_MAP_CRB).
142: */
143:
144: #define NXE_W0_PCIE 0x00100000 /* PCI Express */
145: #define NXE_W0_NIU 0x00600000 /* Network Interface Unit */
146: #define NXE_W0_PPE_0 0x01100000 /* Protocol Processing Engine 0 */
147: #define NXE_W0_PPE_1 0x01200000 /* Protocol Processing Engine 1 */
148: #define NXE_W0_PPE_2 0x01300000 /* Protocol Processing Engine 2 */
149: #define NXE_W0_PPE_3 0x01400000 /* Protocol Processing Engine 3 */
150: #define NXE_W0_PPE_D 0x01500000 /* PPE D-cache */
151: #define NXE_W0_PPE_I 0x01600000 /* PPE I-cache */
152:
153: /*
154: * These are the register blocks inside window 1.
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: * Global registers
164: */
165: #define NXE_BOOTLD_START 0x00010000
166:
167:
168: /*
169: * driver ref section 5
170: *
171: * CRB Window Register Descriptions
172: */
173:
174: /*
175: * PCI Express Registers
176: *
177: * Despite being in the CRB window space, they can be accessed via both
178: * windows. This means they are accessable "globally" without going relative
179: * to the start of the CRB window space.
180: */
181:
182: /* Interrupts */
183: #define NXE_ISR_VECTOR 0x06110100 /* Interrupt Vector */
184: #define NXE_ISR_VECTOR_FUNC(_f) (0x08 << (_f))
185: #define NXE_ISR_MASK 0x06110104 /* Interrupt Mask */
186: #define NXE_ISR_TARGET_STATUS 0x06110118
187: #define NXE_ISR_TARGET_MASK 0x06110128
188:
189: /* lock registers (semaphores between chipset and driver) */
190: #define NXE_SEM_ROM_LOCK 0x0611c010 /* ROM access lock */
191: #define NXE_SEM_ROM_UNLOCK 0x0611c014
192: #define NXE_SEM_PHY_LOCK 0x0611c018 /* PHY access lock */
193: #define NXE_SEM_PHY_UNLOCK 0x0611c01c
194: #define NXE_SEM_DONE 0x1
195:
196: /*
197: * Network Interface Unit (NIU) Registers
198: */
199:
200: #define NXE_0_NIU_MODE 0x00600000
201: #define NXE_0_NIU_MODE_XGE (1<<2) /* XGE interface enabled */
202: #define NXE_0_NIU_MODE_GBE (1<<1) /* 4 GbE interfaces enabled */
203: #define NXE_0_NIU_SINGLE_TERM 0x00600004
204:
205: #define NXE_0_NIU_RESET_XG 0x0060001c /* reset XG */
206: #define NXE_0_NIU_RESET_FIFO 0x00600088 /* reset sys fifos */
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) /* TX enable */
212: #define NXE_0_XG_CFG0_TX_SYNC (1<<1) /* TX synced */
213: #define NXE_0_XG_CFG0_RX_EN (1<<2) /* RX enable */
214: #define NXE_0_XG_CFG0_RX_SYNC (1<<3) /* RX synced */
215: #define NXE_0_XG_CFG0_TX_FLOWCTL (1<<4) /* enable pause frame gen */
216: #define NXE_0_XG_CFG0_RX_FLOWCTL (1<<5) /* act on rxed pause frames */
217: #define NXE_0_XG_CFG0_LOOPBACK (1<<8) /* tx appears on rx */
218: #define NXE_0_XG_CFG0_TX_RST_PB (1<<15) /* reset frm tx proto block */
219: #define NXE_0_XG_CFG0_RX_RST_PB (1<<16) /* reset frm rx proto block */
220: #define NXE_0_XG_CFG0_TX_RST_MAC (1<<17) /* reset frm tx multiplexer */
221: #define NXE_0_XG_CFG0_RX_RST_MAC (1<<18) /* reset ctl frms and timers */
222: #define NXE_0_XG_CFG0_SOFT_RST (1<<31) /* soft reset */
223: #define NXE_0_XG_CFG1(_p) (0x00670004 + _P(_p))
224: #define NXE_0_XG_CFG1_REM_CRC (1<<0) /* enable crc removal */
225: #define NXE_0_XG_CFG1_CRC_EN (1<<1) /* append crc to tx frames */
226: #define NXE_0_XG_CFG1_NO_MAX (1<<5) /* rx all frames despite size */
227: #define NXE_0_XG_CFG1_WIRE_LO_ERR (1<<6) /* recognize local err */
228: #define NXE_0_XG_CFG1_PAUSE_FR_DIS (1<<8) /* disable pause frame detect */
229: #define NXE_0_XG_CFG1_SEQ_ERR_EN (1<<10) /* enable seq err detection */
230: #define NXE_0_XG_CFG1_MULTICAST (1<<12) /* accept all multicast */
231: #define NXE_0_XG_CFG1_PROMISC (1<<13) /* accept all multicast */
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: * Software Defined Registers
237: */
238:
239: /* chipset state registers */
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: /* firmware version */
246: #define NXE_1_SW_FWVER_MAJOR 0x00202150 /* Major f/w version */
247: #define NXE_1_SW_FWVER_MINOR 0x00202154 /* Minor f/w version */
248: #define NXE_1_SW_FWVER_BUILD 0x00202158 /* Build/Sub f/w version */
249:
250: /* misc */
251: #define NXE_1_SW_CMD_ADDR_HI 0x00202218 /* cmd ring phys addr */
252: #define NXE_1_SW_CMD_ADDR_LO 0x0020221c /* cmd ring phys addr */
253: #define NXE_1_SW_CMD_SIZE 0x002022c8 /* entries in the cmd ring */
254: #define NXE_1_SW_DUMMY_ADDR_HI 0x0020223c /* hi address of dummy buf */
255: #define NXE_1_SW_DUMMY_ADDR_LO 0x00202240 /* lo address of dummy buf */
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 /* init status */
321: #define NXE_1_SW_CMDPEG_STATE_START 0xff00 /* init starting */
322: #define NXE_1_SW_CMDPEG_STATE_DONE 0xff01 /* init complete */
323: #define NXE_1_SW_CMDPEG_STATE_ACK 0xf00f /* init ack */
324: #define NXE_1_SW_CMDPEG_STATE_ERROR 0xffff /* init failed */
325:
326: #define NXE_1_SW_XG_STATE 0x00202294 /* phy state */
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 /* host capabilities */
336: #define NXE_1_SW_NIC_CAP_HOST_DEF 0x1 /* nfi */
337:
338: #define NXE_1_SW_DRIVER_VER 0x002024a0 /* host driver version */
339:
340:
341: #define NXE_1_SW_TEMP 0x002023b4 /* Temperature sensor */
342: #define NXE_1_SW_TEMP_STATE(_x) ((_x)&0xffff) /* Temp state */
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) /* Temp value */
348:
349: #define NXE_1_SW_V2P(_f) (0x00202490+((_f)*4)) /* virtual to phys */
350:
351: /*
352: * ROMUSB Registers
353: */
354: #define NXE_1_ROMUSB_STATUS 0x01300004 /* ROM Status */
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 /* reset register */
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: /* ROM Registers */
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 /* dummy byte count */
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: * flash memory layout
386: *
387: * These are offsets of memory accessable via the ROM Registers above
388: */
389: #define NXE_FLASH_CRBINIT 0x00000000 /* crb init section */
390: #define NXE_FLASH_BRDCFG 0x00004000 /* board config */
391: #define NXE_FLASH_INITCODE 0x00006000 /* pegtune code */
392: #define NXE_FLASH_BOOTLD 0x00010000 /* boot loader */
393: #define NXE_FLASH_IMAGE 0x00043000 /* compressed image */
394: #define NXE_FLASH_SECONDARY 0x00200000 /* backup image */
395: #define NXE_FLASH_PXE 0x003d0000 /* pxe image */
396: #define NXE_FLASH_USER 0x003e8000 /* user region for new boards */
397: #define NXE_FLASH_VPD 0x003e8c00 /* vendor private data */
398: #define NXE_FLASH_LICENSE 0x003e9000 /* firmware license */
399: #define NXE_FLASH_FIXED 0x003f0000 /* backup of crbinit */
400:
401:
402: /*
403: * misc hardware details
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: * hardware structures
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: /* hw structures actually used in the io path */
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; /* XXX who makes a 24bit field? */
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; /* packet length */
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: * driver definitions
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: * autoconf glue
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: /* allocations for the hw */
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: /* monitoring */
700: struct timeout sc_tick;
701: struct ksensor sc_sensor;
702: struct ksensordev sc_sensor_dev;
703:
704: /* ioctl lock */
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: /* init code */
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: /* chip state */
736: void nxe_tick(void *);
737: void nxe_link_state(struct nxe_softc *);
738:
739: /* interface operations */
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: /* ifmedia operations */
752: int nxe_media_change(struct ifnet *);
753: void nxe_media_status(struct ifnet *, struct ifmediareq *);
754:
755:
756: /* ring handling */
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: /* pkts */
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: /* wrapper around dmaable memory allocations */
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: /* low level hardware access goo */
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: /* misc bits */
807: #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
808: #define sizeofa(_a) (sizeof(_a) / sizeof((_a)[0]))
809:
810: /* let's go! */
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: /* error already printed by nxe_pci_map() */
858: return;
859: }
860:
861: nxe_crb_set(sc, 1);
862:
863: if (nxe_board_info(sc) != 0) {
864: /* error already printed by nxe_board_info() */
865: goto unmap;
866: }
867:
868: if (nxe_user_info(sc) != 0) {
869: /* error already printed by nxe_board_info() */
870: goto unmap;
871: }
872:
873: if (nxe_init(sc) != 0) {
874: /* error already printed by nxe_init() */
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); /* XXX */
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: /* set up the CRB window */
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: /* bus_space(9) says i dont have to unmap subregions */
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: /* bus_space(9) says i dont have to unmap the crb subregion */
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: /* FALLTHROUGH */
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: /* allocate pkt lists */
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: /* allocate the context memory and the consumer field */
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: /* allocate the cmd/tx ring */
1083: sc->sc_cmd_ring = nxe_ring_alloc(sc,
1084: sizeof(struct nxe_tx_desc), 1024 /* XXX */);
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: /* allocate the status ring */
1093: sc->sc_status_ring = nxe_ring_alloc(sc,
1094: sizeof(struct nxe_status_desc), 16384 /* XXX */);
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: /* allocate the rx rings */
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: /* nothing can possibly go wrong now */
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: /* enable interrupts */
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: /* XXX busy wait in a process context is naughty */
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; /* XXX */
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: /* XXX turn the chip off */
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 /* XXX */) < 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: /* we get here on error */
1391: /* FALLTHROUGH */
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: /* do nothing */
1405: }
1406:
1407: int
1408: nxe_media_change(struct ifnet *ifp)
1409: {
1410: /* ignore for now */
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: /* stop the chip from processing */
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: * if this is the first port on the device it needs some special
1548: * treatment to get things going.
1549: */
1550: if (sc->sc_function == 0) {
1551: /* init adapter offload */
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: /* clear */
1575: nxe_crb_write(sc, NXE_1_SW_BOOTLD_CONFIG, 0);
1576: }
1577:
1578: /* start the device up */
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: * the firmware takes a long time to boot, so we'll check
1584: * it later on, and again when we want to bring a port up.
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: /* we should probably bring things down if this is true */
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: /* set the rom address */
1984: nxe_crb_write(sc, NXE_1_ROM_ADDR, r);
1985:
1986: /* set the xfer len */
1987: nxe_crb_write(sc, NXE_1_ROM_ABYTE_CNT, 3);
1988: delay(100); /* used to prevent bursting on the chipset */
1989: nxe_crb_write(sc, NXE_1_ROM_DBYTE_CNT, 0);
1990:
1991: /* set opcode and wait for completion */
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: /* reset counters */
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: }
CVSweb