summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_smscreg.h
blob: acd8b8c80ff85403fac6207c531d911972d25f0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*	$OpenBSD: if_smscreg.h,v 1.2 2012/09/27 12:38:11 jsg Exp $	*/
/*-
 * Copyright (c) 2012
 *	Ben Gray <bgray@freebsd.org>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: src/sys/dev/usb/net/if_smscreg.h,v 1.1 2012/08/15 04:03:55 gonzo Exp $
 */
#ifndef _IF_SMSCREG_H_
#define _IF_SMSCREG_H_

/*
 * Definitions for the SMSC LAN9514 and LAN9514 USB to ethernet controllers.
 *
 * This information was gleaned from the SMSC driver in the linux kernel, where
 * it is Copyrighted (C) 2007-2008 SMSC.
 *
 */

/**
 * TRANSMIT FRAMES
 * ---------------
 *   Tx frames are prefixed with an 8-byte header which describes the frame
 *
 *         4 bytes      4 bytes           variable
 *      +------------+------------+--- . . . . . . . . . . . . ---+
 *      | TX_CTRL_0  | TX_CTRL_1  |  Ethernet frame data          |
 *      +------------+------------+--- . . . . . . . . . . . . ---+
 *
 *   Where the headers have the following fields:
 *
 *      TX_CTRL_0 <20:16>  Data offset
 *      TX_CTRL_0 <13>     First segment of frame indicator
 *      TX_CTRL_0 <12>     Last segment of frame indicator
 *      TX_CTRL_0 <10:0>   Buffer size (?)
 *
 *      TX_CTRL_1 <14>     Perform H/W checksuming on IP packets 
 *      TX_CTRL_1 <13>     Disable automatic ethernet CRC generation
 *      TX_CTRL_1 <12>     Disable padding (?)
 *      TX_CTRL_1 <10:0>   Packet byte length
 *
 */
#define SMSC_TX_CTRL_0_OFFSET(x)         (((x) & 0x1FUL) << 16)
#define SMSC_TX_CTRL_0_FIRST_SEG         (0x1UL << 13)
#define SMSC_TX_CTRL_0_LAST_SEG          (0x1UL << 12)
#define SMSC_TX_CTRL_0_BUF_SIZE(x)       ((x) & 0x000007FFUL)

#define SMSC_TX_CTRL_1_CSUM_ENABLE       (0x1UL << 14)
#define SMSC_TX_CTRL_1_CRC_DISABLE       (0x1UL << 13)
#define SMSC_TX_CTRL_1_PADDING_DISABLE   (0x1UL << 12)
#define SMSC_TX_CTRL_1_PKT_LENGTH(x)     ((x) & 0x000007FFUL)

/**
 * RECEIVE FRAMES
 * --------------
 *   Rx frames are prefixed with an 4-byte status header which describes any
 *   errors with the frame as well as things like the length
 *
 *         4 bytes             variable
 *      +------------+--- . . . . . . . . . . . . ---+
 *      |   RX_STAT  |  Ethernet frame data          |
 *      +------------+--- . . . . . . . . . . . . ---+
 *
 *   Where the status header has the following fields:
 *
 *      RX_STAT   <30>     Filter Fail
 *      RX_STAT   <29:16>  Frame Length
 *      RX_STAT   <15>     Error Summary
 *      RX_STAT   <13>     Broadcast Frame
 *      RX_STAT   <12>     Length Error
 *      RX_STAT   <11>     Runt Frame
 *      RX_STAT   <10>     Multicast Frame
 *      RX_STAT   <7>      Frame too long
 *      RX_STAT   <6>      Collision Seen
 *      RX_STAT   <5>      Frame Type
 *      RX_STAT   <4>      Receive Watchdog
 *      RX_STAT   <3>      Mii Error
 *      RX_STAT   <2>      Dribbling
 *      RX_STAT   <1>      CRC Error
 *
 */
#define SMSC_RX_STAT_FILTER_FAIL         (0x1UL << 30)
#define SMSC_RX_STAT_FRM_LENGTH(x)       (((x) >> 16) & 0x3FFFUL)
#define SMSC_RX_STAT_ERROR               (0x1UL << 15)
#define SMSC_RX_STAT_BROADCAST           (0x1UL << 13)
#define SMSC_RX_STAT_LENGTH_ERROR        (0x1UL << 12)
#define SMSC_RX_STAT_RUNT                (0x1UL << 11)
#define SMSC_RX_STAT_MULTICAST           (0x1UL << 10)
#define SMSC_RX_STAT_FRM_TO_LONG         (0x1UL << 7)
#define SMSC_RX_STAT_COLLISION           (0x1UL << 6)
#define SMSC_RX_STAT_FRM_TYPE            (0x1UL << 5)
#define SMSC_RX_STAT_WATCHDOG            (0x1UL << 4)
#define SMSC_RX_STAT_MII_ERROR           (0x1UL << 3)
#define SMSC_RX_STAT_DRIBBLING           (0x1UL << 2)
#define SMSC_RX_STAT_CRC_ERROR           (0x1UL << 1)

