diff options
71 files changed, 3567 insertions, 204 deletions
@@ -1856,7 +1856,7 @@ E: rfkoenig@immd4.informatik.uni-erlangen.de | |||
1856 | D: The Linux Support Team Erlangen | 1856 | D: The Linux Support Team Erlangen |
1857 | 1857 | ||
1858 | N: Andreas Koensgen | 1858 | N: Andreas Koensgen |
1859 | E: ajk@iehk.rwth-aachen.de | 1859 | E: ajk@comnets.uni-bremen.de |
1860 | D: 6pack driver for AX.25 | 1860 | D: 6pack driver for AX.25 |
1861 | 1861 | ||
1862 | N: Harald Koerfgen | 1862 | N: Harald Koerfgen |
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index 6e73190af0be..1711adc33373 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cn_test.c | 2 | * cn_test.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -197,5 +197,5 @@ module_init(cn_test_init); | |||
197 | module_exit(cn_test_fini); | 197 | module_exit(cn_test_fini); |
198 | 198 | ||
199 | MODULE_LICENSE("GPL"); | 199 | MODULE_LICENSE("GPL"); |
200 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 200 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
201 | MODULE_DESCRIPTION("Connector's test module"); | 201 | MODULE_DESCRIPTION("Connector's test module"); |
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c index a8e4d5885ad4..4848db8c71ff 100644 --- a/Documentation/connector/ucon.c +++ b/Documentation/connector/ucon.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ucon.c | 2 | * ucon.c |
3 | * | 3 | * |
4 | * Copyright (c) 2004+ Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * Copyright (c) 2004+ Evgeniy Polyakov <zbr@ioremap.net> |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/Documentation/networking/6pack.txt b/Documentation/networking/6pack.txt index d0777a1200e1..8f339428fdf4 100644 --- a/Documentation/networking/6pack.txt +++ b/Documentation/networking/6pack.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | This is the 6pack-mini-HOWTO, written by | 1 | This is the 6pack-mini-HOWTO, written by |
2 | 2 | ||
3 | Andreas Könsgen DG3KQ | 3 | Andreas Könsgen DG3KQ |
4 | Internet: ajk@iehk.rwth-aachen.de | 4 | Internet: ajk@comnets.uni-bremen.de |
5 | AMPR-net: dg3kq@db0pra.ampr.org | 5 | AMPR-net: dg3kq@db0pra.ampr.org |
6 | AX.25: dg3kq@db0ach.#nrw.deu.eu | 6 | AX.25: dg3kq@db0ach.#nrw.deu.eu |
7 | 7 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 57ea97973349..d119ba9e724d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -150,7 +150,7 @@ F: drivers/scsi/53c700* | |||
150 | 150 | ||
151 | 6PACK NETWORK DRIVER FOR AX.25 | 151 | 6PACK NETWORK DRIVER FOR AX.25 |
152 | P: Andreas Koensgen | 152 | P: Andreas Koensgen |
153 | M: ajk@iehk.rwth-aachen.de | 153 | M: ajk@comnets.uni-bremen.de |
154 | L: linux-hams@vger.kernel.org | 154 | L: linux-hams@vger.kernel.org |
155 | S: Maintained | 155 | S: Maintained |
156 | F: drivers/net/hamradio/6pack.c | 156 | F: drivers/net/hamradio/6pack.c |
@@ -1612,6 +1612,13 @@ S: Supported | |||
1612 | F: fs/configfs/ | 1612 | F: fs/configfs/ |
1613 | F: include/linux/configfs.h | 1613 | F: include/linux/configfs.h |
1614 | 1614 | ||
1615 | CONNECTOR | ||
1616 | P: Evgeniy Polyakov | ||
1617 | M: zbr@ioremap.net | ||
1618 | L: netdev@vger.kernel.org | ||
1619 | S: Maintained | ||
1620 | F: drivers/connector/ | ||
1621 | |||
1615 | CONTROL GROUPS (CGROUPS) | 1622 | CONTROL GROUPS (CGROUPS) |
1616 | P: Paul Menage | 1623 | P: Paul Menage |
1617 | M: menage@google.com | 1624 | M: menage@google.com |
@@ -5584,7 +5591,6 @@ S: Odd Fixes | |||
5584 | F: drivers/net/starfire* | 5591 | F: drivers/net/starfire* |
5585 | 5592 | ||
5586 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER | 5593 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER |
5587 | W: http://mosquitonet.Stanford.EDU/strip.html | ||
5588 | S: Orphan | 5594 | S: Orphan |
5589 | F: drivers/net/wireless/strip.c | 5595 | F: drivers/net/wireless/strip.c |
5590 | F: include/linux/if_strip.h | 5596 | F: include/linux/if_strip.h |
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index d478aefcd3be..4a1dfe1f4ba9 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cn_queue.c | 2 | * cn_queue.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 3f45669f5d76..74f52af79563 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * connector.c | 2 | * connector.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include <net/sock.h> | 33 | #include <net/sock.h> |
34 | 34 | ||
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 36 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
38 | 38 | ||
39 | static u32 cn_idx = CN_IDX_CONNECTOR; | 39 | static u32 cn_idx = CN_IDX_CONNECTOR; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c155bd3ec9f1..5f6509a5f640 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1729,6 +1729,13 @@ config KS8842 | |||
1729 | help | 1729 | help |
1730 | This platform driver is for Micrel KSZ8842 chip. | 1730 | This platform driver is for Micrel KSZ8842 chip. |
1731 | 1731 | ||
1732 | config KS8851 | ||
1733 | tristate "Micrel KS8851 SPI" | ||
1734 | depends on SPI | ||
1735 | select MII | ||
1736 | help | ||
1737 | SPI driver for Micrel KS8851 SPI attached network chip. | ||
1738 | |||
1732 | config VIA_RHINE | 1739 | config VIA_RHINE |
1733 | tristate "VIA Rhine support" | 1740 | tristate "VIA Rhine support" |
1734 | depends on NET_PCI && PCI | 1741 | depends on NET_PCI && PCI |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 4b58a59f211b..ead8cab3cfe1 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -88,6 +88,7 @@ obj-$(CONFIG_SKGE) += skge.o | |||
88 | obj-$(CONFIG_SKY2) += sky2.o | 88 | obj-$(CONFIG_SKY2) += sky2.o |
89 | obj-$(CONFIG_SKFP) += skfp/ | 89 | obj-$(CONFIG_SKFP) += skfp/ |
90 | obj-$(CONFIG_KS8842) += ks8842.o | 90 | obj-$(CONFIG_KS8842) += ks8842.o |
91 | obj-$(CONFIG_KS8851) += ks8851.o | ||
91 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o | 92 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o |
92 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o | 93 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o |
93 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | 94 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o |
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 2895db13bfa4..c37ee9e6b67b 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig | |||
@@ -63,3 +63,11 @@ config IXP4XX_ETH | |||
63 | help | 63 | help |
64 | Say Y here if you want to use built-in Ethernet ports | 64 | Say Y here if you want to use built-in Ethernet ports |
65 | on IXP4xx processor. | 65 | on IXP4xx processor. |
66 | |||
67 | config W90P910_ETH | ||
68 | tristate "Nuvoton w90p910 Ethernet support" | ||
69 | depends on ARM && ARCH_W90X900 | ||
70 | select PHYLIB | ||
71 | help | ||
72 | Say Y here if you want to use built-in Ethernet ports | ||
73 | on w90p910 processor. | ||
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index 811a3ccd14c1..303171f589e6 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile | |||
@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o | |||
11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o | 11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o |
12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o | 12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o |
13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o | 13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o |
14 | obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o | ||
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index d46a06e20db0..c8bc60a7040c 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c | |||
@@ -1228,7 +1228,6 @@ static int at91ether_resume(struct platform_device *pdev) | |||
1228 | #endif | 1228 | #endif |
1229 | 1229 | ||
1230 | static struct platform_driver at91ether_driver = { | 1230 | static struct platform_driver at91ether_driver = { |
1231 | .probe = at91ether_probe, | ||
1232 | .remove = __devexit_p(at91ether_remove), | 1231 | .remove = __devexit_p(at91ether_remove), |
1233 | .suspend = at91ether_suspend, | 1232 | .suspend = at91ether_suspend, |
1234 | .resume = at91ether_resume, | 1233 | .resume = at91ether_resume, |
@@ -1240,7 +1239,7 @@ static struct platform_driver at91ether_driver = { | |||
1240 | 1239 | ||
1241 | static int __init at91ether_init(void) | 1240 | static int __init at91ether_init(void) |
1242 | { | 1241 | { |
1243 | return platform_driver_register(&at91ether_driver); | 1242 | return platform_driver_probe(&at91ether_driver, at91ether_probe); |
1244 | } | 1243 | } |
1245 | 1244 | ||
1246 | static void __exit at91ether_exit(void) | 1245 | static void __exit at91ether_exit(void) |
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c new file mode 100644 index 000000000000..616fb7985a34 --- /dev/null +++ b/drivers/net/arm/w90p910_ether.c | |||
@@ -0,0 +1,1105 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Nuvoton technology corporation. | ||
3 | * | ||
4 | * Wan ZongShun <mcuos.com@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation;version 2 of the License. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/mii.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #define DRV_MODULE_NAME "w90p910-emc" | ||
23 | #define DRV_MODULE_VERSION "0.1" | ||
24 | |||
25 | /* Ethernet MAC Registers */ | ||
26 | #define REG_CAMCMR 0x00 | ||
27 | #define REG_CAMEN 0x04 | ||
28 | #define REG_CAMM_BASE 0x08 | ||
29 | #define REG_CAML_BASE 0x0c | ||
30 | #define REG_TXDLSA 0x88 | ||
31 | #define REG_RXDLSA 0x8C | ||
32 | #define REG_MCMDR 0x90 | ||
33 | #define REG_MIID 0x94 | ||
34 | #define REG_MIIDA 0x98 | ||
35 | #define REG_FFTCR 0x9C | ||
36 | #define REG_TSDR 0xa0 | ||
37 | #define REG_RSDR 0xa4 | ||
38 | #define REG_DMARFC 0xa8 | ||
39 | #define REG_MIEN 0xac | ||
40 | #define REG_MISTA 0xb0 | ||
41 | #define REG_CTXDSA 0xcc | ||
42 | #define REG_CTXBSA 0xd0 | ||
43 | #define REG_CRXDSA 0xd4 | ||
44 | #define REG_CRXBSA 0xd8 | ||
45 | |||
46 | /* mac controller bit */ | ||
47 | #define MCMDR_RXON 0x01 | ||
48 | #define MCMDR_ACP (0x01 << 3) | ||
49 | #define MCMDR_SPCRC (0x01 << 5) | ||
50 | #define MCMDR_TXON (0x01 << 8) | ||
51 | #define MCMDR_FDUP (0x01 << 18) | ||
52 | #define MCMDR_ENMDC (0x01 << 19) | ||
53 | #define MCMDR_OPMOD (0x01 << 20) | ||
54 | #define SWR (0x01 << 24) | ||
55 | |||
56 | /* cam command regiser */ | ||
57 | #define CAMCMR_AUP 0x01 | ||
58 | #define CAMCMR_AMP (0x01 << 1) | ||
59 | #define CAMCMR_ABP (0x01 << 2) | ||
60 | #define CAMCMR_CCAM (0x01 << 3) | ||
61 | #define CAMCMR_ECMP (0x01 << 4) | ||
62 | #define CAM0EN 0x01 | ||
63 | |||
64 | /* mac mii controller bit */ | ||
65 | #define MDCCR (0x0a << 20) | ||
66 | #define PHYAD (0x01 << 8) | ||
67 | #define PHYWR (0x01 << 16) | ||
68 | #define PHYBUSY (0x01 << 17) | ||
69 | #define PHYPRESP (0x01 << 18) | ||
70 | #define CAM_ENTRY_SIZE 0x08 | ||
71 | |||
72 | /* rx and tx status */ | ||
73 | #define TXDS_TXCP (0x01 << 19) | ||
74 | #define RXDS_CRCE (0x01 << 17) | ||
75 | #define RXDS_PTLE (0x01 << 19) | ||
76 | #define RXDS_RXGD (0x01 << 20) | ||
77 | #define RXDS_ALIE (0x01 << 21) | ||
78 | #define RXDS_RP (0x01 << 22) | ||
79 | |||
80 | /* mac interrupt status*/ | ||
81 | #define MISTA_EXDEF (0x01 << 19) | ||
82 | #define MISTA_TXBERR (0x01 << 24) | ||
83 | #define MISTA_TDU (0x01 << 23) | ||
84 | #define MISTA_RDU (0x01 << 10) | ||
85 | #define MISTA_RXBERR (0x01 << 11) | ||
86 | |||
87 | #define ENSTART 0x01 | ||
88 | #define ENRXINTR 0x01 | ||
89 | #define ENRXGD (0x01 << 4) | ||
90 | #define ENRXBERR (0x01 << 11) | ||
91 | #define ENTXINTR (0x01 << 16) | ||
92 | #define ENTXCP (0x01 << 18) | ||
93 | #define ENTXABT (0x01 << 21) | ||
94 | #define ENTXBERR (0x01 << 24) | ||
95 | #define ENMDC (0x01 << 19) | ||
96 | #define PHYBUSY (0x01 << 17) | ||
97 | #define MDCCR_VAL 0xa00000 | ||
98 | |||
99 | /* rx and tx owner bit */ | ||
100 | #define RX_OWEN_DMA (0x01 << 31) | ||
101 | #define RX_OWEN_CPU (~(0x03 << 30)) | ||
102 | #define TX_OWEN_DMA (0x01 << 31) | ||
103 | #define TX_OWEN_CPU (~(0x01 << 31)) | ||
104 | |||
105 | /* tx frame desc controller bit */ | ||
106 | #define MACTXINTEN 0x04 | ||
107 | #define CRCMODE 0x02 | ||
108 | #define PADDINGMODE 0x01 | ||
109 | |||
110 | /* fftcr controller bit */ | ||
111 | #define TXTHD (0x03 << 8) | ||
112 | #define BLENGTH (0x01 << 20) | ||
113 | |||
114 | /* global setting for driver */ | ||
115 | #define RX_DESC_SIZE 50 | ||
116 | #define TX_DESC_SIZE 10 | ||
117 | #define MAX_RBUFF_SZ 0x600 | ||
118 | #define MAX_TBUFF_SZ 0x600 | ||
119 | #define TX_TIMEOUT 50 | ||
120 | #define DELAY 1000 | ||
121 | #define CAM0 0x0 | ||
122 | |||
123 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg); | ||
124 | |||
125 | struct w90p910_rxbd { | ||
126 | unsigned int sl; | ||
127 | unsigned int buffer; | ||
128 | unsigned int reserved; | ||
129 | unsigned int next; | ||
130 | }; | ||
131 | |||
132 | struct w90p910_txbd { | ||
133 | unsigned int mode; | ||
134 | unsigned int buffer; | ||
135 | unsigned int sl; | ||
136 | unsigned int next; | ||
137 | }; | ||
138 | |||
139 | struct recv_pdesc { | ||
140 | struct w90p910_rxbd desclist[RX_DESC_SIZE]; | ||
141 | char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ]; | ||
142 | }; | ||
143 | |||
144 | struct tran_pdesc { | ||
145 | struct w90p910_txbd desclist[TX_DESC_SIZE]; | ||
146 | char tran_buf[RX_DESC_SIZE][MAX_TBUFF_SZ]; | ||
147 | }; | ||
148 | |||
149 | struct w90p910_ether { | ||
150 | struct recv_pdesc *rdesc; | ||
151 | struct recv_pdesc *rdesc_phys; | ||
152 | struct tran_pdesc *tdesc; | ||
153 | struct tran_pdesc *tdesc_phys; | ||
154 | struct net_device_stats stats; | ||
155 | struct platform_device *pdev; | ||
156 | struct sk_buff *skb; | ||
157 | struct clk *clk; | ||
158 | struct clk *rmiiclk; | ||
159 | struct mii_if_info mii; | ||
160 | struct timer_list check_timer; | ||
161 | void __iomem *reg; | ||
162 | unsigned int rxirq; | ||
163 | unsigned int txirq; | ||
164 | unsigned int cur_tx; | ||
165 | unsigned int cur_rx; | ||
166 | unsigned int finish_tx; | ||
167 | unsigned int rx_packets; | ||
168 | unsigned int rx_bytes; | ||
169 | unsigned int start_tx_ptr; | ||
170 | unsigned int start_rx_ptr; | ||
171 | unsigned int linkflag; | ||
172 | spinlock_t lock; | ||
173 | }; | ||
174 | |||
175 | static void update_linkspeed_register(struct net_device *dev, | ||
176 | unsigned int speed, unsigned int duplex) | ||
177 | { | ||
178 | struct w90p910_ether *ether = netdev_priv(dev); | ||
179 | unsigned int val; | ||
180 | |||
181 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
182 | |||
183 | if (speed == SPEED_100) { | ||
184 | /* 100 full/half duplex */ | ||
185 | if (duplex == DUPLEX_FULL) { | ||
186 | val |= (MCMDR_OPMOD | MCMDR_FDUP); | ||
187 | } else { | ||
188 | val |= MCMDR_OPMOD; | ||
189 | val &= ~MCMDR_FDUP; | ||
190 | } | ||
191 | } else { | ||
192 | /* 10 full/half duplex */ | ||
193 | if (duplex == DUPLEX_FULL) { | ||
194 | val |= MCMDR_FDUP; | ||
195 | val &= ~MCMDR_OPMOD; | ||
196 | } else { | ||
197 | val &= ~(MCMDR_FDUP | MCMDR_OPMOD); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
202 | } | ||
203 | |||
204 | static void update_linkspeed(struct net_device *dev) | ||
205 | { | ||
206 | struct w90p910_ether *ether = netdev_priv(dev); | ||
207 | struct platform_device *pdev; | ||
208 | unsigned int bmsr, bmcr, lpa, speed, duplex; | ||
209 | |||
210 | pdev = ether->pdev; | ||
211 | |||
212 | if (!mii_link_ok(ðer->mii)) { | ||
213 | ether->linkflag = 0x0; | ||
214 | netif_carrier_off(dev); | ||
215 | dev_warn(&pdev->dev, "%s: Link down.\n", dev->name); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | if (ether->linkflag == 1) | ||
220 | return; | ||
221 | |||
222 | bmsr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMSR); | ||
223 | bmcr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMCR); | ||
224 | |||
225 | if (bmcr & BMCR_ANENABLE) { | ||
226 | if (!(bmsr & BMSR_ANEGCOMPLETE)) | ||
227 | return; | ||
228 | |||
229 | lpa = w90p910_mdio_read(dev, ether->mii.phy_id, MII_LPA); | ||
230 | |||
231 | if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) | ||
232 | speed = SPEED_100; | ||
233 | else | ||
234 | speed = SPEED_10; | ||
235 | |||
236 | if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) | ||
237 | duplex = DUPLEX_FULL; | ||
238 | else | ||
239 | duplex = DUPLEX_HALF; | ||
240 | |||
241 | } else { | ||
242 | speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; | ||
243 | duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; | ||
244 | } | ||
245 | |||
246 | update_linkspeed_register(dev, speed, duplex); | ||
247 | |||
248 | dev_info(&pdev->dev, "%s: Link now %i-%s\n", dev->name, speed, | ||
249 | (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | ||
250 | ether->linkflag = 0x01; | ||
251 | |||
252 | netif_carrier_on(dev); | ||
253 | } | ||
254 | |||
255 | static void w90p910_check_link(unsigned long dev_id) | ||
256 | { | ||
257 | struct net_device *dev = (struct net_device *) dev_id; | ||
258 | struct w90p910_ether *ether = netdev_priv(dev); | ||
259 | |||
260 | update_linkspeed(dev); | ||
261 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
262 | } | ||
263 | |||
264 | static void w90p910_write_cam(struct net_device *dev, | ||
265 | unsigned int x, unsigned char *pval) | ||
266 | { | ||
267 | struct w90p910_ether *ether = netdev_priv(dev); | ||
268 | unsigned int msw, lsw; | ||
269 | |||
270 | msw = (pval[0] << 24) | (pval[1] << 16) | (pval[2] << 8) | pval[3]; | ||
271 | |||
272 | lsw = (pval[4] << 24) | (pval[5] << 16); | ||
273 | |||
274 | __raw_writel(lsw, ether->reg + REG_CAML_BASE + x * CAM_ENTRY_SIZE); | ||
275 | __raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE); | ||
276 | } | ||
277 | |||
278 | static void w90p910_init_desc(struct net_device *dev) | ||
279 | { | ||
280 | struct w90p910_ether *ether; | ||
281 | struct w90p910_txbd *tdesc, *tdesc_phys; | ||
282 | struct w90p910_rxbd *rdesc, *rdesc_phys; | ||
283 | unsigned int i, j; | ||
284 | |||
285 | ether = netdev_priv(dev); | ||
286 | |||
287 | ether->tdesc = (struct tran_pdesc *) | ||
288 | dma_alloc_coherent(NULL, sizeof(struct tran_pdesc), | ||
289 | (dma_addr_t *) ðer->tdesc_phys, GFP_KERNEL); | ||
290 | |||
291 | ether->rdesc = (struct recv_pdesc *) | ||
292 | dma_alloc_coherent(NULL, sizeof(struct recv_pdesc), | ||
293 | (dma_addr_t *) ðer->rdesc_phys, GFP_KERNEL); | ||
294 | |||
295 | for (i = 0; i < TX_DESC_SIZE; i++) { | ||
296 | tdesc = &(ether->tdesc->desclist[i]); | ||
297 | |||
298 | j = ((i + 1) / TX_DESC_SIZE); | ||
299 | |||
300 | if (j != 0) { | ||
301 | tdesc_phys = &(ether->tdesc_phys->desclist[0]); | ||
302 | ether->start_tx_ptr = (unsigned int)tdesc_phys; | ||
303 | tdesc->next = (unsigned int)ether->start_tx_ptr; | ||
304 | } else { | ||
305 | tdesc_phys = &(ether->tdesc_phys->desclist[i+1]); | ||
306 | tdesc->next = (unsigned int)tdesc_phys; | ||
307 | } | ||
308 | |||
309 | tdesc->buffer = (unsigned int)ether->tdesc_phys->tran_buf[i]; | ||
310 | tdesc->sl = 0; | ||
311 | tdesc->mode = 0; | ||
312 | } | ||
313 | |||
314 | for (i = 0; i < RX_DESC_SIZE; i++) { | ||
315 | rdesc = &(ether->rdesc->desclist[i]); | ||
316 | |||
317 | j = ((i + 1) / RX_DESC_SIZE); | ||
318 | |||
319 | if (j != 0) { | ||
320 | rdesc_phys = &(ether->rdesc_phys->desclist[0]); | ||
321 | ether->start_rx_ptr = (unsigned int)rdesc_phys; | ||
322 | rdesc->next = (unsigned int)ether->start_rx_ptr; | ||
323 | } else { | ||
324 | rdesc_phys = &(ether->rdesc_phys->desclist[i+1]); | ||
325 | rdesc->next = (unsigned int)rdesc_phys; | ||
326 | } | ||
327 | |||
328 | rdesc->sl = RX_OWEN_DMA; | ||
329 | rdesc->buffer = (unsigned int)ether->rdesc_phys->recv_buf[i]; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | static void w90p910_set_fifo_threshold(struct net_device *dev) | ||
334 | { | ||
335 | struct w90p910_ether *ether = netdev_priv(dev); | ||
336 | unsigned int val; | ||
337 | |||
338 | val = TXTHD | BLENGTH; | ||
339 | __raw_writel(val, ether->reg + REG_FFTCR); | ||
340 | } | ||
341 | |||
342 | static void w90p910_return_default_idle(struct net_device *dev) | ||
343 | { | ||
344 | struct w90p910_ether *ether = netdev_priv(dev); | ||
345 | unsigned int val; | ||
346 | |||
347 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
348 | val |= SWR; | ||
349 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
350 | } | ||
351 | |||
352 | static void w90p910_trigger_rx(struct net_device *dev) | ||
353 | { | ||
354 | struct w90p910_ether *ether = netdev_priv(dev); | ||
355 | |||
356 | __raw_writel(ENSTART, ether->reg + REG_RSDR); | ||
357 | } | ||
358 | |||
359 | static void w90p910_trigger_tx(struct net_device *dev) | ||
360 | { | ||
361 | struct w90p910_ether *ether = netdev_priv(dev); | ||
362 | |||
363 | __raw_writel(ENSTART, ether->reg + REG_TSDR); | ||
364 | } | ||
365 | |||
366 | static void w90p910_enable_mac_interrupt(struct net_device *dev) | ||
367 | { | ||
368 | struct w90p910_ether *ether = netdev_priv(dev); | ||
369 | unsigned int val; | ||
370 | |||
371 | val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP; | ||
372 | val |= ENTXBERR | ENRXBERR | ENTXABT; | ||
373 | |||
374 | __raw_writel(val, ether->reg + REG_MIEN); | ||
375 | } | ||
376 | |||
377 | static void w90p910_get_and_clear_int(struct net_device *dev, | ||
378 | unsigned int *val) | ||
379 | { | ||
380 | struct w90p910_ether *ether = netdev_priv(dev); | ||
381 | |||
382 | *val = __raw_readl(ether->reg + REG_MISTA); | ||
383 | __raw_writel(*val, ether->reg + REG_MISTA); | ||
384 | } | ||
385 | |||
386 | static void w90p910_set_global_maccmd(struct net_device *dev) | ||
387 | { | ||
388 | struct w90p910_ether *ether = netdev_priv(dev); | ||
389 | unsigned int val; | ||
390 | |||
391 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
392 | val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | ENMDC; | ||
393 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
394 | } | ||
395 | |||
396 | static void w90p910_enable_cam(struct net_device *dev) | ||
397 | { | ||
398 | struct w90p910_ether *ether = netdev_priv(dev); | ||
399 | unsigned int val; | ||
400 | |||
401 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
402 | |||
403 | val = __raw_readl(ether->reg + REG_CAMEN); | ||
404 | val |= CAM0EN; | ||
405 | __raw_writel(val, ether->reg + REG_CAMEN); | ||
406 | } | ||
407 | |||
408 | static void w90p910_enable_cam_command(struct net_device *dev) | ||
409 | { | ||
410 | struct w90p910_ether *ether = netdev_priv(dev); | ||
411 | unsigned int val; | ||
412 | |||
413 | val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP; | ||
414 | __raw_writel(val, ether->reg + REG_CAMCMR); | ||
415 | } | ||
416 | |||
417 | static void w90p910_enable_tx(struct net_device *dev, unsigned int enable) | ||
418 | { | ||
419 | struct w90p910_ether *ether = netdev_priv(dev); | ||
420 | unsigned int val; | ||
421 | |||
422 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
423 | |||
424 | if (enable) | ||
425 | val |= MCMDR_TXON; | ||
426 | else | ||
427 | val &= ~MCMDR_TXON; | ||
428 | |||
429 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
430 | } | ||
431 | |||
432 | static void w90p910_enable_rx(struct net_device *dev, unsigned int enable) | ||
433 | { | ||
434 | struct w90p910_ether *ether = netdev_priv(dev); | ||
435 | unsigned int val; | ||
436 | |||
437 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
438 | |||
439 | if (enable) | ||
440 | val |= MCMDR_RXON; | ||
441 | else | ||
442 | val &= ~MCMDR_RXON; | ||
443 | |||
444 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
445 | } | ||
446 | |||
447 | static void w90p910_set_curdest(struct net_device *dev) | ||
448 | { | ||
449 | struct w90p910_ether *ether = netdev_priv(dev); | ||
450 | |||
451 | __raw_writel(ether->start_rx_ptr, ether->reg + REG_RXDLSA); | ||
452 | __raw_writel(ether->start_tx_ptr, ether->reg + REG_TXDLSA); | ||
453 | } | ||
454 | |||
455 | static void w90p910_reset_mac(struct net_device *dev) | ||
456 | { | ||
457 | struct w90p910_ether *ether = netdev_priv(dev); | ||
458 | |||
459 | spin_lock(ðer->lock); | ||
460 | |||
461 | w90p910_enable_tx(dev, 0); | ||
462 | w90p910_enable_rx(dev, 0); | ||
463 | w90p910_set_fifo_threshold(dev); | ||
464 | w90p910_return_default_idle(dev); | ||
465 | |||
466 | if (!netif_queue_stopped(dev)) | ||
467 | netif_stop_queue(dev); | ||
468 | |||
469 | w90p910_init_desc(dev); | ||
470 | |||
471 | dev->trans_start = jiffies; | ||
472 | ether->cur_tx = 0x0; | ||
473 | ether->finish_tx = 0x0; | ||
474 | ether->cur_rx = 0x0; | ||
475 | |||
476 | w90p910_set_curdest(dev); | ||
477 | w90p910_enable_cam(dev); | ||
478 | w90p910_enable_cam_command(dev); | ||
479 | w90p910_enable_mac_interrupt(dev); | ||
480 | w90p910_enable_tx(dev, 1); | ||
481 | w90p910_enable_rx(dev, 1); | ||
482 | w90p910_trigger_tx(dev); | ||
483 | w90p910_trigger_rx(dev); | ||
484 | |||
485 | dev->trans_start = jiffies; | ||
486 | |||
487 | if (netif_queue_stopped(dev)) | ||
488 | netif_wake_queue(dev); | ||
489 | |||
490 | spin_unlock(ðer->lock); | ||
491 | } | ||
492 | |||
493 | static void w90p910_mdio_write(struct net_device *dev, | ||
494 | int phy_id, int reg, int data) | ||
495 | { | ||
496 | struct w90p910_ether *ether = netdev_priv(dev); | ||
497 | struct platform_device *pdev; | ||
498 | unsigned int val, i; | ||
499 | |||
500 | pdev = ether->pdev; | ||
501 | |||
502 | __raw_writel(data, ether->reg + REG_MIID); | ||
503 | |||
504 | val = (phy_id << 0x08) | reg; | ||
505 | val |= PHYBUSY | PHYWR | MDCCR_VAL; | ||
506 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
507 | |||
508 | for (i = 0; i < DELAY; i++) { | ||
509 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
510 | break; | ||
511 | } | ||
512 | |||
513 | if (i == DELAY) | ||
514 | dev_warn(&pdev->dev, "mdio write timed out\n"); | ||
515 | } | ||
516 | |||
517 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg) | ||
518 | { | ||
519 | struct w90p910_ether *ether = netdev_priv(dev); | ||
520 | struct platform_device *pdev; | ||
521 | unsigned int val, i, data; | ||
522 | |||
523 | pdev = ether->pdev; | ||
524 | |||
525 | val = (phy_id << 0x08) | reg; | ||
526 | val |= PHYBUSY | MDCCR_VAL; | ||
527 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
528 | |||
529 | for (i = 0; i < DELAY; i++) { | ||
530 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | if (i == DELAY) { | ||
535 | dev_warn(&pdev->dev, "mdio read timed out\n"); | ||
536 | data = 0xffff; | ||
537 | } else { | ||
538 | data = __raw_readl(ether->reg + REG_MIID); | ||
539 | } | ||
540 | |||
541 | return data; | ||
542 | } | ||
543 | |||
544 | static int set_mac_address(struct net_device *dev, void *addr) | ||
545 | { | ||
546 | struct sockaddr *address = addr; | ||
547 | |||
548 | if (!is_valid_ether_addr(address->sa_data)) | ||
549 | return -EADDRNOTAVAIL; | ||
550 | |||
551 | memcpy(dev->dev_addr, address->sa_data, dev->addr_len); | ||
552 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static int w90p910_ether_close(struct net_device *dev) | ||
558 | { | ||
559 | struct w90p910_ether *ether = netdev_priv(dev); | ||
560 | |||
561 | dma_free_writecombine(NULL, sizeof(struct w90p910_rxbd), | ||
562 | ether->rdesc, (dma_addr_t)ether->rdesc_phys); | ||
563 | dma_free_writecombine(NULL, sizeof(struct w90p910_txbd), | ||
564 | ether->tdesc, (dma_addr_t)ether->tdesc_phys); | ||
565 | |||
566 | netif_stop_queue(dev); | ||
567 | |||
568 | del_timer_sync(ðer->check_timer); | ||
569 | clk_disable(ether->rmiiclk); | ||
570 | clk_disable(ether->clk); | ||
571 | |||
572 | free_irq(ether->txirq, dev); | ||
573 | free_irq(ether->rxirq, dev); | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static struct net_device_stats *w90p910_ether_stats(struct net_device *dev) | ||
579 | { | ||
580 | struct w90p910_ether *ether; | ||
581 | |||
582 | ether = netdev_priv(dev); | ||
583 | |||
584 | return ðer->stats; | ||
585 | } | ||
586 | |||
587 | static int w90p910_send_frame(struct net_device *dev, | ||
588 | unsigned char *data, int length) | ||
589 | { | ||
590 | struct w90p910_ether *ether; | ||
591 | struct w90p910_txbd *txbd; | ||
592 | struct platform_device *pdev; | ||
593 | unsigned char *buffer; | ||
594 | |||
595 | ether = netdev_priv(dev); | ||
596 | pdev = ether->pdev; | ||
597 | |||
598 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
599 | buffer = ether->tdesc->tran_buf[ether->cur_tx]; | ||
600 | if (length > 1514) { | ||
601 | dev_err(&pdev->dev, "send data %d bytes, check it\n", length); | ||
602 | length = 1514; | ||
603 | } | ||
604 | |||
605 | txbd->sl = length & 0xFFFF; | ||
606 | |||
607 | memcpy(buffer, data, length); | ||
608 | |||
609 | txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE | MACTXINTEN; | ||
610 | |||
611 | w90p910_enable_tx(dev, 1); | ||
612 | |||
613 | w90p910_trigger_tx(dev); | ||
614 | |||
615 | ether->cur_tx = (ether->cur_tx+1) % TX_DESC_SIZE; | ||
616 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
617 | |||
618 | dev->trans_start = jiffies; | ||
619 | |||
620 | if (txbd->mode & TX_OWEN_DMA) | ||
621 | netif_stop_queue(dev); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
627 | { | ||
628 | struct w90p910_ether *ether = netdev_priv(dev); | ||
629 | |||
630 | if (!(w90p910_send_frame(dev, skb->data, skb->len))) { | ||
631 | ether->skb = skb; | ||
632 | dev_kfree_skb_irq(skb); | ||
633 | return 0; | ||
634 | } | ||
635 | return -1; | ||
636 | } | ||
637 | |||
638 | static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) | ||
639 | { | ||
640 | struct w90p910_ether *ether; | ||
641 | struct w90p910_txbd *txbd; | ||
642 | struct platform_device *pdev; | ||
643 | struct tran_pdesc *tran_pdesc; | ||
644 | struct net_device *dev; | ||
645 | unsigned int cur_entry, entry, status; | ||
646 | |||
647 | dev = (struct net_device *)dev_id; | ||
648 | ether = netdev_priv(dev); | ||
649 | pdev = ether->pdev; | ||
650 | |||
651 | spin_lock(ðer->lock); | ||
652 | |||
653 | w90p910_get_and_clear_int(dev, &status); | ||
654 | |||
655 | cur_entry = __raw_readl(ether->reg + REG_CTXDSA); | ||
656 | |||
657 | tran_pdesc = ether->tdesc_phys; | ||
658 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
659 | |||
660 | while (entry != cur_entry) { | ||
661 | txbd = ðer->tdesc->desclist[ether->finish_tx]; | ||
662 | |||
663 | ether->finish_tx = (ether->finish_tx + 1) % TX_DESC_SIZE; | ||
664 | |||
665 | if (txbd->sl & TXDS_TXCP) { | ||
666 | ether->stats.tx_packets++; | ||
667 | ether->stats.tx_bytes += txbd->sl & 0xFFFF; | ||
668 | } else { | ||
669 | ether->stats.tx_errors++; | ||
670 | } | ||
671 | |||
672 | txbd->sl = 0x0; | ||
673 | txbd->mode = 0x0; | ||
674 | |||
675 | if (netif_queue_stopped(dev)) | ||
676 | netif_wake_queue(dev); | ||
677 | |||
678 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
679 | } | ||
680 | |||
681 | if (status & MISTA_EXDEF) { | ||
682 | dev_err(&pdev->dev, "emc defer exceed interrupt\n"); | ||
683 | } else if (status & MISTA_TXBERR) { | ||
684 | dev_err(&pdev->dev, "emc bus error interrupt\n"); | ||
685 | w90p910_reset_mac(dev); | ||
686 | } else if (status & MISTA_TDU) { | ||
687 | if (netif_queue_stopped(dev)) | ||
688 | netif_wake_queue(dev); | ||
689 | } | ||
690 | |||
691 | spin_unlock(ðer->lock); | ||
692 | |||
693 | return IRQ_HANDLED; | ||
694 | } | ||
695 | |||
696 | static void netdev_rx(struct net_device *dev) | ||
697 | { | ||
698 | struct w90p910_ether *ether; | ||
699 | struct w90p910_rxbd *rxbd; | ||
700 | struct platform_device *pdev; | ||
701 | struct recv_pdesc *rdesc_phys; | ||
702 | struct sk_buff *skb; | ||
703 | unsigned char *data; | ||
704 | unsigned int length, status, val, entry; | ||
705 | |||
706 | ether = netdev_priv(dev); | ||
707 | pdev = ether->pdev; | ||
708 | rdesc_phys = ether->rdesc_phys; | ||
709 | |||
710 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
711 | |||
712 | do { | ||
713 | val = __raw_readl(ether->reg + REG_CRXDSA); | ||
714 | entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; | ||
715 | |||
716 | if (val == entry) | ||
717 | break; | ||
718 | |||
719 | status = rxbd->sl; | ||
720 | length = status & 0xFFFF; | ||
721 | |||
722 | if (status & RXDS_RXGD) { | ||
723 | data = ether->rdesc->recv_buf[ether->cur_rx]; | ||
724 | skb = dev_alloc_skb(length+2); | ||
725 | if (!skb) { | ||
726 | dev_err(&pdev->dev, "get skb buffer error\n"); | ||
727 | ether->stats.rx_dropped++; | ||
728 | return; | ||
729 | } | ||
730 | |||
731 | skb->dev = dev; | ||
732 | skb_reserve(skb, 2); | ||
733 | skb_put(skb, length); | ||
734 | skb_copy_to_linear_data(skb, data, length); | ||
735 | skb->protocol = eth_type_trans(skb, dev); | ||
736 | ether->stats.rx_packets++; | ||
737 | ether->stats.rx_bytes += length; | ||
738 | netif_rx(skb); | ||
739 | } else { | ||
740 | ether->stats.rx_errors++; | ||
741 | |||
742 | if (status & RXDS_RP) { | ||
743 | dev_err(&pdev->dev, "rx runt err\n"); | ||
744 | ether->stats.rx_length_errors++; | ||
745 | } else if (status & RXDS_CRCE) { | ||
746 | dev_err(&pdev->dev, "rx crc err\n"); | ||
747 | ether->stats.rx_crc_errors++; | ||
748 | } | ||
749 | |||
750 | if (status & RXDS_ALIE) { | ||
751 | dev_err(&pdev->dev, "rx aligment err\n"); | ||
752 | ether->stats.rx_frame_errors++; | ||
753 | } else if (status & RXDS_PTLE) { | ||
754 | dev_err(&pdev->dev, "rx longer err\n"); | ||
755 | ether->stats.rx_over_errors++; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | rxbd->sl = RX_OWEN_DMA; | ||
760 | rxbd->reserved = 0x0; | ||
761 | ether->cur_rx = (ether->cur_rx+1) % RX_DESC_SIZE; | ||
762 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
763 | |||
764 | dev->last_rx = jiffies; | ||
765 | } while (1); | ||
766 | } | ||
767 | |||
768 | static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id) | ||
769 | { | ||
770 | struct net_device *dev; | ||
771 | struct w90p910_ether *ether; | ||
772 | struct platform_device *pdev; | ||
773 | unsigned int status; | ||
774 | |||
775 | dev = (struct net_device *)dev_id; | ||
776 | ether = netdev_priv(dev); | ||
777 | pdev = ether->pdev; | ||
778 | |||
779 | spin_lock(ðer->lock); | ||
780 | |||
781 | w90p910_get_and_clear_int(dev, &status); | ||
782 | |||
783 | if (status & MISTA_RDU) { | ||
784 | netdev_rx(dev); | ||
785 | |||
786 | w90p910_trigger_rx(dev); | ||
787 | |||
788 | spin_unlock(ðer->lock); | ||
789 | return IRQ_HANDLED; | ||
790 | } else if (status & MISTA_RXBERR) { | ||
791 | dev_err(&pdev->dev, "emc rx bus error\n"); | ||
792 | w90p910_reset_mac(dev); | ||
793 | } | ||
794 | |||
795 | netdev_rx(dev); | ||
796 | spin_unlock(ðer->lock); | ||
797 | return IRQ_HANDLED; | ||
798 | } | ||
799 | |||
800 | static int w90p910_ether_open(struct net_device *dev) | ||
801 | { | ||
802 | struct w90p910_ether *ether; | ||
803 | struct platform_device *pdev; | ||
804 | |||
805 | ether = netdev_priv(dev); | ||
806 | pdev = ether->pdev; | ||
807 | |||
808 | w90p910_reset_mac(dev); | ||
809 | w90p910_set_fifo_threshold(dev); | ||
810 | w90p910_set_curdest(dev); | ||
811 | w90p910_enable_cam(dev); | ||
812 | w90p910_enable_cam_command(dev); | ||
813 | w90p910_enable_mac_interrupt(dev); | ||
814 | w90p910_set_global_maccmd(dev); | ||
815 | w90p910_enable_rx(dev, 1); | ||
816 | |||
817 | ether->rx_packets = 0x0; | ||
818 | ether->rx_bytes = 0x0; | ||
819 | |||
820 | if (request_irq(ether->txirq, w90p910_tx_interrupt, | ||
821 | 0x0, pdev->name, dev)) { | ||
822 | dev_err(&pdev->dev, "register irq tx failed\n"); | ||
823 | return -EAGAIN; | ||
824 | } | ||
825 | |||
826 | if (request_irq(ether->rxirq, w90p910_rx_interrupt, | ||
827 | 0x0, pdev->name, dev)) { | ||
828 | dev_err(&pdev->dev, "register irq rx failed\n"); | ||
829 | return -EAGAIN; | ||
830 | } | ||
831 | |||
832 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
833 | netif_start_queue(dev); | ||
834 | w90p910_trigger_rx(dev); | ||
835 | |||
836 | dev_info(&pdev->dev, "%s is OPENED\n", dev->name); | ||
837 | |||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static void w90p910_ether_set_multicast_list(struct net_device *dev) | ||
842 | { | ||
843 | struct w90p910_ether *ether; | ||
844 | unsigned int rx_mode; | ||
845 | |||
846 | ether = netdev_priv(dev); | ||
847 | |||
848 | if (dev->flags & IFF_PROMISC) | ||
849 | rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
850 | else if ((dev->flags & IFF_ALLMULTI) || dev->mc_list) | ||
851 | rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
852 | else | ||
853 | rx_mode = CAMCMR_ECMP | CAMCMR_ABP; | ||
854 | __raw_writel(rx_mode, ether->reg + REG_CAMCMR); | ||
855 | } | ||
856 | |||
857 | static int w90p910_ether_ioctl(struct net_device *dev, | ||
858 | struct ifreq *ifr, int cmd) | ||
859 | { | ||
860 | struct w90p910_ether *ether = netdev_priv(dev); | ||
861 | struct mii_ioctl_data *data = if_mii(ifr); | ||
862 | |||
863 | return generic_mii_ioctl(ðer->mii, data, cmd, NULL); | ||
864 | } | ||
865 | |||
866 | static void w90p910_get_drvinfo(struct net_device *dev, | ||
867 | struct ethtool_drvinfo *info) | ||
868 | { | ||
869 | strcpy(info->driver, DRV_MODULE_NAME); | ||
870 | strcpy(info->version, DRV_MODULE_VERSION); | ||
871 | } | ||
872 | |||
873 | static int w90p910_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
874 | { | ||
875 | struct w90p910_ether *ether = netdev_priv(dev); | ||
876 | return mii_ethtool_gset(ðer->mii, cmd); | ||
877 | } | ||
878 | |||
879 | static int w90p910_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
880 | { | ||
881 | struct w90p910_ether *ether = netdev_priv(dev); | ||
882 | return mii_ethtool_sset(ðer->mii, cmd); | ||
883 | } | ||
884 | |||
885 | static int w90p910_nway_reset(struct net_device *dev) | ||
886 | { | ||
887 | struct w90p910_ether *ether = netdev_priv(dev); | ||
888 | return mii_nway_restart(ðer->mii); | ||
889 | } | ||
890 | |||
891 | static u32 w90p910_get_link(struct net_device *dev) | ||
892 | { | ||
893 | struct w90p910_ether *ether = netdev_priv(dev); | ||
894 | return mii_link_ok(ðer->mii); | ||
895 | } | ||
896 | |||
897 | static const struct ethtool_ops w90p910_ether_ethtool_ops = { | ||
898 | .get_settings = w90p910_get_settings, | ||
899 | .set_settings = w90p910_set_settings, | ||
900 | .get_drvinfo = w90p910_get_drvinfo, | ||
901 | .nway_reset = w90p910_nway_reset, | ||
902 | .get_link = w90p910_get_link, | ||
903 | }; | ||
904 | |||
905 | static const struct net_device_ops w90p910_ether_netdev_ops = { | ||
906 | .ndo_open = w90p910_ether_open, | ||
907 | .ndo_stop = w90p910_ether_close, | ||
908 | .ndo_start_xmit = w90p910_ether_start_xmit, | ||
909 | .ndo_get_stats = w90p910_ether_stats, | ||
910 | .ndo_set_multicast_list = w90p910_ether_set_multicast_list, | ||
911 | .ndo_set_mac_address = set_mac_address, | ||
912 | .ndo_do_ioctl = w90p910_ether_ioctl, | ||
913 | .ndo_validate_addr = eth_validate_addr, | ||
914 | .ndo_change_mtu = eth_change_mtu, | ||
915 | }; | ||
916 | |||
917 | static void __init get_mac_address(struct net_device *dev) | ||
918 | { | ||
919 | struct w90p910_ether *ether = netdev_priv(dev); | ||
920 | struct platform_device *pdev; | ||
921 | char addr[6]; | ||
922 | |||
923 | pdev = ether->pdev; | ||
924 | |||
925 | addr[0] = 0x00; | ||
926 | addr[1] = 0x02; | ||
927 | addr[2] = 0xac; | ||
928 | addr[3] = 0x55; | ||
929 | addr[4] = 0x88; | ||
930 | addr[5] = 0xa8; | ||
931 | |||
932 | if (is_valid_ether_addr(addr)) | ||
933 | memcpy(dev->dev_addr, &addr, 0x06); | ||
934 | else | ||
935 | dev_err(&pdev->dev, "invalid mac address\n"); | ||
936 | } | ||
937 | |||
938 | static int w90p910_ether_setup(struct net_device *dev) | ||
939 | { | ||
940 | struct w90p910_ether *ether = netdev_priv(dev); | ||
941 | |||
942 | ether_setup(dev); | ||
943 | dev->netdev_ops = &w90p910_ether_netdev_ops; | ||
944 | dev->ethtool_ops = &w90p910_ether_ethtool_ops; | ||
945 | |||
946 | dev->tx_queue_len = 16; | ||
947 | dev->dma = 0x0; | ||
948 | dev->watchdog_timeo = TX_TIMEOUT; | ||
949 | |||
950 | get_mac_address(dev); | ||
951 | |||
952 | spin_lock_init(ðer->lock); | ||
953 | |||
954 | ether->cur_tx = 0x0; | ||
955 | ether->cur_rx = 0x0; | ||
956 | ether->finish_tx = 0x0; | ||
957 | ether->linkflag = 0x0; | ||
958 | ether->mii.phy_id = 0x01; | ||
959 | ether->mii.phy_id_mask = 0x1f; | ||
960 | ether->mii.reg_num_mask = 0x1f; | ||
961 | ether->mii.dev = dev; | ||
962 | ether->mii.mdio_read = w90p910_mdio_read; | ||
963 | ether->mii.mdio_write = w90p910_mdio_write; | ||
964 | |||
965 | setup_timer(ðer->check_timer, w90p910_check_link, | ||
966 | (unsigned long)dev); | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int __devinit w90p910_ether_probe(struct platform_device *pdev) | ||
972 | { | ||
973 | struct w90p910_ether *ether; | ||
974 | struct net_device *dev; | ||
975 | struct resource *res; | ||
976 | int error; | ||
977 | |||
978 | dev = alloc_etherdev(sizeof(struct w90p910_ether)); | ||
979 | if (!dev) | ||
980 | return -ENOMEM; | ||
981 | |||
982 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
983 | if (res == NULL) { | ||
984 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
985 | error = -ENXIO; | ||
986 | goto failed_free; | ||
987 | } | ||
988 | |||
989 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
990 | if (res == NULL) { | ||
991 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
992 | error = -EBUSY; | ||
993 | goto failed_free; | ||
994 | } | ||
995 | |||
996 | ether = netdev_priv(dev); | ||
997 | |||
998 | ether->reg = ioremap(res->start, resource_size(res)); | ||
999 | if (ether->reg == NULL) { | ||
1000 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
1001 | error = -ENXIO; | ||
1002 | goto failed_free_mem; | ||
1003 | } | ||
1004 | |||
1005 | ether->txirq = platform_get_irq(pdev, 0); | ||
1006 | if (ether->txirq < 0) { | ||
1007 | dev_err(&pdev->dev, "failed to get ether tx irq\n"); | ||
1008 | error = -ENXIO; | ||
1009 | goto failed_free_io; | ||
1010 | } | ||
1011 | |||
1012 | ether->rxirq = platform_get_irq(pdev, 1); | ||
1013 | if (ether->rxirq < 0) { | ||
1014 | dev_err(&pdev->dev, "failed to get ether rx irq\n"); | ||
1015 | error = -ENXIO; | ||
1016 | goto failed_free_txirq; | ||
1017 | } | ||
1018 | |||
1019 | platform_set_drvdata(pdev, dev); | ||
1020 | |||
1021 | ether->clk = clk_get(&pdev->dev, NULL); | ||
1022 | if (IS_ERR(ether->clk)) { | ||
1023 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1024 | error = PTR_ERR(ether->clk); | ||
1025 | goto failed_free_rxirq; | ||
1026 | } | ||
1027 | |||
1028 | ether->rmiiclk = clk_get(&pdev->dev, "RMII"); | ||
1029 | if (IS_ERR(ether->rmiiclk)) { | ||
1030 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1031 | error = PTR_ERR(ether->rmiiclk); | ||
1032 | goto failed_put_clk; | ||
1033 | } | ||
1034 | |||
1035 | ether->pdev = pdev; | ||
1036 | |||
1037 | w90p910_ether_setup(dev); | ||
1038 | |||
1039 | error = register_netdev(dev); | ||
1040 | if (error != 0) { | ||
1041 | dev_err(&pdev->dev, "Regiter EMC w90p910 FAILED\n"); | ||
1042 | error = -ENODEV; | ||
1043 | goto failed_put_rmiiclk; | ||
1044 | } | ||
1045 | |||
1046 | return 0; | ||
1047 | failed_put_rmiiclk: | ||
1048 | clk_put(ether->rmiiclk); | ||
1049 | failed_put_clk: | ||
1050 | clk_put(ether->clk); | ||
1051 | failed_free_rxirq: | ||
1052 | free_irq(ether->rxirq, pdev); | ||
1053 | platform_set_drvdata(pdev, NULL); | ||
1054 | failed_free_txirq: | ||
1055 | free_irq(ether->txirq, pdev); | ||
1056 | failed_free_io: | ||
1057 | iounmap(ether->reg); | ||
1058 | failed_free_mem: | ||
1059 | release_mem_region(res->start, resource_size(res)); | ||
1060 | failed_free: | ||
1061 | free_netdev(dev); | ||
1062 | return error; | ||
1063 | } | ||
1064 | |||
1065 | static int __devexit w90p910_ether_remove(struct platform_device *pdev) | ||
1066 | { | ||
1067 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1068 | struct w90p910_ether *ether = netdev_priv(dev); | ||
1069 | |||
1070 | unregister_netdev(dev); | ||
1071 | clk_put(ether->rmiiclk); | ||
1072 | clk_put(ether->clk); | ||
1073 | del_timer_sync(ðer->check_timer); | ||
1074 | platform_set_drvdata(pdev, NULL); | ||
1075 | free_netdev(dev); | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static struct platform_driver w90p910_ether_driver = { | ||
1080 | .probe = w90p910_ether_probe, | ||
1081 | .remove = __devexit_p(w90p910_ether_remove), | ||
1082 | .driver = { | ||
1083 | .name = "w90p910-emc", | ||
1084 | .owner = THIS_MODULE, | ||
1085 | }, | ||
1086 | }; | ||
1087 | |||
1088 | static int __init w90p910_ether_init(void) | ||
1089 | { | ||
1090 | return platform_driver_register(&w90p910_ether_driver); | ||
1091 | } | ||
1092 | |||
1093 | static void __exit w90p910_ether_exit(void) | ||
1094 | { | ||
1095 | platform_driver_unregister(&w90p910_ether_driver); | ||
1096 | } | ||
1097 | |||
1098 | module_init(w90p910_ether_init); | ||
1099 | module_exit(w90p910_ether_exit); | ||
1100 | |||
1101 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
1102 | MODULE_DESCRIPTION("w90p910 MAC driver!"); | ||
1103 | MODULE_LICENSE("GPL"); | ||
1104 | MODULE_ALIAS("platform:w90p910-emc"); | ||
1105 | |||
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 45df8e2d0921..c56487e3700b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -667,7 +667,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
667 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 667 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
668 | struct be_rx_page_info *page_info; | 668 | struct be_rx_page_info *page_info; |
669 | u16 rxq_idx, i, num_rcvd, j; | 669 | u16 rxq_idx, i, num_rcvd, j; |
670 | u32 pktsize, hdr_len, curr_frag_len; | 670 | u32 pktsize, hdr_len, curr_frag_len, size; |
671 | u8 *start; | 671 | u8 *start; |
672 | 672 | ||
673 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 673 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
@@ -708,12 +708,13 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
708 | } | 708 | } |
709 | 709 | ||
710 | /* More frags present for this completion */ | 710 | /* More frags present for this completion */ |
711 | pktsize -= curr_frag_len; /* account for above copied frag */ | 711 | size = pktsize; |
712 | for (i = 1, j = 0; i < num_rcvd; i++) { | 712 | for (i = 1, j = 0; i < num_rcvd; i++) { |
713 | size -= curr_frag_len; | ||
713 | index_inc(&rxq_idx, rxq->len); | 714 | index_inc(&rxq_idx, rxq->len); |
714 | page_info = get_rx_page_info(adapter, rxq_idx); | 715 | page_info = get_rx_page_info(adapter, rxq_idx); |
715 | 716 | ||
716 | curr_frag_len = min(pktsize, rx_frag_size); | 717 | curr_frag_len = min(size, rx_frag_size); |
717 | 718 | ||
718 | /* Coalesce all frags from the same physical page in one slot */ | 719 | /* Coalesce all frags from the same physical page in one slot */ |
719 | if (page_info->page_offset == 0) { | 720 | if (page_info->page_offset == 0) { |
@@ -731,7 +732,6 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
731 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | 732 | skb_shinfo(skb)->frags[j].size += curr_frag_len; |
732 | skb->len += curr_frag_len; | 733 | skb->len += curr_frag_len; |
733 | skb->data_len += curr_frag_len; | 734 | skb->data_len += curr_frag_len; |
734 | pktsize -= curr_frag_len; | ||
735 | 735 | ||
736 | memset(page_info, 0, sizeof(*page_info)); | 736 | memset(page_info, 0, sizeof(*page_info)); |
737 | } | 737 | } |
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index a24bc51c9855..1f17334c8f02 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -4916,13 +4916,14 @@ static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port) | |||
4916 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | 4916 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, |
4917 | u8 *version, u16 len) | 4917 | u8 *version, u16 len) |
4918 | { | 4918 | { |
4919 | struct bnx2x *bp = params->bp; | 4919 | struct bnx2x *bp; |
4920 | u32 ext_phy_type = 0; | 4920 | u32 ext_phy_type = 0; |
4921 | u32 spirom_ver = 0; | 4921 | u32 spirom_ver = 0; |
4922 | u8 status = 0 ; | 4922 | u8 status = 0 ; |
4923 | 4923 | ||
4924 | if (version == NULL || params == NULL) | 4924 | if (version == NULL || params == NULL) |
4925 | return -EINVAL; | 4925 | return -EINVAL; |
4926 | bp = params->bp; | ||
4926 | 4927 | ||
4927 | spirom_ver = REG_RD(bp, params->shmem_base + | 4928 | spirom_ver = REG_RD(bp, params->shmem_base + |
4928 | offsetof(struct shmem_region, | 4929 | offsetof(struct shmem_region, |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 574daddc21bf..9e4283aff828 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -346,7 +346,7 @@ void can_restart(unsigned long data) | |||
346 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 346 | skb = dev_alloc_skb(sizeof(struct can_frame)); |
347 | if (skb == NULL) { | 347 | if (skb == NULL) { |
348 | err = -ENOMEM; | 348 | err = -ENOMEM; |
349 | goto out; | 349 | goto restart; |
350 | } | 350 | } |
351 | skb->dev = dev; | 351 | skb->dev = dev; |
352 | skb->protocol = htons(ETH_P_CAN); | 352 | skb->protocol = htons(ETH_P_CAN); |
@@ -361,13 +361,13 @@ void can_restart(unsigned long data) | |||
361 | stats->rx_packets++; | 361 | stats->rx_packets++; |
362 | stats->rx_bytes += cf->can_dlc; | 362 | stats->rx_bytes += cf->can_dlc; |
363 | 363 | ||
364 | restart: | ||
364 | dev_dbg(dev->dev.parent, "restarted\n"); | 365 | dev_dbg(dev->dev.parent, "restarted\n"); |
365 | priv->can_stats.restarts++; | 366 | priv->can_stats.restarts++; |
366 | 367 | ||
367 | /* Now restart the device */ | 368 | /* Now restart the device */ |
368 | err = priv->do_set_mode(dev, CAN_MODE_START); | 369 | err = priv->do_set_mode(dev, CAN_MODE_START); |
369 | 370 | ||
370 | out: | ||
371 | netif_carrier_on(dev); | 371 | netif_carrier_on(dev); |
372 | if (err) | 372 | if (err) |
373 | dev_err(dev->dev.parent, "Error %d during restart", err); | 373 | dev_err(dev->dev.parent, "Error %d during restart", err); |
@@ -473,6 +473,10 @@ int open_candev(struct net_device *dev) | |||
473 | return -EINVAL; | 473 | return -EINVAL; |
474 | } | 474 | } |
475 | 475 | ||
476 | /* Switch carrier on if device was stopped while in bus-off state */ | ||
477 | if (!netif_carrier_ok(dev)) | ||
478 | netif_carrier_on(dev); | ||
479 | |||
476 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); | 480 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); |
477 | 481 | ||
478 | return 0; | 482 | return 0; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 1c30dbec1954..b3004de1e5e4 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -63,7 +63,6 @@ | |||
63 | #include <linux/can.h> | 63 | #include <linux/can.h> |
64 | #include <linux/can/dev.h> | 64 | #include <linux/can/dev.h> |
65 | #include <linux/can/error.h> | 65 | #include <linux/can/error.h> |
66 | #include <linux/can/dev.h> | ||
67 | 66 | ||
68 | #include "sja1000.h" | 67 | #include "sja1000.h" |
69 | 68 | ||
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index b892c3ad9a74..2bc2d2b20644 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -754,17 +754,16 @@ static int fs_init_phy(struct net_device *dev) | |||
754 | fep->oldlink = 0; | 754 | fep->oldlink = 0; |
755 | fep->oldspeed = 0; | 755 | fep->oldspeed = 0; |
756 | fep->oldduplex = -1; | 756 | fep->oldduplex = -1; |
757 | if(fep->fpi->phy_node) | 757 | |
758 | phydev = of_phy_connect(dev, fep->fpi->phy_node, | 758 | phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0, |
759 | &fs_adjust_link, 0, | 759 | PHY_INTERFACE_MODE_MII); |
760 | PHY_INTERFACE_MODE_MII); | 760 | if (!phydev) { |
761 | else { | 761 | phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link, |
762 | printk("No phy bus ID specified in BSP code\n"); | 762 | PHY_INTERFACE_MODE_MII); |
763 | return -EINVAL; | ||
764 | } | 763 | } |
765 | if (IS_ERR(phydev)) { | 764 | if (!phydev) { |
766 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 765 | dev_err(&dev->dev, "Could not attach to PHY\n"); |
767 | return PTR_ERR(phydev); | 766 | return -ENODEV; |
768 | } | 767 | } |
769 | 768 | ||
770 | fep->phydev = phydev; | 769 | fep->phydev = phydev; |
@@ -1005,6 +1004,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, | |||
1005 | goto out_free_fpi; | 1004 | goto out_free_fpi; |
1006 | } | 1005 | } |
1007 | 1006 | ||
1007 | SET_NETDEV_DEV(ndev, &ofdev->dev); | ||
1008 | dev_set_drvdata(&ofdev->dev, ndev); | 1008 | dev_set_drvdata(&ofdev->dev, ndev); |
1009 | 1009 | ||
1010 | fep = netdev_priv(ndev); | 1010 | fep = netdev_priv(ndev); |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b2db449966e2..056ba4625780 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -264,15 +264,6 @@ static int gfar_of_init(struct net_device *dev) | |||
264 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; | 264 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; |
265 | 265 | ||
266 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); | 266 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); |
267 | if (!priv->phy_node) { | ||
268 | u32 *fixed_link; | ||
269 | |||
270 | fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); | ||
271 | if (!fixed_link) { | ||
272 | err = -ENODEV; | ||
273 | goto err_out; | ||
274 | } | ||
275 | } | ||
276 | 267 | ||
277 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ | 268 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ |
278 | priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | 269 | priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0); |
@@ -658,13 +649,14 @@ static int init_phy(struct net_device *dev) | |||
658 | 649 | ||
659 | interface = gfar_get_interface(dev); | 650 | interface = gfar_get_interface(dev); |
660 | 651 | ||
661 | if (priv->phy_node) { | 652 | priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0, |
662 | priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, | 653 | interface); |
663 | 0, interface); | 654 | if (!priv->phydev) |
664 | if (!priv->phydev) { | 655 | priv->phydev = of_phy_connect_fixed_link(dev, &adjust_link, |
665 | dev_err(&dev->dev, "error: Could not attach to PHY\n"); | 656 | interface); |
666 | return -ENODEV; | 657 | if (!priv->phydev) { |
667 | } | 658 | dev_err(&dev->dev, "could not attach to PHY\n"); |
659 | return -ENODEV; | ||
668 | } | 660 | } |
669 | 661 | ||
670 | if (interface == PHY_INTERFACE_MODE_SGMII) | 662 | if (interface == PHY_INTERFACE_MODE_SGMII) |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index e88209fc2a2b..6cb2bdfd7b19 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * devices like TTY. It interfaces between a raw TTY and the | 3 | * devices like TTY. It interfaces between a raw TTY and the |
4 | * kernel's AX.25 protocol layers. | 4 | * kernel's AX.25 protocol layers. |
5 | * | 5 | * |
6 | * Authors: Andreas Könsgen <ajk@iehk.rwth-aachen.de> | 6 | * Authors: Andreas Könsgen <ajk@comnets.uni-bremen.de> |
7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> | 7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> |
8 | * | 8 | * |
9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by | 9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by |
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 1d5379de6900..8d76cb89dbd6 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c | |||
@@ -188,11 +188,12 @@ void rgmii_put_mdio(struct of_device *ofdev, int input) | |||
188 | void rgmii_detach(struct of_device *ofdev, int input) | 188 | void rgmii_detach(struct of_device *ofdev, int input) |
189 | { | 189 | { |
190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | 190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); |
191 | struct rgmii_regs __iomem *p = dev->base; | 191 | struct rgmii_regs __iomem *p; |
192 | |||
193 | mutex_lock(&dev->lock); | ||
194 | 192 | ||
195 | BUG_ON(!dev || dev->users == 0); | 193 | BUG_ON(!dev || dev->users == 0); |
194 | p = dev->base; | ||
195 | |||
196 | mutex_lock(&dev->lock); | ||
196 | 197 | ||
197 | RGMII_DBG(dev, "detach(%d)" NL, input); | 198 | RGMII_DBG(dev, "detach(%d)" NL, input); |
198 | 199 | ||
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 2a93e116f5a7..dc3cc4348d1d 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -323,6 +323,7 @@ struct ixgbe_adapter { | |||
323 | #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) | 323 | #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) |
324 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) | 324 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) |
325 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) | 325 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) |
326 | #define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 28) | ||
326 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) | 327 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) |
327 | 328 | ||
328 | u32 flags2; | 329 | u32 flags2; |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index da2c8514b8d0..1c7265732900 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -139,6 +139,18 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
139 | adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; | 139 | adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; |
140 | } | 140 | } |
141 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; | 141 | adapter->flags |= IXGBE_FLAG_DCB_ENABLED; |
142 | #ifdef IXGBE_FCOE | ||
143 | /* Turn on FCoE offload */ | ||
144 | if ((adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) && | ||
145 | (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))) { | ||
146 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; | ||
147 | adapter->ring_feature[RING_F_FCOE].indices = | ||
148 | IXGBE_FCRETA_SIZE; | ||
149 | netdev->features |= NETIF_F_FCOE_CRC; | ||
150 | netdev->features |= NETIF_F_FSO; | ||
151 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | ||
152 | } | ||
153 | #endif /* IXGBE_FCOE */ | ||
142 | ixgbe_init_interrupt_scheme(adapter); | 154 | ixgbe_init_interrupt_scheme(adapter); |
143 | if (netif_running(netdev)) | 155 | if (netif_running(netdev)) |
144 | netdev->netdev_ops->ndo_open(netdev); | 156 | netdev->netdev_ops->ndo_open(netdev); |
@@ -156,6 +168,18 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
156 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; | 168 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; |
157 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | 169 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) |
158 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; | 170 | adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; |
171 | |||
172 | #ifdef IXGBE_FCOE | ||
173 | /* Turn off FCoE offload */ | ||
174 | if (adapter->flags & (IXGBE_FLAG_FCOE_CAPABLE | | ||
175 | IXGBE_FLAG_FCOE_ENABLED)) { | ||
176 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; | ||
177 | adapter->ring_feature[RING_F_FCOE].indices = 0; | ||
178 | netdev->features &= ~NETIF_F_FCOE_CRC; | ||
179 | netdev->features &= ~NETIF_F_FSO; | ||
180 | netdev->fcoe_ddp_xid = 0; | ||
181 | } | ||
182 | #endif /* IXGBE_FCOE */ | ||
159 | ixgbe_init_interrupt_scheme(adapter); | 183 | ixgbe_init_interrupt_scheme(adapter); |
160 | if (netif_running(netdev)) | 184 | if (netif_running(netdev)) |
161 | netdev->netdev_ops->ndo_open(netdev); | 185 | netdev->netdev_ops->ndo_open(netdev); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 79f60e869737..50709da922c7 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/in.h> | 34 | #include <linux/in.h> |
35 | #include <linux/ip.h> | 35 | #include <linux/ip.h> |
36 | #include <linux/tcp.h> | 36 | #include <linux/tcp.h> |
37 | #include <linux/pkt_sched.h> | ||
37 | #include <linux/ipv6.h> | 38 | #include <linux/ipv6.h> |
38 | #include <net/checksum.h> | 39 | #include <net/checksum.h> |
39 | #include <net/ip6_checksum.h> | 40 | #include <net/ip6_checksum.h> |
@@ -3808,8 +3809,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
3808 | adapter->atr_sample_rate = 20; | 3809 | adapter->atr_sample_rate = 20; |
3809 | adapter->fdir_pballoc = 0; | 3810 | adapter->fdir_pballoc = 0; |
3810 | #ifdef IXGBE_FCOE | 3811 | #ifdef IXGBE_FCOE |
3811 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; | 3812 | adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; |
3812 | adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE; | 3813 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; |
3814 | adapter->ring_feature[RING_F_FCOE].indices = 0; | ||
3813 | #endif /* IXGBE_FCOE */ | 3815 | #endif /* IXGBE_FCOE */ |
3814 | } | 3816 | } |
3815 | 3817 | ||
@@ -5127,9 +5129,6 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
5127 | int count = 0; | 5129 | int count = 0; |
5128 | unsigned int f; | 5130 | unsigned int f; |
5129 | 5131 | ||
5130 | r_idx = skb->queue_mapping; | ||
5131 | tx_ring = &adapter->tx_ring[r_idx]; | ||
5132 | |||
5133 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { | 5132 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { |
5134 | tx_flags |= vlan_tx_tag_get(skb); | 5133 | tx_flags |= vlan_tx_tag_get(skb); |
5135 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 5134 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
@@ -5139,11 +5138,19 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
5139 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; | 5138 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; |
5140 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | 5139 | tx_flags |= IXGBE_TX_FLAGS_VLAN; |
5141 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 5140 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
5142 | tx_flags |= (skb->queue_mapping << 13); | 5141 | if (skb->priority != TC_PRIO_CONTROL) { |
5143 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; | 5142 | tx_flags |= (skb->queue_mapping << 13); |
5144 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | 5143 | tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; |
5144 | tx_flags |= IXGBE_TX_FLAGS_VLAN; | ||
5145 | } else { | ||
5146 | skb->queue_mapping = | ||
5147 | adapter->ring_feature[RING_F_DCB].indices-1; | ||
5148 | } | ||
5145 | } | 5149 | } |
5146 | 5150 | ||
5151 | r_idx = skb->queue_mapping; | ||
5152 | tx_ring = &adapter->tx_ring[r_idx]; | ||
5153 | |||
5147 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && | 5154 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && |
5148 | (skb->protocol == htons(ETH_P_FCOE))) | 5155 | (skb->protocol == htons(ETH_P_FCOE))) |
5149 | tx_flags |= IXGBE_TX_FLAGS_FCOE; | 5156 | tx_flags |= IXGBE_TX_FLAGS_FCOE; |
@@ -5582,16 +5589,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5582 | #endif | 5589 | #endif |
5583 | 5590 | ||
5584 | #ifdef IXGBE_FCOE | 5591 | #ifdef IXGBE_FCOE |
5585 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | 5592 | if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) { |
5586 | if (hw->mac.ops.get_device_caps) { | 5593 | if (hw->mac.ops.get_device_caps) { |
5587 | hw->mac.ops.get_device_caps(hw, &device_caps); | 5594 | hw->mac.ops.get_device_caps(hw, &device_caps); |
5588 | if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) { | 5595 | if (device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS) |
5589 | netdev->features |= NETIF_F_FCOE_CRC; | 5596 | adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; |
5590 | netdev->features |= NETIF_F_FSO; | ||
5591 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | ||
5592 | } else { | ||
5593 | adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; | ||
5594 | } | ||
5595 | } | 5597 | } |
5596 | } | 5598 | } |
5597 | #endif /* IXGBE_FCOE */ | 5599 | #endif /* IXGBE_FCOE */ |
@@ -5640,7 +5642,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5640 | adapter->wol = 0; | 5642 | adapter->wol = 0; |
5641 | break; | 5643 | break; |
5642 | } | 5644 | } |
5643 | device_init_wakeup(&adapter->pdev->dev, true); | ||
5644 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 5645 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
5645 | 5646 | ||
5646 | /* pick up the PCI bus settings for reporting later */ | 5647 | /* pick up the PCI bus settings for reporting later */ |
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 8baf5950731c..ec337b502fd9 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -229,6 +229,7 @@ static int __devinit jazz_sonic_probe(struct platform_device *pdev) | |||
229 | lp = netdev_priv(dev); | 229 | lp = netdev_priv(dev); |
230 | lp->device = &pdev->dev; | 230 | lp->device = &pdev->dev; |
231 | SET_NETDEV_DEV(dev, &pdev->dev); | 231 | SET_NETDEV_DEV(dev, &pdev->dev); |
232 | platform_set_drvdata(pdev, dev); | ||
232 | 233 | ||
233 | netdev_boot_setup_check(dev); | 234 | netdev_boot_setup_check(dev); |
234 | 235 | ||
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c new file mode 100644 index 000000000000..9a1dea60c1c4 --- /dev/null +++ b/drivers/net/ks8851.c | |||
@@ -0,0 +1,1322 @@ | |||
1 | /* drivers/net/ks8651.c | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * http://www.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #define DEBUG | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/cache.h> | ||
20 | #include <linux/crc32.h> | ||
21 | #include <linux/mii.h> | ||
22 | |||
23 | #include <linux/spi/spi.h> | ||
24 | |||
25 | #include "ks8851.h" | ||
26 | |||
27 | /** | ||
28 | * struct ks8851_rxctrl - KS8851 driver rx control | ||
29 | * @mchash: Multicast hash-table data. | ||
30 | * @rxcr1: KS_RXCR1 register setting | ||
31 | * @rxcr2: KS_RXCR2 register setting | ||
32 | * | ||
33 | * Representation of the settings needs to control the receive filtering | ||
34 | * such as the multicast hash-filter and the receive register settings. This | ||
35 | * is used to make the job of working out if the receive settings change and | ||
36 | * then issuing the new settings to the worker that will send the necessary | ||
37 | * commands. | ||
38 | */ | ||
39 | struct ks8851_rxctrl { | ||
40 | u16 mchash[4]; | ||
41 | u16 rxcr1; | ||
42 | u16 rxcr2; | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * union ks8851_tx_hdr - tx header data | ||
47 | * @txb: The header as bytes | ||
48 | * @txw: The header as 16bit, little-endian words | ||
49 | * | ||
50 | * A dual representation of the tx header data to allow | ||
51 | * access to individual bytes, and to allow 16bit accesses | ||
52 | * with 16bit alignment. | ||
53 | */ | ||
54 | union ks8851_tx_hdr { | ||
55 | u8 txb[6]; | ||
56 | __le16 txw[3]; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * struct ks8851_net - KS8851 driver private data | ||
61 | * @netdev: The network device we're bound to | ||
62 | * @spidev: The spi device we're bound to. | ||
63 | * @lock: Lock to ensure that the device is not accessed when busy. | ||
64 | * @statelock: Lock on this structure for tx list. | ||
65 | * @mii: The MII state information for the mii calls. | ||
66 | * @rxctrl: RX settings for @rxctrl_work. | ||
67 | * @tx_work: Work queue for tx packets | ||
68 | * @irq_work: Work queue for servicing interrupts | ||
69 | * @rxctrl_work: Work queue for updating RX mode and multicast lists | ||
70 | * @txq: Queue of packets for transmission. | ||
71 | * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. | ||
72 | * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. | ||
73 | * @txh: Space for generating packet TX header in DMA-able data | ||
74 | * @rxd: Space for receiving SPI data, in DMA-able space. | ||
75 | * @txd: Space for transmitting SPI data, in DMA-able space. | ||
76 | * @msg_enable: The message flags controlling driver output (see ethtool). | ||
77 | * @fid: Incrementing frame id tag. | ||
78 | * @rc_ier: Cached copy of KS_IER. | ||
79 | * @rc_rxqcr: Cached copy of KS_RXQCR. | ||
80 | * | ||
81 | * The @lock ensures that the chip is protected when certain operations are | ||
82 | * in progress. When the read or write packet transfer is in progress, most | ||
83 | * of the chip registers are not ccessible until the transfer is finished and | ||
84 | * the DMA has been de-asserted. | ||
85 | * | ||
86 | * The @statelock is used to protect information in the structure which may | ||
87 | * need to be accessed via several sources, such as the network driver layer | ||
88 | * or one of the work queues. | ||
89 | * | ||
90 | * We align the buffers we may use for rx/tx to ensure that if the SPI driver | ||
91 | * wants to DMA map them, it will not have any problems with data the driver | ||
92 | * modifies. | ||
93 | */ | ||
94 | struct ks8851_net { | ||
95 | struct net_device *netdev; | ||
96 | struct spi_device *spidev; | ||
97 | struct mutex lock; | ||
98 | spinlock_t statelock; | ||
99 | |||
100 | union ks8851_tx_hdr txh ____cacheline_aligned; | ||
101 | u8 rxd[8]; | ||
102 | u8 txd[8]; | ||
103 | |||
104 | u32 msg_enable ____cacheline_aligned; | ||
105 | u16 tx_space; | ||
106 | u8 fid; | ||
107 | |||
108 | u16 rc_ier; | ||
109 | u16 rc_rxqcr; | ||
110 | |||
111 | struct mii_if_info mii; | ||
112 | struct ks8851_rxctrl rxctrl; | ||
113 | |||
114 | struct work_struct tx_work; | ||
115 | struct work_struct irq_work; | ||
116 | struct work_struct rxctrl_work; | ||
117 | |||
118 | struct sk_buff_head txq; | ||
119 | |||
120 | struct spi_message spi_msg1; | ||
121 | struct spi_message spi_msg2; | ||
122 | struct spi_transfer spi_xfer1; | ||
123 | struct spi_transfer spi_xfer2[2]; | ||
124 | }; | ||
125 | |||
126 | static int msg_enable; | ||
127 | |||
128 | #define ks_info(_ks, _msg...) dev_info(&(_ks)->spidev->dev, _msg) | ||
129 | #define ks_warn(_ks, _msg...) dev_warn(&(_ks)->spidev->dev, _msg) | ||
130 | #define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->spidev->dev, _msg) | ||
131 | #define ks_err(_ks, _msg...) dev_err(&(_ks)->spidev->dev, _msg) | ||
132 | |||
133 | /* shift for byte-enable data */ | ||
134 | #define BYTE_EN(_x) ((_x) << 2) | ||
135 | |||
136 | /* turn register number and byte-enable mask into data for start of packet */ | ||
137 | #define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) | ||
138 | |||
139 | /* SPI register read/write calls. | ||
140 | * | ||
141 | * All these calls issue SPI transactions to access the chip's registers. They | ||
142 | * all require that the necessary lock is held to prevent accesses when the | ||
143 | * chip is busy transfering packet data (RX/TX FIFO accesses). | ||
144 | */ | ||
145 | |||
146 | /** | ||
147 | * ks8851_wrreg16 - write 16bit register value to chip | ||
148 | * @ks: The chip state | ||
149 | * @reg: The register address | ||
150 | * @val: The value to write | ||
151 | * | ||
152 | * Issue a write to put the value @val into the register specified in @reg. | ||
153 | */ | ||
154 | static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) | ||
155 | { | ||
156 | struct spi_transfer *xfer = &ks->spi_xfer1; | ||
157 | struct spi_message *msg = &ks->spi_msg1; | ||
158 | __le16 txb[2]; | ||
159 | int ret; | ||
160 | |||
161 | txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); | ||
162 | txb[1] = cpu_to_le16(val); | ||
163 | |||
164 | xfer->tx_buf = txb; | ||
165 | xfer->rx_buf = NULL; | ||
166 | xfer->len = 4; | ||
167 | |||
168 | ret = spi_sync(ks->spidev, msg); | ||
169 | if (ret < 0) | ||
170 | ks_err(ks, "spi_sync() failed\n"); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * ks8851_rx_1msg - select whether to use one or two messages for spi read | ||
175 | * @ks: The device structure | ||
176 | * | ||
177 | * Return whether to generate a single message with a tx and rx buffer | ||
178 | * supplied to spi_sync(), or alternatively send the tx and rx buffers | ||
179 | * as separate messages. | ||
180 | * | ||
181 | * Depending on the hardware in use, a single message may be more efficient | ||
182 | * on interrupts or work done by the driver. | ||
183 | * | ||
184 | * This currently always returns true until we add some per-device data passed | ||
185 | * from the platform code to specify which mode is better. | ||
186 | */ | ||
187 | static inline bool ks8851_rx_1msg(struct ks8851_net *ks) | ||
188 | { | ||
189 | return true; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * ks8851_rdreg - issue read register command and return the data | ||
194 | * @ks: The device state | ||
195 | * @op: The register address and byte enables in message format. | ||
196 | * @rxb: The RX buffer to return the result into | ||
197 | * @rxl: The length of data expected. | ||
198 | * | ||
199 | * This is the low level read call that issues the necessary spi message(s) | ||
200 | * to read data from the register specified in @op. | ||
201 | */ | ||
202 | static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, | ||
203 | u8 *rxb, unsigned rxl) | ||
204 | { | ||
205 | struct spi_transfer *xfer; | ||
206 | struct spi_message *msg; | ||
207 | __le16 *txb = (__le16 *)ks->txd; | ||
208 | u8 *trx = ks->rxd; | ||
209 | int ret; | ||
210 | |||
211 | txb[0] = cpu_to_le16(op | KS_SPIOP_RD); | ||
212 | |||
213 | if (ks8851_rx_1msg(ks)) { | ||
214 | msg = &ks->spi_msg1; | ||
215 | xfer = &ks->spi_xfer1; | ||
216 | |||
217 | xfer->tx_buf = txb; | ||
218 | xfer->rx_buf = trx; | ||
219 | xfer->len = rxl + 2; | ||
220 | } else { | ||
221 | msg = &ks->spi_msg2; | ||
222 | xfer = ks->spi_xfer2; | ||
223 | |||
224 | xfer->tx_buf = txb; | ||
225 | xfer->rx_buf = NULL; | ||
226 | xfer->len = 2; | ||
227 | |||
228 | xfer++; | ||
229 | xfer->tx_buf = NULL; | ||
230 | xfer->rx_buf = trx; | ||
231 | xfer->len = rxl; | ||
232 | } | ||
233 | |||
234 | ret = spi_sync(ks->spidev, msg); | ||
235 | if (ret < 0) | ||
236 | ks_err(ks, "read: spi_sync() failed\n"); | ||
237 | else if (ks8851_rx_1msg(ks)) | ||
238 | memcpy(rxb, trx + 2, rxl); | ||
239 | else | ||
240 | memcpy(rxb, trx, rxl); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * ks8851_rdreg8 - read 8 bit register from device | ||
245 | * @ks: The chip information | ||
246 | * @reg: The register address | ||
247 | * | ||
248 | * Read a 8bit register from the chip, returning the result | ||
249 | */ | ||
250 | static unsigned ks8851_rdreg8(struct ks8851_net *ks, unsigned reg) | ||
251 | { | ||
252 | u8 rxb[1]; | ||
253 | |||
254 | ks8851_rdreg(ks, MK_OP(1 << (reg & 3), reg), rxb, 1); | ||
255 | return rxb[0]; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * ks8851_rdreg16 - read 16 bit register from device | ||
260 | * @ks: The chip information | ||
261 | * @reg: The register address | ||
262 | * | ||
263 | * Read a 16bit register from the chip, returning the result | ||
264 | */ | ||
265 | static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) | ||
266 | { | ||
267 | __le16 rx = 0; | ||
268 | |||
269 | ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); | ||
270 | return le16_to_cpu(rx); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * ks8851_rdreg32 - read 32 bit register from device | ||
275 | * @ks: The chip information | ||
276 | * @reg: The register address | ||
277 | * | ||
278 | * Read a 32bit register from the chip. | ||
279 | * | ||
280 | * Note, this read requires the address be aligned to 4 bytes. | ||
281 | */ | ||
282 | static unsigned ks8851_rdreg32(struct ks8851_net *ks, unsigned reg) | ||
283 | { | ||
284 | __le32 rx = 0; | ||
285 | |||
286 | WARN_ON(reg & 3); | ||
287 | |||
288 | ks8851_rdreg(ks, MK_OP(0xf, reg), (u8 *)&rx, 4); | ||
289 | return le32_to_cpu(rx); | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * ks8851_soft_reset - issue one of the soft reset to the device | ||
294 | * @ks: The device state. | ||
295 | * @op: The bit(s) to set in the GRR | ||
296 | * | ||
297 | * Issue the relevant soft-reset command to the device's GRR register | ||
298 | * specified by @op. | ||
299 | * | ||
300 | * Note, the delays are in there as a caution to ensure that the reset | ||
301 | * has time to take effect and then complete. Since the datasheet does | ||
302 | * not currently specify the exact sequence, we have chosen something | ||
303 | * that seems to work with our device. | ||
304 | */ | ||
305 | static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op) | ||
306 | { | ||
307 | ks8851_wrreg16(ks, KS_GRR, op); | ||
308 | mdelay(1); /* wait a short time to effect reset */ | ||
309 | ks8851_wrreg16(ks, KS_GRR, 0); | ||
310 | mdelay(1); /* wait for condition to clear */ | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ks8851_write_mac_addr - write mac address to device registers | ||
315 | * @dev: The network device | ||
316 | * | ||
317 | * Update the KS8851 MAC address registers from the address in @dev. | ||
318 | * | ||
319 | * This call assumes that the chip is not running, so there is no need to | ||
320 | * shutdown the RXQ process whilst setting this. | ||
321 | */ | ||
322 | static int ks8851_write_mac_addr(struct net_device *dev) | ||
323 | { | ||
324 | struct ks8851_net *ks = netdev_priv(dev); | ||
325 | u16 *mcp = (u16 *)dev->dev_addr; | ||
326 | |||
327 | mutex_lock(&ks->lock); | ||
328 | |||
329 | ks8851_wrreg16(ks, KS_MARL, mcp[0]); | ||
330 | ks8851_wrreg16(ks, KS_MARM, mcp[1]); | ||
331 | ks8851_wrreg16(ks, KS_MARH, mcp[2]); | ||
332 | |||
333 | mutex_unlock(&ks->lock); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * ks8851_init_mac - initialise the mac address | ||
340 | * @ks: The device structure | ||
341 | * | ||
342 | * Get or create the initial mac address for the device and then set that | ||
343 | * into the station address register. Currently we assume that the device | ||
344 | * does not have a valid mac address in it, and so we use random_ether_addr() | ||
345 | * to create a new one. | ||
346 | * | ||
347 | * In future, the driver should check to see if the device has an EEPROM | ||
348 | * attached and whether that has a valid ethernet address in it. | ||
349 | */ | ||
350 | static void ks8851_init_mac(struct ks8851_net *ks) | ||
351 | { | ||
352 | struct net_device *dev = ks->netdev; | ||
353 | |||
354 | random_ether_addr(dev->dev_addr); | ||
355 | ks8851_write_mac_addr(dev); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * ks8851_irq - device interrupt handler | ||
360 | * @irq: Interrupt number passed from the IRQ hnalder. | ||
361 | * @pw: The private word passed to register_irq(), our struct ks8851_net. | ||
362 | * | ||
363 | * Disable the interrupt from happening again until we've processed the | ||
364 | * current status by scheduling ks8851_irq_work(). | ||
365 | */ | ||
366 | static irqreturn_t ks8851_irq(int irq, void *pw) | ||
367 | { | ||
368 | struct ks8851_net *ks = pw; | ||
369 | |||
370 | disable_irq_nosync(irq); | ||
371 | schedule_work(&ks->irq_work); | ||
372 | return IRQ_HANDLED; | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * ks8851_rdfifo - read data from the receive fifo | ||
377 | * @ks: The device state. | ||
378 | * @buff: The buffer address | ||
379 | * @len: The length of the data to read | ||
380 | * | ||
381 | * Issue an RXQ FIFO read command and read the @len ammount of data from | ||
382 | * the FIFO into the buffer specified by @buff. | ||
383 | */ | ||
384 | static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) | ||
385 | { | ||
386 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
387 | struct spi_message *msg = &ks->spi_msg2; | ||
388 | u8 txb[1]; | ||
389 | int ret; | ||
390 | |||
391 | if (netif_msg_rx_status(ks)) | ||
392 | ks_dbg(ks, "%s: %d@%p\n", __func__, len, buff); | ||
393 | |||
394 | /* set the operation we're issuing */ | ||
395 | txb[0] = KS_SPIOP_RXFIFO; | ||
396 | |||
397 | xfer->tx_buf = txb; | ||
398 | xfer->rx_buf = NULL; | ||
399 | xfer->len = 1; | ||
400 | |||
401 | xfer++; | ||
402 | xfer->rx_buf = buff; | ||
403 | xfer->tx_buf = NULL; | ||
404 | xfer->len = len; | ||
405 | |||
406 | ret = spi_sync(ks->spidev, msg); | ||
407 | if (ret < 0) | ||
408 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * ks8851_dbg_dumpkkt - dump initial packet contents to debug | ||
413 | * @ks: The device state | ||
414 | * @rxpkt: The data for the received packet | ||
415 | * | ||
416 | * Dump the initial data from the packet to dev_dbg(). | ||
417 | */ | ||
418 | static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) | ||
419 | { | ||
420 | ks_dbg(ks, "pkt %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", | ||
421 | rxpkt[4], rxpkt[5], rxpkt[6], rxpkt[7], | ||
422 | rxpkt[8], rxpkt[9], rxpkt[10], rxpkt[11], | ||
423 | rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * ks8851_rx_pkts - receive packets from the host | ||
428 | * @ks: The device information. | ||
429 | * | ||
430 | * This is called from the IRQ work queue when the system detects that there | ||
431 | * are packets in the receive queue. Find out how many packets there are and | ||
432 | * read them from the FIFO. | ||
433 | */ | ||
434 | static void ks8851_rx_pkts(struct ks8851_net *ks) | ||
435 | { | ||
436 | struct sk_buff *skb; | ||
437 | unsigned rxfc; | ||
438 | unsigned rxlen; | ||
439 | unsigned rxstat; | ||
440 | u32 rxh; | ||
441 | u8 *rxpkt; | ||
442 | |||
443 | rxfc = ks8851_rdreg8(ks, KS_RXFC); | ||
444 | |||
445 | if (netif_msg_rx_status(ks)) | ||
446 | ks_dbg(ks, "%s: %d packets\n", __func__, rxfc); | ||
447 | |||
448 | /* Currently we're issuing a read per packet, but we could possibly | ||
449 | * improve the code by issuing a single read, getting the receive | ||
450 | * header, allocating the packet and then reading the packet data | ||
451 | * out in one go. | ||
452 | * | ||
453 | * This form of operation would require us to hold the SPI bus' | ||
454 | * chipselect low during the entie transaction to avoid any | ||
455 | * reset to the data stream comming from the chip. | ||
456 | */ | ||
457 | |||
458 | for (; rxfc != 0; rxfc--) { | ||
459 | rxh = ks8851_rdreg32(ks, KS_RXFHSR); | ||
460 | rxstat = rxh & 0xffff; | ||
461 | rxlen = rxh >> 16; | ||
462 | |||
463 | if (netif_msg_rx_status(ks)) | ||
464 | ks_dbg(ks, "rx: stat 0x%04x, len 0x%04x\n", | ||
465 | rxstat, rxlen); | ||
466 | |||
467 | /* the length of the packet includes the 32bit CRC */ | ||
468 | |||
469 | /* set dma read address */ | ||
470 | ks8851_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI | 0x00); | ||
471 | |||
472 | /* start the packet dma process, and set auto-dequeue rx */ | ||
473 | ks8851_wrreg16(ks, KS_RXQCR, | ||
474 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); | ||
475 | |||
476 | if (rxlen > 0) { | ||
477 | skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8); | ||
478 | if (!skb) { | ||
479 | /* todo - dump frame and move on */ | ||
480 | } | ||
481 | |||
482 | /* two bytes to ensure ip is aligned, and four bytes | ||
483 | * for the status header and 4 bytes of garbage */ | ||
484 | skb_reserve(skb, 2 + 4 + 4); | ||
485 | |||
486 | rxpkt = skb_put(skb, rxlen - 4) - 8; | ||
487 | |||
488 | /* align the packet length to 4 bytes, and add 4 bytes | ||
489 | * as we're getting the rx status header as well */ | ||
490 | ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8); | ||
491 | |||
492 | if (netif_msg_pktdata(ks)) | ||
493 | ks8851_dbg_dumpkkt(ks, rxpkt); | ||
494 | |||
495 | skb->protocol = eth_type_trans(skb, ks->netdev); | ||
496 | netif_rx(skb); | ||
497 | |||
498 | ks->netdev->stats.rx_packets++; | ||
499 | ks->netdev->stats.rx_bytes += rxlen - 4; | ||
500 | } | ||
501 | |||
502 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * ks8851_irq_work - work queue handler for dealing with interrupt requests | ||
508 | * @work: The work structure that was scheduled by schedule_work() | ||
509 | * | ||
510 | * This is the handler invoked when the ks8851_irq() is called to find out | ||
511 | * what happened, as we cannot allow ourselves to sleep whilst waiting for | ||
512 | * anything other process has the chip's lock. | ||
513 | * | ||
514 | * Read the interrupt status, work out what needs to be done and then clear | ||
515 | * any of the interrupts that are not needed. | ||
516 | */ | ||
517 | static void ks8851_irq_work(struct work_struct *work) | ||
518 | { | ||
519 | struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work); | ||
520 | unsigned status; | ||
521 | unsigned handled = 0; | ||
522 | |||
523 | mutex_lock(&ks->lock); | ||
524 | |||
525 | status = ks8851_rdreg16(ks, KS_ISR); | ||
526 | |||
527 | if (netif_msg_intr(ks)) | ||
528 | dev_dbg(&ks->spidev->dev, "%s: status 0x%04x\n", | ||
529 | __func__, status); | ||
530 | |||
531 | if (status & IRQ_LCI) { | ||
532 | /* should do something about checking link status */ | ||
533 | handled |= IRQ_LCI; | ||
534 | } | ||
535 | |||
536 | if (status & IRQ_LDI) { | ||
537 | u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
538 | pmecr &= ~PMECR_WKEVT_MASK; | ||
539 | ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); | ||
540 | |||
541 | handled |= IRQ_LDI; | ||
542 | } | ||
543 | |||
544 | if (status & IRQ_RXPSI) | ||
545 | handled |= IRQ_RXPSI; | ||
546 | |||
547 | if (status & IRQ_TXI) { | ||
548 | handled |= IRQ_TXI; | ||
549 | |||
550 | /* no lock here, tx queue should have been stopped */ | ||
551 | |||
552 | /* update our idea of how much tx space is available to the | ||
553 | * system */ | ||
554 | ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); | ||
555 | |||
556 | if (netif_msg_intr(ks)) | ||
557 | ks_dbg(ks, "%s: txspace %d\n", __func__, ks->tx_space); | ||
558 | } | ||
559 | |||
560 | if (status & IRQ_RXI) | ||
561 | handled |= IRQ_RXI; | ||
562 | |||
563 | if (status & IRQ_SPIBEI) { | ||
564 | dev_err(&ks->spidev->dev, "%s: spi bus error\n", __func__); | ||
565 | handled |= IRQ_SPIBEI; | ||
566 | } | ||
567 | |||
568 | ks8851_wrreg16(ks, KS_ISR, handled); | ||
569 | |||
570 | if (status & IRQ_RXI) { | ||
571 | /* the datasheet says to disable the rx interrupt during | ||
572 | * packet read-out, however we're masking the interrupt | ||
573 | * from the device so do not bother masking just the RX | ||
574 | * from the device. */ | ||
575 | |||
576 | ks8851_rx_pkts(ks); | ||
577 | } | ||
578 | |||
579 | /* if something stopped the rx process, probably due to wanting | ||
580 | * to change the rx settings, then do something about restarting | ||
581 | * it. */ | ||
582 | if (status & IRQ_RXPSI) { | ||
583 | struct ks8851_rxctrl *rxc = &ks->rxctrl; | ||
584 | |||
585 | /* update the multicast hash table */ | ||
586 | ks8851_wrreg16(ks, KS_MAHTR0, rxc->mchash[0]); | ||
587 | ks8851_wrreg16(ks, KS_MAHTR1, rxc->mchash[1]); | ||
588 | ks8851_wrreg16(ks, KS_MAHTR2, rxc->mchash[2]); | ||
589 | ks8851_wrreg16(ks, KS_MAHTR3, rxc->mchash[3]); | ||
590 | |||
591 | ks8851_wrreg16(ks, KS_RXCR2, rxc->rxcr2); | ||
592 | ks8851_wrreg16(ks, KS_RXCR1, rxc->rxcr1); | ||
593 | } | ||
594 | |||
595 | mutex_unlock(&ks->lock); | ||
596 | |||
597 | if (status & IRQ_TXI) | ||
598 | netif_wake_queue(ks->netdev); | ||
599 | |||
600 | enable_irq(ks->netdev->irq); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * calc_txlen - calculate size of message to send packet | ||
605 | * @len: Lenght of data | ||
606 | * | ||
607 | * Returns the size of the TXFIFO message needed to send | ||
608 | * this packet. | ||
609 | */ | ||
610 | static inline unsigned calc_txlen(unsigned len) | ||
611 | { | ||
612 | return ALIGN(len + 4, 4); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * ks8851_wrpkt - write packet to TX FIFO | ||
617 | * @ks: The device state. | ||
618 | * @txp: The sk_buff to transmit. | ||
619 | * @irq: IRQ on completion of the packet. | ||
620 | * | ||
621 | * Send the @txp to the chip. This means creating the relevant packet header | ||
622 | * specifying the length of the packet and the other information the chip | ||
623 | * needs, such as IRQ on completion. Send the header and the packet data to | ||
624 | * the device. | ||
625 | */ | ||
626 | static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) | ||
627 | { | ||
628 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
629 | struct spi_message *msg = &ks->spi_msg2; | ||
630 | unsigned fid = 0; | ||
631 | int ret; | ||
632 | |||
633 | if (netif_msg_tx_queued(ks)) | ||
634 | dev_dbg(&ks->spidev->dev, "%s: skb %p, %d@%p, irq %d\n", | ||
635 | __func__, txp, txp->len, txp->data, irq); | ||
636 | |||
637 | fid = ks->fid++; | ||
638 | fid &= TXFR_TXFID_MASK; | ||
639 | |||
640 | if (irq) | ||
641 | fid |= TXFR_TXIC; /* irq on completion */ | ||
642 | |||
643 | /* start header at txb[1] to align txw entries */ | ||
644 | ks->txh.txb[1] = KS_SPIOP_TXFIFO; | ||
645 | ks->txh.txw[1] = cpu_to_le16(fid); | ||
646 | ks->txh.txw[2] = cpu_to_le16(txp->len); | ||
647 | |||
648 | xfer->tx_buf = &ks->txh.txb[1]; | ||
649 | xfer->rx_buf = NULL; | ||
650 | xfer->len = 5; | ||
651 | |||
652 | xfer++; | ||
653 | xfer->tx_buf = txp->data; | ||
654 | xfer->rx_buf = NULL; | ||
655 | xfer->len = ALIGN(txp->len, 4); | ||
656 | |||
657 | ret = spi_sync(ks->spidev, msg); | ||
658 | if (ret < 0) | ||
659 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * ks8851_done_tx - update and then free skbuff after transmitting | ||
664 | * @ks: The device state | ||
665 | * @txb: The buffer transmitted | ||
666 | */ | ||
667 | static void ks8851_done_tx(struct ks8851_net *ks, struct sk_buff *txb) | ||
668 | { | ||
669 | struct net_device *dev = ks->netdev; | ||
670 | |||
671 | dev->stats.tx_bytes += txb->len; | ||
672 | dev->stats.tx_packets++; | ||
673 | |||
674 | dev_kfree_skb(txb); | ||
675 | } | ||
676 | |||
677 | /** | ||
678 | * ks8851_tx_work - process tx packet(s) | ||
679 | * @work: The work strucutre what was scheduled. | ||
680 | * | ||
681 | * This is called when a number of packets have been scheduled for | ||
682 | * transmission and need to be sent to the device. | ||
683 | */ | ||
684 | static void ks8851_tx_work(struct work_struct *work) | ||
685 | { | ||
686 | struct ks8851_net *ks = container_of(work, struct ks8851_net, tx_work); | ||
687 | struct sk_buff *txb; | ||
688 | bool last = false; | ||
689 | |||
690 | mutex_lock(&ks->lock); | ||
691 | |||
692 | while (!last) { | ||
693 | txb = skb_dequeue(&ks->txq); | ||
694 | last = skb_queue_empty(&ks->txq); | ||
695 | |||
696 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); | ||
697 | ks8851_wrpkt(ks, txb, last); | ||
698 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
699 | ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); | ||
700 | |||
701 | ks8851_done_tx(ks, txb); | ||
702 | } | ||
703 | |||
704 | mutex_unlock(&ks->lock); | ||
705 | } | ||
706 | |||
707 | /** | ||
708 | * ks8851_set_powermode - set power mode of the device | ||
709 | * @ks: The device state | ||
710 | * @pwrmode: The power mode value to write to KS_PMECR. | ||
711 | * | ||
712 | * Change the power mode of the chip. | ||
713 | */ | ||
714 | static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode) | ||
715 | { | ||
716 | unsigned pmecr; | ||
717 | |||
718 | if (netif_msg_hw(ks)) | ||
719 | ks_dbg(ks, "setting power mode %d\n", pwrmode); | ||
720 | |||
721 | pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
722 | pmecr &= ~PMECR_PM_MASK; | ||
723 | pmecr |= pwrmode; | ||
724 | |||
725 | ks8851_wrreg16(ks, KS_PMECR, pmecr); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * ks8851_net_open - open network device | ||
730 | * @dev: The network device being opened. | ||
731 | * | ||
732 | * Called when the network device is marked active, such as a user executing | ||
733 | * 'ifconfig up' on the device. | ||
734 | */ | ||
735 | static int ks8851_net_open(struct net_device *dev) | ||
736 | { | ||
737 | struct ks8851_net *ks = netdev_priv(dev); | ||
738 | |||
739 | /* lock the card, even if we may not actually be doing anything | ||
740 | * else at the moment */ | ||
741 | mutex_lock(&ks->lock); | ||
742 | |||
743 | if (netif_msg_ifup(ks)) | ||
744 | ks_dbg(ks, "opening %s\n", dev->name); | ||
745 | |||
746 | /* bring chip out of any power saving mode it was in */ | ||
747 | ks8851_set_powermode(ks, PMECR_PM_NORMAL); | ||
748 | |||
749 | /* issue a soft reset to the RX/TX QMU to put it into a known | ||
750 | * state. */ | ||
751 | ks8851_soft_reset(ks, GRR_QMU); | ||
752 | |||
753 | /* setup transmission parameters */ | ||
754 | |||
755 | ks8851_wrreg16(ks, KS_TXCR, (TXCR_TXE | /* enable transmit process */ | ||
756 | TXCR_TXPE | /* pad to min length */ | ||
757 | TXCR_TXCRC | /* add CRC */ | ||
758 | TXCR_TXFCE)); /* enable flow control */ | ||
759 | |||
760 | /* auto-increment tx data, reset tx pointer */ | ||
761 | ks8851_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI); | ||
762 | |||
763 | /* setup receiver control */ | ||
764 | |||
765 | ks8851_wrreg16(ks, KS_RXCR1, (RXCR1_RXPAFMA | /* from mac filter */ | ||
766 | RXCR1_RXFCE | /* enable flow control */ | ||
767 | RXCR1_RXBE | /* broadcast enable */ | ||
768 | RXCR1_RXUE | /* unicast enable */ | ||
769 | RXCR1_RXE)); /* enable rx block */ | ||
770 | |||
771 | /* transfer entire frames out in one go */ | ||
772 | ks8851_wrreg16(ks, KS_RXCR2, RXCR2_SRDBL_FRAME); | ||
773 | |||
774 | /* set receive counter timeouts */ | ||
775 | ks8851_wrreg16(ks, KS_RXDTTR, 1000); /* 1ms after first frame to IRQ */ | ||
776 | ks8851_wrreg16(ks, KS_RXDBCTR, 4096); /* >4Kbytes in buffer to IRQ */ | ||
777 | ks8851_wrreg16(ks, KS_RXFCTR, 10); /* 10 frames to IRQ */ | ||
778 | |||
779 | ks->rc_rxqcr = (RXQCR_RXFCTE | /* IRQ on frame count exceeded */ | ||
780 | RXQCR_RXDBCTE | /* IRQ on byte count exceeded */ | ||
781 | RXQCR_RXDTTE); /* IRQ on time exceeded */ | ||
782 | |||
783 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
784 | |||
785 | /* clear then enable interrupts */ | ||
786 | |||
787 | #define STD_IRQ (IRQ_LCI | /* Link Change */ \ | ||
788 | IRQ_TXI | /* TX done */ \ | ||
789 | IRQ_RXI | /* RX done */ \ | ||
790 | IRQ_SPIBEI | /* SPI bus error */ \ | ||
791 | IRQ_TXPSI | /* TX process stop */ \ | ||
792 | IRQ_RXPSI) /* RX process stop */ | ||
793 | |||
794 | ks->rc_ier = STD_IRQ; | ||
795 | ks8851_wrreg16(ks, KS_ISR, STD_IRQ); | ||
796 | ks8851_wrreg16(ks, KS_IER, STD_IRQ); | ||
797 | |||
798 | netif_start_queue(ks->netdev); | ||
799 | |||
800 | if (netif_msg_ifup(ks)) | ||
801 | ks_dbg(ks, "network device %s up\n", dev->name); | ||
802 | |||
803 | mutex_unlock(&ks->lock); | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | /** | ||
808 | * ks8851_net_stop - close network device | ||
809 | * @dev: The device being closed. | ||
810 | * | ||
811 | * Called to close down a network device which has been active. Cancell any | ||
812 | * work, shutdown the RX and TX process and then place the chip into a low | ||
813 | * power state whilst it is not being used. | ||
814 | */ | ||
815 | static int ks8851_net_stop(struct net_device *dev) | ||
816 | { | ||
817 | struct ks8851_net *ks = netdev_priv(dev); | ||
818 | |||
819 | if (netif_msg_ifdown(ks)) | ||
820 | ks_info(ks, "%s: shutting down\n", dev->name); | ||
821 | |||
822 | netif_stop_queue(dev); | ||
823 | |||
824 | mutex_lock(&ks->lock); | ||
825 | |||
826 | /* stop any outstanding work */ | ||
827 | flush_work(&ks->irq_work); | ||
828 | flush_work(&ks->tx_work); | ||
829 | flush_work(&ks->rxctrl_work); | ||
830 | |||
831 | /* turn off the IRQs and ack any outstanding */ | ||
832 | ks8851_wrreg16(ks, KS_IER, 0x0000); | ||
833 | ks8851_wrreg16(ks, KS_ISR, 0xffff); | ||
834 | |||
835 | /* shutdown RX process */ | ||
836 | ks8851_wrreg16(ks, KS_RXCR1, 0x0000); | ||
837 | |||
838 | /* shutdown TX process */ | ||
839 | ks8851_wrreg16(ks, KS_TXCR, 0x0000); | ||
840 | |||
841 | /* set powermode to soft power down to save power */ | ||
842 | ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); | ||
843 | |||
844 | /* ensure any queued tx buffers are dumped */ | ||
845 | while (!skb_queue_empty(&ks->txq)) { | ||
846 | struct sk_buff *txb = skb_dequeue(&ks->txq); | ||
847 | |||
848 | if (netif_msg_ifdown(ks)) | ||
849 | ks_dbg(ks, "%s: freeing txb %p\n", __func__, txb); | ||
850 | |||
851 | dev_kfree_skb(txb); | ||
852 | } | ||
853 | |||
854 | mutex_unlock(&ks->lock); | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /** | ||
859 | * ks8851_start_xmit - transmit packet | ||
860 | * @skb: The buffer to transmit | ||
861 | * @dev: The device used to transmit the packet. | ||
862 | * | ||
863 | * Called by the network layer to transmit the @skb. Queue the packet for | ||
864 | * the device and schedule the necessary work to transmit the packet when | ||
865 | * it is free. | ||
866 | * | ||
867 | * We do this to firstly avoid sleeping with the network device locked, | ||
868 | * and secondly so we can round up more than one packet to transmit which | ||
869 | * means we can try and avoid generating too many transmit done interrupts. | ||
870 | */ | ||
871 | static int ks8851_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
872 | { | ||
873 | struct ks8851_net *ks = netdev_priv(dev); | ||
874 | unsigned needed = calc_txlen(skb->len); | ||
875 | int ret = NETDEV_TX_OK; | ||
876 | |||
877 | if (netif_msg_tx_queued(ks)) | ||
878 | ks_dbg(ks, "%s: skb %p, %d@%p\n", __func__, | ||
879 | skb, skb->len, skb->data); | ||
880 | |||
881 | spin_lock(&ks->statelock); | ||
882 | |||
883 | if (needed > ks->tx_space) { | ||
884 | netif_stop_queue(dev); | ||
885 | ret = NETDEV_TX_BUSY; | ||
886 | } else { | ||
887 | ks->tx_space -= needed; | ||
888 | skb_queue_tail(&ks->txq, skb); | ||
889 | } | ||
890 | |||
891 | spin_unlock(&ks->statelock); | ||
892 | schedule_work(&ks->tx_work); | ||
893 | |||
894 | return ret; | ||
895 | } | ||
896 | |||
897 | /** | ||
898 | * ks8851_rxctrl_work - work handler to change rx mode | ||
899 | * @work: The work structure this belongs to. | ||
900 | * | ||
901 | * Lock the device and issue the necessary changes to the receive mode from | ||
902 | * the network device layer. This is done so that we can do this without | ||
903 | * having to sleep whilst holding the network device lock. | ||
904 | * | ||
905 | * Since the recommendation from Micrel is that the RXQ is shutdown whilst the | ||
906 | * receive parameters are programmed, we issue a write to disable the RXQ and | ||
907 | * then wait for the interrupt handler to be triggered once the RXQ shutdown is | ||
908 | * complete. The interrupt handler then writes the new values into the chip. | ||
909 | */ | ||
910 | static void ks8851_rxctrl_work(struct work_struct *work) | ||
911 | { | ||
912 | struct ks8851_net *ks = container_of(work, struct ks8851_net, rxctrl_work); | ||
913 | |||
914 | mutex_lock(&ks->lock); | ||
915 | |||
916 | /* need to shutdown RXQ before modifying filter parameters */ | ||
917 | ks8851_wrreg16(ks, KS_RXCR1, 0x00); | ||
918 | |||
919 | mutex_unlock(&ks->lock); | ||
920 | } | ||
921 | |||
922 | static void ks8851_set_rx_mode(struct net_device *dev) | ||
923 | { | ||
924 | struct ks8851_net *ks = netdev_priv(dev); | ||
925 | struct ks8851_rxctrl rxctrl; | ||
926 | |||
927 | memset(&rxctrl, 0, sizeof(rxctrl)); | ||
928 | |||
929 | if (dev->flags & IFF_PROMISC) { | ||
930 | /* interface to receive everything */ | ||
931 | |||
932 | rxctrl.rxcr1 = RXCR1_RXAE | RXCR1_RXINVF; | ||
933 | } else if (dev->flags & IFF_ALLMULTI) { | ||
934 | /* accept all multicast packets */ | ||
935 | |||
936 | rxctrl.rxcr1 = (RXCR1_RXME | RXCR1_RXAE | | ||
937 | RXCR1_RXPAFMA | RXCR1_RXMAFMA); | ||
938 | } else if (dev->flags & IFF_MULTICAST && dev->mc_count > 0) { | ||
939 | struct dev_mc_list *mcptr = dev->mc_list; | ||
940 | u32 crc; | ||
941 | int i; | ||
942 | |||
943 | /* accept some multicast */ | ||
944 | |||
945 | for (i = dev->mc_count; i > 0; i--) { | ||
946 | crc = ether_crc(ETH_ALEN, mcptr->dmi_addr); | ||
947 | crc >>= (32 - 6); /* get top six bits */ | ||
948 | |||
949 | rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); | ||
950 | mcptr = mcptr->next; | ||
951 | } | ||
952 | |||
953 | rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA; | ||
954 | } else { | ||
955 | /* just accept broadcast / unicast */ | ||
956 | rxctrl.rxcr1 = RXCR1_RXPAFMA; | ||
957 | } | ||
958 | |||
959 | rxctrl.rxcr1 |= (RXCR1_RXUE | /* unicast enable */ | ||
960 | RXCR1_RXBE | /* broadcast enable */ | ||
961 | RXCR1_RXE | /* RX process enable */ | ||
962 | RXCR1_RXFCE); /* enable flow control */ | ||
963 | |||
964 | rxctrl.rxcr2 |= RXCR2_SRDBL_FRAME; | ||
965 | |||
966 | /* schedule work to do the actual set of the data if needed */ | ||
967 | |||
968 | spin_lock(&ks->statelock); | ||
969 | |||
970 | if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) { | ||
971 | memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl)); | ||
972 | schedule_work(&ks->rxctrl_work); | ||
973 | } | ||
974 | |||
975 | spin_unlock(&ks->statelock); | ||
976 | } | ||
977 | |||
978 | static int ks8851_set_mac_address(struct net_device *dev, void *addr) | ||
979 | { | ||
980 | struct sockaddr *sa = addr; | ||
981 | |||
982 | if (netif_running(dev)) | ||
983 | return -EBUSY; | ||
984 | |||
985 | if (!is_valid_ether_addr(sa->sa_data)) | ||
986 | return -EADDRNOTAVAIL; | ||
987 | |||
988 | memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); | ||
989 | return ks8851_write_mac_addr(dev); | ||
990 | } | ||
991 | |||
992 | static int ks8851_net_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
993 | { | ||
994 | struct ks8851_net *ks = netdev_priv(dev); | ||
995 | |||
996 | if (!netif_running(dev)) | ||
997 | return -EINVAL; | ||
998 | |||
999 | return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL); | ||
1000 | } | ||
1001 | |||
1002 | static const struct net_device_ops ks8851_netdev_ops = { | ||
1003 | .ndo_open = ks8851_net_open, | ||
1004 | .ndo_stop = ks8851_net_stop, | ||
1005 | .ndo_do_ioctl = ks8851_net_ioctl, | ||
1006 | .ndo_start_xmit = ks8851_start_xmit, | ||
1007 | .ndo_set_mac_address = ks8851_set_mac_address, | ||
1008 | .ndo_set_rx_mode = ks8851_set_rx_mode, | ||
1009 | .ndo_change_mtu = eth_change_mtu, | ||
1010 | .ndo_validate_addr = eth_validate_addr, | ||
1011 | }; | ||
1012 | |||
1013 | /* ethtool support */ | ||
1014 | |||
1015 | static void ks8851_get_drvinfo(struct net_device *dev, | ||
1016 | struct ethtool_drvinfo *di) | ||
1017 | { | ||
1018 | strlcpy(di->driver, "KS8851", sizeof(di->driver)); | ||
1019 | strlcpy(di->version, "1.00", sizeof(di->version)); | ||
1020 | strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); | ||
1021 | } | ||
1022 | |||
1023 | static u32 ks8851_get_msglevel(struct net_device *dev) | ||
1024 | { | ||
1025 | struct ks8851_net *ks = netdev_priv(dev); | ||
1026 | return ks->msg_enable; | ||
1027 | } | ||
1028 | |||
1029 | static void ks8851_set_msglevel(struct net_device *dev, u32 to) | ||
1030 | { | ||
1031 | struct ks8851_net *ks = netdev_priv(dev); | ||
1032 | ks->msg_enable = to; | ||
1033 | } | ||
1034 | |||
1035 | static int ks8851_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1036 | { | ||
1037 | struct ks8851_net *ks = netdev_priv(dev); | ||
1038 | return mii_ethtool_gset(&ks->mii, cmd); | ||
1039 | } | ||
1040 | |||
1041 | static int ks8851_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1042 | { | ||
1043 | struct ks8851_net *ks = netdev_priv(dev); | ||
1044 | return mii_ethtool_sset(&ks->mii, cmd); | ||
1045 | } | ||
1046 | |||
1047 | static u32 ks8851_get_link(struct net_device *dev) | ||
1048 | { | ||
1049 | struct ks8851_net *ks = netdev_priv(dev); | ||
1050 | return mii_link_ok(&ks->mii); | ||
1051 | } | ||
1052 | |||
1053 | static int ks8851_nway_reset(struct net_device *dev) | ||
1054 | { | ||
1055 | struct ks8851_net *ks = netdev_priv(dev); | ||
1056 | return mii_nway_restart(&ks->mii); | ||
1057 | } | ||
1058 | |||
1059 | static const struct ethtool_ops ks8851_ethtool_ops = { | ||
1060 | .get_drvinfo = ks8851_get_drvinfo, | ||
1061 | .get_msglevel = ks8851_get_msglevel, | ||
1062 | .set_msglevel = ks8851_set_msglevel, | ||
1063 | .get_settings = ks8851_get_settings, | ||
1064 | .set_settings = ks8851_set_settings, | ||
1065 | .get_link = ks8851_get_link, | ||
1066 | .nway_reset = ks8851_nway_reset, | ||
1067 | }; | ||
1068 | |||
1069 | /* MII interface controls */ | ||
1070 | |||
1071 | /** | ||
1072 | * ks8851_phy_reg - convert MII register into a KS8851 register | ||
1073 | * @reg: MII register number. | ||
1074 | * | ||
1075 | * Return the KS8851 register number for the corresponding MII PHY register | ||
1076 | * if possible. Return zero if the MII register has no direct mapping to the | ||
1077 | * KS8851 register set. | ||
1078 | */ | ||
1079 | static int ks8851_phy_reg(int reg) | ||
1080 | { | ||
1081 | switch (reg) { | ||
1082 | case MII_BMCR: | ||
1083 | return KS_P1MBCR; | ||
1084 | case MII_BMSR: | ||
1085 | return KS_P1MBSR; | ||
1086 | case MII_PHYSID1: | ||
1087 | return KS_PHY1ILR; | ||
1088 | case MII_PHYSID2: | ||
1089 | return KS_PHY1IHR; | ||
1090 | case MII_ADVERTISE: | ||
1091 | return KS_P1ANAR; | ||
1092 | case MII_LPA: | ||
1093 | return KS_P1ANLPR; | ||
1094 | } | ||
1095 | |||
1096 | return 0x0; | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * ks8851_phy_read - MII interface PHY register read. | ||
1101 | * @dev: The network device the PHY is on. | ||
1102 | * @phy_addr: Address of PHY (ignored as we only have one) | ||
1103 | * @reg: The register to read. | ||
1104 | * | ||
1105 | * This call reads data from the PHY register specified in @reg. Since the | ||
1106 | * device does not support all the MII registers, the non-existant values | ||
1107 | * are always returned as zero. | ||
1108 | * | ||
1109 | * We return zero for unsupported registers as the MII code does not check | ||
1110 | * the value returned for any error status, and simply returns it to the | ||
1111 | * caller. The mii-tool that the driver was tested with takes any -ve error | ||
1112 | * as real PHY capabilities, thus displaying incorrect data to the user. | ||
1113 | */ | ||
1114 | static int ks8851_phy_read(struct net_device *dev, int phy_addr, int reg) | ||
1115 | { | ||
1116 | struct ks8851_net *ks = netdev_priv(dev); | ||
1117 | int ksreg; | ||
1118 | int result; | ||
1119 | |||
1120 | ksreg = ks8851_phy_reg(reg); | ||
1121 | if (!ksreg) | ||
1122 | return 0x0; /* no error return allowed, so use zero */ | ||
1123 | |||
1124 | mutex_lock(&ks->lock); | ||
1125 | result = ks8851_rdreg16(ks, ksreg); | ||
1126 | mutex_unlock(&ks->lock); | ||
1127 | |||
1128 | return result; | ||
1129 | } | ||
1130 | |||
1131 | static void ks8851_phy_write(struct net_device *dev, | ||
1132 | int phy, int reg, int value) | ||
1133 | { | ||
1134 | struct ks8851_net *ks = netdev_priv(dev); | ||
1135 | int ksreg; | ||
1136 | |||
1137 | ksreg = ks8851_phy_reg(reg); | ||
1138 | if (ksreg) { | ||
1139 | mutex_lock(&ks->lock); | ||
1140 | ks8851_wrreg16(ks, ksreg, value); | ||
1141 | mutex_unlock(&ks->lock); | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1146 | * ks8851_read_selftest - read the selftest memory info. | ||
1147 | * @ks: The device state | ||
1148 | * | ||
1149 | * Read and check the TX/RX memory selftest information. | ||
1150 | */ | ||
1151 | static int ks8851_read_selftest(struct ks8851_net *ks) | ||
1152 | { | ||
1153 | unsigned both_done = MBIR_TXMBF | MBIR_RXMBF; | ||
1154 | int ret = 0; | ||
1155 | unsigned rd; | ||
1156 | |||
1157 | rd = ks8851_rdreg16(ks, KS_MBIR); | ||
1158 | |||
1159 | if ((rd & both_done) != both_done) { | ||
1160 | ks_warn(ks, "Memory selftest not finished\n"); | ||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | if (rd & MBIR_TXMBFA) { | ||
1165 | ks_err(ks, "TX memory selftest fail\n"); | ||
1166 | ret |= 1; | ||
1167 | } | ||
1168 | |||
1169 | if (rd & MBIR_RXMBFA) { | ||
1170 | ks_err(ks, "RX memory selftest fail\n"); | ||
1171 | ret |= 2; | ||
1172 | } | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | /* driver bus management functions */ | ||
1178 | |||
1179 | static int __devinit ks8851_probe(struct spi_device *spi) | ||
1180 | { | ||
1181 | struct net_device *ndev; | ||
1182 | struct ks8851_net *ks; | ||
1183 | int ret; | ||
1184 | |||
1185 | ndev = alloc_etherdev(sizeof(struct ks8851_net)); | ||
1186 | if (!ndev) { | ||
1187 | dev_err(&spi->dev, "failed to alloc ethernet device\n"); | ||
1188 | return -ENOMEM; | ||
1189 | } | ||
1190 | |||
1191 | spi->bits_per_word = 8; | ||
1192 | |||
1193 | ks = netdev_priv(ndev); | ||
1194 | |||
1195 | ks->netdev = ndev; | ||
1196 | ks->spidev = spi; | ||
1197 | ks->tx_space = 6144; | ||
1198 | |||
1199 | mutex_init(&ks->lock); | ||
1200 | spin_lock_init(&ks->statelock); | ||
1201 | |||
1202 | INIT_WORK(&ks->tx_work, ks8851_tx_work); | ||
1203 | INIT_WORK(&ks->irq_work, ks8851_irq_work); | ||
1204 | INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); | ||
1205 | |||
1206 | /* initialise pre-made spi transfer messages */ | ||
1207 | |||
1208 | spi_message_init(&ks->spi_msg1); | ||
1209 | spi_message_add_tail(&ks->spi_xfer1, &ks->spi_msg1); | ||
1210 | |||
1211 | spi_message_init(&ks->spi_msg2); | ||
1212 | spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2); | ||
1213 | spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2); | ||
1214 | |||
1215 | /* setup mii state */ | ||
1216 | ks->mii.dev = ndev; | ||
1217 | ks->mii.phy_id = 1, | ||
1218 | ks->mii.phy_id_mask = 1; | ||
1219 | ks->mii.reg_num_mask = 0xf; | ||
1220 | ks->mii.mdio_read = ks8851_phy_read; | ||
1221 | ks->mii.mdio_write = ks8851_phy_write; | ||
1222 | |||
1223 | dev_info(&spi->dev, "message enable is %d\n", msg_enable); | ||
1224 | |||
1225 | /* set the default message enable */ | ||
1226 | ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | | ||
1227 | NETIF_MSG_PROBE | | ||
1228 | NETIF_MSG_LINK)); | ||
1229 | |||
1230 | skb_queue_head_init(&ks->txq); | ||
1231 | |||
1232 | SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops); | ||
1233 | SET_NETDEV_DEV(ndev, &spi->dev); | ||
1234 | |||
1235 | dev_set_drvdata(&spi->dev, ks); | ||
1236 | |||
1237 | ndev->if_port = IF_PORT_100BASET; | ||
1238 | ndev->netdev_ops = &ks8851_netdev_ops; | ||
1239 | ndev->irq = spi->irq; | ||
1240 | |||
1241 | /* simple check for a valid chip being connected to the bus */ | ||
1242 | |||
1243 | if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { | ||
1244 | dev_err(&spi->dev, "failed to read device ID\n"); | ||
1245 | ret = -ENODEV; | ||
1246 | goto err_id; | ||
1247 | } | ||
1248 | |||
1249 | ks8851_read_selftest(ks); | ||
1250 | ks8851_init_mac(ks); | ||
1251 | |||
1252 | ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW, | ||
1253 | ndev->name, ks); | ||
1254 | if (ret < 0) { | ||
1255 | dev_err(&spi->dev, "failed to get irq\n"); | ||
1256 | goto err_irq; | ||
1257 | } | ||
1258 | |||
1259 | ret = register_netdev(ndev); | ||
1260 | if (ret) { | ||
1261 | dev_err(&spi->dev, "failed to register network device\n"); | ||
1262 | goto err_netdev; | ||
1263 | } | ||
1264 | |||
1265 | dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d\n", | ||
1266 | CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), | ||
1267 | ndev->dev_addr, ndev->irq); | ||
1268 | |||
1269 | return 0; | ||
1270 | |||
1271 | |||
1272 | err_netdev: | ||
1273 | free_irq(ndev->irq, ndev); | ||
1274 | |||
1275 | err_id: | ||
1276 | err_irq: | ||
1277 | free_netdev(ndev); | ||
1278 | return ret; | ||
1279 | } | ||
1280 | |||
1281 | static int __devexit ks8851_remove(struct spi_device *spi) | ||
1282 | { | ||
1283 | struct ks8851_net *priv = dev_get_drvdata(&spi->dev); | ||
1284 | |||
1285 | if (netif_msg_drv(priv)) | ||
1286 | dev_info(&spi->dev, "remove"); | ||
1287 | |||
1288 | unregister_netdev(priv->netdev); | ||
1289 | free_irq(spi->irq, priv); | ||
1290 | free_netdev(priv->netdev); | ||
1291 | |||
1292 | return 0; | ||
1293 | } | ||
1294 | |||
1295 | static struct spi_driver ks8851_driver = { | ||
1296 | .driver = { | ||
1297 | .name = "ks8851", | ||
1298 | .owner = THIS_MODULE, | ||
1299 | }, | ||
1300 | .probe = ks8851_probe, | ||
1301 | .remove = __devexit_p(ks8851_remove), | ||
1302 | }; | ||
1303 | |||
1304 | static int __init ks8851_init(void) | ||
1305 | { | ||
1306 | return spi_register_driver(&ks8851_driver); | ||
1307 | } | ||
1308 | |||
1309 | static void __exit ks8851_exit(void) | ||
1310 | { | ||
1311 | spi_unregister_driver(&ks8851_driver); | ||
1312 | } | ||
1313 | |||
1314 | module_init(ks8851_init); | ||
1315 | module_exit(ks8851_exit); | ||
1316 | |||
1317 | MODULE_DESCRIPTION("KS8851 Network driver"); | ||
1318 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
1319 | MODULE_LICENSE("GPL"); | ||
1320 | |||
1321 | module_param_named(message, msg_enable, int, 0); | ||
1322 | MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); | ||
diff --git a/drivers/net/ks8851.h b/drivers/net/ks8851.h new file mode 100644 index 000000000000..85abe147afbf --- /dev/null +++ b/drivers/net/ks8851.h | |||
@@ -0,0 +1,296 @@ | |||
1 | /* drivers/net/ks8851.h | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * KS8851 register definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #define KS_CCR 0x08 | ||
14 | #define CCR_EEPROM (1 << 9) | ||
15 | #define CCR_SPI (1 << 8) | ||
16 | #define CCR_32PIN (1 << 0) | ||
17 | |||
18 | /* MAC address registers */ | ||
19 | #define KS_MARL 0x10 | ||
20 | #define KS_MARM 0x12 | ||
21 | #define KS_MARH 0x14 | ||
22 | |||
23 | #define KS_OBCR 0x20 | ||
24 | #define OBCR_ODS_16mA (1 << 6) | ||
25 | |||
26 | #define KS_EEPCR 0x22 | ||
27 | #define EEPCR_EESA (1 << 4) | ||
28 | #define EEPCR_EESB (1 << 3) | ||
29 | #define EEPCR_EEDO (1 << 2) | ||
30 | #define EEPCR_EESCK (1 << 1) | ||
31 | #define EEPCR_EECS (1 << 0) | ||
32 | |||
33 | #define KS_MBIR 0x24 | ||
34 | #define MBIR_TXMBF (1 << 12) | ||
35 | #define MBIR_TXMBFA (1 << 11) | ||
36 | #define MBIR_RXMBF (1 << 4) | ||
37 | #define MBIR_RXMBFA (1 << 3) | ||
38 | |||
39 | #define KS_GRR 0x26 | ||
40 | #define GRR_QMU (1 << 1) | ||
41 | #define GRR_GSR (1 << 0) | ||
42 | |||
43 | #define KS_WFCR 0x2A | ||
44 | #define WFCR_MPRXE (1 << 7) | ||
45 | #define WFCR_WF3E (1 << 3) | ||
46 | #define WFCR_WF2E (1 << 2) | ||
47 | #define WFCR_WF1E (1 << 1) | ||
48 | #define WFCR_WF0E (1 << 0) | ||
49 | |||
50 | #define KS_WF0CRC0 0x30 | ||
51 | #define KS_WF0CRC1 0x32 | ||
52 | #define KS_WF0BM0 0x34 | ||
53 | #define KS_WF0BM1 0x36 | ||
54 | #define KS_WF0BM2 0x38 | ||
55 | #define KS_WF0BM3 0x3A | ||
56 | |||
57 | #define KS_WF1CRC0 0x40 | ||
58 | #define KS_WF1CRC1 0x42 | ||
59 | #define KS_WF1BM0 0x44 | ||
60 | #define KS_WF1BM1 0x46 | ||
61 | #define KS_WF1BM2 0x48 | ||
62 | #define KS_WF1BM3 0x4A | ||
63 | |||
64 | #define KS_WF2CRC0 0x50 | ||
65 | #define KS_WF2CRC1 0x52 | ||
66 | #define KS_WF2BM0 0x54 | ||
67 | #define KS_WF2BM1 0x56 | ||
68 | #define KS_WF2BM2 0x58 | ||
69 | #define KS_WF2BM3 0x5A | ||
70 | |||
71 | #define KS_WF3CRC0 0x60 | ||
72 | #define KS_WF3CRC1 0x62 | ||
73 | #define KS_WF3BM0 0x64 | ||
74 | #define KS_WF3BM1 0x66 | ||
75 | #define KS_WF3BM2 0x68 | ||
76 | #define KS_WF3BM3 0x6A | ||
77 | |||
78 | #define KS_TXCR 0x70 | ||
79 | #define TXCR_TCGICMP (1 << 8) | ||
80 | #define TXCR_TCGUDP (1 << 7) | ||
81 | #define TXCR_TCGTCP (1 << 6) | ||
82 | #define TXCR_TCGIP (1 << 5) | ||
83 | #define TXCR_FTXQ (1 << 4) | ||
84 | #define TXCR_TXFCE (1 << 3) | ||
85 | #define TXCR_TXPE (1 << 2) | ||
86 | #define TXCR_TXCRC (1 << 1) | ||
87 | #define TXCR_TXE (1 << 0) | ||
88 | |||
89 | #define KS_TXSR 0x72 | ||
90 | #define TXSR_TXLC (1 << 13) | ||
91 | #define TXSR_TXMC (1 << 12) | ||
92 | #define TXSR_TXFID_MASK (0x3f << 0) | ||
93 | #define TXSR_TXFID_SHIFT (0) | ||
94 | #define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) | ||
95 | |||
96 | #define KS_RXCR1 0x74 | ||
97 | #define RXCR1_FRXQ (1 << 15) | ||
98 | #define RXCR1_RXUDPFCC (1 << 14) | ||
99 | #define RXCR1_RXTCPFCC (1 << 13) | ||
100 | #define RXCR1_RXIPFCC (1 << 12) | ||
101 | #define RXCR1_RXPAFMA (1 << 11) | ||
102 | #define RXCR1_RXFCE (1 << 10) | ||
103 | #define RXCR1_RXEFE (1 << 9) | ||
104 | #define RXCR1_RXMAFMA (1 << 8) | ||
105 | #define RXCR1_RXBE (1 << 7) | ||
106 | #define RXCR1_RXME (1 << 6) | ||
107 | #define RXCR1_RXUE (1 << 5) | ||
108 | #define RXCR1_RXAE (1 << 4) | ||
109 | #define RXCR1_RXINVF (1 << 1) | ||
110 | #define RXCR1_RXE (1 << 0) | ||
111 | |||
112 | #define KS_RXCR2 0x76 | ||
113 | #define RXCR2_SRDBL_MASK (0x7 << 5) | ||
114 | #define RXCR2_SRDBL_SHIFT (5) | ||
115 | #define RXCR2_SRDBL_4B (0x0 << 5) | ||
116 | #define RXCR2_SRDBL_8B (0x1 << 5) | ||
117 | #define RXCR2_SRDBL_16B (0x2 << 5) | ||
118 | #define RXCR2_SRDBL_32B (0x3 << 5) | ||
119 | #define RXCR2_SRDBL_FRAME (0x4 << 5) | ||
120 | #define RXCR2_IUFFP (1 << 4) | ||
121 | #define RXCR2_RXIUFCEZ (1 << 3) | ||
122 | #define RXCR2_UDPLFE (1 << 2) | ||
123 | #define RXCR2_RXICMPFCC (1 << 1) | ||
124 | #define RXCR2_RXSAF (1 << 0) | ||
125 | |||
126 | #define KS_TXMIR 0x78 | ||
127 | |||
128 | #define KS_RXFHSR 0x7C | ||
129 | #define RXFSHR_RXFV (1 << 15) | ||
130 | #define RXFSHR_RXICMPFCS (1 << 13) | ||
131 | #define RXFSHR_RXIPFCS (1 << 12) | ||
132 | #define RXFSHR_RXTCPFCS (1 << 11) | ||
133 | #define RXFSHR_RXUDPFCS (1 << 10) | ||
134 | #define RXFSHR_RXBF (1 << 7) | ||
135 | #define RXFSHR_RXMF (1 << 6) | ||
136 | #define RXFSHR_RXUF (1 << 5) | ||
137 | #define RXFSHR_RXMR (1 << 4) | ||
138 | #define RXFSHR_RXFT (1 << 3) | ||
139 | #define RXFSHR_RXFTL (1 << 2) | ||
140 | #define RXFSHR_RXRF (1 << 1) | ||
141 | #define RXFSHR_RXCE (1 << 0) | ||
142 | |||
143 | #define KS_RXFHBCR 0x7E | ||
144 | #define KS_TXQCR 0x80 | ||
145 | #define TXQCR_AETFE (1 << 2) | ||
146 | #define TXQCR_TXQMAM (1 << 1) | ||
147 | #define TXQCR_METFE (1 << 0) | ||
148 | |||
149 | #define KS_RXQCR 0x82 | ||
150 | #define RXQCR_RXDTTS (1 << 12) | ||
151 | #define RXQCR_RXDBCTS (1 << 11) | ||
152 | #define RXQCR_RXFCTS (1 << 10) | ||
153 | #define RXQCR_RXIPHTOE (1 << 9) | ||
154 | #define RXQCR_RXDTTE (1 << 7) | ||
155 | #define RXQCR_RXDBCTE (1 << 6) | ||
156 | #define RXQCR_RXFCTE (1 << 5) | ||
157 | #define RXQCR_ADRFE (1 << 4) | ||
158 | #define RXQCR_SDA (1 << 3) | ||
159 | #define RXQCR_RRXEF (1 << 0) | ||
160 | |||
161 | #define KS_TXFDPR 0x84 | ||
162 | #define TXFDPR_TXFPAI (1 << 14) | ||
163 | #define TXFDPR_TXFP_MASK (0x7ff << 0) | ||
164 | #define TXFDPR_TXFP_SHIFT (0) | ||
165 | |||
166 | #define KS_RXFDPR 0x86 | ||
167 | #define RXFDPR_RXFPAI (1 << 14) | ||
168 | |||
169 | #define KS_RXDTTR 0x8C | ||
170 | #define KS_RXDBCTR 0x8E | ||
171 | |||
172 | #define KS_IER 0x90 | ||
173 | #define KS_ISR 0x92 | ||
174 | #define IRQ_LCI (1 << 15) | ||
175 | #define IRQ_TXI (1 << 14) | ||
176 | #define IRQ_RXI (1 << 13) | ||
177 | #define IRQ_RXOI (1 << 11) | ||
178 | #define IRQ_TXPSI (1 << 9) | ||
179 | #define IRQ_RXPSI (1 << 8) | ||
180 | #define IRQ_TXSAI (1 << 6) | ||
181 | #define IRQ_RXWFDI (1 << 5) | ||
182 | #define IRQ_RXMPDI (1 << 4) | ||
183 | #define IRQ_LDI (1 << 3) | ||
184 | #define IRQ_EDI (1 << 2) | ||
185 | #define IRQ_SPIBEI (1 << 1) | ||
186 | #define IRQ_DEDI (1 << 0) | ||
187 | |||
188 | #define KS_RXFCTR 0x9C | ||
189 | #define KS_RXFC 0x9D | ||
190 | #define RXFCTR_RXFC_MASK (0xff << 8) | ||
191 | #define RXFCTR_RXFC_SHIFT (8) | ||
192 | #define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) | ||
193 | #define RXFCTR_RXFCT_MASK (0xff << 0) | ||
194 | #define RXFCTR_RXFCT_SHIFT (0) | ||
195 | |||
196 | #define KS_TXNTFSR 0x9E | ||
197 | |||
198 | #define KS_MAHTR0 0xA0 | ||
199 | #define KS_MAHTR1 0xA2 | ||
200 | #define KS_MAHTR2 0xA4 | ||
201 | #define KS_MAHTR3 0xA6 | ||
202 | |||
203 | #define KS_FCLWR 0xB0 | ||
204 | #define KS_FCHWR 0xB2 | ||
205 | #define KS_FCOWR 0xB4 | ||
206 | |||
207 | #define KS_CIDER 0xC0 | ||
208 | #define CIDER_ID 0x8870 | ||
209 | #define CIDER_REV_MASK (0x7 << 1) | ||
210 | #define CIDER_REV_SHIFT (1) | ||
211 | #define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) | ||
212 | |||
213 | #define KS_CGCR 0xC6 | ||
214 | |||
215 | #define KS_IACR 0xC8 | ||
216 | #define IACR_RDEN (1 << 12) | ||
217 | #define IACR_TSEL_MASK (0x3 << 10) | ||
218 | #define IACR_TSEL_SHIFT (10) | ||
219 | #define IACR_TSEL_MIB (0x3 << 10) | ||
220 | #define IACR_ADDR_MASK (0x1f << 0) | ||
221 | #define IACR_ADDR_SHIFT (0) | ||
222 | |||
223 | #define KS_IADLR 0xD0 | ||
224 | #define KS_IAHDR 0xD2 | ||
225 | |||
226 | #define KS_PMECR 0xD4 | ||
227 | #define PMECR_PME_DELAY (1 << 14) | ||
228 | #define PMECR_PME_POL (1 << 12) | ||
229 | #define PMECR_WOL_WAKEUP (1 << 11) | ||
230 | #define PMECR_WOL_MAGICPKT (1 << 10) | ||
231 | #define PMECR_WOL_LINKUP (1 << 9) | ||
232 | #define PMECR_WOL_ENERGY (1 << 8) | ||
233 | #define PMECR_AUTO_WAKE_EN (1 << 7) | ||
234 | #define PMECR_WAKEUP_NORMAL (1 << 6) | ||
235 | #define PMECR_WKEVT_MASK (0xf << 2) | ||
236 | #define PMECR_WKEVT_SHIFT (2) | ||
237 | #define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) | ||
238 | #define PMECR_WKEVT_ENERGY (0x1 << 2) | ||
239 | #define PMECR_WKEVT_LINK (0x2 << 2) | ||
240 | #define PMECR_WKEVT_MAGICPKT (0x4 << 2) | ||
241 | #define PMECR_WKEVT_FRAME (0x8 << 2) | ||
242 | #define PMECR_PM_MASK (0x3 << 0) | ||
243 | #define PMECR_PM_SHIFT (0) | ||
244 | #define PMECR_PM_NORMAL (0x0 << 0) | ||
245 | #define PMECR_PM_ENERGY (0x1 << 0) | ||
246 | #define PMECR_PM_SOFTDOWN (0x2 << 0) | ||
247 | #define PMECR_PM_POWERSAVE (0x3 << 0) | ||
248 | |||
249 | /* Standard MII PHY data */ | ||
250 | #define KS_P1MBCR 0xE4 | ||
251 | #define KS_P1MBSR 0xE6 | ||
252 | #define KS_PHY1ILR 0xE8 | ||
253 | #define KS_PHY1IHR 0xEA | ||
254 | #define KS_P1ANAR 0xEC | ||
255 | #define KS_P1ANLPR 0xEE | ||
256 | |||
257 | #define KS_P1SCLMD 0xF4 | ||
258 | #define P1SCLMD_LEDOFF (1 << 15) | ||
259 | #define P1SCLMD_TXIDS (1 << 14) | ||
260 | #define P1SCLMD_RESTARTAN (1 << 13) | ||
261 | #define P1SCLMD_DISAUTOMDIX (1 << 10) | ||
262 | #define P1SCLMD_FORCEMDIX (1 << 9) | ||
263 | #define P1SCLMD_AUTONEGEN (1 << 7) | ||
264 | #define P1SCLMD_FORCE100 (1 << 6) | ||
265 | #define P1SCLMD_FORCEFDX (1 << 5) | ||
266 | #define P1SCLMD_ADV_FLOW (1 << 4) | ||
267 | #define P1SCLMD_ADV_100BT_FDX (1 << 3) | ||
268 | #define P1SCLMD_ADV_100BT_HDX (1 << 2) | ||
269 | #define P1SCLMD_ADV_10BT_FDX (1 << 1) | ||
270 | #define P1SCLMD_ADV_10BT_HDX (1 << 0) | ||
271 | |||
272 | #define KS_P1CR 0xF6 | ||
273 | #define P1CR_HP_MDIX (1 << 15) | ||
274 | #define P1CR_REV_POL (1 << 13) | ||
275 | #define P1CR_OP_100M (1 << 10) | ||
276 | #define P1CR_OP_FDX (1 << 9) | ||
277 | #define P1CR_OP_MDI (1 << 7) | ||
278 | #define P1CR_AN_DONE (1 << 6) | ||
279 | #define P1CR_LINK_GOOD (1 << 5) | ||
280 | #define P1CR_PNTR_FLOW (1 << 4) | ||
281 | #define P1CR_PNTR_100BT_FDX (1 << 3) | ||
282 | #define P1CR_PNTR_100BT_HDX (1 << 2) | ||
283 | #define P1CR_PNTR_10BT_FDX (1 << 1) | ||
284 | #define P1CR_PNTR_10BT_HDX (1 << 0) | ||
285 | |||
286 | /* TX Frame control */ | ||
287 | |||
288 | #define TXFR_TXIC (1 << 15) | ||
289 | #define TXFR_TXFID_MASK (0x3f << 0) | ||
290 | #define TXFR_TXFID_SHIFT (0) | ||
291 | |||
292 | /* SPI frame opcodes */ | ||
293 | #define KS_SPIOP_RD (0x00) | ||
294 | #define KS_SPIOP_WR (0x40) | ||
295 | #define KS_SPIOP_RXFIFO (0x80) | ||
296 | #define KS_SPIOP_TXFIFO (0xC0) | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 8f492c7b8093..61eabcac734c 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -575,6 +575,7 @@ static int __devinit mac_sonic_probe(struct platform_device *pdev) | |||
575 | lp = netdev_priv(dev); | 575 | lp = netdev_priv(dev); |
576 | lp->device = &pdev->dev; | 576 | lp->device = &pdev->dev; |
577 | SET_NETDEV_DEV(dev, &pdev->dev); | 577 | SET_NETDEV_DEV(dev, &pdev->dev); |
578 | platform_set_drvdata(pdev, dev); | ||
578 | 579 | ||
579 | /* This will catch fatal stuff like -ENOMEM as well as success */ | 580 | /* This will catch fatal stuff like -ENOMEM as well as success */ |
580 | err = mac_onboard_sonic_probe(dev); | 581 | err = mac_onboard_sonic_probe(dev); |
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 091f99052c91..86467b444ac6 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c | |||
@@ -220,7 +220,7 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
220 | { | 220 | { |
221 | cmd->autoneg = AUTONEG_DISABLE; | 221 | cmd->autoneg = AUTONEG_DISABLE; |
222 | cmd->supported = SUPPORTED_10000baseT_Full; | 222 | cmd->supported = SUPPORTED_10000baseT_Full; |
223 | cmd->advertising = SUPPORTED_10000baseT_Full; | 223 | cmd->advertising = ADVERTISED_1000baseT_Full; |
224 | if (netif_carrier_ok(dev)) { | 224 | if (netif_carrier_ok(dev)) { |
225 | cmd->speed = SPEED_10000; | 225 | cmd->speed = SPEED_10000; |
226 | cmd->duplex = DUPLEX_FULL; | 226 | cmd->duplex = DUPLEX_FULL; |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e1cdba752e09..f86e05047d19 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -210,6 +210,7 @@ | |||
210 | #define NETXEN_CTX_SIGNATURE 0xdee0 | 210 | #define NETXEN_CTX_SIGNATURE 0xdee0 |
211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 | 211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 |
212 | #define NETXEN_CTX_RESET 0xbad0 | 212 | #define NETXEN_CTX_RESET 0xbad0 |
213 | #define NETXEN_CTX_D3_RESET 0xacc0 | ||
213 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) | 214 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) |
214 | 215 | ||
215 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 | 216 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 |
@@ -773,6 +774,8 @@ struct nx_host_tx_ring { | |||
773 | u32 crb_cmd_consumer; | 774 | u32 crb_cmd_consumer; |
774 | u32 num_desc; | 775 | u32 num_desc; |
775 | 776 | ||
777 | struct netdev_queue *txq; | ||
778 | |||
776 | struct netxen_cmd_buffer *cmd_buf_arr; | 779 | struct netxen_cmd_buffer *cmd_buf_arr; |
777 | struct cmd_desc_type0 *desc_head; | 780 | struct cmd_desc_type0 *desc_head; |
778 | dma_addr_t phys_addr; | 781 | dma_addr_t phys_addr; |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 4754f5cffad0..9f8ae4719e2f 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -684,10 +684,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
684 | goto err_out_free; | 684 | goto err_out_free; |
685 | } else { | 685 | } else { |
686 | err = netxen_init_old_ctx(adapter); | 686 | err = netxen_init_old_ctx(adapter); |
687 | if (err) { | 687 | if (err) |
688 | netxen_free_hw_resources(adapter); | 688 | goto err_out_free; |
689 | return err; | ||
690 | } | ||
691 | } | 689 | } |
692 | 690 | ||
693 | return 0; | 691 | return 0; |
@@ -708,15 +706,18 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) | |||
708 | int port = adapter->portnum; | 706 | int port = adapter->portnum; |
709 | 707 | ||
710 | if (adapter->fw_major >= 4) { | 708 | if (adapter->fw_major >= 4) { |
711 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
712 | nx_fw_cmd_destroy_rx_ctx(adapter); | 709 | nx_fw_cmd_destroy_rx_ctx(adapter); |
710 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
713 | } else { | 711 | } else { |
714 | netxen_api_lock(adapter); | 712 | netxen_api_lock(adapter); |
715 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), | 713 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), |
716 | NETXEN_CTX_RESET | port); | 714 | NETXEN_CTX_D3_RESET | port); |
717 | netxen_api_unlock(adapter); | 715 | netxen_api_unlock(adapter); |
718 | } | 716 | } |
719 | 717 | ||
718 | /* Allow dma queues to drain after context reset */ | ||
719 | msleep(20); | ||
720 | |||
720 | recv_ctx = &adapter->recv_ctx; | 721 | recv_ctx = &adapter->recv_ctx; |
721 | 722 | ||
722 | if (recv_ctx->hwctx != NULL) { | 723 | if (recv_ctx->hwctx != NULL) { |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index ce3b89d2cbb6..b9123d445c96 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -461,13 +461,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
461 | i = 0; | 461 | i = 0; |
462 | 462 | ||
463 | tx_ring = adapter->tx_ring; | 463 | tx_ring = adapter->tx_ring; |
464 | netif_tx_lock_bh(adapter->netdev); | 464 | __netif_tx_lock_bh(tx_ring->txq); |
465 | 465 | ||
466 | producer = tx_ring->producer; | 466 | producer = tx_ring->producer; |
467 | consumer = tx_ring->sw_consumer; | 467 | consumer = tx_ring->sw_consumer; |
468 | 468 | ||
469 | if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) { | 469 | if (nr_desc >= netxen_tx_avail(tx_ring)) { |
470 | netif_tx_unlock_bh(adapter->netdev); | 470 | netif_tx_stop_queue(tx_ring->txq); |
471 | __netif_tx_unlock_bh(tx_ring->txq); | ||
471 | return -EBUSY; | 472 | return -EBUSY; |
472 | } | 473 | } |
473 | 474 | ||
@@ -490,7 +491,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
490 | 491 | ||
491 | netxen_nic_update_cmd_producer(adapter, tx_ring); | 492 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
492 | 493 | ||
493 | netif_tx_unlock_bh(adapter->netdev); | 494 | __netif_tx_unlock_bh(tx_ring->txq); |
494 | 495 | ||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index b899bd51fcd8..5d3343ef3d86 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -214,6 +214,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | |||
214 | adapter->tx_ring = tx_ring; | 214 | adapter->tx_ring = tx_ring; |
215 | 215 | ||
216 | tx_ring->num_desc = adapter->num_txd; | 216 | tx_ring->num_desc = adapter->num_txd; |
217 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); | ||
217 | 218 | ||
218 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); | 219 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); |
219 | if (cmd_buf_arr == NULL) { | 220 | if (cmd_buf_arr == NULL) { |
@@ -1400,10 +1401,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1400 | smp_mb(); | 1401 | smp_mb(); |
1401 | 1402 | ||
1402 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1403 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1403 | netif_tx_lock(netdev); | 1404 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); |
1404 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) | 1405 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
1405 | netif_wake_queue(netdev); | 1406 | netif_wake_queue(netdev); |
1406 | netif_tx_unlock(netdev); | 1407 | __netif_tx_unlock(tx_ring->txq); |
1407 | } | 1408 | } |
1408 | } | 1409 | } |
1409 | /* | 1410 | /* |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 27539ddf94c4..637ac8b89bac 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -215,9 +215,9 @@ netxen_napi_disable(struct netxen_adapter *adapter) | |||
215 | 215 | ||
216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
217 | sds_ring = &recv_ctx->sds_rings[ring]; | 217 | sds_ring = &recv_ctx->sds_rings[ring]; |
218 | napi_disable(&sds_ring->napi); | ||
219 | netxen_nic_disable_int(sds_ring); | 218 | netxen_nic_disable_int(sds_ring); |
220 | synchronize_irq(sds_ring->irq); | 219 | napi_synchronize(&sds_ring->napi); |
220 | napi_disable(&sds_ring->napi); | ||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
@@ -833,11 +833,11 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
833 | 833 | ||
834 | adapter->ahw.linkup = 0; | 834 | adapter->ahw.linkup = 0; |
835 | 835 | ||
836 | netxen_napi_enable(adapter); | ||
837 | |||
838 | if (adapter->max_sds_rings > 1) | 836 | if (adapter->max_sds_rings > 1) |
839 | netxen_config_rss(adapter, 1); | 837 | netxen_config_rss(adapter, 1); |
840 | 838 | ||
839 | netxen_napi_enable(adapter); | ||
840 | |||
841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) | 841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) |
842 | netxen_linkevent_request(adapter, 1); | 842 | netxen_linkevent_request(adapter, 1); |
843 | else | 843 | else |
@@ -851,8 +851,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
851 | static void | 851 | static void |
852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
853 | { | 853 | { |
854 | spin_lock(&adapter->tx_clean_lock); | ||
854 | netif_carrier_off(netdev); | 855 | netif_carrier_off(netdev); |
855 | netif_stop_queue(netdev); | 856 | netif_tx_disable(netdev); |
856 | 857 | ||
857 | if (adapter->stop_port) | 858 | if (adapter->stop_port) |
858 | adapter->stop_port(adapter); | 859 | adapter->stop_port(adapter); |
@@ -863,9 +864,10 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
863 | netxen_napi_disable(adapter); | 864 | netxen_napi_disable(adapter); |
864 | 865 | ||
865 | netxen_release_tx_buffers(adapter); | 866 | netxen_release_tx_buffers(adapter); |
867 | spin_unlock(&adapter->tx_clean_lock); | ||
866 | 868 | ||
867 | FLUSH_SCHEDULED_WORK(); | ||
868 | del_timer_sync(&adapter->watchdog_timer); | 869 | del_timer_sync(&adapter->watchdog_timer); |
870 | FLUSH_SCHEDULED_WORK(); | ||
869 | } | 871 | } |
870 | 872 | ||
871 | 873 | ||
@@ -943,8 +945,8 @@ err_out_free_sw: | |||
943 | static void | 945 | static void |
944 | netxen_nic_detach(struct netxen_adapter *adapter) | 946 | netxen_nic_detach(struct netxen_adapter *adapter) |
945 | { | 947 | { |
946 | netxen_release_rx_buffers(adapter); | ||
947 | netxen_free_hw_resources(adapter); | 948 | netxen_free_hw_resources(adapter); |
949 | netxen_release_rx_buffers(adapter); | ||
948 | netxen_nic_free_irq(adapter); | 950 | netxen_nic_free_irq(adapter); |
949 | netxen_free_sw_resources(adapter); | 951 | netxen_free_sw_resources(adapter); |
950 | 952 | ||
@@ -1533,10 +1535,12 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1533 | printk(KERN_ALERT | 1535 | printk(KERN_ALERT |
1534 | "%s: Device temperature %d degrees C exceeds" | 1536 | "%s: Device temperature %d degrees C exceeds" |
1535 | " maximum allowed. Hardware has been shut down.\n", | 1537 | " maximum allowed. Hardware has been shut down.\n", |
1536 | netxen_nic_driver_name, temp_val); | 1538 | netdev->name, temp_val); |
1539 | |||
1540 | netif_device_detach(netdev); | ||
1541 | netxen_nic_down(adapter, netdev); | ||
1542 | netxen_nic_detach(adapter); | ||
1537 | 1543 | ||
1538 | netif_carrier_off(netdev); | ||
1539 | netif_stop_queue(netdev); | ||
1540 | rv = 1; | 1544 | rv = 1; |
1541 | } else if (temp_state == NX_TEMP_WARN) { | 1545 | } else if (temp_state == NX_TEMP_WARN) { |
1542 | if (adapter->temp == NX_TEMP_NORMAL) { | 1546 | if (adapter->temp == NX_TEMP_NORMAL) { |
@@ -1544,13 +1548,13 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1544 | "%s: Device temperature %d degrees C " | 1548 | "%s: Device temperature %d degrees C " |
1545 | "exceeds operating range." | 1549 | "exceeds operating range." |
1546 | " Immediate action needed.\n", | 1550 | " Immediate action needed.\n", |
1547 | netxen_nic_driver_name, temp_val); | 1551 | netdev->name, temp_val); |
1548 | } | 1552 | } |
1549 | } else { | 1553 | } else { |
1550 | if (adapter->temp == NX_TEMP_WARN) { | 1554 | if (adapter->temp == NX_TEMP_WARN) { |
1551 | printk(KERN_INFO | 1555 | printk(KERN_INFO |
1552 | "%s: Device temperature is now %d degrees C" | 1556 | "%s: Device temperature is now %d degrees C" |
1553 | " in normal range.\n", netxen_nic_driver_name, | 1557 | " in normal range.\n", netdev->name, |
1554 | temp_val); | 1558 | temp_val); |
1555 | } | 1559 | } |
1556 | } | 1560 | } |
@@ -1623,7 +1627,7 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1623 | struct netxen_adapter *adapter = | 1627 | struct netxen_adapter *adapter = |
1624 | container_of(work, struct netxen_adapter, watchdog_task); | 1628 | container_of(work, struct netxen_adapter, watchdog_task); |
1625 | 1629 | ||
1626 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1630 | if (netxen_nic_check_temp(adapter)) |
1627 | return; | 1631 | return; |
1628 | 1632 | ||
1629 | if (!adapter->has_link_events) | 1633 | if (!adapter->has_link_events) |
@@ -1645,6 +1649,9 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1645 | struct netxen_adapter *adapter = | 1649 | struct netxen_adapter *adapter = |
1646 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1650 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1647 | 1651 | ||
1652 | if (!netif_running(adapter->netdev)) | ||
1653 | return; | ||
1654 | |||
1648 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1655 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1649 | netxen_nic_driver_name, adapter->netdev->name); | 1656 | netxen_nic_driver_name, adapter->netdev->name); |
1650 | 1657 | ||
@@ -1757,7 +1764,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1757 | 1764 | ||
1758 | if ((work_done < budget) && tx_complete) { | 1765 | if ((work_done < budget) && tx_complete) { |
1759 | napi_complete(&sds_ring->napi); | 1766 | napi_complete(&sds_ring->napi); |
1760 | netxen_nic_enable_int(sds_ring); | 1767 | if (netif_running(adapter->netdev)) |
1768 | netxen_nic_enable_int(sds_ring); | ||
1761 | } | 1769 | } |
1762 | 1770 | ||
1763 | return work_done; | 1771 | return work_done; |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index a77417c51e44..d2156ab3da2b 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -156,6 +156,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev); | |||
156 | static int el3_rx(struct net_device *dev); | 156 | static int el3_rx(struct net_device *dev); |
157 | static int el3_close(struct net_device *dev); | 157 | static int el3_close(struct net_device *dev); |
158 | static void el3_tx_timeout(struct net_device *dev); | 158 | static void el3_tx_timeout(struct net_device *dev); |
159 | static void set_rx_mode(struct net_device *dev); | ||
159 | static void set_multicast_list(struct net_device *dev); | 160 | static void set_multicast_list(struct net_device *dev); |
160 | static const struct ethtool_ops netdev_ethtool_ops; | 161 | static const struct ethtool_ops netdev_ethtool_ops; |
161 | 162 | ||
@@ -488,8 +489,7 @@ static void tc589_reset(struct net_device *dev) | |||
488 | /* Switch to register set 1 for normal use. */ | 489 | /* Switch to register set 1 for normal use. */ |
489 | EL3WINDOW(1); | 490 | EL3WINDOW(1); |
490 | 491 | ||
491 | /* Accept b-cast and phys addr only. */ | 492 | set_rx_mode(dev); |
492 | outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); | ||
493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ | 493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ |
494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ | 494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ |
495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ | 495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ |
@@ -700,7 +700,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) | |||
700 | if (fifo_diag & 0x2000) { | 700 | if (fifo_diag & 0x2000) { |
701 | /* Rx underrun */ | 701 | /* Rx underrun */ |
702 | tc589_wait_for_completion(dev, RxReset); | 702 | tc589_wait_for_completion(dev, RxReset); |
703 | set_multicast_list(dev); | 703 | set_rx_mode(dev); |
704 | outw(RxEnable, ioaddr + EL3_CMD); | 704 | outw(RxEnable, ioaddr + EL3_CMD); |
705 | } | 705 | } |
706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); | 706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); |
@@ -905,14 +905,11 @@ static int el3_rx(struct net_device *dev) | |||
905 | return 0; | 905 | return 0; |
906 | } | 906 | } |
907 | 907 | ||
908 | static void set_multicast_list(struct net_device *dev) | 908 | static void set_rx_mode(struct net_device *dev) |
909 | { | 909 | { |
910 | struct el3_private *lp = netdev_priv(dev); | ||
911 | struct pcmcia_device *link = lp->p_dev; | ||
912 | unsigned int ioaddr = dev->base_addr; | 910 | unsigned int ioaddr = dev->base_addr; |
913 | u16 opts = SetRxFilter | RxStation | RxBroadcast; | 911 | u16 opts = SetRxFilter | RxStation | RxBroadcast; |
914 | 912 | ||
915 | if (!pcmcia_dev_present(link)) return; | ||
916 | if (dev->flags & IFF_PROMISC) | 913 | if (dev->flags & IFF_PROMISC) |
917 | opts |= RxMulticast | RxProm; | 914 | opts |= RxMulticast | RxProm; |
918 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) | 915 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) |
@@ -920,6 +917,16 @@ static void set_multicast_list(struct net_device *dev) | |||
920 | outw(opts, ioaddr + EL3_CMD); | 917 | outw(opts, ioaddr + EL3_CMD); |
921 | } | 918 | } |
922 | 919 | ||
920 | static void set_multicast_list(struct net_device *dev) | ||
921 | { | ||
922 | struct el3_private *priv = netdev_priv(dev); | ||
923 | unsigned long flags; | ||
924 | |||
925 | spin_lock_irqsave(&priv->lock, flags); | ||
926 | set_rx_mode(dev); | ||
927 | spin_unlock_irqrestore(&priv->lock, flags); | ||
928 | } | ||
929 | |||
923 | static int el3_close(struct net_device *dev) | 930 | static int el3_close(struct net_device *dev) |
924 | { | 931 | { |
925 | struct el3_private *lp = netdev_priv(dev); | 932 | struct el3_private *lp = netdev_priv(dev); |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 33984b737233..22cdd451fb82 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_OF_GPIO | 31 | #ifdef CONFIG_OF_GPIO |
32 | #include <linux/of_gpio.h> | 32 | #include <linux/of_gpio.h> |
33 | #include <linux/of_mdio.h> | ||
33 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
34 | #endif | 35 | #endif |
35 | 36 | ||
@@ -81,13 +82,12 @@ static struct mdiobb_ops mdio_gpio_ops = { | |||
81 | .get_mdio_data = mdio_get, | 82 | .get_mdio_data = mdio_get, |
82 | }; | 83 | }; |
83 | 84 | ||
84 | static int __devinit mdio_gpio_bus_init(struct device *dev, | 85 | static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, |
85 | struct mdio_gpio_platform_data *pdata, | 86 | struct mdio_gpio_platform_data *pdata, |
86 | int bus_id) | 87 | int bus_id) |
87 | { | 88 | { |
88 | struct mii_bus *new_bus; | 89 | struct mii_bus *new_bus; |
89 | struct mdio_gpio_info *bitbang; | 90 | struct mdio_gpio_info *bitbang; |
90 | int ret = -ENOMEM; | ||
91 | int i; | 91 | int i; |
92 | 92 | ||
93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); | 93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); |
@@ -104,8 +104,6 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
104 | 104 | ||
105 | new_bus->name = "GPIO Bitbanged MDIO", | 105 | new_bus->name = "GPIO Bitbanged MDIO", |
106 | 106 | ||
107 | ret = -ENODEV; | ||
108 | |||
109 | new_bus->phy_mask = pdata->phy_mask; | 107 | new_bus->phy_mask = pdata->phy_mask; |
110 | new_bus->irq = pdata->irqs; | 108 | new_bus->irq = pdata->irqs; |
111 | new_bus->parent = dev; | 109 | new_bus->parent = dev; |
@@ -129,15 +127,8 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
129 | 127 | ||
130 | dev_set_drvdata(dev, new_bus); | 128 | dev_set_drvdata(dev, new_bus); |
131 | 129 | ||
132 | ret = mdiobus_register(new_bus); | 130 | return new_bus; |
133 | if (ret) | ||
134 | goto out_free_all; | ||
135 | |||
136 | return 0; | ||
137 | 131 | ||
138 | out_free_all: | ||
139 | dev_set_drvdata(dev, NULL); | ||
140 | gpio_free(bitbang->mdio); | ||
141 | out_free_mdc: | 132 | out_free_mdc: |
142 | gpio_free(bitbang->mdc); | 133 | gpio_free(bitbang->mdc); |
143 | out_free_bus: | 134 | out_free_bus: |
@@ -145,30 +136,47 @@ out_free_bus: | |||
145 | out_free_bitbang: | 136 | out_free_bitbang: |
146 | kfree(bitbang); | 137 | kfree(bitbang); |
147 | out: | 138 | out: |
148 | return ret; | 139 | return NULL; |
149 | } | 140 | } |
150 | 141 | ||
151 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | 142 | static void __devinit mdio_gpio_bus_deinit(struct device *dev) |
152 | { | 143 | { |
153 | struct mii_bus *bus = dev_get_drvdata(dev); | 144 | struct mii_bus *bus = dev_get_drvdata(dev); |
154 | struct mdio_gpio_info *bitbang = bus->priv; | 145 | struct mdio_gpio_info *bitbang = bus->priv; |
155 | 146 | ||
156 | mdiobus_unregister(bus); | ||
157 | free_mdio_bitbang(bus); | ||
158 | dev_set_drvdata(dev, NULL); | 147 | dev_set_drvdata(dev, NULL); |
159 | gpio_free(bitbang->mdc); | ||
160 | gpio_free(bitbang->mdio); | 148 | gpio_free(bitbang->mdio); |
149 | gpio_free(bitbang->mdc); | ||
150 | free_mdio_bitbang(bus); | ||
161 | kfree(bitbang); | 151 | kfree(bitbang); |
162 | } | 152 | } |
163 | 153 | ||
154 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | ||
155 | { | ||
156 | struct mii_bus *bus = dev_get_drvdata(dev); | ||
157 | |||
158 | mdiobus_unregister(bus); | ||
159 | mdio_gpio_bus_deinit(dev); | ||
160 | } | ||
161 | |||
164 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) | 162 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) |
165 | { | 163 | { |
166 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; | 164 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; |
165 | struct mii_bus *new_bus; | ||
166 | int ret; | ||
167 | 167 | ||
168 | if (!pdata) | 168 | if (!pdata) |
169 | return -ENODEV; | 169 | return -ENODEV; |
170 | 170 | ||
171 | return mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); | 171 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); |
172 | if (!new_bus) | ||
173 | return -ENODEV; | ||
174 | |||
175 | ret = mdiobus_register(new_bus); | ||
176 | if (ret) | ||
177 | mdio_gpio_bus_deinit(&pdev->dev); | ||
178 | |||
179 | return ret; | ||
172 | } | 180 | } |
173 | 181 | ||
174 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) | 182 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) |
@@ -179,29 +187,12 @@ static int __devexit mdio_gpio_remove(struct platform_device *pdev) | |||
179 | } | 187 | } |
180 | 188 | ||
181 | #ifdef CONFIG_OF_GPIO | 189 | #ifdef CONFIG_OF_GPIO |
182 | static void __devinit add_phy(struct mdio_gpio_platform_data *pdata, | ||
183 | struct device_node *np) | ||
184 | { | ||
185 | const u32 *data; | ||
186 | int len, id, irq; | ||
187 | |||
188 | data = of_get_property(np, "reg", &len); | ||
189 | if (!data || len != 4) | ||
190 | return; | ||
191 | |||
192 | id = *data; | ||
193 | pdata->phy_mask &= ~(1 << id); | ||
194 | |||
195 | irq = of_irq_to_resource(np, 0, NULL); | ||
196 | if (irq) | ||
197 | pdata->irqs[id] = irq; | ||
198 | } | ||
199 | 190 | ||
200 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | 191 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, |
201 | const struct of_device_id *match) | 192 | const struct of_device_id *match) |
202 | { | 193 | { |
203 | struct device_node *np = NULL; | ||
204 | struct mdio_gpio_platform_data *pdata; | 194 | struct mdio_gpio_platform_data *pdata; |
195 | struct mii_bus *new_bus; | ||
205 | int ret; | 196 | int ret; |
206 | 197 | ||
207 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 198 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
@@ -215,14 +206,18 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | |||
215 | 206 | ||
216 | ret = of_get_gpio(ofdev->node, 1); | 207 | ret = of_get_gpio(ofdev->node, 1); |
217 | if (ret < 0) | 208 | if (ret < 0) |
218 | goto out_free; | 209 | goto out_free; |
219 | pdata->mdio = ret; | 210 | pdata->mdio = ret; |
220 | 211 | ||
221 | while ((np = of_get_next_child(ofdev->node, np))) | 212 | new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); |
222 | if (!strcmp(np->type, "ethernet-phy")) | 213 | if (!new_bus) |
223 | add_phy(pdata, np); | 214 | return -ENODEV; |
224 | 215 | ||
225 | return mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); | 216 | ret = of_mdiobus_register(new_bus, ofdev->node); |
217 | if (ret) | ||
218 | mdio_gpio_bus_deinit(&ofdev->dev); | ||
219 | |||
220 | return ret; | ||
226 | 221 | ||
227 | out_free: | 222 | out_free: |
228 | kfree(pdata); | 223 | kfree(pdata); |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 18821f217e19..e3156c97bb58 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
@@ -1593,6 +1593,7 @@ out: | |||
1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { | 1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { |
1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, | 1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, |
1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, | 1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, |
1596 | { PCI_DEVICE(0x1088, 0x2031) }, | ||
1596 | { 0, } | 1597 | { 0, } |
1597 | }; | 1598 | }; |
1598 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); | 1599 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 60d502eef4fc..543af2044f40 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3854,8 +3854,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3854 | skge->speed = -1; | 3854 | skge->speed = -1; |
3855 | skge->advertising = skge_supported_modes(hw); | 3855 | skge->advertising = skge_supported_modes(hw); |
3856 | 3856 | ||
3857 | if (device_may_wakeup(&hw->pdev->dev)) | 3857 | if (device_can_wakeup(&hw->pdev->dev)) { |
3858 | skge->wol = wol_supported(hw) & WAKE_MAGIC; | 3858 | skge->wol = wol_supported(hw) & WAKE_MAGIC; |
3859 | device_set_wakeup_enable(&hw->pdev->dev, skge->wol); | ||
3860 | } | ||
3859 | 3861 | ||
3860 | hw->dev[port] = dev; | 3862 | hw->dev[port] = dev; |
3861 | 3863 | ||
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ba768dfa59e0..3550c5dcd93c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1818,12 +1818,6 @@ static int sky2_down(struct net_device *dev) | |||
1818 | if (netif_msg_ifdown(sky2)) | 1818 | if (netif_msg_ifdown(sky2)) |
1819 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1819 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
1820 | 1820 | ||
1821 | /* Disable port IRQ */ | ||
1822 | imask = sky2_read32(hw, B0_IMSK); | ||
1823 | imask &= ~portirq_msk[port]; | ||
1824 | sky2_write32(hw, B0_IMSK, imask); | ||
1825 | sky2_read32(hw, B0_IMSK); | ||
1826 | |||
1827 | /* Force flow control off */ | 1821 | /* Force flow control off */ |
1828 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1822 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
1829 | 1823 | ||
@@ -1863,8 +1857,6 @@ static int sky2_down(struct net_device *dev) | |||
1863 | 1857 | ||
1864 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); | 1858 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); |
1865 | 1859 | ||
1866 | sky2_rx_stop(sky2); | ||
1867 | |||
1868 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1860 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1869 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1861 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1870 | 1862 | ||
@@ -1874,6 +1866,14 @@ static int sky2_down(struct net_device *dev) | |||
1874 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); | 1866 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); |
1875 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); | 1867 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); |
1876 | 1868 | ||
1869 | sky2_rx_stop(sky2); | ||
1870 | |||
1871 | /* Disable port IRQ */ | ||
1872 | imask = sky2_read32(hw, B0_IMSK); | ||
1873 | imask &= ~portirq_msk[port]; | ||
1874 | sky2_write32(hw, B0_IMSK, imask); | ||
1875 | sky2_read32(hw, B0_IMSK); | ||
1876 | |||
1877 | synchronize_irq(hw->pdev->irq); | 1877 | synchronize_irq(hw->pdev->irq); |
1878 | napi_synchronize(&hw->napi); | 1878 | napi_synchronize(&hw->napi); |
1879 | 1879 | ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index ca476a58087c..52a6750b8201 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -1591,13 +1591,13 @@ static int init_phy(struct net_device *dev) | |||
1591 | priv->oldspeed = 0; | 1591 | priv->oldspeed = 0; |
1592 | priv->oldduplex = -1; | 1592 | priv->oldduplex = -1; |
1593 | 1593 | ||
1594 | if (!ug_info->phy_node) | ||
1595 | return 0; | ||
1596 | |||
1597 | phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, | 1594 | phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, |
1598 | priv->phy_interface); | 1595 | priv->phy_interface); |
1596 | if (!phydev) | ||
1597 | phydev = of_phy_connect_fixed_link(dev, &adjust_link, | ||
1598 | priv->phy_interface); | ||
1599 | if (!phydev) { | 1599 | if (!phydev) { |
1600 | printk("%s: Could not attach to PHY\n", dev->name); | 1600 | dev_err(&dev->dev, "Could not attach to PHY\n"); |
1601 | return -ENODEV; | 1601 | return -ENODEV; |
1602 | } | 1602 | } |
1603 | 1603 | ||
@@ -3624,9 +3624,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3624 | struct ucc_geth_private *ugeth = NULL; | 3624 | struct ucc_geth_private *ugeth = NULL; |
3625 | struct ucc_geth_info *ug_info; | 3625 | struct ucc_geth_info *ug_info; |
3626 | struct resource res; | 3626 | struct resource res; |
3627 | struct device_node *phy; | ||
3628 | int err, ucc_num, max_speed = 0; | 3627 | int err, ucc_num, max_speed = 0; |
3629 | const u32 *fixed_link; | ||
3630 | const unsigned int *prop; | 3628 | const unsigned int *prop; |
3631 | const char *sprop; | 3629 | const char *sprop; |
3632 | const void *mac_addr; | 3630 | const void *mac_addr; |
@@ -3724,15 +3722,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3724 | 3722 | ||
3725 | ug_info->uf_info.regs = res.start; | 3723 | ug_info->uf_info.regs = res.start; |
3726 | ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); | 3724 | ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); |
3727 | fixed_link = of_get_property(np, "fixed-link", NULL); | 3725 | |
3728 | if (fixed_link) { | 3726 | ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0); |
3729 | phy = NULL; | ||
3730 | } else { | ||
3731 | phy = of_parse_phandle(np, "phy-handle", 0); | ||
3732 | if (phy == NULL) | ||
3733 | return -ENODEV; | ||
3734 | } | ||
3735 | ug_info->phy_node = phy; | ||
3736 | 3727 | ||
3737 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ | 3728 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ |
3738 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | 3729 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); |
@@ -3741,7 +3732,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3741 | prop = of_get_property(np, "phy-connection-type", NULL); | 3732 | prop = of_get_property(np, "phy-connection-type", NULL); |
3742 | if (!prop) { | 3733 | if (!prop) { |
3743 | /* handle interface property present in old trees */ | 3734 | /* handle interface property present in old trees */ |
3744 | prop = of_get_property(phy, "interface", NULL); | 3735 | prop = of_get_property(ug_info->phy_node, "interface", NULL); |
3745 | if (prop != NULL) { | 3736 | if (prop != NULL) { |
3746 | phy_interface = enet_to_phy_interface[*prop]; | 3737 | phy_interface = enet_to_phy_interface[*prop]; |
3747 | max_speed = enet_to_speed[*prop]; | 3738 | max_speed = enet_to_speed[*prop]; |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index a906d3998131..c47237c2d638 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -369,4 +369,12 @@ config USB_NET_INT51X1 | |||
369 | (Powerline Communications) solution with an Intellon | 369 | (Powerline Communications) solution with an Intellon |
370 | INT51x1/INT5200 chip, like the "devolo dLan duo". | 370 | INT51x1/INT5200 chip, like the "devolo dLan duo". |
371 | 371 | ||
372 | config USB_CDC_PHONET | ||
373 | tristate "CDC Phonet support" | ||
374 | depends on PHONET | ||
375 | help | ||
376 | Choose this option to support the Phonet interface to a Nokia | ||
377 | cellular modem, as found on most Nokia handsets with the | ||
378 | "PC suite" USB profile. | ||
379 | |||
372 | endmenu | 380 | endmenu |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b870b0b1cbe0..e17afb78f372 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -21,4 +21,5 @@ obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o | |||
21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | 21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o |
22 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 22 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o | 23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o |
24 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o | ||
24 | 25 | ||
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c new file mode 100644 index 000000000000..792af72da8ac --- /dev/null +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | * phonet.c -- USB CDC Phonet host driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. | ||
5 | * | ||
6 | * Author: Rémi Denis-Courmont | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/usb/cdc.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_phonet.h> | ||
30 | |||
31 | #define PN_MEDIA_USB 0x1B | ||
32 | |||
33 | static const unsigned rxq_size = 17; | ||
34 | |||
35 | struct usbpn_dev { | ||
36 | struct net_device *dev; | ||
37 | |||
38 | struct usb_interface *intf, *data_intf; | ||
39 | struct usb_device *usb; | ||
40 | unsigned int tx_pipe, rx_pipe; | ||
41 | u8 active_setting; | ||
42 | u8 disconnected; | ||
43 | |||
44 | unsigned tx_queue; | ||
45 | spinlock_t tx_lock; | ||
46 | |||
47 | spinlock_t rx_lock; | ||
48 | struct sk_buff *rx_skb; | ||
49 | struct urb *urbs[0]; | ||
50 | }; | ||
51 | |||
52 | static void tx_complete(struct urb *req); | ||
53 | static void rx_complete(struct urb *req); | ||
54 | |||
55 | /* | ||
56 | * Network device callbacks | ||
57 | */ | ||
58 | static int usbpn_xmit(struct sk_buff *skb, struct net_device *dev) | ||
59 | { | ||
60 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
61 | struct urb *req = NULL; | ||
62 | unsigned long flags; | ||
63 | int err; | ||
64 | |||
65 | if (skb->protocol != htons(ETH_P_PHONET)) | ||
66 | goto drop; | ||
67 | |||
68 | req = usb_alloc_urb(0, GFP_ATOMIC); | ||
69 | if (!req) | ||
70 | goto drop; | ||
71 | usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, | ||
72 | tx_complete, skb); | ||
73 | req->transfer_flags = URB_ZERO_PACKET; | ||
74 | err = usb_submit_urb(req, GFP_ATOMIC); | ||
75 | if (err) { | ||
76 | usb_free_urb(req); | ||
77 | goto drop; | ||
78 | } | ||
79 | |||
80 | spin_lock_irqsave(&pnd->tx_lock, flags); | ||
81 | pnd->tx_queue++; | ||
82 | if (pnd->tx_queue >= dev->tx_queue_len) | ||
83 | netif_stop_queue(dev); | ||
84 | spin_unlock_irqrestore(&pnd->tx_lock, flags); | ||
85 | return 0; | ||
86 | |||
87 | drop: | ||
88 | dev_kfree_skb(skb); | ||
89 | dev->stats.tx_dropped++; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void tx_complete(struct urb *req) | ||
94 | { | ||
95 | struct sk_buff *skb = req->context; | ||
96 | struct net_device *dev = skb->dev; | ||
97 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
98 | |||
99 | switch (req->status) { | ||
100 | case 0: | ||
101 | dev->stats.tx_bytes += skb->len; | ||
102 | break; | ||
103 | |||
104 | case -ENOENT: | ||
105 | case -ECONNRESET: | ||
106 | case -ESHUTDOWN: | ||
107 | dev->stats.tx_aborted_errors++; | ||
108 | default: | ||
109 | dev->stats.tx_errors++; | ||
110 | dev_dbg(&dev->dev, "TX error (%d)\n", req->status); | ||
111 | } | ||
112 | dev->stats.tx_packets++; | ||
113 | |||
114 | spin_lock(&pnd->tx_lock); | ||
115 | pnd->tx_queue--; | ||
116 | netif_wake_queue(dev); | ||
117 | spin_unlock(&pnd->tx_lock); | ||
118 | |||
119 | dev_kfree_skb_any(skb); | ||
120 | usb_free_urb(req); | ||
121 | } | ||
122 | |||
123 | static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) | ||
124 | { | ||
125 | struct net_device *dev = pnd->dev; | ||
126 | struct page *page; | ||
127 | int err; | ||
128 | |||
129 | page = __netdev_alloc_page(dev, gfp_flags); | ||
130 | if (!page) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), | ||
134 | PAGE_SIZE, rx_complete, dev); | ||
135 | req->transfer_flags = 0; | ||
136 | err = usb_submit_urb(req, gfp_flags); | ||
137 | if (unlikely(err)) { | ||
138 | dev_dbg(&dev->dev, "RX submit error (%d)\n", err); | ||
139 | netdev_free_page(dev, page); | ||
140 | } | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | static void rx_complete(struct urb *req) | ||
145 | { | ||
146 | struct net_device *dev = req->context; | ||
147 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
148 | struct page *page = virt_to_page(req->transfer_buffer); | ||
149 | struct sk_buff *skb; | ||
150 | unsigned long flags; | ||
151 | |||
152 | switch (req->status) { | ||
153 | case 0: | ||
154 | spin_lock_irqsave(&pnd->rx_lock, flags); | ||
155 | skb = pnd->rx_skb; | ||
156 | if (!skb) { | ||
157 | skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); | ||
158 | if (likely(skb)) { | ||
159 | /* Can't use pskb_pull() on page in IRQ */ | ||
160 | memcpy(skb_put(skb, 1), page_address(page), 1); | ||
161 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
162 | page, 1, req->actual_length); | ||
163 | page = NULL; | ||
164 | } | ||
165 | } else { | ||
166 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
167 | page, 0, req->actual_length); | ||
168 | page = NULL; | ||
169 | } | ||
170 | if (req->actual_length < PAGE_SIZE) | ||
171 | pnd->rx_skb = NULL; /* Last fragment */ | ||
172 | else | ||
173 | skb = NULL; | ||
174 | spin_unlock_irqrestore(&pnd->rx_lock, flags); | ||
175 | if (skb) { | ||
176 | skb->protocol = htons(ETH_P_PHONET); | ||
177 | skb_reset_mac_header(skb); | ||
178 | __skb_pull(skb, 1); | ||
179 | skb->dev = dev; | ||
180 | dev->stats.rx_packets++; | ||
181 | dev->stats.rx_bytes += skb->len; | ||
182 | |||
183 | netif_rx(skb); | ||
184 | } | ||
185 | goto resubmit; | ||
186 | |||
187 | case -ENOENT: | ||
188 | case -ECONNRESET: | ||
189 | case -ESHUTDOWN: | ||
190 | req = NULL; | ||
191 | break; | ||
192 | |||
193 | case -EOVERFLOW: | ||
194 | dev->stats.rx_over_errors++; | ||
195 | dev_dbg(&dev->dev, "RX overflow\n"); | ||
196 | break; | ||
197 | |||
198 | case -EILSEQ: | ||
199 | dev->stats.rx_crc_errors++; | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | dev->stats.rx_errors++; | ||
204 | resubmit: | ||
205 | if (page) | ||
206 | netdev_free_page(dev, page); | ||
207 | if (req) | ||
208 | rx_submit(pnd, req, GFP_ATOMIC); | ||
209 | } | ||
210 | |||
211 | static int usbpn_close(struct net_device *dev); | ||
212 | |||
213 | static int usbpn_open(struct net_device *dev) | ||
214 | { | ||
215 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
216 | int err; | ||
217 | unsigned i; | ||
218 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
219 | |||
220 | err = usb_set_interface(pnd->usb, num, pnd->active_setting); | ||
221 | if (err) | ||
222 | return err; | ||
223 | |||
224 | for (i = 0; i < rxq_size; i++) { | ||
225 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | ||
226 | |||
227 | if (!req || rx_submit(pnd, req, GFP_KERNEL)) { | ||
228 | usbpn_close(dev); | ||
229 | return -ENOMEM; | ||
230 | } | ||
231 | pnd->urbs[i] = req; | ||
232 | } | ||
233 | |||
234 | netif_wake_queue(dev); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int usbpn_close(struct net_device *dev) | ||
239 | { | ||
240 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
241 | unsigned i; | ||
242 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
243 | |||
244 | netif_stop_queue(dev); | ||
245 | |||
246 | for (i = 0; i < rxq_size; i++) { | ||
247 | struct urb *req = pnd->urbs[i]; | ||
248 | |||
249 | if (!req) | ||
250 | continue; | ||
251 | usb_kill_urb(req); | ||
252 | usb_free_urb(req); | ||
253 | pnd->urbs[i] = NULL; | ||
254 | } | ||
255 | |||
256 | return usb_set_interface(pnd->usb, num, !pnd->active_setting); | ||
257 | } | ||
258 | |||
259 | static int usbpn_set_mtu(struct net_device *dev, int new_mtu) | ||
260 | { | ||
261 | if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) | ||
262 | return -EINVAL; | ||
263 | |||
264 | dev->mtu = new_mtu; | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct net_device_ops usbpn_ops = { | ||
269 | .ndo_open = usbpn_open, | ||
270 | .ndo_stop = usbpn_close, | ||
271 | .ndo_start_xmit = usbpn_xmit, | ||
272 | .ndo_change_mtu = usbpn_set_mtu, | ||
273 | }; | ||
274 | |||
275 | static void usbpn_setup(struct net_device *dev) | ||
276 | { | ||
277 | dev->features = 0; | ||
278 | dev->netdev_ops = &usbpn_ops, | ||
279 | dev->header_ops = &phonet_header_ops; | ||
280 | dev->type = ARPHRD_PHONET; | ||
281 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | ||
282 | dev->mtu = PHONET_MAX_MTU; | ||
283 | dev->hard_header_len = 1; | ||
284 | dev->dev_addr[0] = PN_MEDIA_USB; | ||
285 | dev->addr_len = 1; | ||
286 | dev->tx_queue_len = 3; | ||
287 | |||
288 | dev->destructor = free_netdev; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * USB driver callbacks | ||
293 | */ | ||
294 | static struct usb_device_id usbpn_ids[] = { | ||
295 | { | ||
296 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
297 | | USB_DEVICE_ID_MATCH_INT_CLASS | ||
298 | | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
299 | .idVendor = 0x0421, /* Nokia */ | ||
300 | .bInterfaceClass = USB_CLASS_COMM, | ||
301 | .bInterfaceSubClass = 0xFE, | ||
302 | }, | ||
303 | { }, | ||
304 | }; | ||
305 | |||
306 | MODULE_DEVICE_TABLE(usb, usbpn_ids); | ||
307 | |||
308 | static struct usb_driver usbpn_driver; | ||
309 | |||
310 | int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
311 | { | ||
312 | static const char ifname[] = "usbpn%d"; | ||
313 | const struct usb_cdc_union_desc *union_header = NULL; | ||
314 | const struct usb_cdc_header_desc *phonet_header = NULL; | ||
315 | const struct usb_host_interface *data_desc; | ||
316 | struct usb_interface *data_intf; | ||
317 | struct usb_device *usbdev = interface_to_usbdev(intf); | ||
318 | struct net_device *dev; | ||
319 | struct usbpn_dev *pnd; | ||
320 | u8 *data; | ||
321 | int len, err; | ||
322 | |||
323 | data = intf->altsetting->extra; | ||
324 | len = intf->altsetting->extralen; | ||
325 | while (len >= 3) { | ||
326 | u8 dlen = data[0]; | ||
327 | if (dlen < 3) | ||
328 | return -EINVAL; | ||
329 | |||
330 | /* bDescriptorType */ | ||
331 | if (data[1] == USB_DT_CS_INTERFACE) { | ||
332 | /* bDescriptorSubType */ | ||
333 | switch (data[2]) { | ||
334 | case USB_CDC_UNION_TYPE: | ||
335 | if (union_header || dlen < 5) | ||
336 | break; | ||
337 | union_header = | ||
338 | (struct usb_cdc_union_desc *)data; | ||
339 | break; | ||
340 | case 0xAB: | ||
341 | if (phonet_header || dlen < 5) | ||
342 | break; | ||
343 | phonet_header = | ||
344 | (struct usb_cdc_header_desc *)data; | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | data += dlen; | ||
349 | len -= dlen; | ||
350 | } | ||
351 | |||
352 | if (!union_header || !phonet_header) | ||
353 | return -EINVAL; | ||
354 | |||
355 | data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); | ||
356 | if (data_intf == NULL) | ||
357 | return -ENODEV; | ||
358 | /* Data interface has one inactive and one active setting */ | ||
359 | if (data_intf->num_altsetting != 2) | ||
360 | return -EINVAL; | ||
361 | if (data_intf->altsetting[0].desc.bNumEndpoints == 0 | ||
362 | && data_intf->altsetting[1].desc.bNumEndpoints == 2) | ||
363 | data_desc = data_intf->altsetting + 1; | ||
364 | else | ||
365 | if (data_intf->altsetting[0].desc.bNumEndpoints == 2 | ||
366 | && data_intf->altsetting[1].desc.bNumEndpoints == 0) | ||
367 | data_desc = data_intf->altsetting; | ||
368 | else | ||
369 | return -EINVAL; | ||
370 | |||
371 | dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, | ||
372 | ifname, usbpn_setup); | ||
373 | if (!dev) | ||
374 | return -ENOMEM; | ||
375 | |||
376 | pnd = netdev_priv(dev); | ||
377 | SET_NETDEV_DEV(dev, &intf->dev); | ||
378 | netif_stop_queue(dev); | ||
379 | |||
380 | pnd->dev = dev; | ||
381 | pnd->usb = usb_get_dev(usbdev); | ||
382 | pnd->intf = intf; | ||
383 | pnd->data_intf = data_intf; | ||
384 | spin_lock_init(&pnd->tx_lock); | ||
385 | spin_lock_init(&pnd->rx_lock); | ||
386 | /* Endpoints */ | ||
387 | if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { | ||
388 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
389 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
390 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
391 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
392 | } else { | ||
393 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
394 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
395 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
396 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
397 | } | ||
398 | pnd->active_setting = data_desc - data_intf->altsetting; | ||
399 | |||
400 | err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); | ||
401 | if (err) | ||
402 | goto out; | ||
403 | |||
404 | /* Force inactive mode until the network device is brought UP */ | ||
405 | usb_set_interface(usbdev, union_header->bSlaveInterface0, | ||
406 | !pnd->active_setting); | ||
407 | usb_set_intfdata(intf, pnd); | ||
408 | |||
409 | err = register_netdev(dev); | ||
410 | if (err) { | ||
411 | usb_driver_release_interface(&usbpn_driver, data_intf); | ||
412 | goto out; | ||
413 | } | ||
414 | |||
415 | dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); | ||
416 | return 0; | ||
417 | |||
418 | out: | ||
419 | usb_set_intfdata(intf, NULL); | ||
420 | free_netdev(dev); | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | static void usbpn_disconnect(struct usb_interface *intf) | ||
425 | { | ||
426 | struct usbpn_dev *pnd = usb_get_intfdata(intf); | ||
427 | struct usb_device *usb = pnd->usb; | ||
428 | |||
429 | if (pnd->disconnected) | ||
430 | return; | ||
431 | |||
432 | pnd->disconnected = 1; | ||
433 | usb_driver_release_interface(&usbpn_driver, | ||
434 | (pnd->intf == intf) ? pnd->data_intf : pnd->intf); | ||
435 | unregister_netdev(pnd->dev); | ||
436 | usb_put_dev(usb); | ||
437 | } | ||
438 | |||
439 | static struct usb_driver usbpn_driver = { | ||
440 | .name = "cdc_phonet", | ||
441 | .probe = usbpn_probe, | ||
442 | .disconnect = usbpn_disconnect, | ||
443 | .id_table = usbpn_ids, | ||
444 | }; | ||
445 | |||
446 | static int __init usbpn_init(void) | ||
447 | { | ||
448 | return usb_register(&usbpn_driver); | ||
449 | } | ||
450 | |||
451 | static void __exit usbpn_exit(void) | ||
452 | { | ||
453 | usb_deregister(&usbpn_driver); | ||
454 | } | ||
455 | |||
456 | module_init(usbpn_init); | ||
457 | module_exit(usbpn_exit); | ||
458 | |||
459 | MODULE_AUTHOR("Remi Denis-Courmont"); | ||
460 | MODULE_DESCRIPTION("USB CDC Phonet host interface"); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 20ba6fa5f1f1..7db32ce3dbd8 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2980,6 +2980,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2980 | if (modparam_nohwcrypt) | 2980 | if (modparam_nohwcrypt) |
2981 | return -EOPNOTSUPP; | 2981 | return -EOPNOTSUPP; |
2982 | 2982 | ||
2983 | if (sc->opmode == NL80211_IFTYPE_AP) | ||
2984 | return -EOPNOTSUPP; | ||
2985 | |||
2983 | switch (key->alg) { | 2986 | switch (key->alg) { |
2984 | case ALG_WEP: | 2987 | case ALG_WEP: |
2985 | case ALG_TKIP: | 2988 | case ALG_TKIP: |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 1aeafb511ddd..aad259b4c197 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah) | |||
478 | "Reset ANI state opmode %u\n", ah->opmode); | 478 | "Reset ANI state opmode %u\n", ah->opmode); |
479 | ah->stats.ast_ani_reset++; | 479 | ah->stats.ast_ani_reset++; |
480 | 480 | ||
481 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
482 | /* | ||
483 | * ath9k_hw_ani_control() will only process items set on | ||
484 | * ah->ani_function | ||
485 | */ | ||
486 | if (IS_CHAN_2GHZ(chan)) | ||
487 | ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | | ||
488 | ATH9K_ANI_FIRSTEP_LEVEL); | ||
489 | else | ||
490 | ah->ani_function = 0; | ||
491 | } | ||
492 | |||
481 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); | 493 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); |
482 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); | 494 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); |
483 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); | 495 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f37c83275793..077bcc142cde 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
474 | return 0; | 474 | return 0; |
475 | } | 475 | } |
476 | 476 | ||
477 | /* | ||
478 | * Some users have reported their EEPROM programmed with | ||
479 | * 0x8000 set, this is not a supported regulatory domain | ||
480 | * but since we have more than one user with it we need | ||
481 | * a solution for them. We default to 0x64, which is the | ||
482 | * default Atheros world regulatory domain. | ||
483 | */ | ||
484 | static void ath_regd_sanitize(struct ath_regulatory *reg) | ||
485 | { | ||
486 | if (reg->current_rd != COUNTRY_ERD_FLAG) | ||
487 | return; | ||
488 | printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); | ||
489 | reg->current_rd = 0x64; | ||
490 | } | ||
491 | |||
477 | int | 492 | int |
478 | ath_regd_init(struct ath_regulatory *reg, | 493 | ath_regd_init(struct ath_regulatory *reg, |
479 | struct wiphy *wiphy, | 494 | struct wiphy *wiphy, |
@@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg, | |||
486 | if (!reg) | 501 | if (!reg) |
487 | return -EINVAL; | 502 | return -EINVAL; |
488 | 503 | ||
504 | ath_regd_sanitize(reg); | ||
505 | |||
489 | printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); | 506 | printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); |
490 | 507 | ||
491 | if (!ath_regd_is_eeprom_valid(reg)) { | 508 | if (!ath_regd_is_eeprom_valid(reg)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1d4e9cadb088..e2cc5994d108 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2617,12 +2617,10 @@ static ssize_t show_power_level(struct device *d, | |||
2617 | struct device_attribute *attr, char *buf) | 2617 | struct device_attribute *attr, char *buf) |
2618 | { | 2618 | { |
2619 | struct iwl_priv *priv = dev_get_drvdata(d); | 2619 | struct iwl_priv *priv = dev_get_drvdata(d); |
2620 | int mode = priv->power_data.user_power_setting; | ||
2621 | int level = priv->power_data.power_mode; | 2620 | int level = priv->power_data.power_mode; |
2622 | char *p = buf; | 2621 | char *p = buf; |
2623 | 2622 | ||
2624 | p += sprintf(p, "INDEX:%d\t", level); | 2623 | p += sprintf(p, "%d\n", level); |
2625 | p += sprintf(p, "USER:%d\n", mode); | ||
2626 | return p - buf + 1; | 2624 | return p - buf + 1; |
2627 | } | 2625 | } |
2628 | 2626 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 753fca32d9df..7073069a61a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -873,7 +873,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
873 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | 873 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); |
874 | 874 | ||
875 | /* Set up entry for this TFD in Tx byte-count array */ | 875 | /* Set up entry for this TFD in Tx byte-count array */ |
876 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, | 876 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
877 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, | ||
877 | le16_to_cpu(tx_cmd->len)); | 878 | le16_to_cpu(tx_cmd->len)); |
878 | 879 | ||
879 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, | 880 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 303c4b483f5b..7ff95f80b817 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3573,12 +3573,10 @@ static ssize_t show_power_level(struct device *d, | |||
3573 | struct device_attribute *attr, char *buf) | 3573 | struct device_attribute *attr, char *buf) |
3574 | { | 3574 | { |
3575 | struct iwl_priv *priv = dev_get_drvdata(d); | 3575 | struct iwl_priv *priv = dev_get_drvdata(d); |
3576 | int mode = priv->power_data.user_power_setting; | ||
3577 | int level = priv->power_data.power_mode; | 3576 | int level = priv->power_data.power_mode; |
3578 | char *p = buf; | 3577 | char *p = buf; |
3579 | 3578 | ||
3580 | p += sprintf(p, "INDEX:%d\t", level); | 3579 | p += sprintf(p, "%d\n", level); |
3581 | p += sprintf(p, "USER:%d\n", mode); | ||
3582 | return p - buf + 1; | 3580 | return p - buf + 1; |
3583 | } | 3581 | } |
3584 | 3582 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index e94e96955b99..092d28ae56a0 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c | |||
@@ -156,10 +156,10 @@ void iwm_if_free(struct iwm_priv *iwm) | |||
156 | return; | 156 | return; |
157 | 157 | ||
158 | free_netdev(iwm_to_ndev(iwm)); | 158 | free_netdev(iwm_to_ndev(iwm)); |
159 | iwm_wdev_free(iwm); | ||
160 | iwm_priv_deinit(iwm); | 159 | iwm_priv_deinit(iwm); |
161 | kfree(iwm->umac_profile); | 160 | kfree(iwm->umac_profile); |
162 | iwm->umac_profile = NULL; | 161 | iwm->umac_profile = NULL; |
162 | iwm_wdev_free(iwm); | ||
163 | } | 163 | } |
164 | 164 | ||
165 | int iwm_if_add(struct iwm_priv *iwm) | 165 | int iwm_if_add(struct iwm_priv *iwm) |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 01db705a38ec..685098148e10 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -135,8 +135,14 @@ int lbs_update_hw_spec(struct lbs_private *priv) | |||
135 | /* Clamp region code to 8-bit since FW spec indicates that it should | 135 | /* Clamp region code to 8-bit since FW spec indicates that it should |
136 | * only ever be 8-bit, even though the field size is 16-bit. Some firmware | 136 | * only ever be 8-bit, even though the field size is 16-bit. Some firmware |
137 | * returns non-zero high 8 bits here. | 137 | * returns non-zero high 8 bits here. |
138 | * | ||
139 | * Firmware version 4.0.102 used in CF8381 has region code shifted. We | ||
140 | * need to check for this problem and handle it properly. | ||
138 | */ | 141 | */ |
139 | priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; | 142 | if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) |
143 | priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; | ||
144 | else | ||
145 | priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; | ||
140 | 146 | ||
141 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { | 147 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { |
142 | /* use the region code to search for the index */ | 148 | /* use the region code to search for the index */ |
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 48da157d6cda..72f3479a4d70 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h | |||
@@ -234,6 +234,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
234 | /** Mesh enable bit in FW capability */ | 234 | /** Mesh enable bit in FW capability */ |
235 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) | 235 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) |
236 | 236 | ||
237 | /** FW definition from Marvell v4 */ | ||
238 | #define MRVL_FW_V4 (0x04) | ||
237 | /** FW definition from Marvell v5 */ | 239 | /** FW definition from Marvell v5 */ |
238 | #define MRVL_FW_V5 (0x05) | 240 | #define MRVL_FW_V5 (0x05) |
239 | /** FW definition from Marvell v10 */ | 241 | /** FW definition from Marvell v10 */ |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4befa48dbc34..e9b5442f1dda 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -788,7 +788,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops = | |||
788 | static void mac80211_hwsim_free(void) | 788 | static void mac80211_hwsim_free(void) |
789 | { | 789 | { |
790 | struct list_head tmplist, *i, *tmp; | 790 | struct list_head tmplist, *i, *tmp; |
791 | struct mac80211_hwsim_data *data; | 791 | struct mac80211_hwsim_data *data, *tmpdata; |
792 | 792 | ||
793 | INIT_LIST_HEAD(&tmplist); | 793 | INIT_LIST_HEAD(&tmplist); |
794 | 794 | ||
@@ -797,7 +797,7 @@ static void mac80211_hwsim_free(void) | |||
797 | list_move(i, &tmplist); | 797 | list_move(i, &tmplist); |
798 | spin_unlock_bh(&hwsim_radio_lock); | 798 | spin_unlock_bh(&hwsim_radio_lock); |
799 | 799 | ||
800 | list_for_each_entry(data, &tmplist, list) { | 800 | list_for_each_entry_safe(data, tmpdata, &tmplist, list) { |
801 | debugfs_remove(data->debugfs_group); | 801 | debugfs_remove(data->debugfs_group); |
802 | debugfs_remove(data->debugfs_ps); | 802 | debugfs_remove(data->debugfs_ps); |
803 | debugfs_remove(data->debugfs); | 803 | debugfs_remove(data->debugfs); |
@@ -1246,8 +1246,8 @@ static void __exit exit_mac80211_hwsim(void) | |||
1246 | { | 1246 | { |
1247 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); | 1247 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); |
1248 | 1248 | ||
1249 | unregister_netdev(hwsim_mon); | ||
1250 | mac80211_hwsim_free(); | 1249 | mac80211_hwsim_free(); |
1250 | unregister_netdev(hwsim_mon); | ||
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | 1253 | ||
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index d5f181ad37fc..eef532987d05 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -600,7 +600,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
600 | 600 | ||
601 | hw = p54_init_common(sizeof(*priv)); | 601 | hw = p54_init_common(sizeof(*priv)); |
602 | if (!hw) { | 602 | if (!hw) { |
603 | dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); | 603 | dev_err(&spi->dev, "could not alloc ieee80211_hw"); |
604 | return -ENOMEM; | 604 | return -ENOMEM; |
605 | } | 605 | } |
606 | 606 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 795706d63b94..00611b32d08b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1546,7 +1546,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1546 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); | 1546 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); |
1547 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); | 1547 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); |
1548 | 1548 | ||
1549 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) { | 1549 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || |
1550 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { | ||
1551 | |||
1550 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 1552 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); |
1551 | return -ENODEV; | 1553 | return -ENODEV; |
1552 | } | 1554 | } |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index b44253592243..cf9f899fe0e6 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c | |||
@@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) | |||
208 | { | 208 | { |
209 | struct rtl8187_priv *priv = dev->priv; | 209 | struct rtl8187_priv *priv = dev->priv; |
210 | 210 | ||
211 | rtl8187_unregister_led(&priv->led_tx); | ||
212 | /* turn the LED off before exiting */ | 211 | /* turn the LED off before exiting */ |
213 | queue_delayed_work(dev->workqueue, &priv->led_off, 0); | 212 | queue_delayed_work(dev->workqueue, &priv->led_off, 0); |
214 | cancel_delayed_work_sync(&priv->led_off); | 213 | cancel_delayed_work_sync(&priv->led_off); |
214 | cancel_delayed_work_sync(&priv->led_on); | ||
215 | rtl8187_unregister_led(&priv->led_rx); | 215 | rtl8187_unregister_led(&priv->led_rx); |
216 | rtl8187_unregister_led(&priv->led_tx); | ||
216 | } | 217 | } |
217 | #endif /* def CONFIG_RTL8187_LED */ | 218 | #endif /* def CONFIG_RTL8187_LED */ |
218 | 219 | ||
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index aee967d7f760..bacaa536fd51 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -9,6 +9,10 @@ | |||
9 | * out of the OpenFirmware device tree and using it to populate an mii_bus. | 9 | * out of the OpenFirmware device tree and using it to populate an mii_bus. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/err.h> | ||
12 | #include <linux/phy.h> | 16 | #include <linux/phy.h> |
13 | #include <linux/of.h> | 17 | #include <linux/of.h> |
14 | #include <linux/of_mdio.h> | 18 | #include <linux/of_mdio.h> |
@@ -137,3 +141,41 @@ struct phy_device *of_phy_connect(struct net_device *dev, | |||
137 | return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; | 141 | return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; |
138 | } | 142 | } |
139 | EXPORT_SYMBOL(of_phy_connect); | 143 | EXPORT_SYMBOL(of_phy_connect); |
144 | |||
145 | /** | ||
146 | * of_phy_connect_fixed_link - Parse fixed-link property and return a dummy phy | ||
147 | * @dev: pointer to net_device claiming the phy | ||
148 | * @hndlr: Link state callback for the network device | ||
149 | * @iface: PHY data interface type | ||
150 | * | ||
151 | * This function is a temporary stop-gap and will be removed soon. It is | ||
152 | * only to support the fs_enet, ucc_geth and gianfar Ethernet drivers. Do | ||
153 | * not call this function from new drivers. | ||
154 | */ | ||
155 | struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, | ||
156 | void (*hndlr)(struct net_device *), | ||
157 | phy_interface_t iface) | ||
158 | { | ||
159 | struct device_node *net_np; | ||
160 | char bus_id[MII_BUS_ID_SIZE + 3]; | ||
161 | struct phy_device *phy; | ||
162 | const u32 *phy_id; | ||
163 | int sz; | ||
164 | |||
165 | if (!dev->dev.parent) | ||
166 | return NULL; | ||
167 | |||
168 | net_np = dev_archdata_get_node(&dev->dev.parent->archdata); | ||
169 | if (!net_np) | ||
170 | return NULL; | ||
171 | |||
172 | phy_id = of_get_property(net_np, "fixed-link", &sz); | ||
173 | if (!phy_id || sz < sizeof(*phy_id)) | ||
174 | return NULL; | ||
175 | |||
176 | sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]); | ||
177 | |||
178 | phy = phy_connect(dev, bus_id, hndlr, 0, iface); | ||
179 | return IS_ERR(phy) ? NULL : phy; | ||
180 | } | ||
181 | EXPORT_SYMBOL(of_phy_connect_fixed_link); | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index be2fd6f91639..fb45f5ee8df1 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -973,7 +973,7 @@ static int acer_rfkill_set(void *data, bool blocked) | |||
973 | { | 973 | { |
974 | acpi_status status; | 974 | acpi_status status; |
975 | u32 cap = (unsigned long)data; | 975 | u32 cap = (unsigned long)data; |
976 | status = set_u32(!!blocked, cap); | 976 | status = set_u32(!blocked, cap); |
977 | if (ACPI_FAILURE(status)) | 977 | if (ACPI_FAILURE(status)) |
978 | return -ENODEV; | 978 | return -ENODEV; |
979 | return 0; | 979 | return 0; |
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index c9663c690303..53b94e025c7c 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h | |||
@@ -18,5 +18,8 @@ extern struct phy_device *of_phy_connect(struct net_device *dev, | |||
18 | struct device_node *phy_np, | 18 | struct device_node *phy_np, |
19 | void (*hndlr)(struct net_device *), | 19 | void (*hndlr)(struct net_device *), |
20 | u32 flags, phy_interface_t iface); | 20 | u32 flags, phy_interface_t iface); |
21 | extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, | ||
22 | void (*hndlr)(struct net_device *), | ||
23 | phy_interface_t iface); | ||
21 | 24 | ||
22 | #endif /* __LINUX_OF_MDIO_H */ | 25 | #endif /* __LINUX_OF_MDIO_H */ |
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index f3d5812693d6..10202903141a 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
@@ -238,7 +238,7 @@ void rfkill_destroy(struct rfkill *rfkill); | |||
238 | * should be blocked) so that drivers need not keep track of the soft | 238 | * should be blocked) so that drivers need not keep track of the soft |
239 | * block state -- which they might not be able to. | 239 | * block state -- which they might not be able to. |
240 | */ | 240 | */ |
241 | bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); | 241 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); |
242 | 242 | ||
243 | /** | 243 | /** |
244 | * rfkill_set_sw_state - Set the internal rfkill software block state | 244 | * rfkill_set_sw_state - Set the internal rfkill software block state |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 19f4150f4d4d..88af84306471 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1425,6 +1425,11 @@ struct tcp_request_sock_ops { | |||
1425 | #ifdef CONFIG_TCP_MD5SIG | 1425 | #ifdef CONFIG_TCP_MD5SIG |
1426 | struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, | 1426 | struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, |
1427 | struct request_sock *req); | 1427 | struct request_sock *req); |
1428 | int (*calc_md5_hash) (char *location, | ||
1429 | struct tcp_md5sig_key *md5, | ||
1430 | struct sock *sk, | ||
1431 | struct request_sock *req, | ||
1432 | struct sk_buff *skb); | ||
1428 | #endif | 1433 | #endif |
1429 | }; | 1434 | }; |
1430 | 1435 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index d9eec153d531..bbb25be7ddfe 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -631,7 +631,7 @@ set_rcvbuf: | |||
631 | 631 | ||
632 | case SO_TIMESTAMPING: | 632 | case SO_TIMESTAMPING: |
633 | if (val & ~SOF_TIMESTAMPING_MASK) { | 633 | if (val & ~SOF_TIMESTAMPING_MASK) { |
634 | ret = EINVAL; | 634 | ret = -EINVAL; |
635 | break; | 635 | break; |
636 | } | 636 | } |
637 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, | 637 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a1ca2698c88..6d88219c5e22 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1160,6 +1160,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = { | |||
1160 | #ifdef CONFIG_TCP_MD5SIG | 1160 | #ifdef CONFIG_TCP_MD5SIG |
1161 | static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { | 1161 | static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { |
1162 | .md5_lookup = tcp_v4_reqsk_md5_lookup, | 1162 | .md5_lookup = tcp_v4_reqsk_md5_lookup, |
1163 | .calc_md5_hash = tcp_v4_md5_hash_skb, | ||
1163 | }; | 1164 | }; |
1164 | #endif | 1165 | #endif |
1165 | 1166 | ||
@@ -1373,7 +1374,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1373 | */ | 1374 | */ |
1374 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); | 1375 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); |
1375 | if (newkey != NULL) | 1376 | if (newkey != NULL) |
1376 | tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr, | 1377 | tcp_v4_md5_do_add(newsk, newinet->daddr, |
1377 | newkey, key->keylen); | 1378 | newkey, key->keylen); |
1378 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 1379 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; |
1379 | } | 1380 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c464892cf642..4e004424d400 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2294,7 +2294,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2294 | #ifdef CONFIG_TCP_MD5SIG | 2294 | #ifdef CONFIG_TCP_MD5SIG |
2295 | /* Okay, we have all we need - do the md5 hash if needed */ | 2295 | /* Okay, we have all we need - do the md5 hash if needed */ |
2296 | if (md5) { | 2296 | if (md5) { |
2297 | tp->af_specific->calc_md5_hash(md5_hash_location, | 2297 | tcp_rsk(req)->af_specific->calc_md5_hash(md5_hash_location, |
2298 | md5, NULL, req, skb); | 2298 | md5, NULL, req, skb); |
2299 | } | 2299 | } |
2300 | #endif | 2300 | #endif |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 58810c65b635..d849dd53b788 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -896,6 +896,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = { | |||
896 | #ifdef CONFIG_TCP_MD5SIG | 896 | #ifdef CONFIG_TCP_MD5SIG |
897 | static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { | 897 | static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { |
898 | .md5_lookup = tcp_v6_reqsk_md5_lookup, | 898 | .md5_lookup = tcp_v6_reqsk_md5_lookup, |
899 | .calc_md5_hash = tcp_v6_md5_hash_skb, | ||
899 | }; | 900 | }; |
900 | #endif | 901 | #endif |
901 | 902 | ||
@@ -1441,7 +1442,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1441 | */ | 1442 | */ |
1442 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); | 1443 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); |
1443 | if (newkey != NULL) | 1444 | if (newkey != NULL) |
1444 | tcp_v6_md5_do_add(newsk, &inet6_sk(sk)->daddr, | 1445 | tcp_v6_md5_do_add(newsk, &newnp->daddr, |
1445 | newkey, key->keylen); | 1446 | newkey, key->keylen); |
1446 | } | 1447 | } |
1447 | #endif | 1448 | #endif |
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 41a32cd919af..182c9c5c6818 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -67,6 +67,7 @@ endmenu | |||
67 | config MAC80211_MESH | 67 | config MAC80211_MESH |
68 | bool "Enable mac80211 mesh networking (pre-802.11s) support" | 68 | bool "Enable mac80211 mesh networking (pre-802.11s) support" |
69 | depends on MAC80211 && EXPERIMENTAL | 69 | depends on MAC80211 && EXPERIMENTAL |
70 | depends on BROKEN | ||
70 | ---help--- | 71 | ---help--- |
71 | This options enables support of Draft 802.11s mesh networking. | 72 | This options enables support of Draft 802.11s mesh networking. |
72 | The implementation is based on Draft 1.08 of the Mesh Networking | 73 | The implementation is based on Draft 1.08 of the Mesh Networking |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 3c72557df45a..479597e88583 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -175,6 +175,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
175 | int err = 0; | 175 | int err = 0; |
176 | u32 hash_idx; | 176 | u32 hash_idx; |
177 | 177 | ||
178 | might_sleep(); | ||
179 | |||
178 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) | 180 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) |
179 | /* never add ourselves as neighbours */ | 181 | /* never add ourselves as neighbours */ |
180 | return -ENOTSUPP; | 182 | return -ENOTSUPP; |
@@ -265,6 +267,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
265 | int err = 0; | 267 | int err = 0; |
266 | u32 hash_idx; | 268 | u32 hash_idx; |
267 | 269 | ||
270 | might_sleep(); | ||
268 | 271 | ||
269 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) | 272 | if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) |
270 | /* never add ourselves as neighbours */ | 273 | /* never add ourselves as neighbours */ |
@@ -491,8 +494,10 @@ void mesh_path_tx_pending(struct mesh_path *mpath) | |||
491 | * @skb: frame to discard | 494 | * @skb: frame to discard |
492 | * @sdata: network subif the frame was to be sent through | 495 | * @sdata: network subif the frame was to be sent through |
493 | * | 496 | * |
494 | * If the frame was beign forwarded from another MP, a PERR frame will be sent | 497 | * If the frame was being forwarded from another MP, a PERR frame will be sent |
495 | * to the precursor. | 498 | * to the precursor. The precursor's address (i.e. the previous hop) was saved |
499 | * in addr1 of the frame-to-be-forwarded, and would only be overwritten once | ||
500 | * the destination is successfully resolved. | ||
496 | * | 501 | * |
497 | * Locking: the function must me called within a rcu_read_lock region | 502 | * Locking: the function must me called within a rcu_read_lock region |
498 | */ | 503 | */ |
@@ -507,7 +512,7 @@ void mesh_path_discard_frame(struct sk_buff *skb, | |||
507 | u8 *ra, *da; | 512 | u8 *ra, *da; |
508 | 513 | ||
509 | da = hdr->addr3; | 514 | da = hdr->addr3; |
510 | ra = hdr->addr2; | 515 | ra = hdr->addr1; |
511 | mpath = mesh_path_lookup(da, sdata); | 516 | mpath = mesh_path_lookup(da, sdata); |
512 | if (mpath) | 517 | if (mpath) |
513 | dsn = ++mpath->dsn; | 518 | dsn = ++mpath->dsn; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2ffb35d3f566..60ae086995b1 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1455,7 +1455,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1455 | monitor_iface = UNKNOWN_ADDRESS; | 1455 | monitor_iface = UNKNOWN_ADDRESS; |
1456 | 1456 | ||
1457 | len_rthdr = ieee80211_get_radiotap_len(skb->data); | 1457 | len_rthdr = ieee80211_get_radiotap_len(skb->data); |
1458 | hdr = (struct ieee80211_hdr *)skb->data + len_rthdr; | 1458 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |
1459 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1459 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1460 | 1460 | ||
1461 | /* check the header is complete in the frame */ | 1461 | /* check the header is complete in the frame */ |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 47497c97c8d9..044de1c6af3d 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -549,6 +549,10 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
549 | swprev = !!(rfkill->state & RFKILL_BLOCK_SW); | 549 | swprev = !!(rfkill->state & RFKILL_BLOCK_SW); |
550 | hwprev = !!(rfkill->state & RFKILL_BLOCK_HW); | 550 | hwprev = !!(rfkill->state & RFKILL_BLOCK_HW); |
551 | __rfkill_set_sw_state(rfkill, sw); | 551 | __rfkill_set_sw_state(rfkill, sw); |
552 | if (hw) | ||
553 | rfkill->state |= RFKILL_BLOCK_HW; | ||
554 | else | ||
555 | rfkill->state &= ~RFKILL_BLOCK_HW; | ||
552 | 556 | ||
553 | spin_unlock_irqrestore(&rfkill->lock, flags); | 557 | spin_unlock_irqrestore(&rfkill->lock, flags); |
554 | 558 | ||
@@ -648,15 +652,26 @@ static ssize_t rfkill_state_store(struct device *dev, | |||
648 | struct device_attribute *attr, | 652 | struct device_attribute *attr, |
649 | const char *buf, size_t count) | 653 | const char *buf, size_t count) |
650 | { | 654 | { |
651 | /* | 655 | struct rfkill *rfkill = to_rfkill(dev); |
652 | * The intention was that userspace can only take control over | 656 | unsigned long state; |
653 | * a given device when/if rfkill-input doesn't control it due | 657 | int err; |
654 | * to user_claim. Since user_claim is currently unsupported, | 658 | |
655 | * we never support changing the state from userspace -- this | 659 | if (!capable(CAP_NET_ADMIN)) |
656 | * can be implemented again later. | 660 | return -EPERM; |
657 | */ | 661 | |
662 | err = strict_strtoul(buf, 0, &state); | ||
663 | if (err) | ||
664 | return err; | ||
665 | |||
666 | if (state != RFKILL_USER_STATE_SOFT_BLOCKED && | ||
667 | state != RFKILL_USER_STATE_UNBLOCKED) | ||
668 | return -EINVAL; | ||
669 | |||
670 | mutex_lock(&rfkill_global_mutex); | ||
671 | rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED); | ||
672 | mutex_unlock(&rfkill_global_mutex); | ||
658 | 673 | ||
659 | return -EPERM; | 674 | return err ?: count; |
660 | } | 675 | } |
661 | 676 | ||
662 | static ssize_t rfkill_claim_show(struct device *dev, | 677 | static ssize_t rfkill_claim_show(struct device *dev, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2a04beba4369..4478760b7dc3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1010,7 +1010,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
1010 | 1010 | ||
1011 | if (IS_ERR(hdr)) { | 1011 | if (IS_ERR(hdr)) { |
1012 | err = PTR_ERR(hdr); | 1012 | err = PTR_ERR(hdr); |
1013 | goto out; | 1013 | goto free_msg; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | cookie.msg = msg; | 1016 | cookie.msg = msg; |
@@ -1024,7 +1024,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
1024 | &cookie, get_key_callback); | 1024 | &cookie, get_key_callback); |
1025 | 1025 | ||
1026 | if (err) | 1026 | if (err) |
1027 | goto out; | 1027 | goto free_msg; |
1028 | 1028 | ||
1029 | if (cookie.error) | 1029 | if (cookie.error) |
1030 | goto nla_put_failure; | 1030 | goto nla_put_failure; |
@@ -1035,6 +1035,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
1035 | 1035 | ||
1036 | nla_put_failure: | 1036 | nla_put_failure: |
1037 | err = -ENOBUFS; | 1037 | err = -ENOBUFS; |
1038 | free_msg: | ||
1038 | nlmsg_free(msg); | 1039 | nlmsg_free(msg); |
1039 | out: | 1040 | out: |
1040 | cfg80211_unlock_rdev(rdev); | 1041 | cfg80211_unlock_rdev(rdev); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 4f552c3f29a3..decc59fe0ee8 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -48,8 +48,6 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
48 | else | 48 | else |
49 | nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); | 49 | nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); |
50 | 50 | ||
51 | wiphy_to_dev(request->wiphy)->scan_req = NULL; | ||
52 | |||
53 | #ifdef CONFIG_WIRELESS_EXT | 51 | #ifdef CONFIG_WIRELESS_EXT |
54 | if (!request->aborted) { | 52 | if (!request->aborted) { |
55 | memset(&wrqu, 0, sizeof(wrqu)); | 53 | memset(&wrqu, 0, sizeof(wrqu)); |
@@ -62,6 +60,7 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
62 | 60 | ||
63 | out: | 61 | out: |
64 | cfg80211_unlock_rdev(rdev); | 62 | cfg80211_unlock_rdev(rdev); |
63 | wiphy_to_dev(request->wiphy)->scan_req = NULL; | ||
65 | kfree(request); | 64 | kfree(request); |
66 | } | 65 | } |
67 | 66 | ||