Commit 66c097165cf6d4196e798145fb33c768164fb361
Committed by
Jeff Garzik
1 parent
a664ccf430
Exists in
master
and in
7 other branches
[PATCH] powerpc/cell spidernet variable name change
Cosmetic patch: give the variable holding the numer of descriptors a more descriptive name, so to avoid confusion. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> Cc: James K Lewis <jklewis@us.ibm.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Showing 3 changed files with 10 additions and 10 deletions Inline Diff
drivers/net/spider_net.c
1 | /* | 1 | /* |
2 | * Network device driver for Cell Processor-Based Blade | 2 | * Network device driver for Cell Processor-Based Blade |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * | 5 | * |
6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> |
7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2, or (at your option) | 11 | * the Free Software Foundation; either version 2, or (at your option) |
12 | * any later version. | 12 | * any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/crc32.h> | 25 | #include <linux/crc32.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/ethtool.h> | 28 | #include <linux/ethtool.h> |
29 | #include <linux/firmware.h> | 29 | #include <linux/firmware.h> |
30 | #include <linux/if_vlan.h> | 30 | #include <linux/if_vlan.h> |
31 | #include <linux/in.h> | 31 | #include <linux/in.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/ip.h> | 34 | #include <linux/ip.h> |
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/mii.h> | 36 | #include <linux/mii.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/netdevice.h> | 38 | #include <linux/netdevice.h> |
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/skbuff.h> | 41 | #include <linux/skbuff.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/tcp.h> | 43 | #include <linux/tcp.h> |
44 | #include <linux/types.h> | 44 | #include <linux/types.h> |
45 | #include <linux/vmalloc.h> | 45 | #include <linux/vmalloc.h> |
46 | #include <linux/wait.h> | 46 | #include <linux/wait.h> |
47 | #include <linux/workqueue.h> | 47 | #include <linux/workqueue.h> |
48 | #include <asm/bitops.h> | 48 | #include <asm/bitops.h> |
49 | #include <asm/pci-bridge.h> | 49 | #include <asm/pci-bridge.h> |
50 | #include <net/checksum.h> | 50 | #include <net/checksum.h> |
51 | 51 | ||
52 | #include "spider_net.h" | 52 | #include "spider_net.h" |
53 | 53 | ||
54 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \ | 54 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \ |
55 | "<Jens.Osterkamp@de.ibm.com>"); | 55 | "<Jens.Osterkamp@de.ibm.com>"); |
56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); | 56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); |
57 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
58 | MODULE_VERSION(VERSION); | 58 | MODULE_VERSION(VERSION); |
59 | 59 | ||
60 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; | 60 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; |
61 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; | 61 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; |
62 | 62 | ||
63 | module_param(rx_descriptors, int, 0444); | 63 | module_param(rx_descriptors, int, 0444); |
64 | module_param(tx_descriptors, int, 0444); | 64 | module_param(tx_descriptors, int, 0444); |
65 | 65 | ||
66 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ | 66 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ |
67 | "in rx chains"); | 67 | "in rx chains"); |
68 | MODULE_PARM_DESC(tx_descriptors, "number of descriptors used " \ | 68 | MODULE_PARM_DESC(tx_descriptors, "number of descriptors used " \ |
69 | "in tx chain"); | 69 | "in tx chain"); |
70 | 70 | ||
71 | char spider_net_driver_name[] = "spidernet"; | 71 | char spider_net_driver_name[] = "spidernet"; |
72 | 72 | ||
73 | static struct pci_device_id spider_net_pci_tbl[] = { | 73 | static struct pci_device_id spider_net_pci_tbl[] = { |
74 | { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SPIDER_NET, | 74 | { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SPIDER_NET, |
75 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 75 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, |
76 | { 0, } | 76 | { 0, } |
77 | }; | 77 | }; |
78 | 78 | ||
79 | MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); | 79 | MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); |
80 | 80 | ||
81 | /** | 81 | /** |
82 | * spider_net_read_reg - reads an SMMIO register of a card | 82 | * spider_net_read_reg - reads an SMMIO register of a card |
83 | * @card: device structure | 83 | * @card: device structure |
84 | * @reg: register to read from | 84 | * @reg: register to read from |
85 | * | 85 | * |
86 | * returns the content of the specified SMMIO register. | 86 | * returns the content of the specified SMMIO register. |
87 | */ | 87 | */ |
88 | static inline u32 | 88 | static inline u32 |
89 | spider_net_read_reg(struct spider_net_card *card, u32 reg) | 89 | spider_net_read_reg(struct spider_net_card *card, u32 reg) |
90 | { | 90 | { |
91 | u32 value; | 91 | u32 value; |
92 | 92 | ||
93 | value = readl(card->regs + reg); | 93 | value = readl(card->regs + reg); |
94 | value = le32_to_cpu(value); | 94 | value = le32_to_cpu(value); |
95 | 95 | ||
96 | return value; | 96 | return value; |
97 | } | 97 | } |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * spider_net_write_reg - writes to an SMMIO register of a card | 100 | * spider_net_write_reg - writes to an SMMIO register of a card |
101 | * @card: device structure | 101 | * @card: device structure |
102 | * @reg: register to write to | 102 | * @reg: register to write to |
103 | * @value: value to write into the specified SMMIO register | 103 | * @value: value to write into the specified SMMIO register |
104 | */ | 104 | */ |
105 | static inline void | 105 | static inline void |
106 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) | 106 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) |
107 | { | 107 | { |
108 | value = cpu_to_le32(value); | 108 | value = cpu_to_le32(value); |
109 | writel(value, card->regs + reg); | 109 | writel(value, card->regs + reg); |
110 | } | 110 | } |
111 | 111 | ||
112 | /** spider_net_write_phy - write to phy register | 112 | /** spider_net_write_phy - write to phy register |
113 | * @netdev: adapter to be written to | 113 | * @netdev: adapter to be written to |
114 | * @mii_id: id of MII | 114 | * @mii_id: id of MII |
115 | * @reg: PHY register | 115 | * @reg: PHY register |
116 | * @val: value to be written to phy register | 116 | * @val: value to be written to phy register |
117 | * | 117 | * |
118 | * spider_net_write_phy_register writes to an arbitrary PHY | 118 | * spider_net_write_phy_register writes to an arbitrary PHY |
119 | * register via the spider GPCWOPCMD register. We assume the queue does | 119 | * register via the spider GPCWOPCMD register. We assume the queue does |
120 | * not run full (not more than 15 commands outstanding). | 120 | * not run full (not more than 15 commands outstanding). |
121 | **/ | 121 | **/ |
122 | static void | 122 | static void |
123 | spider_net_write_phy(struct net_device *netdev, int mii_id, | 123 | spider_net_write_phy(struct net_device *netdev, int mii_id, |
124 | int reg, int val) | 124 | int reg, int val) |
125 | { | 125 | { |
126 | struct spider_net_card *card = netdev_priv(netdev); | 126 | struct spider_net_card *card = netdev_priv(netdev); |
127 | u32 writevalue; | 127 | u32 writevalue; |
128 | 128 | ||
129 | writevalue = ((u32)mii_id << 21) | | 129 | writevalue = ((u32)mii_id << 21) | |
130 | ((u32)reg << 16) | ((u32)val); | 130 | ((u32)reg << 16) | ((u32)val); |
131 | 131 | ||
132 | spider_net_write_reg(card, SPIDER_NET_GPCWOPCMD, writevalue); | 132 | spider_net_write_reg(card, SPIDER_NET_GPCWOPCMD, writevalue); |
133 | } | 133 | } |
134 | 134 | ||
135 | /** spider_net_read_phy - read from phy register | 135 | /** spider_net_read_phy - read from phy register |
136 | * @netdev: network device to be read from | 136 | * @netdev: network device to be read from |
137 | * @mii_id: id of MII | 137 | * @mii_id: id of MII |
138 | * @reg: PHY register | 138 | * @reg: PHY register |
139 | * | 139 | * |
140 | * Returns value read from PHY register | 140 | * Returns value read from PHY register |
141 | * | 141 | * |
142 | * spider_net_write_phy reads from an arbitrary PHY | 142 | * spider_net_write_phy reads from an arbitrary PHY |
143 | * register via the spider GPCROPCMD register | 143 | * register via the spider GPCROPCMD register |
144 | **/ | 144 | **/ |
145 | static int | 145 | static int |
146 | spider_net_read_phy(struct net_device *netdev, int mii_id, int reg) | 146 | spider_net_read_phy(struct net_device *netdev, int mii_id, int reg) |
147 | { | 147 | { |
148 | struct spider_net_card *card = netdev_priv(netdev); | 148 | struct spider_net_card *card = netdev_priv(netdev); |
149 | u32 readvalue; | 149 | u32 readvalue; |
150 | 150 | ||
151 | readvalue = ((u32)mii_id << 21) | ((u32)reg << 16); | 151 | readvalue = ((u32)mii_id << 21) | ((u32)reg << 16); |
152 | spider_net_write_reg(card, SPIDER_NET_GPCROPCMD, readvalue); | 152 | spider_net_write_reg(card, SPIDER_NET_GPCROPCMD, readvalue); |
153 | 153 | ||
154 | /* we don't use semaphores to wait for an SPIDER_NET_GPROPCMPINT | 154 | /* we don't use semaphores to wait for an SPIDER_NET_GPROPCMPINT |
155 | * interrupt, as we poll for the completion of the read operation | 155 | * interrupt, as we poll for the completion of the read operation |
156 | * in spider_net_read_phy. Should take about 50 us */ | 156 | * in spider_net_read_phy. Should take about 50 us */ |
157 | do { | 157 | do { |
158 | readvalue = spider_net_read_reg(card, SPIDER_NET_GPCROPCMD); | 158 | readvalue = spider_net_read_reg(card, SPIDER_NET_GPCROPCMD); |
159 | } while (readvalue & SPIDER_NET_GPREXEC); | 159 | } while (readvalue & SPIDER_NET_GPREXEC); |
160 | 160 | ||
161 | readvalue &= SPIDER_NET_GPRDAT_MASK; | 161 | readvalue &= SPIDER_NET_GPRDAT_MASK; |
162 | 162 | ||
163 | return readvalue; | 163 | return readvalue; |
164 | } | 164 | } |
165 | 165 | ||
166 | /** | 166 | /** |
167 | * spider_net_rx_irq_off - switch off rx irq on this spider card | 167 | * spider_net_rx_irq_off - switch off rx irq on this spider card |
168 | * @card: device structure | 168 | * @card: device structure |
169 | * | 169 | * |
170 | * switches off rx irq by masking them out in the GHIINTnMSK register | 170 | * switches off rx irq by masking them out in the GHIINTnMSK register |
171 | */ | 171 | */ |
172 | static void | 172 | static void |
173 | spider_net_rx_irq_off(struct spider_net_card *card) | 173 | spider_net_rx_irq_off(struct spider_net_card *card) |
174 | { | 174 | { |
175 | u32 regvalue; | 175 | u32 regvalue; |
176 | 176 | ||
177 | regvalue = SPIDER_NET_INT0_MASK_VALUE & (~SPIDER_NET_RXINT); | 177 | regvalue = SPIDER_NET_INT0_MASK_VALUE & (~SPIDER_NET_RXINT); |
178 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); | 178 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); |
179 | } | 179 | } |
180 | 180 | ||
181 | /** | 181 | /** |
182 | * spider_net_rx_irq_on - switch on rx irq on this spider card | 182 | * spider_net_rx_irq_on - switch on rx irq on this spider card |
183 | * @card: device structure | 183 | * @card: device structure |
184 | * | 184 | * |
185 | * switches on rx irq by enabling them in the GHIINTnMSK register | 185 | * switches on rx irq by enabling them in the GHIINTnMSK register |
186 | */ | 186 | */ |
187 | static void | 187 | static void |
188 | spider_net_rx_irq_on(struct spider_net_card *card) | 188 | spider_net_rx_irq_on(struct spider_net_card *card) |
189 | { | 189 | { |
190 | u32 regvalue; | 190 | u32 regvalue; |
191 | 191 | ||
192 | regvalue = SPIDER_NET_INT0_MASK_VALUE | SPIDER_NET_RXINT; | 192 | regvalue = SPIDER_NET_INT0_MASK_VALUE | SPIDER_NET_RXINT; |
193 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); | 193 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); |
194 | } | 194 | } |
195 | 195 | ||
196 | /** | 196 | /** |
197 | * spider_net_set_promisc - sets the unicast address or the promiscuous mode | 197 | * spider_net_set_promisc - sets the unicast address or the promiscuous mode |
198 | * @card: card structure | 198 | * @card: card structure |
199 | * | 199 | * |
200 | * spider_net_set_promisc sets the unicast destination address filter and | 200 | * spider_net_set_promisc sets the unicast destination address filter and |
201 | * thus either allows for non-promisc mode or promisc mode | 201 | * thus either allows for non-promisc mode or promisc mode |
202 | */ | 202 | */ |
203 | static void | 203 | static void |
204 | spider_net_set_promisc(struct spider_net_card *card) | 204 | spider_net_set_promisc(struct spider_net_card *card) |
205 | { | 205 | { |
206 | u32 macu, macl; | 206 | u32 macu, macl; |
207 | struct net_device *netdev = card->netdev; | 207 | struct net_device *netdev = card->netdev; |
208 | 208 | ||
209 | if (netdev->flags & IFF_PROMISC) { | 209 | if (netdev->flags & IFF_PROMISC) { |
210 | /* clear destination entry 0 */ | 210 | /* clear destination entry 0 */ |
211 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, 0); | 211 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, 0); |
212 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, 0); | 212 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, 0); |
213 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, | 213 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, |
214 | SPIDER_NET_PROMISC_VALUE); | 214 | SPIDER_NET_PROMISC_VALUE); |
215 | } else { | 215 | } else { |
216 | macu = netdev->dev_addr[0]; | 216 | macu = netdev->dev_addr[0]; |
217 | macu <<= 8; | 217 | macu <<= 8; |
218 | macu |= netdev->dev_addr[1]; | 218 | macu |= netdev->dev_addr[1]; |
219 | memcpy(&macl, &netdev->dev_addr[2], sizeof(macl)); | 219 | memcpy(&macl, &netdev->dev_addr[2], sizeof(macl)); |
220 | 220 | ||
221 | macu |= SPIDER_NET_UA_DESCR_VALUE; | 221 | macu |= SPIDER_NET_UA_DESCR_VALUE; |
222 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, macu); | 222 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, macu); |
223 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, macl); | 223 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, macl); |
224 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, | 224 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, |
225 | SPIDER_NET_NONPROMISC_VALUE); | 225 | SPIDER_NET_NONPROMISC_VALUE); |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | /** | 229 | /** |
230 | * spider_net_get_mac_address - read mac address from spider card | 230 | * spider_net_get_mac_address - read mac address from spider card |
231 | * @card: device structure | 231 | * @card: device structure |
232 | * | 232 | * |
233 | * reads MAC address from GMACUNIMACU and GMACUNIMACL registers | 233 | * reads MAC address from GMACUNIMACU and GMACUNIMACL registers |
234 | */ | 234 | */ |
235 | static int | 235 | static int |
236 | spider_net_get_mac_address(struct net_device *netdev) | 236 | spider_net_get_mac_address(struct net_device *netdev) |
237 | { | 237 | { |
238 | struct spider_net_card *card = netdev_priv(netdev); | 238 | struct spider_net_card *card = netdev_priv(netdev); |
239 | u32 macl, macu; | 239 | u32 macl, macu; |
240 | 240 | ||
241 | macl = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACL); | 241 | macl = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACL); |
242 | macu = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACU); | 242 | macu = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACU); |
243 | 243 | ||
244 | netdev->dev_addr[0] = (macu >> 24) & 0xff; | 244 | netdev->dev_addr[0] = (macu >> 24) & 0xff; |
245 | netdev->dev_addr[1] = (macu >> 16) & 0xff; | 245 | netdev->dev_addr[1] = (macu >> 16) & 0xff; |
246 | netdev->dev_addr[2] = (macu >> 8) & 0xff; | 246 | netdev->dev_addr[2] = (macu >> 8) & 0xff; |
247 | netdev->dev_addr[3] = macu & 0xff; | 247 | netdev->dev_addr[3] = macu & 0xff; |
248 | netdev->dev_addr[4] = (macl >> 8) & 0xff; | 248 | netdev->dev_addr[4] = (macl >> 8) & 0xff; |
249 | netdev->dev_addr[5] = macl & 0xff; | 249 | netdev->dev_addr[5] = macl & 0xff; |
250 | 250 | ||
251 | if (!is_valid_ether_addr(&netdev->dev_addr[0])) | 251 | if (!is_valid_ether_addr(&netdev->dev_addr[0])) |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | 253 | ||
254 | return 0; | 254 | return 0; |
255 | } | 255 | } |
256 | 256 | ||
257 | /** | 257 | /** |
258 | * spider_net_get_descr_status -- returns the status of a descriptor | 258 | * spider_net_get_descr_status -- returns the status of a descriptor |
259 | * @descr: descriptor to look at | 259 | * @descr: descriptor to look at |
260 | * | 260 | * |
261 | * returns the status as in the dmac_cmd_status field of the descriptor | 261 | * returns the status as in the dmac_cmd_status field of the descriptor |
262 | */ | 262 | */ |
263 | static inline int | 263 | static inline int |
264 | spider_net_get_descr_status(struct spider_net_descr *descr) | 264 | spider_net_get_descr_status(struct spider_net_descr *descr) |
265 | { | 265 | { |
266 | return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; | 266 | return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; |
267 | } | 267 | } |
268 | 268 | ||
269 | /** | 269 | /** |
270 | * spider_net_free_chain - free descriptor chain | 270 | * spider_net_free_chain - free descriptor chain |
271 | * @card: card structure | 271 | * @card: card structure |
272 | * @chain: address of chain | 272 | * @chain: address of chain |
273 | * | 273 | * |
274 | */ | 274 | */ |
275 | static void | 275 | static void |
276 | spider_net_free_chain(struct spider_net_card *card, | 276 | spider_net_free_chain(struct spider_net_card *card, |
277 | struct spider_net_descr_chain *chain) | 277 | struct spider_net_descr_chain *chain) |
278 | { | 278 | { |
279 | struct spider_net_descr *descr; | 279 | struct spider_net_descr *descr; |
280 | 280 | ||
281 | for (descr = chain->tail; !descr->bus_addr; descr = descr->next) { | 281 | for (descr = chain->tail; !descr->bus_addr; descr = descr->next) { |
282 | pci_unmap_single(card->pdev, descr->bus_addr, | 282 | pci_unmap_single(card->pdev, descr->bus_addr, |
283 | SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); | 283 | SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); |
284 | descr->bus_addr = 0; | 284 | descr->bus_addr = 0; |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | /** | 288 | /** |
289 | * spider_net_init_chain - links descriptor chain | 289 | * spider_net_init_chain - links descriptor chain |
290 | * @card: card structure | 290 | * @card: card structure |
291 | * @chain: address of chain | 291 | * @chain: address of chain |
292 | * @start_descr: address of descriptor array | 292 | * @start_descr: address of descriptor array |
293 | * @no: number of descriptors | 293 | * @no: number of descriptors |
294 | * | 294 | * |
295 | * we manage a circular list that mirrors the hardware structure, | 295 | * we manage a circular list that mirrors the hardware structure, |
296 | * except that the hardware uses bus addresses. | 296 | * except that the hardware uses bus addresses. |
297 | * | 297 | * |
298 | * returns 0 on success, <0 on failure | 298 | * returns 0 on success, <0 on failure |
299 | */ | 299 | */ |
300 | static int | 300 | static int |
301 | spider_net_init_chain(struct spider_net_card *card, | 301 | spider_net_init_chain(struct spider_net_card *card, |
302 | struct spider_net_descr_chain *chain, | 302 | struct spider_net_descr_chain *chain, |
303 | struct spider_net_descr *start_descr, | 303 | struct spider_net_descr *start_descr, |
304 | int direction, int no) | 304 | int direction, int no) |
305 | { | 305 | { |
306 | int i; | 306 | int i; |
307 | struct spider_net_descr *descr; | 307 | struct spider_net_descr *descr; |
308 | dma_addr_t buf; | 308 | dma_addr_t buf; |
309 | 309 | ||
310 | descr = start_descr; | 310 | descr = start_descr; |
311 | memset(descr, 0, sizeof(*descr) * no); | 311 | memset(descr, 0, sizeof(*descr) * no); |
312 | 312 | ||
313 | /* set up the hardware pointers in each descriptor */ | 313 | /* set up the hardware pointers in each descriptor */ |
314 | for (i=0; i<no; i++, descr++) { | 314 | for (i=0; i<no; i++, descr++) { |
315 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 315 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
316 | 316 | ||
317 | buf = pci_map_single(card->pdev, descr, | 317 | buf = pci_map_single(card->pdev, descr, |
318 | SPIDER_NET_DESCR_SIZE, | 318 | SPIDER_NET_DESCR_SIZE, |
319 | direction); | 319 | direction); |
320 | 320 | ||
321 | if (pci_dma_mapping_error(buf)) | 321 | if (pci_dma_mapping_error(buf)) |
322 | goto iommu_error; | 322 | goto iommu_error; |
323 | 323 | ||
324 | descr->bus_addr = buf; | 324 | descr->bus_addr = buf; |
325 | descr->next = descr + 1; | 325 | descr->next = descr + 1; |
326 | descr->prev = descr - 1; | 326 | descr->prev = descr - 1; |
327 | 327 | ||
328 | } | 328 | } |
329 | /* do actual circular list */ | 329 | /* do actual circular list */ |
330 | (descr-1)->next = start_descr; | 330 | (descr-1)->next = start_descr; |
331 | start_descr->prev = descr-1; | 331 | start_descr->prev = descr-1; |
332 | 332 | ||
333 | descr = start_descr; | 333 | descr = start_descr; |
334 | if (direction == PCI_DMA_FROMDEVICE) | 334 | if (direction == PCI_DMA_FROMDEVICE) |
335 | for (i=0; i < no; i++, descr++) | 335 | for (i=0; i < no; i++, descr++) |
336 | descr->next_descr_addr = descr->next->bus_addr; | 336 | descr->next_descr_addr = descr->next->bus_addr; |
337 | 337 | ||
338 | spin_lock_init(&chain->lock); | 338 | spin_lock_init(&chain->lock); |
339 | chain->head = start_descr; | 339 | chain->head = start_descr; |
340 | chain->tail = start_descr; | 340 | chain->tail = start_descr; |
341 | 341 | ||
342 | return 0; | 342 | return 0; |
343 | 343 | ||
344 | iommu_error: | 344 | iommu_error: |
345 | descr = start_descr; | 345 | descr = start_descr; |
346 | for (i=0; i < no; i++, descr++) | 346 | for (i=0; i < no; i++, descr++) |
347 | if (descr->bus_addr) | 347 | if (descr->bus_addr) |
348 | pci_unmap_single(card->pdev, descr->bus_addr, | 348 | pci_unmap_single(card->pdev, descr->bus_addr, |
349 | SPIDER_NET_DESCR_SIZE, | 349 | SPIDER_NET_DESCR_SIZE, |
350 | direction); | 350 | direction); |
351 | return -ENOMEM; | 351 | return -ENOMEM; |
352 | } | 352 | } |
353 | 353 | ||
354 | /** | 354 | /** |
355 | * spider_net_free_rx_chain_contents - frees descr contents in rx chain | 355 | * spider_net_free_rx_chain_contents - frees descr contents in rx chain |
356 | * @card: card structure | 356 | * @card: card structure |
357 | * | 357 | * |
358 | * returns 0 on success, <0 on failure | 358 | * returns 0 on success, <0 on failure |
359 | */ | 359 | */ |
360 | static void | 360 | static void |
361 | spider_net_free_rx_chain_contents(struct spider_net_card *card) | 361 | spider_net_free_rx_chain_contents(struct spider_net_card *card) |
362 | { | 362 | { |
363 | struct spider_net_descr *descr; | 363 | struct spider_net_descr *descr; |
364 | 364 | ||
365 | descr = card->rx_chain.head; | 365 | descr = card->rx_chain.head; |
366 | while (descr->next != card->rx_chain.head) { | 366 | while (descr->next != card->rx_chain.head) { |
367 | if (descr->skb) { | 367 | if (descr->skb) { |
368 | dev_kfree_skb(descr->skb); | 368 | dev_kfree_skb(descr->skb); |
369 | pci_unmap_single(card->pdev, descr->buf_addr, | 369 | pci_unmap_single(card->pdev, descr->buf_addr, |
370 | SPIDER_NET_MAX_FRAME, | 370 | SPIDER_NET_MAX_FRAME, |
371 | PCI_DMA_FROMDEVICE); | 371 | PCI_DMA_FROMDEVICE); |
372 | } | 372 | } |
373 | descr = descr->next; | 373 | descr = descr->next; |
374 | } | 374 | } |
375 | } | 375 | } |
376 | 376 | ||
377 | /** | 377 | /** |
378 | * spider_net_prepare_rx_descr - reinitializes a rx descriptor | 378 | * spider_net_prepare_rx_descr - reinitializes a rx descriptor |
379 | * @card: card structure | 379 | * @card: card structure |
380 | * @descr: descriptor to re-init | 380 | * @descr: descriptor to re-init |
381 | * | 381 | * |
382 | * return 0 on succes, <0 on failure | 382 | * return 0 on succes, <0 on failure |
383 | * | 383 | * |
384 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. | 384 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. |
385 | * Activate the descriptor state-wise | 385 | * Activate the descriptor state-wise |
386 | */ | 386 | */ |
387 | static int | 387 | static int |
388 | spider_net_prepare_rx_descr(struct spider_net_card *card, | 388 | spider_net_prepare_rx_descr(struct spider_net_card *card, |
389 | struct spider_net_descr *descr) | 389 | struct spider_net_descr *descr) |
390 | { | 390 | { |
391 | dma_addr_t buf; | 391 | dma_addr_t buf; |
392 | int error = 0; | 392 | int error = 0; |
393 | int offset; | 393 | int offset; |
394 | int bufsize; | 394 | int bufsize; |
395 | 395 | ||
396 | /* we need to round up the buffer size to a multiple of 128 */ | 396 | /* we need to round up the buffer size to a multiple of 128 */ |
397 | bufsize = (SPIDER_NET_MAX_FRAME + SPIDER_NET_RXBUF_ALIGN - 1) & | 397 | bufsize = (SPIDER_NET_MAX_FRAME + SPIDER_NET_RXBUF_ALIGN - 1) & |
398 | (~(SPIDER_NET_RXBUF_ALIGN - 1)); | 398 | (~(SPIDER_NET_RXBUF_ALIGN - 1)); |
399 | 399 | ||
400 | /* and we need to have it 128 byte aligned, therefore we allocate a | 400 | /* and we need to have it 128 byte aligned, therefore we allocate a |
401 | * bit more */ | 401 | * bit more */ |
402 | /* allocate an skb */ | 402 | /* allocate an skb */ |
403 | descr->skb = dev_alloc_skb(bufsize + SPIDER_NET_RXBUF_ALIGN - 1); | 403 | descr->skb = dev_alloc_skb(bufsize + SPIDER_NET_RXBUF_ALIGN - 1); |
404 | if (!descr->skb) { | 404 | if (!descr->skb) { |
405 | if (netif_msg_rx_err(card) && net_ratelimit()) | 405 | if (netif_msg_rx_err(card) && net_ratelimit()) |
406 | pr_err("Not enough memory to allocate rx buffer\n"); | 406 | pr_err("Not enough memory to allocate rx buffer\n"); |
407 | card->spider_stats.alloc_rx_skb_error++; | 407 | card->spider_stats.alloc_rx_skb_error++; |
408 | return -ENOMEM; | 408 | return -ENOMEM; |
409 | } | 409 | } |
410 | descr->buf_size = bufsize; | 410 | descr->buf_size = bufsize; |
411 | descr->result_size = 0; | 411 | descr->result_size = 0; |
412 | descr->valid_size = 0; | 412 | descr->valid_size = 0; |
413 | descr->data_status = 0; | 413 | descr->data_status = 0; |
414 | descr->data_error = 0; | 414 | descr->data_error = 0; |
415 | 415 | ||
416 | offset = ((unsigned long)descr->skb->data) & | 416 | offset = ((unsigned long)descr->skb->data) & |
417 | (SPIDER_NET_RXBUF_ALIGN - 1); | 417 | (SPIDER_NET_RXBUF_ALIGN - 1); |
418 | if (offset) | 418 | if (offset) |
419 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); | 419 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); |
420 | /* io-mmu-map the skb */ | 420 | /* io-mmu-map the skb */ |
421 | buf = pci_map_single(card->pdev, descr->skb->data, | 421 | buf = pci_map_single(card->pdev, descr->skb->data, |
422 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 422 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
423 | descr->buf_addr = buf; | 423 | descr->buf_addr = buf; |
424 | if (pci_dma_mapping_error(buf)) { | 424 | if (pci_dma_mapping_error(buf)) { |
425 | dev_kfree_skb_any(descr->skb); | 425 | dev_kfree_skb_any(descr->skb); |
426 | if (netif_msg_rx_err(card) && net_ratelimit()) | 426 | if (netif_msg_rx_err(card) && net_ratelimit()) |
427 | pr_err("Could not iommu-map rx buffer\n"); | 427 | pr_err("Could not iommu-map rx buffer\n"); |
428 | card->spider_stats.rx_iommu_map_error++; | 428 | card->spider_stats.rx_iommu_map_error++; |
429 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 429 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
430 | } else { | 430 | } else { |
431 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | | 431 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
432 | SPIDER_NET_DMAC_NOINTR_COMPLETE; | 432 | SPIDER_NET_DMAC_NOINTR_COMPLETE; |
433 | } | 433 | } |
434 | 434 | ||
435 | return error; | 435 | return error; |
436 | } | 436 | } |
437 | 437 | ||
438 | /** | 438 | /** |
439 | * spider_net_enable_rxchtails - sets RX dmac chain tail addresses | 439 | * spider_net_enable_rxchtails - sets RX dmac chain tail addresses |
440 | * @card: card structure | 440 | * @card: card structure |
441 | * | 441 | * |
442 | * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the | 442 | * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the |
443 | * chip by writing to the appropriate register. DMA is enabled in | 443 | * chip by writing to the appropriate register. DMA is enabled in |
444 | * spider_net_enable_rxdmac. | 444 | * spider_net_enable_rxdmac. |
445 | */ | 445 | */ |
446 | static inline void | 446 | static inline void |
447 | spider_net_enable_rxchtails(struct spider_net_card *card) | 447 | spider_net_enable_rxchtails(struct spider_net_card *card) |
448 | { | 448 | { |
449 | /* assume chain is aligned correctly */ | 449 | /* assume chain is aligned correctly */ |
450 | spider_net_write_reg(card, SPIDER_NET_GDADCHA , | 450 | spider_net_write_reg(card, SPIDER_NET_GDADCHA , |
451 | card->rx_chain.tail->bus_addr); | 451 | card->rx_chain.tail->bus_addr); |
452 | } | 452 | } |
453 | 453 | ||
454 | /** | 454 | /** |
455 | * spider_net_enable_rxdmac - enables a receive DMA controller | 455 | * spider_net_enable_rxdmac - enables a receive DMA controller |
456 | * @card: card structure | 456 | * @card: card structure |
457 | * | 457 | * |
458 | * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN | 458 | * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN |
459 | * in the GDADMACCNTR register | 459 | * in the GDADMACCNTR register |
460 | */ | 460 | */ |
461 | static inline void | 461 | static inline void |
462 | spider_net_enable_rxdmac(struct spider_net_card *card) | 462 | spider_net_enable_rxdmac(struct spider_net_card *card) |
463 | { | 463 | { |
464 | wmb(); | 464 | wmb(); |
465 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, | 465 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, |
466 | SPIDER_NET_DMA_RX_VALUE); | 466 | SPIDER_NET_DMA_RX_VALUE); |
467 | } | 467 | } |
468 | 468 | ||
469 | /** | 469 | /** |
470 | * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains | 470 | * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains |
471 | * @card: card structure | 471 | * @card: card structure |
472 | * | 472 | * |
473 | * refills descriptors in the rx chain: allocates skbs and iommu-maps them. | 473 | * refills descriptors in the rx chain: allocates skbs and iommu-maps them. |
474 | */ | 474 | */ |
475 | static void | 475 | static void |
476 | spider_net_refill_rx_chain(struct spider_net_card *card) | 476 | spider_net_refill_rx_chain(struct spider_net_card *card) |
477 | { | 477 | { |
478 | struct spider_net_descr_chain *chain = &card->rx_chain; | 478 | struct spider_net_descr_chain *chain = &card->rx_chain; |
479 | unsigned long flags; | 479 | unsigned long flags; |
480 | 480 | ||
481 | /* one context doing the refill (and a second context seeing that | 481 | /* one context doing the refill (and a second context seeing that |
482 | * and omitting it) is ok. If called by NAPI, we'll be called again | 482 | * and omitting it) is ok. If called by NAPI, we'll be called again |
483 | * as spider_net_decode_one_descr is called several times. If some | 483 | * as spider_net_decode_one_descr is called several times. If some |
484 | * interrupt calls us, the NAPI is about to clean up anyway. */ | 484 | * interrupt calls us, the NAPI is about to clean up anyway. */ |
485 | if (!spin_trylock_irqsave(&chain->lock, flags)) | 485 | if (!spin_trylock_irqsave(&chain->lock, flags)) |
486 | return; | 486 | return; |
487 | 487 | ||
488 | while (spider_net_get_descr_status(chain->head) == | 488 | while (spider_net_get_descr_status(chain->head) == |
489 | SPIDER_NET_DESCR_NOT_IN_USE) { | 489 | SPIDER_NET_DESCR_NOT_IN_USE) { |
490 | if (spider_net_prepare_rx_descr(card, chain->head)) | 490 | if (spider_net_prepare_rx_descr(card, chain->head)) |
491 | break; | 491 | break; |
492 | chain->head = chain->head->next; | 492 | chain->head = chain->head->next; |
493 | } | 493 | } |
494 | 494 | ||
495 | spin_unlock_irqrestore(&chain->lock, flags); | 495 | spin_unlock_irqrestore(&chain->lock, flags); |
496 | } | 496 | } |
497 | 497 | ||
498 | /** | 498 | /** |
499 | * spider_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains | 499 | * spider_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains |
500 | * @card: card structure | 500 | * @card: card structure |
501 | * | 501 | * |
502 | * returns 0 on success, <0 on failure | 502 | * returns 0 on success, <0 on failure |
503 | */ | 503 | */ |
504 | static int | 504 | static int |
505 | spider_net_alloc_rx_skbs(struct spider_net_card *card) | 505 | spider_net_alloc_rx_skbs(struct spider_net_card *card) |
506 | { | 506 | { |
507 | int result; | 507 | int result; |
508 | struct spider_net_descr_chain *chain; | 508 | struct spider_net_descr_chain *chain; |
509 | 509 | ||
510 | result = -ENOMEM; | 510 | result = -ENOMEM; |
511 | 511 | ||
512 | chain = &card->rx_chain; | 512 | chain = &card->rx_chain; |
513 | /* put at least one buffer into the chain. if this fails, | 513 | /* put at least one buffer into the chain. if this fails, |
514 | * we've got a problem. if not, spider_net_refill_rx_chain | 514 | * we've got a problem. if not, spider_net_refill_rx_chain |
515 | * will do the rest at the end of this function */ | 515 | * will do the rest at the end of this function */ |
516 | if (spider_net_prepare_rx_descr(card, chain->head)) | 516 | if (spider_net_prepare_rx_descr(card, chain->head)) |
517 | goto error; | 517 | goto error; |
518 | else | 518 | else |
519 | chain->head = chain->head->next; | 519 | chain->head = chain->head->next; |
520 | 520 | ||
521 | /* this will allocate the rest of the rx buffers; if not, it's | 521 | /* this will allocate the rest of the rx buffers; if not, it's |
522 | * business as usual later on */ | 522 | * business as usual later on */ |
523 | spider_net_refill_rx_chain(card); | 523 | spider_net_refill_rx_chain(card); |
524 | spider_net_enable_rxdmac(card); | 524 | spider_net_enable_rxdmac(card); |
525 | return 0; | 525 | return 0; |
526 | 526 | ||
527 | error: | 527 | error: |
528 | spider_net_free_rx_chain_contents(card); | 528 | spider_net_free_rx_chain_contents(card); |
529 | return result; | 529 | return result; |
530 | } | 530 | } |
531 | 531 | ||
532 | /** | 532 | /** |
533 | * spider_net_get_multicast_hash - generates hash for multicast filter table | 533 | * spider_net_get_multicast_hash - generates hash for multicast filter table |
534 | * @addr: multicast address | 534 | * @addr: multicast address |
535 | * | 535 | * |
536 | * returns the hash value. | 536 | * returns the hash value. |
537 | * | 537 | * |
538 | * spider_net_get_multicast_hash calculates a hash value for a given multicast | 538 | * spider_net_get_multicast_hash calculates a hash value for a given multicast |
539 | * address, that is used to set the multicast filter tables | 539 | * address, that is used to set the multicast filter tables |
540 | */ | 540 | */ |
541 | static u8 | 541 | static u8 |
542 | spider_net_get_multicast_hash(struct net_device *netdev, __u8 *addr) | 542 | spider_net_get_multicast_hash(struct net_device *netdev, __u8 *addr) |
543 | { | 543 | { |
544 | u32 crc; | 544 | u32 crc; |
545 | u8 hash; | 545 | u8 hash; |
546 | char addr_for_crc[ETH_ALEN] = { 0, }; | 546 | char addr_for_crc[ETH_ALEN] = { 0, }; |
547 | int i, bit; | 547 | int i, bit; |
548 | 548 | ||
549 | for (i = 0; i < ETH_ALEN * 8; i++) { | 549 | for (i = 0; i < ETH_ALEN * 8; i++) { |
550 | bit = (addr[i / 8] >> (i % 8)) & 1; | 550 | bit = (addr[i / 8] >> (i % 8)) & 1; |
551 | addr_for_crc[ETH_ALEN - 1 - i / 8] += bit << (7 - (i % 8)); | 551 | addr_for_crc[ETH_ALEN - 1 - i / 8] += bit << (7 - (i % 8)); |
552 | } | 552 | } |
553 | 553 | ||
554 | crc = crc32_be(~0, addr_for_crc, netdev->addr_len); | 554 | crc = crc32_be(~0, addr_for_crc, netdev->addr_len); |
555 | 555 | ||
556 | hash = (crc >> 27); | 556 | hash = (crc >> 27); |
557 | hash <<= 3; | 557 | hash <<= 3; |
558 | hash |= crc & 7; | 558 | hash |= crc & 7; |
559 | hash &= 0xff; | 559 | hash &= 0xff; |
560 | 560 | ||
561 | return hash; | 561 | return hash; |
562 | } | 562 | } |
563 | 563 | ||
564 | /** | 564 | /** |
565 | * spider_net_set_multi - sets multicast addresses and promisc flags | 565 | * spider_net_set_multi - sets multicast addresses and promisc flags |
566 | * @netdev: interface device structure | 566 | * @netdev: interface device structure |
567 | * | 567 | * |
568 | * spider_net_set_multi configures multicast addresses as needed for the | 568 | * spider_net_set_multi configures multicast addresses as needed for the |
569 | * netdev interface. It also sets up multicast, allmulti and promisc | 569 | * netdev interface. It also sets up multicast, allmulti and promisc |
570 | * flags appropriately | 570 | * flags appropriately |
571 | */ | 571 | */ |
572 | static void | 572 | static void |
573 | spider_net_set_multi(struct net_device *netdev) | 573 | spider_net_set_multi(struct net_device *netdev) |
574 | { | 574 | { |
575 | struct dev_mc_list *mc; | 575 | struct dev_mc_list *mc; |
576 | u8 hash; | 576 | u8 hash; |
577 | int i; | 577 | int i; |
578 | u32 reg; | 578 | u32 reg; |
579 | struct spider_net_card *card = netdev_priv(netdev); | 579 | struct spider_net_card *card = netdev_priv(netdev); |
580 | unsigned long bitmask[SPIDER_NET_MULTICAST_HASHES / BITS_PER_LONG] = | 580 | unsigned long bitmask[SPIDER_NET_MULTICAST_HASHES / BITS_PER_LONG] = |
581 | {0, }; | 581 | {0, }; |
582 | 582 | ||
583 | spider_net_set_promisc(card); | 583 | spider_net_set_promisc(card); |
584 | 584 | ||
585 | if (netdev->flags & IFF_ALLMULTI) { | 585 | if (netdev->flags & IFF_ALLMULTI) { |
586 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES; i++) { | 586 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES; i++) { |
587 | set_bit(i, bitmask); | 587 | set_bit(i, bitmask); |
588 | } | 588 | } |
589 | goto write_hash; | 589 | goto write_hash; |
590 | } | 590 | } |
591 | 591 | ||
592 | /* well, we know, what the broadcast hash value is: it's xfd | 592 | /* well, we know, what the broadcast hash value is: it's xfd |
593 | hash = spider_net_get_multicast_hash(netdev, netdev->broadcast); */ | 593 | hash = spider_net_get_multicast_hash(netdev, netdev->broadcast); */ |
594 | set_bit(0xfd, bitmask); | 594 | set_bit(0xfd, bitmask); |
595 | 595 | ||
596 | for (mc = netdev->mc_list; mc; mc = mc->next) { | 596 | for (mc = netdev->mc_list; mc; mc = mc->next) { |
597 | hash = spider_net_get_multicast_hash(netdev, mc->dmi_addr); | 597 | hash = spider_net_get_multicast_hash(netdev, mc->dmi_addr); |
598 | set_bit(hash, bitmask); | 598 | set_bit(hash, bitmask); |
599 | } | 599 | } |
600 | 600 | ||
601 | write_hash: | 601 | write_hash: |
602 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES / 4; i++) { | 602 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES / 4; i++) { |
603 | reg = 0; | 603 | reg = 0; |
604 | if (test_bit(i * 4, bitmask)) | 604 | if (test_bit(i * 4, bitmask)) |
605 | reg += 0x08; | 605 | reg += 0x08; |
606 | reg <<= 8; | 606 | reg <<= 8; |
607 | if (test_bit(i * 4 + 1, bitmask)) | 607 | if (test_bit(i * 4 + 1, bitmask)) |
608 | reg += 0x08; | 608 | reg += 0x08; |
609 | reg <<= 8; | 609 | reg <<= 8; |
610 | if (test_bit(i * 4 + 2, bitmask)) | 610 | if (test_bit(i * 4 + 2, bitmask)) |
611 | reg += 0x08; | 611 | reg += 0x08; |
612 | reg <<= 8; | 612 | reg <<= 8; |
613 | if (test_bit(i * 4 + 3, bitmask)) | 613 | if (test_bit(i * 4 + 3, bitmask)) |
614 | reg += 0x08; | 614 | reg += 0x08; |
615 | 615 | ||
616 | spider_net_write_reg(card, SPIDER_NET_GMRMHFILnR + i * 4, reg); | 616 | spider_net_write_reg(card, SPIDER_NET_GMRMHFILnR + i * 4, reg); |
617 | } | 617 | } |
618 | } | 618 | } |
619 | 619 | ||
620 | /** | 620 | /** |
621 | * spider_net_disable_rxdmac - disables the receive DMA controller | 621 | * spider_net_disable_rxdmac - disables the receive DMA controller |
622 | * @card: card structure | 622 | * @card: card structure |
623 | * | 623 | * |
624 | * spider_net_disable_rxdmac terminates processing on the DMA controller by | 624 | * spider_net_disable_rxdmac terminates processing on the DMA controller by |
625 | * turing off DMA and issueing a force end | 625 | * turing off DMA and issueing a force end |
626 | */ | 626 | */ |
627 | static void | 627 | static void |
628 | spider_net_disable_rxdmac(struct spider_net_card *card) | 628 | spider_net_disable_rxdmac(struct spider_net_card *card) |
629 | { | 629 | { |
630 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, | 630 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, |
631 | SPIDER_NET_DMA_RX_FEND_VALUE); | 631 | SPIDER_NET_DMA_RX_FEND_VALUE); |
632 | } | 632 | } |
633 | 633 | ||
634 | /** | 634 | /** |
635 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data | 635 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data |
636 | * @card: card structure | 636 | * @card: card structure |
637 | * @descr: descriptor structure to fill out | 637 | * @descr: descriptor structure to fill out |
638 | * @skb: packet to use | 638 | * @skb: packet to use |
639 | * | 639 | * |
640 | * returns 0 on success, <0 on failure. | 640 | * returns 0 on success, <0 on failure. |
641 | * | 641 | * |
642 | * fills out the descriptor structure with skb data and len. Copies data, | 642 | * fills out the descriptor structure with skb data and len. Copies data, |
643 | * if needed (32bit DMA!) | 643 | * if needed (32bit DMA!) |
644 | */ | 644 | */ |
645 | static int | 645 | static int |
646 | spider_net_prepare_tx_descr(struct spider_net_card *card, | 646 | spider_net_prepare_tx_descr(struct spider_net_card *card, |
647 | struct sk_buff *skb) | 647 | struct sk_buff *skb) |
648 | { | 648 | { |
649 | struct spider_net_descr *descr; | 649 | struct spider_net_descr *descr; |
650 | dma_addr_t buf; | 650 | dma_addr_t buf; |
651 | unsigned long flags; | 651 | unsigned long flags; |
652 | int length; | 652 | int length; |
653 | 653 | ||
654 | length = skb->len; | 654 | length = skb->len; |
655 | if (length < ETH_ZLEN) { | 655 | if (length < ETH_ZLEN) { |
656 | if (skb_pad(skb, ETH_ZLEN-length)) | 656 | if (skb_pad(skb, ETH_ZLEN-length)) |
657 | return 0; | 657 | return 0; |
658 | length = ETH_ZLEN; | 658 | length = ETH_ZLEN; |
659 | } | 659 | } |
660 | 660 | ||
661 | buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE); | 661 | buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE); |
662 | if (pci_dma_mapping_error(buf)) { | 662 | if (pci_dma_mapping_error(buf)) { |
663 | if (netif_msg_tx_err(card) && net_ratelimit()) | 663 | if (netif_msg_tx_err(card) && net_ratelimit()) |
664 | pr_err("could not iommu-map packet (%p, %i). " | 664 | pr_err("could not iommu-map packet (%p, %i). " |
665 | "Dropping packet\n", skb->data, length); | 665 | "Dropping packet\n", skb->data, length); |
666 | card->spider_stats.tx_iommu_map_error++; | 666 | card->spider_stats.tx_iommu_map_error++; |
667 | return -ENOMEM; | 667 | return -ENOMEM; |
668 | } | 668 | } |
669 | 669 | ||
670 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 670 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
671 | descr = card->tx_chain.head; | 671 | descr = card->tx_chain.head; |
672 | card->tx_chain.head = descr->next; | 672 | card->tx_chain.head = descr->next; |
673 | 673 | ||
674 | descr->buf_addr = buf; | 674 | descr->buf_addr = buf; |
675 | descr->buf_size = length; | 675 | descr->buf_size = length; |
676 | descr->next_descr_addr = 0; | 676 | descr->next_descr_addr = 0; |
677 | descr->skb = skb; | 677 | descr->skb = skb; |
678 | descr->data_status = 0; | 678 | descr->data_status = 0; |
679 | 679 | ||
680 | descr->dmac_cmd_status = | 680 | descr->dmac_cmd_status = |
681 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | 681 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; |
682 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 682 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); |
683 | 683 | ||
684 | if (skb->protocol == htons(ETH_P_IP)) | 684 | if (skb->protocol == htons(ETH_P_IP)) |
685 | switch (skb->nh.iph->protocol) { | 685 | switch (skb->nh.iph->protocol) { |
686 | case IPPROTO_TCP: | 686 | case IPPROTO_TCP: |
687 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; | 687 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; |
688 | break; | 688 | break; |
689 | case IPPROTO_UDP: | 689 | case IPPROTO_UDP: |
690 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; | 690 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; |
691 | break; | 691 | break; |
692 | } | 692 | } |
693 | 693 | ||
694 | /* Chain the bus address, so that the DMA engine finds this descr. */ | 694 | /* Chain the bus address, so that the DMA engine finds this descr. */ |
695 | descr->prev->next_descr_addr = descr->bus_addr; | 695 | descr->prev->next_descr_addr = descr->bus_addr; |
696 | 696 | ||
697 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ | 697 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ |
698 | return 0; | 698 | return 0; |
699 | } | 699 | } |
700 | 700 | ||
701 | static int | 701 | static int |
702 | spider_net_set_low_watermark(struct spider_net_card *card) | 702 | spider_net_set_low_watermark(struct spider_net_card *card) |
703 | { | 703 | { |
704 | unsigned long flags; | 704 | unsigned long flags; |
705 | int status; | 705 | int status; |
706 | int cnt=0; | 706 | int cnt=0; |
707 | int i; | 707 | int i; |
708 | struct spider_net_descr *descr = card->tx_chain.tail; | 708 | struct spider_net_descr *descr = card->tx_chain.tail; |
709 | 709 | ||
710 | /* Measure the length of the queue. Measurement does not | 710 | /* Measure the length of the queue. Measurement does not |
711 | * need to be precise -- does not need a lock. */ | 711 | * need to be precise -- does not need a lock. */ |
712 | while (descr != card->tx_chain.head) { | 712 | while (descr != card->tx_chain.head) { |
713 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; | 713 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; |
714 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) | 714 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) |
715 | break; | 715 | break; |
716 | descr = descr->next; | 716 | descr = descr->next; |
717 | cnt++; | 717 | cnt++; |
718 | } | 718 | } |
719 | 719 | ||
720 | /* If TX queue is short, don't even bother with interrupts */ | 720 | /* If TX queue is short, don't even bother with interrupts */ |
721 | if (cnt < card->tx_desc/4) | 721 | if (cnt < card->num_tx_desc/4) |
722 | return cnt; | 722 | return cnt; |
723 | 723 | ||
724 | /* Set low-watermark 3/4th's of the way into the queue. */ | 724 | /* Set low-watermark 3/4th's of the way into the queue. */ |
725 | descr = card->tx_chain.tail; | 725 | descr = card->tx_chain.tail; |
726 | cnt = (cnt*3)/4; | 726 | cnt = (cnt*3)/4; |
727 | for (i=0;i<cnt; i++) | 727 | for (i=0;i<cnt; i++) |
728 | descr = descr->next; | 728 | descr = descr->next; |
729 | 729 | ||
730 | /* Set the new watermark, clear the old watermark */ | 730 | /* Set the new watermark, clear the old watermark */ |
731 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 731 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
732 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; | 732 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; |
733 | if (card->low_watermark && card->low_watermark != descr) | 733 | if (card->low_watermark && card->low_watermark != descr) |
734 | card->low_watermark->dmac_cmd_status = | 734 | card->low_watermark->dmac_cmd_status = |
735 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | 735 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; |
736 | card->low_watermark = descr; | 736 | card->low_watermark = descr; |
737 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 737 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); |
738 | return cnt; | 738 | return cnt; |
739 | } | 739 | } |
740 | 740 | ||
741 | /** | 741 | /** |
742 | * spider_net_release_tx_chain - processes sent tx descriptors | 742 | * spider_net_release_tx_chain - processes sent tx descriptors |
743 | * @card: adapter structure | 743 | * @card: adapter structure |
744 | * @brutal: if set, don't care about whether descriptor seems to be in use | 744 | * @brutal: if set, don't care about whether descriptor seems to be in use |
745 | * | 745 | * |
746 | * returns 0 if the tx ring is empty, otherwise 1. | 746 | * returns 0 if the tx ring is empty, otherwise 1. |
747 | * | 747 | * |
748 | * spider_net_release_tx_chain releases the tx descriptors that spider has | 748 | * spider_net_release_tx_chain releases the tx descriptors that spider has |
749 | * finished with (if non-brutal) or simply release tx descriptors (if brutal). | 749 | * finished with (if non-brutal) or simply release tx descriptors (if brutal). |
750 | * If some other context is calling this function, we return 1 so that we're | 750 | * If some other context is calling this function, we return 1 so that we're |
751 | * scheduled again (if we were scheduled) and will not loose initiative. | 751 | * scheduled again (if we were scheduled) and will not loose initiative. |
752 | */ | 752 | */ |
753 | static int | 753 | static int |
754 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | 754 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) |
755 | { | 755 | { |
756 | struct spider_net_descr_chain *chain = &card->tx_chain; | 756 | struct spider_net_descr_chain *chain = &card->tx_chain; |
757 | struct spider_net_descr *descr; | 757 | struct spider_net_descr *descr; |
758 | struct sk_buff *skb; | 758 | struct sk_buff *skb; |
759 | u32 buf_addr; | 759 | u32 buf_addr; |
760 | unsigned long flags; | 760 | unsigned long flags; |
761 | int status; | 761 | int status; |
762 | 762 | ||
763 | while (chain->tail != chain->head) { | 763 | while (chain->tail != chain->head) { |
764 | spin_lock_irqsave(&chain->lock, flags); | 764 | spin_lock_irqsave(&chain->lock, flags); |
765 | descr = chain->tail; | 765 | descr = chain->tail; |
766 | 766 | ||
767 | status = spider_net_get_descr_status(descr); | 767 | status = spider_net_get_descr_status(descr); |
768 | switch (status) { | 768 | switch (status) { |
769 | case SPIDER_NET_DESCR_COMPLETE: | 769 | case SPIDER_NET_DESCR_COMPLETE: |
770 | card->netdev_stats.tx_packets++; | 770 | card->netdev_stats.tx_packets++; |
771 | card->netdev_stats.tx_bytes += descr->skb->len; | 771 | card->netdev_stats.tx_bytes += descr->skb->len; |
772 | break; | 772 | break; |
773 | 773 | ||
774 | case SPIDER_NET_DESCR_CARDOWNED: | 774 | case SPIDER_NET_DESCR_CARDOWNED: |
775 | if (!brutal) { | 775 | if (!brutal) { |
776 | spin_unlock_irqrestore(&chain->lock, flags); | 776 | spin_unlock_irqrestore(&chain->lock, flags); |
777 | return 1; | 777 | return 1; |
778 | } | 778 | } |
779 | 779 | ||
780 | /* fallthrough, if we release the descriptors | 780 | /* fallthrough, if we release the descriptors |
781 | * brutally (then we don't care about | 781 | * brutally (then we don't care about |
782 | * SPIDER_NET_DESCR_CARDOWNED) */ | 782 | * SPIDER_NET_DESCR_CARDOWNED) */ |
783 | 783 | ||
784 | case SPIDER_NET_DESCR_RESPONSE_ERROR: | 784 | case SPIDER_NET_DESCR_RESPONSE_ERROR: |
785 | case SPIDER_NET_DESCR_PROTECTION_ERROR: | 785 | case SPIDER_NET_DESCR_PROTECTION_ERROR: |
786 | case SPIDER_NET_DESCR_FORCE_END: | 786 | case SPIDER_NET_DESCR_FORCE_END: |
787 | if (netif_msg_tx_err(card)) | 787 | if (netif_msg_tx_err(card)) |
788 | pr_err("%s: forcing end of tx descriptor " | 788 | pr_err("%s: forcing end of tx descriptor " |
789 | "with status x%02x\n", | 789 | "with status x%02x\n", |
790 | card->netdev->name, status); | 790 | card->netdev->name, status); |
791 | card->netdev_stats.tx_errors++; | 791 | card->netdev_stats.tx_errors++; |
792 | break; | 792 | break; |
793 | 793 | ||
794 | default: | 794 | default: |
795 | card->netdev_stats.tx_dropped++; | 795 | card->netdev_stats.tx_dropped++; |
796 | if (!brutal) { | 796 | if (!brutal) { |
797 | spin_unlock_irqrestore(&chain->lock, flags); | 797 | spin_unlock_irqrestore(&chain->lock, flags); |
798 | return 1; | 798 | return 1; |
799 | } | 799 | } |
800 | } | 800 | } |
801 | 801 | ||
802 | chain->tail = descr->next; | 802 | chain->tail = descr->next; |
803 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | 803 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; |
804 | skb = descr->skb; | 804 | skb = descr->skb; |
805 | buf_addr = descr->buf_addr; | 805 | buf_addr = descr->buf_addr; |
806 | spin_unlock_irqrestore(&chain->lock, flags); | 806 | spin_unlock_irqrestore(&chain->lock, flags); |
807 | 807 | ||
808 | /* unmap the skb */ | 808 | /* unmap the skb */ |
809 | if (skb) { | 809 | if (skb) { |
810 | int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; | 810 | int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; |
811 | pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE); | 811 | pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE); |
812 | dev_kfree_skb(skb); | 812 | dev_kfree_skb(skb); |
813 | } | 813 | } |
814 | } | 814 | } |
815 | return 0; | 815 | return 0; |
816 | } | 816 | } |
817 | 817 | ||
818 | /** | 818 | /** |
819 | * spider_net_kick_tx_dma - enables TX DMA processing | 819 | * spider_net_kick_tx_dma - enables TX DMA processing |
820 | * @card: card structure | 820 | * @card: card structure |
821 | * @descr: descriptor address to enable TX processing at | 821 | * @descr: descriptor address to enable TX processing at |
822 | * | 822 | * |
823 | * This routine will start the transmit DMA running if | 823 | * This routine will start the transmit DMA running if |
824 | * it is not already running. This routine ned only be | 824 | * it is not already running. This routine ned only be |
825 | * called when queueing a new packet to an empty tx queue. | 825 | * called when queueing a new packet to an empty tx queue. |
826 | * Writes the current tx chain head as start address | 826 | * Writes the current tx chain head as start address |
827 | * of the tx descriptor chain and enables the transmission | 827 | * of the tx descriptor chain and enables the transmission |
828 | * DMA engine. | 828 | * DMA engine. |
829 | */ | 829 | */ |
830 | static inline void | 830 | static inline void |
831 | spider_net_kick_tx_dma(struct spider_net_card *card) | 831 | spider_net_kick_tx_dma(struct spider_net_card *card) |
832 | { | 832 | { |
833 | struct spider_net_descr *descr; | 833 | struct spider_net_descr *descr; |
834 | 834 | ||
835 | if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) & | 835 | if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) & |
836 | SPIDER_NET_TX_DMA_EN) | 836 | SPIDER_NET_TX_DMA_EN) |
837 | goto out; | 837 | goto out; |
838 | 838 | ||
839 | descr = card->tx_chain.tail; | 839 | descr = card->tx_chain.tail; |
840 | for (;;) { | 840 | for (;;) { |
841 | if (spider_net_get_descr_status(descr) == | 841 | if (spider_net_get_descr_status(descr) == |
842 | SPIDER_NET_DESCR_CARDOWNED) { | 842 | SPIDER_NET_DESCR_CARDOWNED) { |
843 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | 843 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, |
844 | descr->bus_addr); | 844 | descr->bus_addr); |
845 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 845 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
846 | SPIDER_NET_DMA_TX_VALUE); | 846 | SPIDER_NET_DMA_TX_VALUE); |
847 | break; | 847 | break; |
848 | } | 848 | } |
849 | if (descr == card->tx_chain.head) | 849 | if (descr == card->tx_chain.head) |
850 | break; | 850 | break; |
851 | descr = descr->next; | 851 | descr = descr->next; |
852 | } | 852 | } |
853 | 853 | ||
854 | out: | 854 | out: |
855 | mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); | 855 | mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); |
856 | } | 856 | } |
857 | 857 | ||
858 | /** | 858 | /** |
859 | * spider_net_xmit - transmits a frame over the device | 859 | * spider_net_xmit - transmits a frame over the device |
860 | * @skb: packet to send out | 860 | * @skb: packet to send out |
861 | * @netdev: interface device structure | 861 | * @netdev: interface device structure |
862 | * | 862 | * |
863 | * returns 0 on success, !0 on failure | 863 | * returns 0 on success, !0 on failure |
864 | */ | 864 | */ |
865 | static int | 865 | static int |
866 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | 866 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) |
867 | { | 867 | { |
868 | int cnt; | 868 | int cnt; |
869 | struct spider_net_card *card = netdev_priv(netdev); | 869 | struct spider_net_card *card = netdev_priv(netdev); |
870 | struct spider_net_descr_chain *chain = &card->tx_chain; | 870 | struct spider_net_descr_chain *chain = &card->tx_chain; |
871 | 871 | ||
872 | spider_net_release_tx_chain(card, 0); | 872 | spider_net_release_tx_chain(card, 0); |
873 | 873 | ||
874 | if ((chain->head->next == chain->tail->prev) || | 874 | if ((chain->head->next == chain->tail->prev) || |
875 | (spider_net_prepare_tx_descr(card, skb) != 0)) { | 875 | (spider_net_prepare_tx_descr(card, skb) != 0)) { |
876 | 876 | ||
877 | card->netdev_stats.tx_dropped++; | 877 | card->netdev_stats.tx_dropped++; |
878 | netif_stop_queue(netdev); | 878 | netif_stop_queue(netdev); |
879 | return NETDEV_TX_BUSY; | 879 | return NETDEV_TX_BUSY; |
880 | } | 880 | } |
881 | 881 | ||
882 | cnt = spider_net_set_low_watermark(card); | 882 | cnt = spider_net_set_low_watermark(card); |
883 | if (cnt < 5) | 883 | if (cnt < 5) |
884 | spider_net_kick_tx_dma(card); | 884 | spider_net_kick_tx_dma(card); |
885 | return NETDEV_TX_OK; | 885 | return NETDEV_TX_OK; |
886 | } | 886 | } |
887 | 887 | ||
888 | /** | 888 | /** |
889 | * spider_net_cleanup_tx_ring - cleans up the TX ring | 889 | * spider_net_cleanup_tx_ring - cleans up the TX ring |
890 | * @card: card structure | 890 | * @card: card structure |
891 | * | 891 | * |
892 | * spider_net_cleanup_tx_ring is called by either the tx_timer | 892 | * spider_net_cleanup_tx_ring is called by either the tx_timer |
893 | * or from the NAPI polling routine. | 893 | * or from the NAPI polling routine. |
894 | * This routine releases resources associted with transmitted | 894 | * This routine releases resources associted with transmitted |
895 | * packets, including updating the queue tail pointer. | 895 | * packets, including updating the queue tail pointer. |
896 | */ | 896 | */ |
897 | static void | 897 | static void |
898 | spider_net_cleanup_tx_ring(struct spider_net_card *card) | 898 | spider_net_cleanup_tx_ring(struct spider_net_card *card) |
899 | { | 899 | { |
900 | if ((spider_net_release_tx_chain(card, 0) != 0) && | 900 | if ((spider_net_release_tx_chain(card, 0) != 0) && |
901 | (card->netdev->flags & IFF_UP)) { | 901 | (card->netdev->flags & IFF_UP)) { |
902 | spider_net_kick_tx_dma(card); | 902 | spider_net_kick_tx_dma(card); |
903 | netif_wake_queue(card->netdev); | 903 | netif_wake_queue(card->netdev); |
904 | } | 904 | } |
905 | } | 905 | } |
906 | 906 | ||
907 | /** | 907 | /** |
908 | * spider_net_do_ioctl - called for device ioctls | 908 | * spider_net_do_ioctl - called for device ioctls |
909 | * @netdev: interface device structure | 909 | * @netdev: interface device structure |
910 | * @ifr: request parameter structure for ioctl | 910 | * @ifr: request parameter structure for ioctl |
911 | * @cmd: command code for ioctl | 911 | * @cmd: command code for ioctl |
912 | * | 912 | * |
913 | * returns 0 on success, <0 on failure. Currently, we have no special ioctls. | 913 | * returns 0 on success, <0 on failure. Currently, we have no special ioctls. |
914 | * -EOPNOTSUPP is returned, if an unknown ioctl was requested | 914 | * -EOPNOTSUPP is returned, if an unknown ioctl was requested |
915 | */ | 915 | */ |
916 | static int | 916 | static int |
917 | spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | 917 | spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) |
918 | { | 918 | { |
919 | switch (cmd) { | 919 | switch (cmd) { |
920 | default: | 920 | default: |
921 | return -EOPNOTSUPP; | 921 | return -EOPNOTSUPP; |
922 | } | 922 | } |
923 | } | 923 | } |
924 | 924 | ||
925 | /** | 925 | /** |
926 | * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on | 926 | * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on |
927 | * @descr: descriptor to process | 927 | * @descr: descriptor to process |
928 | * @card: card structure | 928 | * @card: card structure |
929 | * @napi: whether caller is in NAPI context | 929 | * @napi: whether caller is in NAPI context |
930 | * | 930 | * |
931 | * returns 1 on success, 0 if no packet was passed to the stack | 931 | * returns 1 on success, 0 if no packet was passed to the stack |
932 | * | 932 | * |
933 | * iommu-unmaps the skb, fills out skb structure and passes the data to the | 933 | * iommu-unmaps the skb, fills out skb structure and passes the data to the |
934 | * stack. The descriptor state is not changed. | 934 | * stack. The descriptor state is not changed. |
935 | */ | 935 | */ |
936 | static int | 936 | static int |
937 | spider_net_pass_skb_up(struct spider_net_descr *descr, | 937 | spider_net_pass_skb_up(struct spider_net_descr *descr, |
938 | struct spider_net_card *card, int napi) | 938 | struct spider_net_card *card, int napi) |
939 | { | 939 | { |
940 | struct sk_buff *skb; | 940 | struct sk_buff *skb; |
941 | struct net_device *netdev; | 941 | struct net_device *netdev; |
942 | u32 data_status, data_error; | 942 | u32 data_status, data_error; |
943 | 943 | ||
944 | data_status = descr->data_status; | 944 | data_status = descr->data_status; |
945 | data_error = descr->data_error; | 945 | data_error = descr->data_error; |
946 | 946 | ||
947 | netdev = card->netdev; | 947 | netdev = card->netdev; |
948 | 948 | ||
949 | /* unmap descriptor */ | 949 | /* unmap descriptor */ |
950 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, | 950 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, |
951 | PCI_DMA_FROMDEVICE); | 951 | PCI_DMA_FROMDEVICE); |
952 | 952 | ||
953 | /* the cases we'll throw away the packet immediately */ | 953 | /* the cases we'll throw away the packet immediately */ |
954 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { | 954 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { |
955 | if (netif_msg_rx_err(card)) | 955 | if (netif_msg_rx_err(card)) |
956 | pr_err("error in received descriptor found, " | 956 | pr_err("error in received descriptor found, " |
957 | "data_status=x%08x, data_error=x%08x\n", | 957 | "data_status=x%08x, data_error=x%08x\n", |
958 | data_status, data_error); | 958 | data_status, data_error); |
959 | card->spider_stats.rx_desc_error++; | 959 | card->spider_stats.rx_desc_error++; |
960 | return 0; | 960 | return 0; |
961 | } | 961 | } |
962 | 962 | ||
963 | skb = descr->skb; | 963 | skb = descr->skb; |
964 | skb->dev = netdev; | 964 | skb->dev = netdev; |
965 | skb_put(skb, descr->valid_size); | 965 | skb_put(skb, descr->valid_size); |
966 | 966 | ||
967 | /* the card seems to add 2 bytes of junk in front | 967 | /* the card seems to add 2 bytes of junk in front |
968 | * of the ethernet frame */ | 968 | * of the ethernet frame */ |
969 | #define SPIDER_MISALIGN 2 | 969 | #define SPIDER_MISALIGN 2 |
970 | skb_pull(skb, SPIDER_MISALIGN); | 970 | skb_pull(skb, SPIDER_MISALIGN); |
971 | skb->protocol = eth_type_trans(skb, netdev); | 971 | skb->protocol = eth_type_trans(skb, netdev); |
972 | 972 | ||
973 | /* checksum offload */ | 973 | /* checksum offload */ |
974 | if (card->options.rx_csum) { | 974 | if (card->options.rx_csum) { |
975 | if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) == | 975 | if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) == |
976 | SPIDER_NET_DATA_STATUS_CKSUM_MASK) && | 976 | SPIDER_NET_DATA_STATUS_CKSUM_MASK) && |
977 | !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) | 977 | !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) |
978 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 978 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
979 | else | 979 | else |
980 | skb->ip_summed = CHECKSUM_NONE; | 980 | skb->ip_summed = CHECKSUM_NONE; |
981 | } else | 981 | } else |
982 | skb->ip_summed = CHECKSUM_NONE; | 982 | skb->ip_summed = CHECKSUM_NONE; |
983 | 983 | ||
984 | if (data_status & SPIDER_NET_VLAN_PACKET) { | 984 | if (data_status & SPIDER_NET_VLAN_PACKET) { |
985 | /* further enhancements: HW-accel VLAN | 985 | /* further enhancements: HW-accel VLAN |
986 | * vlan_hwaccel_receive_skb | 986 | * vlan_hwaccel_receive_skb |
987 | */ | 987 | */ |
988 | } | 988 | } |
989 | 989 | ||
990 | /* pass skb up to stack */ | 990 | /* pass skb up to stack */ |
991 | if (napi) | 991 | if (napi) |
992 | netif_receive_skb(skb); | 992 | netif_receive_skb(skb); |
993 | else | 993 | else |
994 | netif_rx_ni(skb); | 994 | netif_rx_ni(skb); |
995 | 995 | ||
996 | /* update netdevice statistics */ | 996 | /* update netdevice statistics */ |
997 | card->netdev_stats.rx_packets++; | 997 | card->netdev_stats.rx_packets++; |
998 | card->netdev_stats.rx_bytes += skb->len; | 998 | card->netdev_stats.rx_bytes += skb->len; |
999 | 999 | ||
1000 | return 1; | 1000 | return 1; |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | /** | 1003 | /** |
1004 | * spider_net_decode_one_descr - processes an rx descriptor | 1004 | * spider_net_decode_one_descr - processes an rx descriptor |
1005 | * @card: card structure | 1005 | * @card: card structure |
1006 | * @napi: whether caller is in NAPI context | 1006 | * @napi: whether caller is in NAPI context |
1007 | * | 1007 | * |
1008 | * returns 1 if a packet has been sent to the stack, otherwise 0 | 1008 | * returns 1 if a packet has been sent to the stack, otherwise 0 |
1009 | * | 1009 | * |
1010 | * processes an rx descriptor by iommu-unmapping the data buffer and passing | 1010 | * processes an rx descriptor by iommu-unmapping the data buffer and passing |
1011 | * the packet up to the stack. This function is called in softirq | 1011 | * the packet up to the stack. This function is called in softirq |
1012 | * context, e.g. either bottom half from interrupt or NAPI polling context | 1012 | * context, e.g. either bottom half from interrupt or NAPI polling context |
1013 | */ | 1013 | */ |
1014 | static int | 1014 | static int |
1015 | spider_net_decode_one_descr(struct spider_net_card *card, int napi) | 1015 | spider_net_decode_one_descr(struct spider_net_card *card, int napi) |
1016 | { | 1016 | { |
1017 | struct spider_net_descr_chain *chain = &card->rx_chain; | 1017 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1018 | struct spider_net_descr *descr = chain->tail; | 1018 | struct spider_net_descr *descr = chain->tail; |
1019 | int status; | 1019 | int status; |
1020 | int result; | 1020 | int result; |
1021 | 1021 | ||
1022 | status = spider_net_get_descr_status(descr); | 1022 | status = spider_net_get_descr_status(descr); |
1023 | 1023 | ||
1024 | if (status == SPIDER_NET_DESCR_CARDOWNED) { | 1024 | if (status == SPIDER_NET_DESCR_CARDOWNED) { |
1025 | /* nothing in the descriptor yet */ | 1025 | /* nothing in the descriptor yet */ |
1026 | result=0; | 1026 | result=0; |
1027 | goto out; | 1027 | goto out; |
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) { | 1030 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) { |
1031 | /* not initialized yet, the ring must be empty */ | 1031 | /* not initialized yet, the ring must be empty */ |
1032 | spider_net_refill_rx_chain(card); | 1032 | spider_net_refill_rx_chain(card); |
1033 | spider_net_enable_rxdmac(card); | 1033 | spider_net_enable_rxdmac(card); |
1034 | result=0; | 1034 | result=0; |
1035 | goto out; | 1035 | goto out; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | /* descriptor definitively used -- move on tail */ | 1038 | /* descriptor definitively used -- move on tail */ |
1039 | chain->tail = descr->next; | 1039 | chain->tail = descr->next; |
1040 | 1040 | ||
1041 | result = 0; | 1041 | result = 0; |
1042 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || | 1042 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || |
1043 | (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || | 1043 | (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || |
1044 | (status == SPIDER_NET_DESCR_FORCE_END) ) { | 1044 | (status == SPIDER_NET_DESCR_FORCE_END) ) { |
1045 | if (netif_msg_rx_err(card)) | 1045 | if (netif_msg_rx_err(card)) |
1046 | pr_err("%s: dropping RX descriptor with state %d\n", | 1046 | pr_err("%s: dropping RX descriptor with state %d\n", |
1047 | card->netdev->name, status); | 1047 | card->netdev->name, status); |
1048 | card->netdev_stats.rx_dropped++; | 1048 | card->netdev_stats.rx_dropped++; |
1049 | pci_unmap_single(card->pdev, descr->buf_addr, | 1049 | pci_unmap_single(card->pdev, descr->buf_addr, |
1050 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 1050 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
1051 | dev_kfree_skb_irq(descr->skb); | 1051 | dev_kfree_skb_irq(descr->skb); |
1052 | goto refill; | 1052 | goto refill; |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && | 1055 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && |
1056 | (status != SPIDER_NET_DESCR_FRAME_END) ) { | 1056 | (status != SPIDER_NET_DESCR_FRAME_END) ) { |
1057 | if (netif_msg_rx_err(card)) { | 1057 | if (netif_msg_rx_err(card)) { |
1058 | pr_err("%s: RX descriptor with state %d\n", | 1058 | pr_err("%s: RX descriptor with state %d\n", |
1059 | card->netdev->name, status); | 1059 | card->netdev->name, status); |
1060 | card->spider_stats.rx_desc_unk_state++; | 1060 | card->spider_stats.rx_desc_unk_state++; |
1061 | } | 1061 | } |
1062 | goto refill; | 1062 | goto refill; |
1063 | } | 1063 | } |
1064 | 1064 | ||
1065 | /* ok, we've got a packet in descr */ | 1065 | /* ok, we've got a packet in descr */ |
1066 | result = spider_net_pass_skb_up(descr, card, napi); | 1066 | result = spider_net_pass_skb_up(descr, card, napi); |
1067 | refill: | 1067 | refill: |
1068 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1068 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1069 | /* change the descriptor state: */ | 1069 | /* change the descriptor state: */ |
1070 | if (!napi) | 1070 | if (!napi) |
1071 | spider_net_refill_rx_chain(card); | 1071 | spider_net_refill_rx_chain(card); |
1072 | out: | 1072 | out: |
1073 | return result; | 1073 | return result; |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | /** | 1076 | /** |
1077 | * spider_net_poll - NAPI poll function called by the stack to return packets | 1077 | * spider_net_poll - NAPI poll function called by the stack to return packets |
1078 | * @netdev: interface device structure | 1078 | * @netdev: interface device structure |
1079 | * @budget: number of packets we can pass to the stack at most | 1079 | * @budget: number of packets we can pass to the stack at most |
1080 | * | 1080 | * |
1081 | * returns 0 if no more packets available to the driver/stack. Returns 1, | 1081 | * returns 0 if no more packets available to the driver/stack. Returns 1, |
1082 | * if the quota is exceeded, but the driver has still packets. | 1082 | * if the quota is exceeded, but the driver has still packets. |
1083 | * | 1083 | * |
1084 | * spider_net_poll returns all packets from the rx descriptors to the stack | 1084 | * spider_net_poll returns all packets from the rx descriptors to the stack |
1085 | * (using netif_receive_skb). If all/enough packets are up, the driver | 1085 | * (using netif_receive_skb). If all/enough packets are up, the driver |
1086 | * reenables interrupts and returns 0. If not, 1 is returned. | 1086 | * reenables interrupts and returns 0. If not, 1 is returned. |
1087 | */ | 1087 | */ |
1088 | static int | 1088 | static int |
1089 | spider_net_poll(struct net_device *netdev, int *budget) | 1089 | spider_net_poll(struct net_device *netdev, int *budget) |
1090 | { | 1090 | { |
1091 | struct spider_net_card *card = netdev_priv(netdev); | 1091 | struct spider_net_card *card = netdev_priv(netdev); |
1092 | int packets_to_do, packets_done = 0; | 1092 | int packets_to_do, packets_done = 0; |
1093 | int no_more_packets = 0; | 1093 | int no_more_packets = 0; |
1094 | 1094 | ||
1095 | spider_net_cleanup_tx_ring(card); | 1095 | spider_net_cleanup_tx_ring(card); |
1096 | packets_to_do = min(*budget, netdev->quota); | 1096 | packets_to_do = min(*budget, netdev->quota); |
1097 | 1097 | ||
1098 | while (packets_to_do) { | 1098 | while (packets_to_do) { |
1099 | if (spider_net_decode_one_descr(card, 1)) { | 1099 | if (spider_net_decode_one_descr(card, 1)) { |
1100 | packets_done++; | 1100 | packets_done++; |
1101 | packets_to_do--; | 1101 | packets_to_do--; |
1102 | } else { | 1102 | } else { |
1103 | /* no more packets for the stack */ | 1103 | /* no more packets for the stack */ |
1104 | no_more_packets = 1; | 1104 | no_more_packets = 1; |
1105 | break; | 1105 | break; |
1106 | } | 1106 | } |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | netdev->quota -= packets_done; | 1109 | netdev->quota -= packets_done; |
1110 | *budget -= packets_done; | 1110 | *budget -= packets_done; |
1111 | spider_net_refill_rx_chain(card); | 1111 | spider_net_refill_rx_chain(card); |
1112 | 1112 | ||
1113 | /* if all packets are in the stack, enable interrupts and return 0 */ | 1113 | /* if all packets are in the stack, enable interrupts and return 0 */ |
1114 | /* if not, return 1 */ | 1114 | /* if not, return 1 */ |
1115 | if (no_more_packets) { | 1115 | if (no_more_packets) { |
1116 | netif_rx_complete(netdev); | 1116 | netif_rx_complete(netdev); |
1117 | spider_net_rx_irq_on(card); | 1117 | spider_net_rx_irq_on(card); |
1118 | return 0; | 1118 | return 0; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | return 1; | 1121 | return 1; |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | /** | 1124 | /** |
1125 | * spider_net_vlan_rx_reg - initializes VLAN structures in the driver and card | 1125 | * spider_net_vlan_rx_reg - initializes VLAN structures in the driver and card |
1126 | * @netdev: interface device structure | 1126 | * @netdev: interface device structure |
1127 | * @grp: vlan_group structure that is registered (NULL on destroying interface) | 1127 | * @grp: vlan_group structure that is registered (NULL on destroying interface) |
1128 | */ | 1128 | */ |
1129 | static void | 1129 | static void |
1130 | spider_net_vlan_rx_reg(struct net_device *netdev, struct vlan_group *grp) | 1130 | spider_net_vlan_rx_reg(struct net_device *netdev, struct vlan_group *grp) |
1131 | { | 1131 | { |
1132 | /* further enhancement... yet to do */ | 1132 | /* further enhancement... yet to do */ |
1133 | return; | 1133 | return; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | /** | 1136 | /** |
1137 | * spider_net_vlan_rx_add - adds VLAN id to the card filter | 1137 | * spider_net_vlan_rx_add - adds VLAN id to the card filter |
1138 | * @netdev: interface device structure | 1138 | * @netdev: interface device structure |
1139 | * @vid: VLAN id to add | 1139 | * @vid: VLAN id to add |
1140 | */ | 1140 | */ |
1141 | static void | 1141 | static void |
1142 | spider_net_vlan_rx_add(struct net_device *netdev, uint16_t vid) | 1142 | spider_net_vlan_rx_add(struct net_device *netdev, uint16_t vid) |
1143 | { | 1143 | { |
1144 | /* further enhancement... yet to do */ | 1144 | /* further enhancement... yet to do */ |
1145 | /* add vid to card's VLAN filter table */ | 1145 | /* add vid to card's VLAN filter table */ |
1146 | return; | 1146 | return; |
1147 | } | 1147 | } |
1148 | 1148 | ||
1149 | /** | 1149 | /** |
1150 | * spider_net_vlan_rx_kill - removes VLAN id to the card filter | 1150 | * spider_net_vlan_rx_kill - removes VLAN id to the card filter |
1151 | * @netdev: interface device structure | 1151 | * @netdev: interface device structure |
1152 | * @vid: VLAN id to remove | 1152 | * @vid: VLAN id to remove |
1153 | */ | 1153 | */ |
1154 | static void | 1154 | static void |
1155 | spider_net_vlan_rx_kill(struct net_device *netdev, uint16_t vid) | 1155 | spider_net_vlan_rx_kill(struct net_device *netdev, uint16_t vid) |
1156 | { | 1156 | { |
1157 | /* further enhancement... yet to do */ | 1157 | /* further enhancement... yet to do */ |
1158 | /* remove vid from card's VLAN filter table */ | 1158 | /* remove vid from card's VLAN filter table */ |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | /** | 1161 | /** |
1162 | * spider_net_get_stats - get interface statistics | 1162 | * spider_net_get_stats - get interface statistics |
1163 | * @netdev: interface device structure | 1163 | * @netdev: interface device structure |
1164 | * | 1164 | * |
1165 | * returns the interface statistics residing in the spider_net_card struct | 1165 | * returns the interface statistics residing in the spider_net_card struct |
1166 | */ | 1166 | */ |
1167 | static struct net_device_stats * | 1167 | static struct net_device_stats * |
1168 | spider_net_get_stats(struct net_device *netdev) | 1168 | spider_net_get_stats(struct net_device *netdev) |
1169 | { | 1169 | { |
1170 | struct spider_net_card *card = netdev_priv(netdev); | 1170 | struct spider_net_card *card = netdev_priv(netdev); |
1171 | struct net_device_stats *stats = &card->netdev_stats; | 1171 | struct net_device_stats *stats = &card->netdev_stats; |
1172 | return stats; | 1172 | return stats; |
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | /** | 1175 | /** |
1176 | * spider_net_change_mtu - changes the MTU of an interface | 1176 | * spider_net_change_mtu - changes the MTU of an interface |
1177 | * @netdev: interface device structure | 1177 | * @netdev: interface device structure |
1178 | * @new_mtu: new MTU value | 1178 | * @new_mtu: new MTU value |
1179 | * | 1179 | * |
1180 | * returns 0 on success, <0 on failure | 1180 | * returns 0 on success, <0 on failure |
1181 | */ | 1181 | */ |
1182 | static int | 1182 | static int |
1183 | spider_net_change_mtu(struct net_device *netdev, int new_mtu) | 1183 | spider_net_change_mtu(struct net_device *netdev, int new_mtu) |
1184 | { | 1184 | { |
1185 | /* no need to re-alloc skbs or so -- the max mtu is about 2.3k | 1185 | /* no need to re-alloc skbs or so -- the max mtu is about 2.3k |
1186 | * and mtu is outbound only anyway */ | 1186 | * and mtu is outbound only anyway */ |
1187 | if ( (new_mtu < SPIDER_NET_MIN_MTU ) || | 1187 | if ( (new_mtu < SPIDER_NET_MIN_MTU ) || |
1188 | (new_mtu > SPIDER_NET_MAX_MTU) ) | 1188 | (new_mtu > SPIDER_NET_MAX_MTU) ) |
1189 | return -EINVAL; | 1189 | return -EINVAL; |
1190 | netdev->mtu = new_mtu; | 1190 | netdev->mtu = new_mtu; |
1191 | return 0; | 1191 | return 0; |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | /** | 1194 | /** |
1195 | * spider_net_set_mac - sets the MAC of an interface | 1195 | * spider_net_set_mac - sets the MAC of an interface |
1196 | * @netdev: interface device structure | 1196 | * @netdev: interface device structure |
1197 | * @ptr: pointer to new MAC address | 1197 | * @ptr: pointer to new MAC address |
1198 | * | 1198 | * |
1199 | * Returns 0 on success, <0 on failure. Currently, we don't support this | 1199 | * Returns 0 on success, <0 on failure. Currently, we don't support this |
1200 | * and will always return EOPNOTSUPP. | 1200 | * and will always return EOPNOTSUPP. |
1201 | */ | 1201 | */ |
1202 | static int | 1202 | static int |
1203 | spider_net_set_mac(struct net_device *netdev, void *p) | 1203 | spider_net_set_mac(struct net_device *netdev, void *p) |
1204 | { | 1204 | { |
1205 | struct spider_net_card *card = netdev_priv(netdev); | 1205 | struct spider_net_card *card = netdev_priv(netdev); |
1206 | u32 macl, macu, regvalue; | 1206 | u32 macl, macu, regvalue; |
1207 | struct sockaddr *addr = p; | 1207 | struct sockaddr *addr = p; |
1208 | 1208 | ||
1209 | if (!is_valid_ether_addr(addr->sa_data)) | 1209 | if (!is_valid_ether_addr(addr->sa_data)) |
1210 | return -EADDRNOTAVAIL; | 1210 | return -EADDRNOTAVAIL; |
1211 | 1211 | ||
1212 | /* switch off GMACTPE and GMACRPE */ | 1212 | /* switch off GMACTPE and GMACRPE */ |
1213 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); | 1213 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); |
1214 | regvalue &= ~((1 << 5) | (1 << 6)); | 1214 | regvalue &= ~((1 << 5) | (1 << 6)); |
1215 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); | 1215 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); |
1216 | 1216 | ||
1217 | /* write mac */ | 1217 | /* write mac */ |
1218 | macu = (addr->sa_data[0]<<24) + (addr->sa_data[1]<<16) + | 1218 | macu = (addr->sa_data[0]<<24) + (addr->sa_data[1]<<16) + |
1219 | (addr->sa_data[2]<<8) + (addr->sa_data[3]); | 1219 | (addr->sa_data[2]<<8) + (addr->sa_data[3]); |
1220 | macl = (addr->sa_data[4]<<8) + (addr->sa_data[5]); | 1220 | macl = (addr->sa_data[4]<<8) + (addr->sa_data[5]); |
1221 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACU, macu); | 1221 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACU, macu); |
1222 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACL, macl); | 1222 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACL, macl); |
1223 | 1223 | ||
1224 | /* switch GMACTPE and GMACRPE back on */ | 1224 | /* switch GMACTPE and GMACRPE back on */ |
1225 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); | 1225 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); |
1226 | regvalue |= ((1 << 5) | (1 << 6)); | 1226 | regvalue |= ((1 << 5) | (1 << 6)); |
1227 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); | 1227 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); |
1228 | 1228 | ||
1229 | spider_net_set_promisc(card); | 1229 | spider_net_set_promisc(card); |
1230 | 1230 | ||
1231 | /* look up, whether we have been successful */ | 1231 | /* look up, whether we have been successful */ |
1232 | if (spider_net_get_mac_address(netdev)) | 1232 | if (spider_net_get_mac_address(netdev)) |
1233 | return -EADDRNOTAVAIL; | 1233 | return -EADDRNOTAVAIL; |
1234 | if (memcmp(netdev->dev_addr,addr->sa_data,netdev->addr_len)) | 1234 | if (memcmp(netdev->dev_addr,addr->sa_data,netdev->addr_len)) |
1235 | return -EADDRNOTAVAIL; | 1235 | return -EADDRNOTAVAIL; |
1236 | 1236 | ||
1237 | return 0; | 1237 | return 0; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | /** | 1240 | /** |
1241 | * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt | 1241 | * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt |
1242 | * @card: card structure | 1242 | * @card: card structure |
1243 | * | 1243 | * |
1244 | * spider_net_handle_rxram_full empties the RX ring so that spider can put | 1244 | * spider_net_handle_rxram_full empties the RX ring so that spider can put |
1245 | * more packets in it and empty its RX RAM. This is called in bottom half | 1245 | * more packets in it and empty its RX RAM. This is called in bottom half |
1246 | * context | 1246 | * context |
1247 | */ | 1247 | */ |
1248 | static void | 1248 | static void |
1249 | spider_net_handle_rxram_full(struct spider_net_card *card) | 1249 | spider_net_handle_rxram_full(struct spider_net_card *card) |
1250 | { | 1250 | { |
1251 | while (spider_net_decode_one_descr(card, 0)) | 1251 | while (spider_net_decode_one_descr(card, 0)) |
1252 | ; | 1252 | ; |
1253 | spider_net_enable_rxchtails(card); | 1253 | spider_net_enable_rxchtails(card); |
1254 | spider_net_enable_rxdmac(card); | 1254 | spider_net_enable_rxdmac(card); |
1255 | netif_rx_schedule(card->netdev); | 1255 | netif_rx_schedule(card->netdev); |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | /** | 1258 | /** |
1259 | * spider_net_handle_error_irq - handles errors raised by an interrupt | 1259 | * spider_net_handle_error_irq - handles errors raised by an interrupt |
1260 | * @card: card structure | 1260 | * @card: card structure |
1261 | * @status_reg: interrupt status register 0 (GHIINT0STS) | 1261 | * @status_reg: interrupt status register 0 (GHIINT0STS) |
1262 | * | 1262 | * |
1263 | * spider_net_handle_error_irq treats or ignores all error conditions | 1263 | * spider_net_handle_error_irq treats or ignores all error conditions |
1264 | * found when an interrupt is presented | 1264 | * found when an interrupt is presented |
1265 | */ | 1265 | */ |
1266 | static void | 1266 | static void |
1267 | spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | 1267 | spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) |
1268 | { | 1268 | { |
1269 | u32 error_reg1, error_reg2; | 1269 | u32 error_reg1, error_reg2; |
1270 | u32 i; | 1270 | u32 i; |
1271 | int show_error = 1; | 1271 | int show_error = 1; |
1272 | 1272 | ||
1273 | error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); | 1273 | error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); |
1274 | error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); | 1274 | error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); |
1275 | 1275 | ||
1276 | /* check GHIINT0STS ************************************/ | 1276 | /* check GHIINT0STS ************************************/ |
1277 | if (status_reg) | 1277 | if (status_reg) |
1278 | for (i = 0; i < 32; i++) | 1278 | for (i = 0; i < 32; i++) |
1279 | if (status_reg & (1<<i)) | 1279 | if (status_reg & (1<<i)) |
1280 | switch (i) | 1280 | switch (i) |
1281 | { | 1281 | { |
1282 | /* let error_reg1 and error_reg2 evaluation decide, what to do | 1282 | /* let error_reg1 and error_reg2 evaluation decide, what to do |
1283 | case SPIDER_NET_PHYINT: | 1283 | case SPIDER_NET_PHYINT: |
1284 | case SPIDER_NET_GMAC2INT: | 1284 | case SPIDER_NET_GMAC2INT: |
1285 | case SPIDER_NET_GMAC1INT: | 1285 | case SPIDER_NET_GMAC1INT: |
1286 | case SPIDER_NET_GFIFOINT: | 1286 | case SPIDER_NET_GFIFOINT: |
1287 | case SPIDER_NET_DMACINT: | 1287 | case SPIDER_NET_DMACINT: |
1288 | case SPIDER_NET_GSYSINT: | 1288 | case SPIDER_NET_GSYSINT: |
1289 | break; */ | 1289 | break; */ |
1290 | 1290 | ||
1291 | case SPIDER_NET_GIPSINT: | 1291 | case SPIDER_NET_GIPSINT: |
1292 | show_error = 0; | 1292 | show_error = 0; |
1293 | break; | 1293 | break; |
1294 | 1294 | ||
1295 | case SPIDER_NET_GPWOPCMPINT: | 1295 | case SPIDER_NET_GPWOPCMPINT: |
1296 | /* PHY write operation completed */ | 1296 | /* PHY write operation completed */ |
1297 | show_error = 0; | 1297 | show_error = 0; |
1298 | break; | 1298 | break; |
1299 | case SPIDER_NET_GPROPCMPINT: | 1299 | case SPIDER_NET_GPROPCMPINT: |
1300 | /* PHY read operation completed */ | 1300 | /* PHY read operation completed */ |
1301 | /* we don't use semaphores, as we poll for the completion | 1301 | /* we don't use semaphores, as we poll for the completion |
1302 | * of the read operation in spider_net_read_phy. Should take | 1302 | * of the read operation in spider_net_read_phy. Should take |
1303 | * about 50 us */ | 1303 | * about 50 us */ |
1304 | show_error = 0; | 1304 | show_error = 0; |
1305 | break; | 1305 | break; |
1306 | case SPIDER_NET_GPWFFINT: | 1306 | case SPIDER_NET_GPWFFINT: |
1307 | /* PHY command queue full */ | 1307 | /* PHY command queue full */ |
1308 | if (netif_msg_intr(card)) | 1308 | if (netif_msg_intr(card)) |
1309 | pr_err("PHY write queue full\n"); | 1309 | pr_err("PHY write queue full\n"); |
1310 | show_error = 0; | 1310 | show_error = 0; |
1311 | break; | 1311 | break; |
1312 | 1312 | ||
1313 | /* case SPIDER_NET_GRMDADRINT: not used. print a message */ | 1313 | /* case SPIDER_NET_GRMDADRINT: not used. print a message */ |
1314 | /* case SPIDER_NET_GRMARPINT: not used. print a message */ | 1314 | /* case SPIDER_NET_GRMARPINT: not used. print a message */ |
1315 | /* case SPIDER_NET_GRMMPINT: not used. print a message */ | 1315 | /* case SPIDER_NET_GRMMPINT: not used. print a message */ |
1316 | 1316 | ||
1317 | case SPIDER_NET_GDTDEN0INT: | 1317 | case SPIDER_NET_GDTDEN0INT: |
1318 | /* someone has set TX_DMA_EN to 0 */ | 1318 | /* someone has set TX_DMA_EN to 0 */ |
1319 | show_error = 0; | 1319 | show_error = 0; |
1320 | break; | 1320 | break; |
1321 | 1321 | ||
1322 | case SPIDER_NET_GDDDEN0INT: /* fallthrough */ | 1322 | case SPIDER_NET_GDDDEN0INT: /* fallthrough */ |
1323 | case SPIDER_NET_GDCDEN0INT: /* fallthrough */ | 1323 | case SPIDER_NET_GDCDEN0INT: /* fallthrough */ |
1324 | case SPIDER_NET_GDBDEN0INT: /* fallthrough */ | 1324 | case SPIDER_NET_GDBDEN0INT: /* fallthrough */ |
1325 | case SPIDER_NET_GDADEN0INT: | 1325 | case SPIDER_NET_GDADEN0INT: |
1326 | /* someone has set RX_DMA_EN to 0 */ | 1326 | /* someone has set RX_DMA_EN to 0 */ |
1327 | show_error = 0; | 1327 | show_error = 0; |
1328 | break; | 1328 | break; |
1329 | 1329 | ||
1330 | /* RX interrupts */ | 1330 | /* RX interrupts */ |
1331 | case SPIDER_NET_GDDFDCINT: | 1331 | case SPIDER_NET_GDDFDCINT: |
1332 | case SPIDER_NET_GDCFDCINT: | 1332 | case SPIDER_NET_GDCFDCINT: |
1333 | case SPIDER_NET_GDBFDCINT: | 1333 | case SPIDER_NET_GDBFDCINT: |
1334 | case SPIDER_NET_GDAFDCINT: | 1334 | case SPIDER_NET_GDAFDCINT: |
1335 | /* case SPIDER_NET_GDNMINT: not used. print a message */ | 1335 | /* case SPIDER_NET_GDNMINT: not used. print a message */ |
1336 | /* case SPIDER_NET_GCNMINT: not used. print a message */ | 1336 | /* case SPIDER_NET_GCNMINT: not used. print a message */ |
1337 | /* case SPIDER_NET_GBNMINT: not used. print a message */ | 1337 | /* case SPIDER_NET_GBNMINT: not used. print a message */ |
1338 | /* case SPIDER_NET_GANMINT: not used. print a message */ | 1338 | /* case SPIDER_NET_GANMINT: not used. print a message */ |
1339 | /* case SPIDER_NET_GRFNMINT: not used. print a message */ | 1339 | /* case SPIDER_NET_GRFNMINT: not used. print a message */ |
1340 | show_error = 0; | 1340 | show_error = 0; |
1341 | break; | 1341 | break; |
1342 | 1342 | ||
1343 | /* TX interrupts */ | 1343 | /* TX interrupts */ |
1344 | case SPIDER_NET_GDTFDCINT: | 1344 | case SPIDER_NET_GDTFDCINT: |
1345 | show_error = 0; | 1345 | show_error = 0; |
1346 | break; | 1346 | break; |
1347 | case SPIDER_NET_GTTEDINT: | 1347 | case SPIDER_NET_GTTEDINT: |
1348 | show_error = 0; | 1348 | show_error = 0; |
1349 | break; | 1349 | break; |
1350 | case SPIDER_NET_GDTDCEINT: | 1350 | case SPIDER_NET_GDTDCEINT: |
1351 | /* chain end. If a descriptor should be sent, kick off | 1351 | /* chain end. If a descriptor should be sent, kick off |
1352 | * tx dma | 1352 | * tx dma |
1353 | if (card->tx_chain.tail != card->tx_chain.head) | 1353 | if (card->tx_chain.tail != card->tx_chain.head) |
1354 | spider_net_kick_tx_dma(card); | 1354 | spider_net_kick_tx_dma(card); |
1355 | */ | 1355 | */ |
1356 | show_error = 0; | 1356 | show_error = 0; |
1357 | break; | 1357 | break; |
1358 | 1358 | ||
1359 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ | 1359 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ |
1360 | /* case SPIDER_NET_GFREECNTINT: not used. print a message */ | 1360 | /* case SPIDER_NET_GFREECNTINT: not used. print a message */ |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | /* check GHIINT1STS ************************************/ | 1363 | /* check GHIINT1STS ************************************/ |
1364 | if (error_reg1) | 1364 | if (error_reg1) |
1365 | for (i = 0; i < 32; i++) | 1365 | for (i = 0; i < 32; i++) |
1366 | if (error_reg1 & (1<<i)) | 1366 | if (error_reg1 & (1<<i)) |
1367 | switch (i) | 1367 | switch (i) |
1368 | { | 1368 | { |
1369 | case SPIDER_NET_GTMFLLINT: | 1369 | case SPIDER_NET_GTMFLLINT: |
1370 | if (netif_msg_intr(card) && net_ratelimit()) | 1370 | if (netif_msg_intr(card) && net_ratelimit()) |
1371 | pr_err("Spider TX RAM full\n"); | 1371 | pr_err("Spider TX RAM full\n"); |
1372 | show_error = 0; | 1372 | show_error = 0; |
1373 | break; | 1373 | break; |
1374 | case SPIDER_NET_GRFDFLLINT: /* fallthrough */ | 1374 | case SPIDER_NET_GRFDFLLINT: /* fallthrough */ |
1375 | case SPIDER_NET_GRFCFLLINT: /* fallthrough */ | 1375 | case SPIDER_NET_GRFCFLLINT: /* fallthrough */ |
1376 | case SPIDER_NET_GRFBFLLINT: /* fallthrough */ | 1376 | case SPIDER_NET_GRFBFLLINT: /* fallthrough */ |
1377 | case SPIDER_NET_GRFAFLLINT: /* fallthrough */ | 1377 | case SPIDER_NET_GRFAFLLINT: /* fallthrough */ |
1378 | case SPIDER_NET_GRMFLLINT: | 1378 | case SPIDER_NET_GRMFLLINT: |
1379 | if (netif_msg_intr(card) && net_ratelimit()) | 1379 | if (netif_msg_intr(card) && net_ratelimit()) |
1380 | pr_debug("Spider RX RAM full, incoming packets " | 1380 | pr_debug("Spider RX RAM full, incoming packets " |
1381 | "might be discarded!\n"); | 1381 | "might be discarded!\n"); |
1382 | spider_net_rx_irq_off(card); | 1382 | spider_net_rx_irq_off(card); |
1383 | tasklet_schedule(&card->rxram_full_tl); | 1383 | tasklet_schedule(&card->rxram_full_tl); |
1384 | show_error = 0; | 1384 | show_error = 0; |
1385 | break; | 1385 | break; |
1386 | 1386 | ||
1387 | /* case SPIDER_NET_GTMSHTINT: problem, print a message */ | 1387 | /* case SPIDER_NET_GTMSHTINT: problem, print a message */ |
1388 | case SPIDER_NET_GDTINVDINT: | 1388 | case SPIDER_NET_GDTINVDINT: |
1389 | /* allrighty. tx from previous descr ok */ | 1389 | /* allrighty. tx from previous descr ok */ |
1390 | show_error = 0; | 1390 | show_error = 0; |
1391 | break; | 1391 | break; |
1392 | 1392 | ||
1393 | /* chain end */ | 1393 | /* chain end */ |
1394 | case SPIDER_NET_GDDDCEINT: /* fallthrough */ | 1394 | case SPIDER_NET_GDDDCEINT: /* fallthrough */ |
1395 | case SPIDER_NET_GDCDCEINT: /* fallthrough */ | 1395 | case SPIDER_NET_GDCDCEINT: /* fallthrough */ |
1396 | case SPIDER_NET_GDBDCEINT: /* fallthrough */ | 1396 | case SPIDER_NET_GDBDCEINT: /* fallthrough */ |
1397 | case SPIDER_NET_GDADCEINT: | 1397 | case SPIDER_NET_GDADCEINT: |
1398 | if (netif_msg_intr(card)) | 1398 | if (netif_msg_intr(card)) |
1399 | pr_err("got descriptor chain end interrupt, " | 1399 | pr_err("got descriptor chain end interrupt, " |
1400 | "restarting DMAC %c.\n", | 1400 | "restarting DMAC %c.\n", |
1401 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); | 1401 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); |
1402 | spider_net_refill_rx_chain(card); | 1402 | spider_net_refill_rx_chain(card); |
1403 | spider_net_enable_rxdmac(card); | 1403 | spider_net_enable_rxdmac(card); |
1404 | show_error = 0; | 1404 | show_error = 0; |
1405 | break; | 1405 | break; |
1406 | 1406 | ||
1407 | /* invalid descriptor */ | 1407 | /* invalid descriptor */ |
1408 | case SPIDER_NET_GDDINVDINT: /* fallthrough */ | 1408 | case SPIDER_NET_GDDINVDINT: /* fallthrough */ |
1409 | case SPIDER_NET_GDCINVDINT: /* fallthrough */ | 1409 | case SPIDER_NET_GDCINVDINT: /* fallthrough */ |
1410 | case SPIDER_NET_GDBINVDINT: /* fallthrough */ | 1410 | case SPIDER_NET_GDBINVDINT: /* fallthrough */ |
1411 | case SPIDER_NET_GDAINVDINT: | 1411 | case SPIDER_NET_GDAINVDINT: |
1412 | /* could happen when rx chain is full */ | 1412 | /* could happen when rx chain is full */ |
1413 | spider_net_refill_rx_chain(card); | 1413 | spider_net_refill_rx_chain(card); |
1414 | spider_net_enable_rxdmac(card); | 1414 | spider_net_enable_rxdmac(card); |
1415 | show_error = 0; | 1415 | show_error = 0; |
1416 | break; | 1416 | break; |
1417 | 1417 | ||
1418 | /* case SPIDER_NET_GDTRSERINT: problem, print a message */ | 1418 | /* case SPIDER_NET_GDTRSERINT: problem, print a message */ |
1419 | /* case SPIDER_NET_GDDRSERINT: problem, print a message */ | 1419 | /* case SPIDER_NET_GDDRSERINT: problem, print a message */ |
1420 | /* case SPIDER_NET_GDCRSERINT: problem, print a message */ | 1420 | /* case SPIDER_NET_GDCRSERINT: problem, print a message */ |
1421 | /* case SPIDER_NET_GDBRSERINT: problem, print a message */ | 1421 | /* case SPIDER_NET_GDBRSERINT: problem, print a message */ |
1422 | /* case SPIDER_NET_GDARSERINT: problem, print a message */ | 1422 | /* case SPIDER_NET_GDARSERINT: problem, print a message */ |
1423 | /* case SPIDER_NET_GDSERINT: problem, print a message */ | 1423 | /* case SPIDER_NET_GDSERINT: problem, print a message */ |
1424 | /* case SPIDER_NET_GDTPTERINT: problem, print a message */ | 1424 | /* case SPIDER_NET_GDTPTERINT: problem, print a message */ |
1425 | /* case SPIDER_NET_GDDPTERINT: problem, print a message */ | 1425 | /* case SPIDER_NET_GDDPTERINT: problem, print a message */ |
1426 | /* case SPIDER_NET_GDCPTERINT: problem, print a message */ | 1426 | /* case SPIDER_NET_GDCPTERINT: problem, print a message */ |
1427 | /* case SPIDER_NET_GDBPTERINT: problem, print a message */ | 1427 | /* case SPIDER_NET_GDBPTERINT: problem, print a message */ |
1428 | /* case SPIDER_NET_GDAPTERINT: problem, print a message */ | 1428 | /* case SPIDER_NET_GDAPTERINT: problem, print a message */ |
1429 | default: | 1429 | default: |
1430 | show_error = 1; | 1430 | show_error = 1; |
1431 | break; | 1431 | break; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | /* check GHIINT2STS ************************************/ | 1434 | /* check GHIINT2STS ************************************/ |
1435 | if (error_reg2) | 1435 | if (error_reg2) |
1436 | for (i = 0; i < 32; i++) | 1436 | for (i = 0; i < 32; i++) |
1437 | if (error_reg2 & (1<<i)) | 1437 | if (error_reg2 & (1<<i)) |
1438 | switch (i) | 1438 | switch (i) |
1439 | { | 1439 | { |
1440 | /* there is nothing we can (want to) do at this time. Log a | 1440 | /* there is nothing we can (want to) do at this time. Log a |
1441 | * message, we can switch on and off the specific values later on | 1441 | * message, we can switch on and off the specific values later on |
1442 | case SPIDER_NET_GPROPERINT: | 1442 | case SPIDER_NET_GPROPERINT: |
1443 | case SPIDER_NET_GMCTCRSNGINT: | 1443 | case SPIDER_NET_GMCTCRSNGINT: |
1444 | case SPIDER_NET_GMCTLCOLINT: | 1444 | case SPIDER_NET_GMCTLCOLINT: |
1445 | case SPIDER_NET_GMCTTMOTINT: | 1445 | case SPIDER_NET_GMCTTMOTINT: |
1446 | case SPIDER_NET_GMCRCAERINT: | 1446 | case SPIDER_NET_GMCRCAERINT: |
1447 | case SPIDER_NET_GMCRCALERINT: | 1447 | case SPIDER_NET_GMCRCALERINT: |
1448 | case SPIDER_NET_GMCRALNERINT: | 1448 | case SPIDER_NET_GMCRALNERINT: |
1449 | case SPIDER_NET_GMCROVRINT: | 1449 | case SPIDER_NET_GMCROVRINT: |
1450 | case SPIDER_NET_GMCRRNTINT: | 1450 | case SPIDER_NET_GMCRRNTINT: |
1451 | case SPIDER_NET_GMCRRXERINT: | 1451 | case SPIDER_NET_GMCRRXERINT: |
1452 | case SPIDER_NET_GTITCSERINT: | 1452 | case SPIDER_NET_GTITCSERINT: |
1453 | case SPIDER_NET_GTIFMTERINT: | 1453 | case SPIDER_NET_GTIFMTERINT: |
1454 | case SPIDER_NET_GTIPKTRVKINT: | 1454 | case SPIDER_NET_GTIPKTRVKINT: |
1455 | case SPIDER_NET_GTISPINGINT: | 1455 | case SPIDER_NET_GTISPINGINT: |
1456 | case SPIDER_NET_GTISADNGINT: | 1456 | case SPIDER_NET_GTISADNGINT: |
1457 | case SPIDER_NET_GTISPDNGINT: | 1457 | case SPIDER_NET_GTISPDNGINT: |
1458 | case SPIDER_NET_GRIFMTERINT: | 1458 | case SPIDER_NET_GRIFMTERINT: |
1459 | case SPIDER_NET_GRIPKTRVKINT: | 1459 | case SPIDER_NET_GRIPKTRVKINT: |
1460 | case SPIDER_NET_GRISPINGINT: | 1460 | case SPIDER_NET_GRISPINGINT: |
1461 | case SPIDER_NET_GRISADNGINT: | 1461 | case SPIDER_NET_GRISADNGINT: |
1462 | case SPIDER_NET_GRISPDNGINT: | 1462 | case SPIDER_NET_GRISPDNGINT: |
1463 | break; | 1463 | break; |
1464 | */ | 1464 | */ |
1465 | default: | 1465 | default: |
1466 | break; | 1466 | break; |
1467 | } | 1467 | } |
1468 | 1468 | ||
1469 | if ((show_error) && (netif_msg_intr(card))) | 1469 | if ((show_error) && (netif_msg_intr(card))) |
1470 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " | 1470 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " |
1471 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", | 1471 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", |
1472 | card->netdev->name, | 1472 | card->netdev->name, |
1473 | status_reg, error_reg1, error_reg2); | 1473 | status_reg, error_reg1, error_reg2); |
1474 | 1474 | ||
1475 | /* clear interrupt sources */ | 1475 | /* clear interrupt sources */ |
1476 | spider_net_write_reg(card, SPIDER_NET_GHIINT1STS, error_reg1); | 1476 | spider_net_write_reg(card, SPIDER_NET_GHIINT1STS, error_reg1); |
1477 | spider_net_write_reg(card, SPIDER_NET_GHIINT2STS, error_reg2); | 1477 | spider_net_write_reg(card, SPIDER_NET_GHIINT2STS, error_reg2); |
1478 | } | 1478 | } |
1479 | 1479 | ||
1480 | /** | 1480 | /** |
1481 | * spider_net_interrupt - interrupt handler for spider_net | 1481 | * spider_net_interrupt - interrupt handler for spider_net |
1482 | * @irq: interupt number | 1482 | * @irq: interupt number |
1483 | * @ptr: pointer to net_device | 1483 | * @ptr: pointer to net_device |
1484 | * @regs: PU registers | 1484 | * @regs: PU registers |
1485 | * | 1485 | * |
1486 | * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no | 1486 | * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no |
1487 | * interrupt found raised by card. | 1487 | * interrupt found raised by card. |
1488 | * | 1488 | * |
1489 | * This is the interrupt handler, that turns off | 1489 | * This is the interrupt handler, that turns off |
1490 | * interrupts for this device and makes the stack poll the driver | 1490 | * interrupts for this device and makes the stack poll the driver |
1491 | */ | 1491 | */ |
1492 | static irqreturn_t | 1492 | static irqreturn_t |
1493 | spider_net_interrupt(int irq, void *ptr) | 1493 | spider_net_interrupt(int irq, void *ptr) |
1494 | { | 1494 | { |
1495 | struct net_device *netdev = ptr; | 1495 | struct net_device *netdev = ptr; |
1496 | struct spider_net_card *card = netdev_priv(netdev); | 1496 | struct spider_net_card *card = netdev_priv(netdev); |
1497 | u32 status_reg; | 1497 | u32 status_reg; |
1498 | 1498 | ||
1499 | status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); | 1499 | status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); |
1500 | 1500 | ||
1501 | if (!status_reg) | 1501 | if (!status_reg) |
1502 | return IRQ_NONE; | 1502 | return IRQ_NONE; |
1503 | 1503 | ||
1504 | if (status_reg & SPIDER_NET_RXINT ) { | 1504 | if (status_reg & SPIDER_NET_RXINT ) { |
1505 | spider_net_rx_irq_off(card); | 1505 | spider_net_rx_irq_off(card); |
1506 | netif_rx_schedule(netdev); | 1506 | netif_rx_schedule(netdev); |
1507 | } | 1507 | } |
1508 | if (status_reg & SPIDER_NET_TXINT) | 1508 | if (status_reg & SPIDER_NET_TXINT) |
1509 | netif_rx_schedule(netdev); | 1509 | netif_rx_schedule(netdev); |
1510 | 1510 | ||
1511 | if (status_reg & SPIDER_NET_ERRINT ) | 1511 | if (status_reg & SPIDER_NET_ERRINT ) |
1512 | spider_net_handle_error_irq(card, status_reg); | 1512 | spider_net_handle_error_irq(card, status_reg); |
1513 | 1513 | ||
1514 | /* clear interrupt sources */ | 1514 | /* clear interrupt sources */ |
1515 | spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); | 1515 | spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); |
1516 | 1516 | ||
1517 | return IRQ_HANDLED; | 1517 | return IRQ_HANDLED; |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1520 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1521 | /** | 1521 | /** |
1522 | * spider_net_poll_controller - artificial interrupt for netconsole etc. | 1522 | * spider_net_poll_controller - artificial interrupt for netconsole etc. |
1523 | * @netdev: interface device structure | 1523 | * @netdev: interface device structure |
1524 | * | 1524 | * |
1525 | * see Documentation/networking/netconsole.txt | 1525 | * see Documentation/networking/netconsole.txt |
1526 | */ | 1526 | */ |
1527 | static void | 1527 | static void |
1528 | spider_net_poll_controller(struct net_device *netdev) | 1528 | spider_net_poll_controller(struct net_device *netdev) |
1529 | { | 1529 | { |
1530 | disable_irq(netdev->irq); | 1530 | disable_irq(netdev->irq); |
1531 | spider_net_interrupt(netdev->irq, netdev); | 1531 | spider_net_interrupt(netdev->irq, netdev); |
1532 | enable_irq(netdev->irq); | 1532 | enable_irq(netdev->irq); |
1533 | } | 1533 | } |
1534 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 1534 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
1535 | 1535 | ||
1536 | /** | 1536 | /** |
1537 | * spider_net_init_card - initializes the card | 1537 | * spider_net_init_card - initializes the card |
1538 | * @card: card structure | 1538 | * @card: card structure |
1539 | * | 1539 | * |
1540 | * spider_net_init_card initializes the card so that other registers can | 1540 | * spider_net_init_card initializes the card so that other registers can |
1541 | * be used | 1541 | * be used |
1542 | */ | 1542 | */ |
1543 | static void | 1543 | static void |
1544 | spider_net_init_card(struct spider_net_card *card) | 1544 | spider_net_init_card(struct spider_net_card *card) |
1545 | { | 1545 | { |
1546 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 1546 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
1547 | SPIDER_NET_CKRCTRL_STOP_VALUE); | 1547 | SPIDER_NET_CKRCTRL_STOP_VALUE); |
1548 | 1548 | ||
1549 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 1549 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
1550 | SPIDER_NET_CKRCTRL_RUN_VALUE); | 1550 | SPIDER_NET_CKRCTRL_RUN_VALUE); |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | /** | 1553 | /** |
1554 | * spider_net_enable_card - enables the card by setting all kinds of regs | 1554 | * spider_net_enable_card - enables the card by setting all kinds of regs |
1555 | * @card: card structure | 1555 | * @card: card structure |
1556 | * | 1556 | * |
1557 | * spider_net_enable_card sets a lot of SMMIO registers to enable the device | 1557 | * spider_net_enable_card sets a lot of SMMIO registers to enable the device |
1558 | */ | 1558 | */ |
1559 | static void | 1559 | static void |
1560 | spider_net_enable_card(struct spider_net_card *card) | 1560 | spider_net_enable_card(struct spider_net_card *card) |
1561 | { | 1561 | { |
1562 | int i; | 1562 | int i; |
1563 | /* the following array consists of (register),(value) pairs | 1563 | /* the following array consists of (register),(value) pairs |
1564 | * that are set in this function. A register of 0 ends the list */ | 1564 | * that are set in this function. A register of 0 ends the list */ |
1565 | u32 regs[][2] = { | 1565 | u32 regs[][2] = { |
1566 | { SPIDER_NET_GRESUMINTNUM, 0 }, | 1566 | { SPIDER_NET_GRESUMINTNUM, 0 }, |
1567 | { SPIDER_NET_GREINTNUM, 0 }, | 1567 | { SPIDER_NET_GREINTNUM, 0 }, |
1568 | 1568 | ||
1569 | /* set interrupt frame number registers */ | 1569 | /* set interrupt frame number registers */ |
1570 | /* clear the single DMA engine registers first */ | 1570 | /* clear the single DMA engine registers first */ |
1571 | { SPIDER_NET_GFAFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | 1571 | { SPIDER_NET_GFAFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, |
1572 | { SPIDER_NET_GFBFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | 1572 | { SPIDER_NET_GFBFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, |
1573 | { SPIDER_NET_GFCFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | 1573 | { SPIDER_NET_GFCFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, |
1574 | { SPIDER_NET_GFDFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | 1574 | { SPIDER_NET_GFDFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, |
1575 | /* then set, what we really need */ | 1575 | /* then set, what we really need */ |
1576 | { SPIDER_NET_GFFRMNUM, SPIDER_NET_FRAMENUM_VALUE }, | 1576 | { SPIDER_NET_GFFRMNUM, SPIDER_NET_FRAMENUM_VALUE }, |
1577 | 1577 | ||
1578 | /* timer counter registers and stuff */ | 1578 | /* timer counter registers and stuff */ |
1579 | { SPIDER_NET_GFREECNNUM, 0 }, | 1579 | { SPIDER_NET_GFREECNNUM, 0 }, |
1580 | { SPIDER_NET_GONETIMENUM, 0 }, | 1580 | { SPIDER_NET_GONETIMENUM, 0 }, |
1581 | { SPIDER_NET_GTOUTFRMNUM, 0 }, | 1581 | { SPIDER_NET_GTOUTFRMNUM, 0 }, |
1582 | 1582 | ||
1583 | /* RX mode setting */ | 1583 | /* RX mode setting */ |
1584 | { SPIDER_NET_GRXMDSET, SPIDER_NET_RXMODE_VALUE }, | 1584 | { SPIDER_NET_GRXMDSET, SPIDER_NET_RXMODE_VALUE }, |
1585 | /* TX mode setting */ | 1585 | /* TX mode setting */ |
1586 | { SPIDER_NET_GTXMDSET, SPIDER_NET_TXMODE_VALUE }, | 1586 | { SPIDER_NET_GTXMDSET, SPIDER_NET_TXMODE_VALUE }, |
1587 | /* IPSEC mode setting */ | 1587 | /* IPSEC mode setting */ |
1588 | { SPIDER_NET_GIPSECINIT, SPIDER_NET_IPSECINIT_VALUE }, | 1588 | { SPIDER_NET_GIPSECINIT, SPIDER_NET_IPSECINIT_VALUE }, |
1589 | 1589 | ||
1590 | { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE }, | 1590 | { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE }, |
1591 | 1591 | ||
1592 | { SPIDER_NET_GMRWOLCTRL, 0 }, | 1592 | { SPIDER_NET_GMRWOLCTRL, 0 }, |
1593 | { SPIDER_NET_GTESTMD, 0x10000000 }, | 1593 | { SPIDER_NET_GTESTMD, 0x10000000 }, |
1594 | { SPIDER_NET_GTTQMSK, 0x00400040 }, | 1594 | { SPIDER_NET_GTTQMSK, 0x00400040 }, |
1595 | 1595 | ||
1596 | { SPIDER_NET_GMACINTEN, 0 }, | 1596 | { SPIDER_NET_GMACINTEN, 0 }, |
1597 | 1597 | ||
1598 | /* flow control stuff */ | 1598 | /* flow control stuff */ |
1599 | { SPIDER_NET_GMACAPAUSE, SPIDER_NET_MACAPAUSE_VALUE }, | 1599 | { SPIDER_NET_GMACAPAUSE, SPIDER_NET_MACAPAUSE_VALUE }, |
1600 | { SPIDER_NET_GMACTXPAUSE, SPIDER_NET_TXPAUSE_VALUE }, | 1600 | { SPIDER_NET_GMACTXPAUSE, SPIDER_NET_TXPAUSE_VALUE }, |
1601 | 1601 | ||
1602 | { SPIDER_NET_GMACBSTLMT, SPIDER_NET_BURSTLMT_VALUE }, | 1602 | { SPIDER_NET_GMACBSTLMT, SPIDER_NET_BURSTLMT_VALUE }, |
1603 | { 0, 0} | 1603 | { 0, 0} |
1604 | }; | 1604 | }; |
1605 | 1605 | ||
1606 | i = 0; | 1606 | i = 0; |
1607 | while (regs[i][0]) { | 1607 | while (regs[i][0]) { |
1608 | spider_net_write_reg(card, regs[i][0], regs[i][1]); | 1608 | spider_net_write_reg(card, regs[i][0], regs[i][1]); |
1609 | i++; | 1609 | i++; |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | /* clear unicast filter table entries 1 to 14 */ | 1612 | /* clear unicast filter table entries 1 to 14 */ |
1613 | for (i = 1; i <= 14; i++) { | 1613 | for (i = 1; i <= 14; i++) { |
1614 | spider_net_write_reg(card, | 1614 | spider_net_write_reg(card, |
1615 | SPIDER_NET_GMRUAFILnR + i * 8, | 1615 | SPIDER_NET_GMRUAFILnR + i * 8, |
1616 | 0x00080000); | 1616 | 0x00080000); |
1617 | spider_net_write_reg(card, | 1617 | spider_net_write_reg(card, |
1618 | SPIDER_NET_GMRUAFILnR + i * 8 + 4, | 1618 | SPIDER_NET_GMRUAFILnR + i * 8 + 4, |
1619 | 0x00000000); | 1619 | 0x00000000); |
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, 0x08080000); | 1622 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, 0x08080000); |
1623 | 1623 | ||
1624 | spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); | 1624 | spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); |
1625 | 1625 | ||
1626 | /* set chain tail adress for RX chains and | 1626 | /* set chain tail adress for RX chains and |
1627 | * enable DMA */ | 1627 | * enable DMA */ |
1628 | spider_net_enable_rxchtails(card); | 1628 | spider_net_enable_rxchtails(card); |
1629 | spider_net_enable_rxdmac(card); | 1629 | spider_net_enable_rxdmac(card); |
1630 | 1630 | ||
1631 | spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); | 1631 | spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); |
1632 | 1632 | ||
1633 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, | 1633 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, |
1634 | SPIDER_NET_LENLMT_VALUE); | 1634 | SPIDER_NET_LENLMT_VALUE); |
1635 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, | 1635 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, |
1636 | SPIDER_NET_MACMODE_VALUE); | 1636 | SPIDER_NET_MACMODE_VALUE); |
1637 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, | 1637 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, |
1638 | SPIDER_NET_OPMODE_VALUE); | 1638 | SPIDER_NET_OPMODE_VALUE); |
1639 | 1639 | ||
1640 | /* set interrupt mask registers */ | 1640 | /* set interrupt mask registers */ |
1641 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, | 1641 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, |
1642 | SPIDER_NET_INT0_MASK_VALUE); | 1642 | SPIDER_NET_INT0_MASK_VALUE); |
1643 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, | 1643 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, |
1644 | SPIDER_NET_INT1_MASK_VALUE); | 1644 | SPIDER_NET_INT1_MASK_VALUE); |
1645 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, | 1645 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, |
1646 | SPIDER_NET_INT2_MASK_VALUE); | 1646 | SPIDER_NET_INT2_MASK_VALUE); |
1647 | 1647 | ||
1648 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 1648 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
1649 | SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS); | 1649 | SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS); |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | /** | 1652 | /** |
1653 | * spider_net_open - called upon ifonfig up | 1653 | * spider_net_open - called upon ifonfig up |
1654 | * @netdev: interface device structure | 1654 | * @netdev: interface device structure |
1655 | * | 1655 | * |
1656 | * returns 0 on success, <0 on failure | 1656 | * returns 0 on success, <0 on failure |
1657 | * | 1657 | * |
1658 | * spider_net_open allocates all the descriptors and memory needed for | 1658 | * spider_net_open allocates all the descriptors and memory needed for |
1659 | * operation, sets up multicast list and enables interrupts | 1659 | * operation, sets up multicast list and enables interrupts |
1660 | */ | 1660 | */ |
1661 | int | 1661 | int |
1662 | spider_net_open(struct net_device *netdev) | 1662 | spider_net_open(struct net_device *netdev) |
1663 | { | 1663 | { |
1664 | struct spider_net_card *card = netdev_priv(netdev); | 1664 | struct spider_net_card *card = netdev_priv(netdev); |
1665 | int result; | 1665 | int result; |
1666 | 1666 | ||
1667 | result = -ENOMEM; | 1667 | result = -ENOMEM; |
1668 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, | 1668 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, |
1669 | PCI_DMA_TODEVICE, card->tx_desc)) | 1669 | PCI_DMA_TODEVICE, card->num_tx_desc)) |
1670 | goto alloc_tx_failed; | 1670 | goto alloc_tx_failed; |
1671 | 1671 | ||
1672 | card->low_watermark = NULL; | 1672 | card->low_watermark = NULL; |
1673 | 1673 | ||
1674 | /* rx_chain is after tx_chain, so offset is descr + tx_count */ | 1674 | /* rx_chain is after tx_chain, so offset is descr + tx_count */ |
1675 | if (spider_net_init_chain(card, &card->rx_chain, | 1675 | if (spider_net_init_chain(card, &card->rx_chain, |
1676 | card->descr + card->tx_desc, | 1676 | card->descr + card->num_tx_desc, |
1677 | PCI_DMA_FROMDEVICE, card->rx_desc)) | 1677 | PCI_DMA_FROMDEVICE, card->num_rx_desc)) |
1678 | goto alloc_rx_failed; | 1678 | goto alloc_rx_failed; |
1679 | 1679 | ||
1680 | /* allocate rx skbs */ | 1680 | /* allocate rx skbs */ |
1681 | if (spider_net_alloc_rx_skbs(card)) | 1681 | if (spider_net_alloc_rx_skbs(card)) |
1682 | goto alloc_skbs_failed; | 1682 | goto alloc_skbs_failed; |
1683 | 1683 | ||
1684 | spider_net_set_multi(netdev); | 1684 | spider_net_set_multi(netdev); |
1685 | 1685 | ||
1686 | /* further enhancement: setup hw vlan, if needed */ | 1686 | /* further enhancement: setup hw vlan, if needed */ |
1687 | 1687 | ||
1688 | result = -EBUSY; | 1688 | result = -EBUSY; |
1689 | if (request_irq(netdev->irq, spider_net_interrupt, | 1689 | if (request_irq(netdev->irq, spider_net_interrupt, |
1690 | IRQF_SHARED, netdev->name, netdev)) | 1690 | IRQF_SHARED, netdev->name, netdev)) |
1691 | goto register_int_failed; | 1691 | goto register_int_failed; |
1692 | 1692 | ||
1693 | spider_net_enable_card(card); | 1693 | spider_net_enable_card(card); |
1694 | 1694 | ||
1695 | netif_start_queue(netdev); | 1695 | netif_start_queue(netdev); |
1696 | netif_carrier_on(netdev); | 1696 | netif_carrier_on(netdev); |
1697 | netif_poll_enable(netdev); | 1697 | netif_poll_enable(netdev); |
1698 | 1698 | ||
1699 | return 0; | 1699 | return 0; |
1700 | 1700 | ||
1701 | register_int_failed: | 1701 | register_int_failed: |
1702 | spider_net_free_rx_chain_contents(card); | 1702 | spider_net_free_rx_chain_contents(card); |
1703 | alloc_skbs_failed: | 1703 | alloc_skbs_failed: |
1704 | spider_net_free_chain(card, &card->rx_chain); | 1704 | spider_net_free_chain(card, &card->rx_chain); |
1705 | alloc_rx_failed: | 1705 | alloc_rx_failed: |
1706 | spider_net_free_chain(card, &card->tx_chain); | 1706 | spider_net_free_chain(card, &card->tx_chain); |
1707 | alloc_tx_failed: | 1707 | alloc_tx_failed: |
1708 | return result; | 1708 | return result; |
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | /** | 1711 | /** |
1712 | * spider_net_setup_phy - setup PHY | 1712 | * spider_net_setup_phy - setup PHY |
1713 | * @card: card structure | 1713 | * @card: card structure |
1714 | * | 1714 | * |
1715 | * returns 0 on success, <0 on failure | 1715 | * returns 0 on success, <0 on failure |
1716 | * | 1716 | * |
1717 | * spider_net_setup_phy is used as part of spider_net_probe. Sets | 1717 | * spider_net_setup_phy is used as part of spider_net_probe. Sets |
1718 | * the PHY to 1000 Mbps | 1718 | * the PHY to 1000 Mbps |
1719 | **/ | 1719 | **/ |
1720 | static int | 1720 | static int |
1721 | spider_net_setup_phy(struct spider_net_card *card) | 1721 | spider_net_setup_phy(struct spider_net_card *card) |
1722 | { | 1722 | { |
1723 | struct mii_phy *phy = &card->phy; | 1723 | struct mii_phy *phy = &card->phy; |
1724 | 1724 | ||
1725 | spider_net_write_reg(card, SPIDER_NET_GDTDMASEL, | 1725 | spider_net_write_reg(card, SPIDER_NET_GDTDMASEL, |
1726 | SPIDER_NET_DMASEL_VALUE); | 1726 | SPIDER_NET_DMASEL_VALUE); |
1727 | spider_net_write_reg(card, SPIDER_NET_GPCCTRL, | 1727 | spider_net_write_reg(card, SPIDER_NET_GPCCTRL, |
1728 | SPIDER_NET_PHY_CTRL_VALUE); | 1728 | SPIDER_NET_PHY_CTRL_VALUE); |
1729 | phy->mii_id = 1; | 1729 | phy->mii_id = 1; |
1730 | phy->dev = card->netdev; | 1730 | phy->dev = card->netdev; |
1731 | phy->mdio_read = spider_net_read_phy; | 1731 | phy->mdio_read = spider_net_read_phy; |
1732 | phy->mdio_write = spider_net_write_phy; | 1732 | phy->mdio_write = spider_net_write_phy; |
1733 | 1733 | ||
1734 | mii_phy_probe(phy, phy->mii_id); | 1734 | mii_phy_probe(phy, phy->mii_id); |
1735 | 1735 | ||
1736 | if (phy->def->ops->setup_forced) | 1736 | if (phy->def->ops->setup_forced) |
1737 | phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); | 1737 | phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); |
1738 | 1738 | ||
1739 | phy->def->ops->enable_fiber(phy); | 1739 | phy->def->ops->enable_fiber(phy); |
1740 | 1740 | ||
1741 | phy->def->ops->read_link(phy); | 1741 | phy->def->ops->read_link(phy); |
1742 | pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, | 1742 | pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, |
1743 | phy->speed, phy->duplex==1 ? "Full" : "Half"); | 1743 | phy->speed, phy->duplex==1 ? "Full" : "Half"); |
1744 | 1744 | ||
1745 | return 0; | 1745 | return 0; |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | /** | 1748 | /** |
1749 | * spider_net_download_firmware - loads firmware into the adapter | 1749 | * spider_net_download_firmware - loads firmware into the adapter |
1750 | * @card: card structure | 1750 | * @card: card structure |
1751 | * @firmware_ptr: pointer to firmware data | 1751 | * @firmware_ptr: pointer to firmware data |
1752 | * | 1752 | * |
1753 | * spider_net_download_firmware loads the firmware data into the | 1753 | * spider_net_download_firmware loads the firmware data into the |
1754 | * adapter. It assumes the length etc. to be allright. | 1754 | * adapter. It assumes the length etc. to be allright. |
1755 | */ | 1755 | */ |
1756 | static int | 1756 | static int |
1757 | spider_net_download_firmware(struct spider_net_card *card, | 1757 | spider_net_download_firmware(struct spider_net_card *card, |
1758 | const void *firmware_ptr) | 1758 | const void *firmware_ptr) |
1759 | { | 1759 | { |
1760 | int sequencer, i; | 1760 | int sequencer, i; |
1761 | const u32 *fw_ptr = firmware_ptr; | 1761 | const u32 *fw_ptr = firmware_ptr; |
1762 | 1762 | ||
1763 | /* stop sequencers */ | 1763 | /* stop sequencers */ |
1764 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | 1764 | spider_net_write_reg(card, SPIDER_NET_GSINIT, |
1765 | SPIDER_NET_STOP_SEQ_VALUE); | 1765 | SPIDER_NET_STOP_SEQ_VALUE); |
1766 | 1766 | ||
1767 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; | 1767 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; |
1768 | sequencer++) { | 1768 | sequencer++) { |
1769 | spider_net_write_reg(card, | 1769 | spider_net_write_reg(card, |
1770 | SPIDER_NET_GSnPRGADR + sequencer * 8, 0); | 1770 | SPIDER_NET_GSnPRGADR + sequencer * 8, 0); |
1771 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { | 1771 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { |
1772 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | 1772 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + |
1773 | sequencer * 8, *fw_ptr); | 1773 | sequencer * 8, *fw_ptr); |
1774 | fw_ptr++; | 1774 | fw_ptr++; |
1775 | } | 1775 | } |
1776 | } | 1776 | } |
1777 | 1777 | ||
1778 | if (spider_net_read_reg(card, SPIDER_NET_GSINIT)) | 1778 | if (spider_net_read_reg(card, SPIDER_NET_GSINIT)) |
1779 | return -EIO; | 1779 | return -EIO; |
1780 | 1780 | ||
1781 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | 1781 | spider_net_write_reg(card, SPIDER_NET_GSINIT, |
1782 | SPIDER_NET_RUN_SEQ_VALUE); | 1782 | SPIDER_NET_RUN_SEQ_VALUE); |
1783 | 1783 | ||
1784 | return 0; | 1784 | return 0; |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | /** | 1787 | /** |
1788 | * spider_net_init_firmware - reads in firmware parts | 1788 | * spider_net_init_firmware - reads in firmware parts |
1789 | * @card: card structure | 1789 | * @card: card structure |
1790 | * | 1790 | * |
1791 | * Returns 0 on success, <0 on failure | 1791 | * Returns 0 on success, <0 on failure |
1792 | * | 1792 | * |
1793 | * spider_net_init_firmware opens the sequencer firmware and does some basic | 1793 | * spider_net_init_firmware opens the sequencer firmware and does some basic |
1794 | * checks. This function opens and releases the firmware structure. A call | 1794 | * checks. This function opens and releases the firmware structure. A call |
1795 | * to download the firmware is performed before the release. | 1795 | * to download the firmware is performed before the release. |
1796 | * | 1796 | * |
1797 | * Firmware format | 1797 | * Firmware format |
1798 | * =============== | 1798 | * =============== |
1799 | * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being | 1799 | * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being |
1800 | * the program for each sequencer. Use the command | 1800 | * the program for each sequencer. Use the command |
1801 | * tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt \ | 1801 | * tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt \ |
1802 | * Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt \ | 1802 | * Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt \ |
1803 | * Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin | 1803 | * Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin |
1804 | * | 1804 | * |
1805 | * to generate spider_fw.bin, if you have sequencer programs with something | 1805 | * to generate spider_fw.bin, if you have sequencer programs with something |
1806 | * like the following contents for each sequencer: | 1806 | * like the following contents for each sequencer: |
1807 | * <ONE LINE COMMENT> | 1807 | * <ONE LINE COMMENT> |
1808 | * <FIRST 4-BYTES-WORD FOR SEQUENCER> | 1808 | * <FIRST 4-BYTES-WORD FOR SEQUENCER> |
1809 | * <SECOND 4-BYTES-WORD FOR SEQUENCER> | 1809 | * <SECOND 4-BYTES-WORD FOR SEQUENCER> |
1810 | * ... | 1810 | * ... |
1811 | * <1024th 4-BYTES-WORD FOR SEQUENCER> | 1811 | * <1024th 4-BYTES-WORD FOR SEQUENCER> |
1812 | */ | 1812 | */ |
1813 | static int | 1813 | static int |
1814 | spider_net_init_firmware(struct spider_net_card *card) | 1814 | spider_net_init_firmware(struct spider_net_card *card) |
1815 | { | 1815 | { |
1816 | struct firmware *firmware = NULL; | 1816 | struct firmware *firmware = NULL; |
1817 | struct device_node *dn; | 1817 | struct device_node *dn; |
1818 | const u8 *fw_prop = NULL; | 1818 | const u8 *fw_prop = NULL; |
1819 | int err = -ENOENT; | 1819 | int err = -ENOENT; |
1820 | int fw_size; | 1820 | int fw_size; |
1821 | 1821 | ||
1822 | if (request_firmware((const struct firmware **)&firmware, | 1822 | if (request_firmware((const struct firmware **)&firmware, |
1823 | SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { | 1823 | SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { |
1824 | if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && | 1824 | if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && |
1825 | netif_msg_probe(card) ) { | 1825 | netif_msg_probe(card) ) { |
1826 | pr_err("Incorrect size of spidernet firmware in " \ | 1826 | pr_err("Incorrect size of spidernet firmware in " \ |
1827 | "filesystem. Looking in host firmware...\n"); | 1827 | "filesystem. Looking in host firmware...\n"); |
1828 | goto try_host_fw; | 1828 | goto try_host_fw; |
1829 | } | 1829 | } |
1830 | err = spider_net_download_firmware(card, firmware->data); | 1830 | err = spider_net_download_firmware(card, firmware->data); |
1831 | 1831 | ||
1832 | release_firmware(firmware); | 1832 | release_firmware(firmware); |
1833 | if (err) | 1833 | if (err) |
1834 | goto try_host_fw; | 1834 | goto try_host_fw; |
1835 | 1835 | ||
1836 | goto done; | 1836 | goto done; |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | try_host_fw: | 1839 | try_host_fw: |
1840 | dn = pci_device_to_OF_node(card->pdev); | 1840 | dn = pci_device_to_OF_node(card->pdev); |
1841 | if (!dn) | 1841 | if (!dn) |
1842 | goto out_err; | 1842 | goto out_err; |
1843 | 1843 | ||
1844 | fw_prop = get_property(dn, "firmware", &fw_size); | 1844 | fw_prop = get_property(dn, "firmware", &fw_size); |
1845 | if (!fw_prop) | 1845 | if (!fw_prop) |
1846 | goto out_err; | 1846 | goto out_err; |
1847 | 1847 | ||
1848 | if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && | 1848 | if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && |
1849 | netif_msg_probe(card) ) { | 1849 | netif_msg_probe(card) ) { |
1850 | pr_err("Incorrect size of spidernet firmware in " \ | 1850 | pr_err("Incorrect size of spidernet firmware in " \ |
1851 | "host firmware\n"); | 1851 | "host firmware\n"); |
1852 | goto done; | 1852 | goto done; |
1853 | } | 1853 | } |
1854 | 1854 | ||
1855 | err = spider_net_download_firmware(card, fw_prop); | 1855 | err = spider_net_download_firmware(card, fw_prop); |
1856 | 1856 | ||
1857 | done: | 1857 | done: |
1858 | return err; | 1858 | return err; |
1859 | out_err: | 1859 | out_err: |
1860 | if (netif_msg_probe(card)) | 1860 | if (netif_msg_probe(card)) |
1861 | pr_err("Couldn't find spidernet firmware in filesystem " \ | 1861 | pr_err("Couldn't find spidernet firmware in filesystem " \ |
1862 | "or host firmware\n"); | 1862 | "or host firmware\n"); |
1863 | return err; | 1863 | return err; |
1864 | } | 1864 | } |
1865 | 1865 | ||
1866 | /** | 1866 | /** |
1867 | * spider_net_workaround_rxramfull - work around firmware bug | 1867 | * spider_net_workaround_rxramfull - work around firmware bug |
1868 | * @card: card structure | 1868 | * @card: card structure |
1869 | * | 1869 | * |
1870 | * no return value | 1870 | * no return value |
1871 | **/ | 1871 | **/ |
1872 | static void | 1872 | static void |
1873 | spider_net_workaround_rxramfull(struct spider_net_card *card) | 1873 | spider_net_workaround_rxramfull(struct spider_net_card *card) |
1874 | { | 1874 | { |
1875 | int i, sequencer = 0; | 1875 | int i, sequencer = 0; |
1876 | 1876 | ||
1877 | /* cancel reset */ | 1877 | /* cancel reset */ |
1878 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 1878 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
1879 | SPIDER_NET_CKRCTRL_RUN_VALUE); | 1879 | SPIDER_NET_CKRCTRL_RUN_VALUE); |
1880 | 1880 | ||
1881 | /* empty sequencer data */ | 1881 | /* empty sequencer data */ |
1882 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; | 1882 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; |
1883 | sequencer++) { | 1883 | sequencer++) { |
1884 | spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + | 1884 | spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + |
1885 | sequencer * 8, 0x0); | 1885 | sequencer * 8, 0x0); |
1886 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { | 1886 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { |
1887 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | 1887 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + |
1888 | sequencer * 8, 0x0); | 1888 | sequencer * 8, 0x0); |
1889 | } | 1889 | } |
1890 | } | 1890 | } |
1891 | 1891 | ||
1892 | /* set sequencer operation */ | 1892 | /* set sequencer operation */ |
1893 | spider_net_write_reg(card, SPIDER_NET_GSINIT, 0x000000fe); | 1893 | spider_net_write_reg(card, SPIDER_NET_GSINIT, 0x000000fe); |
1894 | 1894 | ||
1895 | /* reset */ | 1895 | /* reset */ |
1896 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 1896 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
1897 | SPIDER_NET_CKRCTRL_STOP_VALUE); | 1897 | SPIDER_NET_CKRCTRL_STOP_VALUE); |
1898 | } | 1898 | } |
1899 | 1899 | ||
1900 | /** | 1900 | /** |
1901 | * spider_net_stop - called upon ifconfig down | 1901 | * spider_net_stop - called upon ifconfig down |
1902 | * @netdev: interface device structure | 1902 | * @netdev: interface device structure |
1903 | * | 1903 | * |
1904 | * always returns 0 | 1904 | * always returns 0 |
1905 | */ | 1905 | */ |
1906 | int | 1906 | int |
1907 | spider_net_stop(struct net_device *netdev) | 1907 | spider_net_stop(struct net_device *netdev) |
1908 | { | 1908 | { |
1909 | struct spider_net_card *card = netdev_priv(netdev); | 1909 | struct spider_net_card *card = netdev_priv(netdev); |
1910 | 1910 | ||
1911 | tasklet_kill(&card->rxram_full_tl); | 1911 | tasklet_kill(&card->rxram_full_tl); |
1912 | netif_poll_disable(netdev); | 1912 | netif_poll_disable(netdev); |
1913 | netif_carrier_off(netdev); | 1913 | netif_carrier_off(netdev); |
1914 | netif_stop_queue(netdev); | 1914 | netif_stop_queue(netdev); |
1915 | del_timer_sync(&card->tx_timer); | 1915 | del_timer_sync(&card->tx_timer); |
1916 | 1916 | ||
1917 | /* disable/mask all interrupts */ | 1917 | /* disable/mask all interrupts */ |
1918 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); | 1918 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); |
1919 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); | 1919 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); |
1920 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); | 1920 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); |
1921 | 1921 | ||
1922 | /* free_irq(netdev->irq, netdev);*/ | 1922 | /* free_irq(netdev->irq, netdev);*/ |
1923 | free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); | 1923 | free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); |
1924 | 1924 | ||
1925 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 1925 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
1926 | SPIDER_NET_DMA_TX_FEND_VALUE); | 1926 | SPIDER_NET_DMA_TX_FEND_VALUE); |
1927 | 1927 | ||
1928 | /* turn off DMA, force end */ | 1928 | /* turn off DMA, force end */ |
1929 | spider_net_disable_rxdmac(card); | 1929 | spider_net_disable_rxdmac(card); |
1930 | 1930 | ||
1931 | /* release chains */ | 1931 | /* release chains */ |
1932 | spider_net_release_tx_chain(card, 1); | 1932 | spider_net_release_tx_chain(card, 1); |
1933 | 1933 | ||
1934 | spider_net_free_chain(card, &card->tx_chain); | 1934 | spider_net_free_chain(card, &card->tx_chain); |
1935 | spider_net_free_chain(card, &card->rx_chain); | 1935 | spider_net_free_chain(card, &card->rx_chain); |
1936 | 1936 | ||
1937 | return 0; | 1937 | return 0; |
1938 | } | 1938 | } |
1939 | 1939 | ||
1940 | /** | 1940 | /** |
1941 | * spider_net_tx_timeout_task - task scheduled by the watchdog timeout | 1941 | * spider_net_tx_timeout_task - task scheduled by the watchdog timeout |
1942 | * function (to be called not under interrupt status) | 1942 | * function (to be called not under interrupt status) |
1943 | * @data: data, is interface device structure | 1943 | * @data: data, is interface device structure |
1944 | * | 1944 | * |
1945 | * called as task when tx hangs, resets interface (if interface is up) | 1945 | * called as task when tx hangs, resets interface (if interface is up) |
1946 | */ | 1946 | */ |
1947 | static void | 1947 | static void |
1948 | spider_net_tx_timeout_task(void *data) | 1948 | spider_net_tx_timeout_task(void *data) |
1949 | { | 1949 | { |
1950 | struct net_device *netdev = data; | 1950 | struct net_device *netdev = data; |
1951 | struct spider_net_card *card = netdev_priv(netdev); | 1951 | struct spider_net_card *card = netdev_priv(netdev); |
1952 | 1952 | ||
1953 | if (!(netdev->flags & IFF_UP)) | 1953 | if (!(netdev->flags & IFF_UP)) |
1954 | goto out; | 1954 | goto out; |
1955 | 1955 | ||
1956 | netif_device_detach(netdev); | 1956 | netif_device_detach(netdev); |
1957 | spider_net_stop(netdev); | 1957 | spider_net_stop(netdev); |
1958 | 1958 | ||
1959 | spider_net_workaround_rxramfull(card); | 1959 | spider_net_workaround_rxramfull(card); |
1960 | spider_net_init_card(card); | 1960 | spider_net_init_card(card); |
1961 | 1961 | ||
1962 | if (spider_net_setup_phy(card)) | 1962 | if (spider_net_setup_phy(card)) |
1963 | goto out; | 1963 | goto out; |
1964 | if (spider_net_init_firmware(card)) | 1964 | if (spider_net_init_firmware(card)) |
1965 | goto out; | 1965 | goto out; |
1966 | 1966 | ||
1967 | spider_net_open(netdev); | 1967 | spider_net_open(netdev); |
1968 | spider_net_kick_tx_dma(card); | 1968 | spider_net_kick_tx_dma(card); |
1969 | netif_device_attach(netdev); | 1969 | netif_device_attach(netdev); |
1970 | 1970 | ||
1971 | out: | 1971 | out: |
1972 | atomic_dec(&card->tx_timeout_task_counter); | 1972 | atomic_dec(&card->tx_timeout_task_counter); |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | /** | 1975 | /** |
1976 | * spider_net_tx_timeout - called when the tx timeout watchdog kicks in. | 1976 | * spider_net_tx_timeout - called when the tx timeout watchdog kicks in. |
1977 | * @netdev: interface device structure | 1977 | * @netdev: interface device structure |
1978 | * | 1978 | * |
1979 | * called, if tx hangs. Schedules a task that resets the interface | 1979 | * called, if tx hangs. Schedules a task that resets the interface |
1980 | */ | 1980 | */ |
1981 | static void | 1981 | static void |
1982 | spider_net_tx_timeout(struct net_device *netdev) | 1982 | spider_net_tx_timeout(struct net_device *netdev) |
1983 | { | 1983 | { |
1984 | struct spider_net_card *card; | 1984 | struct spider_net_card *card; |
1985 | 1985 | ||
1986 | card = netdev_priv(netdev); | 1986 | card = netdev_priv(netdev); |
1987 | atomic_inc(&card->tx_timeout_task_counter); | 1987 | atomic_inc(&card->tx_timeout_task_counter); |
1988 | if (netdev->flags & IFF_UP) | 1988 | if (netdev->flags & IFF_UP) |
1989 | schedule_work(&card->tx_timeout_task); | 1989 | schedule_work(&card->tx_timeout_task); |
1990 | else | 1990 | else |
1991 | atomic_dec(&card->tx_timeout_task_counter); | 1991 | atomic_dec(&card->tx_timeout_task_counter); |
1992 | card->spider_stats.tx_timeouts++; | 1992 | card->spider_stats.tx_timeouts++; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | /** | 1995 | /** |
1996 | * spider_net_setup_netdev_ops - initialization of net_device operations | 1996 | * spider_net_setup_netdev_ops - initialization of net_device operations |
1997 | * @netdev: net_device structure | 1997 | * @netdev: net_device structure |
1998 | * | 1998 | * |
1999 | * fills out function pointers in the net_device structure | 1999 | * fills out function pointers in the net_device structure |
2000 | */ | 2000 | */ |
2001 | static void | 2001 | static void |
2002 | spider_net_setup_netdev_ops(struct net_device *netdev) | 2002 | spider_net_setup_netdev_ops(struct net_device *netdev) |
2003 | { | 2003 | { |
2004 | netdev->open = &spider_net_open; | 2004 | netdev->open = &spider_net_open; |
2005 | netdev->stop = &spider_net_stop; | 2005 | netdev->stop = &spider_net_stop; |
2006 | netdev->hard_start_xmit = &spider_net_xmit; | 2006 | netdev->hard_start_xmit = &spider_net_xmit; |
2007 | netdev->get_stats = &spider_net_get_stats; | 2007 | netdev->get_stats = &spider_net_get_stats; |
2008 | netdev->set_multicast_list = &spider_net_set_multi; | 2008 | netdev->set_multicast_list = &spider_net_set_multi; |
2009 | netdev->set_mac_address = &spider_net_set_mac; | 2009 | netdev->set_mac_address = &spider_net_set_mac; |
2010 | netdev->change_mtu = &spider_net_change_mtu; | 2010 | netdev->change_mtu = &spider_net_change_mtu; |
2011 | netdev->do_ioctl = &spider_net_do_ioctl; | 2011 | netdev->do_ioctl = &spider_net_do_ioctl; |
2012 | /* tx watchdog */ | 2012 | /* tx watchdog */ |
2013 | netdev->tx_timeout = &spider_net_tx_timeout; | 2013 | netdev->tx_timeout = &spider_net_tx_timeout; |
2014 | netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT; | 2014 | netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT; |
2015 | /* NAPI */ | 2015 | /* NAPI */ |
2016 | netdev->poll = &spider_net_poll; | 2016 | netdev->poll = &spider_net_poll; |
2017 | netdev->weight = SPIDER_NET_NAPI_WEIGHT; | 2017 | netdev->weight = SPIDER_NET_NAPI_WEIGHT; |
2018 | /* HW VLAN */ | 2018 | /* HW VLAN */ |
2019 | netdev->vlan_rx_register = &spider_net_vlan_rx_reg; | 2019 | netdev->vlan_rx_register = &spider_net_vlan_rx_reg; |
2020 | netdev->vlan_rx_add_vid = &spider_net_vlan_rx_add; | 2020 | netdev->vlan_rx_add_vid = &spider_net_vlan_rx_add; |
2021 | netdev->vlan_rx_kill_vid = &spider_net_vlan_rx_kill; | 2021 | netdev->vlan_rx_kill_vid = &spider_net_vlan_rx_kill; |
2022 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2022 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2023 | /* poll controller */ | 2023 | /* poll controller */ |
2024 | netdev->poll_controller = &spider_net_poll_controller; | 2024 | netdev->poll_controller = &spider_net_poll_controller; |
2025 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 2025 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
2026 | /* ethtool ops */ | 2026 | /* ethtool ops */ |
2027 | netdev->ethtool_ops = &spider_net_ethtool_ops; | 2027 | netdev->ethtool_ops = &spider_net_ethtool_ops; |
2028 | } | 2028 | } |
2029 | 2029 | ||
2030 | /** | 2030 | /** |
2031 | * spider_net_setup_netdev - initialization of net_device | 2031 | * spider_net_setup_netdev - initialization of net_device |
2032 | * @card: card structure | 2032 | * @card: card structure |
2033 | * | 2033 | * |
2034 | * Returns 0 on success or <0 on failure | 2034 | * Returns 0 on success or <0 on failure |
2035 | * | 2035 | * |
2036 | * spider_net_setup_netdev initializes the net_device structure | 2036 | * spider_net_setup_netdev initializes the net_device structure |
2037 | **/ | 2037 | **/ |
2038 | static int | 2038 | static int |
2039 | spider_net_setup_netdev(struct spider_net_card *card) | 2039 | spider_net_setup_netdev(struct spider_net_card *card) |
2040 | { | 2040 | { |
2041 | int result; | 2041 | int result; |
2042 | struct net_device *netdev = card->netdev; | 2042 | struct net_device *netdev = card->netdev; |
2043 | struct device_node *dn; | 2043 | struct device_node *dn; |
2044 | struct sockaddr addr; | 2044 | struct sockaddr addr; |
2045 | const u8 *mac; | 2045 | const u8 *mac; |
2046 | 2046 | ||
2047 | SET_MODULE_OWNER(netdev); | 2047 | SET_MODULE_OWNER(netdev); |
2048 | SET_NETDEV_DEV(netdev, &card->pdev->dev); | 2048 | SET_NETDEV_DEV(netdev, &card->pdev->dev); |
2049 | 2049 | ||
2050 | pci_set_drvdata(card->pdev, netdev); | 2050 | pci_set_drvdata(card->pdev, netdev); |
2051 | 2051 | ||
2052 | card->rxram_full_tl.data = (unsigned long) card; | 2052 | card->rxram_full_tl.data = (unsigned long) card; |
2053 | card->rxram_full_tl.func = | 2053 | card->rxram_full_tl.func = |
2054 | (void (*)(unsigned long)) spider_net_handle_rxram_full; | 2054 | (void (*)(unsigned long)) spider_net_handle_rxram_full; |
2055 | init_timer(&card->tx_timer); | 2055 | init_timer(&card->tx_timer); |
2056 | card->tx_timer.function = | 2056 | card->tx_timer.function = |
2057 | (void (*)(unsigned long)) spider_net_cleanup_tx_ring; | 2057 | (void (*)(unsigned long)) spider_net_cleanup_tx_ring; |
2058 | card->tx_timer.data = (unsigned long) card; | 2058 | card->tx_timer.data = (unsigned long) card; |
2059 | netdev->irq = card->pdev->irq; | 2059 | netdev->irq = card->pdev->irq; |
2060 | 2060 | ||
2061 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2061 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
2062 | 2062 | ||
2063 | card->tx_desc = tx_descriptors; | 2063 | card->num_tx_desc = tx_descriptors; |
2064 | card->rx_desc = rx_descriptors; | 2064 | card->num_rx_desc = rx_descriptors; |
2065 | 2065 | ||
2066 | spider_net_setup_netdev_ops(netdev); | 2066 | spider_net_setup_netdev_ops(netdev); |
2067 | 2067 | ||
2068 | netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; | 2068 | netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; |
2069 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | | 2069 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | |
2070 | * NETIF_F_HW_VLAN_FILTER */ | 2070 | * NETIF_F_HW_VLAN_FILTER */ |
2071 | 2071 | ||
2072 | netdev->irq = card->pdev->irq; | 2072 | netdev->irq = card->pdev->irq; |
2073 | 2073 | ||
2074 | dn = pci_device_to_OF_node(card->pdev); | 2074 | dn = pci_device_to_OF_node(card->pdev); |
2075 | if (!dn) | 2075 | if (!dn) |
2076 | return -EIO; | 2076 | return -EIO; |
2077 | 2077 | ||
2078 | mac = get_property(dn, "local-mac-address", NULL); | 2078 | mac = get_property(dn, "local-mac-address", NULL); |
2079 | if (!mac) | 2079 | if (!mac) |
2080 | return -EIO; | 2080 | return -EIO; |
2081 | memcpy(addr.sa_data, mac, ETH_ALEN); | 2081 | memcpy(addr.sa_data, mac, ETH_ALEN); |
2082 | 2082 | ||
2083 | result = spider_net_set_mac(netdev, &addr); | 2083 | result = spider_net_set_mac(netdev, &addr); |
2084 | if ((result) && (netif_msg_probe(card))) | 2084 | if ((result) && (netif_msg_probe(card))) |
2085 | pr_err("Failed to set MAC address: %i\n", result); | 2085 | pr_err("Failed to set MAC address: %i\n", result); |
2086 | 2086 | ||
2087 | result = register_netdev(netdev); | 2087 | result = register_netdev(netdev); |
2088 | if (result) { | 2088 | if (result) { |
2089 | if (netif_msg_probe(card)) | 2089 | if (netif_msg_probe(card)) |
2090 | pr_err("Couldn't register net_device: %i\n", | 2090 | pr_err("Couldn't register net_device: %i\n", |
2091 | result); | 2091 | result); |
2092 | return result; | 2092 | return result; |
2093 | } | 2093 | } |
2094 | 2094 | ||
2095 | if (netif_msg_probe(card)) | 2095 | if (netif_msg_probe(card)) |
2096 | pr_info("Initialized device %s.\n", netdev->name); | 2096 | pr_info("Initialized device %s.\n", netdev->name); |
2097 | 2097 | ||
2098 | return 0; | 2098 | return 0; |
2099 | } | 2099 | } |
2100 | 2100 | ||
2101 | /** | 2101 | /** |
2102 | * spider_net_alloc_card - allocates net_device and card structure | 2102 | * spider_net_alloc_card - allocates net_device and card structure |
2103 | * | 2103 | * |
2104 | * returns the card structure or NULL in case of errors | 2104 | * returns the card structure or NULL in case of errors |
2105 | * | 2105 | * |
2106 | * the card and net_device structures are linked to each other | 2106 | * the card and net_device structures are linked to each other |
2107 | */ | 2107 | */ |
2108 | static struct spider_net_card * | 2108 | static struct spider_net_card * |
2109 | spider_net_alloc_card(void) | 2109 | spider_net_alloc_card(void) |
2110 | { | 2110 | { |
2111 | struct net_device *netdev; | 2111 | struct net_device *netdev; |
2112 | struct spider_net_card *card; | 2112 | struct spider_net_card *card; |
2113 | size_t alloc_size; | 2113 | size_t alloc_size; |
2114 | 2114 | ||
2115 | alloc_size = sizeof (*card) + | 2115 | alloc_size = sizeof (*card) + |
2116 | sizeof (struct spider_net_descr) * rx_descriptors + | 2116 | sizeof (struct spider_net_descr) * rx_descriptors + |
2117 | sizeof (struct spider_net_descr) * tx_descriptors; | 2117 | sizeof (struct spider_net_descr) * tx_descriptors; |
2118 | netdev = alloc_etherdev(alloc_size); | 2118 | netdev = alloc_etherdev(alloc_size); |
2119 | if (!netdev) | 2119 | if (!netdev) |
2120 | return NULL; | 2120 | return NULL; |
2121 | 2121 | ||
2122 | card = netdev_priv(netdev); | 2122 | card = netdev_priv(netdev); |
2123 | card->netdev = netdev; | 2123 | card->netdev = netdev; |
2124 | card->msg_enable = SPIDER_NET_DEFAULT_MSG; | 2124 | card->msg_enable = SPIDER_NET_DEFAULT_MSG; |
2125 | INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev); | 2125 | INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev); |
2126 | init_waitqueue_head(&card->waitq); | 2126 | init_waitqueue_head(&card->waitq); |
2127 | atomic_set(&card->tx_timeout_task_counter, 0); | 2127 | atomic_set(&card->tx_timeout_task_counter, 0); |
2128 | 2128 | ||
2129 | return card; | 2129 | return card; |
2130 | } | 2130 | } |
2131 | 2131 | ||
2132 | /** | 2132 | /** |
2133 | * spider_net_undo_pci_setup - releases PCI ressources | 2133 | * spider_net_undo_pci_setup - releases PCI ressources |
2134 | * @card: card structure | 2134 | * @card: card structure |
2135 | * | 2135 | * |
2136 | * spider_net_undo_pci_setup releases the mapped regions | 2136 | * spider_net_undo_pci_setup releases the mapped regions |
2137 | */ | 2137 | */ |
2138 | static void | 2138 | static void |
2139 | spider_net_undo_pci_setup(struct spider_net_card *card) | 2139 | spider_net_undo_pci_setup(struct spider_net_card *card) |
2140 | { | 2140 | { |
2141 | iounmap(card->regs); | 2141 | iounmap(card->regs); |
2142 | pci_release_regions(card->pdev); | 2142 | pci_release_regions(card->pdev); |
2143 | } | 2143 | } |
2144 | 2144 | ||
2145 | /** | 2145 | /** |
2146 | * spider_net_setup_pci_dev - sets up the device in terms of PCI operations | 2146 | * spider_net_setup_pci_dev - sets up the device in terms of PCI operations |
2147 | * @card: card structure | 2147 | * @card: card structure |
2148 | * @pdev: PCI device | 2148 | * @pdev: PCI device |
2149 | * | 2149 | * |
2150 | * Returns the card structure or NULL if any errors occur | 2150 | * Returns the card structure or NULL if any errors occur |
2151 | * | 2151 | * |
2152 | * spider_net_setup_pci_dev initializes pdev and together with the | 2152 | * spider_net_setup_pci_dev initializes pdev and together with the |
2153 | * functions called in spider_net_open configures the device so that | 2153 | * functions called in spider_net_open configures the device so that |
2154 | * data can be transferred over it | 2154 | * data can be transferred over it |
2155 | * The net_device structure is attached to the card structure, if the | 2155 | * The net_device structure is attached to the card structure, if the |
2156 | * function returns without error. | 2156 | * function returns without error. |
2157 | **/ | 2157 | **/ |
2158 | static struct spider_net_card * | 2158 | static struct spider_net_card * |
2159 | spider_net_setup_pci_dev(struct pci_dev *pdev) | 2159 | spider_net_setup_pci_dev(struct pci_dev *pdev) |
2160 | { | 2160 | { |
2161 | struct spider_net_card *card; | 2161 | struct spider_net_card *card; |
2162 | unsigned long mmio_start, mmio_len; | 2162 | unsigned long mmio_start, mmio_len; |
2163 | 2163 | ||
2164 | if (pci_enable_device(pdev)) { | 2164 | if (pci_enable_device(pdev)) { |
2165 | pr_err("Couldn't enable PCI device\n"); | 2165 | pr_err("Couldn't enable PCI device\n"); |
2166 | return NULL; | 2166 | return NULL; |
2167 | } | 2167 | } |
2168 | 2168 | ||
2169 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 2169 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
2170 | pr_err("Couldn't find proper PCI device base address.\n"); | 2170 | pr_err("Couldn't find proper PCI device base address.\n"); |
2171 | goto out_disable_dev; | 2171 | goto out_disable_dev; |
2172 | } | 2172 | } |
2173 | 2173 | ||
2174 | if (pci_request_regions(pdev, spider_net_driver_name)) { | 2174 | if (pci_request_regions(pdev, spider_net_driver_name)) { |
2175 | pr_err("Couldn't obtain PCI resources, aborting.\n"); | 2175 | pr_err("Couldn't obtain PCI resources, aborting.\n"); |
2176 | goto out_disable_dev; | 2176 | goto out_disable_dev; |
2177 | } | 2177 | } |
2178 | 2178 | ||
2179 | pci_set_master(pdev); | 2179 | pci_set_master(pdev); |
2180 | 2180 | ||
2181 | card = spider_net_alloc_card(); | 2181 | card = spider_net_alloc_card(); |
2182 | if (!card) { | 2182 | if (!card) { |
2183 | pr_err("Couldn't allocate net_device structure, " | 2183 | pr_err("Couldn't allocate net_device structure, " |
2184 | "aborting.\n"); | 2184 | "aborting.\n"); |
2185 | goto out_release_regions; | 2185 | goto out_release_regions; |
2186 | } | 2186 | } |
2187 | card->pdev = pdev; | 2187 | card->pdev = pdev; |
2188 | 2188 | ||
2189 | /* fetch base address and length of first resource */ | 2189 | /* fetch base address and length of first resource */ |
2190 | mmio_start = pci_resource_start(pdev, 0); | 2190 | mmio_start = pci_resource_start(pdev, 0); |
2191 | mmio_len = pci_resource_len(pdev, 0); | 2191 | mmio_len = pci_resource_len(pdev, 0); |
2192 | 2192 | ||
2193 | card->netdev->mem_start = mmio_start; | 2193 | card->netdev->mem_start = mmio_start; |
2194 | card->netdev->mem_end = mmio_start + mmio_len; | 2194 | card->netdev->mem_end = mmio_start + mmio_len; |
2195 | card->regs = ioremap(mmio_start, mmio_len); | 2195 | card->regs = ioremap(mmio_start, mmio_len); |
2196 | 2196 | ||
2197 | if (!card->regs) { | 2197 | if (!card->regs) { |
2198 | pr_err("Couldn't obtain PCI resources, aborting.\n"); | 2198 | pr_err("Couldn't obtain PCI resources, aborting.\n"); |
2199 | goto out_release_regions; | 2199 | goto out_release_regions; |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | return card; | 2202 | return card; |
2203 | 2203 | ||
2204 | out_release_regions: | 2204 | out_release_regions: |
2205 | pci_release_regions(pdev); | 2205 | pci_release_regions(pdev); |
2206 | out_disable_dev: | 2206 | out_disable_dev: |
2207 | pci_disable_device(pdev); | 2207 | pci_disable_device(pdev); |
2208 | pci_set_drvdata(pdev, NULL); | 2208 | pci_set_drvdata(pdev, NULL); |
2209 | return NULL; | 2209 | return NULL; |
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | /** | 2212 | /** |
2213 | * spider_net_probe - initialization of a device | 2213 | * spider_net_probe - initialization of a device |
2214 | * @pdev: PCI device | 2214 | * @pdev: PCI device |
2215 | * @ent: entry in the device id list | 2215 | * @ent: entry in the device id list |
2216 | * | 2216 | * |
2217 | * Returns 0 on success, <0 on failure | 2217 | * Returns 0 on success, <0 on failure |
2218 | * | 2218 | * |
2219 | * spider_net_probe initializes pdev and registers a net_device | 2219 | * spider_net_probe initializes pdev and registers a net_device |
2220 | * structure for it. After that, the device can be ifconfig'ed up | 2220 | * structure for it. After that, the device can be ifconfig'ed up |
2221 | **/ | 2221 | **/ |
2222 | static int __devinit | 2222 | static int __devinit |
2223 | spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 2223 | spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
2224 | { | 2224 | { |
2225 | int err = -EIO; | 2225 | int err = -EIO; |
2226 | struct spider_net_card *card; | 2226 | struct spider_net_card *card; |
2227 | 2227 | ||
2228 | card = spider_net_setup_pci_dev(pdev); | 2228 | card = spider_net_setup_pci_dev(pdev); |
2229 | if (!card) | 2229 | if (!card) |
2230 | goto out; | 2230 | goto out; |
2231 | 2231 | ||
2232 | spider_net_workaround_rxramfull(card); | 2232 | spider_net_workaround_rxramfull(card); |
2233 | spider_net_init_card(card); | 2233 | spider_net_init_card(card); |
2234 | 2234 | ||
2235 | err = spider_net_setup_phy(card); | 2235 | err = spider_net_setup_phy(card); |
2236 | if (err) | 2236 | if (err) |
2237 | goto out_undo_pci; | 2237 | goto out_undo_pci; |
2238 | 2238 | ||
2239 | err = spider_net_init_firmware(card); | 2239 | err = spider_net_init_firmware(card); |
2240 | if (err) | 2240 | if (err) |
2241 | goto out_undo_pci; | 2241 | goto out_undo_pci; |
2242 | 2242 | ||
2243 | err = spider_net_setup_netdev(card); | 2243 | err = spider_net_setup_netdev(card); |
2244 | if (err) | 2244 | if (err) |
2245 | goto out_undo_pci; | 2245 | goto out_undo_pci; |
2246 | 2246 | ||
2247 | return 0; | 2247 | return 0; |
2248 | 2248 | ||
2249 | out_undo_pci: | 2249 | out_undo_pci: |
2250 | spider_net_undo_pci_setup(card); | 2250 | spider_net_undo_pci_setup(card); |
2251 | free_netdev(card->netdev); | 2251 | free_netdev(card->netdev); |
2252 | out: | 2252 | out: |
2253 | return err; | 2253 | return err; |
2254 | } | 2254 | } |
2255 | 2255 | ||
2256 | /** | 2256 | /** |
2257 | * spider_net_remove - removal of a device | 2257 | * spider_net_remove - removal of a device |
2258 | * @pdev: PCI device | 2258 | * @pdev: PCI device |
2259 | * | 2259 | * |
2260 | * Returns 0 on success, <0 on failure | 2260 | * Returns 0 on success, <0 on failure |
2261 | * | 2261 | * |
2262 | * spider_net_remove is called to remove the device and unregisters the | 2262 | * spider_net_remove is called to remove the device and unregisters the |
2263 | * net_device | 2263 | * net_device |
2264 | **/ | 2264 | **/ |
2265 | static void __devexit | 2265 | static void __devexit |
2266 | spider_net_remove(struct pci_dev *pdev) | 2266 | spider_net_remove(struct pci_dev *pdev) |
2267 | { | 2267 | { |
2268 | struct net_device *netdev; | 2268 | struct net_device *netdev; |
2269 | struct spider_net_card *card; | 2269 | struct spider_net_card *card; |
2270 | 2270 | ||
2271 | netdev = pci_get_drvdata(pdev); | 2271 | netdev = pci_get_drvdata(pdev); |
2272 | card = netdev_priv(netdev); | 2272 | card = netdev_priv(netdev); |
2273 | 2273 | ||
2274 | wait_event(card->waitq, | 2274 | wait_event(card->waitq, |
2275 | atomic_read(&card->tx_timeout_task_counter) == 0); | 2275 | atomic_read(&card->tx_timeout_task_counter) == 0); |
2276 | 2276 | ||
2277 | unregister_netdev(netdev); | 2277 | unregister_netdev(netdev); |
2278 | 2278 | ||
2279 | /* switch off card */ | 2279 | /* switch off card */ |
2280 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 2280 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
2281 | SPIDER_NET_CKRCTRL_STOP_VALUE); | 2281 | SPIDER_NET_CKRCTRL_STOP_VALUE); |
2282 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 2282 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
2283 | SPIDER_NET_CKRCTRL_RUN_VALUE); | 2283 | SPIDER_NET_CKRCTRL_RUN_VALUE); |
2284 | 2284 | ||
2285 | spider_net_undo_pci_setup(card); | 2285 | spider_net_undo_pci_setup(card); |
2286 | free_netdev(netdev); | 2286 | free_netdev(netdev); |
2287 | } | 2287 | } |
2288 | 2288 | ||
2289 | static struct pci_driver spider_net_driver = { | 2289 | static struct pci_driver spider_net_driver = { |
2290 | .name = spider_net_driver_name, | 2290 | .name = spider_net_driver_name, |
2291 | .id_table = spider_net_pci_tbl, | 2291 | .id_table = spider_net_pci_tbl, |
2292 | .probe = spider_net_probe, | 2292 | .probe = spider_net_probe, |
2293 | .remove = __devexit_p(spider_net_remove) | 2293 | .remove = __devexit_p(spider_net_remove) |
2294 | }; | 2294 | }; |
2295 | 2295 | ||
2296 | /** | 2296 | /** |
2297 | * spider_net_init - init function when the driver is loaded | 2297 | * spider_net_init - init function when the driver is loaded |
2298 | * | 2298 | * |
2299 | * spider_net_init registers the device driver | 2299 | * spider_net_init registers the device driver |
2300 | */ | 2300 | */ |
2301 | static int __init spider_net_init(void) | 2301 | static int __init spider_net_init(void) |
2302 | { | 2302 | { |
2303 | printk(KERN_INFO "Spidernet version %s.\n", VERSION); | 2303 | printk(KERN_INFO "Spidernet version %s.\n", VERSION); |
2304 | 2304 | ||
2305 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { | 2305 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { |
2306 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; | 2306 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; |
2307 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | 2307 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); |
2308 | } | 2308 | } |
2309 | if (rx_descriptors > SPIDER_NET_RX_DESCRIPTORS_MAX) { | 2309 | if (rx_descriptors > SPIDER_NET_RX_DESCRIPTORS_MAX) { |
2310 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MAX; | 2310 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MAX; |
2311 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | 2311 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); |
2312 | } | 2312 | } |
2313 | if (tx_descriptors < SPIDER_NET_TX_DESCRIPTORS_MIN) { | 2313 | if (tx_descriptors < SPIDER_NET_TX_DESCRIPTORS_MIN) { |
2314 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MIN; | 2314 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MIN; |
2315 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); | 2315 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); |
2316 | } | 2316 | } |
2317 | if (tx_descriptors > SPIDER_NET_TX_DESCRIPTORS_MAX) { | 2317 | if (tx_descriptors > SPIDER_NET_TX_DESCRIPTORS_MAX) { |
2318 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MAX; | 2318 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MAX; |
2319 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); | 2319 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); |
2320 | } | 2320 | } |
2321 | 2321 | ||
2322 | return pci_register_driver(&spider_net_driver); | 2322 | return pci_register_driver(&spider_net_driver); |
2323 | } | 2323 | } |
2324 | 2324 | ||
2325 | /** | 2325 | /** |
2326 | * spider_net_cleanup - exit function when driver is unloaded | 2326 | * spider_net_cleanup - exit function when driver is unloaded |
2327 | * | 2327 | * |
2328 | * spider_net_cleanup unregisters the device driver | 2328 | * spider_net_cleanup unregisters the device driver |
2329 | */ | 2329 | */ |
2330 | static void __exit spider_net_cleanup(void) | 2330 | static void __exit spider_net_cleanup(void) |
2331 | { | 2331 | { |
2332 | pci_unregister_driver(&spider_net_driver); | 2332 | pci_unregister_driver(&spider_net_driver); |
2333 | } | 2333 | } |
2334 | 2334 | ||
2335 | module_init(spider_net_init); | 2335 | module_init(spider_net_init); |
2336 | module_exit(spider_net_cleanup); | 2336 | module_exit(spider_net_cleanup); |
2337 | 2337 |
drivers/net/spider_net.h
1 | /* | 1 | /* |
2 | * Network device driver for Cell Processor-Based Blade | 2 | * Network device driver for Cell Processor-Based Blade |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * | 5 | * |
6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> |
7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2, or (at your option) | 11 | * the Free Software Foundation; either version 2, or (at your option) |
12 | * any later version. | 12 | * any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef _SPIDER_NET_H | 24 | #ifndef _SPIDER_NET_H |
25 | #define _SPIDER_NET_H | 25 | #define _SPIDER_NET_H |
26 | 26 | ||
27 | #define VERSION "1.1 A" | 27 | #define VERSION "1.1 A" |
28 | 28 | ||
29 | #include "sungem_phy.h" | 29 | #include "sungem_phy.h" |
30 | 30 | ||
31 | extern int spider_net_stop(struct net_device *netdev); | 31 | extern int spider_net_stop(struct net_device *netdev); |
32 | extern int spider_net_open(struct net_device *netdev); | 32 | extern int spider_net_open(struct net_device *netdev); |
33 | 33 | ||
34 | extern const struct ethtool_ops spider_net_ethtool_ops; | 34 | extern const struct ethtool_ops spider_net_ethtool_ops; |
35 | 35 | ||
36 | extern char spider_net_driver_name[]; | 36 | extern char spider_net_driver_name[]; |
37 | 37 | ||
38 | #define SPIDER_NET_MAX_FRAME 2312 | 38 | #define SPIDER_NET_MAX_FRAME 2312 |
39 | #define SPIDER_NET_MAX_MTU 2294 | 39 | #define SPIDER_NET_MAX_MTU 2294 |
40 | #define SPIDER_NET_MIN_MTU 64 | 40 | #define SPIDER_NET_MIN_MTU 64 |
41 | 41 | ||
42 | #define SPIDER_NET_RXBUF_ALIGN 128 | 42 | #define SPIDER_NET_RXBUF_ALIGN 128 |
43 | 43 | ||
44 | #define SPIDER_NET_RX_DESCRIPTORS_DEFAULT 256 | 44 | #define SPIDER_NET_RX_DESCRIPTORS_DEFAULT 256 |
45 | #define SPIDER_NET_RX_DESCRIPTORS_MIN 16 | 45 | #define SPIDER_NET_RX_DESCRIPTORS_MIN 16 |
46 | #define SPIDER_NET_RX_DESCRIPTORS_MAX 512 | 46 | #define SPIDER_NET_RX_DESCRIPTORS_MAX 512 |
47 | 47 | ||
48 | #define SPIDER_NET_TX_DESCRIPTORS_DEFAULT 256 | 48 | #define SPIDER_NET_TX_DESCRIPTORS_DEFAULT 256 |
49 | #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 | 49 | #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 |
50 | #define SPIDER_NET_TX_DESCRIPTORS_MAX 512 | 50 | #define SPIDER_NET_TX_DESCRIPTORS_MAX 512 |
51 | 51 | ||
52 | #define SPIDER_NET_TX_TIMER (HZ/5) | 52 | #define SPIDER_NET_TX_TIMER (HZ/5) |
53 | 53 | ||
54 | #define SPIDER_NET_RX_CSUM_DEFAULT 1 | 54 | #define SPIDER_NET_RX_CSUM_DEFAULT 1 |
55 | 55 | ||
56 | #define SPIDER_NET_WATCHDOG_TIMEOUT 50*HZ | 56 | #define SPIDER_NET_WATCHDOG_TIMEOUT 50*HZ |
57 | #define SPIDER_NET_NAPI_WEIGHT 64 | 57 | #define SPIDER_NET_NAPI_WEIGHT 64 |
58 | 58 | ||
59 | #define SPIDER_NET_FIRMWARE_SEQS 6 | 59 | #define SPIDER_NET_FIRMWARE_SEQS 6 |
60 | #define SPIDER_NET_FIRMWARE_SEQWORDS 1024 | 60 | #define SPIDER_NET_FIRMWARE_SEQWORDS 1024 |
61 | #define SPIDER_NET_FIRMWARE_LEN (SPIDER_NET_FIRMWARE_SEQS * \ | 61 | #define SPIDER_NET_FIRMWARE_LEN (SPIDER_NET_FIRMWARE_SEQS * \ |
62 | SPIDER_NET_FIRMWARE_SEQWORDS * \ | 62 | SPIDER_NET_FIRMWARE_SEQWORDS * \ |
63 | sizeof(u32)) | 63 | sizeof(u32)) |
64 | #define SPIDER_NET_FIRMWARE_NAME "spider_fw.bin" | 64 | #define SPIDER_NET_FIRMWARE_NAME "spider_fw.bin" |
65 | 65 | ||
66 | /** spider_net SMMIO registers */ | 66 | /** spider_net SMMIO registers */ |
67 | #define SPIDER_NET_GHIINT0STS 0x00000000 | 67 | #define SPIDER_NET_GHIINT0STS 0x00000000 |
68 | #define SPIDER_NET_GHIINT1STS 0x00000004 | 68 | #define SPIDER_NET_GHIINT1STS 0x00000004 |
69 | #define SPIDER_NET_GHIINT2STS 0x00000008 | 69 | #define SPIDER_NET_GHIINT2STS 0x00000008 |
70 | #define SPIDER_NET_GHIINT0MSK 0x00000010 | 70 | #define SPIDER_NET_GHIINT0MSK 0x00000010 |
71 | #define SPIDER_NET_GHIINT1MSK 0x00000014 | 71 | #define SPIDER_NET_GHIINT1MSK 0x00000014 |
72 | #define SPIDER_NET_GHIINT2MSK 0x00000018 | 72 | #define SPIDER_NET_GHIINT2MSK 0x00000018 |
73 | 73 | ||
74 | #define SPIDER_NET_GRESUMINTNUM 0x00000020 | 74 | #define SPIDER_NET_GRESUMINTNUM 0x00000020 |
75 | #define SPIDER_NET_GREINTNUM 0x00000024 | 75 | #define SPIDER_NET_GREINTNUM 0x00000024 |
76 | 76 | ||
77 | #define SPIDER_NET_GFFRMNUM 0x00000028 | 77 | #define SPIDER_NET_GFFRMNUM 0x00000028 |
78 | #define SPIDER_NET_GFAFRMNUM 0x0000002c | 78 | #define SPIDER_NET_GFAFRMNUM 0x0000002c |
79 | #define SPIDER_NET_GFBFRMNUM 0x00000030 | 79 | #define SPIDER_NET_GFBFRMNUM 0x00000030 |
80 | #define SPIDER_NET_GFCFRMNUM 0x00000034 | 80 | #define SPIDER_NET_GFCFRMNUM 0x00000034 |
81 | #define SPIDER_NET_GFDFRMNUM 0x00000038 | 81 | #define SPIDER_NET_GFDFRMNUM 0x00000038 |
82 | 82 | ||
83 | /* clear them (don't use it) */ | 83 | /* clear them (don't use it) */ |
84 | #define SPIDER_NET_GFREECNNUM 0x0000003c | 84 | #define SPIDER_NET_GFREECNNUM 0x0000003c |
85 | #define SPIDER_NET_GONETIMENUM 0x00000040 | 85 | #define SPIDER_NET_GONETIMENUM 0x00000040 |
86 | 86 | ||
87 | #define SPIDER_NET_GTOUTFRMNUM 0x00000044 | 87 | #define SPIDER_NET_GTOUTFRMNUM 0x00000044 |
88 | 88 | ||
89 | #define SPIDER_NET_GTXMDSET 0x00000050 | 89 | #define SPIDER_NET_GTXMDSET 0x00000050 |
90 | #define SPIDER_NET_GPCCTRL 0x00000054 | 90 | #define SPIDER_NET_GPCCTRL 0x00000054 |
91 | #define SPIDER_NET_GRXMDSET 0x00000058 | 91 | #define SPIDER_NET_GRXMDSET 0x00000058 |
92 | #define SPIDER_NET_GIPSECINIT 0x0000005c | 92 | #define SPIDER_NET_GIPSECINIT 0x0000005c |
93 | #define SPIDER_NET_GFTRESTRT 0x00000060 | 93 | #define SPIDER_NET_GFTRESTRT 0x00000060 |
94 | #define SPIDER_NET_GRXDMAEN 0x00000064 | 94 | #define SPIDER_NET_GRXDMAEN 0x00000064 |
95 | #define SPIDER_NET_GMRWOLCTRL 0x00000068 | 95 | #define SPIDER_NET_GMRWOLCTRL 0x00000068 |
96 | #define SPIDER_NET_GPCWOPCMD 0x0000006c | 96 | #define SPIDER_NET_GPCWOPCMD 0x0000006c |
97 | #define SPIDER_NET_GPCROPCMD 0x00000070 | 97 | #define SPIDER_NET_GPCROPCMD 0x00000070 |
98 | #define SPIDER_NET_GTTFRMCNT 0x00000078 | 98 | #define SPIDER_NET_GTTFRMCNT 0x00000078 |
99 | #define SPIDER_NET_GTESTMD 0x0000007c | 99 | #define SPIDER_NET_GTESTMD 0x0000007c |
100 | 100 | ||
101 | #define SPIDER_NET_GSINIT 0x00000080 | 101 | #define SPIDER_NET_GSINIT 0x00000080 |
102 | #define SPIDER_NET_GSnPRGADR 0x00000084 | 102 | #define SPIDER_NET_GSnPRGADR 0x00000084 |
103 | #define SPIDER_NET_GSnPRGDAT 0x00000088 | 103 | #define SPIDER_NET_GSnPRGDAT 0x00000088 |
104 | 104 | ||
105 | #define SPIDER_NET_GMACOPEMD 0x00000100 | 105 | #define SPIDER_NET_GMACOPEMD 0x00000100 |
106 | #define SPIDER_NET_GMACLENLMT 0x00000108 | 106 | #define SPIDER_NET_GMACLENLMT 0x00000108 |
107 | #define SPIDER_NET_GMACINTEN 0x00000118 | 107 | #define SPIDER_NET_GMACINTEN 0x00000118 |
108 | #define SPIDER_NET_GMACPHYCTRL 0x00000120 | 108 | #define SPIDER_NET_GMACPHYCTRL 0x00000120 |
109 | 109 | ||
110 | #define SPIDER_NET_GMACAPAUSE 0x00000154 | 110 | #define SPIDER_NET_GMACAPAUSE 0x00000154 |
111 | #define SPIDER_NET_GMACTXPAUSE 0x00000164 | 111 | #define SPIDER_NET_GMACTXPAUSE 0x00000164 |
112 | 112 | ||
113 | #define SPIDER_NET_GMACMODE 0x000001b0 | 113 | #define SPIDER_NET_GMACMODE 0x000001b0 |
114 | #define SPIDER_NET_GMACBSTLMT 0x000001b4 | 114 | #define SPIDER_NET_GMACBSTLMT 0x000001b4 |
115 | 115 | ||
116 | #define SPIDER_NET_GMACUNIMACU 0x000001c0 | 116 | #define SPIDER_NET_GMACUNIMACU 0x000001c0 |
117 | #define SPIDER_NET_GMACUNIMACL 0x000001c8 | 117 | #define SPIDER_NET_GMACUNIMACL 0x000001c8 |
118 | 118 | ||
119 | #define SPIDER_NET_GMRMHFILnR 0x00000400 | 119 | #define SPIDER_NET_GMRMHFILnR 0x00000400 |
120 | #define SPIDER_NET_MULTICAST_HASHES 256 | 120 | #define SPIDER_NET_MULTICAST_HASHES 256 |
121 | 121 | ||
122 | #define SPIDER_NET_GMRUAFILnR 0x00000500 | 122 | #define SPIDER_NET_GMRUAFILnR 0x00000500 |
123 | #define SPIDER_NET_GMRUA0FIL15R 0x00000578 | 123 | #define SPIDER_NET_GMRUA0FIL15R 0x00000578 |
124 | 124 | ||
125 | #define SPIDER_NET_GTTQMSK 0x00000934 | 125 | #define SPIDER_NET_GTTQMSK 0x00000934 |
126 | 126 | ||
127 | /* RX DMA controller registers, all 0x00000a.. are for DMA controller A, | 127 | /* RX DMA controller registers, all 0x00000a.. are for DMA controller A, |
128 | * 0x00000b.. for DMA controller B, etc. */ | 128 | * 0x00000b.. for DMA controller B, etc. */ |
129 | #define SPIDER_NET_GDADCHA 0x00000a00 | 129 | #define SPIDER_NET_GDADCHA 0x00000a00 |
130 | #define SPIDER_NET_GDADMACCNTR 0x00000a04 | 130 | #define SPIDER_NET_GDADMACCNTR 0x00000a04 |
131 | #define SPIDER_NET_GDACTDPA 0x00000a08 | 131 | #define SPIDER_NET_GDACTDPA 0x00000a08 |
132 | #define SPIDER_NET_GDACTDCNT 0x00000a0c | 132 | #define SPIDER_NET_GDACTDCNT 0x00000a0c |
133 | #define SPIDER_NET_GDACDBADDR 0x00000a20 | 133 | #define SPIDER_NET_GDACDBADDR 0x00000a20 |
134 | #define SPIDER_NET_GDACDBSIZE 0x00000a24 | 134 | #define SPIDER_NET_GDACDBSIZE 0x00000a24 |
135 | #define SPIDER_NET_GDACNEXTDA 0x00000a28 | 135 | #define SPIDER_NET_GDACNEXTDA 0x00000a28 |
136 | #define SPIDER_NET_GDACCOMST 0x00000a2c | 136 | #define SPIDER_NET_GDACCOMST 0x00000a2c |
137 | #define SPIDER_NET_GDAWBCOMST 0x00000a30 | 137 | #define SPIDER_NET_GDAWBCOMST 0x00000a30 |
138 | #define SPIDER_NET_GDAWBRSIZE 0x00000a34 | 138 | #define SPIDER_NET_GDAWBRSIZE 0x00000a34 |
139 | #define SPIDER_NET_GDAWBVSIZE 0x00000a38 | 139 | #define SPIDER_NET_GDAWBVSIZE 0x00000a38 |
140 | #define SPIDER_NET_GDAWBTRST 0x00000a3c | 140 | #define SPIDER_NET_GDAWBTRST 0x00000a3c |
141 | #define SPIDER_NET_GDAWBTRERR 0x00000a40 | 141 | #define SPIDER_NET_GDAWBTRERR 0x00000a40 |
142 | 142 | ||
143 | /* TX DMA controller registers */ | 143 | /* TX DMA controller registers */ |
144 | #define SPIDER_NET_GDTDCHA 0x00000e00 | 144 | #define SPIDER_NET_GDTDCHA 0x00000e00 |
145 | #define SPIDER_NET_GDTDMACCNTR 0x00000e04 | 145 | #define SPIDER_NET_GDTDMACCNTR 0x00000e04 |
146 | #define SPIDER_NET_GDTCDPA 0x00000e08 | 146 | #define SPIDER_NET_GDTCDPA 0x00000e08 |
147 | #define SPIDER_NET_GDTDMASEL 0x00000e14 | 147 | #define SPIDER_NET_GDTDMASEL 0x00000e14 |
148 | 148 | ||
149 | #define SPIDER_NET_ECMODE 0x00000f00 | 149 | #define SPIDER_NET_ECMODE 0x00000f00 |
150 | /* clock and reset control register */ | 150 | /* clock and reset control register */ |
151 | #define SPIDER_NET_CKRCTRL 0x00000ff0 | 151 | #define SPIDER_NET_CKRCTRL 0x00000ff0 |
152 | 152 | ||
153 | /** SCONFIG registers */ | 153 | /** SCONFIG registers */ |
154 | #define SPIDER_NET_SCONFIG_IOACTE 0x00002810 | 154 | #define SPIDER_NET_SCONFIG_IOACTE 0x00002810 |
155 | 155 | ||
156 | /** interrupt mask registers */ | 156 | /** interrupt mask registers */ |
157 | #define SPIDER_NET_INT0_MASK_VALUE 0x3f7fe2c7 | 157 | #define SPIDER_NET_INT0_MASK_VALUE 0x3f7fe2c7 |
158 | #define SPIDER_NET_INT1_MASK_VALUE 0xffff7ff7 | 158 | #define SPIDER_NET_INT1_MASK_VALUE 0xffff7ff7 |
159 | /* no MAC aborts -> auto retransmission */ | 159 | /* no MAC aborts -> auto retransmission */ |
160 | #define SPIDER_NET_INT2_MASK_VALUE 0xffef7ff1 | 160 | #define SPIDER_NET_INT2_MASK_VALUE 0xffef7ff1 |
161 | 161 | ||
162 | /* we rely on flagged descriptor interrupts */ | 162 | /* we rely on flagged descriptor interrupts */ |
163 | #define SPIDER_NET_FRAMENUM_VALUE 0x00000000 | 163 | #define SPIDER_NET_FRAMENUM_VALUE 0x00000000 |
164 | /* set this first, then the FRAMENUM_VALUE */ | 164 | /* set this first, then the FRAMENUM_VALUE */ |
165 | #define SPIDER_NET_GFXFRAMES_VALUE 0x00000000 | 165 | #define SPIDER_NET_GFXFRAMES_VALUE 0x00000000 |
166 | 166 | ||
167 | #define SPIDER_NET_STOP_SEQ_VALUE 0x00000000 | 167 | #define SPIDER_NET_STOP_SEQ_VALUE 0x00000000 |
168 | #define SPIDER_NET_RUN_SEQ_VALUE 0x0000007e | 168 | #define SPIDER_NET_RUN_SEQ_VALUE 0x0000007e |
169 | 169 | ||
170 | #define SPIDER_NET_PHY_CTRL_VALUE 0x00040040 | 170 | #define SPIDER_NET_PHY_CTRL_VALUE 0x00040040 |
171 | /* #define SPIDER_NET_PHY_CTRL_VALUE 0x01070080*/ | 171 | /* #define SPIDER_NET_PHY_CTRL_VALUE 0x01070080*/ |
172 | #define SPIDER_NET_RXMODE_VALUE 0x00000011 | 172 | #define SPIDER_NET_RXMODE_VALUE 0x00000011 |
173 | /* auto retransmission in case of MAC aborts */ | 173 | /* auto retransmission in case of MAC aborts */ |
174 | #define SPIDER_NET_TXMODE_VALUE 0x00010000 | 174 | #define SPIDER_NET_TXMODE_VALUE 0x00010000 |
175 | #define SPIDER_NET_RESTART_VALUE 0x00000000 | 175 | #define SPIDER_NET_RESTART_VALUE 0x00000000 |
176 | #define SPIDER_NET_WOL_VALUE 0x00001111 | 176 | #define SPIDER_NET_WOL_VALUE 0x00001111 |
177 | #if 0 | 177 | #if 0 |
178 | #define SPIDER_NET_WOL_VALUE 0x00000000 | 178 | #define SPIDER_NET_WOL_VALUE 0x00000000 |
179 | #endif | 179 | #endif |
180 | #define SPIDER_NET_IPSECINIT_VALUE 0x6f716f71 | 180 | #define SPIDER_NET_IPSECINIT_VALUE 0x6f716f71 |
181 | 181 | ||
182 | /* pause frames: automatic, no upper retransmission count */ | 182 | /* pause frames: automatic, no upper retransmission count */ |
183 | /* outside loopback mode: ETOMOD signal dont matter, not connected */ | 183 | /* outside loopback mode: ETOMOD signal dont matter, not connected */ |
184 | #define SPIDER_NET_OPMODE_VALUE 0x00000063 | 184 | #define SPIDER_NET_OPMODE_VALUE 0x00000063 |
185 | /*#define SPIDER_NET_OPMODE_VALUE 0x001b0062*/ | 185 | /*#define SPIDER_NET_OPMODE_VALUE 0x001b0062*/ |
186 | #define SPIDER_NET_LENLMT_VALUE 0x00000908 | 186 | #define SPIDER_NET_LENLMT_VALUE 0x00000908 |
187 | 187 | ||
188 | #define SPIDER_NET_MACAPAUSE_VALUE 0x00000800 /* about 1 ms */ | 188 | #define SPIDER_NET_MACAPAUSE_VALUE 0x00000800 /* about 1 ms */ |
189 | #define SPIDER_NET_TXPAUSE_VALUE 0x00000000 | 189 | #define SPIDER_NET_TXPAUSE_VALUE 0x00000000 |
190 | 190 | ||
191 | #define SPIDER_NET_MACMODE_VALUE 0x00000001 | 191 | #define SPIDER_NET_MACMODE_VALUE 0x00000001 |
192 | #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ | 192 | #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ |
193 | 193 | ||
194 | /* DMAC control register GDMACCNTR | 194 | /* DMAC control register GDMACCNTR |
195 | * | 195 | * |
196 | * 1(0) enable r/tx dma | 196 | * 1(0) enable r/tx dma |
197 | * 0000000 fixed to 0 | 197 | * 0000000 fixed to 0 |
198 | * | 198 | * |
199 | * 000000 fixed to 0 | 199 | * 000000 fixed to 0 |
200 | * 0(1) en/disable descr writeback on force end | 200 | * 0(1) en/disable descr writeback on force end |
201 | * 0(1) force end | 201 | * 0(1) force end |
202 | * | 202 | * |
203 | * 000000 fixed to 0 | 203 | * 000000 fixed to 0 |
204 | * 00 burst alignment: 128 bytes | 204 | * 00 burst alignment: 128 bytes |
205 | * 11 burst alignment: 1024 bytes | 205 | * 11 burst alignment: 1024 bytes |
206 | * | 206 | * |
207 | * 00000 fixed to 0 | 207 | * 00000 fixed to 0 |
208 | * 0 descr writeback size 32 bytes | 208 | * 0 descr writeback size 32 bytes |
209 | * 0(1) descr chain end interrupt enable | 209 | * 0(1) descr chain end interrupt enable |
210 | * 0(1) descr status writeback enable */ | 210 | * 0(1) descr status writeback enable */ |
211 | 211 | ||
212 | /* to set RX_DMA_EN */ | 212 | /* to set RX_DMA_EN */ |
213 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 | 213 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 |
214 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 | 214 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 |
215 | /* to set TX_DMA_EN */ | 215 | /* to set TX_DMA_EN */ |
216 | #define SPIDER_NET_TX_DMA_EN 0x80000000 | 216 | #define SPIDER_NET_TX_DMA_EN 0x80000000 |
217 | #define SPIDER_NET_GDTBSTA 0x00000300 | 217 | #define SPIDER_NET_GDTBSTA 0x00000300 |
218 | #define SPIDER_NET_GDTDCEIDIS 0x00000002 | 218 | #define SPIDER_NET_GDTDCEIDIS 0x00000002 |
219 | #define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ | 219 | #define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ |
220 | SPIDER_NET_GDTBSTA | \ | 220 | SPIDER_NET_GDTBSTA | \ |
221 | SPIDER_NET_GDTDCEIDIS | 221 | SPIDER_NET_GDTDCEIDIS |
222 | 222 | ||
223 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 | 223 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 |
224 | 224 | ||
225 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ | 225 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ |
226 | #define SPIDER_NET_UA_DESCR_VALUE 0x00080000 | 226 | #define SPIDER_NET_UA_DESCR_VALUE 0x00080000 |
227 | #define SPIDER_NET_PROMISC_VALUE 0x00080000 | 227 | #define SPIDER_NET_PROMISC_VALUE 0x00080000 |
228 | #define SPIDER_NET_NONPROMISC_VALUE 0x00000000 | 228 | #define SPIDER_NET_NONPROMISC_VALUE 0x00000000 |
229 | 229 | ||
230 | #define SPIDER_NET_DMASEL_VALUE 0x00000001 | 230 | #define SPIDER_NET_DMASEL_VALUE 0x00000001 |
231 | 231 | ||
232 | #define SPIDER_NET_ECMODE_VALUE 0x00000000 | 232 | #define SPIDER_NET_ECMODE_VALUE 0x00000000 |
233 | 233 | ||
234 | #define SPIDER_NET_CKRCTRL_RUN_VALUE 0x1fff010f | 234 | #define SPIDER_NET_CKRCTRL_RUN_VALUE 0x1fff010f |
235 | #define SPIDER_NET_CKRCTRL_STOP_VALUE 0x0000010f | 235 | #define SPIDER_NET_CKRCTRL_STOP_VALUE 0x0000010f |
236 | 236 | ||
237 | #define SPIDER_NET_SBIMSTATE_VALUE 0x00000000 | 237 | #define SPIDER_NET_SBIMSTATE_VALUE 0x00000000 |
238 | #define SPIDER_NET_SBTMSTATE_VALUE 0x00000000 | 238 | #define SPIDER_NET_SBTMSTATE_VALUE 0x00000000 |
239 | 239 | ||
240 | /* SPIDER_NET_GHIINT0STS bits, in reverse order so that they can be used | 240 | /* SPIDER_NET_GHIINT0STS bits, in reverse order so that they can be used |
241 | * with 1 << SPIDER_NET_... */ | 241 | * with 1 << SPIDER_NET_... */ |
242 | enum spider_net_int0_status { | 242 | enum spider_net_int0_status { |
243 | SPIDER_NET_GPHYINT = 0, | 243 | SPIDER_NET_GPHYINT = 0, |
244 | SPIDER_NET_GMAC2INT, | 244 | SPIDER_NET_GMAC2INT, |
245 | SPIDER_NET_GMAC1INT, | 245 | SPIDER_NET_GMAC1INT, |
246 | SPIDER_NET_GIPSINT, | 246 | SPIDER_NET_GIPSINT, |
247 | SPIDER_NET_GFIFOINT, | 247 | SPIDER_NET_GFIFOINT, |
248 | SPIDER_NET_GDMACINT, | 248 | SPIDER_NET_GDMACINT, |
249 | SPIDER_NET_GSYSINT, | 249 | SPIDER_NET_GSYSINT, |
250 | SPIDER_NET_GPWOPCMPINT, | 250 | SPIDER_NET_GPWOPCMPINT, |
251 | SPIDER_NET_GPROPCMPINT, | 251 | SPIDER_NET_GPROPCMPINT, |
252 | SPIDER_NET_GPWFFINT, | 252 | SPIDER_NET_GPWFFINT, |
253 | SPIDER_NET_GRMDADRINT, | 253 | SPIDER_NET_GRMDADRINT, |
254 | SPIDER_NET_GRMARPINT, | 254 | SPIDER_NET_GRMARPINT, |
255 | SPIDER_NET_GRMMPINT, | 255 | SPIDER_NET_GRMMPINT, |
256 | SPIDER_NET_GDTDEN0INT, | 256 | SPIDER_NET_GDTDEN0INT, |
257 | SPIDER_NET_GDDDEN0INT, | 257 | SPIDER_NET_GDDDEN0INT, |
258 | SPIDER_NET_GDCDEN0INT, | 258 | SPIDER_NET_GDCDEN0INT, |
259 | SPIDER_NET_GDBDEN0INT, | 259 | SPIDER_NET_GDBDEN0INT, |
260 | SPIDER_NET_GDADEN0INT, | 260 | SPIDER_NET_GDADEN0INT, |
261 | SPIDER_NET_GDTFDCINT, | 261 | SPIDER_NET_GDTFDCINT, |
262 | SPIDER_NET_GDDFDCINT, | 262 | SPIDER_NET_GDDFDCINT, |
263 | SPIDER_NET_GDCFDCINT, | 263 | SPIDER_NET_GDCFDCINT, |
264 | SPIDER_NET_GDBFDCINT, | 264 | SPIDER_NET_GDBFDCINT, |
265 | SPIDER_NET_GDAFDCINT, | 265 | SPIDER_NET_GDAFDCINT, |
266 | SPIDER_NET_GTTEDINT, | 266 | SPIDER_NET_GTTEDINT, |
267 | SPIDER_NET_GDTDCEINT, | 267 | SPIDER_NET_GDTDCEINT, |
268 | SPIDER_NET_GRFDNMINT, | 268 | SPIDER_NET_GRFDNMINT, |
269 | SPIDER_NET_GRFCNMINT, | 269 | SPIDER_NET_GRFCNMINT, |
270 | SPIDER_NET_GRFBNMINT, | 270 | SPIDER_NET_GRFBNMINT, |
271 | SPIDER_NET_GRFANMINT, | 271 | SPIDER_NET_GRFANMINT, |
272 | SPIDER_NET_GRFNMINT, | 272 | SPIDER_NET_GRFNMINT, |
273 | SPIDER_NET_G1TMCNTINT, | 273 | SPIDER_NET_G1TMCNTINT, |
274 | SPIDER_NET_GFREECNTINT | 274 | SPIDER_NET_GFREECNTINT |
275 | }; | 275 | }; |
276 | /* GHIINT1STS bits */ | 276 | /* GHIINT1STS bits */ |
277 | enum spider_net_int1_status { | 277 | enum spider_net_int1_status { |
278 | SPIDER_NET_GTMFLLINT = 0, | 278 | SPIDER_NET_GTMFLLINT = 0, |
279 | SPIDER_NET_GRMFLLINT, | 279 | SPIDER_NET_GRMFLLINT, |
280 | SPIDER_NET_GTMSHTINT, | 280 | SPIDER_NET_GTMSHTINT, |
281 | SPIDER_NET_GDTINVDINT, | 281 | SPIDER_NET_GDTINVDINT, |
282 | SPIDER_NET_GRFDFLLINT, | 282 | SPIDER_NET_GRFDFLLINT, |
283 | SPIDER_NET_GDDDCEINT, | 283 | SPIDER_NET_GDDDCEINT, |
284 | SPIDER_NET_GDDINVDINT, | 284 | SPIDER_NET_GDDINVDINT, |
285 | SPIDER_NET_GRFCFLLINT, | 285 | SPIDER_NET_GRFCFLLINT, |
286 | SPIDER_NET_GDCDCEINT, | 286 | SPIDER_NET_GDCDCEINT, |
287 | SPIDER_NET_GDCINVDINT, | 287 | SPIDER_NET_GDCINVDINT, |
288 | SPIDER_NET_GRFBFLLINT, | 288 | SPIDER_NET_GRFBFLLINT, |
289 | SPIDER_NET_GDBDCEINT, | 289 | SPIDER_NET_GDBDCEINT, |
290 | SPIDER_NET_GDBINVDINT, | 290 | SPIDER_NET_GDBINVDINT, |
291 | SPIDER_NET_GRFAFLLINT, | 291 | SPIDER_NET_GRFAFLLINT, |
292 | SPIDER_NET_GDADCEINT, | 292 | SPIDER_NET_GDADCEINT, |
293 | SPIDER_NET_GDAINVDINT, | 293 | SPIDER_NET_GDAINVDINT, |
294 | SPIDER_NET_GDTRSERINT, | 294 | SPIDER_NET_GDTRSERINT, |
295 | SPIDER_NET_GDDRSERINT, | 295 | SPIDER_NET_GDDRSERINT, |
296 | SPIDER_NET_GDCRSERINT, | 296 | SPIDER_NET_GDCRSERINT, |
297 | SPIDER_NET_GDBRSERINT, | 297 | SPIDER_NET_GDBRSERINT, |
298 | SPIDER_NET_GDARSERINT, | 298 | SPIDER_NET_GDARSERINT, |
299 | SPIDER_NET_GDSERINT, | 299 | SPIDER_NET_GDSERINT, |
300 | SPIDER_NET_GDTPTERINT, | 300 | SPIDER_NET_GDTPTERINT, |
301 | SPIDER_NET_GDDPTERINT, | 301 | SPIDER_NET_GDDPTERINT, |
302 | SPIDER_NET_GDCPTERINT, | 302 | SPIDER_NET_GDCPTERINT, |
303 | SPIDER_NET_GDBPTERINT, | 303 | SPIDER_NET_GDBPTERINT, |
304 | SPIDER_NET_GDAPTERINT | 304 | SPIDER_NET_GDAPTERINT |
305 | }; | 305 | }; |
306 | /* GHIINT2STS bits */ | 306 | /* GHIINT2STS bits */ |
307 | enum spider_net_int2_status { | 307 | enum spider_net_int2_status { |
308 | SPIDER_NET_GPROPERINT = 0, | 308 | SPIDER_NET_GPROPERINT = 0, |
309 | SPIDER_NET_GMCTCRSNGINT, | 309 | SPIDER_NET_GMCTCRSNGINT, |
310 | SPIDER_NET_GMCTLCOLINT, | 310 | SPIDER_NET_GMCTLCOLINT, |
311 | SPIDER_NET_GMCTTMOTINT, | 311 | SPIDER_NET_GMCTTMOTINT, |
312 | SPIDER_NET_GMCRCAERINT, | 312 | SPIDER_NET_GMCRCAERINT, |
313 | SPIDER_NET_GMCRCALERINT, | 313 | SPIDER_NET_GMCRCALERINT, |
314 | SPIDER_NET_GMCRALNERINT, | 314 | SPIDER_NET_GMCRALNERINT, |
315 | SPIDER_NET_GMCROVRINT, | 315 | SPIDER_NET_GMCROVRINT, |
316 | SPIDER_NET_GMCRRNTINT, | 316 | SPIDER_NET_GMCRRNTINT, |
317 | SPIDER_NET_GMCRRXERINT, | 317 | SPIDER_NET_GMCRRXERINT, |
318 | SPIDER_NET_GTITCSERINT, | 318 | SPIDER_NET_GTITCSERINT, |
319 | SPIDER_NET_GTIFMTERINT, | 319 | SPIDER_NET_GTIFMTERINT, |
320 | SPIDER_NET_GTIPKTRVKINT, | 320 | SPIDER_NET_GTIPKTRVKINT, |
321 | SPIDER_NET_GTISPINGINT, | 321 | SPIDER_NET_GTISPINGINT, |
322 | SPIDER_NET_GTISADNGINT, | 322 | SPIDER_NET_GTISADNGINT, |
323 | SPIDER_NET_GTISPDNGINT, | 323 | SPIDER_NET_GTISPDNGINT, |
324 | SPIDER_NET_GRIFMTERINT, | 324 | SPIDER_NET_GRIFMTERINT, |
325 | SPIDER_NET_GRIPKTRVKINT, | 325 | SPIDER_NET_GRIPKTRVKINT, |
326 | SPIDER_NET_GRISPINGINT, | 326 | SPIDER_NET_GRISPINGINT, |
327 | SPIDER_NET_GRISADNGINT, | 327 | SPIDER_NET_GRISADNGINT, |
328 | SPIDER_NET_GRISPDNGINT | 328 | SPIDER_NET_GRISPDNGINT |
329 | }; | 329 | }; |
330 | 330 | ||
331 | #define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GDTFDCINT) ) | 331 | #define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GDTFDCINT) ) |
332 | 332 | ||
333 | /* We rely on flagged descriptor interrupts */ | 333 | /* We rely on flagged descriptor interrupts */ |
334 | #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) ) | 334 | #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) ) |
335 | 335 | ||
336 | #define SPIDER_NET_ERRINT ( 0xffffffff & \ | 336 | #define SPIDER_NET_ERRINT ( 0xffffffff & \ |
337 | (~SPIDER_NET_TXINT) & \ | 337 | (~SPIDER_NET_TXINT) & \ |
338 | (~SPIDER_NET_RXINT) ) | 338 | (~SPIDER_NET_RXINT) ) |
339 | 339 | ||
340 | #define SPIDER_NET_GPREXEC 0x80000000 | 340 | #define SPIDER_NET_GPREXEC 0x80000000 |
341 | #define SPIDER_NET_GPRDAT_MASK 0x0000ffff | 341 | #define SPIDER_NET_GPRDAT_MASK 0x0000ffff |
342 | 342 | ||
343 | #define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 | 343 | #define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 |
344 | #define SPIDER_NET_DMAC_NOCS 0x00040000 | 344 | #define SPIDER_NET_DMAC_NOCS 0x00040000 |
345 | #define SPIDER_NET_DMAC_TCP 0x00020000 | 345 | #define SPIDER_NET_DMAC_TCP 0x00020000 |
346 | #define SPIDER_NET_DMAC_UDP 0x00030000 | 346 | #define SPIDER_NET_DMAC_UDP 0x00030000 |
347 | #define SPIDER_NET_TXDCEST 0x08000000 | 347 | #define SPIDER_NET_TXDCEST 0x08000000 |
348 | 348 | ||
349 | #define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 | 349 | #define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 |
350 | #define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ | 350 | #define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ |
351 | #define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ | 351 | #define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ |
352 | #define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */ | 352 | #define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */ |
353 | #define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */ | 353 | #define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */ |
354 | #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ | 354 | #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ |
355 | #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ | 355 | #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ |
356 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 | 356 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 |
357 | #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 | 357 | #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 |
358 | 358 | ||
359 | struct spider_net_descr { | 359 | struct spider_net_descr { |
360 | /* as defined by the hardware */ | 360 | /* as defined by the hardware */ |
361 | u32 buf_addr; | 361 | u32 buf_addr; |
362 | u32 buf_size; | 362 | u32 buf_size; |
363 | u32 next_descr_addr; | 363 | u32 next_descr_addr; |
364 | u32 dmac_cmd_status; | 364 | u32 dmac_cmd_status; |
365 | u32 result_size; | 365 | u32 result_size; |
366 | u32 valid_size; /* all zeroes for tx */ | 366 | u32 valid_size; /* all zeroes for tx */ |
367 | u32 data_status; | 367 | u32 data_status; |
368 | u32 data_error; /* all zeroes for tx */ | 368 | u32 data_error; /* all zeroes for tx */ |
369 | 369 | ||
370 | /* used in the driver */ | 370 | /* used in the driver */ |
371 | struct sk_buff *skb; | 371 | struct sk_buff *skb; |
372 | u32 bus_addr; | 372 | u32 bus_addr; |
373 | struct spider_net_descr *next; | 373 | struct spider_net_descr *next; |
374 | struct spider_net_descr *prev; | 374 | struct spider_net_descr *prev; |
375 | } __attribute__((aligned(32))); | 375 | } __attribute__((aligned(32))); |
376 | 376 | ||
377 | struct spider_net_descr_chain { | 377 | struct spider_net_descr_chain { |
378 | spinlock_t lock; | 378 | spinlock_t lock; |
379 | struct spider_net_descr *head; | 379 | struct spider_net_descr *head; |
380 | struct spider_net_descr *tail; | 380 | struct spider_net_descr *tail; |
381 | }; | 381 | }; |
382 | 382 | ||
383 | /* descriptor data_status bits */ | 383 | /* descriptor data_status bits */ |
384 | #define SPIDER_NET_RX_IPCHK 29 | 384 | #define SPIDER_NET_RX_IPCHK 29 |
385 | #define SPIDER_NET_RX_TCPCHK 28 | 385 | #define SPIDER_NET_RX_TCPCHK 28 |
386 | #define SPIDER_NET_VLAN_PACKET 21 | 386 | #define SPIDER_NET_VLAN_PACKET 21 |
387 | #define SPIDER_NET_DATA_STATUS_CKSUM_MASK ( (1 << SPIDER_NET_RX_IPCHK) | \ | 387 | #define SPIDER_NET_DATA_STATUS_CKSUM_MASK ( (1 << SPIDER_NET_RX_IPCHK) | \ |
388 | (1 << SPIDER_NET_RX_TCPCHK) ) | 388 | (1 << SPIDER_NET_RX_TCPCHK) ) |
389 | 389 | ||
390 | /* descriptor data_error bits */ | 390 | /* descriptor data_error bits */ |
391 | #define SPIDER_NET_RX_IPCHKERR 27 | 391 | #define SPIDER_NET_RX_IPCHKERR 27 |
392 | #define SPIDER_NET_RX_RXTCPCHKERR 28 | 392 | #define SPIDER_NET_RX_RXTCPCHKERR 28 |
393 | 393 | ||
394 | #define SPIDER_NET_DATA_ERR_CKSUM_MASK (1 << SPIDER_NET_RX_IPCHKERR) | 394 | #define SPIDER_NET_DATA_ERR_CKSUM_MASK (1 << SPIDER_NET_RX_IPCHKERR) |
395 | 395 | ||
396 | /* the cases we don't pass the packet to the stack. | 396 | /* the cases we don't pass the packet to the stack. |
397 | * 701b8000 would be correct, but every packets gets that flag */ | 397 | * 701b8000 would be correct, but every packets gets that flag */ |
398 | #define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000 | 398 | #define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000 |
399 | 399 | ||
400 | #define SPIDER_NET_DESCR_SIZE 32 | 400 | #define SPIDER_NET_DESCR_SIZE 32 |
401 | 401 | ||
402 | /* this will be bigger some time */ | 402 | /* this will be bigger some time */ |
403 | struct spider_net_options { | 403 | struct spider_net_options { |
404 | int rx_csum; /* for rx: if 0 ip_summed=NONE, | 404 | int rx_csum; /* for rx: if 0 ip_summed=NONE, |
405 | if 1 and hw has verified, ip_summed=UNNECESSARY */ | 405 | if 1 and hw has verified, ip_summed=UNNECESSARY */ |
406 | }; | 406 | }; |
407 | 407 | ||
408 | #define SPIDER_NET_DEFAULT_MSG ( NETIF_MSG_DRV | \ | 408 | #define SPIDER_NET_DEFAULT_MSG ( NETIF_MSG_DRV | \ |
409 | NETIF_MSG_PROBE | \ | 409 | NETIF_MSG_PROBE | \ |
410 | NETIF_MSG_LINK | \ | 410 | NETIF_MSG_LINK | \ |
411 | NETIF_MSG_TIMER | \ | 411 | NETIF_MSG_TIMER | \ |
412 | NETIF_MSG_IFDOWN | \ | 412 | NETIF_MSG_IFDOWN | \ |
413 | NETIF_MSG_IFUP | \ | 413 | NETIF_MSG_IFUP | \ |
414 | NETIF_MSG_RX_ERR | \ | 414 | NETIF_MSG_RX_ERR | \ |
415 | NETIF_MSG_TX_ERR | \ | 415 | NETIF_MSG_TX_ERR | \ |
416 | NETIF_MSG_TX_QUEUED | \ | 416 | NETIF_MSG_TX_QUEUED | \ |
417 | NETIF_MSG_INTR | \ | 417 | NETIF_MSG_INTR | \ |
418 | NETIF_MSG_TX_DONE | \ | 418 | NETIF_MSG_TX_DONE | \ |
419 | NETIF_MSG_RX_STATUS | \ | 419 | NETIF_MSG_RX_STATUS | \ |
420 | NETIF_MSG_PKTDATA | \ | 420 | NETIF_MSG_PKTDATA | \ |
421 | NETIF_MSG_HW | \ | 421 | NETIF_MSG_HW | \ |
422 | NETIF_MSG_WOL ) | 422 | NETIF_MSG_WOL ) |
423 | 423 | ||
424 | struct spider_net_extra_stats { | 424 | struct spider_net_extra_stats { |
425 | unsigned long rx_desc_error; | 425 | unsigned long rx_desc_error; |
426 | unsigned long tx_timeouts; | 426 | unsigned long tx_timeouts; |
427 | unsigned long alloc_rx_skb_error; | 427 | unsigned long alloc_rx_skb_error; |
428 | unsigned long rx_iommu_map_error; | 428 | unsigned long rx_iommu_map_error; |
429 | unsigned long tx_iommu_map_error; | 429 | unsigned long tx_iommu_map_error; |
430 | unsigned long rx_desc_unk_state; | 430 | unsigned long rx_desc_unk_state; |
431 | }; | 431 | }; |
432 | 432 | ||
433 | struct spider_net_card { | 433 | struct spider_net_card { |
434 | struct net_device *netdev; | 434 | struct net_device *netdev; |
435 | struct pci_dev *pdev; | 435 | struct pci_dev *pdev; |
436 | struct mii_phy phy; | 436 | struct mii_phy phy; |
437 | 437 | ||
438 | void __iomem *regs; | 438 | void __iomem *regs; |
439 | 439 | ||
440 | struct spider_net_descr_chain tx_chain; | 440 | struct spider_net_descr_chain tx_chain; |
441 | struct spider_net_descr_chain rx_chain; | 441 | struct spider_net_descr_chain rx_chain; |
442 | struct spider_net_descr *low_watermark; | 442 | struct spider_net_descr *low_watermark; |
443 | 443 | ||
444 | struct net_device_stats netdev_stats; | 444 | struct net_device_stats netdev_stats; |
445 | 445 | ||
446 | struct spider_net_options options; | 446 | struct spider_net_options options; |
447 | 447 | ||
448 | spinlock_t intmask_lock; | 448 | spinlock_t intmask_lock; |
449 | struct tasklet_struct rxram_full_tl; | 449 | struct tasklet_struct rxram_full_tl; |
450 | struct timer_list tx_timer; | 450 | struct timer_list tx_timer; |
451 | 451 | ||
452 | struct work_struct tx_timeout_task; | 452 | struct work_struct tx_timeout_task; |
453 | atomic_t tx_timeout_task_counter; | 453 | atomic_t tx_timeout_task_counter; |
454 | wait_queue_head_t waitq; | 454 | wait_queue_head_t waitq; |
455 | 455 | ||
456 | /* for ethtool */ | 456 | /* for ethtool */ |
457 | int msg_enable; | 457 | int msg_enable; |
458 | int rx_desc; | 458 | int num_rx_desc; |
459 | int tx_desc; | 459 | int num_tx_desc; |
460 | struct spider_net_extra_stats spider_stats; | 460 | struct spider_net_extra_stats spider_stats; |
461 | 461 | ||
462 | struct spider_net_descr descr[0]; | 462 | struct spider_net_descr descr[0]; |
463 | }; | 463 | }; |
464 | 464 | ||
465 | #define pr_err(fmt,arg...) \ | 465 | #define pr_err(fmt,arg...) \ |
466 | printk(KERN_ERR fmt ,##arg) | 466 | printk(KERN_ERR fmt ,##arg) |
467 | 467 | ||
468 | #endif | 468 | #endif |
469 | 469 |
drivers/net/spider_net_ethtool.c
1 | /* | 1 | /* |
2 | * Network device driver for Cell Processor-Based Blade | 2 | * Network device driver for Cell Processor-Based Blade |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * | 5 | * |
6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> |
7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2, or (at your option) | 11 | * the Free Software Foundation; either version 2, or (at your option) |
12 | * any later version. | 12 | * any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/netdevice.h> | 24 | #include <linux/netdevice.h> |
25 | #include <linux/ethtool.h> | 25 | #include <linux/ethtool.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | 27 | ||
28 | #include "spider_net.h" | 28 | #include "spider_net.h" |
29 | 29 | ||
30 | 30 | ||
31 | #define SPIDER_NET_NUM_STATS 13 | 31 | #define SPIDER_NET_NUM_STATS 13 |
32 | 32 | ||
33 | static struct { | 33 | static struct { |
34 | const char str[ETH_GSTRING_LEN]; | 34 | const char str[ETH_GSTRING_LEN]; |
35 | } ethtool_stats_keys[] = { | 35 | } ethtool_stats_keys[] = { |
36 | { "tx_packets" }, | 36 | { "tx_packets" }, |
37 | { "tx_bytes" }, | 37 | { "tx_bytes" }, |
38 | { "rx_packets" }, | 38 | { "rx_packets" }, |
39 | { "rx_bytes" }, | 39 | { "rx_bytes" }, |
40 | { "tx_errors" }, | 40 | { "tx_errors" }, |
41 | { "tx_dropped" }, | 41 | { "tx_dropped" }, |
42 | { "rx_dropped" }, | 42 | { "rx_dropped" }, |
43 | { "rx_descriptor_error" }, | 43 | { "rx_descriptor_error" }, |
44 | { "tx_timeouts" }, | 44 | { "tx_timeouts" }, |
45 | { "alloc_rx_skb_error" }, | 45 | { "alloc_rx_skb_error" }, |
46 | { "rx_iommu_map_error" }, | 46 | { "rx_iommu_map_error" }, |
47 | { "tx_iommu_map_error" }, | 47 | { "tx_iommu_map_error" }, |
48 | { "rx_desc_unk_state" }, | 48 | { "rx_desc_unk_state" }, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static int | 51 | static int |
52 | spider_net_ethtool_get_settings(struct net_device *netdev, | 52 | spider_net_ethtool_get_settings(struct net_device *netdev, |
53 | struct ethtool_cmd *cmd) | 53 | struct ethtool_cmd *cmd) |
54 | { | 54 | { |
55 | struct spider_net_card *card; | 55 | struct spider_net_card *card; |
56 | card = netdev_priv(netdev); | 56 | card = netdev_priv(netdev); |
57 | 57 | ||
58 | cmd->supported = (SUPPORTED_1000baseT_Full | | 58 | cmd->supported = (SUPPORTED_1000baseT_Full | |
59 | SUPPORTED_FIBRE); | 59 | SUPPORTED_FIBRE); |
60 | cmd->advertising = (ADVERTISED_1000baseT_Full | | 60 | cmd->advertising = (ADVERTISED_1000baseT_Full | |
61 | ADVERTISED_FIBRE); | 61 | ADVERTISED_FIBRE); |
62 | cmd->port = PORT_FIBRE; | 62 | cmd->port = PORT_FIBRE; |
63 | cmd->speed = card->phy.speed; | 63 | cmd->speed = card->phy.speed; |
64 | cmd->duplex = DUPLEX_FULL; | 64 | cmd->duplex = DUPLEX_FULL; |
65 | 65 | ||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | static void | 69 | static void |
70 | spider_net_ethtool_get_drvinfo(struct net_device *netdev, | 70 | spider_net_ethtool_get_drvinfo(struct net_device *netdev, |
71 | struct ethtool_drvinfo *drvinfo) | 71 | struct ethtool_drvinfo *drvinfo) |
72 | { | 72 | { |
73 | struct spider_net_card *card; | 73 | struct spider_net_card *card; |
74 | card = netdev_priv(netdev); | 74 | card = netdev_priv(netdev); |
75 | 75 | ||
76 | /* clear and fill out info */ | 76 | /* clear and fill out info */ |
77 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); | 77 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
78 | strncpy(drvinfo->driver, spider_net_driver_name, 32); | 78 | strncpy(drvinfo->driver, spider_net_driver_name, 32); |
79 | strncpy(drvinfo->version, VERSION, 32); | 79 | strncpy(drvinfo->version, VERSION, 32); |
80 | strcpy(drvinfo->fw_version, "no information"); | 80 | strcpy(drvinfo->fw_version, "no information"); |
81 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); | 81 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void | 84 | static void |
85 | spider_net_ethtool_get_wol(struct net_device *netdev, | 85 | spider_net_ethtool_get_wol(struct net_device *netdev, |
86 | struct ethtool_wolinfo *wolinfo) | 86 | struct ethtool_wolinfo *wolinfo) |
87 | { | 87 | { |
88 | /* no support for wol */ | 88 | /* no support for wol */ |
89 | wolinfo->supported = 0; | 89 | wolinfo->supported = 0; |
90 | wolinfo->wolopts = 0; | 90 | wolinfo->wolopts = 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static u32 | 93 | static u32 |
94 | spider_net_ethtool_get_msglevel(struct net_device *netdev) | 94 | spider_net_ethtool_get_msglevel(struct net_device *netdev) |
95 | { | 95 | { |
96 | struct spider_net_card *card; | 96 | struct spider_net_card *card; |
97 | card = netdev_priv(netdev); | 97 | card = netdev_priv(netdev); |
98 | return card->msg_enable; | 98 | return card->msg_enable; |
99 | } | 99 | } |
100 | 100 | ||
101 | static void | 101 | static void |
102 | spider_net_ethtool_set_msglevel(struct net_device *netdev, | 102 | spider_net_ethtool_set_msglevel(struct net_device *netdev, |
103 | u32 level) | 103 | u32 level) |
104 | { | 104 | { |
105 | struct spider_net_card *card; | 105 | struct spider_net_card *card; |
106 | card = netdev_priv(netdev); | 106 | card = netdev_priv(netdev); |
107 | card->msg_enable = level; | 107 | card->msg_enable = level; |
108 | } | 108 | } |
109 | 109 | ||
110 | static int | 110 | static int |
111 | spider_net_ethtool_nway_reset(struct net_device *netdev) | 111 | spider_net_ethtool_nway_reset(struct net_device *netdev) |
112 | { | 112 | { |
113 | if (netif_running(netdev)) { | 113 | if (netif_running(netdev)) { |
114 | spider_net_stop(netdev); | 114 | spider_net_stop(netdev); |
115 | spider_net_open(netdev); | 115 | spider_net_open(netdev); |
116 | } | 116 | } |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | static u32 | 120 | static u32 |
121 | spider_net_ethtool_get_rx_csum(struct net_device *netdev) | 121 | spider_net_ethtool_get_rx_csum(struct net_device *netdev) |
122 | { | 122 | { |
123 | struct spider_net_card *card = netdev->priv; | 123 | struct spider_net_card *card = netdev->priv; |
124 | 124 | ||
125 | return card->options.rx_csum; | 125 | return card->options.rx_csum; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int | 128 | static int |
129 | spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) | 129 | spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) |
130 | { | 130 | { |
131 | struct spider_net_card *card = netdev->priv; | 131 | struct spider_net_card *card = netdev->priv; |
132 | 132 | ||
133 | card->options.rx_csum = n; | 133 | card->options.rx_csum = n; |
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | static uint32_t | 137 | static uint32_t |
138 | spider_net_ethtool_get_tx_csum(struct net_device *netdev) | 138 | spider_net_ethtool_get_tx_csum(struct net_device *netdev) |
139 | { | 139 | { |
140 | return (netdev->features & NETIF_F_HW_CSUM) != 0; | 140 | return (netdev->features & NETIF_F_HW_CSUM) != 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int | 143 | static int |
144 | spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data) | 144 | spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data) |
145 | { | 145 | { |
146 | if (data) | 146 | if (data) |
147 | netdev->features |= NETIF_F_HW_CSUM; | 147 | netdev->features |= NETIF_F_HW_CSUM; |
148 | else | 148 | else |
149 | netdev->features &= ~NETIF_F_HW_CSUM; | 149 | netdev->features &= ~NETIF_F_HW_CSUM; |
150 | 150 | ||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | static void | 154 | static void |
155 | spider_net_ethtool_get_ringparam(struct net_device *netdev, | 155 | spider_net_ethtool_get_ringparam(struct net_device *netdev, |
156 | struct ethtool_ringparam *ering) | 156 | struct ethtool_ringparam *ering) |
157 | { | 157 | { |
158 | struct spider_net_card *card = netdev->priv; | 158 | struct spider_net_card *card = netdev->priv; |
159 | 159 | ||
160 | ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; | 160 | ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; |
161 | ering->tx_pending = card->tx_desc; | 161 | ering->tx_pending = card->num_tx_desc; |
162 | ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; | 162 | ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; |
163 | ering->rx_pending = card->rx_desc; | 163 | ering->rx_pending = card->num_rx_desc; |
164 | } | 164 | } |
165 | 165 | ||
166 | static int spider_net_get_stats_count(struct net_device *netdev) | 166 | static int spider_net_get_stats_count(struct net_device *netdev) |
167 | { | 167 | { |
168 | return SPIDER_NET_NUM_STATS; | 168 | return SPIDER_NET_NUM_STATS; |
169 | } | 169 | } |
170 | 170 | ||
171 | static void spider_net_get_ethtool_stats(struct net_device *netdev, | 171 | static void spider_net_get_ethtool_stats(struct net_device *netdev, |
172 | struct ethtool_stats *stats, u64 *data) | 172 | struct ethtool_stats *stats, u64 *data) |
173 | { | 173 | { |
174 | struct spider_net_card *card = netdev->priv; | 174 | struct spider_net_card *card = netdev->priv; |
175 | 175 | ||
176 | data[0] = card->netdev_stats.tx_packets; | 176 | data[0] = card->netdev_stats.tx_packets; |
177 | data[1] = card->netdev_stats.tx_bytes; | 177 | data[1] = card->netdev_stats.tx_bytes; |
178 | data[2] = card->netdev_stats.rx_packets; | 178 | data[2] = card->netdev_stats.rx_packets; |
179 | data[3] = card->netdev_stats.rx_bytes; | 179 | data[3] = card->netdev_stats.rx_bytes; |
180 | data[4] = card->netdev_stats.tx_errors; | 180 | data[4] = card->netdev_stats.tx_errors; |
181 | data[5] = card->netdev_stats.tx_dropped; | 181 | data[5] = card->netdev_stats.tx_dropped; |
182 | data[6] = card->netdev_stats.rx_dropped; | 182 | data[6] = card->netdev_stats.rx_dropped; |
183 | data[7] = card->spider_stats.rx_desc_error; | 183 | data[7] = card->spider_stats.rx_desc_error; |
184 | data[8] = card->spider_stats.tx_timeouts; | 184 | data[8] = card->spider_stats.tx_timeouts; |
185 | data[9] = card->spider_stats.alloc_rx_skb_error; | 185 | data[9] = card->spider_stats.alloc_rx_skb_error; |
186 | data[10] = card->spider_stats.rx_iommu_map_error; | 186 | data[10] = card->spider_stats.rx_iommu_map_error; |
187 | data[11] = card->spider_stats.tx_iommu_map_error; | 187 | data[11] = card->spider_stats.tx_iommu_map_error; |
188 | data[12] = card->spider_stats.rx_desc_unk_state; | 188 | data[12] = card->spider_stats.rx_desc_unk_state; |
189 | } | 189 | } |
190 | 190 | ||
191 | static void spider_net_get_strings(struct net_device *netdev, u32 stringset, | 191 | static void spider_net_get_strings(struct net_device *netdev, u32 stringset, |
192 | u8 *data) | 192 | u8 *data) |
193 | { | 193 | { |
194 | memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); | 194 | memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); |
195 | } | 195 | } |
196 | 196 | ||
197 | const struct ethtool_ops spider_net_ethtool_ops = { | 197 | const struct ethtool_ops spider_net_ethtool_ops = { |
198 | .get_settings = spider_net_ethtool_get_settings, | 198 | .get_settings = spider_net_ethtool_get_settings, |
199 | .get_drvinfo = spider_net_ethtool_get_drvinfo, | 199 | .get_drvinfo = spider_net_ethtool_get_drvinfo, |
200 | .get_wol = spider_net_ethtool_get_wol, | 200 | .get_wol = spider_net_ethtool_get_wol, |
201 | .get_msglevel = spider_net_ethtool_get_msglevel, | 201 | .get_msglevel = spider_net_ethtool_get_msglevel, |
202 | .set_msglevel = spider_net_ethtool_set_msglevel, | 202 | .set_msglevel = spider_net_ethtool_set_msglevel, |
203 | .nway_reset = spider_net_ethtool_nway_reset, | 203 | .nway_reset = spider_net_ethtool_nway_reset, |
204 | .get_rx_csum = spider_net_ethtool_get_rx_csum, | 204 | .get_rx_csum = spider_net_ethtool_get_rx_csum, |
205 | .set_rx_csum = spider_net_ethtool_set_rx_csum, | 205 | .set_rx_csum = spider_net_ethtool_set_rx_csum, |
206 | .get_tx_csum = spider_net_ethtool_get_tx_csum, | 206 | .get_tx_csum = spider_net_ethtool_get_tx_csum, |
207 | .set_tx_csum = spider_net_ethtool_set_tx_csum, | 207 | .set_tx_csum = spider_net_ethtool_set_tx_csum, |
208 | .get_ringparam = spider_net_ethtool_get_ringparam, | 208 | .get_ringparam = spider_net_ethtool_get_ringparam, |
209 | .get_strings = spider_net_get_strings, | 209 | .get_strings = spider_net_get_strings, |
210 | .get_stats_count = spider_net_get_stats_count, | 210 | .get_stats_count = spider_net_get_stats_count, |
211 | .get_ethtool_stats = spider_net_get_ethtool_stats, | 211 | .get_ethtool_stats = spider_net_get_ethtool_stats, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | 214 |