/**
 * REGISTERS
 *
 */
#define SMSC_ID_REV                 0x000
#define SMSC_INTR_STATUS            0x008
#define SMSC_RX_CFG                 0x00C
#define SMSC_TX_CFG                 0x010
#define SMSC_HW_CFG                 0x014
#define SMSC_PM_CTRL                0x020
#define SMSC_LED_GPIO_CFG           0x024
#define SMSC_GPIO_CFG               0x028
#define SMSC_AFC_CFG                0x02C
#define SMSC_EEPROM_CMD             0x030
#define SMSC_EEPROM_DATA            0x034
#define SMSC_BURST_CAP              0x038
#define SMSC_GPIO_WAKE              0x064
#define SMSC_INTR_CFG               0x068
#define SMSC_BULK_IN_DLY            0x06C
#define SMSC_MAC_CSR                0x100
#define SMSC_MAC_ADDRH              0x104
#define SMSC_MAC_ADDRL              0x108
#define SMSC_HASHH                  0x10C
#define SMSC_HASHL                  0x110
#define SMSC_MII_ADDR               0x114
#define SMSC_MII_DATA               0x118
#define SMSC_FLOW                   0x11C
#define SMSC_VLAN1                  0x120
#define SMSC_VLAN2                  0x124
#define SMSC_WUFF                   0x128
#define SMSC_WUCSR                  0x12C
#define SMSC_COE_CTRL               0x130

/* ID / Revision register */
#define SMSC_ID_REV_CHIP_ID_MASK    0xFFFF0000UL
#define SMSC_ID_REV_CHIP_REV_MASK   0x0000FFFFUL

#define SMSC_RX_FIFO_FLUSH          (0x1UL << 0)

#define SMSC_TX_CFG_ON              (0x1UL << 2)
#define SMSC_TX_CFG_STOP            (0x1UL << 1)
#define SMSC_TX_CFG_FIFO_FLUSH      (0x1UL << 0)

#define SMSC_HW_CFG_BIR             (0x1UL << 12)
#define SMSC_HW_CFG_LEDB            (0x1UL << 11)
#define SMSC_HW_CFG_RXDOFF          (0x3UL << 9)    /* RX pkt alignment */
#define SMSC_HW_CFG_DRP             (0x1UL << 6)
#define SMSC_HW_CFG_MEF             (0x1UL << 5)
#define SMSC_HW_CFG_LRST            (0x1UL << 3)    /* Lite reset */
#define SMSC_HW_CFG_PSEL            (0x1UL << 2)
#define SMSC_HW_CFG_BCE             (0x1UL << 1)
#define SMSC_HW_CFG_SRST            (0x1UL << 0)

#define SMSC_PM_CTRL_PHY_RST        (0x1UL << 4)    /* PHY reset */

#define SMSC_LED_GPIO_CFG_SPD_LED   (0x1UL << 24)
#define SMSC_LED_GPIO_CFG_LNK_LED   (0x1UL << 20)
#define SMSC_LED_GPIO_CFG_FDX_LED   (0x1UL << 16)

/* Hi watermark = 15.5Kb (~10 mtu pkts) */
/* low watermark = 3k (~2 mtu pkts) */
/* backpressure duration = ~ 350us */
/* Apply FC on any frame. */
#define AFC_CFG_DEFAULT             (0x00F830A1)

#define SMSC_EEPROM_CMD_BUSY        (0x1UL << 31)
#define SMSC_EEPROM_CMD_MASK        (0x7UL << 28)
#define SMSC_EEPROM_CMD_READ        (0x0UL << 28)
#define SMSC_EEPROM_CMD_WRITE       (0x3UL << 28)
#define SMSC_EEPROM_CMD_ERASE       (0x5UL << 28)
#define SMSC_EEPROM_CMD_RELOAD      (0x7UL << 28)
#define SMSC_EEPROM_CMD_TIMEOUT     (0x1UL << 10)
#define SMSC_EEPROM_CMD_ADDR_MASK   0x000001FFUL

