diff options
author | hayeswang <hayeswang@realtek.com> | 2013-05-02 12:01:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-06 16:16:52 -0400 |
commit | ac718b69301c7c07cd0d858570f76a0e1c4c8726 (patch) | |
tree | 8d70adae65fe8326403b3db73f25b9b52d24de93 | |
parent | c81400be716aa4c76f6ebf339ba94358dbbf6da6 (diff) |
net/usb: new driver for RTL8152
Add new driver for supporting Realtek RTL8152 Based USB 2.0 Ethernet Adapters
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Cc: Realtek linux nic maintainers <nic_swsd@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/Kconfig | 11 | ||||
-rw-r--r-- | drivers/net/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 10 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 1767 |
4 files changed, 1789 insertions, 0 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 7c769d8e25ad..287cc624b90b 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -93,6 +93,17 @@ config USB_RTL8150 | |||
93 | To compile this driver as a module, choose M here: the | 93 | To compile this driver as a module, choose M here: the |
94 | module will be called rtl8150. | 94 | module will be called rtl8150. |
95 | 95 | ||
96 | config USB_RTL8152 | ||
97 | tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" | ||
98 | select NET_CORE | ||
99 | select MII | ||
100 | help | ||
101 | This option adds support for Realtek RTL8152 based USB 2.0 | ||
102 | 10/100 Ethernet adapters. | ||
103 | |||
104 | To compile this driver as a module, choose M here: the | ||
105 | module will be called r8152. | ||
106 | |||
96 | config USB_USBNET | 107 | config USB_USBNET |
97 | tristate "Multi-purpose USB Networking Framework" | 108 | tristate "Multi-purpose USB Networking Framework" |
98 | select NET_CORE | 109 | select NET_CORE |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 119b06c9aa16..9ab5c9d4b45a 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC) += catc.o | |||
6 | obj-$(CONFIG_USB_KAWETH) += kaweth.o | 6 | obj-$(CONFIG_USB_KAWETH) += kaweth.o |
7 | obj-$(CONFIG_USB_PEGASUS) += pegasus.o | 7 | obj-$(CONFIG_USB_PEGASUS) += pegasus.o |
8 | obj-$(CONFIG_USB_RTL8150) += rtl8150.o | 8 | obj-$(CONFIG_USB_RTL8150) += rtl8150.o |
9 | obj-$(CONFIG_USB_RTL8152) += r8152.o | ||
9 | obj-$(CONFIG_USB_HSO) += hso.o | 10 | obj-$(CONFIG_USB_HSO) += hso.o |
10 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o | 11 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o |
11 | asix-y := asix_devices.o asix_common.o ax88172a.o | 12 | asix-y := asix_devices.o asix_common.o ax88172a.o |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4ff71d619cd8..24fbec27a22a 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -479,6 +479,7 @@ static const struct driver_info wwan_info = { | |||
479 | #define NOVATEL_VENDOR_ID 0x1410 | 479 | #define NOVATEL_VENDOR_ID 0x1410 |
480 | #define ZTE_VENDOR_ID 0x19D2 | 480 | #define ZTE_VENDOR_ID 0x19D2 |
481 | #define DELL_VENDOR_ID 0x413C | 481 | #define DELL_VENDOR_ID 0x413C |
482 | #define REALTEK_VENDOR_ID 0x0bda | ||
482 | 483 | ||
483 | static const struct usb_device_id products [] = { | 484 | static const struct usb_device_id products [] = { |
484 | /* | 485 | /* |
@@ -619,6 +620,15 @@ static const struct usb_device_id products [] = { | |||
619 | .driver_info = 0, | 620 | .driver_info = 0, |
620 | }, | 621 | }, |
621 | 622 | ||
623 | /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ | ||
624 | #if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) | ||
625 | { | ||
626 | USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, | ||
627 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
628 | .driver_info = 0, | ||
629 | }, | ||
630 | #endif | ||
631 | |||
622 | /* | 632 | /* |
623 | * WHITELIST!!! | 633 | * WHITELIST!!! |
624 | * | 634 | * |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c new file mode 100644 index 000000000000..14e519888631 --- /dev/null +++ b/drivers/net/usb/r8152.c | |||
@@ -0,0 +1,1767 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Realtek Semiconductor Corp. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/signal.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/version.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/mii.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/crc32.h> | ||
21 | #include <linux/if_vlan.h> | ||
22 | #include <linux/uaccess.h> | ||
23 | |||
24 | /* Version Information */ | ||
25 | #define DRIVER_VERSION "v1.0.0 (2013/05/03)" | ||
26 | #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" | ||
27 | #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" | ||
28 | #define MODULENAME "r8152" | ||
29 | |||
30 | #define R8152_PHY_ID 32 | ||
31 | |||
32 | #define PLA_IDR 0xc000 | ||
33 | #define PLA_RCR 0xc010 | ||
34 | #define PLA_RMS 0xc016 | ||
35 | #define PLA_RXFIFO_CTRL0 0xc0a0 | ||
36 | #define PLA_RXFIFO_CTRL1 0xc0a4 | ||
37 | #define PLA_RXFIFO_CTRL2 0xc0a8 | ||
38 | #define PLA_FMC 0xc0b4 | ||
39 | #define PLA_CFG_WOL 0xc0b6 | ||
40 | #define PLA_MAR 0xcd00 | ||
41 | #define PAL_BDC_CR 0xd1a0 | ||
42 | #define PLA_LEDSEL 0xdd90 | ||
43 | #define PLA_LED_FEATURE 0xdd92 | ||
44 | #define PLA_PHYAR 0xde00 | ||
45 | #define PLA_GPHY_INTR_IMR 0xe022 | ||
46 | #define PLA_EEE_CR 0xe040 | ||
47 | #define PLA_EEEP_CR 0xe080 | ||
48 | #define PLA_MAC_PWR_CTRL 0xe0c0 | ||
49 | #define PLA_TCR0 0xe610 | ||
50 | #define PLA_TCR1 0xe612 | ||
51 | #define PLA_TXFIFO_CTRL 0xe618 | ||
52 | #define PLA_RSTTELLY 0xe800 | ||
53 | #define PLA_CR 0xe813 | ||
54 | #define PLA_CRWECR 0xe81c | ||
55 | #define PLA_CONFIG5 0xe822 | ||
56 | #define PLA_PHY_PWR 0xe84c | ||
57 | #define PLA_OOB_CTRL 0xe84f | ||
58 | #define PLA_CPCR 0xe854 | ||
59 | #define PLA_MISC_0 0xe858 | ||
60 | #define PLA_MISC_1 0xe85a | ||
61 | #define PLA_OCP_GPHY_BASE 0xe86c | ||
62 | #define PLA_TELLYCNT 0xe890 | ||
63 | #define PLA_SFF_STS_7 0xe8de | ||
64 | #define PLA_PHYSTATUS 0xe908 | ||
65 | #define PLA_BP_BA 0xfc26 | ||
66 | #define PLA_BP_0 0xfc28 | ||
67 | #define PLA_BP_1 0xfc2a | ||
68 | #define PLA_BP_2 0xfc2c | ||
69 | #define PLA_BP_3 0xfc2e | ||
70 | #define PLA_BP_4 0xfc30 | ||
71 | #define PLA_BP_5 0xfc32 | ||
72 | #define PLA_BP_6 0xfc34 | ||
73 | #define PLA_BP_7 0xfc36 | ||
74 | |||
75 | #define USB_DEV_STAT 0xb808 | ||
76 | #define USB_USB_CTRL 0xd406 | ||
77 | #define USB_PHY_CTRL 0xd408 | ||
78 | #define USB_TX_AGG 0xd40a | ||
79 | #define USB_RX_BUF_TH 0xd40c | ||
80 | #define USB_USB_TIMER 0xd428 | ||
81 | #define USB_PM_CTRL_STATUS 0xd432 | ||
82 | #define USB_TX_DMA 0xd434 | ||
83 | #define USB_UPS_CTRL 0xd800 | ||
84 | #define USB_BP_BA 0xfc26 | ||
85 | #define USB_BP_0 0xfc28 | ||
86 | #define USB_BP_1 0xfc2a | ||
87 | #define USB_BP_2 0xfc2c | ||
88 | #define USB_BP_3 0xfc2e | ||
89 | #define USB_BP_4 0xfc30 | ||
90 | #define USB_BP_5 0xfc32 | ||
91 | #define USB_BP_6 0xfc34 | ||
92 | #define USB_BP_7 0xfc36 | ||
93 | |||
94 | /* OCP Registers */ | ||
95 | #define OCP_ALDPS_CONFIG 0x2010 | ||
96 | #define OCP_EEE_CONFIG1 0x2080 | ||
97 | #define OCP_EEE_CONFIG2 0x2092 | ||
98 | #define OCP_EEE_CONFIG3 0x2094 | ||
99 | #define OCP_EEE_AR 0xa41a | ||
100 | #define OCP_EEE_DATA 0xa41c | ||
101 | |||
102 | /* PLA_RCR */ | ||
103 | #define RCR_AAP 0x00000001 | ||
104 | #define RCR_APM 0x00000002 | ||
105 | #define RCR_AM 0x00000004 | ||
106 | #define RCR_AB 0x00000008 | ||
107 | #define RCR_ACPT_ALL (RCR_AAP | RCR_APM | RCR_AM | RCR_AB) | ||
108 | |||
109 | /* PLA_RXFIFO_CTRL0 */ | ||
110 | #define RXFIFO_THR1_NORMAL 0x00080002 | ||
111 | #define RXFIFO_THR1_OOB 0x01800003 | ||
112 | |||
113 | /* PLA_RXFIFO_CTRL1 */ | ||
114 | #define RXFIFO_THR2_FULL 0x00000060 | ||
115 | #define RXFIFO_THR2_HIGH 0x00000038 | ||
116 | #define RXFIFO_THR2_OOB 0x0000004a | ||
117 | |||
118 | /* PLA_RXFIFO_CTRL2 */ | ||
119 | #define RXFIFO_THR3_FULL 0x00000078 | ||
120 | #define RXFIFO_THR3_HIGH 0x00000048 | ||
121 | #define RXFIFO_THR3_OOB 0x0000005a | ||
122 | |||
123 | /* PLA_TXFIFO_CTRL */ | ||
124 | #define TXFIFO_THR_NORMAL 0x00400008 | ||
125 | |||
126 | /* PLA_FMC */ | ||
127 | #define FMC_FCR_MCU_EN 0x0001 | ||
128 | |||
129 | /* PLA_EEEP_CR */ | ||
130 | #define EEEP_CR_EEEP_TX 0x0002 | ||
131 | |||
132 | /* PLA_TCR0 */ | ||
133 | #define TCR0_TX_EMPTY 0x0800 | ||
134 | #define TCR0_AUTO_FIFO 0x0080 | ||
135 | |||
136 | /* PLA_TCR1 */ | ||
137 | #define VERSION_MASK 0x7cf0 | ||
138 | |||
139 | /* PLA_CR */ | ||
140 | #define CR_RST 0x10 | ||
141 | #define CR_RE 0x08 | ||
142 | #define CR_TE 0x04 | ||
143 | |||
144 | /* PLA_CRWECR */ | ||
145 | #define CRWECR_NORAML 0x00 | ||
146 | #define CRWECR_CONFIG 0xc0 | ||
147 | |||
148 | /* PLA_OOB_CTRL */ | ||
149 | #define NOW_IS_OOB 0x80 | ||
150 | #define TXFIFO_EMPTY 0x20 | ||
151 | #define RXFIFO_EMPTY 0x10 | ||
152 | #define LINK_LIST_READY 0x02 | ||
153 | #define DIS_MCU_CLROOB 0x01 | ||
154 | #define FIFO_EMPTY (TXFIFO_EMPTY | RXFIFO_EMPTY) | ||
155 | |||
156 | /* PLA_MISC_1 */ | ||
157 | #define RXDY_GATED_EN 0x0008 | ||
158 | |||
159 | /* PLA_SFF_STS_7 */ | ||
160 | #define RE_INIT_LL 0x8000 | ||
161 | #define MCU_BORW_EN 0x4000 | ||
162 | |||
163 | /* PLA_CPCR */ | ||
164 | #define CPCR_RX_VLAN 0x0040 | ||
165 | |||
166 | /* PLA_CFG_WOL */ | ||
167 | #define MAGIC_EN 0x0001 | ||
168 | |||
169 | /* PAL_BDC_CR */ | ||
170 | #define ALDPS_PROXY_MODE 0x0001 | ||
171 | |||
172 | /* PLA_CONFIG5 */ | ||
173 | #define LAN_WAKE_EN 0x0002 | ||
174 | |||
175 | /* PLA_LED_FEATURE */ | ||
176 | #define LED_MODE_MASK 0x0700 | ||
177 | |||
178 | /* PLA_PHY_PWR */ | ||
179 | #define TX_10M_IDLE_EN 0x0080 | ||
180 | #define PFM_PWM_SWITCH 0x0040 | ||
181 | |||
182 | /* PLA_MAC_PWR_CTRL */ | ||
183 | #define D3_CLK_GATED_EN 0x00004000 | ||
184 | #define MCU_CLK_RATIO 0x07010f07 | ||
185 | #define MCU_CLK_RATIO_MASK 0x0f0f0f0f | ||
186 | |||
187 | /* PLA_GPHY_INTR_IMR */ | ||
188 | #define GPHY_STS_MSK 0x0001 | ||
189 | #define SPEED_DOWN_MSK 0x0002 | ||
190 | #define SPDWN_RXDV_MSK 0x0004 | ||
191 | #define SPDWN_LINKCHG_MSK 0x0008 | ||
192 | |||
193 | /* PLA_PHYAR */ | ||
194 | #define PHYAR_FLAG 0x80000000 | ||
195 | |||
196 | /* PLA_EEE_CR */ | ||
197 | #define EEE_RX_EN 0x0001 | ||
198 | #define EEE_TX_EN 0x0002 | ||
199 | |||
200 | /* USB_DEV_STAT */ | ||
201 | #define STAT_SPEED_MASK 0x0006 | ||
202 | #define STAT_SPEED_HIGH 0x0000 | ||
203 | #define STAT_SPEED_FULL 0x0001 | ||
204 | |||
205 | /* USB_TX_AGG */ | ||
206 | #define TX_AGG_MAX_THRESHOLD 0x03 | ||
207 | |||
208 | /* USB_RX_BUF_TH */ | ||
209 | #define RX_BUF_THR 0x7a120180 | ||
210 | |||
211 | /* USB_TX_DMA */ | ||
212 | #define TEST_MODE_DISABLE 0x00000001 | ||
213 | #define TX_SIZE_ADJUST1 0x00000100 | ||
214 | |||
215 | /* USB_UPS_CTRL */ | ||
216 | #define POWER_CUT 0x0100 | ||
217 | |||
218 | /* USB_PM_CTRL_STATUS */ | ||
219 | #define RWSUME_INDICATE 0x0001 | ||
220 | |||
221 | /* USB_USB_CTRL */ | ||
222 | #define RX_AGG_DISABLE 0x0010 | ||
223 | |||
224 | /* OCP_ALDPS_CONFIG */ | ||
225 | #define ENPWRSAVE 0x8000 | ||
226 | #define ENPDNPS 0x0200 | ||
227 | #define LINKENA 0x0100 | ||
228 | #define DIS_SDSAVE 0x0010 | ||
229 | |||
230 | /* OCP_EEE_CONFIG1 */ | ||
231 | #define RG_TXLPI_MSK_HFDUP 0x8000 | ||
232 | #define RG_MATCLR_EN 0x4000 | ||
233 | #define EEE_10_CAP 0x2000 | ||
234 | #define EEE_NWAY_EN 0x1000 | ||
235 | #define TX_QUIET_EN 0x0200 | ||
236 | #define RX_QUIET_EN 0x0100 | ||
237 | #define SDRISETIME 0x0010 /* bit 4 ~ 6 */ | ||
238 | #define RG_RXLPI_MSK_HFDUP 0x0008 | ||
239 | #define SDFALLTIME 0x0007 /* bit 0 ~ 2 */ | ||
240 | |||
241 | /* OCP_EEE_CONFIG2 */ | ||
242 | #define RG_LPIHYS_NUM 0x7000 /* bit 12 ~ 15 */ | ||
243 | #define RG_DACQUIET_EN 0x0400 | ||
244 | #define RG_LDVQUIET_EN 0x0200 | ||
245 | #define RG_CKRSEL 0x0020 | ||
246 | #define RG_EEEPRG_EN 0x0010 | ||
247 | |||
248 | /* OCP_EEE_CONFIG3 */ | ||
249 | #define FST_SNR_EYE_R 0x1500 /* bit 7 ~ 15 */ | ||
250 | #define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */ | ||
251 | #define MSK_PH 0x0006 /* bit 0 ~ 3 */ | ||
252 | |||
253 | /* OCP_EEE_AR */ | ||
254 | /* bit[15:14] function */ | ||
255 | #define FUN_ADDR 0x0000 | ||
256 | #define FUN_DATA 0x4000 | ||
257 | /* bit[4:0] device addr */ | ||
258 | #define DEVICE_ADDR 0x0007 | ||
259 | |||
260 | /* OCP_EEE_DATA */ | ||
261 | #define EEE_ADDR 0x003C | ||
262 | #define EEE_DATA 0x0002 | ||
263 | |||
264 | enum rtl_register_content { | ||
265 | _100bps = 0x08, | ||
266 | _10bps = 0x04, | ||
267 | LINK_STATUS = 0x02, | ||
268 | FULL_DUP = 0x01, | ||
269 | }; | ||
270 | |||
271 | #define RTL8152_REQT_READ 0xc0 | ||
272 | #define RTL8152_REQT_WRITE 0x40 | ||
273 | #define RTL8152_REQ_GET_REGS 0x05 | ||
274 | #define RTL8152_REQ_SET_REGS 0x05 | ||
275 | |||
276 | #define BYTE_EN_DWORD 0xff | ||
277 | #define BYTE_EN_WORD 0x33 | ||
278 | #define BYTE_EN_BYTE 0x11 | ||
279 | #define BYTE_EN_SIX_BYTES 0x3f | ||
280 | #define BYTE_EN_START_MASK 0x0f | ||
281 | #define BYTE_EN_END_MASK 0xf0 | ||
282 | |||
283 | #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + VLAN_HLEN) | ||
284 | #define RTL8152_TX_TIMEOUT (HZ) | ||
285 | |||
286 | /* rtl8152 flags */ | ||
287 | enum rtl8152_flags { | ||
288 | RTL8152_UNPLUG = 0, | ||
289 | RX_URB_FAIL, | ||
290 | RTL8152_SET_RX_MODE, | ||
291 | WORK_ENABLE | ||
292 | }; | ||
293 | |||
294 | /* Define these values to match your device */ | ||
295 | #define VENDOR_ID_REALTEK 0x0bda | ||
296 | #define PRODUCT_ID_RTL8152 0x8152 | ||
297 | |||
298 | #define MCU_TYPE_PLA 0x0100 | ||
299 | #define MCU_TYPE_USB 0x0000 | ||
300 | |||
301 | struct rx_desc { | ||
302 | u32 opts1; | ||
303 | #define RX_LEN_MASK 0x7fff | ||
304 | u32 opts2; | ||
305 | u32 opts3; | ||
306 | u32 opts4; | ||
307 | u32 opts5; | ||
308 | u32 opts6; | ||
309 | }; | ||
310 | |||
311 | struct tx_desc { | ||
312 | u32 opts1; | ||
313 | #define TX_FS (1 << 31) /* First segment of a packet */ | ||
314 | #define TX_LS (1 << 30) /* Final segment of a packet */ | ||
315 | #define TX_LEN_MASK 0xffff | ||
316 | u32 opts2; | ||
317 | }; | ||
318 | |||
319 | struct r8152 { | ||
320 | unsigned long flags; | ||
321 | struct usb_device *udev; | ||
322 | struct tasklet_struct tl; | ||
323 | struct net_device *netdev; | ||
324 | struct urb *rx_urb, *tx_urb; | ||
325 | struct sk_buff *tx_skb, *rx_skb; | ||
326 | struct delayed_work schedule; | ||
327 | struct mii_if_info mii; | ||
328 | u32 msg_enable; | ||
329 | u16 ocp_base; | ||
330 | u8 version; | ||
331 | u8 speed; | ||
332 | }; | ||
333 | |||
334 | enum rtl_version { | ||
335 | RTL_VER_UNKNOWN = 0, | ||
336 | RTL_VER_01, | ||
337 | RTL_VER_02 | ||
338 | }; | ||
339 | |||
340 | /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). | ||
341 | * The RTL chips use a 64 element hash table based on the Ethernet CRC. | ||
342 | */ | ||
343 | static const int multicast_filter_limit = 32; | ||
344 | |||
345 | static | ||
346 | int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | ||
347 | { | ||
348 | return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), | ||
349 | RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, | ||
350 | value, index, data, size, 500); | ||
351 | } | ||
352 | |||
353 | static | ||
354 | int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | ||
355 | { | ||
356 | return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), | ||
357 | RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, | ||
358 | value, index, data, size, 500); | ||
359 | } | ||
360 | |||
361 | static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, | ||
362 | void *data, u16 type) | ||
363 | { | ||
364 | u16 limit = 64; | ||
365 | int ret = 0; | ||
366 | |||
367 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
368 | return -ENODEV; | ||
369 | |||
370 | /* both size and indix must be 4 bytes align */ | ||
371 | if ((size & 3) || !size || (index & 3) || !data) | ||
372 | return -EPERM; | ||
373 | |||
374 | if ((u32)index + (u32)size > 0xffff) | ||
375 | return -EPERM; | ||
376 | |||
377 | while (size) { | ||
378 | if (size > limit) { | ||
379 | ret = get_registers(tp, index, type, limit, data); | ||
380 | if (ret < 0) | ||
381 | break; | ||
382 | |||
383 | index += limit; | ||
384 | data += limit; | ||
385 | size -= limit; | ||
386 | } else { | ||
387 | ret = get_registers(tp, index, type, size, data); | ||
388 | if (ret < 0) | ||
389 | break; | ||
390 | |||
391 | index += size; | ||
392 | data += size; | ||
393 | size = 0; | ||
394 | break; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, | ||
402 | u16 size, void *data, u16 type) | ||
403 | { | ||
404 | int ret; | ||
405 | u16 byteen_start, byteen_end, byen; | ||
406 | u16 limit = 512; | ||
407 | |||
408 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
409 | return -ENODEV; | ||
410 | |||
411 | /* both size and indix must be 4 bytes align */ | ||
412 | if ((size & 3) || !size || (index & 3) || !data) | ||
413 | return -EPERM; | ||
414 | |||
415 | if ((u32)index + (u32)size > 0xffff) | ||
416 | return -EPERM; | ||
417 | |||
418 | byteen_start = byteen & BYTE_EN_START_MASK; | ||
419 | byteen_end = byteen & BYTE_EN_END_MASK; | ||
420 | |||
421 | byen = byteen_start | (byteen_start << 4); | ||
422 | ret = set_registers(tp, index, type | byen, 4, data); | ||
423 | if (ret < 0) | ||
424 | goto error1; | ||
425 | |||
426 | index += 4; | ||
427 | data += 4; | ||
428 | size -= 4; | ||
429 | |||
430 | if (size) { | ||
431 | size -= 4; | ||
432 | |||
433 | while (size) { | ||
434 | if (size > limit) { | ||
435 | ret = set_registers(tp, index, | ||
436 | type | BYTE_EN_DWORD, | ||
437 | limit, data); | ||
438 | if (ret < 0) | ||
439 | goto error1; | ||
440 | |||
441 | index += limit; | ||
442 | data += limit; | ||
443 | size -= limit; | ||
444 | } else { | ||
445 | ret = set_registers(tp, index, | ||
446 | type | BYTE_EN_DWORD, | ||
447 | size, data); | ||
448 | if (ret < 0) | ||
449 | goto error1; | ||
450 | |||
451 | index += size; | ||
452 | data += size; | ||
453 | size = 0; | ||
454 | break; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | byen = byteen_end | (byteen_end >> 4); | ||
459 | ret = set_registers(tp, index, type | byen, 4, data); | ||
460 | if (ret < 0) | ||
461 | goto error1; | ||
462 | } | ||
463 | |||
464 | error1: | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | static inline | ||
469 | int pla_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data) | ||
470 | { | ||
471 | return generic_ocp_read(tp, index, size, data, MCU_TYPE_PLA); | ||
472 | } | ||
473 | |||
474 | static inline | ||
475 | int pla_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) | ||
476 | { | ||
477 | return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_PLA); | ||
478 | } | ||
479 | |||
480 | static inline | ||
481 | int usb_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data) | ||
482 | { | ||
483 | return generic_ocp_read(tp, index, size, data, MCU_TYPE_USB); | ||
484 | } | ||
485 | |||
486 | static inline | ||
487 | int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) | ||
488 | { | ||
489 | return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_USB); | ||
490 | } | ||
491 | |||
492 | static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) | ||
493 | { | ||
494 | u32 data; | ||
495 | |||
496 | if (type == MCU_TYPE_PLA) | ||
497 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
498 | else | ||
499 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
500 | |||
501 | return __le32_to_cpu(data); | ||
502 | } | ||
503 | |||
504 | static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) | ||
505 | { | ||
506 | if (type == MCU_TYPE_PLA) | ||
507 | pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); | ||
508 | else | ||
509 | usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); | ||
510 | } | ||
511 | |||
512 | static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) | ||
513 | { | ||
514 | u32 data; | ||
515 | u8 shift = index & 2; | ||
516 | |||
517 | index &= ~3; | ||
518 | |||
519 | if (type == MCU_TYPE_PLA) | ||
520 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
521 | else | ||
522 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
523 | |||
524 | data = __le32_to_cpu(data); | ||
525 | data >>= (shift * 8); | ||
526 | data &= 0xffff; | ||
527 | |||
528 | return (u16)data; | ||
529 | } | ||
530 | |||
531 | static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) | ||
532 | { | ||
533 | u32 tmp, mask = 0xffff; | ||
534 | u16 byen = BYTE_EN_WORD; | ||
535 | u8 shift = index & 2; | ||
536 | |||
537 | data &= mask; | ||
538 | |||
539 | if (index & 2) { | ||
540 | byen <<= shift; | ||
541 | mask <<= (shift * 8); | ||
542 | data <<= (shift * 8); | ||
543 | index &= ~3; | ||
544 | } | ||
545 | |||
546 | if (type == MCU_TYPE_PLA) | ||
547 | pla_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
548 | else | ||
549 | usb_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
550 | |||
551 | tmp = __le32_to_cpu(tmp) & ~mask; | ||
552 | tmp |= data; | ||
553 | tmp = __cpu_to_le32(tmp); | ||
554 | |||
555 | if (type == MCU_TYPE_PLA) | ||
556 | pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
557 | else | ||
558 | usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
559 | } | ||
560 | |||
561 | static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) | ||
562 | { | ||
563 | u32 data; | ||
564 | u8 shift = index & 3; | ||
565 | |||
566 | index &= ~3; | ||
567 | |||
568 | if (type == MCU_TYPE_PLA) | ||
569 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
570 | else | ||
571 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
572 | |||
573 | data = __le32_to_cpu(data); | ||
574 | data >>= (shift * 8); | ||
575 | data &= 0xff; | ||
576 | |||
577 | return (u8)data; | ||
578 | } | ||
579 | |||
580 | static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) | ||
581 | { | ||
582 | u32 tmp, mask = 0xff; | ||
583 | u16 byen = BYTE_EN_BYTE; | ||
584 | u8 shift = index & 3; | ||
585 | |||
586 | data &= mask; | ||
587 | |||
588 | if (index & 3) { | ||
589 | byen <<= shift; | ||
590 | mask <<= (shift * 8); | ||
591 | data <<= (shift * 8); | ||
592 | index &= ~3; | ||
593 | } | ||
594 | |||
595 | if (type == MCU_TYPE_PLA) | ||
596 | pla_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
597 | else | ||
598 | usb_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
599 | |||
600 | tmp = __le32_to_cpu(tmp) & ~mask; | ||
601 | tmp |= data; | ||
602 | tmp = __cpu_to_le32(tmp); | ||
603 | |||
604 | if (type == MCU_TYPE_PLA) | ||
605 | pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
606 | else | ||
607 | usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
608 | } | ||
609 | |||
610 | static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) | ||
611 | { | ||
612 | u32 ocp_data; | ||
613 | int i; | ||
614 | |||
615 | ocp_data = PHYAR_FLAG | ((reg_addr & 0x1f) << 16) | | ||
616 | (value & 0xffff); | ||
617 | |||
618 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_PHYAR, ocp_data); | ||
619 | |||
620 | for (i = 20; i > 0; i--) { | ||
621 | udelay(25); | ||
622 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_PHYAR); | ||
623 | if (!(ocp_data & PHYAR_FLAG)) | ||
624 | break; | ||
625 | } | ||
626 | udelay(20); | ||
627 | } | ||
628 | |||
629 | static int r8152_mdio_read(struct r8152 *tp, u32 reg_addr) | ||
630 | { | ||
631 | u32 ocp_data; | ||
632 | int i; | ||
633 | |||
634 | ocp_data = (reg_addr & 0x1f) << 16; | ||
635 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_PHYAR, ocp_data); | ||
636 | |||
637 | for (i = 20; i > 0; i--) { | ||
638 | udelay(25); | ||
639 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_PHYAR); | ||
640 | if (ocp_data & PHYAR_FLAG) | ||
641 | break; | ||
642 | } | ||
643 | udelay(20); | ||
644 | |||
645 | if (!(ocp_data & PHYAR_FLAG)) | ||
646 | return -EAGAIN; | ||
647 | |||
648 | return (u16)(ocp_data & 0xffff); | ||
649 | } | ||
650 | |||
651 | static int read_mii_word(struct net_device *netdev, int phy_id, int reg) | ||
652 | { | ||
653 | struct r8152 *tp = netdev_priv(netdev); | ||
654 | |||
655 | if (phy_id != R8152_PHY_ID) | ||
656 | return -EINVAL; | ||
657 | |||
658 | return r8152_mdio_read(tp, reg); | ||
659 | } | ||
660 | |||
661 | static | ||
662 | void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) | ||
663 | { | ||
664 | struct r8152 *tp = netdev_priv(netdev); | ||
665 | |||
666 | if (phy_id != R8152_PHY_ID) | ||
667 | return; | ||
668 | |||
669 | r8152_mdio_write(tp, reg, val); | ||
670 | } | ||
671 | |||
672 | static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) | ||
673 | { | ||
674 | u16 ocp_base, ocp_index; | ||
675 | |||
676 | ocp_base = addr & 0xf000; | ||
677 | if (ocp_base != tp->ocp_base) { | ||
678 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, ocp_base); | ||
679 | tp->ocp_base = ocp_base; | ||
680 | } | ||
681 | |||
682 | ocp_index = (addr & 0x0fff) | 0xb000; | ||
683 | ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data); | ||
684 | } | ||
685 | |||
686 | static inline void set_ethernet_addr(struct r8152 *tp) | ||
687 | { | ||
688 | struct net_device *dev = tp->netdev; | ||
689 | u8 *node_id; | ||
690 | |||
691 | node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); | ||
692 | if (!node_id) { | ||
693 | netif_err(tp, probe, dev, "out of memory"); | ||
694 | return; | ||
695 | } | ||
696 | |||
697 | if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) | ||
698 | netif_notice(tp, probe, dev, "inet addr fail\n"); | ||
699 | else { | ||
700 | memcpy(dev->dev_addr, node_id, dev->addr_len); | ||
701 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
702 | } | ||
703 | kfree(node_id); | ||
704 | } | ||
705 | |||
706 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) | ||
707 | { | ||
708 | struct r8152 *tp = netdev_priv(netdev); | ||
709 | struct sockaddr *addr = p; | ||
710 | |||
711 | if (!is_valid_ether_addr(addr->sa_data)) | ||
712 | return -EADDRNOTAVAIL; | ||
713 | |||
714 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
715 | |||
716 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); | ||
717 | pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES, 8, addr->sa_data); | ||
718 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int alloc_all_urbs(struct r8152 *tp) | ||
724 | { | ||
725 | tp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
726 | if (!tp->rx_urb) | ||
727 | return 0; | ||
728 | tp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
729 | if (!tp->tx_urb) { | ||
730 | usb_free_urb(tp->rx_urb); | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | return 1; | ||
735 | } | ||
736 | |||
737 | static void free_all_urbs(struct r8152 *tp) | ||
738 | { | ||
739 | usb_free_urb(tp->rx_urb); | ||
740 | usb_free_urb(tp->tx_urb); | ||
741 | } | ||
742 | |||
743 | static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) | ||
744 | { | ||
745 | return &dev->stats; | ||
746 | } | ||
747 | |||
748 | static void read_bulk_callback(struct urb *urb) | ||
749 | { | ||
750 | struct r8152 *tp; | ||
751 | unsigned pkt_len; | ||
752 | struct sk_buff *skb; | ||
753 | struct net_device *netdev; | ||
754 | struct net_device_stats *stats; | ||
755 | int status = urb->status; | ||
756 | int result; | ||
757 | struct rx_desc *rx_desc; | ||
758 | |||
759 | tp = urb->context; | ||
760 | if (!tp) | ||
761 | return; | ||
762 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
763 | return; | ||
764 | netdev = tp->netdev; | ||
765 | if (!netif_device_present(netdev)) | ||
766 | return; | ||
767 | |||
768 | stats = rtl8152_get_stats(netdev); | ||
769 | switch (status) { | ||
770 | case 0: | ||
771 | break; | ||
772 | case -ESHUTDOWN: | ||
773 | set_bit(RTL8152_UNPLUG, &tp->flags); | ||
774 | netif_device_detach(tp->netdev); | ||
775 | case -ENOENT: | ||
776 | return; /* the urb is in unlink state */ | ||
777 | case -ETIME: | ||
778 | pr_warn_ratelimited("may be reset is needed?..\n"); | ||
779 | goto goon; | ||
780 | default: | ||
781 | pr_warn_ratelimited("Rx status %d\n", status); | ||
782 | goto goon; | ||
783 | } | ||
784 | |||
785 | /* protect against short packets (tell me why we got some?!?) */ | ||
786 | if (urb->actual_length < sizeof(*rx_desc)) | ||
787 | goto goon; | ||
788 | |||
789 | |||
790 | rx_desc = (struct rx_desc *)urb->transfer_buffer; | ||
791 | pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; | ||
792 | if (urb->actual_length < sizeof(struct rx_desc) + pkt_len) | ||
793 | goto goon; | ||
794 | |||
795 | skb = netdev_alloc_skb_ip_align(netdev, pkt_len); | ||
796 | if (!skb) | ||
797 | goto goon; | ||
798 | |||
799 | memcpy(skb->data, tp->rx_skb->data + sizeof(struct rx_desc), pkt_len); | ||
800 | skb_put(skb, pkt_len); | ||
801 | skb->protocol = eth_type_trans(skb, netdev); | ||
802 | netif_rx(skb); | ||
803 | stats->rx_packets++; | ||
804 | stats->rx_bytes += pkt_len; | ||
805 | goon: | ||
806 | usb_fill_bulk_urb(tp->rx_urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), | ||
807 | tp->rx_skb->data, RTL8152_RMS + sizeof(struct rx_desc), | ||
808 | (usb_complete_t)read_bulk_callback, tp); | ||
809 | result = usb_submit_urb(tp->rx_urb, GFP_ATOMIC); | ||
810 | if (result == -ENODEV) { | ||
811 | netif_device_detach(tp->netdev); | ||
812 | } else if (result) { | ||
813 | set_bit(RX_URB_FAIL, &tp->flags); | ||
814 | goto resched; | ||
815 | } else { | ||
816 | clear_bit(RX_URB_FAIL, &tp->flags); | ||
817 | } | ||
818 | |||
819 | return; | ||
820 | resched: | ||
821 | tasklet_schedule(&tp->tl); | ||
822 | } | ||
823 | |||
824 | static void rx_fixup(unsigned long data) | ||
825 | { | ||
826 | struct r8152 *tp; | ||
827 | int status; | ||
828 | |||
829 | tp = (struct r8152 *)data; | ||
830 | if (!test_bit(WORK_ENABLE, &tp->flags)) | ||
831 | return; | ||
832 | |||
833 | status = usb_submit_urb(tp->rx_urb, GFP_ATOMIC); | ||
834 | if (status == -ENODEV) { | ||
835 | netif_device_detach(tp->netdev); | ||
836 | } else if (status) { | ||
837 | set_bit(RX_URB_FAIL, &tp->flags); | ||
838 | goto tlsched; | ||
839 | } else { | ||
840 | clear_bit(RX_URB_FAIL, &tp->flags); | ||
841 | } | ||
842 | |||
843 | return; | ||
844 | tlsched: | ||
845 | tasklet_schedule(&tp->tl); | ||
846 | } | ||
847 | |||
848 | static void write_bulk_callback(struct urb *urb) | ||
849 | { | ||
850 | struct r8152 *tp; | ||
851 | int status = urb->status; | ||
852 | |||
853 | tp = urb->context; | ||
854 | if (!tp) | ||
855 | return; | ||
856 | dev_kfree_skb_irq(tp->tx_skb); | ||
857 | if (!netif_device_present(tp->netdev)) | ||
858 | return; | ||
859 | if (status) | ||
860 | dev_info(&urb->dev->dev, "%s: Tx status %d\n", | ||
861 | tp->netdev->name, status); | ||
862 | tp->netdev->trans_start = jiffies; | ||
863 | netif_wake_queue(tp->netdev); | ||
864 | } | ||
865 | |||
866 | static void rtl8152_tx_timeout(struct net_device *netdev) | ||
867 | { | ||
868 | struct r8152 *tp = netdev_priv(netdev); | ||
869 | struct net_device_stats *stats = rtl8152_get_stats(netdev); | ||
870 | netif_warn(tp, tx_err, netdev, "Tx timeout.\n"); | ||
871 | usb_unlink_urb(tp->tx_urb); | ||
872 | stats->tx_errors++; | ||
873 | } | ||
874 | |||
875 | static void rtl8152_set_rx_mode(struct net_device *netdev) | ||
876 | { | ||
877 | struct r8152 *tp = netdev_priv(netdev); | ||
878 | |||
879 | if (tp->speed & LINK_STATUS) | ||
880 | set_bit(RTL8152_SET_RX_MODE, &tp->flags); | ||
881 | } | ||
882 | |||
883 | static void _rtl8152_set_rx_mode(struct net_device *netdev) | ||
884 | { | ||
885 | struct r8152 *tp = netdev_priv(netdev); | ||
886 | u32 tmp, *mc_filter; /* Multicast hash filter */ | ||
887 | u32 ocp_data; | ||
888 | |||
889 | mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); | ||
890 | if (!mc_filter) { | ||
891 | netif_err(tp, link, netdev, "out of memory"); | ||
892 | return; | ||
893 | } | ||
894 | |||
895 | clear_bit(RTL8152_SET_RX_MODE, &tp->flags); | ||
896 | netif_stop_queue(netdev); | ||
897 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | ||
898 | ocp_data &= ~RCR_ACPT_ALL; | ||
899 | ocp_data |= RCR_AB | RCR_APM; | ||
900 | |||
901 | if (netdev->flags & IFF_PROMISC) { | ||
902 | /* Unconditionally log net taps. */ | ||
903 | netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); | ||
904 | ocp_data |= RCR_AM | RCR_AAP; | ||
905 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
906 | } else if ((netdev_mc_count(netdev) > multicast_filter_limit) || | ||
907 | (netdev->flags & IFF_ALLMULTI)) { | ||
908 | /* Too many to filter perfectly -- accept all multicasts. */ | ||
909 | ocp_data |= RCR_AM; | ||
910 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
911 | } else { | ||
912 | struct netdev_hw_addr *ha; | ||
913 | |||
914 | mc_filter[1] = mc_filter[0] = 0; | ||
915 | netdev_for_each_mc_addr(ha, netdev) { | ||
916 | int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; | ||
917 | mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); | ||
918 | ocp_data |= RCR_AM; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | tmp = mc_filter[0]; | ||
923 | mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); | ||
924 | mc_filter[1] = __cpu_to_le32(swab32(tmp)); | ||
925 | |||
926 | pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); | ||
927 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | ||
928 | netif_wake_queue(netdev); | ||
929 | kfree(mc_filter); | ||
930 | } | ||
931 | |||
932 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, | ||
933 | struct net_device *netdev) | ||
934 | { | ||
935 | struct r8152 *tp = netdev_priv(netdev); | ||
936 | struct net_device_stats *stats = rtl8152_get_stats(netdev); | ||
937 | struct tx_desc *tx_desc; | ||
938 | int len, res; | ||
939 | |||
940 | netif_stop_queue(netdev); | ||
941 | len = skb->len; | ||
942 | if (skb_header_cloned(skb) || skb_headroom(skb) < sizeof(*tx_desc)) { | ||
943 | struct sk_buff *tx_skb; | ||
944 | |||
945 | tx_skb = skb_copy_expand(skb, sizeof(*tx_desc), 0, GFP_ATOMIC); | ||
946 | dev_kfree_skb_any(skb); | ||
947 | if (!tx_skb) { | ||
948 | stats->tx_dropped++; | ||
949 | netif_wake_queue(netdev); | ||
950 | return NETDEV_TX_OK; | ||
951 | } | ||
952 | skb = tx_skb; | ||
953 | } | ||
954 | tx_desc = (struct tx_desc *)skb_push(skb, sizeof(*tx_desc)); | ||
955 | memset(tx_desc, 0, sizeof(*tx_desc)); | ||
956 | tx_desc->opts1 = cpu_to_le32((len & TX_LEN_MASK) | TX_FS | TX_LS); | ||
957 | tp->tx_skb = skb; | ||
958 | skb_tx_timestamp(skb); | ||
959 | usb_fill_bulk_urb(tp->tx_urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), | ||
960 | skb->data, skb->len, | ||
961 | (usb_complete_t)write_bulk_callback, tp); | ||
962 | res = usb_submit_urb(tp->tx_urb, GFP_ATOMIC); | ||
963 | if (res) { | ||
964 | /* Can we get/handle EPIPE here? */ | ||
965 | if (res == -ENODEV) { | ||
966 | netif_device_detach(tp->netdev); | ||
967 | } else { | ||
968 | netif_warn(tp, tx_err, netdev, | ||
969 | "failed tx_urb %d\n", res); | ||
970 | stats->tx_errors++; | ||
971 | netif_start_queue(netdev); | ||
972 | } | ||
973 | } else { | ||
974 | stats->tx_packets++; | ||
975 | stats->tx_bytes += skb->len; | ||
976 | } | ||
977 | |||
978 | return NETDEV_TX_OK; | ||
979 | } | ||
980 | |||
981 | static void r8152b_reset_packet_filter(struct r8152 *tp) | ||
982 | { | ||
983 | u32 ocp_data; | ||
984 | |||
985 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); | ||
986 | ocp_data &= ~FMC_FCR_MCU_EN; | ||
987 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); | ||
988 | ocp_data |= FMC_FCR_MCU_EN; | ||
989 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); | ||
990 | } | ||
991 | |||
992 | static void rtl8152_nic_reset(struct r8152 *tp) | ||
993 | { | ||
994 | int i; | ||
995 | |||
996 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); | ||
997 | |||
998 | for (i = 0; i < 1000; i++) { | ||
999 | if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) | ||
1000 | break; | ||
1001 | udelay(100); | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | static inline u8 rtl8152_get_speed(struct r8152 *tp) | ||
1006 | { | ||
1007 | return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); | ||
1008 | } | ||
1009 | |||
1010 | static int rtl8152_enable(struct r8152 *tp) | ||
1011 | { | ||
1012 | u32 ocp_data; | ||
1013 | u8 speed; | ||
1014 | |||
1015 | speed = rtl8152_get_speed(tp); | ||
1016 | if (speed & _100bps) { | ||
1017 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); | ||
1018 | ocp_data &= ~EEEP_CR_EEEP_TX; | ||
1019 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); | ||
1020 | } else { | ||
1021 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); | ||
1022 | ocp_data |= EEEP_CR_EEEP_TX; | ||
1023 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); | ||
1024 | } | ||
1025 | |||
1026 | r8152b_reset_packet_filter(tp); | ||
1027 | |||
1028 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); | ||
1029 | ocp_data |= CR_RE | CR_TE; | ||
1030 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); | ||
1031 | |||
1032 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); | ||
1033 | ocp_data &= ~RXDY_GATED_EN; | ||
1034 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); | ||
1035 | |||
1036 | usb_fill_bulk_urb(tp->rx_urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), | ||
1037 | tp->rx_skb->data, RTL8152_RMS + sizeof(struct rx_desc), | ||
1038 | (usb_complete_t)read_bulk_callback, tp); | ||
1039 | |||
1040 | return usb_submit_urb(tp->rx_urb, GFP_KERNEL); | ||
1041 | } | ||
1042 | |||
1043 | static void rtl8152_disable(struct r8152 *tp) | ||
1044 | { | ||
1045 | u32 ocp_data; | ||
1046 | int i; | ||
1047 | |||
1048 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | ||
1049 | ocp_data &= ~RCR_ACPT_ALL; | ||
1050 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | ||
1051 | |||
1052 | usb_kill_urb(tp->tx_urb); | ||
1053 | |||
1054 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); | ||
1055 | ocp_data |= RXDY_GATED_EN; | ||
1056 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); | ||
1057 | |||
1058 | for (i = 0; i < 1000; i++) { | ||
1059 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1060 | if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY) | ||
1061 | break; | ||
1062 | mdelay(1); | ||
1063 | } | ||
1064 | |||
1065 | for (i = 0; i < 1000; i++) { | ||
1066 | if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY) | ||
1067 | break; | ||
1068 | mdelay(1); | ||
1069 | } | ||
1070 | |||
1071 | usb_kill_urb(tp->rx_urb); | ||
1072 | |||
1073 | rtl8152_nic_reset(tp); | ||
1074 | } | ||
1075 | |||
1076 | static void r8152b_exit_oob(struct r8152 *tp) | ||
1077 | { | ||
1078 | u32 ocp_data; | ||
1079 | int i; | ||
1080 | |||
1081 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | ||
1082 | ocp_data &= ~RCR_ACPT_ALL; | ||
1083 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | ||
1084 | |||
1085 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); | ||
1086 | ocp_data |= RXDY_GATED_EN; | ||
1087 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); | ||
1088 | |||
1089 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); | ||
1090 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00); | ||
1091 | |||
1092 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1093 | ocp_data &= ~NOW_IS_OOB; | ||
1094 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); | ||
1095 | |||
1096 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); | ||
1097 | ocp_data &= ~MCU_BORW_EN; | ||
1098 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); | ||
1099 | |||
1100 | for (i = 0; i < 1000; i++) { | ||
1101 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1102 | if (ocp_data & LINK_LIST_READY) | ||
1103 | break; | ||
1104 | mdelay(1); | ||
1105 | } | ||
1106 | |||
1107 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); | ||
1108 | ocp_data |= RE_INIT_LL; | ||
1109 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); | ||
1110 | |||
1111 | for (i = 0; i < 1000; i++) { | ||
1112 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1113 | if (ocp_data & LINK_LIST_READY) | ||
1114 | break; | ||
1115 | mdelay(1); | ||
1116 | } | ||
1117 | |||
1118 | rtl8152_nic_reset(tp); | ||
1119 | |||
1120 | /* rx share fifo credit full threshold */ | ||
1121 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL); | ||
1122 | |||
1123 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_DEV_STAT); | ||
1124 | ocp_data &= STAT_SPEED_MASK; | ||
1125 | if (ocp_data == STAT_SPEED_FULL) { | ||
1126 | /* rx share fifo credit near full threshold */ | ||
1127 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, | ||
1128 | RXFIFO_THR2_FULL); | ||
1129 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, | ||
1130 | RXFIFO_THR3_FULL); | ||
1131 | } else { | ||
1132 | /* rx share fifo credit near full threshold */ | ||
1133 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, | ||
1134 | RXFIFO_THR2_HIGH); | ||
1135 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, | ||
1136 | RXFIFO_THR3_HIGH); | ||
1137 | } | ||
1138 | |||
1139 | /* TX share fifo free credit full threshold */ | ||
1140 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL); | ||
1141 | |||
1142 | ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD); | ||
1143 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_BUF_THR); | ||
1144 | ocp_write_dword(tp, MCU_TYPE_USB, USB_TX_DMA, | ||
1145 | TEST_MODE_DISABLE | TX_SIZE_ADJUST1); | ||
1146 | |||
1147 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | ||
1148 | ocp_data &= ~CPCR_RX_VLAN; | ||
1149 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
1150 | |||
1151 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); | ||
1152 | |||
1153 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); | ||
1154 | ocp_data |= TCR0_AUTO_FIFO; | ||
1155 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data); | ||
1156 | } | ||
1157 | |||
1158 | static void r8152b_enter_oob(struct r8152 *tp) | ||
1159 | { | ||
1160 | u32 ocp_data; | ||
1161 | int i; | ||
1162 | |||
1163 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1164 | ocp_data &= ~NOW_IS_OOB; | ||
1165 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); | ||
1166 | |||
1167 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); | ||
1168 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB); | ||
1169 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB); | ||
1170 | |||
1171 | rtl8152_disable(tp); | ||
1172 | |||
1173 | for (i = 0; i < 1000; i++) { | ||
1174 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1175 | if (ocp_data & LINK_LIST_READY) | ||
1176 | break; | ||
1177 | mdelay(1); | ||
1178 | } | ||
1179 | |||
1180 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); | ||
1181 | ocp_data |= RE_INIT_LL; | ||
1182 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); | ||
1183 | |||
1184 | for (i = 0; i < 1000; i++) { | ||
1185 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1186 | if (ocp_data & LINK_LIST_READY) | ||
1187 | break; | ||
1188 | mdelay(1); | ||
1189 | } | ||
1190 | |||
1191 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); | ||
1192 | |||
1193 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL); | ||
1194 | ocp_data |= MAGIC_EN; | ||
1195 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data); | ||
1196 | |||
1197 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | ||
1198 | ocp_data |= CPCR_RX_VLAN; | ||
1199 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
1200 | |||
1201 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); | ||
1202 | ocp_data |= ALDPS_PROXY_MODE; | ||
1203 | ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data); | ||
1204 | |||
1205 | ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); | ||
1206 | ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; | ||
1207 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); | ||
1208 | |||
1209 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN); | ||
1210 | |||
1211 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); | ||
1212 | ocp_data &= ~RXDY_GATED_EN; | ||
1213 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); | ||
1214 | |||
1215 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | ||
1216 | ocp_data |= RCR_APM | RCR_AM | RCR_AB; | ||
1217 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | ||
1218 | } | ||
1219 | |||
1220 | static void r8152b_disable_aldps(struct r8152 *tp) | ||
1221 | { | ||
1222 | ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPDNPS | LINKENA | DIS_SDSAVE); | ||
1223 | msleep(20); | ||
1224 | } | ||
1225 | |||
1226 | static inline void r8152b_enable_aldps(struct r8152 *tp) | ||
1227 | { | ||
1228 | ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPWRSAVE | ENPDNPS | | ||
1229 | LINKENA | DIS_SDSAVE); | ||
1230 | } | ||
1231 | |||
1232 | static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex) | ||
1233 | { | ||
1234 | u16 bmcr, anar; | ||
1235 | int ret = 0; | ||
1236 | |||
1237 | cancel_delayed_work_sync(&tp->schedule); | ||
1238 | anar = r8152_mdio_read(tp, MII_ADVERTISE); | ||
1239 | anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | | ||
1240 | ADVERTISE_100HALF | ADVERTISE_100FULL); | ||
1241 | |||
1242 | if (autoneg == AUTONEG_DISABLE) { | ||
1243 | if (speed == SPEED_10) { | ||
1244 | bmcr = 0; | ||
1245 | anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; | ||
1246 | } else if (speed == SPEED_100) { | ||
1247 | bmcr = BMCR_SPEED100; | ||
1248 | anar |= ADVERTISE_100HALF | ADVERTISE_100FULL; | ||
1249 | } else { | ||
1250 | ret = -EINVAL; | ||
1251 | goto out; | ||
1252 | } | ||
1253 | |||
1254 | if (duplex == DUPLEX_FULL) | ||
1255 | bmcr |= BMCR_FULLDPLX; | ||
1256 | } else { | ||
1257 | if (speed == SPEED_10) { | ||
1258 | if (duplex == DUPLEX_FULL) | ||
1259 | anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; | ||
1260 | else | ||
1261 | anar |= ADVERTISE_10HALF; | ||
1262 | } else if (speed == SPEED_100) { | ||
1263 | if (duplex == DUPLEX_FULL) { | ||
1264 | anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; | ||
1265 | anar |= ADVERTISE_100HALF | ADVERTISE_100FULL; | ||
1266 | } else { | ||
1267 | anar |= ADVERTISE_10HALF; | ||
1268 | anar |= ADVERTISE_100HALF; | ||
1269 | } | ||
1270 | } else { | ||
1271 | ret = -EINVAL; | ||
1272 | goto out; | ||
1273 | } | ||
1274 | |||
1275 | bmcr = BMCR_ANENABLE | BMCR_ANRESTART; | ||
1276 | } | ||
1277 | |||
1278 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | ||
1279 | r8152_mdio_write(tp, MII_BMCR, bmcr); | ||
1280 | |||
1281 | out: | ||
1282 | schedule_delayed_work(&tp->schedule, 5 * HZ); | ||
1283 | |||
1284 | return ret; | ||
1285 | } | ||
1286 | |||
1287 | static void rtl8152_down(struct r8152 *tp) | ||
1288 | { | ||
1289 | u32 ocp_data; | ||
1290 | |||
1291 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL); | ||
1292 | ocp_data &= ~POWER_CUT; | ||
1293 | ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data); | ||
1294 | |||
1295 | r8152b_disable_aldps(tp); | ||
1296 | r8152b_enter_oob(tp); | ||
1297 | r8152b_enable_aldps(tp); | ||
1298 | } | ||
1299 | |||
1300 | static void set_carrier(struct r8152 *tp) | ||
1301 | { | ||
1302 | struct net_device *netdev = tp->netdev; | ||
1303 | u8 speed; | ||
1304 | |||
1305 | speed = rtl8152_get_speed(tp); | ||
1306 | |||
1307 | if (speed & LINK_STATUS) { | ||
1308 | if (!(tp->speed & LINK_STATUS)) { | ||
1309 | rtl8152_enable(tp); | ||
1310 | set_bit(RTL8152_SET_RX_MODE, &tp->flags); | ||
1311 | netif_carrier_on(netdev); | ||
1312 | } | ||
1313 | } else { | ||
1314 | if (tp->speed & LINK_STATUS) { | ||
1315 | netif_carrier_off(netdev); | ||
1316 | rtl8152_disable(tp); | ||
1317 | } | ||
1318 | } | ||
1319 | tp->speed = speed; | ||
1320 | } | ||
1321 | |||
1322 | static void rtl_work_func_t(struct work_struct *work) | ||
1323 | { | ||
1324 | struct r8152 *tp = container_of(work, struct r8152, schedule.work); | ||
1325 | |||
1326 | if (!test_bit(WORK_ENABLE, &tp->flags)) | ||
1327 | goto out1; | ||
1328 | |||
1329 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | ||
1330 | goto out1; | ||
1331 | |||
1332 | set_carrier(tp); | ||
1333 | |||
1334 | if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) | ||
1335 | _rtl8152_set_rx_mode(tp->netdev); | ||
1336 | |||
1337 | schedule_delayed_work(&tp->schedule, HZ); | ||
1338 | |||
1339 | out1: | ||
1340 | return; | ||
1341 | } | ||
1342 | |||
1343 | static int rtl8152_open(struct net_device *netdev) | ||
1344 | { | ||
1345 | struct r8152 *tp = netdev_priv(netdev); | ||
1346 | int res = 0; | ||
1347 | |||
1348 | tp->speed = rtl8152_get_speed(tp); | ||
1349 | if (tp->speed & LINK_STATUS) { | ||
1350 | res = rtl8152_enable(tp); | ||
1351 | if (res) { | ||
1352 | if (res == -ENODEV) | ||
1353 | netif_device_detach(tp->netdev); | ||
1354 | |||
1355 | netif_err(tp, ifup, netdev, | ||
1356 | "rtl8152_open failed: %d\n", res); | ||
1357 | return res; | ||
1358 | } | ||
1359 | |||
1360 | netif_carrier_on(netdev); | ||
1361 | } else { | ||
1362 | netif_stop_queue(netdev); | ||
1363 | netif_carrier_off(netdev); | ||
1364 | } | ||
1365 | |||
1366 | rtl8152_set_speed(tp, AUTONEG_ENABLE, SPEED_100, DUPLEX_FULL); | ||
1367 | netif_start_queue(netdev); | ||
1368 | set_bit(WORK_ENABLE, &tp->flags); | ||
1369 | schedule_delayed_work(&tp->schedule, 0); | ||
1370 | |||
1371 | return res; | ||
1372 | } | ||
1373 | |||
1374 | static int rtl8152_close(struct net_device *netdev) | ||
1375 | { | ||
1376 | struct r8152 *tp = netdev_priv(netdev); | ||
1377 | int res = 0; | ||
1378 | |||
1379 | clear_bit(WORK_ENABLE, &tp->flags); | ||
1380 | cancel_delayed_work_sync(&tp->schedule); | ||
1381 | netif_stop_queue(netdev); | ||
1382 | rtl8152_disable(tp); | ||
1383 | |||
1384 | return res; | ||
1385 | } | ||
1386 | |||
1387 | static void rtl_clear_bp(struct r8152 *tp) | ||
1388 | { | ||
1389 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0); | ||
1390 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0); | ||
1391 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0); | ||
1392 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0); | ||
1393 | ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0); | ||
1394 | ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0); | ||
1395 | ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0); | ||
1396 | ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0); | ||
1397 | mdelay(3); | ||
1398 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0); | ||
1399 | ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0); | ||
1400 | } | ||
1401 | |||
1402 | static void r8152b_enable_eee(struct r8152 *tp) | ||
1403 | { | ||
1404 | u32 ocp_data; | ||
1405 | |||
1406 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); | ||
1407 | ocp_data |= EEE_RX_EN | EEE_TX_EN; | ||
1408 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); | ||
1409 | ocp_reg_write(tp, OCP_EEE_CONFIG1, RG_TXLPI_MSK_HFDUP | RG_MATCLR_EN | | ||
1410 | EEE_10_CAP | EEE_NWAY_EN | | ||
1411 | TX_QUIET_EN | RX_QUIET_EN | | ||
1412 | SDRISETIME | RG_RXLPI_MSK_HFDUP | | ||
1413 | SDFALLTIME); | ||
1414 | ocp_reg_write(tp, OCP_EEE_CONFIG2, RG_LPIHYS_NUM | RG_DACQUIET_EN | | ||
1415 | RG_LDVQUIET_EN | RG_CKRSEL | | ||
1416 | RG_EEEPRG_EN); | ||
1417 | ocp_reg_write(tp, OCP_EEE_CONFIG3, FST_SNR_EYE_R | RG_LFS_SEL | MSK_PH); | ||
1418 | ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | DEVICE_ADDR); | ||
1419 | ocp_reg_write(tp, OCP_EEE_DATA, EEE_ADDR); | ||
1420 | ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | DEVICE_ADDR); | ||
1421 | ocp_reg_write(tp, OCP_EEE_DATA, EEE_DATA); | ||
1422 | ocp_reg_write(tp, OCP_EEE_AR, 0x0000); | ||
1423 | } | ||
1424 | |||
1425 | static void r8152b_enable_fc(struct r8152 *tp) | ||
1426 | { | ||
1427 | u16 anar; | ||
1428 | |||
1429 | anar = r8152_mdio_read(tp, MII_ADVERTISE); | ||
1430 | anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | ||
1431 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | ||
1432 | } | ||
1433 | |||
1434 | static void r8152b_hw_phy_cfg(struct r8152 *tp) | ||
1435 | { | ||
1436 | r8152_mdio_write(tp, MII_BMCR, BMCR_ANENABLE); | ||
1437 | r8152b_disable_aldps(tp); | ||
1438 | } | ||
1439 | |||
1440 | static void r8152b_init(struct r8152 *tp) | ||
1441 | { | ||
1442 | u32 ocp_data; | ||
1443 | int i; | ||
1444 | |||
1445 | rtl_clear_bp(tp); | ||
1446 | |||
1447 | if (tp->version == RTL_VER_01) { | ||
1448 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE); | ||
1449 | ocp_data &= ~LED_MODE_MASK; | ||
1450 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data); | ||
1451 | } | ||
1452 | |||
1453 | r8152b_hw_phy_cfg(tp); | ||
1454 | |||
1455 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL); | ||
1456 | ocp_data &= ~POWER_CUT; | ||
1457 | ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data); | ||
1458 | |||
1459 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS); | ||
1460 | ocp_data &= ~RWSUME_INDICATE; | ||
1461 | ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); | ||
1462 | |||
1463 | r8152b_exit_oob(tp); | ||
1464 | |||
1465 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); | ||
1466 | ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH; | ||
1467 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); | ||
1468 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL); | ||
1469 | ocp_data &= ~MCU_CLK_RATIO_MASK; | ||
1470 | ocp_data |= MCU_CLK_RATIO | D3_CLK_GATED_EN; | ||
1471 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ocp_data); | ||
1472 | ocp_data = GPHY_STS_MSK | SPEED_DOWN_MSK | | ||
1473 | SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; | ||
1474 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); | ||
1475 | |||
1476 | r8152b_enable_eee(tp); | ||
1477 | r8152b_enable_aldps(tp); | ||
1478 | r8152b_enable_fc(tp); | ||
1479 | |||
1480 | r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | | ||
1481 | BMCR_ANRESTART); | ||
1482 | for (i = 0; i < 100; i++) { | ||
1483 | udelay(100); | ||
1484 | if (!(r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET)) | ||
1485 | break; | ||
1486 | } | ||
1487 | |||
1488 | /* disable rx aggregation */ | ||
1489 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); | ||
1490 | ocp_data |= RX_AGG_DISABLE; | ||
1491 | ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); | ||
1492 | } | ||
1493 | |||
1494 | static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) | ||
1495 | { | ||
1496 | struct r8152 *tp = usb_get_intfdata(intf); | ||
1497 | |||
1498 | netif_device_detach(tp->netdev); | ||
1499 | |||
1500 | if (netif_running(tp->netdev)) { | ||
1501 | clear_bit(WORK_ENABLE, &tp->flags); | ||
1502 | cancel_delayed_work_sync(&tp->schedule); | ||
1503 | } | ||
1504 | |||
1505 | rtl8152_down(tp); | ||
1506 | |||
1507 | return 0; | ||
1508 | } | ||
1509 | |||
1510 | static int rtl8152_resume(struct usb_interface *intf) | ||
1511 | { | ||
1512 | struct r8152 *tp = usb_get_intfdata(intf); | ||
1513 | |||
1514 | r8152b_init(tp); | ||
1515 | netif_device_attach(tp->netdev); | ||
1516 | if (netif_running(tp->netdev)) { | ||
1517 | rtl8152_enable(tp); | ||
1518 | set_bit(WORK_ENABLE, &tp->flags); | ||
1519 | set_bit(RTL8152_SET_RX_MODE, &tp->flags); | ||
1520 | schedule_delayed_work(&tp->schedule, 0); | ||
1521 | } | ||
1522 | |||
1523 | return 0; | ||
1524 | } | ||
1525 | |||
1526 | static void rtl8152_get_drvinfo(struct net_device *netdev, | ||
1527 | struct ethtool_drvinfo *info) | ||
1528 | { | ||
1529 | struct r8152 *tp = netdev_priv(netdev); | ||
1530 | |||
1531 | strncpy(info->driver, MODULENAME, ETHTOOL_BUSINFO_LEN); | ||
1532 | strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); | ||
1533 | usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); | ||
1534 | } | ||
1535 | |||
1536 | static | ||
1537 | int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) | ||
1538 | { | ||
1539 | struct r8152 *tp = netdev_priv(netdev); | ||
1540 | |||
1541 | if (!tp->mii.mdio_read) | ||
1542 | return -EOPNOTSUPP; | ||
1543 | |||
1544 | return mii_ethtool_gset(&tp->mii, cmd); | ||
1545 | } | ||
1546 | |||
1547 | static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1548 | { | ||
1549 | struct r8152 *tp = netdev_priv(dev); | ||
1550 | |||
1551 | return rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); | ||
1552 | } | ||
1553 | |||
1554 | static struct ethtool_ops ops = { | ||
1555 | .get_drvinfo = rtl8152_get_drvinfo, | ||
1556 | .get_settings = rtl8152_get_settings, | ||
1557 | .set_settings = rtl8152_set_settings, | ||
1558 | .get_link = ethtool_op_get_link, | ||
1559 | }; | ||
1560 | |||
1561 | static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | ||
1562 | { | ||
1563 | struct r8152 *tp = netdev_priv(netdev); | ||
1564 | struct mii_ioctl_data *data = if_mii(rq); | ||
1565 | int res = 0; | ||
1566 | |||
1567 | switch (cmd) { | ||
1568 | case SIOCGMIIPHY: | ||
1569 | data->phy_id = R8152_PHY_ID; /* Internal PHY */ | ||
1570 | break; | ||
1571 | |||
1572 | case SIOCGMIIREG: | ||
1573 | data->val_out = r8152_mdio_read(tp, data->reg_num); | ||
1574 | break; | ||
1575 | |||
1576 | case SIOCSMIIREG: | ||
1577 | if (!capable(CAP_NET_ADMIN)) { | ||
1578 | res = -EPERM; | ||
1579 | break; | ||
1580 | } | ||
1581 | r8152_mdio_write(tp, data->reg_num, data->val_in); | ||
1582 | break; | ||
1583 | |||
1584 | default: | ||
1585 | res = -EOPNOTSUPP; | ||
1586 | } | ||
1587 | |||
1588 | return res; | ||
1589 | } | ||
1590 | |||
1591 | static const struct net_device_ops rtl8152_netdev_ops = { | ||
1592 | .ndo_open = rtl8152_open, | ||
1593 | .ndo_stop = rtl8152_close, | ||
1594 | .ndo_do_ioctl = rtl8152_ioctl, | ||
1595 | .ndo_start_xmit = rtl8152_start_xmit, | ||
1596 | .ndo_tx_timeout = rtl8152_tx_timeout, | ||
1597 | .ndo_set_rx_mode = rtl8152_set_rx_mode, | ||
1598 | .ndo_set_mac_address = rtl8152_set_mac_address, | ||
1599 | |||
1600 | .ndo_change_mtu = eth_change_mtu, | ||
1601 | .ndo_validate_addr = eth_validate_addr, | ||
1602 | }; | ||
1603 | |||
1604 | static void r8152b_get_version(struct r8152 *tp) | ||
1605 | { | ||
1606 | u32 ocp_data; | ||
1607 | u16 version; | ||
1608 | |||
1609 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); | ||
1610 | version = (u16)(ocp_data & VERSION_MASK); | ||
1611 | |||
1612 | switch (version) { | ||
1613 | case 0x4c00: | ||
1614 | tp->version = RTL_VER_01; | ||
1615 | break; | ||
1616 | case 0x4c10: | ||
1617 | tp->version = RTL_VER_02; | ||
1618 | break; | ||
1619 | default: | ||
1620 | netif_info(tp, probe, tp->netdev, | ||
1621 | "Unknown version 0x%04x\n", version); | ||
1622 | break; | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | static int rtl8152_probe(struct usb_interface *intf, | ||
1627 | const struct usb_device_id *id) | ||
1628 | { | ||
1629 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1630 | struct r8152 *tp; | ||
1631 | struct net_device *netdev; | ||
1632 | |||
1633 | if (udev->actconfig->desc.bConfigurationValue != 1) { | ||
1634 | usb_driver_set_configuration(udev, 1); | ||
1635 | return -ENODEV; | ||
1636 | } | ||
1637 | |||
1638 | netdev = alloc_etherdev(sizeof(struct r8152)); | ||
1639 | if (!netdev) { | ||
1640 | dev_err(&intf->dev, "Out of memory"); | ||
1641 | return -ENOMEM; | ||
1642 | } | ||
1643 | |||
1644 | tp = netdev_priv(netdev); | ||
1645 | tp->msg_enable = 0x7FFF; | ||
1646 | |||
1647 | tasklet_init(&tp->tl, rx_fixup, (unsigned long)tp); | ||
1648 | INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t); | ||
1649 | |||
1650 | tp->udev = udev; | ||
1651 | tp->netdev = netdev; | ||
1652 | netdev->netdev_ops = &rtl8152_netdev_ops; | ||
1653 | netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; | ||
1654 | netdev->features &= ~NETIF_F_IP_CSUM; | ||
1655 | SET_ETHTOOL_OPS(netdev, &ops); | ||
1656 | tp->speed = 0; | ||
1657 | |||
1658 | tp->mii.dev = netdev; | ||
1659 | tp->mii.mdio_read = read_mii_word; | ||
1660 | tp->mii.mdio_write = write_mii_word; | ||
1661 | tp->mii.phy_id_mask = 0x3f; | ||
1662 | tp->mii.reg_num_mask = 0x1f; | ||
1663 | tp->mii.phy_id = R8152_PHY_ID; | ||
1664 | tp->mii.supports_gmii = 0; | ||
1665 | |||
1666 | r8152b_get_version(tp); | ||
1667 | r8152b_init(tp); | ||
1668 | set_ethernet_addr(tp); | ||
1669 | |||
1670 | if (!alloc_all_urbs(tp)) { | ||
1671 | netif_err(tp, probe, netdev, "out of memory"); | ||
1672 | goto out; | ||
1673 | } | ||
1674 | |||
1675 | tp->rx_skb = netdev_alloc_skb(netdev, | ||
1676 | RTL8152_RMS + sizeof(struct rx_desc)); | ||
1677 | if (!tp->rx_skb) | ||
1678 | goto out1; | ||
1679 | |||
1680 | usb_set_intfdata(intf, tp); | ||
1681 | SET_NETDEV_DEV(netdev, &intf->dev); | ||
1682 | |||
1683 | |||
1684 | if (register_netdev(netdev) != 0) { | ||
1685 | netif_err(tp, probe, netdev, "couldn't register the device"); | ||
1686 | goto out2; | ||
1687 | } | ||
1688 | |||
1689 | netif_info(tp, probe, netdev, "%s", DRIVER_VERSION); | ||
1690 | |||
1691 | return 0; | ||
1692 | |||
1693 | out2: | ||
1694 | usb_set_intfdata(intf, NULL); | ||
1695 | dev_kfree_skb(tp->rx_skb); | ||
1696 | out1: | ||
1697 | free_all_urbs(tp); | ||
1698 | out: | ||
1699 | free_netdev(netdev); | ||
1700 | return -EIO; | ||
1701 | } | ||
1702 | |||
1703 | static void rtl8152_unload(struct r8152 *tp) | ||
1704 | { | ||
1705 | u32 ocp_data; | ||
1706 | |||
1707 | if (tp->version != RTL_VER_01) { | ||
1708 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL); | ||
1709 | ocp_data |= POWER_CUT; | ||
1710 | ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data); | ||
1711 | } | ||
1712 | |||
1713 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS); | ||
1714 | ocp_data &= ~RWSUME_INDICATE; | ||
1715 | ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); | ||
1716 | } | ||
1717 | |||
1718 | static void rtl8152_disconnect(struct usb_interface *intf) | ||
1719 | { | ||
1720 | struct r8152 *tp = usb_get_intfdata(intf); | ||
1721 | |||
1722 | usb_set_intfdata(intf, NULL); | ||
1723 | if (tp) { | ||
1724 | set_bit(RTL8152_UNPLUG, &tp->flags); | ||
1725 | tasklet_kill(&tp->tl); | ||
1726 | unregister_netdev(tp->netdev); | ||
1727 | rtl8152_unload(tp); | ||
1728 | free_all_urbs(tp); | ||
1729 | if (tp->rx_skb) | ||
1730 | dev_kfree_skb(tp->rx_skb); | ||
1731 | free_netdev(tp->netdev); | ||
1732 | } | ||
1733 | } | ||
1734 | |||
1735 | /* table of devices that work with this driver */ | ||
1736 | static struct usb_device_id rtl8152_table[] = { | ||
1737 | {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, | ||
1738 | {} | ||
1739 | }; | ||
1740 | |||
1741 | MODULE_DEVICE_TABLE(usb, rtl8152_table); | ||
1742 | |||
1743 | static struct usb_driver rtl8152_driver = { | ||
1744 | .name = MODULENAME, | ||
1745 | .probe = rtl8152_probe, | ||
1746 | .disconnect = rtl8152_disconnect, | ||
1747 | .id_table = rtl8152_table, | ||
1748 | .suspend = rtl8152_suspend, | ||
1749 | .resume = rtl8152_resume | ||
1750 | }; | ||
1751 | |||
1752 | static int __init usb_rtl8152_init(void) | ||
1753 | { | ||
1754 | return usb_register(&rtl8152_driver); | ||
1755 | } | ||
1756 | |||
1757 | static void __exit usb_rtl8152_exit(void) | ||
1758 | { | ||
1759 | usb_deregister(&rtl8152_driver); | ||
1760 | } | ||
1761 | |||
1762 | module_init(usb_rtl8152_init); | ||
1763 | module_exit(usb_rtl8152_exit); | ||
1764 | |||
1765 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1766 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1767 | MODULE_LICENSE("GPL"); | ||