diff options
Diffstat (limited to 'drivers/net')
53 files changed, 1800 insertions, 199 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5fb659f8b20..3073f679584 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -838,6 +838,50 @@ config ULTRA32 | |||
838 | <file:Documentation/networking/net-modules.txt>. The module | 838 | <file:Documentation/networking/net-modules.txt>. The module |
839 | will be called smc-ultra32. | 839 | will be called smc-ultra32. |
840 | 840 | ||
841 | config BFIN_MAC | ||
842 | tristate "Blackfin 536/537 on-chip mac support" | ||
843 | depends on NET_ETHERNET && (BF537 || BF536) && (!BF537_PORT_H) | ||
844 | select CRC32 | ||
845 | select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE | ||
846 | help | ||
847 | This is the driver for blackfin on-chip mac device. Say Y if you want it | ||
848 | compiled into the kernel. This driver is also available as a module | ||
849 | ( = code which can be inserted in and removed from the running kernel | ||
850 | whenever you want). The module will be called bfin_mac. | ||
851 | |||
852 | config BFIN_MAC_USE_L1 | ||
853 | bool "Use L1 memory for rx/tx packets" | ||
854 | depends on BFIN_MAC && BF537 | ||
855 | default y | ||
856 | help | ||
857 | To get maximum network performace, you should use L1 memory as rx/tx buffers. | ||
858 | Say N here if you want to reserve L1 memory for other uses. | ||
859 | |||
860 | config BFIN_TX_DESC_NUM | ||
861 | int "Number of transmit buffer packets" | ||
862 | depends on BFIN_MAC | ||
863 | range 6 10 if BFIN_MAC_USE_L1 | ||
864 | range 10 100 | ||
865 | default "10" | ||
866 | help | ||
867 | Set the number of buffer packets used in driver. | ||
868 | |||
869 | config BFIN_RX_DESC_NUM | ||
870 | int "Number of receive buffer packets" | ||
871 | depends on BFIN_MAC | ||
872 | range 20 100 if BFIN_MAC_USE_L1 | ||
873 | range 20 800 | ||
874 | default "20" | ||
875 | help | ||
876 | Set the number of buffer packets used in driver. | ||
877 | |||
878 | config BFIN_MAC_RMII | ||
879 | bool "RMII PHY Interface (EXPERIMENTAL)" | ||
880 | depends on BFIN_MAC && EXPERIMENTAL | ||
881 | default n | ||
882 | help | ||
883 | Use Reduced PHY MII Interface | ||
884 | |||
841 | config SMC9194 | 885 | config SMC9194 |
842 | tristate "SMC 9194 support" | 886 | tristate "SMC 9194 support" |
843 | depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) | 887 | depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 0e286ab8855..336af0635df 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -177,6 +177,7 @@ obj-$(CONFIG_ZORRO8390) += zorro8390.o | |||
177 | obj-$(CONFIG_HPLANCE) += hplance.o 7990.o | 177 | obj-$(CONFIG_HPLANCE) += hplance.o 7990.o |
178 | obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o | 178 | obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o |
179 | obj-$(CONFIG_EQUALIZER) += eql.o | 179 | obj-$(CONFIG_EQUALIZER) += eql.o |
180 | obj-$(CONFIG_LGUEST_GUEST) += lguest_net.o | ||
180 | obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o | 181 | obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o |
181 | obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o | 182 | obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o |
182 | obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o | 183 | obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o |
@@ -200,6 +201,7 @@ obj-$(CONFIG_S2IO) += s2io.o | |||
200 | obj-$(CONFIG_MYRI10GE) += myri10ge/ | 201 | obj-$(CONFIG_MYRI10GE) += myri10ge/ |
201 | obj-$(CONFIG_SMC91X) += smc91x.o | 202 | obj-$(CONFIG_SMC91X) += smc91x.o |
202 | obj-$(CONFIG_SMC911X) += smc911x.o | 203 | obj-$(CONFIG_SMC911X) += smc911x.o |
204 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o | ||
203 | obj-$(CONFIG_DM9000) += dm9000.o | 205 | obj-$(CONFIG_DM9000) += dm9000.o |
204 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ | 206 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ |
205 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o | 207 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o |
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index da713500654..a7cac695a9b 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c | |||
@@ -464,7 +464,7 @@ static void ether3_setmulticastlist(struct net_device *dev) | |||
464 | if (dev->flags & IFF_PROMISC) { | 464 | if (dev->flags & IFF_PROMISC) { |
465 | /* promiscuous mode */ | 465 | /* promiscuous mode */ |
466 | priv(dev)->regs.config1 |= CFG1_RECVPROMISC; | 466 | priv(dev)->regs.config1 |= CFG1_RECVPROMISC; |
467 | } else if (dev->flags & IFF_ALLMULTI) { | 467 | } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) { |
468 | priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI; | 468 | priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI; |
469 | } else | 469 | } else |
470 | priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD; | 470 | priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD; |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 96fb0ec905a..37f1b6ff5c1 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -1519,14 +1519,13 @@ static void b44_setup_pseudo_magicp(struct b44 *bp) | |||
1519 | u8 *pwol_pattern; | 1519 | u8 *pwol_pattern; |
1520 | u8 pwol_mask[B44_PMASK_SIZE]; | 1520 | u8 pwol_mask[B44_PMASK_SIZE]; |
1521 | 1521 | ||
1522 | pwol_pattern = kmalloc(B44_PATTERN_SIZE, GFP_KERNEL); | 1522 | pwol_pattern = kzalloc(B44_PATTERN_SIZE, GFP_KERNEL); |
1523 | if (!pwol_pattern) { | 1523 | if (!pwol_pattern) { |
1524 | printk(KERN_ERR PFX "Memory not available for WOL\n"); | 1524 | printk(KERN_ERR PFX "Memory not available for WOL\n"); |
1525 | return; | 1525 | return; |
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | /* Ipv4 magic packet pattern - pattern 0.*/ | 1528 | /* Ipv4 magic packet pattern - pattern 0.*/ |
1529 | memset(pwol_pattern, 0, B44_PATTERN_SIZE); | ||
1530 | memset(pwol_mask, 0, B44_PMASK_SIZE); | 1529 | memset(pwol_mask, 0, B44_PMASK_SIZE); |
1531 | plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, | 1530 | plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, |
1532 | B44_ETHIPV4UDP_HLEN); | 1531 | B44_ETHIPV4UDP_HLEN); |
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c new file mode 100644 index 00000000000..9a08d656f1c --- /dev/null +++ b/drivers/net/bfin_mac.c | |||
@@ -0,0 +1,1009 @@ | |||
1 | /* | ||
2 | * File: drivers/net/bfin_mac.c | ||
3 | * Based on: | ||
4 | * Maintainer: | ||
5 | * Bryan Wu <bryan.wu@analog.com> | ||
6 | * | ||
7 | * Original author: | ||
8 | * Luke Yang <luke.yang@analog.com> | ||
9 | * | ||
10 | * Created: | ||
11 | * Description: | ||
12 | * | ||
13 | * Modified: | ||
14 | * Copyright 2004-2006 Analog Devices Inc. | ||
15 | * | ||
16 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
17 | * | ||
18 | * This program is free software ; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation ; either version 2, or (at your option) | ||
21 | * any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program ; see the file COPYING. | ||
30 | * If not, write to the Free Software Foundation, | ||
31 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
32 | */ | ||
33 | |||
34 | #include <linux/init.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/sched.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/delay.h> | ||
40 | #include <linux/timer.h> | ||
41 | #include <linux/errno.h> | ||
42 | #include <linux/irq.h> | ||
43 | #include <linux/io.h> | ||
44 | #include <linux/ioport.h> | ||
45 | #include <linux/crc32.h> | ||
46 | #include <linux/device.h> | ||
47 | #include <linux/spinlock.h> | ||
48 | #include <linux/ethtool.h> | ||
49 | #include <linux/mii.h> | ||
50 | |||
51 | #include <linux/netdevice.h> | ||
52 | #include <linux/etherdevice.h> | ||
53 | #include <linux/skbuff.h> | ||
54 | |||
55 | #include <linux/platform_device.h> | ||
56 | #include <linux/netdevice.h> | ||
57 | #include <linux/etherdevice.h> | ||
58 | #include <linux/skbuff.h> | ||
59 | |||
60 | #include <asm/dma.h> | ||
61 | #include <linux/dma-mapping.h> | ||
62 | |||
63 | #include <asm/blackfin.h> | ||
64 | #include <asm/cacheflush.h> | ||
65 | #include <asm/portmux.h> | ||
66 | |||
67 | #include "bfin_mac.h" | ||
68 | |||
69 | #define DRV_NAME "bfin_mac" | ||
70 | #define DRV_VERSION "1.1" | ||
71 | #define DRV_AUTHOR "Bryan Wu, Luke Yang" | ||
72 | #define DRV_DESC "Blackfin BF53[67] on-chip Ethernet MAC driver" | ||
73 | |||
74 | MODULE_AUTHOR(DRV_AUTHOR); | ||
75 | MODULE_LICENSE("GPL"); | ||
76 | MODULE_DESCRIPTION(DRV_DESC); | ||
77 | |||
78 | #if defined(CONFIG_BFIN_MAC_USE_L1) | ||
79 | # define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size) | ||
80 | # define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr) | ||
81 | #else | ||
82 | # define bfin_mac_alloc(dma_handle, size) \ | ||
83 | dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL) | ||
84 | # define bfin_mac_free(dma_handle, ptr) \ | ||
85 | dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle) | ||
86 | #endif | ||
87 | |||
88 | #define PKT_BUF_SZ 1580 | ||
89 | |||
90 | #define MAX_TIMEOUT_CNT 500 | ||
91 | |||
92 | /* pointers to maintain transmit list */ | ||
93 | static struct net_dma_desc_tx *tx_list_head; | ||
94 | static struct net_dma_desc_tx *tx_list_tail; | ||
95 | static struct net_dma_desc_rx *rx_list_head; | ||
96 | static struct net_dma_desc_rx *rx_list_tail; | ||
97 | static struct net_dma_desc_rx *current_rx_ptr; | ||
98 | static struct net_dma_desc_tx *current_tx_ptr; | ||
99 | static struct net_dma_desc_tx *tx_desc; | ||
100 | static struct net_dma_desc_rx *rx_desc; | ||
101 | |||
102 | static void desc_list_free(void) | ||
103 | { | ||
104 | struct net_dma_desc_rx *r; | ||
105 | struct net_dma_desc_tx *t; | ||
106 | int i; | ||
107 | #if !defined(CONFIG_BFIN_MAC_USE_L1) | ||
108 | dma_addr_t dma_handle = 0; | ||
109 | #endif | ||
110 | |||
111 | if (tx_desc) { | ||
112 | t = tx_list_head; | ||
113 | for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) { | ||
114 | if (t) { | ||
115 | if (t->skb) { | ||
116 | dev_kfree_skb(t->skb); | ||
117 | t->skb = NULL; | ||
118 | } | ||
119 | t = t->next; | ||
120 | } | ||
121 | } | ||
122 | bfin_mac_free(dma_handle, tx_desc); | ||
123 | } | ||
124 | |||
125 | if (rx_desc) { | ||
126 | r = rx_list_head; | ||
127 | for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) { | ||
128 | if (r) { | ||
129 | if (r->skb) { | ||
130 | dev_kfree_skb(r->skb); | ||
131 | r->skb = NULL; | ||
132 | } | ||
133 | r = r->next; | ||
134 | } | ||
135 | } | ||
136 | bfin_mac_free(dma_handle, rx_desc); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | static int desc_list_init(void) | ||
141 | { | ||
142 | int i; | ||
143 | struct sk_buff *new_skb; | ||
144 | #if !defined(CONFIG_BFIN_MAC_USE_L1) | ||
145 | /* | ||
146 | * This dma_handle is useless in Blackfin dma_alloc_coherent(). | ||
147 | * The real dma handler is the return value of dma_alloc_coherent(). | ||
148 | */ | ||
149 | dma_addr_t dma_handle; | ||
150 | #endif | ||
151 | |||
152 | tx_desc = bfin_mac_alloc(&dma_handle, | ||
153 | sizeof(struct net_dma_desc_tx) * | ||
154 | CONFIG_BFIN_TX_DESC_NUM); | ||
155 | if (tx_desc == NULL) | ||
156 | goto init_error; | ||
157 | |||
158 | rx_desc = bfin_mac_alloc(&dma_handle, | ||
159 | sizeof(struct net_dma_desc_rx) * | ||
160 | CONFIG_BFIN_RX_DESC_NUM); | ||
161 | if (rx_desc == NULL) | ||
162 | goto init_error; | ||
163 | |||
164 | /* init tx_list */ | ||
165 | tx_list_head = tx_list_tail = tx_desc; | ||
166 | |||
167 | for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) { | ||
168 | struct net_dma_desc_tx *t = tx_desc + i; | ||
169 | struct dma_descriptor *a = &(t->desc_a); | ||
170 | struct dma_descriptor *b = &(t->desc_b); | ||
171 | |||
172 | /* | ||
173 | * disable DMA | ||
174 | * read from memory WNR = 0 | ||
175 | * wordsize is 32 bits | ||
176 | * 6 half words is desc size | ||
177 | * large desc flow | ||
178 | */ | ||
179 | a->config = WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE; | ||
180 | a->start_addr = (unsigned long)t->packet; | ||
181 | a->x_count = 0; | ||
182 | a->next_dma_desc = b; | ||
183 | |||
184 | /* | ||
185 | * enabled DMA | ||
186 | * write to memory WNR = 1 | ||
187 | * wordsize is 32 bits | ||
188 | * disable interrupt | ||
189 | * 6 half words is desc size | ||
190 | * large desc flow | ||
191 | */ | ||
192 | b->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE; | ||
193 | b->start_addr = (unsigned long)(&(t->status)); | ||
194 | b->x_count = 0; | ||
195 | |||
196 | t->skb = NULL; | ||
197 | tx_list_tail->desc_b.next_dma_desc = a; | ||
198 | tx_list_tail->next = t; | ||
199 | tx_list_tail = t; | ||
200 | } | ||
201 | tx_list_tail->next = tx_list_head; /* tx_list is a circle */ | ||
202 | tx_list_tail->desc_b.next_dma_desc = &(tx_list_head->desc_a); | ||
203 | current_tx_ptr = tx_list_head; | ||
204 | |||
205 | /* init rx_list */ | ||
206 | rx_list_head = rx_list_tail = rx_desc; | ||
207 | |||
208 | for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) { | ||
209 | struct net_dma_desc_rx *r = rx_desc + i; | ||
210 | struct dma_descriptor *a = &(r->desc_a); | ||
211 | struct dma_descriptor *b = &(r->desc_b); | ||
212 | |||
213 | /* allocate a new skb for next time receive */ | ||
214 | new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); | ||
215 | if (!new_skb) { | ||
216 | printk(KERN_NOTICE DRV_NAME | ||
217 | ": init: low on mem - packet dropped\n"); | ||
218 | goto init_error; | ||
219 | } | ||
220 | skb_reserve(new_skb, 2); | ||
221 | r->skb = new_skb; | ||
222 | |||
223 | /* | ||
224 | * enabled DMA | ||
225 | * write to memory WNR = 1 | ||
226 | * wordsize is 32 bits | ||
227 | * disable interrupt | ||
228 | * 6 half words is desc size | ||
229 | * large desc flow | ||
230 | */ | ||
231 | a->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE; | ||
232 | /* since RXDWA is enabled */ | ||
233 | a->start_addr = (unsigned long)new_skb->data - 2; | ||
234 | a->x_count = 0; | ||
235 | a->next_dma_desc = b; | ||
236 | |||
237 | /* | ||
238 | * enabled DMA | ||
239 | * write to memory WNR = 1 | ||
240 | * wordsize is 32 bits | ||
241 | * enable interrupt | ||
242 | * 6 half words is desc size | ||
243 | * large desc flow | ||
244 | */ | ||
245 | b->config = DMAEN | WNR | WDSIZE_32 | DI_EN | | ||
246 | NDSIZE_6 | DMAFLOW_LARGE; | ||
247 | b->start_addr = (unsigned long)(&(r->status)); | ||
248 | b->x_count = 0; | ||
249 | |||
250 | rx_list_tail->desc_b.next_dma_desc = a; | ||
251 | rx_list_tail->next = r; | ||
252 | rx_list_tail = r; | ||
253 | } | ||
254 | rx_list_tail->next = rx_list_head; /* rx_list is a circle */ | ||
255 | rx_list_tail->desc_b.next_dma_desc = &(rx_list_head->desc_a); | ||
256 | current_rx_ptr = rx_list_head; | ||
257 | |||
258 | return 0; | ||
259 | |||
260 | init_error: | ||
261 | desc_list_free(); | ||
262 | printk(KERN_ERR DRV_NAME ": kmalloc failed\n"); | ||
263 | return -ENOMEM; | ||
264 | } | ||
265 | |||
266 | |||
267 | /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ | ||
268 | |||
269 | /* Set FER regs to MUX in Ethernet pins */ | ||
270 | static int setup_pin_mux(int action) | ||
271 | { | ||
272 | #if defined(CONFIG_BFIN_MAC_RMII) | ||
273 | u16 pin_req[] = P_RMII0; | ||
274 | #else | ||
275 | u16 pin_req[] = P_MII0; | ||
276 | #endif | ||
277 | |||
278 | if (action) { | ||
279 | if (peripheral_request_list(pin_req, DRV_NAME)) { | ||
280 | printk(KERN_ERR DRV_NAME | ||
281 | ": Requesting Peripherals failed\n"); | ||
282 | return -EFAULT; | ||
283 | } | ||
284 | } else | ||
285 | peripheral_free_list(pin_req); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | /* Wait until the previous MDC/MDIO transaction has completed */ | ||
291 | static void poll_mdc_done(void) | ||
292 | { | ||
293 | int timeout_cnt = MAX_TIMEOUT_CNT; | ||
294 | |||
295 | /* poll the STABUSY bit */ | ||
296 | while ((bfin_read_EMAC_STAADD()) & STABUSY) { | ||
297 | mdelay(10); | ||
298 | if (timeout_cnt-- < 0) { | ||
299 | printk(KERN_ERR DRV_NAME | ||
300 | ": wait MDC/MDIO transaction to complete timeout\n"); | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | |||
306 | /* Read an off-chip register in a PHY through the MDC/MDIO port */ | ||
307 | static u16 read_phy_reg(u16 PHYAddr, u16 RegAddr) | ||
308 | { | ||
309 | poll_mdc_done(); | ||
310 | /* read mode */ | ||
311 | bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) | | ||
312 | SET_REGAD(RegAddr) | | ||
313 | STABUSY); | ||
314 | poll_mdc_done(); | ||
315 | |||
316 | return (u16) bfin_read_EMAC_STADAT(); | ||
317 | } | ||
318 | |||
319 | /* Write an off-chip register in a PHY through the MDC/MDIO port */ | ||
320 | static void raw_write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data) | ||
321 | { | ||
322 | bfin_write_EMAC_STADAT(Data); | ||
323 | |||
324 | /* write mode */ | ||
325 | bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) | | ||
326 | SET_REGAD(RegAddr) | | ||
327 | STAOP | | ||
328 | STABUSY); | ||
329 | |||
330 | poll_mdc_done(); | ||
331 | } | ||
332 | |||
333 | static void write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data) | ||
334 | { | ||
335 | poll_mdc_done(); | ||
336 | raw_write_phy_reg(PHYAddr, RegAddr, Data); | ||
337 | } | ||
338 | |||
339 | /* set up the phy */ | ||
340 | static void bf537mac_setphy(struct net_device *dev) | ||
341 | { | ||
342 | u16 phydat; | ||
343 | struct bf537mac_local *lp = netdev_priv(dev); | ||
344 | |||
345 | /* Program PHY registers */ | ||
346 | pr_debug("start setting up phy\n"); | ||
347 | |||
348 | /* issue a reset */ | ||
349 | raw_write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, 0x8000); | ||
350 | |||
351 | /* wait half a second */ | ||
352 | msleep(500); | ||
353 | |||
354 | phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL); | ||
355 | |||
356 | /* advertise flow control supported */ | ||
357 | phydat = read_phy_reg(lp->PhyAddr, PHYREG_ANAR); | ||
358 | phydat |= (1 << 10); | ||
359 | write_phy_reg(lp->PhyAddr, PHYREG_ANAR, phydat); | ||
360 | |||
361 | phydat = 0; | ||
362 | if (lp->Negotiate) | ||
363 | phydat |= 0x1000; /* enable auto negotiation */ | ||
364 | else { | ||
365 | if (lp->FullDuplex) | ||
366 | phydat |= (1 << 8); /* full duplex */ | ||
367 | else | ||
368 | phydat &= (~(1 << 8)); /* half duplex */ | ||
369 | |||
370 | if (!lp->Port10) | ||
371 | phydat |= (1 << 13); /* 100 Mbps */ | ||
372 | else | ||
373 | phydat &= (~(1 << 13)); /* 10 Mbps */ | ||
374 | } | ||
375 | |||
376 | if (lp->Loopback) | ||
377 | phydat |= (1 << 14); /* enable TX->RX loopback */ | ||
378 | |||
379 | write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, phydat); | ||
380 | msleep(500); | ||
381 | |||
382 | phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL); | ||
383 | /* check for SMSC PHY */ | ||
384 | if ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID1) == 0x7) && | ||
385 | ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID2) & 0xfff0) == 0xC0A0)) { | ||
386 | /* | ||
387 | * we have SMSC PHY so reqest interrupt | ||
388 | * on link down condition | ||
389 | */ | ||
390 | |||
391 | /* enable interrupts */ | ||
392 | write_phy_reg(lp->PhyAddr, 30, 0x0ff); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | /**************************************************************************/ | ||
397 | void setup_system_regs(struct net_device *dev) | ||
398 | { | ||
399 | int phyaddr; | ||
400 | unsigned short sysctl, phydat; | ||
401 | u32 opmode; | ||
402 | struct bf537mac_local *lp = netdev_priv(dev); | ||
403 | int count = 0; | ||
404 | |||
405 | phyaddr = lp->PhyAddr; | ||
406 | |||
407 | /* Enable PHY output */ | ||
408 | if (!(bfin_read_VR_CTL() & PHYCLKOE)) | ||
409 | bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); | ||
410 | |||
411 | /* MDC = 2.5 MHz */ | ||
412 | sysctl = SET_MDCDIV(24); | ||
413 | /* Odd word alignment for Receive Frame DMA word */ | ||
414 | /* Configure checksum support and rcve frame word alignment */ | ||
415 | #if defined(BFIN_MAC_CSUM_OFFLOAD) | ||
416 | sysctl |= RXDWA | RXCKS; | ||
417 | #else | ||
418 | sysctl |= RXDWA; | ||
419 | #endif | ||
420 | bfin_write_EMAC_SYSCTL(sysctl); | ||
421 | /* auto negotiation on */ | ||
422 | /* full duplex */ | ||
423 | /* 100 Mbps */ | ||
424 | phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET; | ||
425 | write_phy_reg(phyaddr, PHYREG_MODECTL, phydat); | ||
426 | |||
427 | /* test if full duplex supported */ | ||
428 | do { | ||
429 | msleep(100); | ||
430 | phydat = read_phy_reg(phyaddr, PHYREG_MODESTAT); | ||
431 | if (count > 30) { | ||
432 | printk(KERN_NOTICE DRV_NAME ": Link is down\n"); | ||
433 | printk(KERN_NOTICE DRV_NAME | ||
434 | "please check your network connection\n"); | ||
435 | break; | ||
436 | } | ||
437 | count++; | ||
438 | } while (!(phydat & 0x0004)); | ||
439 | |||
440 | phydat = read_phy_reg(phyaddr, PHYREG_ANLPAR); | ||
441 | |||
442 | if ((phydat & 0x0100) || (phydat & 0x0040)) { | ||
443 | opmode = FDMODE; | ||
444 | } else { | ||
445 | opmode = 0; | ||
446 | printk(KERN_INFO DRV_NAME | ||
447 | ": Network is set to half duplex\n"); | ||
448 | } | ||
449 | |||
450 | #if defined(CONFIG_BFIN_MAC_RMII) | ||
451 | opmode |= RMII; /* For Now only 100MBit are supported */ | ||
452 | #endif | ||
453 | |||
454 | bfin_write_EMAC_OPMODE(opmode); | ||
455 | |||
456 | bfin_write_EMAC_MMC_CTL(RSTC | CROLL); | ||
457 | |||
458 | /* Initialize the TX DMA channel registers */ | ||
459 | bfin_write_DMA2_X_COUNT(0); | ||
460 | bfin_write_DMA2_X_MODIFY(4); | ||
461 | bfin_write_DMA2_Y_COUNT(0); | ||
462 | bfin_write_DMA2_Y_MODIFY(0); | ||
463 | |||
464 | /* Initialize the RX DMA channel registers */ | ||
465 | bfin_write_DMA1_X_COUNT(0); | ||
466 | bfin_write_DMA1_X_MODIFY(4); | ||
467 | bfin_write_DMA1_Y_COUNT(0); | ||
468 | bfin_write_DMA1_Y_MODIFY(0); | ||
469 | } | ||
470 | |||
471 | void setup_mac_addr(u8 * mac_addr) | ||
472 | { | ||
473 | u32 addr_low = le32_to_cpu(*(__le32 *) & mac_addr[0]); | ||
474 | u16 addr_hi = le16_to_cpu(*(__le16 *) & mac_addr[4]); | ||
475 | |||
476 | /* this depends on a little-endian machine */ | ||
477 | bfin_write_EMAC_ADDRLO(addr_low); | ||
478 | bfin_write_EMAC_ADDRHI(addr_hi); | ||
479 | } | ||
480 | |||
481 | static void adjust_tx_list(void) | ||
482 | { | ||
483 | int timeout_cnt = MAX_TIMEOUT_CNT; | ||
484 | |||
485 | if (tx_list_head->status.status_word != 0 | ||
486 | && current_tx_ptr != tx_list_head) { | ||
487 | goto adjust_head; /* released something, just return; */ | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * if nothing released, check wait condition | ||
492 | * current's next can not be the head, | ||
493 | * otherwise the dma will not stop as we want | ||
494 | */ | ||
495 | if (current_tx_ptr->next->next == tx_list_head) { | ||
496 | while (tx_list_head->status.status_word == 0) { | ||
497 | mdelay(10); | ||
498 | if (tx_list_head->status.status_word != 0 | ||
499 | || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) { | ||
500 | goto adjust_head; | ||
501 | } | ||
502 | if (timeout_cnt-- < 0) { | ||
503 | printk(KERN_ERR DRV_NAME | ||
504 | ": wait for adjust tx list head timeout\n"); | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | if (tx_list_head->status.status_word != 0) { | ||
509 | goto adjust_head; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | return; | ||
514 | |||
515 | adjust_head: | ||
516 | do { | ||
517 | tx_list_head->desc_a.config &= ~DMAEN; | ||
518 | tx_list_head->status.status_word = 0; | ||
519 | if (tx_list_head->skb) { | ||
520 | dev_kfree_skb(tx_list_head->skb); | ||
521 | tx_list_head->skb = NULL; | ||
522 | } else { | ||
523 | printk(KERN_ERR DRV_NAME | ||
524 | ": no sk_buff in a transmitted frame!\n"); | ||
525 | } | ||
526 | tx_list_head = tx_list_head->next; | ||
527 | } while (tx_list_head->status.status_word != 0 | ||
528 | && current_tx_ptr != tx_list_head); | ||
529 | return; | ||
530 | |||
531 | } | ||
532 | |||
533 | static int bf537mac_hard_start_xmit(struct sk_buff *skb, | ||
534 | struct net_device *dev) | ||
535 | { | ||
536 | struct bf537mac_local *lp = netdev_priv(dev); | ||
537 | unsigned int data; | ||
538 | |||
539 | current_tx_ptr->skb = skb; | ||
540 | |||
541 | /* | ||
542 | * Is skb->data always 16-bit aligned? | ||
543 | * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)? | ||
544 | */ | ||
545 | if ((((unsigned int)(skb->data)) & 0x02) == 2) { | ||
546 | /* move skb->data to current_tx_ptr payload */ | ||
547 | data = (unsigned int)(skb->data) - 2; | ||
548 | *((unsigned short *)data) = (unsigned short)(skb->len); | ||
549 | current_tx_ptr->desc_a.start_addr = (unsigned long)data; | ||
550 | /* this is important! */ | ||
551 | blackfin_dcache_flush_range(data, (data + (skb->len)) + 2); | ||
552 | |||
553 | } else { | ||
554 | *((unsigned short *)(current_tx_ptr->packet)) = | ||
555 | (unsigned short)(skb->len); | ||
556 | memcpy((char *)(current_tx_ptr->packet + 2), skb->data, | ||
557 | (skb->len)); | ||
558 | current_tx_ptr->desc_a.start_addr = | ||
559 | (unsigned long)current_tx_ptr->packet; | ||
560 | if (current_tx_ptr->status.status_word != 0) | ||
561 | current_tx_ptr->status.status_word = 0; | ||
562 | blackfin_dcache_flush_range((unsigned int)current_tx_ptr-> | ||
563 | packet, | ||
564 | (unsigned int)(current_tx_ptr-> | ||
565 | packet + skb->len) + | ||
566 | 2); | ||
567 | } | ||
568 | |||
569 | /* enable this packet's dma */ | ||
570 | current_tx_ptr->desc_a.config |= DMAEN; | ||
571 | |||
572 | /* tx dma is running, just return */ | ||
573 | if (bfin_read_DMA2_IRQ_STATUS() & 0x08) | ||
574 | goto out; | ||
575 | |||
576 | /* tx dma is not running */ | ||
577 | bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a)); | ||
578 | /* dma enabled, read from memory, size is 6 */ | ||
579 | bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config); | ||
580 | /* Turn on the EMAC tx */ | ||
581 | bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE); | ||
582 | |||
583 | out: | ||
584 | adjust_tx_list(); | ||
585 | current_tx_ptr = current_tx_ptr->next; | ||
586 | dev->trans_start = jiffies; | ||
587 | lp->stats.tx_packets++; | ||
588 | lp->stats.tx_bytes += (skb->len); | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static void bf537mac_rx(struct net_device *dev) | ||
593 | { | ||
594 | struct sk_buff *skb, *new_skb; | ||
595 | struct bf537mac_local *lp = netdev_priv(dev); | ||
596 | unsigned short len; | ||
597 | |||
598 | /* allocate a new skb for next time receive */ | ||
599 | skb = current_rx_ptr->skb; | ||
600 | new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); | ||
601 | if (!new_skb) { | ||
602 | printk(KERN_NOTICE DRV_NAME | ||
603 | ": rx: low on mem - packet dropped\n"); | ||
604 | lp->stats.rx_dropped++; | ||
605 | goto out; | ||
606 | } | ||
607 | /* reserve 2 bytes for RXDWA padding */ | ||
608 | skb_reserve(new_skb, 2); | ||
609 | current_rx_ptr->skb = new_skb; | ||
610 | current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; | ||
611 | |||
612 | len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN); | ||
613 | skb_put(skb, len); | ||
614 | blackfin_dcache_invalidate_range((unsigned long)skb->head, | ||
615 | (unsigned long)skb->tail); | ||
616 | |||
617 | dev->last_rx = jiffies; | ||
618 | skb->dev = dev; | ||
619 | skb->protocol = eth_type_trans(skb, dev); | ||
620 | #if defined(BFIN_MAC_CSUM_OFFLOAD) | ||
621 | skb->csum = current_rx_ptr->status.ip_payload_csum; | ||
622 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
623 | #endif | ||
624 | |||
625 | netif_rx(skb); | ||
626 | lp->stats.rx_packets++; | ||
627 | lp->stats.rx_bytes += len; | ||
628 | current_rx_ptr->status.status_word = 0x00000000; | ||
629 | current_rx_ptr = current_rx_ptr->next; | ||
630 | |||
631 | out: | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | /* interrupt routine to handle rx and error signal */ | ||
636 | static irqreturn_t bf537mac_interrupt(int irq, void *dev_id) | ||
637 | { | ||
638 | struct net_device *dev = dev_id; | ||
639 | int number = 0; | ||
640 | |||
641 | get_one_packet: | ||
642 | if (current_rx_ptr->status.status_word == 0) { | ||
643 | /* no more new packet received */ | ||
644 | if (number == 0) { | ||
645 | if (current_rx_ptr->next->status.status_word != 0) { | ||
646 | current_rx_ptr = current_rx_ptr->next; | ||
647 | goto real_rx; | ||
648 | } | ||
649 | } | ||
650 | bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() | | ||
651 | DMA_DONE | DMA_ERR); | ||
652 | return IRQ_HANDLED; | ||
653 | } | ||
654 | |||
655 | real_rx: | ||
656 | bf537mac_rx(dev); | ||
657 | number++; | ||
658 | goto get_one_packet; | ||
659 | } | ||
660 | |||
661 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
662 | static void bf537mac_poll(struct net_device *dev) | ||
663 | { | ||
664 | disable_irq(IRQ_MAC_RX); | ||
665 | bf537mac_interrupt(IRQ_MAC_RX, dev); | ||
666 | enable_irq(IRQ_MAC_RX); | ||
667 | } | ||
668 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | ||
669 | |||
670 | static void bf537mac_reset(void) | ||
671 | { | ||
672 | unsigned int opmode; | ||
673 | |||
674 | opmode = bfin_read_EMAC_OPMODE(); | ||
675 | opmode &= (~RE); | ||
676 | opmode &= (~TE); | ||
677 | /* Turn off the EMAC */ | ||
678 | bfin_write_EMAC_OPMODE(opmode); | ||
679 | } | ||
680 | |||
681 | /* | ||
682 | * Enable Interrupts, Receive, and Transmit | ||
683 | */ | ||
684 | static int bf537mac_enable(struct net_device *dev) | ||
685 | { | ||
686 | u32 opmode; | ||
687 | |||
688 | pr_debug("%s: %s\n", dev->name, __FUNCTION__); | ||
689 | |||
690 | /* Set RX DMA */ | ||
691 | bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a)); | ||
692 | bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config); | ||
693 | |||
694 | /* Wait MII done */ | ||
695 | poll_mdc_done(); | ||
696 | |||
697 | /* We enable only RX here */ | ||
698 | /* ASTP : Enable Automatic Pad Stripping | ||
699 | PR : Promiscuous Mode for test | ||
700 | PSF : Receive frames with total length less than 64 bytes. | ||
701 | FDMODE : Full Duplex Mode | ||
702 | LB : Internal Loopback for test | ||
703 | RE : Receiver Enable */ | ||
704 | opmode = bfin_read_EMAC_OPMODE(); | ||
705 | if (opmode & FDMODE) | ||
706 | opmode |= PSF; | ||
707 | else | ||
708 | opmode |= DRO | DC | PSF; | ||
709 | opmode |= RE; | ||
710 | |||
711 | #if defined(CONFIG_BFIN_MAC_RMII) | ||
712 | opmode |= RMII; /* For Now only 100MBit are supported */ | ||
713 | #ifdef CONFIG_BF_REV_0_2 | ||
714 | opmode |= TE; | ||
715 | #endif | ||
716 | #endif | ||
717 | /* Turn on the EMAC rx */ | ||
718 | bfin_write_EMAC_OPMODE(opmode); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | /* Our watchdog timed out. Called by the networking layer */ | ||
724 | static void bf537mac_timeout(struct net_device *dev) | ||
725 | { | ||
726 | pr_debug("%s: %s\n", dev->name, __FUNCTION__); | ||
727 | |||
728 | bf537mac_reset(); | ||
729 | |||
730 | /* reset tx queue */ | ||
731 | tx_list_tail = tx_list_head->next; | ||
732 | |||
733 | bf537mac_enable(dev); | ||
734 | |||
735 | /* We can accept TX packets again */ | ||
736 | dev->trans_start = jiffies; | ||
737 | netif_wake_queue(dev); | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Get the current statistics. | ||
742 | * This may be called with the card open or closed. | ||
743 | */ | ||
744 | static struct net_device_stats *bf537mac_query_statistics(struct net_device | ||
745 | *dev) | ||
746 | { | ||
747 | struct bf537mac_local *lp = netdev_priv(dev); | ||
748 | |||
749 | pr_debug("%s: %s\n", dev->name, __FUNCTION__); | ||
750 | |||
751 | return &lp->stats; | ||
752 | } | ||
753 | |||
754 | /* | ||
755 | * This routine will, depending on the values passed to it, | ||
756 | * either make it accept multicast packets, go into | ||
757 | * promiscuous mode (for TCPDUMP and cousins) or accept | ||
758 | * a select set of multicast packets | ||
759 | */ | ||
760 | static void bf537mac_set_multicast_list(struct net_device *dev) | ||
761 | { | ||
762 | u32 sysctl; | ||
763 | |||
764 | if (dev->flags & IFF_PROMISC) { | ||
765 | printk(KERN_INFO "%s: set to promisc mode\n", dev->name); | ||
766 | sysctl = bfin_read_EMAC_OPMODE(); | ||
767 | sysctl |= RAF; | ||
768 | bfin_write_EMAC_OPMODE(sysctl); | ||
769 | } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) { | ||
770 | /* accept all multicast */ | ||
771 | sysctl = bfin_read_EMAC_OPMODE(); | ||
772 | sysctl |= PAM; | ||
773 | bfin_write_EMAC_OPMODE(sysctl); | ||
774 | } else { | ||
775 | /* clear promisc or multicast mode */ | ||
776 | sysctl = bfin_read_EMAC_OPMODE(); | ||
777 | sysctl &= ~(RAF | PAM); | ||
778 | bfin_write_EMAC_OPMODE(sysctl); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | /* | ||
783 | * this puts the device in an inactive state | ||
784 | */ | ||
785 | static void bf537mac_shutdown(struct net_device *dev) | ||
786 | { | ||
787 | /* Turn off the EMAC */ | ||
788 | bfin_write_EMAC_OPMODE(0x00000000); | ||
789 | /* Turn off the EMAC RX DMA */ | ||
790 | bfin_write_DMA1_CONFIG(0x0000); | ||
791 | bfin_write_DMA2_CONFIG(0x0000); | ||
792 | } | ||
793 | |||
794 | /* | ||
795 | * Open and Initialize the interface | ||
796 | * | ||
797 | * Set up everything, reset the card, etc.. | ||
798 | */ | ||
799 | static int bf537mac_open(struct net_device *dev) | ||
800 | { | ||
801 | pr_debug("%s: %s\n", dev->name, __FUNCTION__); | ||
802 | |||
803 | /* | ||
804 | * Check that the address is valid. If its not, refuse | ||
805 | * to bring the device up. The user must specify an | ||
806 | * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx | ||
807 | */ | ||
808 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
809 | printk(KERN_WARNING DRV_NAME ": no valid ethernet hw addr\n"); | ||
810 | return -EINVAL; | ||
811 | } | ||
812 | |||
813 | /* initial rx and tx list */ | ||
814 | desc_list_init(); | ||
815 | |||
816 | bf537mac_setphy(dev); | ||
817 | setup_system_regs(dev); | ||
818 | bf537mac_reset(); | ||
819 | bf537mac_enable(dev); | ||
820 | |||
821 | pr_debug("hardware init finished\n"); | ||
822 | netif_start_queue(dev); | ||
823 | netif_carrier_on(dev); | ||
824 | |||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | /* | ||
829 | * | ||
830 | * this makes the board clean up everything that it can | ||
831 | * and not talk to the outside world. Caused by | ||
832 | * an 'ifconfig ethX down' | ||
833 | */ | ||
834 | static int bf537mac_close(struct net_device *dev) | ||
835 | { | ||
836 | pr_debug("%s: %s\n", dev->name, __FUNCTION__); | ||
837 | |||
838 | netif_stop_queue(dev); | ||
839 | netif_carrier_off(dev); | ||
840 | |||
841 | /* clear everything */ | ||
842 | bf537mac_shutdown(dev); | ||
843 | |||
844 | /* free the rx/tx buffers */ | ||
845 | desc_list_free(); | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static int __init bf537mac_probe(struct net_device *dev) | ||
851 | { | ||
852 | struct bf537mac_local *lp = netdev_priv(dev); | ||
853 | int retval; | ||
854 | |||
855 | /* Grab the MAC address in the MAC */ | ||
856 | *(__le32 *) (&(dev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO()); | ||
857 | *(__le16 *) (&(dev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI()); | ||
858 | |||
859 | /* probe mac */ | ||
860 | /*todo: how to proble? which is revision_register */ | ||
861 | bfin_write_EMAC_ADDRLO(0x12345678); | ||
862 | if (bfin_read_EMAC_ADDRLO() != 0x12345678) { | ||
863 | pr_debug("can't detect bf537 mac!\n"); | ||
864 | retval = -ENODEV; | ||
865 | goto err_out; | ||
866 | } | ||
867 | |||
868 | /* set the GPIO pins to Ethernet mode */ | ||
869 | retval = setup_pin_mux(1); | ||
870 | |||
871 | if (retval) | ||
872 | return retval; | ||
873 | |||
874 | /*Is it valid? (Did bootloader initialize it?) */ | ||
875 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
876 | /* Grab the MAC from the board somehow - this is done in the | ||
877 | arch/blackfin/mach-bf537/boards/eth_mac.c */ | ||
878 | get_bf537_ether_addr(dev->dev_addr); | ||
879 | } | ||
880 | |||
881 | /* If still not valid, get a random one */ | ||
882 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
883 | random_ether_addr(dev->dev_addr); | ||
884 | } | ||
885 | |||
886 | setup_mac_addr(dev->dev_addr); | ||
887 | |||
888 | /* Fill in the fields of the device structure with ethernet values. */ | ||
889 | ether_setup(dev); | ||
890 | |||
891 | dev->open = bf537mac_open; | ||
892 | dev->stop = bf537mac_close; | ||
893 | dev->hard_start_xmit = bf537mac_hard_start_xmit; | ||
894 | dev->tx_timeout = bf537mac_timeout; | ||
895 | dev->get_stats = bf537mac_query_statistics; | ||
896 | dev->set_multicast_list = bf537mac_set_multicast_list; | ||
897 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
898 | dev->poll_controller = bf537mac_poll; | ||
899 | #endif | ||
900 | |||
901 | /* fill in some of the fields */ | ||
902 | lp->version = 1; | ||
903 | lp->PhyAddr = 0x01; | ||
904 | lp->CLKIN = 25; | ||
905 | lp->FullDuplex = 0; | ||
906 | lp->Negotiate = 1; | ||
907 | lp->FlowControl = 0; | ||
908 | spin_lock_init(&lp->lock); | ||
909 | |||
910 | /* now, enable interrupts */ | ||
911 | /* register irq handler */ | ||
912 | if (request_irq | ||
913 | (IRQ_MAC_RX, bf537mac_interrupt, IRQF_DISABLED | IRQF_SHARED, | ||
914 | "BFIN537_MAC_RX", dev)) { | ||
915 | printk(KERN_WARNING DRV_NAME | ||
916 | ": Unable to attach BlackFin MAC RX interrupt\n"); | ||
917 | return -EBUSY; | ||
918 | } | ||
919 | |||
920 | /* Enable PHY output early */ | ||
921 | if (!(bfin_read_VR_CTL() & PHYCLKOE)) | ||
922 | bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); | ||
923 | |||
924 | retval = register_netdev(dev); | ||
925 | if (retval == 0) { | ||
926 | /* now, print out the card info, in a short format.. */ | ||
927 | printk(KERN_INFO "%s: Version %s, %s\n", | ||
928 | DRV_NAME, DRV_VERSION, DRV_DESC); | ||
929 | } | ||
930 | |||
931 | err_out: | ||
932 | return retval; | ||
933 | } | ||
934 | |||
935 | static int bfin_mac_probe(struct platform_device *pdev) | ||
936 | { | ||
937 | struct net_device *ndev; | ||
938 | |||
939 | ndev = alloc_etherdev(sizeof(struct bf537mac_local)); | ||
940 | if (!ndev) { | ||
941 | printk(KERN_WARNING DRV_NAME ": could not allocate device\n"); | ||
942 | return -ENOMEM; | ||
943 | } | ||
944 | |||
945 | SET_MODULE_OWNER(ndev); | ||
946 | SET_NETDEV_DEV(ndev, &pdev->dev); | ||
947 | |||
948 | platform_set_drvdata(pdev, ndev); | ||
949 | |||
950 | if (bf537mac_probe(ndev) != 0) { | ||
951 | platform_set_drvdata(pdev, NULL); | ||
952 | free_netdev(ndev); | ||
953 | printk(KERN_WARNING DRV_NAME ": not found\n"); | ||
954 | return -ENODEV; | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static int bfin_mac_remove(struct platform_device *pdev) | ||
961 | { | ||
962 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
963 | |||
964 | platform_set_drvdata(pdev, NULL); | ||
965 | |||
966 | unregister_netdev(ndev); | ||
967 | |||
968 | free_irq(IRQ_MAC_RX, ndev); | ||
969 | |||
970 | free_netdev(ndev); | ||
971 | |||
972 | setup_pin_mux(0); | ||
973 | |||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t state) | ||
978 | { | ||
979 | return 0; | ||
980 | } | ||
981 | |||
982 | static int bfin_mac_resume(struct platform_device *pdev) | ||
983 | { | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static struct platform_driver bfin_mac_driver = { | ||
988 | .probe = bfin_mac_probe, | ||
989 | .remove = bfin_mac_remove, | ||
990 | .resume = bfin_mac_resume, | ||
991 | .suspend = bfin_mac_suspend, | ||
992 | .driver = { | ||
993 | .name = DRV_NAME, | ||
994 | }, | ||
995 | }; | ||
996 | |||
997 | static int __init bfin_mac_init(void) | ||
998 | { | ||
999 | return platform_driver_register(&bfin_mac_driver); | ||
1000 | } | ||
1001 | |||
1002 | module_init(bfin_mac_init); | ||
1003 | |||
1004 | static void __exit bfin_mac_cleanup(void) | ||
1005 | { | ||
1006 | platform_driver_unregister(&bfin_mac_driver); | ||
1007 | } | ||
1008 | |||
1009 | module_exit(bfin_mac_cleanup); | ||
diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h new file mode 100644 index 00000000000..af87189b85f --- /dev/null +++ b/drivers/net/bfin_mac.h | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | * File: drivers/net/bfin_mac.c | ||
3 | * Based on: | ||
4 | * Maintainer: | ||
5 | * Bryan Wu <bryan.wu@analog.com> | ||
6 | * | ||
7 | * Original author: | ||
8 | * Luke Yang <luke.yang@analog.com> | ||
9 | * | ||
10 | * Created: | ||
11 | * Description: | ||
12 | * | ||
13 | * Modified: | ||
14 | * Copyright 2004-2006 Analog Devices Inc. | ||
15 | * | ||
16 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
17 | * | ||
18 | * This program is free software ; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation ; either version 2, or (at your option) | ||
21 | * any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program ; see the file COPYING. | ||
30 | * If not, write to the Free Software Foundation, | ||
31 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
32 | */ | ||
33 | |||
34 | /* | ||
35 | * PHY REGISTER NAMES | ||
36 | */ | ||
37 | #define PHYREG_MODECTL 0x0000 | ||
38 | #define PHYREG_MODESTAT 0x0001 | ||
39 | #define PHYREG_PHYID1 0x0002 | ||
40 | #define PHYREG_PHYID2 0x0003 | ||
41 | #define PHYREG_ANAR 0x0004 | ||
42 | #define PHYREG_ANLPAR 0x0005 | ||
43 | #define PHYREG_ANER 0x0006 | ||
44 | #define PHYREG_NSR 0x0010 | ||
45 | #define PHYREG_LBREMR 0x0011 | ||
46 | #define PHYREG_REC 0x0012 | ||
47 | #define PHYREG_10CFG 0x0013 | ||
48 | #define PHYREG_PHY1_1 0x0014 | ||
49 | #define PHYREG_PHY1_2 0x0015 | ||
50 | #define PHYREG_PHY2 0x0016 | ||
51 | #define PHYREG_TW_1 0x0017 | ||
52 | #define PHYREG_TW_2 0x0018 | ||
53 | #define PHYREG_TEST 0x0019 | ||
54 | |||
55 | #define PHY_RESET 0x8000 | ||
56 | #define PHY_ANEG_EN 0x1000 | ||
57 | #define PHY_DUPLEX 0x0100 | ||
58 | #define PHY_SPD_SET 0x2000 | ||
59 | |||
60 | #define BFIN_MAC_CSUM_OFFLOAD | ||
61 | |||
62 | struct dma_descriptor { | ||
63 | struct dma_descriptor *next_dma_desc; | ||
64 | unsigned long start_addr; | ||
65 | unsigned short config; | ||
66 | unsigned short x_count; | ||
67 | }; | ||
68 | |||
69 | struct status_area_rx { | ||
70 | #if defined(BFIN_MAC_CSUM_OFFLOAD) | ||
71 | unsigned short ip_hdr_csum; /* ip header checksum */ | ||
72 | /* ip payload(udp or tcp or others) checksum */ | ||
73 | unsigned short ip_payload_csum; | ||
74 | #endif | ||
75 | unsigned long status_word; /* the frame status word */ | ||
76 | }; | ||
77 | |||
78 | struct status_area_tx { | ||
79 | unsigned long status_word; /* the frame status word */ | ||
80 | }; | ||
81 | |||
82 | /* use two descriptors for a packet */ | ||
83 | struct net_dma_desc_rx { | ||
84 | struct net_dma_desc_rx *next; | ||
85 | struct sk_buff *skb; | ||
86 | struct dma_descriptor desc_a; | ||
87 | struct dma_descriptor desc_b; | ||
88 | struct status_area_rx status; | ||
89 | }; | ||
90 | |||
91 | /* use two descriptors for a packet */ | ||
92 | struct net_dma_desc_tx { | ||
93 | struct net_dma_desc_tx *next; | ||
94 | struct sk_buff *skb; | ||
95 | struct dma_descriptor desc_a; | ||
96 | struct dma_descriptor desc_b; | ||
97 | unsigned char packet[1560]; | ||
98 | struct status_area_tx status; | ||
99 | }; | ||
100 | |||
101 | struct bf537mac_local { | ||
102 | /* | ||
103 | * these are things that the kernel wants me to keep, so users | ||
104 | * can find out semi-useless statistics of how well the card is | ||
105 | * performing | ||
106 | */ | ||
107 | struct net_device_stats stats; | ||
108 | |||
109 | int version; | ||
110 | |||
111 | int FlowEnabled; /* record if data flow is active */ | ||
112 | int EtherIntIVG; /* IVG for the ethernet interrupt */ | ||
113 | int RXIVG; /* IVG for the RX completion */ | ||
114 | int TXIVG; /* IVG for the TX completion */ | ||
115 | int PhyAddr; /* PHY address */ | ||
116 | int OpMode; /* set these bits n the OPMODE regs */ | ||
117 | int Port10; /* set port speed to 10 Mbit/s */ | ||
118 | int GenChksums; /* IP checksums to be calculated */ | ||
119 | int NoRcveLnth; /* dont insert recv length at start of buffer */ | ||
120 | int StripPads; /* remove trailing pad bytes */ | ||
121 | int FullDuplex; /* set full duplex mode */ | ||
122 | int Negotiate; /* enable auto negotiation */ | ||
123 | int Loopback; /* loopback at the PHY */ | ||
124 | int Cache; /* Buffers may be cached */ | ||
125 | int FlowControl; /* flow control active */ | ||
126 | int CLKIN; /* clock in value in MHZ */ | ||
127 | unsigned short IntMask; /* interrupt mask */ | ||
128 | unsigned char Mac[6]; /* MAC address of the board */ | ||
129 | spinlock_t lock; | ||
130 | }; | ||
131 | |||
132 | extern void get_bf537_ether_addr(char *addr); | ||
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 7845eaf6f29..202d4a4ef75 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c | |||
@@ -395,14 +395,13 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) | |||
395 | * Allocate the main control structure for this instance. | 395 | * Allocate the main control structure for this instance. |
396 | */ | 396 | */ |
397 | maxmaxcode = MAXCODE(bits); | 397 | maxmaxcode = MAXCODE(bits); |
398 | db = kmalloc(sizeof (struct bsd_db), | 398 | db = kzalloc(sizeof (struct bsd_db), |
399 | GFP_KERNEL); | 399 | GFP_KERNEL); |
400 | if (!db) | 400 | if (!db) |
401 | { | 401 | { |
402 | return NULL; | 402 | return NULL; |
403 | } | 403 | } |
404 | 404 | ||
405 | memset (db, 0, sizeof(struct bsd_db)); | ||
406 | /* | 405 | /* |
407 | * Allocate space for the dictionary. This may be more than one page in | 406 | * Allocate space for the dictionary. This may be more than one page in |
408 | * length. | 407 | * length. |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 6628fa622e2..489c8b260dd 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ehea" | 41 | #define DRV_NAME "ehea" |
42 | #define DRV_VERSION "EHEA_0070" | 42 | #define DRV_VERSION "EHEA_0071" |
43 | 43 | ||
44 | /* eHEA capability flags */ | 44 | /* eHEA capability flags */ |
45 | #define DLPAR_PORT_ADD_REM 1 | 45 | #define DLPAR_PORT_ADD_REM 1 |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 1d1571cf322..4c70a9301c1 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -466,6 +466,8 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev, | |||
466 | cqe->vlan_tag); | 466 | cqe->vlan_tag); |
467 | else | 467 | else |
468 | netif_receive_skb(skb); | 468 | netif_receive_skb(skb); |
469 | |||
470 | dev->last_rx = jiffies; | ||
469 | } else { | 471 | } else { |
470 | pr->p_stats.poll_receive_errors++; | 472 | pr->p_stats.poll_receive_errors++; |
471 | port_reset = ehea_treat_poll_error(pr, rq, cqe, | 473 | port_reset = ehea_treat_poll_error(pr, rq, cqe, |
@@ -1433,7 +1435,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) | |||
1433 | port->logical_port_id, | 1435 | port->logical_port_id, |
1434 | reg_type, port->mac_addr, 0, hcallid); | 1436 | reg_type, port->mac_addr, 0, hcallid); |
1435 | if (hret != H_SUCCESS) { | 1437 | if (hret != H_SUCCESS) { |
1436 | ehea_error("reg_dereg_bcmc failed (tagged)"); | 1438 | ehea_error("%sregistering bc address failed (tagged)", |
1439 | hcallid == H_REG_BCMC ? "" : "de"); | ||
1437 | ret = -EIO; | 1440 | ret = -EIO; |
1438 | goto out_herr; | 1441 | goto out_herr; |
1439 | } | 1442 | } |
@@ -1444,7 +1447,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) | |||
1444 | port->logical_port_id, | 1447 | port->logical_port_id, |
1445 | reg_type, port->mac_addr, 0, hcallid); | 1448 | reg_type, port->mac_addr, 0, hcallid); |
1446 | if (hret != H_SUCCESS) { | 1449 | if (hret != H_SUCCESS) { |
1447 | ehea_error("reg_dereg_bcmc failed (vlan)"); | 1450 | ehea_error("%sregistering bc address failed (vlan)", |
1451 | hcallid == H_REG_BCMC ? "" : "de"); | ||
1448 | ret = -EIO; | 1452 | ret = -EIO; |
1449 | } | 1453 | } |
1450 | out_herr: | 1454 | out_herr: |
@@ -2170,7 +2174,6 @@ static int ehea_up(struct net_device *dev) | |||
2170 | { | 2174 | { |
2171 | int ret, i; | 2175 | int ret, i; |
2172 | struct ehea_port *port = netdev_priv(dev); | 2176 | struct ehea_port *port = netdev_priv(dev); |
2173 | u64 mac_addr = 0; | ||
2174 | 2177 | ||
2175 | if (port->state == EHEA_PORT_UP) | 2178 | if (port->state == EHEA_PORT_UP) |
2176 | return 0; | 2179 | return 0; |
@@ -2189,18 +2192,10 @@ static int ehea_up(struct net_device *dev) | |||
2189 | goto out_clean_pr; | 2192 | goto out_clean_pr; |
2190 | } | 2193 | } |
2191 | 2194 | ||
2192 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | ||
2193 | if (ret) { | ||
2194 | ret = -EIO; | ||
2195 | ehea_error("out_clean_pr"); | ||
2196 | goto out_clean_pr; | ||
2197 | } | ||
2198 | mac_addr = (*(u64*)dev->dev_addr) >> 16; | ||
2199 | |||
2200 | ret = ehea_reg_interrupts(dev); | 2195 | ret = ehea_reg_interrupts(dev); |
2201 | if (ret) { | 2196 | if (ret) { |
2202 | ehea_error("out_dereg_bc"); | 2197 | ehea_error("reg_interrupts failed. ret:%d", ret); |
2203 | goto out_dereg_bc; | 2198 | goto out_clean_pr; |
2204 | } | 2199 | } |
2205 | 2200 | ||
2206 | for(i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | 2201 | for(i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { |
@@ -2226,9 +2221,6 @@ static int ehea_up(struct net_device *dev) | |||
2226 | out_free_irqs: | 2221 | out_free_irqs: |
2227 | ehea_free_interrupts(dev); | 2222 | ehea_free_interrupts(dev); |
2228 | 2223 | ||
2229 | out_dereg_bc: | ||
2230 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | ||
2231 | |||
2232 | out_clean_pr: | 2224 | out_clean_pr: |
2233 | ehea_clean_all_portres(port); | 2225 | ehea_clean_all_portres(port); |
2234 | out: | 2226 | out: |
@@ -2273,7 +2265,6 @@ static int ehea_down(struct net_device *dev) | |||
2273 | &port->port_res[i].d_netdev->state)) | 2265 | &port->port_res[i].d_netdev->state)) |
2274 | msleep(1); | 2266 | msleep(1); |
2275 | 2267 | ||
2276 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | ||
2277 | port->state = EHEA_PORT_DOWN; | 2268 | port->state = EHEA_PORT_DOWN; |
2278 | 2269 | ||
2279 | ret = ehea_clean_all_portres(port); | 2270 | ret = ehea_clean_all_portres(port); |
@@ -2655,12 +2646,18 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
2655 | 2646 | ||
2656 | INIT_WORK(&port->reset_task, ehea_reset_port); | 2647 | INIT_WORK(&port->reset_task, ehea_reset_port); |
2657 | 2648 | ||
2649 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | ||
2650 | if (ret) { | ||
2651 | ret = -EIO; | ||
2652 | goto out_unreg_port; | ||
2653 | } | ||
2654 | |||
2658 | ehea_set_ethtool_ops(dev); | 2655 | ehea_set_ethtool_ops(dev); |
2659 | 2656 | ||
2660 | ret = register_netdev(dev); | 2657 | ret = register_netdev(dev); |
2661 | if (ret) { | 2658 | if (ret) { |
2662 | ehea_error("register_netdev failed. ret=%d", ret); | 2659 | ehea_error("register_netdev failed. ret=%d", ret); |
2663 | goto out_unreg_port; | 2660 | goto out_dereg_bc; |
2664 | } | 2661 | } |
2665 | 2662 | ||
2666 | ret = ehea_get_jumboframe_status(port, &jumbo); | 2663 | ret = ehea_get_jumboframe_status(port, &jumbo); |
@@ -2675,6 +2672,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
2675 | 2672 | ||
2676 | return port; | 2673 | return port; |
2677 | 2674 | ||
2675 | out_dereg_bc: | ||
2676 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | ||
2677 | |||
2678 | out_unreg_port: | 2678 | out_unreg_port: |
2679 | ehea_unregister_port(port); | 2679 | ehea_unregister_port(port); |
2680 | 2680 | ||
@@ -2694,6 +2694,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port) | |||
2694 | { | 2694 | { |
2695 | unregister_netdev(port->netdev); | 2695 | unregister_netdev(port->netdev); |
2696 | ehea_unregister_port(port); | 2696 | ehea_unregister_port(port); |
2697 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | ||
2697 | kfree(port->mc_list); | 2698 | kfree(port->mc_list); |
2698 | free_netdev(port->netdev); | 2699 | free_netdev(port->netdev); |
2699 | port->adapter->active_ports--; | 2700 | port->adapter->active_ports--; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 136827f8dc2..6d1d50a1978 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -5137,12 +5137,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5137 | goto out_unmap; | 5137 | goto out_unmap; |
5138 | np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; | 5138 | np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; |
5139 | } | 5139 | } |
5140 | np->rx_skb = kmalloc(sizeof(struct nv_skb_map) * np->rx_ring_size, GFP_KERNEL); | 5140 | np->rx_skb = kcalloc(np->rx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL); |
5141 | np->tx_skb = kmalloc(sizeof(struct nv_skb_map) * np->tx_ring_size, GFP_KERNEL); | 5141 | np->tx_skb = kcalloc(np->tx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL); |
5142 | if (!np->rx_skb || !np->tx_skb) | 5142 | if (!np->rx_skb || !np->tx_skb) |
5143 | goto out_freering; | 5143 | goto out_freering; |
5144 | memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size); | ||
5145 | memset(np->tx_skb, 0, sizeof(struct nv_skb_map) * np->tx_ring_size); | ||
5146 | 5144 | ||
5147 | dev->open = nv_open; | 5145 | dev->open = nv_open; |
5148 | dev->stop = nv_close; | 5146 | dev->stop = nv_close; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index d7a1a58de76..f92690555dd 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -420,8 +420,18 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) | |||
420 | if (ecntrl & ECNTRL_REDUCED_MODE) { | 420 | if (ecntrl & ECNTRL_REDUCED_MODE) { |
421 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) | 421 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) |
422 | return PHY_INTERFACE_MODE_RMII; | 422 | return PHY_INTERFACE_MODE_RMII; |
423 | else | 423 | else { |
424 | phy_interface_t interface = priv->einfo->interface; | ||
425 | |||
426 | /* | ||
427 | * This isn't autodetected right now, so it must | ||
428 | * be set by the device tree or platform code. | ||
429 | */ | ||
430 | if (interface == PHY_INTERFACE_MODE_RGMII_ID) | ||
431 | return PHY_INTERFACE_MODE_RGMII_ID; | ||
432 | |||
424 | return PHY_INTERFACE_MODE_RGMII; | 433 | return PHY_INTERFACE_MODE_RGMII; |
434 | } | ||
425 | } | 435 | } |
426 | 436 | ||
427 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) | 437 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 3be8c504759..205f0967249 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -453,8 +453,8 @@ static int __init setup_adapter(int card_base, int type, int n) | |||
453 | int scc_base = card_base + hw[type].scc_offset; | 453 | int scc_base = card_base + hw[type].scc_offset; |
454 | char *chipnames[] = CHIPNAMES; | 454 | char *chipnames[] = CHIPNAMES; |
455 | 455 | ||
456 | /* Allocate memory */ | 456 | /* Initialize what is necessary for write_scc and write_scc_data */ |
457 | info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA); | 457 | info = kzalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA); |
458 | if (!info) { | 458 | if (!info) { |
459 | printk(KERN_ERR "dmascc: " | 459 | printk(KERN_ERR "dmascc: " |
460 | "could not allocate memory for %s at %#3x\n", | 460 | "could not allocate memory for %s at %#3x\n", |
@@ -462,8 +462,6 @@ static int __init setup_adapter(int card_base, int type, int n) | |||
462 | goto out; | 462 | goto out; |
463 | } | 463 | } |
464 | 464 | ||
465 | /* Initialize what is necessary for write_scc and write_scc_data */ | ||
466 | memset(info, 0, sizeof(struct scc_info)); | ||
467 | 465 | ||
468 | info->dev[0] = alloc_netdev(0, "", dev_setup); | 466 | info->dev[0] = alloc_netdev(0, "", dev_setup); |
469 | if (!info->dev[0]) { | 467 | if (!info->dev[0]) { |
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 3078c419cb0..20732458f5a 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c | |||
@@ -164,14 +164,13 @@ irport_open(int i, unsigned int iobase, unsigned int irq) | |||
164 | 164 | ||
165 | /* Allocate memory if needed */ | 165 | /* Allocate memory if needed */ |
166 | if (self->tx_buff.truesize > 0) { | 166 | if (self->tx_buff.truesize > 0) { |
167 | self->tx_buff.head = kmalloc(self->tx_buff.truesize, | 167 | self->tx_buff.head = kzalloc(self->tx_buff.truesize, |
168 | GFP_KERNEL); | 168 | GFP_KERNEL); |
169 | if (self->tx_buff.head == NULL) { | 169 | if (self->tx_buff.head == NULL) { |
170 | IRDA_ERROR("%s(), can't allocate memory for " | 170 | IRDA_ERROR("%s(), can't allocate memory for " |
171 | "transmit buffer!\n", __FUNCTION__); | 171 | "transmit buffer!\n", __FUNCTION__); |
172 | goto err_out4; | 172 | goto err_out4; |
173 | } | 173 | } |
174 | memset(self->tx_buff.head, 0, self->tx_buff.truesize); | ||
175 | } | 174 | } |
176 | self->tx_buff.data = self->tx_buff.head; | 175 | self->tx_buff.data = self->tx_buff.head; |
177 | 176 | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index ad1857364d5..6f5f697ec9f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -505,10 +505,9 @@ static int irtty_open(struct tty_struct *tty) | |||
505 | } | 505 | } |
506 | 506 | ||
507 | /* allocate private device info block */ | 507 | /* allocate private device info block */ |
508 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 508 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
509 | if (!priv) | 509 | if (!priv) |
510 | goto out_put; | 510 | goto out_put; |
511 | memset(priv, 0, sizeof(*priv)); | ||
512 | 511 | ||
513 | priv->magic = IRTTY_MAGIC; | 512 | priv->magic = IRTTY_MAGIC; |
514 | priv->tty = tty; | 513 | priv->tty = tty; |
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 347d50cd77d..0433c41f902 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -822,10 +822,9 @@ static int veth_init_connection(u8 rlp) | |||
822 | || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) ) | 822 | || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) ) |
823 | return 0; | 823 | return 0; |
824 | 824 | ||
825 | cnx = kmalloc(sizeof(*cnx), GFP_KERNEL); | 825 | cnx = kzalloc(sizeof(*cnx), GFP_KERNEL); |
826 | if (! cnx) | 826 | if (! cnx) |
827 | return -ENOMEM; | 827 | return -ENOMEM; |
828 | memset(cnx, 0, sizeof(*cnx)); | ||
829 | 828 | ||
830 | cnx->remote_lp = rlp; | 829 | cnx->remote_lp = rlp; |
831 | spin_lock_init(&cnx->lock); | 830 | spin_lock_init(&cnx->lock); |
@@ -852,14 +851,13 @@ static int veth_init_connection(u8 rlp) | |||
852 | if (rc != 0) | 851 | if (rc != 0) |
853 | return rc; | 852 | return rc; |
854 | 853 | ||
855 | msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL); | 854 | msgs = kcalloc(VETH_NUMBUFFERS, sizeof(struct veth_msg), GFP_KERNEL); |
856 | if (! msgs) { | 855 | if (! msgs) { |
857 | veth_error("Can't allocate buffers for LPAR %d.\n", rlp); | 856 | veth_error("Can't allocate buffers for LPAR %d.\n", rlp); |
858 | return -ENOMEM; | 857 | return -ENOMEM; |
859 | } | 858 | } |
860 | 859 | ||
861 | cnx->msgs = msgs; | 860 | cnx->msgs = msgs; |
862 | memset(msgs, 0, VETH_NUMBUFFERS * sizeof(struct veth_msg)); | ||
863 | 861 | ||
864 | for (i = 0; i < VETH_NUMBUFFERS; i++) { | 862 | for (i = 0; i < VETH_NUMBUFFERS; i++) { |
865 | msgs[i].token = i; | 863 | msgs[i].token = i; |
diff --git a/drivers/net/lance.c b/drivers/net/lance.c index a2f37e52b92..a4e5fab1262 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c | |||
@@ -533,11 +533,10 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int | |||
533 | dev->base_addr = ioaddr; | 533 | dev->base_addr = ioaddr; |
534 | /* Make certain the data structures used by the LANCE are aligned and DMAble. */ | 534 | /* Make certain the data structures used by the LANCE are aligned and DMAble. */ |
535 | 535 | ||
536 | lp = kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL); | 536 | lp = kzalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL); |
537 | if(lp==NULL) | 537 | if(lp==NULL) |
538 | return -ENODEV; | 538 | return -ENODEV; |
539 | if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp); | 539 | if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp); |
540 | memset(lp, 0, sizeof(*lp)); | ||
541 | dev->priv = lp; | 540 | dev->priv = lp; |
542 | lp->name = chipname; | 541 | lp->name = chipname; |
543 | lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE, | 542 | lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE, |
diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c new file mode 100644 index 00000000000..112778652f7 --- /dev/null +++ b/drivers/net/lguest_net.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* A simple network driver for lguest. | ||
2 | * | ||
3 | * Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | //#define DEBUG | ||
20 | #include <linux/netdevice.h> | ||
21 | #include <linux/etherdevice.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/mm_types.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/lguest_bus.h> | ||
26 | |||
27 | #define SHARED_SIZE PAGE_SIZE | ||
28 | #define MAX_LANS 4 | ||
29 | #define NUM_SKBS 8 | ||
30 | |||
31 | struct lguestnet_info | ||
32 | { | ||
33 | /* The shared page(s). */ | ||
34 | struct lguest_net *peer; | ||
35 | unsigned long peer_phys; | ||
36 | unsigned long mapsize; | ||
37 | |||
38 | /* The lguest_device I come from */ | ||
39 | struct lguest_device *lgdev; | ||
40 | |||
41 | /* My peerid. */ | ||
42 | unsigned int me; | ||
43 | |||
44 | /* Receive queue. */ | ||
45 | struct sk_buff *skb[NUM_SKBS]; | ||
46 | struct lguest_dma dma[NUM_SKBS]; | ||
47 | }; | ||
48 | |||
49 | /* How many bytes left in this page. */ | ||
50 | static unsigned int rest_of_page(void *data) | ||
51 | { | ||
52 | return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE); | ||
53 | } | ||
54 | |||
55 | /* Simple convention: offset 4 * peernum. */ | ||
56 | static unsigned long peer_key(struct lguestnet_info *info, unsigned peernum) | ||
57 | { | ||
58 | return info->peer_phys + 4 * peernum; | ||
59 | } | ||
60 | |||
61 | static void skb_to_dma(const struct sk_buff *skb, unsigned int headlen, | ||
62 | struct lguest_dma *dma) | ||
63 | { | ||
64 | unsigned int i, seg; | ||
65 | |||
66 | for (i = seg = 0; i < headlen; seg++, i += rest_of_page(skb->data+i)) { | ||
67 | dma->addr[seg] = virt_to_phys(skb->data + i); | ||
68 | dma->len[seg] = min((unsigned)(headlen - i), | ||
69 | rest_of_page(skb->data + i)); | ||
70 | } | ||
71 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, seg++) { | ||
72 | const skb_frag_t *f = &skb_shinfo(skb)->frags[i]; | ||
73 | /* Should not happen with MTU less than 64k - 2 * PAGE_SIZE. */ | ||
74 | if (seg == LGUEST_MAX_DMA_SECTIONS) { | ||
75 | printk("Woah dude! Megapacket!\n"); | ||
76 | break; | ||
77 | } | ||
78 | dma->addr[seg] = page_to_phys(f->page) + f->page_offset; | ||
79 | dma->len[seg] = f->size; | ||
80 | } | ||
81 | if (seg < LGUEST_MAX_DMA_SECTIONS) | ||
82 | dma->len[seg] = 0; | ||
83 | } | ||
84 | |||
85 | /* We overload multicast bit to show promiscuous mode. */ | ||
86 | #define PROMISC_BIT 0x01 | ||
87 | |||
88 | static void lguestnet_set_multicast(struct net_device *dev) | ||
89 | { | ||
90 | struct lguestnet_info *info = netdev_priv(dev); | ||
91 | |||
92 | if ((dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || dev->mc_count) | ||
93 | info->peer[info->me].mac[0] |= PROMISC_BIT; | ||
94 | else | ||
95 | info->peer[info->me].mac[0] &= ~PROMISC_BIT; | ||
96 | } | ||
97 | |||
98 | static int promisc(struct lguestnet_info *info, unsigned int peer) | ||
99 | { | ||
100 | return info->peer[peer].mac[0] & PROMISC_BIT; | ||
101 | } | ||
102 | |||
103 | static int mac_eq(const unsigned char mac[ETH_ALEN], | ||
104 | struct lguestnet_info *info, unsigned int peer) | ||
105 | { | ||
106 | /* Ignore multicast bit, which peer turns on to mean promisc. */ | ||
107 | if ((info->peer[peer].mac[0] & (~PROMISC_BIT)) != mac[0]) | ||
108 | return 0; | ||
109 | return memcmp(mac+1, info->peer[peer].mac+1, ETH_ALEN-1) == 0; | ||
110 | } | ||
111 | |||
112 | static void transfer_packet(struct net_device *dev, | ||
113 | struct sk_buff *skb, | ||
114 | unsigned int peernum) | ||
115 | { | ||
116 | struct lguestnet_info *info = netdev_priv(dev); | ||
117 | struct lguest_dma dma; | ||
118 | |||
119 | skb_to_dma(skb, skb_headlen(skb), &dma); | ||
120 | pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len); | ||
121 | |||
122 | lguest_send_dma(peer_key(info, peernum), &dma); | ||
123 | if (dma.used_len != skb->len) { | ||
124 | dev->stats.tx_carrier_errors++; | ||
125 | pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n", | ||
126 | peernum, dma.used_len, skb->len, | ||
127 | (void *)dma.addr[0], dma.len[0]); | ||
128 | } else { | ||
129 | dev->stats.tx_bytes += skb->len; | ||
130 | dev->stats.tx_packets++; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static int unused_peer(const struct lguest_net peer[], unsigned int num) | ||
135 | { | ||
136 | return peer[num].mac[0] == 0; | ||
137 | } | ||
138 | |||
139 | static int lguestnet_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
140 | { | ||
141 | unsigned int i; | ||
142 | int broadcast; | ||
143 | struct lguestnet_info *info = netdev_priv(dev); | ||
144 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | ||
145 | |||
146 | pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
147 | dev->name, dest[0],dest[1],dest[2],dest[3],dest[4],dest[5]); | ||
148 | |||
149 | broadcast = is_multicast_ether_addr(dest); | ||
150 | for (i = 0; i < info->mapsize/sizeof(struct lguest_net); i++) { | ||
151 | if (i == info->me || unused_peer(info->peer, i)) | ||
152 | continue; | ||
153 | |||
154 | if (!broadcast && !promisc(info, i) && !mac_eq(dest, info, i)) | ||
155 | continue; | ||
156 | |||
157 | pr_debug("lguestnet %s: sending from %i to %i\n", | ||
158 | dev->name, info->me, i); | ||
159 | transfer_packet(dev, skb, i); | ||
160 | } | ||
161 | dev_kfree_skb(skb); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | /* Find a new skb to put in this slot in shared mem. */ | ||
166 | static int fill_slot(struct net_device *dev, unsigned int slot) | ||
167 | { | ||
168 | struct lguestnet_info *info = netdev_priv(dev); | ||
169 | /* Try to create and register a new one. */ | ||
170 | info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN); | ||
171 | if (!info->skb[slot]) { | ||
172 | printk("%s: could not fill slot %i\n", dev->name, slot); | ||
173 | return -ENOMEM; | ||
174 | } | ||
175 | |||
176 | skb_to_dma(info->skb[slot], ETH_HLEN + ETH_DATA_LEN, &info->dma[slot]); | ||
177 | wmb(); | ||
178 | /* Now we tell hypervisor it can use the slot. */ | ||
179 | info->dma[slot].used_len = 0; | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static irqreturn_t lguestnet_rcv(int irq, void *dev_id) | ||
184 | { | ||
185 | struct net_device *dev = dev_id; | ||
186 | struct lguestnet_info *info = netdev_priv(dev); | ||
187 | unsigned int i, done = 0; | ||
188 | |||
189 | for (i = 0; i < ARRAY_SIZE(info->dma); i++) { | ||
190 | unsigned int length; | ||
191 | struct sk_buff *skb; | ||
192 | |||
193 | length = info->dma[i].used_len; | ||
194 | if (length == 0) | ||
195 | continue; | ||
196 | |||
197 | done++; | ||
198 | skb = info->skb[i]; | ||
199 | fill_slot(dev, i); | ||
200 | |||
201 | if (length < ETH_HLEN || length > ETH_HLEN + ETH_DATA_LEN) { | ||
202 | pr_debug(KERN_WARNING "%s: unbelievable skb len: %i\n", | ||
203 | dev->name, length); | ||
204 | dev_kfree_skb(skb); | ||
205 | continue; | ||
206 | } | ||
207 | |||
208 | skb_put(skb, length); | ||
209 | skb->protocol = eth_type_trans(skb, dev); | ||
210 | /* This is a reliable transport. */ | ||
211 | if (dev->features & NETIF_F_NO_CSUM) | ||
212 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
213 | pr_debug("Receiving skb proto 0x%04x len %i type %i\n", | ||
214 | ntohs(skb->protocol), skb->len, skb->pkt_type); | ||
215 | |||
216 | dev->stats.rx_bytes += skb->len; | ||
217 | dev->stats.rx_packets++; | ||
218 | netif_rx(skb); | ||
219 | } | ||
220 | return done ? IRQ_HANDLED : IRQ_NONE; | ||
221 | } | ||
222 | |||
223 | static int lguestnet_open(struct net_device *dev) | ||
224 | { | ||
225 | int i; | ||
226 | struct lguestnet_info *info = netdev_priv(dev); | ||
227 | |||
228 | /* Set up our MAC address */ | ||
229 | memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN); | ||
230 | |||
231 | /* Turn on promisc mode if needed */ | ||
232 | lguestnet_set_multicast(dev); | ||
233 | |||
234 | for (i = 0; i < ARRAY_SIZE(info->dma); i++) { | ||
235 | if (fill_slot(dev, i) != 0) | ||
236 | goto cleanup; | ||
237 | } | ||
238 | if (lguest_bind_dma(peer_key(info,info->me), info->dma, | ||
239 | NUM_SKBS, lgdev_irq(info->lgdev)) != 0) | ||
240 | goto cleanup; | ||
241 | return 0; | ||
242 | |||
243 | cleanup: | ||
244 | while (--i >= 0) | ||
245 | dev_kfree_skb(info->skb[i]); | ||
246 | return -ENOMEM; | ||
247 | } | ||
248 | |||
249 | static int lguestnet_close(struct net_device *dev) | ||
250 | { | ||
251 | unsigned int i; | ||
252 | struct lguestnet_info *info = netdev_priv(dev); | ||
253 | |||
254 | /* Clear all trace: others might deliver packets, we'll ignore it. */ | ||
255 | memset(&info->peer[info->me], 0, sizeof(info->peer[info->me])); | ||
256 | |||
257 | /* Deregister sg lists. */ | ||
258 | lguest_unbind_dma(peer_key(info, info->me), info->dma); | ||
259 | for (i = 0; i < ARRAY_SIZE(info->dma); i++) | ||
260 | dev_kfree_skb(info->skb[i]); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int lguestnet_probe(struct lguest_device *lgdev) | ||
265 | { | ||
266 | int err, irqf = IRQF_SHARED; | ||
267 | struct net_device *dev; | ||
268 | struct lguestnet_info *info; | ||
269 | struct lguest_device_desc *desc = &lguest_devices[lgdev->index]; | ||
270 | |||
271 | pr_debug("lguest_net: probing for device %i\n", lgdev->index); | ||
272 | |||
273 | dev = alloc_etherdev(sizeof(struct lguestnet_info)); | ||
274 | if (!dev) | ||
275 | return -ENOMEM; | ||
276 | |||
277 | SET_MODULE_OWNER(dev); | ||
278 | |||
279 | /* Ethernet defaults with some changes */ | ||
280 | ether_setup(dev); | ||
281 | dev->set_mac_address = NULL; | ||
282 | |||
283 | dev->dev_addr[0] = 0x02; /* set local assignment bit (IEEE802) */ | ||
284 | dev->dev_addr[1] = 0x00; | ||
285 | memcpy(&dev->dev_addr[2], &lguest_data.guestid, 2); | ||
286 | dev->dev_addr[4] = 0x00; | ||
287 | dev->dev_addr[5] = 0x00; | ||
288 | |||
289 | dev->open = lguestnet_open; | ||
290 | dev->stop = lguestnet_close; | ||
291 | dev->hard_start_xmit = lguestnet_start_xmit; | ||
292 | |||
293 | /* Turning on/off promisc will call dev->set_multicast_list. | ||
294 | * We don't actually support multicast yet */ | ||
295 | dev->set_multicast_list = lguestnet_set_multicast; | ||
296 | SET_NETDEV_DEV(dev, &lgdev->dev); | ||
297 | if (desc->features & LGUEST_NET_F_NOCSUM) | ||
298 | dev->features = NETIF_F_SG|NETIF_F_NO_CSUM; | ||
299 | |||
300 | info = netdev_priv(dev); | ||
301 | info->mapsize = PAGE_SIZE * desc->num_pages; | ||
302 | info->peer_phys = ((unsigned long)desc->pfn << PAGE_SHIFT); | ||
303 | info->lgdev = lgdev; | ||
304 | info->peer = lguest_map(info->peer_phys, desc->num_pages); | ||
305 | if (!info->peer) { | ||
306 | err = -ENOMEM; | ||
307 | goto free; | ||
308 | } | ||
309 | |||
310 | /* This stores our peerid (upper bits reserved for future). */ | ||
311 | info->me = (desc->features & (info->mapsize-1)); | ||
312 | |||
313 | err = register_netdev(dev); | ||
314 | if (err) { | ||
315 | pr_debug("lguestnet: registering device failed\n"); | ||
316 | goto unmap; | ||
317 | } | ||
318 | |||
319 | if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS) | ||
320 | irqf |= IRQF_SAMPLE_RANDOM; | ||
321 | if (request_irq(lgdev_irq(lgdev), lguestnet_rcv, irqf, "lguestnet", | ||
322 | dev) != 0) { | ||
323 | pr_debug("lguestnet: cannot get irq %i\n", lgdev_irq(lgdev)); | ||
324 | goto unregister; | ||
325 | } | ||
326 | |||
327 | pr_debug("lguestnet: registered device %s\n", dev->name); | ||
328 | lgdev->private = dev; | ||
329 | return 0; | ||
330 | |||
331 | unregister: | ||
332 | unregister_netdev(dev); | ||
333 | unmap: | ||
334 | lguest_unmap(info->peer); | ||
335 | free: | ||
336 | free_netdev(dev); | ||
337 | return err; | ||
338 | } | ||
339 | |||
340 | static struct lguest_driver lguestnet_drv = { | ||
341 | .name = "lguestnet", | ||
342 | .owner = THIS_MODULE, | ||
343 | .device_type = LGUEST_DEVICE_T_NET, | ||
344 | .probe = lguestnet_probe, | ||
345 | }; | ||
346 | |||
347 | static __init int lguestnet_init(void) | ||
348 | { | ||
349 | return register_lguest_driver(&lguestnet_drv); | ||
350 | } | ||
351 | module_init(lguestnet_init); | ||
352 | |||
353 | MODULE_DESCRIPTION("Lguest network driver"); | ||
354 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c index 1bb088aeaf7..6b32ec94b3a 100644 --- a/drivers/net/mlx4/catas.c +++ b/drivers/net/mlx4/catas.c | |||
@@ -30,41 +30,133 @@ | |||
30 | * SOFTWARE. | 30 | * SOFTWARE. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/workqueue.h> | ||
34 | |||
33 | #include "mlx4.h" | 35 | #include "mlx4.h" |
34 | 36 | ||
35 | void mlx4_handle_catas_err(struct mlx4_dev *dev) | 37 | enum { |
38 | MLX4_CATAS_POLL_INTERVAL = 5 * HZ, | ||
39 | }; | ||
40 | |||
41 | static DEFINE_SPINLOCK(catas_lock); | ||
42 | |||
43 | static LIST_HEAD(catas_list); | ||
44 | static struct workqueue_struct *catas_wq; | ||
45 | static struct work_struct catas_work; | ||
46 | |||
47 | static int internal_err_reset = 1; | ||
48 | module_param(internal_err_reset, int, 0644); | ||
49 | MODULE_PARM_DESC(internal_err_reset, | ||
50 | "Reset device on internal errors if non-zero (default 1)"); | ||
51 | |||
52 | static void dump_err_buf(struct mlx4_dev *dev) | ||
36 | { | 53 | { |
37 | struct mlx4_priv *priv = mlx4_priv(dev); | 54 | struct mlx4_priv *priv = mlx4_priv(dev); |
38 | 55 | ||
39 | int i; | 56 | int i; |
40 | 57 | ||
41 | mlx4_err(dev, "Catastrophic error detected:\n"); | 58 | mlx4_err(dev, "Internal error detected:\n"); |
42 | for (i = 0; i < priv->fw.catas_size; ++i) | 59 | for (i = 0; i < priv->fw.catas_size; ++i) |
43 | mlx4_err(dev, " buf[%02x]: %08x\n", | 60 | mlx4_err(dev, " buf[%02x]: %08x\n", |
44 | i, swab32(readl(priv->catas_err.map + i))); | 61 | i, swab32(readl(priv->catas_err.map + i))); |
62 | } | ||
45 | 63 | ||
46 | mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0); | 64 | static void poll_catas(unsigned long dev_ptr) |
65 | { | ||
66 | struct mlx4_dev *dev = (struct mlx4_dev *) dev_ptr; | ||
67 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
68 | |||
69 | if (readl(priv->catas_err.map)) { | ||
70 | dump_err_buf(dev); | ||
71 | |||
72 | mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0); | ||
73 | |||
74 | if (internal_err_reset) { | ||
75 | spin_lock(&catas_lock); | ||
76 | list_add(&priv->catas_err.list, &catas_list); | ||
77 | spin_unlock(&catas_lock); | ||
78 | |||
79 | queue_work(catas_wq, &catas_work); | ||
80 | } | ||
81 | } else | ||
82 | mod_timer(&priv->catas_err.timer, | ||
83 | round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL)); | ||
47 | } | 84 | } |
48 | 85 | ||
49 | void mlx4_map_catas_buf(struct mlx4_dev *dev) | 86 | static void catas_reset(struct work_struct *work) |
87 | { | ||
88 | struct mlx4_priv *priv, *tmppriv; | ||
89 | struct mlx4_dev *dev; | ||
90 | |||
91 | LIST_HEAD(tlist); | ||
92 | int ret; | ||
93 | |||
94 | spin_lock_irq(&catas_lock); | ||
95 | list_splice_init(&catas_list, &tlist); | ||
96 | spin_unlock_irq(&catas_lock); | ||
97 | |||
98 | list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) { | ||
99 | ret = mlx4_restart_one(priv->dev.pdev); | ||
100 | dev = &priv->dev; | ||
101 | if (ret) | ||
102 | mlx4_err(dev, "Reset failed (%d)\n", ret); | ||
103 | else | ||
104 | mlx4_dbg(dev, "Reset succeeded\n"); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void mlx4_start_catas_poll(struct mlx4_dev *dev) | ||
50 | { | 109 | { |
51 | struct mlx4_priv *priv = mlx4_priv(dev); | 110 | struct mlx4_priv *priv = mlx4_priv(dev); |
52 | unsigned long addr; | 111 | unsigned long addr; |
53 | 112 | ||
113 | INIT_LIST_HEAD(&priv->catas_err.list); | ||
114 | init_timer(&priv->catas_err.timer); | ||
115 | priv->catas_err.map = NULL; | ||
116 | |||
54 | addr = pci_resource_start(dev->pdev, priv->fw.catas_bar) + | 117 | addr = pci_resource_start(dev->pdev, priv->fw.catas_bar) + |
55 | priv->fw.catas_offset; | 118 | priv->fw.catas_offset; |
56 | 119 | ||
57 | priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4); | 120 | priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4); |
58 | if (!priv->catas_err.map) | 121 | if (!priv->catas_err.map) { |
59 | mlx4_warn(dev, "Failed to map catastrophic error buffer at 0x%lx\n", | 122 | mlx4_warn(dev, "Failed to map internal error buffer at 0x%lx\n", |
60 | addr); | 123 | addr); |
124 | return; | ||
125 | } | ||
61 | 126 | ||
127 | priv->catas_err.timer.data = (unsigned long) dev; | ||
128 | priv->catas_err.timer.function = poll_catas; | ||
129 | priv->catas_err.timer.expires = | ||
130 | round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL); | ||
131 | add_timer(&priv->catas_err.timer); | ||
62 | } | 132 | } |
63 | 133 | ||
64 | void mlx4_unmap_catas_buf(struct mlx4_dev *dev) | 134 | void mlx4_stop_catas_poll(struct mlx4_dev *dev) |
65 | { | 135 | { |
66 | struct mlx4_priv *priv = mlx4_priv(dev); | 136 | struct mlx4_priv *priv = mlx4_priv(dev); |
67 | 137 | ||
138 | del_timer_sync(&priv->catas_err.timer); | ||
139 | |||
68 | if (priv->catas_err.map) | 140 | if (priv->catas_err.map) |
69 | iounmap(priv->catas_err.map); | 141 | iounmap(priv->catas_err.map); |
142 | |||
143 | spin_lock_irq(&catas_lock); | ||
144 | list_del(&priv->catas_err.list); | ||
145 | spin_unlock_irq(&catas_lock); | ||
146 | } | ||
147 | |||
148 | int __init mlx4_catas_init(void) | ||
149 | { | ||
150 | INIT_WORK(&catas_work, catas_reset); | ||
151 | |||
152 | catas_wq = create_singlethread_workqueue("mlx4_err"); | ||
153 | if (!catas_wq) | ||
154 | return -ENOMEM; | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | void mlx4_catas_cleanup(void) | ||
160 | { | ||
161 | destroy_workqueue(catas_wq); | ||
70 | } | 162 | } |
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 27a82cecd69..2095c843fa1 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c | |||
@@ -89,14 +89,12 @@ struct mlx4_eq_context { | |||
89 | (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED) | \ | 89 | (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED) | \ |
90 | (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \ | 90 | (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \ |
91 | (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR) | \ | 91 | (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR) | \ |
92 | (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR) | \ | ||
93 | (1ull << MLX4_EVENT_TYPE_PORT_CHANGE) | \ | 92 | (1ull << MLX4_EVENT_TYPE_PORT_CHANGE) | \ |
94 | (1ull << MLX4_EVENT_TYPE_ECC_DETECT) | \ | 93 | (1ull << MLX4_EVENT_TYPE_ECC_DETECT) | \ |
95 | (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) | \ | 94 | (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) | \ |
96 | (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE) | \ | 95 | (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE) | \ |
97 | (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \ | 96 | (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \ |
98 | (1ull << MLX4_EVENT_TYPE_CMD)) | 97 | (1ull << MLX4_EVENT_TYPE_CMD)) |
99 | #define MLX4_CATAS_EVENT_MASK (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR) | ||
100 | 98 | ||
101 | struct mlx4_eqe { | 99 | struct mlx4_eqe { |
102 | u8 reserved1; | 100 | u8 reserved1; |
@@ -264,7 +262,7 @@ static irqreturn_t mlx4_interrupt(int irq, void *dev_ptr) | |||
264 | 262 | ||
265 | writel(priv->eq_table.clr_mask, priv->eq_table.clr_int); | 263 | writel(priv->eq_table.clr_mask, priv->eq_table.clr_int); |
266 | 264 | ||
267 | for (i = 0; i < MLX4_EQ_CATAS; ++i) | 265 | for (i = 0; i < MLX4_NUM_EQ; ++i) |
268 | work |= mlx4_eq_int(dev, &priv->eq_table.eq[i]); | 266 | work |= mlx4_eq_int(dev, &priv->eq_table.eq[i]); |
269 | 267 | ||
270 | return IRQ_RETVAL(work); | 268 | return IRQ_RETVAL(work); |
@@ -281,14 +279,6 @@ static irqreturn_t mlx4_msi_x_interrupt(int irq, void *eq_ptr) | |||
281 | return IRQ_HANDLED; | 279 | return IRQ_HANDLED; |
282 | } | 280 | } |
283 | 281 | ||
284 | static irqreturn_t mlx4_catas_interrupt(int irq, void *dev_ptr) | ||
285 | { | ||
286 | mlx4_handle_catas_err(dev_ptr); | ||
287 | |||
288 | /* MSI-X vectors always belong to us */ | ||
289 | return IRQ_HANDLED; | ||
290 | } | ||
291 | |||
292 | static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap, | 282 | static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap, |
293 | int eq_num) | 283 | int eq_num) |
294 | { | 284 | { |
@@ -490,11 +480,9 @@ static void mlx4_free_irqs(struct mlx4_dev *dev) | |||
490 | 480 | ||
491 | if (eq_table->have_irq) | 481 | if (eq_table->have_irq) |
492 | free_irq(dev->pdev->irq, dev); | 482 | free_irq(dev->pdev->irq, dev); |
493 | for (i = 0; i < MLX4_EQ_CATAS; ++i) | 483 | for (i = 0; i < MLX4_NUM_EQ; ++i) |
494 | if (eq_table->eq[i].have_irq) | 484 | if (eq_table->eq[i].have_irq) |
495 | free_irq(eq_table->eq[i].irq, eq_table->eq + i); | 485 | free_irq(eq_table->eq[i].irq, eq_table->eq + i); |
496 | if (eq_table->eq[MLX4_EQ_CATAS].have_irq) | ||
497 | free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev); | ||
498 | } | 486 | } |
499 | 487 | ||
500 | static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev) | 488 | static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev) |
@@ -598,32 +586,19 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev) | |||
598 | if (dev->flags & MLX4_FLAG_MSI_X) { | 586 | if (dev->flags & MLX4_FLAG_MSI_X) { |
599 | static const char *eq_name[] = { | 587 | static const char *eq_name[] = { |
600 | [MLX4_EQ_COMP] = DRV_NAME " (comp)", | 588 | [MLX4_EQ_COMP] = DRV_NAME " (comp)", |
601 | [MLX4_EQ_ASYNC] = DRV_NAME " (async)", | 589 | [MLX4_EQ_ASYNC] = DRV_NAME " (async)" |
602 | [MLX4_EQ_CATAS] = DRV_NAME " (catas)" | ||
603 | }; | 590 | }; |
604 | 591 | ||
605 | err = mlx4_create_eq(dev, 1, MLX4_EQ_CATAS, | 592 | for (i = 0; i < MLX4_NUM_EQ; ++i) { |
606 | &priv->eq_table.eq[MLX4_EQ_CATAS]); | ||
607 | if (err) | ||
608 | goto err_out_async; | ||
609 | |||
610 | for (i = 0; i < MLX4_EQ_CATAS; ++i) { | ||
611 | err = request_irq(priv->eq_table.eq[i].irq, | 593 | err = request_irq(priv->eq_table.eq[i].irq, |
612 | mlx4_msi_x_interrupt, | 594 | mlx4_msi_x_interrupt, |
613 | 0, eq_name[i], priv->eq_table.eq + i); | 595 | 0, eq_name[i], priv->eq_table.eq + i); |
614 | if (err) | 596 | if (err) |
615 | goto err_out_catas; | 597 | goto err_out_async; |
616 | 598 | ||
617 | priv->eq_table.eq[i].have_irq = 1; | 599 | priv->eq_table.eq[i].have_irq = 1; |
618 | } | 600 | } |
619 | 601 | ||
620 | err = request_irq(priv->eq_table.eq[MLX4_EQ_CATAS].irq, | ||
621 | mlx4_catas_interrupt, 0, | ||
622 | eq_name[MLX4_EQ_CATAS], dev); | ||
623 | if (err) | ||
624 | goto err_out_catas; | ||
625 | |||
626 | priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1; | ||
627 | } else { | 602 | } else { |
628 | err = request_irq(dev->pdev->irq, mlx4_interrupt, | 603 | err = request_irq(dev->pdev->irq, mlx4_interrupt, |
629 | IRQF_SHARED, DRV_NAME, dev); | 604 | IRQF_SHARED, DRV_NAME, dev); |
@@ -639,22 +614,11 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev) | |||
639 | mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n", | 614 | mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n", |
640 | priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err); | 615 | priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err); |
641 | 616 | ||
642 | for (i = 0; i < MLX4_EQ_CATAS; ++i) | 617 | for (i = 0; i < MLX4_NUM_EQ; ++i) |
643 | eq_set_ci(&priv->eq_table.eq[i], 1); | 618 | eq_set_ci(&priv->eq_table.eq[i], 1); |
644 | 619 | ||
645 | if (dev->flags & MLX4_FLAG_MSI_X) { | ||
646 | err = mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 0, | ||
647 | priv->eq_table.eq[MLX4_EQ_CATAS].eqn); | ||
648 | if (err) | ||
649 | mlx4_warn(dev, "MAP_EQ for catas EQ %d failed (%d)\n", | ||
650 | priv->eq_table.eq[MLX4_EQ_CATAS].eqn, err); | ||
651 | } | ||
652 | |||
653 | return 0; | 620 | return 0; |
654 | 621 | ||
655 | err_out_catas: | ||
656 | mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]); | ||
657 | |||
658 | err_out_async: | 622 | err_out_async: |
659 | mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]); | 623 | mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]); |
660 | 624 | ||
@@ -675,19 +639,13 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) | |||
675 | struct mlx4_priv *priv = mlx4_priv(dev); | 639 | struct mlx4_priv *priv = mlx4_priv(dev); |
676 | int i; | 640 | int i; |
677 | 641 | ||
678 | if (dev->flags & MLX4_FLAG_MSI_X) | ||
679 | mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 1, | ||
680 | priv->eq_table.eq[MLX4_EQ_CATAS].eqn); | ||
681 | |||
682 | mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1, | 642 | mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1, |
683 | priv->eq_table.eq[MLX4_EQ_ASYNC].eqn); | 643 | priv->eq_table.eq[MLX4_EQ_ASYNC].eqn); |
684 | 644 | ||
685 | mlx4_free_irqs(dev); | 645 | mlx4_free_irqs(dev); |
686 | 646 | ||
687 | for (i = 0; i < MLX4_EQ_CATAS; ++i) | 647 | for (i = 0; i < MLX4_NUM_EQ; ++i) |
688 | mlx4_free_eq(dev, &priv->eq_table.eq[i]); | 648 | mlx4_free_eq(dev, &priv->eq_table.eq[i]); |
689 | if (dev->flags & MLX4_FLAG_MSI_X) | ||
690 | mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]); | ||
691 | 649 | ||
692 | mlx4_unmap_clr_int(dev); | 650 | mlx4_unmap_clr_int(dev); |
693 | 651 | ||
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c index 9ae951bf6aa..be5d9e90ccf 100644 --- a/drivers/net/mlx4/intf.c +++ b/drivers/net/mlx4/intf.c | |||
@@ -142,6 +142,7 @@ int mlx4_register_device(struct mlx4_dev *dev) | |||
142 | mlx4_add_device(intf, priv); | 142 | mlx4_add_device(intf, priv); |
143 | 143 | ||
144 | mutex_unlock(&intf_mutex); | 144 | mutex_unlock(&intf_mutex); |
145 | mlx4_start_catas_poll(dev); | ||
145 | 146 | ||
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
@@ -151,6 +152,7 @@ void mlx4_unregister_device(struct mlx4_dev *dev) | |||
151 | struct mlx4_priv *priv = mlx4_priv(dev); | 152 | struct mlx4_priv *priv = mlx4_priv(dev); |
152 | struct mlx4_interface *intf; | 153 | struct mlx4_interface *intf; |
153 | 154 | ||
155 | mlx4_stop_catas_poll(dev); | ||
154 | mutex_lock(&intf_mutex); | 156 | mutex_lock(&intf_mutex); |
155 | 157 | ||
156 | list_for_each_entry(intf, &intf_list, list) | 158 | list_for_each_entry(intf, &intf_list, list) |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index a4f2e0475a7..4dc9dc19b71 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -78,7 +78,7 @@ static const char mlx4_version[] __devinitdata = | |||
78 | static struct mlx4_profile default_profile = { | 78 | static struct mlx4_profile default_profile = { |
79 | .num_qp = 1 << 16, | 79 | .num_qp = 1 << 16, |
80 | .num_srq = 1 << 16, | 80 | .num_srq = 1 << 16, |
81 | .rdmarc_per_qp = 4, | 81 | .rdmarc_per_qp = 1 << 4, |
82 | .num_cq = 1 << 16, | 82 | .num_cq = 1 << 16, |
83 | .num_mcg = 1 << 13, | 83 | .num_mcg = 1 << 13, |
84 | .num_mpt = 1 << 17, | 84 | .num_mpt = 1 << 17, |
@@ -583,13 +583,11 @@ static int __devinit mlx4_setup_hca(struct mlx4_dev *dev) | |||
583 | goto err_pd_table_free; | 583 | goto err_pd_table_free; |
584 | } | 584 | } |
585 | 585 | ||
586 | mlx4_map_catas_buf(dev); | ||
587 | |||
588 | err = mlx4_init_eq_table(dev); | 586 | err = mlx4_init_eq_table(dev); |
589 | if (err) { | 587 | if (err) { |
590 | mlx4_err(dev, "Failed to initialize " | 588 | mlx4_err(dev, "Failed to initialize " |
591 | "event queue table, aborting.\n"); | 589 | "event queue table, aborting.\n"); |
592 | goto err_catas_buf; | 590 | goto err_mr_table_free; |
593 | } | 591 | } |
594 | 592 | ||
595 | err = mlx4_cmd_use_events(dev); | 593 | err = mlx4_cmd_use_events(dev); |
@@ -659,8 +657,7 @@ err_cmd_poll: | |||
659 | err_eq_table_free: | 657 | err_eq_table_free: |
660 | mlx4_cleanup_eq_table(dev); | 658 | mlx4_cleanup_eq_table(dev); |
661 | 659 | ||
662 | err_catas_buf: | 660 | err_mr_table_free: |
663 | mlx4_unmap_catas_buf(dev); | ||
664 | mlx4_cleanup_mr_table(dev); | 661 | mlx4_cleanup_mr_table(dev); |
665 | 662 | ||
666 | err_pd_table_free: | 663 | err_pd_table_free: |
@@ -836,9 +833,6 @@ err_cleanup: | |||
836 | mlx4_cleanup_cq_table(dev); | 833 | mlx4_cleanup_cq_table(dev); |
837 | mlx4_cmd_use_polling(dev); | 834 | mlx4_cmd_use_polling(dev); |
838 | mlx4_cleanup_eq_table(dev); | 835 | mlx4_cleanup_eq_table(dev); |
839 | |||
840 | mlx4_unmap_catas_buf(dev); | ||
841 | |||
842 | mlx4_cleanup_mr_table(dev); | 836 | mlx4_cleanup_mr_table(dev); |
843 | mlx4_cleanup_pd_table(dev); | 837 | mlx4_cleanup_pd_table(dev); |
844 | mlx4_cleanup_uar_table(dev); | 838 | mlx4_cleanup_uar_table(dev); |
@@ -885,9 +879,6 @@ static void __devexit mlx4_remove_one(struct pci_dev *pdev) | |||
885 | mlx4_cleanup_cq_table(dev); | 879 | mlx4_cleanup_cq_table(dev); |
886 | mlx4_cmd_use_polling(dev); | 880 | mlx4_cmd_use_polling(dev); |
887 | mlx4_cleanup_eq_table(dev); | 881 | mlx4_cleanup_eq_table(dev); |
888 | |||
889 | mlx4_unmap_catas_buf(dev); | ||
890 | |||
891 | mlx4_cleanup_mr_table(dev); | 882 | mlx4_cleanup_mr_table(dev); |
892 | mlx4_cleanup_pd_table(dev); | 883 | mlx4_cleanup_pd_table(dev); |
893 | 884 | ||
@@ -908,6 +899,12 @@ static void __devexit mlx4_remove_one(struct pci_dev *pdev) | |||
908 | } | 899 | } |
909 | } | 900 | } |
910 | 901 | ||
902 | int mlx4_restart_one(struct pci_dev *pdev) | ||
903 | { | ||
904 | mlx4_remove_one(pdev); | ||
905 | return mlx4_init_one(pdev, NULL); | ||
906 | } | ||
907 | |||
911 | static struct pci_device_id mlx4_pci_table[] = { | 908 | static struct pci_device_id mlx4_pci_table[] = { |
912 | { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */ | 909 | { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */ |
913 | { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */ | 910 | { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */ |
@@ -930,6 +927,10 @@ static int __init mlx4_init(void) | |||
930 | { | 927 | { |
931 | int ret; | 928 | int ret; |
932 | 929 | ||
930 | ret = mlx4_catas_init(); | ||
931 | if (ret) | ||
932 | return ret; | ||
933 | |||
933 | ret = pci_register_driver(&mlx4_driver); | 934 | ret = pci_register_driver(&mlx4_driver); |
934 | return ret < 0 ? ret : 0; | 935 | return ret < 0 ? ret : 0; |
935 | } | 936 | } |
@@ -937,6 +938,7 @@ static int __init mlx4_init(void) | |||
937 | static void __exit mlx4_cleanup(void) | 938 | static void __exit mlx4_cleanup(void) |
938 | { | 939 | { |
939 | pci_unregister_driver(&mlx4_driver); | 940 | pci_unregister_driver(&mlx4_driver); |
941 | mlx4_catas_cleanup(); | ||
940 | } | 942 | } |
941 | 943 | ||
942 | module_init(mlx4_init); | 944 | module_init(mlx4_init); |
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index d9c91a71fc8..be304a7c2c9 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include <linux/radix-tree.h> | 41 | #include <linux/radix-tree.h> |
42 | #include <linux/timer.h> | ||
42 | 43 | ||
43 | #include <linux/mlx4/device.h> | 44 | #include <linux/mlx4/device.h> |
44 | #include <linux/mlx4/doorbell.h> | 45 | #include <linux/mlx4/doorbell.h> |
@@ -67,7 +68,6 @@ enum { | |||
67 | enum { | 68 | enum { |
68 | MLX4_EQ_ASYNC, | 69 | MLX4_EQ_ASYNC, |
69 | MLX4_EQ_COMP, | 70 | MLX4_EQ_COMP, |
70 | MLX4_EQ_CATAS, | ||
71 | MLX4_NUM_EQ | 71 | MLX4_NUM_EQ |
72 | }; | 72 | }; |
73 | 73 | ||
@@ -248,7 +248,8 @@ struct mlx4_mcg_table { | |||
248 | 248 | ||
249 | struct mlx4_catas_err { | 249 | struct mlx4_catas_err { |
250 | u32 __iomem *map; | 250 | u32 __iomem *map; |
251 | int size; | 251 | struct timer_list timer; |
252 | struct list_head list; | ||
252 | }; | 253 | }; |
253 | 254 | ||
254 | struct mlx4_priv { | 255 | struct mlx4_priv { |
@@ -311,9 +312,11 @@ void mlx4_cleanup_qp_table(struct mlx4_dev *dev); | |||
311 | void mlx4_cleanup_srq_table(struct mlx4_dev *dev); | 312 | void mlx4_cleanup_srq_table(struct mlx4_dev *dev); |
312 | void mlx4_cleanup_mcg_table(struct mlx4_dev *dev); | 313 | void mlx4_cleanup_mcg_table(struct mlx4_dev *dev); |
313 | 314 | ||
314 | void mlx4_map_catas_buf(struct mlx4_dev *dev); | 315 | void mlx4_start_catas_poll(struct mlx4_dev *dev); |
315 | void mlx4_unmap_catas_buf(struct mlx4_dev *dev); | 316 | void mlx4_stop_catas_poll(struct mlx4_dev *dev); |
316 | 317 | int mlx4_catas_init(void); | |
318 | void mlx4_catas_cleanup(void); | ||
319 | int mlx4_restart_one(struct pci_dev *pdev); | ||
317 | int mlx4_register_device(struct mlx4_dev *dev); | 320 | int mlx4_register_device(struct mlx4_dev *dev); |
318 | void mlx4_unregister_device(struct mlx4_dev *dev); | 321 | void mlx4_unregister_device(struct mlx4_dev *dev); |
319 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_event type, | 322 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_event type, |
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index 3d5b4232f65..22a3b3dc7d8 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c | |||
@@ -670,14 +670,10 @@ static void ni5010_set_multicast_list(struct net_device *dev) | |||
670 | 670 | ||
671 | PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name)); | 671 | PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name)); |
672 | 672 | ||
673 | if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI) { | 673 | if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) { |
674 | dev->flags |= IFF_PROMISC; | 674 | dev->flags |= IFF_PROMISC; |
675 | outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */ | 675 | outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */ |
676 | PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name)); | 676 | PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name)); |
677 | } else if (dev->mc_list) { | ||
678 | /* Sorry, multicast not supported */ | ||
679 | PRINTK((KERN_DEBUG "%s: No multicast, entering broadcast mode\n", dev->name)); | ||
680 | outb(RMD_BROADCAST, EDLC_RMODE); | ||
681 | } else { | 677 | } else { |
682 | PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name)); | 678 | PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name)); |
683 | outb(RMD_BROADCAST, EDLC_RMODE); /* Disable promiscuous mode, use normal mode */ | 679 | outb(RMD_BROADCAST, EDLC_RMODE); /* Disable promiscuous mode, use normal mode */ |
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 104aab3c957..ea80e6cb3de 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -1582,7 +1582,7 @@ static void ns83820_set_multicast(struct net_device *ndev) | |||
1582 | else | 1582 | else |
1583 | and_mask &= ~(RFCR_AAU | RFCR_AAM); | 1583 | and_mask &= ~(RFCR_AAU | RFCR_AAM); |
1584 | 1584 | ||
1585 | if (ndev->flags & IFF_ALLMULTI) | 1585 | if (ndev->flags & IFF_ALLMULTI || ndev->mc_count) |
1586 | or_mask |= RFCR_AAM; | 1586 | or_mask |= RFCR_AAM; |
1587 | else | 1587 | else |
1588 | and_mask &= ~RFCR_AAM; | 1588 | and_mask &= ~RFCR_AAM; |
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 0d1c7a41c9c..ea9414c4d90 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c | |||
@@ -147,7 +147,7 @@ static int com20020_probe(struct pcmcia_device *p_dev) | |||
147 | DEBUG(0, "com20020_attach()\n"); | 147 | DEBUG(0, "com20020_attach()\n"); |
148 | 148 | ||
149 | /* Create new network device */ | 149 | /* Create new network device */ |
150 | info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); | 150 | info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); |
151 | if (!info) | 151 | if (!info) |
152 | goto fail_alloc_info; | 152 | goto fail_alloc_info; |
153 | 153 | ||
@@ -155,7 +155,6 @@ static int com20020_probe(struct pcmcia_device *p_dev) | |||
155 | if (!dev) | 155 | if (!dev) |
156 | goto fail_alloc_dev; | 156 | goto fail_alloc_dev; |
157 | 157 | ||
158 | memset(info, 0, sizeof(struct com20020_dev_t)); | ||
159 | lp = dev->priv; | 158 | lp = dev->priv; |
160 | lp->timeout = timeout; | 159 | lp->timeout = timeout; |
161 | lp->backplane = backplane; | 160 | lp->backplane = backplane; |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 4ecb8ca5a99..4eafa4f42cf 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
@@ -146,9 +146,8 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) | |||
146 | DEBUG(0, "ibmtr_attach()\n"); | 146 | DEBUG(0, "ibmtr_attach()\n"); |
147 | 147 | ||
148 | /* Create new token-ring device */ | 148 | /* Create new token-ring device */ |
149 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 149 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
150 | if (!info) return -ENOMEM; | 150 | if (!info) return -ENOMEM; |
151 | memset(info,0,sizeof(*info)); | ||
152 | dev = alloc_trdev(sizeof(struct tok_info)); | 151 | dev = alloc_trdev(sizeof(struct tok_info)); |
153 | if (!dev) { | 152 | if (!dev) { |
154 | kfree(info); | 153 | kfree(info); |
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 596222b260d..6a538564791 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c | |||
@@ -21,6 +21,10 @@ | |||
21 | /* Vitesse Extended Control Register 1 */ | 21 | /* Vitesse Extended Control Register 1 */ |
22 | #define MII_VSC8244_EXT_CON1 0x17 | 22 | #define MII_VSC8244_EXT_CON1 0x17 |
23 | #define MII_VSC8244_EXTCON1_INIT 0x0000 | 23 | #define MII_VSC8244_EXTCON1_INIT 0x0000 |
24 | #define MII_VSC8244_EXTCON1_TX_SKEW_MASK 0x0c00 | ||
25 | #define MII_VSC8244_EXTCON1_RX_SKEW_MASK 0x0300 | ||
26 | #define MII_VSC8244_EXTCON1_TX_SKEW 0x0800 | ||
27 | #define MII_VSC8244_EXTCON1_RX_SKEW 0x0200 | ||
24 | 28 | ||
25 | /* Vitesse Interrupt Mask Register */ | 29 | /* Vitesse Interrupt Mask Register */ |
26 | #define MII_VSC8244_IMASK 0x19 | 30 | #define MII_VSC8244_IMASK 0x19 |
@@ -39,7 +43,7 @@ | |||
39 | 43 | ||
40 | /* Vitesse Auxiliary Control/Status Register */ | 44 | /* Vitesse Auxiliary Control/Status Register */ |
41 | #define MII_VSC8244_AUX_CONSTAT 0x1c | 45 | #define MII_VSC8244_AUX_CONSTAT 0x1c |
42 | #define MII_VSC8244_AUXCONSTAT_INIT 0x0004 | 46 | #define MII_VSC8244_AUXCONSTAT_INIT 0x0000 |
43 | #define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 | 47 | #define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 |
44 | #define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 | 48 | #define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 |
45 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 | 49 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 |
@@ -51,6 +55,7 @@ MODULE_LICENSE("GPL"); | |||
51 | 55 | ||
52 | static int vsc824x_config_init(struct phy_device *phydev) | 56 | static int vsc824x_config_init(struct phy_device *phydev) |
53 | { | 57 | { |
58 | int extcon; | ||
54 | int err; | 59 | int err; |
55 | 60 | ||
56 | err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, | 61 | err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, |
@@ -58,14 +63,34 @@ static int vsc824x_config_init(struct phy_device *phydev) | |||
58 | if (err < 0) | 63 | if (err < 0) |
59 | return err; | 64 | return err; |
60 | 65 | ||
61 | err = phy_write(phydev, MII_VSC8244_EXT_CON1, | 66 | extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); |
62 | MII_VSC8244_EXTCON1_INIT); | 67 | |
68 | if (extcon < 0) | ||
69 | return err; | ||
70 | |||
71 | extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK | | ||
72 | MII_VSC8244_EXTCON1_RX_SKEW_MASK); | ||
73 | |||
74 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | ||
75 | extcon |= (MII_VSC8244_EXTCON1_TX_SKEW | | ||
76 | MII_VSC8244_EXTCON1_RX_SKEW); | ||
77 | |||
78 | err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); | ||
79 | |||
63 | return err; | 80 | return err; |
64 | } | 81 | } |
65 | 82 | ||
66 | static int vsc824x_ack_interrupt(struct phy_device *phydev) | 83 | static int vsc824x_ack_interrupt(struct phy_device *phydev) |
67 | { | 84 | { |
68 | int err = phy_read(phydev, MII_VSC8244_ISTAT); | 85 | int err = 0; |
86 | |||
87 | /* | ||
88 | * Don't bother to ACK the interrupts if interrupts | ||
89 | * are disabled. The 824x cannot clear the interrupts | ||
90 | * if they are disabled. | ||
91 | */ | ||
92 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
93 | err = phy_read(phydev, MII_VSC8244_ISTAT); | ||
69 | 94 | ||
70 | return (err < 0) ? err : 0; | 95 | return (err < 0) ? err : 0; |
71 | } | 96 | } |
@@ -77,8 +102,19 @@ static int vsc824x_config_intr(struct phy_device *phydev) | |||
77 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 102 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
78 | err = phy_write(phydev, MII_VSC8244_IMASK, | 103 | err = phy_write(phydev, MII_VSC8244_IMASK, |
79 | MII_VSC8244_IMASK_MASK); | 104 | MII_VSC8244_IMASK_MASK); |
80 | else | 105 | else { |
106 | /* | ||
107 | * The Vitesse PHY cannot clear the interrupt | ||
108 | * once it has disabled them, so we clear them first | ||
109 | */ | ||
110 | err = phy_read(phydev, MII_VSC8244_ISTAT); | ||
111 | |||
112 | if (err) | ||
113 | return err; | ||
114 | |||
81 | err = phy_write(phydev, MII_VSC8244_IMASK, 0); | 115 | err = phy_write(phydev, MII_VSC8244_IMASK, 0); |
116 | } | ||
117 | |||
82 | return err; | 118 | return err; |
83 | } | 119 | } |
84 | 120 | ||
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index caabbc408c3..27f5b904f48 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -159,12 +159,11 @@ ppp_asynctty_open(struct tty_struct *tty) | |||
159 | int err; | 159 | int err; |
160 | 160 | ||
161 | err = -ENOMEM; | 161 | err = -ENOMEM; |
162 | ap = kmalloc(sizeof(*ap), GFP_KERNEL); | 162 | ap = kzalloc(sizeof(*ap), GFP_KERNEL); |
163 | if (ap == 0) | 163 | if (ap == 0) |
164 | goto out; | 164 | goto out; |
165 | 165 | ||
166 | /* initialize the asyncppp structure */ | 166 | /* initialize the asyncppp structure */ |
167 | memset(ap, 0, sizeof(*ap)); | ||
168 | ap->tty = tty; | 167 | ap->tty = tty; |
169 | ap->mru = PPP_MRU; | 168 | ap->mru = PPP_MRU; |
170 | spin_lock_init(&ap->xmit_lock); | 169 | spin_lock_init(&ap->xmit_lock); |
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index 72c8d6628f5..eb98b661efb 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c | |||
@@ -121,12 +121,11 @@ static void *z_comp_alloc(unsigned char *options, int opt_len) | |||
121 | if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) | 121 | if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) |
122 | return NULL; | 122 | return NULL; |
123 | 123 | ||
124 | state = kmalloc(sizeof(*state), | 124 | state = kzalloc(sizeof(*state), |
125 | GFP_KERNEL); | 125 | GFP_KERNEL); |
126 | if (state == NULL) | 126 | if (state == NULL) |
127 | return NULL; | 127 | return NULL; |
128 | 128 | ||
129 | memset (state, 0, sizeof (struct ppp_deflate_state)); | ||
130 | state->strm.next_in = NULL; | 129 | state->strm.next_in = NULL; |
131 | state->w_size = w_size; | 130 | state->w_size = w_size; |
132 | state->strm.workspace = vmalloc(zlib_deflate_workspacesize()); | 131 | state->strm.workspace = vmalloc(zlib_deflate_workspacesize()); |
@@ -341,11 +340,10 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len) | |||
341 | if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) | 340 | if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) |
342 | return NULL; | 341 | return NULL; |
343 | 342 | ||
344 | state = kmalloc(sizeof(*state), GFP_KERNEL); | 343 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
345 | if (state == NULL) | 344 | if (state == NULL) |
346 | return NULL; | 345 | return NULL; |
347 | 346 | ||
348 | memset (state, 0, sizeof (struct ppp_deflate_state)); | ||
349 | state->w_size = w_size; | 347 | state->w_size = w_size; |
350 | state->strm.next_out = NULL; | 348 | state->strm.next_out = NULL; |
351 | state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), | 349 | state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3ef0092dc09..ef3325b6923 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -2684,8 +2684,7 @@ static void __exit ppp_cleanup(void) | |||
2684 | if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) | 2684 | if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) |
2685 | printk(KERN_ERR "PPP: removing module but units remain!\n"); | 2685 | printk(KERN_ERR "PPP: removing module but units remain!\n"); |
2686 | cardmap_destroy(&all_ppp_units); | 2686 | cardmap_destroy(&all_ppp_units); |
2687 | if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) | 2687 | unregister_chrdev(PPP_MAJOR, "ppp"); |
2688 | printk(KERN_ERR "PPP: failed to unregister PPP device\n"); | ||
2689 | device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); | 2688 | device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); |
2690 | class_destroy(ppp_class); | 2689 | class_destroy(ppp_class); |
2691 | } | 2690 | } |
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c index d5bdd257465..f79cf87a2bf 100644 --- a/drivers/net/ppp_mppe.c +++ b/drivers/net/ppp_mppe.c | |||
@@ -200,11 +200,10 @@ static void *mppe_alloc(unsigned char *options, int optlen) | |||
200 | || options[0] != CI_MPPE || options[1] != CILEN_MPPE) | 200 | || options[0] != CI_MPPE || options[1] != CILEN_MPPE) |
201 | goto out; | 201 | goto out; |
202 | 202 | ||
203 | state = kmalloc(sizeof(*state), GFP_KERNEL); | 203 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
204 | if (state == NULL) | 204 | if (state == NULL) |
205 | goto out; | 205 | goto out; |
206 | 206 | ||
207 | memset(state, 0, sizeof(*state)); | ||
208 | 207 | ||
209 | state->arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); | 208 | state->arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
210 | if (IS_ERR(state->arc4)) { | 209 | if (IS_ERR(state->arc4)) { |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 5918fab3834..ce64032a465 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -207,13 +207,12 @@ ppp_sync_open(struct tty_struct *tty) | |||
207 | struct syncppp *ap; | 207 | struct syncppp *ap; |
208 | int err; | 208 | int err; |
209 | 209 | ||
210 | ap = kmalloc(sizeof(*ap), GFP_KERNEL); | 210 | ap = kzalloc(sizeof(*ap), GFP_KERNEL); |
211 | err = -ENOMEM; | 211 | err = -ENOMEM; |
212 | if (ap == 0) | 212 | if (ap == 0) |
213 | goto out; | 213 | goto out; |
214 | 214 | ||
215 | /* initialize the syncppp structure */ | 215 | /* initialize the syncppp structure */ |
216 | memset(ap, 0, sizeof(*ap)); | ||
217 | ap->tty = tty; | 216 | ap->tty = tty; |
218 | ap->mru = PPP_MRU; | 217 | ap->mru = PPP_MRU; |
219 | spin_lock_init(&ap->xmit_lock); | 218 | spin_lock_init(&ap->xmit_lock); |
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c index 451486b32f2..7dae4d40497 100644 --- a/drivers/net/saa9730.c +++ b/drivers/net/saa9730.c | |||
@@ -940,15 +940,14 @@ static void lan_saa9730_set_multicast(struct net_device *dev) | |||
940 | CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC, | 940 | CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC, |
941 | &lp->lan_saa9730_regs->CamCtl); | 941 | &lp->lan_saa9730_regs->CamCtl); |
942 | } else { | 942 | } else { |
943 | if (dev->flags & IFF_ALLMULTI) { | 943 | if (dev->flags & IFF_ALLMULTI || dev->mc_count) { |
944 | /* accept all multicast packets */ | 944 | /* accept all multicast packets */ |
945 | writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC | | ||
946 | CAM_CONTROL_BROAD_ACC, | ||
947 | &lp->lan_saa9730_regs->CamCtl); | ||
948 | } else { | ||
949 | /* | 945 | /* |
950 | * Will handle the multicast stuff later. -carstenl | 946 | * Will handle the multicast stuff later. -carstenl |
951 | */ | 947 | */ |
948 | writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC | | ||
949 | CAM_CONTROL_BROAD_ACC, | ||
950 | &lp->lan_saa9730_regs->CamCtl); | ||
952 | } | 951 | } |
953 | } | 952 | } |
954 | 953 | ||
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index e886e8d7cfd..4c3d98ff4cd 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
@@ -600,10 +600,9 @@ static int __init shaper_init(void) | |||
600 | return -ENODEV; | 600 | return -ENODEV; |
601 | 601 | ||
602 | alloc_size = sizeof(*dev) * shapers; | 602 | alloc_size = sizeof(*dev) * shapers; |
603 | devs = kmalloc(alloc_size, GFP_KERNEL); | 603 | devs = kzalloc(alloc_size, GFP_KERNEL); |
604 | if (!devs) | 604 | if (!devs) |
605 | return -ENOMEM; | 605 | return -ENOMEM; |
606 | memset(devs, 0, alloc_size); | ||
607 | 606 | ||
608 | for (i = 0; i < shapers; i++) { | 607 | for (i = 0; i < shapers; i++) { |
609 | 608 | ||
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 75655add3f3..7f94ca93098 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -626,7 +626,7 @@ static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev) | |||
626 | return -ENODEV; | 626 | return -ENODEV; |
627 | } | 627 | } |
628 | #else | 628 | #else |
629 | static int __devinit tc35815_read_plat_dev_addr(struct device *dev) | 629 | static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev) |
630 | { | 630 | { |
631 | return -ENODEV; | 631 | return -ENODEV; |
632 | } | 632 | } |
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 6b63b350cd5..8ead774d14c 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c | |||
@@ -315,12 +315,11 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) | |||
315 | return -ENODEV; | 315 | return -ENODEV; |
316 | } | 316 | } |
317 | 317 | ||
318 | card = kmalloc(sizeof(card_t), GFP_KERNEL); | 318 | card = kzalloc(sizeof(card_t), GFP_KERNEL); |
319 | if (card == NULL) { | 319 | if (card == NULL) { |
320 | printk(KERN_ERR "c101: unable to allocate memory\n"); | 320 | printk(KERN_ERR "c101: unable to allocate memory\n"); |
321 | return -ENOBUFS; | 321 | return -ENOBUFS; |
322 | } | 322 | } |
323 | memset(card, 0, sizeof(card_t)); | ||
324 | 323 | ||
325 | card->dev = alloc_hdlcdev(card); | 324 | card->dev = alloc_hdlcdev(card); |
326 | if (!card->dev) { | 325 | if (!card->dev) { |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 9ef49ce148b..26058b4f8f3 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -572,13 +572,11 @@ static int cosa_probe(int base, int irq, int dma) | |||
572 | sprintf(cosa->name, "cosa%d", cosa->num); | 572 | sprintf(cosa->name, "cosa%d", cosa->num); |
573 | 573 | ||
574 | /* Initialize the per-channel data */ | 574 | /* Initialize the per-channel data */ |
575 | cosa->chan = kmalloc(sizeof(struct channel_data)*cosa->nchannels, | 575 | cosa->chan = kcalloc(cosa->nchannels, sizeof(struct channel_data), GFP_KERNEL); |
576 | GFP_KERNEL); | ||
577 | if (!cosa->chan) { | 576 | if (!cosa->chan) { |
578 | err = -ENOMEM; | 577 | err = -ENOMEM; |
579 | goto err_out3; | 578 | goto err_out3; |
580 | } | 579 | } |
581 | memset(cosa->chan, 0, sizeof(struct channel_data)*cosa->nchannels); | ||
582 | for (i=0; i<cosa->nchannels; i++) { | 580 | for (i=0; i<cosa->nchannels; i++) { |
583 | cosa->chan[i].cosa = cosa; | 581 | cosa->chan[i].cosa = cosa; |
584 | cosa->chan[i].num = i; | 582 | cosa->chan[i].num = i; |
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c index 6e5f1c89851..a0e8611ad8e 100644 --- a/drivers/net/wan/cycx_main.c +++ b/drivers/net/wan/cycx_main.c | |||
@@ -113,12 +113,10 @@ static int __init cycx_init(void) | |||
113 | /* Verify number of cards and allocate adapter data space */ | 113 | /* Verify number of cards and allocate adapter data space */ |
114 | cycx_ncards = min_t(int, cycx_ncards, CYCX_MAX_CARDS); | 114 | cycx_ncards = min_t(int, cycx_ncards, CYCX_MAX_CARDS); |
115 | cycx_ncards = max_t(int, cycx_ncards, 1); | 115 | cycx_ncards = max_t(int, cycx_ncards, 1); |
116 | cycx_card_array = kmalloc(sizeof(struct cycx_device) * cycx_ncards, | 116 | cycx_card_array = kcalloc(cycx_ncards, sizeof(struct cycx_device), GFP_KERNEL); |
117 | GFP_KERNEL); | ||
118 | if (!cycx_card_array) | 117 | if (!cycx_card_array) |
119 | goto out; | 118 | goto out; |
120 | 119 | ||
121 | memset(cycx_card_array, 0, sizeof(struct cycx_device) * cycx_ncards); | ||
122 | 120 | ||
123 | /* Register adapters with WAN router */ | 121 | /* Register adapters with WAN router */ |
124 | for (cnt = 0; cnt < cycx_ncards; ++cnt) { | 122 | for (cnt = 0; cnt < cycx_ncards; ++cnt) { |
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 016b3ff3ea5..a8af28b273d 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c | |||
@@ -376,11 +376,10 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, | |||
376 | } | 376 | } |
377 | 377 | ||
378 | /* allocate and initialize private data */ | 378 | /* allocate and initialize private data */ |
379 | chan = kmalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL); | 379 | chan = kzalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL); |
380 | if (!chan) | 380 | if (!chan) |
381 | return -ENOMEM; | 381 | return -ENOMEM; |
382 | 382 | ||
383 | memset(chan, 0, sizeof(*chan)); | ||
384 | strcpy(chan->name, conf->name); | 383 | strcpy(chan->name, conf->name); |
385 | chan->card = card; | 384 | chan->card = card; |
386 | chan->link = conf->port; | 385 | chan->link = conf->port; |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index dca02447145..50d2f9108dc 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -890,12 +890,11 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) | |||
890 | struct dscc4_dev_priv *root; | 890 | struct dscc4_dev_priv *root; |
891 | int i, ret = -ENOMEM; | 891 | int i, ret = -ENOMEM; |
892 | 892 | ||
893 | root = kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL); | 893 | root = kcalloc(dev_per_card, sizeof(*root), GFP_KERNEL); |
894 | if (!root) { | 894 | if (!root) { |
895 | printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME); | 895 | printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME); |
896 | goto err_out; | 896 | goto err_out; |
897 | } | 897 | } |
898 | memset(root, 0, dev_per_card*sizeof(*root)); | ||
899 | 898 | ||
900 | for (i = 0; i < dev_per_card; i++) { | 899 | for (i = 0; i < dev_per_card; i++) { |
901 | root[i].dev = alloc_hdlcdev(root + i); | 900 | root[i].dev = alloc_hdlcdev(root + i); |
@@ -903,12 +902,11 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) | |||
903 | goto err_free_dev; | 902 | goto err_free_dev; |
904 | } | 903 | } |
905 | 904 | ||
906 | ppriv = kmalloc(sizeof(*ppriv), GFP_KERNEL); | 905 | ppriv = kzalloc(sizeof(*ppriv), GFP_KERNEL); |
907 | if (!ppriv) { | 906 | if (!ppriv) { |
908 | printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME); | 907 | printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME); |
909 | goto err_free_dev; | 908 | goto err_free_dev; |
910 | } | 909 | } |
911 | memset(ppriv, 0, sizeof(struct dscc4_pci_priv)); | ||
912 | 910 | ||
913 | ppriv->root = root; | 911 | ppriv->root = root; |
914 | spin_lock_init(&ppriv->lock); | 912 | spin_lock_init(&ppriv->lock); |
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 58a53b6d9b4..12dae8e2484 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c | |||
@@ -2476,13 +2476,12 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2476 | } | 2476 | } |
2477 | 2477 | ||
2478 | /* Allocate driver private data */ | 2478 | /* Allocate driver private data */ |
2479 | card = kmalloc(sizeof (struct fst_card_info), GFP_KERNEL); | 2479 | card = kzalloc(sizeof (struct fst_card_info), GFP_KERNEL); |
2480 | if (card == NULL) { | 2480 | if (card == NULL) { |
2481 | printk_err("FarSync card found but insufficient memory for" | 2481 | printk_err("FarSync card found but insufficient memory for" |
2482 | " driver storage\n"); | 2482 | " driver storage\n"); |
2483 | return -ENOMEM; | 2483 | return -ENOMEM; |
2484 | } | 2484 | } |
2485 | memset(card, 0, sizeof (struct fst_card_info)); | ||
2486 | 2485 | ||
2487 | /* Try to enable the device */ | 2486 | /* Try to enable the device */ |
2488 | if ((err = pci_enable_device(pdev)) != 0) { | 2487 | if ((err = pci_enable_device(pdev)) != 0) { |
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 9ba3e4ee6ec..bf5f8d9b5c8 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c | |||
@@ -231,11 +231,10 @@ static struct sv11_device *sv11_init(int iobase, int irq) | |||
231 | return NULL; | 231 | return NULL; |
232 | } | 232 | } |
233 | 233 | ||
234 | sv = kmalloc(sizeof(struct sv11_device), GFP_KERNEL); | 234 | sv = kzalloc(sizeof(struct sv11_device), GFP_KERNEL); |
235 | if(!sv) | 235 | if(!sv) |
236 | goto fail3; | 236 | goto fail3; |
237 | 237 | ||
238 | memset(sv, 0, sizeof(*sv)); | ||
239 | sv->if_ptr=&sv->netdev; | 238 | sv->if_ptr=&sv->netdev; |
240 | 239 | ||
241 | sv->netdev.dev = alloc_netdev(0, "hdlc%d", sv11_setup); | 240 | sv->netdev.dev = alloc_netdev(0, "hdlc%d", sv11_setup); |
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 5c322dfb79f..cbdf0b748bd 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c | |||
@@ -351,12 +351,11 @@ static int __init n2_run(unsigned long io, unsigned long irq, | |||
351 | return -ENODEV; | 351 | return -ENODEV; |
352 | } | 352 | } |
353 | 353 | ||
354 | card = kmalloc(sizeof(card_t), GFP_KERNEL); | 354 | card = kzalloc(sizeof(card_t), GFP_KERNEL); |
355 | if (card == NULL) { | 355 | if (card == NULL) { |
356 | printk(KERN_ERR "n2: unable to allocate memory\n"); | 356 | printk(KERN_ERR "n2: unable to allocate memory\n"); |
357 | return -ENOBUFS; | 357 | return -ENOBUFS; |
358 | } | 358 | } |
359 | memset(card, 0, sizeof(card_t)); | ||
360 | 359 | ||
361 | card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); | 360 | card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); |
362 | card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); | 361 | card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); |
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 5d8c78ee2cd..99fee2f1d01 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
@@ -3456,7 +3456,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3456 | if ((err = pci_enable_device(pdev)) < 0) | 3456 | if ((err = pci_enable_device(pdev)) < 0) |
3457 | return err; | 3457 | return err; |
3458 | 3458 | ||
3459 | card = kmalloc(sizeof(pc300_t), GFP_KERNEL); | 3459 | card = kzalloc(sizeof(pc300_t), GFP_KERNEL); |
3460 | if (card == NULL) { | 3460 | if (card == NULL) { |
3461 | printk("PC300 found at RAM 0x%016llx, " | 3461 | printk("PC300 found at RAM 0x%016llx, " |
3462 | "but could not allocate card structure.\n", | 3462 | "but could not allocate card structure.\n", |
@@ -3464,7 +3464,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3464 | err = -ENOMEM; | 3464 | err = -ENOMEM; |
3465 | goto err_disable_dev; | 3465 | goto err_disable_dev; |
3466 | } | 3466 | } |
3467 | memset(card, 0, sizeof(pc300_t)); | ||
3468 | 3467 | ||
3469 | err = -ENODEV; | 3468 | err = -ENODEV; |
3470 | 3469 | ||
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index dfbd3b00f03..6353cb5c658 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c | |||
@@ -334,14 +334,13 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, | |||
334 | return i; | 334 | return i; |
335 | } | 335 | } |
336 | 336 | ||
337 | card = kmalloc(sizeof(card_t), GFP_KERNEL); | 337 | card = kzalloc(sizeof(card_t), GFP_KERNEL); |
338 | if (card == NULL) { | 338 | if (card == NULL) { |
339 | printk(KERN_ERR "pc300: unable to allocate memory\n"); | 339 | printk(KERN_ERR "pc300: unable to allocate memory\n"); |
340 | pci_release_regions(pdev); | 340 | pci_release_regions(pdev); |
341 | pci_disable_device(pdev); | 341 | pci_disable_device(pdev); |
342 | return -ENOBUFS; | 342 | return -ENOBUFS; |
343 | } | 343 | } |
344 | memset(card, 0, sizeof(card_t)); | ||
345 | pci_set_drvdata(pdev, card); | 344 | pci_set_drvdata(pdev, card); |
346 | 345 | ||
347 | if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 || | 346 | if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 || |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 7f720de2e9f..092e51d8903 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
@@ -312,14 +312,13 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, | |||
312 | return i; | 312 | return i; |
313 | } | 313 | } |
314 | 314 | ||
315 | card = kmalloc(sizeof(card_t), GFP_KERNEL); | 315 | card = kzalloc(sizeof(card_t), GFP_KERNEL); |
316 | if (card == NULL) { | 316 | if (card == NULL) { |
317 | printk(KERN_ERR "pci200syn: unable to allocate memory\n"); | 317 | printk(KERN_ERR "pci200syn: unable to allocate memory\n"); |
318 | pci_release_regions(pdev); | 318 | pci_release_regions(pdev); |
319 | pci_disable_device(pdev); | 319 | pci_disable_device(pdev); |
320 | return -ENOBUFS; | 320 | return -ENOBUFS; |
321 | } | 321 | } |
322 | memset(card, 0, sizeof(card_t)); | ||
323 | pci_set_drvdata(pdev, card); | 322 | pci_set_drvdata(pdev, card); |
324 | card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); | 323 | card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); |
325 | card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); | 324 | card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); |
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 6a485f0556f..792e588d7d6 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c | |||
@@ -1196,10 +1196,9 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r | |||
1196 | 1196 | ||
1197 | if (read) | 1197 | if (read) |
1198 | { | 1198 | { |
1199 | temp = kmalloc(mem.len, GFP_KERNEL); | 1199 | temp = kzalloc(mem.len, GFP_KERNEL); |
1200 | if (!temp) | 1200 | if (!temp) |
1201 | return(-ENOMEM); | 1201 | return(-ENOMEM); |
1202 | memset(temp, 0, mem.len); | ||
1203 | sdla_read(dev, mem.addr, temp, mem.len); | 1202 | sdla_read(dev, mem.addr, temp, mem.len); |
1204 | if(copy_to_user(mem.data, temp, mem.len)) | 1203 | if(copy_to_user(mem.data, temp, mem.len)) |
1205 | { | 1204 | { |
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 131358108c5..11276bf3149 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c | |||
@@ -270,11 +270,10 @@ static __init struct slvl_board *slvl_init(int iobase, int irq, | |||
270 | return NULL; | 270 | return NULL; |
271 | } | 271 | } |
272 | 272 | ||
273 | b = kmalloc(sizeof(struct slvl_board), GFP_KERNEL); | 273 | b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL); |
274 | if(!b) | 274 | if(!b) |
275 | goto fail3; | 275 | goto fail3; |
276 | 276 | ||
277 | memset(b, 0, sizeof(*b)); | ||
278 | if (!(b->dev[0]= slvl_alloc(iobase, irq))) | 277 | if (!(b->dev[0]= slvl_alloc(iobase, irq))) |
279 | goto fail2; | 278 | goto fail2; |
280 | 279 | ||
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index c7360157433..3c78f985638 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c | |||
@@ -599,7 +599,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, | |||
599 | } | 599 | } |
600 | 600 | ||
601 | alloc_size = sizeof(card_t) + ports * sizeof(port_t); | 601 | alloc_size = sizeof(card_t) + ports * sizeof(port_t); |
602 | card = kmalloc(alloc_size, GFP_KERNEL); | 602 | card = kzalloc(alloc_size, GFP_KERNEL); |
603 | if (card == NULL) { | 603 | if (card == NULL) { |
604 | printk(KERN_ERR "wanXL %s: unable to allocate memory\n", | 604 | printk(KERN_ERR "wanXL %s: unable to allocate memory\n", |
605 | pci_name(pdev)); | 605 | pci_name(pdev)); |
@@ -607,7 +607,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, | |||
607 | pci_disable_device(pdev); | 607 | pci_disable_device(pdev); |
608 | return -ENOBUFS; | 608 | return -ENOBUFS; |
609 | } | 609 | } |
610 | memset(card, 0, alloc_size); | ||
611 | 610 | ||
612 | pci_set_drvdata(pdev, card); | 611 | pci_set_drvdata(pdev, card); |
613 | card->pdev = pdev; | 612 | card->pdev = pdev; |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 1c9edd97acc..c48b1cc63fd 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -786,14 +786,12 @@ static int __init init_x25_asy(void) | |||
786 | printk(KERN_INFO "X.25 async: version 0.00 ALPHA " | 786 | printk(KERN_INFO "X.25 async: version 0.00 ALPHA " |
787 | "(dynamic channels, max=%d).\n", x25_asy_maxdev ); | 787 | "(dynamic channels, max=%d).\n", x25_asy_maxdev ); |
788 | 788 | ||
789 | x25_asy_devs = kmalloc(sizeof(struct net_device *)*x25_asy_maxdev, | 789 | x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device*), GFP_KERNEL); |
790 | GFP_KERNEL); | ||
791 | if (!x25_asy_devs) { | 790 | if (!x25_asy_devs) { |
792 | printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] " | 791 | printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] " |
793 | "array! Uaargh! (-> No X.25 available)\n"); | 792 | "array! Uaargh! (-> No X.25 available)\n"); |
794 | return -ENOMEM; | 793 | return -ENOMEM; |
795 | } | 794 | } |
796 | memset(x25_asy_devs, 0, sizeof(struct net_device *)*x25_asy_maxdev); | ||
797 | 795 | ||
798 | return tty_register_ldisc(N_X25, &x25_ldisc); | 796 | return tty_register_ldisc(N_X25, &x25_ldisc); |
799 | } | 797 | } |
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 072ede71e57..8990585bd22 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c | |||
@@ -7868,10 +7868,10 @@ static int ipw2100_wx_set_powermode(struct net_device *dev, | |||
7868 | goto done; | 7868 | goto done; |
7869 | } | 7869 | } |
7870 | 7870 | ||
7871 | if ((mode < 1) || (mode > POWER_MODES)) | 7871 | if ((mode < 0) || (mode > POWER_MODES)) |
7872 | mode = IPW_POWER_AUTO; | 7872 | mode = IPW_POWER_AUTO; |
7873 | 7873 | ||
7874 | if (priv->power_mode != mode) | 7874 | if (IPW_POWER_LEVEL(priv->power_mode) != mode) |
7875 | err = ipw2100_set_power_mode(priv, mode); | 7875 | err = ipw2100_set_power_mode(priv, mode); |
7876 | done: | 7876 | done: |
7877 | mutex_unlock(&priv->action_mutex); | 7877 | mutex_unlock(&priv->action_mutex); |
@@ -7902,7 +7902,7 @@ static int ipw2100_wx_get_powermode(struct net_device *dev, | |||
7902 | break; | 7902 | break; |
7903 | case IPW_POWER_AUTO: | 7903 | case IPW_POWER_AUTO: |
7904 | snprintf(extra, MAX_POWER_STRING, | 7904 | snprintf(extra, MAX_POWER_STRING, |
7905 | "Power save level: %d (Auto)", 0); | 7905 | "Power save level: %d (Auto)", level); |
7906 | break; | 7906 | break; |
7907 | default: | 7907 | default: |
7908 | timeout = timeout_duration[level - 1] / 1000; | 7908 | timeout = timeout_duration[level - 1] / 1000; |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index aa32a97380e..61497c46746 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -70,7 +70,7 @@ | |||
70 | #define VQ | 70 | #define VQ |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ | 73 | #define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ |
74 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" | 74 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" |
75 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" | 75 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" |
76 | #define DRV_VERSION IPW2200_VERSION | 76 | #define DRV_VERSION IPW2200_VERSION |
@@ -2506,7 +2506,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) | |||
2506 | break; | 2506 | break; |
2507 | } | 2507 | } |
2508 | 2508 | ||
2509 | param = cpu_to_le32(mode); | 2509 | param = cpu_to_le32(param); |
2510 | return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), | 2510 | return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), |
2511 | ¶m); | 2511 | ¶m); |
2512 | } | 2512 | } |
@@ -9568,6 +9568,7 @@ static int ipw_wx_set_power(struct net_device *dev, | |||
9568 | priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; | 9568 | priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; |
9569 | else | 9569 | else |
9570 | priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; | 9570 | priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; |
9571 | |||
9571 | err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); | 9572 | err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); |
9572 | if (err) { | 9573 | if (err) { |
9573 | IPW_DEBUG_WX("failed setting power mode.\n"); | 9574 | IPW_DEBUG_WX("failed setting power mode.\n"); |
@@ -9604,22 +9605,19 @@ static int ipw_wx_set_powermode(struct net_device *dev, | |||
9604 | struct ipw_priv *priv = ieee80211_priv(dev); | 9605 | struct ipw_priv *priv = ieee80211_priv(dev); |
9605 | int mode = *(int *)extra; | 9606 | int mode = *(int *)extra; |
9606 | int err; | 9607 | int err; |
9608 | |||
9607 | mutex_lock(&priv->mutex); | 9609 | mutex_lock(&priv->mutex); |
9608 | if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { | 9610 | if ((mode < 1) || (mode > IPW_POWER_LIMIT)) |
9609 | mode = IPW_POWER_AC; | 9611 | mode = IPW_POWER_AC; |
9610 | priv->power_mode = mode; | ||
9611 | } else { | ||
9612 | priv->power_mode = IPW_POWER_ENABLED | mode; | ||
9613 | } | ||
9614 | 9612 | ||
9615 | if (priv->power_mode != mode) { | 9613 | if (IPW_POWER_LEVEL(priv->power_mode) != mode) { |
9616 | err = ipw_send_power_mode(priv, mode); | 9614 | err = ipw_send_power_mode(priv, mode); |
9617 | |||
9618 | if (err) { | 9615 | if (err) { |
9619 | IPW_DEBUG_WX("failed setting power mode.\n"); | 9616 | IPW_DEBUG_WX("failed setting power mode.\n"); |
9620 | mutex_unlock(&priv->mutex); | 9617 | mutex_unlock(&priv->mutex); |
9621 | return err; | 9618 | return err; |
9622 | } | 9619 | } |
9620 | priv->power_mode = IPW_POWER_ENABLED | mode; | ||
9623 | } | 9621 | } |
9624 | mutex_unlock(&priv->mutex); | 9622 | mutex_unlock(&priv->mutex); |
9625 | return 0; | 9623 | return 0; |
@@ -10555,7 +10553,7 @@ static irqreturn_t ipw_isr(int irq, void *data) | |||
10555 | spin_lock(&priv->irq_lock); | 10553 | spin_lock(&priv->irq_lock); |
10556 | 10554 | ||
10557 | if (!(priv->status & STATUS_INT_ENABLED)) { | 10555 | if (!(priv->status & STATUS_INT_ENABLED)) { |
10558 | /* Shared IRQ */ | 10556 | /* IRQ is disabled */ |
10559 | goto none; | 10557 | goto none; |
10560 | } | 10558 | } |
10561 | 10559 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 28d41a29d7b..a9c339ef116 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -72,6 +72,8 @@ static struct usb_device_id usb_ids[] = { | |||
72 | { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, | 72 | { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, |
73 | { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, | 73 | { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, |
74 | { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, | 74 | { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, |
75 | { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B }, | ||
76 | { USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B }, | ||
75 | /* "Driverless" devices that need ejecting */ | 77 | /* "Driverless" devices that need ejecting */ |
76 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, | 78 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, |
77 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, | 79 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, |