/* MAC Control and Status Register */
#define SMSC_MAC_CSR_RCVOWN         (0x1UL << 23)  /* Half duplex */
#define SMSC_MAC_CSR_LOOPBK         (0x1UL << 21)  /* Loopback */
#define SMSC_MAC_CSR_FDPX           (0x1UL << 20)  /* Full duplex */
#define SMSC_MAC_CSR_MCPAS          (0x1UL << 19)  /* Multicast mode */
#define SMSC_MAC_CSR_PRMS           (0x1UL << 18)  /* Promiscuous mode */
#define SMSC_MAC_CSR_INVFILT        (0x1UL << 17)  /* Inverse filtering */
#define SMSC_MAC_CSR_PASSBAD        (0x1UL << 16)  /* Pass on bad frames */
#define SMSC_MAC_CSR_HPFILT         (0x1UL << 13)  /* Hash filtering */
#define SMSC_MAC_CSR_BCAST          (0x1UL << 11)  /* Broadcast */
#define SMSC_MAC_CSR_TXEN           (0x1UL << 3)   /* TX enable */
#define SMSC_MAC_CSR_RXEN           (0x1UL << 2)   /* RX enable */

/* Interrupt control register */
#define SMSC_INTR_NTEP              (0x1UL << 31) 
#define SMSC_INTR_MACRTO            (0x1UL << 19)
#define SMSC_INTR_TX_STOP           (0x1UL << 17)
#define SMSC_INTR_RX_STOP           (0x1UL << 16)
#define SMSC_INTR_PHY_INT           (0x1UL << 15)
#define SMSC_INTR_TXE               (0x1UL << 14)
#define SMSC_INTR_TDFU              (0x1UL << 13)
#define SMSC_INTR_TDFO              (0x1UL << 12)
#define SMSC_INTR_RXDF              (0x1UL << 11)
#define SMSC_INTR_GPIOS             0x000007FFUL

/* Phy MII interface register */
#define SMSC_MII_WRITE              (0x1UL << 1)
#define SMSC_MII_READ               (0x0UL << 1)
#define SMSC_MII_BUSY               (0x1UL << 0)

/* H/W checksum register */
#define SMSC_COE_CTRL_TX_EN         (0x1UL << 16)  /* Tx H/W csum enable */
#define SMSC_COE_CTRL_RX_MODE       (0x1UL << 1)
#define SMSC_COE_CTRL_RX_EN         (0x1UL << 0)   /* Rx H/W csum enable */

/* Registers on the phy, accessed via MII/MDIO */
#define SMSC_PHY_INTR_STAT          (29)
#define SMSC_PHY_INTR_MASK          (30)

#define SMSC_PHY_INTR_ENERGY_ON     (0x1U << 7)
#define SMSC_PHY_INTR_ANEG_COMP     (0x1U << 6)
#define SMSC_PHY_INTR_REMOTE_FAULT  (0x1U << 5)
#define SMSC_PHY_INTR_LINK_DOWN     (0x1U << 4)

/* USB Vendor Requests */
#define SMSC_UR_WRITE_REG   0xA0
#define SMSC_UR_READ_REG    0xA1
#define SMSC_UR_GET_STATS   0xA2

#define SMSC_RX_LIST_CNT	1
#define SMSC_TX_LIST_CNT	1

#define	SMSC_CONFIG_INDEX	1	/* config number 1 */
#define	SMSC_IFACE_IDX		0

#define SMSC_ENDPT_RX		0
#define SMSC_ENDPT_TX		1
#define SMSC_ENDPT_INTR		2
#define SMSC_ENDPT_MAX		3

struct smsc_chain {
	struct smsc_softc	*sc_sc;
	usbd_xfer_handle	 sc_xfer;
	char			*sc_buf;
	struct mbuf		*sc_mbuf;
	int			 sc_accum;
	int			 sc_idx;
};

struct smsc_cdata {
	struct smsc_chain	 tx_chain[SMSC_TX_LIST_CNT];
	struct smsc_chain	 rx_chain[SMSC_RX_LIST_CNT];
	int			 tx_prod;
	int			 tx_cons;
	int			 tx_cnt;
	int			 rx_prod;
};

struct smsc_softc {
	struct device		sc_dev;
	usbd_device_handle	sc_udev;
	struct arpcom		sc_ac;
	struct mii_data		sc_mii;
	int			sc_phyno;
	usbd_interface_handle	sc_iface;

	/*
	 * The following stores the settings in the mac control (MAC_CSR)
	 * register
	 */
	uint32_t		sc_mac_csr;
	uint32_t		sc_rev_id;

	int			sc_if_flags;
	int			sc_refcnt;

	struct usb_task		sc_tick_task;
	struct usb_task		sc_stop_task;

	int			sc_ed[SMSC_ENDPT_MAX];
	usbd_pipe_handle	sc_ep[SMSC_ENDPT_MAX];

	struct rwlock		sc_mii_lock;

	struct smsc_cdata	sc_cdata;
	struct timeout		sc_stat_ch;

	struct timeval		sc_rx_notice;
	u_int			sc_bufsz;

	uint32_t		sc_flags;
#define	SMSC_FLAG_LINK      0x0001
};

#define SMSC_MIN_BUFSZ		2048
#define SMSC_MAX_BUFSZ		18944

#endif  /* _IF_SMSCREG_H_ */