diff options
author | Masakazu Mokuno <mokuno@sm.sony.co.jp> | 2007-07-05 07:11:16 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-10 14:13:46 -0400 |
commit | 02c1889166b47b9ade309a8f4b7c4ddf0489d869 (patch) | |
tree | eaaa0827b57dea6cd7945019b3f73b600f582654 | |
parent | def47c5095d53814512bb0c62ec02dfdec769db1 (diff) |
ps3: gigabit ethernet driver for PS3, take3
Hi,
This is the third submission of the network driver for PS3.
The differences from the previous one are:
- renamed source file names so that their prefix can match
with the module name
- added cbe-oss-dev@ozlabs.org line for MAINTAINER file
- changed some in copyright comments
If there are no more comments, please apply for 2.6.23.
Thank you
--
Subject: PS3: Ethernet driver
From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Add Gigabit Ethernet support for the PS3 game console. The module will
be called ps3_gelic.
CC: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | drivers/net/Kconfig | 10 | ||||
-rw-r--r-- | drivers/net/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ps3_gelic_net.c | 1576 | ||||
-rw-r--r-- | drivers/net/ps3_gelic_net.h | 239 |
5 files changed, 1834 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2c1dfb271613..0223d6d191df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2930,6 +2930,13 @@ M: mikpe@it.uu.se | |||
2930 | L: linux-ide@vger.kernel.org | 2930 | L: linux-ide@vger.kernel.org |
2931 | S: Maintained | 2931 | S: Maintained |
2932 | 2932 | ||
2933 | PS3 NETWORK SUPPORT | ||
2934 | P: Masakazu Mokuno | ||
2935 | M: mokuno@sm.sony.co.jp | ||
2936 | L: netdev@vger.kernel.org | ||
2937 | L: cbe-oss-dev@ozlabs.org | ||
2938 | S: Supported | ||
2939 | |||
2933 | PS3 PLATFORM SUPPORT | 2940 | PS3 PLATFORM SUPPORT |
2934 | P: Geoff Levand | 2941 | P: Geoff Levand |
2935 | M: geoffrey.levand@am.sony.com | 2942 | M: geoffrey.levand@am.sony.com |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a64c2fb8ac28..ec846842c480 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2200,6 +2200,16 @@ config TSI108_ETH | |||
2200 | To compile this driver as a module, choose M here: the module | 2200 | To compile this driver as a module, choose M here: the module |
2201 | will be called tsi108_eth. | 2201 | will be called tsi108_eth. |
2202 | 2202 | ||
2203 | config GELIC_NET | ||
2204 | tristate "PS3 Gigabit Ethernet driver" | ||
2205 | depends on PPC_PS3 | ||
2206 | help | ||
2207 | This driver supports the network device on the PS3 game | ||
2208 | console. This driver has built-in support for Ethernet. | ||
2209 | |||
2210 | To compile this driver as a module, choose M here: the | ||
2211 | module will be called ps3_gelic. | ||
2212 | |||
2203 | config GIANFAR | 2213 | config GIANFAR |
2204 | tristate "Gianfar Ethernet" | 2214 | tristate "Gianfar Ethernet" |
2205 | depends on 85xx || 83xx || PPC_86xx | 2215 | depends on 85xx || 83xx || PPC_86xx |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 77bd8222ab44..1bbcbedad04a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -60,6 +60,8 @@ obj-$(CONFIG_TIGON3) += tg3.o | |||
60 | obj-$(CONFIG_BNX2) += bnx2.o | 60 | obj-$(CONFIG_BNX2) += bnx2.o |
61 | spidernet-y += spider_net.o spider_net_ethtool.o | 61 | spidernet-y += spider_net.o spider_net_ethtool.o |
62 | obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o | 62 | obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o |
63 | obj-$(CONFIG_GELIC_NET) += ps3_gelic.o | ||
64 | ps3_gelic-objs += ps3_gelic_net.o | ||
63 | obj-$(CONFIG_TC35815) += tc35815.o | 65 | obj-$(CONFIG_TC35815) += tc35815.o |
64 | obj-$(CONFIG_SKGE) += skge.o | 66 | obj-$(CONFIG_SKGE) += skge.o |
65 | obj-$(CONFIG_SKY2) += sky2.o | 67 | obj-$(CONFIG_SKY2) += sky2.o |
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c new file mode 100644 index 000000000000..08d25066f051 --- /dev/null +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -0,0 +1,1576 @@ | |||
1 | /* | ||
2 | * PS3 gelic network driver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006, 2007 Sony Corporation | ||
6 | * | ||
7 | * This file is based on: spider_net.c | ||
8 | * | ||
9 | * (C) Copyright IBM Corp. 2005 | ||
10 | * | ||
11 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
12 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2, or (at your option) | ||
17 | * any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #undef DEBUG | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/module.h> | ||
33 | |||
34 | #include <linux/etherdevice.h> | ||
35 | #include <linux/ethtool.h> | ||
36 | #include <linux/if_vlan.h> | ||
37 | |||
38 | #include <linux/in.h> | ||
39 | #include <linux/ip.h> | ||
40 | #include <linux/tcp.h> | ||
41 | |||
42 | #include <linux/dma-mapping.h> | ||
43 | #include <net/checksum.h> | ||
44 | #include <asm/firmware.h> | ||
45 | #include <asm/ps3.h> | ||
46 | #include <asm/lv1call.h> | ||
47 | |||
48 | #include "ps3_gelic_net.h" | ||
49 | |||
50 | #define DRV_NAME "Gelic Network Driver" | ||
51 | #define DRV_VERSION "1.0" | ||
52 | |||
53 | MODULE_AUTHOR("SCE Inc."); | ||
54 | MODULE_DESCRIPTION("Gelic Network driver"); | ||
55 | MODULE_LICENSE("GPL"); | ||
56 | |||
57 | static inline struct device *ctodev(struct gelic_net_card *card) | ||
58 | { | ||
59 | return &card->dev->core; | ||
60 | } | ||
61 | static inline unsigned int bus_id(struct gelic_net_card *card) | ||
62 | { | ||
63 | return card->dev->bus_id; | ||
64 | } | ||
65 | static inline unsigned int dev_id(struct gelic_net_card *card) | ||
66 | { | ||
67 | return card->dev->dev_id; | ||
68 | } | ||
69 | |||
70 | /* set irq_mask */ | ||
71 | static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask) | ||
72 | { | ||
73 | int status; | ||
74 | |||
75 | status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card), | ||
76 | mask, 0); | ||
77 | if (status) | ||
78 | dev_info(ctodev(card), | ||
79 | "lv1_net_set_interrupt_mask failed %d\n", status); | ||
80 | return status; | ||
81 | } | ||
82 | static inline void gelic_net_rx_irq_on(struct gelic_net_card *card) | ||
83 | { | ||
84 | gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT); | ||
85 | } | ||
86 | static inline void gelic_net_rx_irq_off(struct gelic_net_card *card) | ||
87 | { | ||
88 | gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT); | ||
89 | } | ||
90 | /** | ||
91 | * gelic_net_get_descr_status -- returns the status of a descriptor | ||
92 | * @descr: descriptor to look at | ||
93 | * | ||
94 | * returns the status as in the dmac_cmd_status field of the descriptor | ||
95 | */ | ||
96 | static enum gelic_net_descr_status | ||
97 | gelic_net_get_descr_status(struct gelic_net_descr *descr) | ||
98 | { | ||
99 | u32 cmd_status; | ||
100 | |||
101 | cmd_status = descr->dmac_cmd_status; | ||
102 | cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT; | ||
103 | return cmd_status; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * gelic_net_set_descr_status -- sets the status of a descriptor | ||
108 | * @descr: descriptor to change | ||
109 | * @status: status to set in the descriptor | ||
110 | * | ||
111 | * changes the status to the specified value. Doesn't change other bits | ||
112 | * in the status | ||
113 | */ | ||
114 | static void gelic_net_set_descr_status(struct gelic_net_descr *descr, | ||
115 | enum gelic_net_descr_status status) | ||
116 | { | ||
117 | u32 cmd_status; | ||
118 | |||
119 | /* read the status */ | ||
120 | cmd_status = descr->dmac_cmd_status; | ||
121 | /* clean the upper 4 bits */ | ||
122 | cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO; | ||
123 | /* add the status to it */ | ||
124 | cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT; | ||
125 | /* and write it back */ | ||
126 | descr->dmac_cmd_status = cmd_status; | ||
127 | /* | ||
128 | * dma_cmd_status field is used to indicate whether the descriptor | ||
129 | * is valid or not. | ||
130 | * Usually caller of this function wants to inform that to the | ||
131 | * hardware, so we assure here the hardware sees the change. | ||
132 | */ | ||
133 | wmb(); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * gelic_net_free_chain - free descriptor chain | ||
138 | * @card: card structure | ||
139 | * @descr_in: address of desc | ||
140 | */ | ||
141 | static void gelic_net_free_chain(struct gelic_net_card *card, | ||
142 | struct gelic_net_descr *descr_in) | ||
143 | { | ||
144 | struct gelic_net_descr *descr; | ||
145 | |||
146 | for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) { | ||
147 | dma_unmap_single(ctodev(card), descr->bus_addr, | ||
148 | GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); | ||
149 | descr->bus_addr = 0; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * gelic_net_init_chain - links descriptor chain | ||
155 | * @card: card structure | ||
156 | * @chain: address of chain | ||
157 | * @start_descr: address of descriptor array | ||
158 | * @no: number of descriptors | ||
159 | * | ||
160 | * we manage a circular list that mirrors the hardware structure, | ||
161 | * except that the hardware uses bus addresses. | ||
162 | * | ||
163 | * returns 0 on success, <0 on failure | ||
164 | */ | ||
165 | static int gelic_net_init_chain(struct gelic_net_card *card, | ||
166 | struct gelic_net_descr_chain *chain, | ||
167 | struct gelic_net_descr *start_descr, int no) | ||
168 | { | ||
169 | int i; | ||
170 | struct gelic_net_descr *descr; | ||
171 | |||
172 | descr = start_descr; | ||
173 | memset(descr, 0, sizeof(*descr) * no); | ||
174 | |||
175 | /* set up the hardware pointers in each descriptor */ | ||
176 | for (i = 0; i < no; i++, descr++) { | ||
177 | gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); | ||
178 | descr->bus_addr = | ||
179 | dma_map_single(ctodev(card), descr, | ||
180 | GELIC_NET_DESCR_SIZE, | ||
181 | DMA_BIDIRECTIONAL); | ||
182 | |||
183 | if (!descr->bus_addr) | ||
184 | goto iommu_error; | ||
185 | |||
186 | descr->next = descr + 1; | ||
187 | descr->prev = descr - 1; | ||
188 | } | ||
189 | /* make them as ring */ | ||
190 | (descr - 1)->next = start_descr; | ||
191 | start_descr->prev = (descr - 1); | ||
192 | |||
193 | /* chain bus addr of hw descriptor */ | ||
194 | descr = start_descr; | ||
195 | for (i = 0; i < no; i++, descr++) { | ||
196 | descr->next_descr_addr = descr->next->bus_addr; | ||
197 | } | ||
198 | |||
199 | chain->head = start_descr; | ||
200 | chain->tail = start_descr; | ||
201 | |||
202 | /* do not chain last hw descriptor */ | ||
203 | (descr - 1)->next_descr_addr = 0; | ||
204 | |||
205 | return 0; | ||
206 | |||
207 | iommu_error: | ||
208 | for (i--, descr--; 0 <= i; i--, descr--) | ||
209 | if (descr->bus_addr) | ||
210 | dma_unmap_single(ctodev(card), descr->bus_addr, | ||
211 | GELIC_NET_DESCR_SIZE, | ||
212 | DMA_BIDIRECTIONAL); | ||
213 | return -ENOMEM; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * gelic_net_prepare_rx_descr - reinitializes a rx descriptor | ||
218 | * @card: card structure | ||
219 | * @descr: descriptor to re-init | ||
220 | * | ||
221 | * return 0 on succes, <0 on failure | ||
222 | * | ||
223 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. | ||
224 | * Activate the descriptor state-wise | ||
225 | */ | ||
226 | static int gelic_net_prepare_rx_descr(struct gelic_net_card *card, | ||
227 | struct gelic_net_descr *descr) | ||
228 | { | ||
229 | int offset; | ||
230 | unsigned int bufsize; | ||
231 | |||
232 | if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) { | ||
233 | dev_info(ctodev(card), "%s: ERROR status \n", __func__); | ||
234 | } | ||
235 | /* we need to round up the buffer size to a multiple of 128 */ | ||
236 | bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN); | ||
237 | |||
238 | /* and we need to have it 128 byte aligned, therefore we allocate a | ||
239 | * bit more */ | ||
240 | descr->skb = netdev_alloc_skb(card->netdev, | ||
241 | bufsize + GELIC_NET_RXBUF_ALIGN - 1); | ||
242 | if (!descr->skb) { | ||
243 | descr->buf_addr = 0; /* tell DMAC don't touch memory */ | ||
244 | dev_info(ctodev(card), | ||
245 | "%s:allocate skb failed !!\n", __func__); | ||
246 | return -ENOMEM; | ||
247 | } | ||
248 | descr->buf_size = bufsize; | ||
249 | descr->dmac_cmd_status = 0; | ||
250 | descr->result_size = 0; | ||
251 | descr->valid_size = 0; | ||
252 | descr->data_error = 0; | ||
253 | |||
254 | offset = ((unsigned long)descr->skb->data) & | ||
255 | (GELIC_NET_RXBUF_ALIGN - 1); | ||
256 | if (offset) | ||
257 | skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); | ||
258 | /* io-mmu-map the skb */ | ||
259 | descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data, | ||
260 | GELIC_NET_MAX_MTU, | ||
261 | DMA_FROM_DEVICE); | ||
262 | if (!descr->buf_addr) { | ||
263 | dev_kfree_skb_any(descr->skb); | ||
264 | descr->skb = NULL; | ||
265 | dev_info(ctodev(card), | ||
266 | "%s:Could not iommu-map rx buffer\n", __func__); | ||
267 | gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); | ||
268 | return -ENOMEM; | ||
269 | } else { | ||
270 | gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED); | ||
271 | return 0; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * gelic_net_release_rx_chain - free all skb of rx descr | ||
277 | * @card: card structure | ||
278 | * | ||
279 | */ | ||
280 | static void gelic_net_release_rx_chain(struct gelic_net_card *card) | ||
281 | { | ||
282 | struct gelic_net_descr *descr = card->rx_chain.head; | ||
283 | |||
284 | do { | ||
285 | if (descr->skb) { | ||
286 | dma_unmap_single(ctodev(card), | ||
287 | descr->buf_addr, | ||
288 | descr->skb->len, | ||
289 | DMA_FROM_DEVICE); | ||
290 | descr->buf_addr = 0; | ||
291 | dev_kfree_skb_any(descr->skb); | ||
292 | descr->skb = NULL; | ||
293 | descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE; | ||
294 | } | ||
295 | descr = descr->next; | ||
296 | } while (descr != card->rx_chain.head); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains | ||
301 | * @card: card structure | ||
302 | * | ||
303 | * fills all descriptors in the rx chain: allocates skbs | ||
304 | * and iommu-maps them. | ||
305 | * returns 0 on success, <0 on failure | ||
306 | */ | ||
307 | static int gelic_net_fill_rx_chain(struct gelic_net_card *card) | ||
308 | { | ||
309 | struct gelic_net_descr *descr = card->rx_chain.head; | ||
310 | int ret; | ||
311 | |||
312 | do { | ||
313 | if (!descr->skb) { | ||
314 | ret = gelic_net_prepare_rx_descr(card, descr); | ||
315 | if (ret) | ||
316 | goto rewind; | ||
317 | } | ||
318 | descr = descr->next; | ||
319 | } while (descr != card->rx_chain.head); | ||
320 | |||
321 | return 0; | ||
322 | rewind: | ||
323 | gelic_net_release_rx_chain(card); | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains | ||
329 | * @card: card structure | ||
330 | * | ||
331 | * returns 0 on success, <0 on failure | ||
332 | */ | ||
333 | static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card) | ||
334 | { | ||
335 | struct gelic_net_descr_chain *chain; | ||
336 | int ret; | ||
337 | chain = &card->rx_chain; | ||
338 | ret = gelic_net_fill_rx_chain(card); | ||
339 | chain->head = card->rx_top->prev; /* point to the last */ | ||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * gelic_net_release_tx_descr - processes a used tx descriptor | ||
345 | * @card: card structure | ||
346 | * @descr: descriptor to release | ||
347 | * | ||
348 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
349 | */ | ||
350 | static void gelic_net_release_tx_descr(struct gelic_net_card *card, | ||
351 | struct gelic_net_descr *descr) | ||
352 | { | ||
353 | struct sk_buff *skb; | ||
354 | |||
355 | |||
356 | if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) { | ||
357 | /* 2nd descriptor */ | ||
358 | skb = descr->skb; | ||
359 | dma_unmap_single(ctodev(card), descr->buf_addr, skb->len, | ||
360 | DMA_TO_DEVICE); | ||
361 | dev_kfree_skb_any(skb); | ||
362 | } else { | ||
363 | dma_unmap_single(ctodev(card), descr->buf_addr, | ||
364 | descr->buf_size, DMA_TO_DEVICE); | ||
365 | } | ||
366 | |||
367 | descr->buf_addr = 0; | ||
368 | descr->buf_size = 0; | ||
369 | descr->next_descr_addr = 0; | ||
370 | descr->result_size = 0; | ||
371 | descr->valid_size = 0; | ||
372 | descr->data_status = 0; | ||
373 | descr->data_error = 0; | ||
374 | descr->skb = NULL; | ||
375 | |||
376 | /* set descr status */ | ||
377 | descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE; | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * gelic_net_release_tx_chain - processes sent tx descriptors | ||
382 | * @card: adapter structure | ||
383 | * @stop: net_stop sequence | ||
384 | * | ||
385 | * releases the tx descriptors that gelic has finished with | ||
386 | */ | ||
387 | static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop) | ||
388 | { | ||
389 | struct gelic_net_descr_chain *tx_chain; | ||
390 | enum gelic_net_descr_status status; | ||
391 | int release = 0; | ||
392 | |||
393 | for (tx_chain = &card->tx_chain; | ||
394 | tx_chain->head != tx_chain->tail && tx_chain->tail; | ||
395 | tx_chain->tail = tx_chain->tail->next) { | ||
396 | status = gelic_net_get_descr_status(tx_chain->tail); | ||
397 | switch (status) { | ||
398 | case GELIC_NET_DESCR_RESPONSE_ERROR: | ||
399 | case GELIC_NET_DESCR_PROTECTION_ERROR: | ||
400 | case GELIC_NET_DESCR_FORCE_END: | ||
401 | if (printk_ratelimit()) | ||
402 | dev_info(ctodev(card), | ||
403 | "%s: forcing end of tx descriptor " \ | ||
404 | "with status %x\n", | ||
405 | __func__, status); | ||
406 | card->netdev_stats.tx_dropped++; | ||
407 | break; | ||
408 | |||
409 | case GELIC_NET_DESCR_COMPLETE: | ||
410 | card->netdev_stats.tx_packets++; | ||
411 | card->netdev_stats.tx_bytes += | ||
412 | tx_chain->tail->skb->len; | ||
413 | break; | ||
414 | |||
415 | case GELIC_NET_DESCR_CARDOWNED: | ||
416 | /* pending tx request */ | ||
417 | default: | ||
418 | /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */ | ||
419 | goto out; | ||
420 | } | ||
421 | gelic_net_release_tx_descr(card, tx_chain->tail); | ||
422 | release = 1; | ||
423 | } | ||
424 | out: | ||
425 | if (!stop && release) | ||
426 | netif_wake_queue(card->netdev); | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * gelic_net_set_multi - sets multicast addresses and promisc flags | ||
431 | * @netdev: interface device structure | ||
432 | * | ||
433 | * gelic_net_set_multi configures multicast addresses as needed for the | ||
434 | * netdev interface. It also sets up multicast, allmulti and promisc | ||
435 | * flags appropriately | ||
436 | */ | ||
437 | static void gelic_net_set_multi(struct net_device *netdev) | ||
438 | { | ||
439 | struct gelic_net_card *card = netdev_priv(netdev); | ||
440 | struct dev_mc_list *mc; | ||
441 | unsigned int i; | ||
442 | uint8_t *p; | ||
443 | u64 addr; | ||
444 | int status; | ||
445 | |||
446 | /* clear all multicast address */ | ||
447 | status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card), | ||
448 | 0, 1); | ||
449 | if (status) | ||
450 | dev_err(ctodev(card), | ||
451 | "lv1_net_remove_multicast_address failed %d\n", | ||
452 | status); | ||
453 | /* set broadcast address */ | ||
454 | status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), | ||
455 | GELIC_NET_BROADCAST_ADDR, 0); | ||
456 | if (status) | ||
457 | dev_err(ctodev(card), | ||
458 | "lv1_net_add_multicast_address failed, %d\n", | ||
459 | status); | ||
460 | |||
461 | if (netdev->flags & IFF_ALLMULTI | ||
462 | || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */ | ||
463 | status = lv1_net_add_multicast_address(bus_id(card), | ||
464 | dev_id(card), | ||
465 | 0, 1); | ||
466 | if (status) | ||
467 | dev_err(ctodev(card), | ||
468 | "lv1_net_add_multicast_address failed, %d\n", | ||
469 | status); | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | /* set multicast address */ | ||
474 | for (mc = netdev->mc_list; mc; mc = mc->next) { | ||
475 | addr = 0; | ||
476 | p = mc->dmi_addr; | ||
477 | for (i = 0; i < ETH_ALEN; i++) { | ||
478 | addr <<= 8; | ||
479 | addr |= *p++; | ||
480 | } | ||
481 | status = lv1_net_add_multicast_address(bus_id(card), | ||
482 | dev_id(card), | ||
483 | addr, 0); | ||
484 | if (status) | ||
485 | dev_err(ctodev(card), | ||
486 | "lv1_net_add_multicast_address failed, %d\n", | ||
487 | status); | ||
488 | } | ||
489 | } | ||
490 | |||
491 | /** | ||
492 | * gelic_net_enable_rxdmac - enables the receive DMA controller | ||
493 | * @card: card structure | ||
494 | * | ||
495 | * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN | ||
496 | * in the GDADMACCNTR register | ||
497 | */ | ||
498 | static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card) | ||
499 | { | ||
500 | int status; | ||
501 | |||
502 | status = lv1_net_start_rx_dma(bus_id(card), dev_id(card), | ||
503 | card->rx_chain.tail->bus_addr, 0); | ||
504 | if (status) | ||
505 | dev_info(ctodev(card), | ||
506 | "lv1_net_start_rx_dma failed, status=%d\n", status); | ||
507 | } | ||
508 | |||
509 | /** | ||
510 | * gelic_net_disable_rxdmac - disables the receive DMA controller | ||
511 | * @card: card structure | ||
512 | * | ||
513 | * gelic_net_disable_rxdmac terminates processing on the DMA controller by | ||
514 | * turing off DMA and issueing a force end | ||
515 | */ | ||
516 | static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card) | ||
517 | { | ||
518 | int status; | ||
519 | |||
520 | /* this hvc blocks until the DMA in progress really stopped */ | ||
521 | status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0); | ||
522 | if (status) | ||
523 | dev_err(ctodev(card), | ||
524 | "lv1_net_stop_rx_dma faild, %d\n", status); | ||
525 | } | ||
526 | |||
527 | /** | ||
528 | * gelic_net_disable_txdmac - disables the transmit DMA controller | ||
529 | * @card: card structure | ||
530 | * | ||
531 | * gelic_net_disable_txdmac terminates processing on the DMA controller by | ||
532 | * turing off DMA and issueing a force end | ||
533 | */ | ||
534 | static inline void gelic_net_disable_txdmac(struct gelic_net_card *card) | ||
535 | { | ||
536 | int status; | ||
537 | |||
538 | /* this hvc blocks until the DMA in progress really stopped */ | ||
539 | status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0); | ||
540 | if (status) | ||
541 | dev_err(ctodev(card), | ||
542 | "lv1_net_stop_tx_dma faild, status=%d\n", status); | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * gelic_net_stop - called upon ifconfig down | ||
547 | * @netdev: interface device structure | ||
548 | * | ||
549 | * always returns 0 | ||
550 | */ | ||
551 | static int gelic_net_stop(struct net_device *netdev) | ||
552 | { | ||
553 | struct gelic_net_card *card = netdev_priv(netdev); | ||
554 | |||
555 | netif_poll_disable(netdev); | ||
556 | netif_stop_queue(netdev); | ||
557 | |||
558 | /* turn off DMA, force end */ | ||
559 | gelic_net_disable_rxdmac(card); | ||
560 | gelic_net_disable_txdmac(card); | ||
561 | |||
562 | gelic_net_set_irq_mask(card, 0); | ||
563 | |||
564 | /* disconnect event port */ | ||
565 | free_irq(card->netdev->irq, card->netdev); | ||
566 | ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); | ||
567 | card->netdev->irq = NO_IRQ; | ||
568 | |||
569 | netif_carrier_off(netdev); | ||
570 | |||
571 | /* release chains */ | ||
572 | gelic_net_release_tx_chain(card, 1); | ||
573 | gelic_net_release_rx_chain(card); | ||
574 | |||
575 | gelic_net_free_chain(card, card->tx_top); | ||
576 | gelic_net_free_chain(card, card->rx_top); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /** | ||
582 | * gelic_net_get_next_tx_descr - returns the next available tx descriptor | ||
583 | * @card: device structure to get descriptor from | ||
584 | * | ||
585 | * returns the address of the next descriptor, or NULL if not available. | ||
586 | */ | ||
587 | static struct gelic_net_descr * | ||
588 | gelic_net_get_next_tx_descr(struct gelic_net_card *card) | ||
589 | { | ||
590 | if (!card->tx_chain.head) | ||
591 | return NULL; | ||
592 | /* see if we can two consecutive free descrs */ | ||
593 | if (card->tx_chain.tail != card->tx_chain.head->next && | ||
594 | gelic_net_get_descr_status(card->tx_chain.head) == | ||
595 | GELIC_NET_DESCR_NOT_IN_USE && | ||
596 | card->tx_chain.tail != card->tx_chain.head->next->next && | ||
597 | gelic_net_get_descr_status(card->tx_chain.head->next) == | ||
598 | GELIC_NET_DESCR_NOT_IN_USE ) | ||
599 | return card->tx_chain.head; | ||
600 | else | ||
601 | return NULL; | ||
602 | |||
603 | } | ||
604 | |||
605 | /** | ||
606 | * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field | ||
607 | * @descr: descriptor structure to fill out | ||
608 | * @skb: packet to consider | ||
609 | * @middle: middle of frame | ||
610 | * | ||
611 | * fills out the command and status field of the descriptor structure, | ||
612 | * depending on hardware checksum settings. This function assumes a wmb() | ||
613 | * has executed before. | ||
614 | */ | ||
615 | static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr, | ||
616 | struct sk_buff *skb, int middle) | ||
617 | { | ||
618 | u32 eofr; | ||
619 | |||
620 | if (middle) | ||
621 | eofr = 0; | ||
622 | else | ||
623 | eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME; | ||
624 | |||
625 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
626 | descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; | ||
627 | else { | ||
628 | /* is packet ip? | ||
629 | * if yes: tcp? udp? */ | ||
630 | if (skb->protocol == htons(ETH_P_IP)) { | ||
631 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | ||
632 | descr->dmac_cmd_status = | ||
633 | GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr; | ||
634 | else if (ip_hdr(skb)->protocol == IPPROTO_UDP) | ||
635 | descr->dmac_cmd_status = | ||
636 | GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr; | ||
637 | else /* | ||
638 | * the stack should checksum non-tcp and non-udp | ||
639 | * packets on his own: NETIF_F_IP_CSUM | ||
640 | */ | ||
641 | descr->dmac_cmd_status = | ||
642 | GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * gelic_net_prepare_tx_descr_v - get dma address of skb_data | ||
649 | * @card: card structure | ||
650 | * @descr: descriptor structure | ||
651 | * @skb: packet to use | ||
652 | * | ||
653 | * returns 0 on success, <0 on failure. | ||
654 | * | ||
655 | */ | ||
656 | static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card, | ||
657 | struct gelic_net_descr *descr, | ||
658 | struct sk_buff *skb) | ||
659 | { | ||
660 | dma_addr_t buf[2]; | ||
661 | unsigned int vlan_len; | ||
662 | |||
663 | if (skb->len < GELIC_NET_VLAN_POS) | ||
664 | return -EINVAL; | ||
665 | |||
666 | memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS); | ||
667 | if (card->vlan_index != -1) { | ||
668 | descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/ | ||
669 | descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]); | ||
670 | vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */ | ||
671 | } else | ||
672 | vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */ | ||
673 | |||
674 | /* first descr */ | ||
675 | buf[0] = dma_map_single(ctodev(card), &descr->vlan, | ||
676 | vlan_len, DMA_TO_DEVICE); | ||
677 | |||
678 | if (!buf[0]) { | ||
679 | dev_err(ctodev(card), | ||
680 | "dma map 1 failed (%p, %i). Dropping packet\n", | ||
681 | skb->data, vlan_len); | ||
682 | return -ENOMEM; | ||
683 | } | ||
684 | |||
685 | descr->buf_addr = buf[0]; | ||
686 | descr->buf_size = vlan_len; | ||
687 | descr->skb = skb; /* not used */ | ||
688 | descr->data_status = 0; | ||
689 | gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */ | ||
690 | |||
691 | /* second descr */ | ||
692 | card->tx_chain.head = card->tx_chain.head->next; | ||
693 | descr->next_descr_addr = descr->next->bus_addr; | ||
694 | descr = descr->next; | ||
695 | if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) | ||
696 | /* XXX will be removed */ | ||
697 | dev_err(ctodev(card), "descr is not free!\n"); | ||
698 | |||
699 | buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS, | ||
700 | skb->len - GELIC_NET_VLAN_POS, | ||
701 | DMA_TO_DEVICE); | ||
702 | |||
703 | if (!buf[1]) { | ||
704 | dev_err(ctodev(card), | ||
705 | "dma map 2 failed (%p, %i). Dropping packet\n", | ||
706 | skb->data + GELIC_NET_VLAN_POS, | ||
707 | skb->len - GELIC_NET_VLAN_POS); | ||
708 | dma_unmap_single(ctodev(card), buf[0], vlan_len, | ||
709 | DMA_TO_DEVICE); | ||
710 | return -ENOMEM; | ||
711 | } | ||
712 | |||
713 | descr->buf_addr = buf[1]; | ||
714 | descr->buf_size = skb->len - GELIC_NET_VLAN_POS; | ||
715 | descr->skb = skb; | ||
716 | descr->data_status = 0; | ||
717 | descr->next_descr_addr = 0; /* terminate hw descr */ | ||
718 | gelic_net_set_txdescr_cmdstat(descr, skb, 0); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * gelic_net_kick_txdma - enables TX DMA processing | ||
725 | * @card: card structure | ||
726 | * @descr: descriptor address to enable TX processing at | ||
727 | * | ||
728 | */ | ||
729 | static int gelic_net_kick_txdma(struct gelic_net_card *card, | ||
730 | struct gelic_net_descr *descr) | ||
731 | { | ||
732 | int status = -ENXIO; | ||
733 | int count = 10; | ||
734 | |||
735 | if (card->tx_dma_progress) | ||
736 | return 0; | ||
737 | |||
738 | if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) { | ||
739 | card->tx_dma_progress = 1; | ||
740 | /* sometimes we need retry here */ | ||
741 | while (count--) { | ||
742 | status = lv1_net_start_tx_dma(bus_id(card), | ||
743 | dev_id(card), | ||
744 | descr->bus_addr, 0); | ||
745 | if (!status) | ||
746 | break; | ||
747 | } | ||
748 | if (!count) | ||
749 | dev_info(ctodev(card), "lv1_net_start_txdma failed," \ | ||
750 | "status=%d %#lx\n", | ||
751 | status, card->irq_status); | ||
752 | } | ||
753 | return status; | ||
754 | } | ||
755 | |||
756 | /** | ||
757 | * gelic_net_xmit - transmits a frame over the device | ||
758 | * @skb: packet to send out | ||
759 | * @netdev: interface device structure | ||
760 | * | ||
761 | * returns 0 on success, <0 on failure | ||
762 | */ | ||
763 | static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) | ||
764 | { | ||
765 | struct gelic_net_card *card = netdev_priv(netdev); | ||
766 | struct gelic_net_descr *descr = NULL; | ||
767 | int result; | ||
768 | unsigned long flags; | ||
769 | |||
770 | spin_lock_irqsave(&card->tx_dma_lock, flags); | ||
771 | |||
772 | gelic_net_release_tx_chain(card, 0); | ||
773 | if (!skb) | ||
774 | goto kick; | ||
775 | descr = gelic_net_get_next_tx_descr(card); | ||
776 | if (!descr) { | ||
777 | netif_stop_queue(netdev); | ||
778 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); | ||
779 | return NETDEV_TX_BUSY; | ||
780 | } | ||
781 | result = gelic_net_prepare_tx_descr_v(card, descr, skb); | ||
782 | |||
783 | if (result) | ||
784 | goto error; | ||
785 | |||
786 | card->tx_chain.head = card->tx_chain.head->next; | ||
787 | |||
788 | if (descr->prev) | ||
789 | descr->prev->next_descr_addr = descr->bus_addr; | ||
790 | kick: | ||
791 | /* | ||
792 | * as hardware descriptor is modified in the above lines, | ||
793 | * ensure that the hardware sees it | ||
794 | */ | ||
795 | wmb(); | ||
796 | if (gelic_net_kick_txdma(card, card->tx_chain.tail)) | ||
797 | goto error; | ||
798 | |||
799 | netdev->trans_start = jiffies; | ||
800 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); | ||
801 | return NETDEV_TX_OK; | ||
802 | |||
803 | error: | ||
804 | card->netdev_stats.tx_dropped++; | ||
805 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); | ||
806 | return NETDEV_TX_LOCKED; | ||
807 | } | ||
808 | |||
809 | /** | ||
810 | * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on | ||
811 | * @descr: descriptor to process | ||
812 | * @card: card structure | ||
813 | * | ||
814 | * iommu-unmaps the skb, fills out skb structure and passes the data to the | ||
815 | * stack. The descriptor state is not changed. | ||
816 | */ | ||
817 | static void gelic_net_pass_skb_up(struct gelic_net_descr *descr, | ||
818 | struct gelic_net_card *card) | ||
819 | { | ||
820 | struct sk_buff *skb; | ||
821 | struct net_device *netdev; | ||
822 | u32 data_status, data_error; | ||
823 | |||
824 | data_status = descr->data_status; | ||
825 | data_error = descr->data_error; | ||
826 | netdev = card->netdev; | ||
827 | /* unmap skb buffer */ | ||
828 | skb = descr->skb; | ||
829 | dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU, | ||
830 | DMA_FROM_DEVICE); | ||
831 | |||
832 | skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size); | ||
833 | if (!descr->valid_size) | ||
834 | dev_info(ctodev(card), "buffer full %x %x %x\n", | ||
835 | descr->result_size, descr->buf_size, | ||
836 | descr->dmac_cmd_status); | ||
837 | |||
838 | descr->skb = NULL; | ||
839 | /* | ||
840 | * the card put 2 bytes vlan tag in front | ||
841 | * of the ethernet frame | ||
842 | */ | ||
843 | skb_pull(skb, 2); | ||
844 | skb->protocol = eth_type_trans(skb, netdev); | ||
845 | |||
846 | /* checksum offload */ | ||
847 | if (card->rx_csum) { | ||
848 | if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) && | ||
849 | (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK))) | ||
850 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
851 | else | ||
852 | skb->ip_summed = CHECKSUM_NONE; | ||
853 | } else | ||
854 | skb->ip_summed = CHECKSUM_NONE; | ||
855 | |||
856 | /* update netdevice statistics */ | ||
857 | card->netdev_stats.rx_packets++; | ||
858 | card->netdev_stats.rx_bytes += skb->len; | ||
859 | |||
860 | /* pass skb up to stack */ | ||
861 | netif_receive_skb(skb); | ||
862 | } | ||
863 | |||
864 | /** | ||
865 | * gelic_net_decode_one_descr - processes an rx descriptor | ||
866 | * @card: card structure | ||
867 | * | ||
868 | * returns 1 if a packet has been sent to the stack, otherwise 0 | ||
869 | * | ||
870 | * processes an rx descriptor by iommu-unmapping the data buffer and passing | ||
871 | * the packet up to the stack | ||
872 | */ | ||
873 | static int gelic_net_decode_one_descr(struct gelic_net_card *card) | ||
874 | { | ||
875 | enum gelic_net_descr_status status; | ||
876 | struct gelic_net_descr_chain *chain = &card->rx_chain; | ||
877 | struct gelic_net_descr *descr = chain->tail; | ||
878 | int dmac_chain_ended; | ||
879 | |||
880 | status = gelic_net_get_descr_status(descr); | ||
881 | /* is this descriptor terminated with next_descr == NULL? */ | ||
882 | dmac_chain_ended = | ||
883 | descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS; | ||
884 | |||
885 | if (status == GELIC_NET_DESCR_CARDOWNED) | ||
886 | return 0; | ||
887 | |||
888 | if (status == GELIC_NET_DESCR_NOT_IN_USE) { | ||
889 | dev_dbg(ctodev(card), "dormant descr? %p\n", descr); | ||
890 | return 0; | ||
891 | } | ||
892 | |||
893 | if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) || | ||
894 | (status == GELIC_NET_DESCR_PROTECTION_ERROR) || | ||
895 | (status == GELIC_NET_DESCR_FORCE_END)) { | ||
896 | dev_info(ctodev(card), "dropping RX descriptor with state %x\n", | ||
897 | status); | ||
898 | card->netdev_stats.rx_dropped++; | ||
899 | goto refill; | ||
900 | } | ||
901 | |||
902 | if ((status != GELIC_NET_DESCR_COMPLETE) && | ||
903 | (status != GELIC_NET_DESCR_FRAME_END)) { | ||
904 | dev_dbg(ctodev(card), "RX descriptor with state %x\n", | ||
905 | status); | ||
906 | goto refill; | ||
907 | } | ||
908 | |||
909 | /* ok, we've got a packet in descr */ | ||
910 | gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */ | ||
911 | |||
912 | refill: | ||
913 | descr->next_descr_addr = 0; /* unlink the descr */ | ||
914 | |||
915 | /* change the descriptor state: */ | ||
916 | gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); | ||
917 | |||
918 | /* refill one desc | ||
919 | * FIXME: this can fail, but for now, just leave this | ||
920 | * descriptor without skb | ||
921 | */ | ||
922 | gelic_net_prepare_rx_descr(card, descr); | ||
923 | chain->head = descr; | ||
924 | chain->tail = descr->next; | ||
925 | descr->prev->next_descr_addr = descr->bus_addr; | ||
926 | |||
927 | if (dmac_chain_ended) { | ||
928 | gelic_net_enable_rxdmac(card); | ||
929 | dev_dbg(ctodev(card), "reenable rx dma\n"); | ||
930 | } | ||
931 | |||
932 | return 1; | ||
933 | } | ||
934 | |||
935 | /** | ||
936 | * gelic_net_poll - NAPI poll function called by the stack to return packets | ||
937 | * @netdev: interface device structure | ||
938 | * @budget: number of packets we can pass to the stack at most | ||
939 | * | ||
940 | * returns 0 if no more packets available to the driver/stack. Returns 1, | ||
941 | * if the quota is exceeded, but the driver has still packets. | ||
942 | * | ||
943 | */ | ||
944 | static int gelic_net_poll(struct net_device *netdev, int *budget) | ||
945 | { | ||
946 | struct gelic_net_card *card = netdev_priv(netdev); | ||
947 | int packets_to_do, packets_done = 0; | ||
948 | int no_more_packets = 0; | ||
949 | |||
950 | packets_to_do = min(*budget, netdev->quota); | ||
951 | |||
952 | while (packets_to_do) { | ||
953 | if (gelic_net_decode_one_descr(card)) { | ||
954 | packets_done++; | ||
955 | packets_to_do--; | ||
956 | } else { | ||
957 | /* no more packets for the stack */ | ||
958 | no_more_packets = 1; | ||
959 | break; | ||
960 | } | ||
961 | } | ||
962 | netdev->quota -= packets_done; | ||
963 | *budget -= packets_done; | ||
964 | if (no_more_packets) { | ||
965 | netif_rx_complete(netdev); | ||
966 | gelic_net_rx_irq_on(card); | ||
967 | return 0; | ||
968 | } else | ||
969 | return 1; | ||
970 | } | ||
971 | |||
972 | /** | ||
973 | * gelic_net_get_stats - get interface statistics | ||
974 | * @netdev: interface device structure | ||
975 | * | ||
976 | * returns the interface statistics residing in the gelic_net_card struct | ||
977 | */ | ||
978 | static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev) | ||
979 | { | ||
980 | struct gelic_net_card *card = netdev_priv(netdev); | ||
981 | |||
982 | return &card->netdev_stats; | ||
983 | } | ||
984 | |||
985 | /** | ||
986 | * gelic_net_change_mtu - changes the MTU of an interface | ||
987 | * @netdev: interface device structure | ||
988 | * @new_mtu: new MTU value | ||
989 | * | ||
990 | * returns 0 on success, <0 on failure | ||
991 | */ | ||
992 | static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) | ||
993 | { | ||
994 | /* no need to re-alloc skbs or so -- the max mtu is about 2.3k | ||
995 | * and mtu is outbound only anyway */ | ||
996 | if ((new_mtu < GELIC_NET_MIN_MTU) || | ||
997 | (new_mtu > GELIC_NET_MAX_MTU)) { | ||
998 | return -EINVAL; | ||
999 | } | ||
1000 | netdev->mtu = new_mtu; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | /** | ||
1005 | * gelic_net_interrupt - event handler for gelic_net | ||
1006 | */ | ||
1007 | static irqreturn_t gelic_net_interrupt(int irq, void *ptr) | ||
1008 | { | ||
1009 | unsigned long flags; | ||
1010 | struct net_device *netdev = ptr; | ||
1011 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1012 | u64 status; | ||
1013 | |||
1014 | status = card->irq_status; | ||
1015 | |||
1016 | if (!status) | ||
1017 | return IRQ_NONE; | ||
1018 | |||
1019 | if (status & GELIC_NET_RXINT) { | ||
1020 | gelic_net_rx_irq_off(card); | ||
1021 | netif_rx_schedule(netdev); | ||
1022 | } | ||
1023 | |||
1024 | if (status & GELIC_NET_TXINT) { | ||
1025 | spin_lock_irqsave(&card->tx_dma_lock, flags); | ||
1026 | card->tx_dma_progress = 0; | ||
1027 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); | ||
1028 | /* start pending DMA */ | ||
1029 | gelic_net_xmit(NULL, netdev); | ||
1030 | } | ||
1031 | return IRQ_HANDLED; | ||
1032 | } | ||
1033 | |||
1034 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1035 | /** | ||
1036 | * gelic_net_poll_controller - artificial interrupt for netconsole etc. | ||
1037 | * @netdev: interface device structure | ||
1038 | * | ||
1039 | * see Documentation/networking/netconsole.txt | ||
1040 | */ | ||
1041 | static void gelic_net_poll_controller(struct net_device *netdev) | ||
1042 | { | ||
1043 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1044 | |||
1045 | gelic_net_set_irq_mask(card, 0); | ||
1046 | gelic_net_interrupt(netdev->irq, netdev); | ||
1047 | gelic_net_set_irq_mask(card, card->ghiintmask); | ||
1048 | } | ||
1049 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | ||
1050 | |||
1051 | /** | ||
1052 | * gelic_net_open_device - open device and map dma region | ||
1053 | * @card: card structure | ||
1054 | */ | ||
1055 | static int gelic_net_open_device(struct gelic_net_card *card) | ||
1056 | { | ||
1057 | int result; | ||
1058 | |||
1059 | result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY, | ||
1060 | &card->netdev->irq); | ||
1061 | |||
1062 | if (result) { | ||
1063 | dev_info(ctodev(card), | ||
1064 | "%s:%d: gelic_net_open_device failed (%d)\n", | ||
1065 | __func__, __LINE__, result); | ||
1066 | result = -EPERM; | ||
1067 | goto fail_alloc_irq; | ||
1068 | } | ||
1069 | |||
1070 | result = request_irq(card->netdev->irq, gelic_net_interrupt, | ||
1071 | IRQF_DISABLED, "gelic network", card->netdev); | ||
1072 | |||
1073 | if (result) { | ||
1074 | dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n", | ||
1075 | __func__, __LINE__, result); | ||
1076 | goto fail_request_irq; | ||
1077 | } | ||
1078 | |||
1079 | return 0; | ||
1080 | |||
1081 | fail_request_irq: | ||
1082 | ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); | ||
1083 | card->netdev->irq = NO_IRQ; | ||
1084 | fail_alloc_irq: | ||
1085 | return result; | ||
1086 | } | ||
1087 | |||
1088 | |||
1089 | /** | ||
1090 | * gelic_net_open - called upon ifonfig up | ||
1091 | * @netdev: interface device structure | ||
1092 | * | ||
1093 | * returns 0 on success, <0 on failure | ||
1094 | * | ||
1095 | * gelic_net_open allocates all the descriptors and memory needed for | ||
1096 | * operation, sets up multicast list and enables interrupts | ||
1097 | */ | ||
1098 | static int gelic_net_open(struct net_device *netdev) | ||
1099 | { | ||
1100 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1101 | |||
1102 | dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__); | ||
1103 | |||
1104 | gelic_net_open_device(card); | ||
1105 | |||
1106 | if (gelic_net_init_chain(card, &card->tx_chain, | ||
1107 | card->descr, GELIC_NET_TX_DESCRIPTORS)) | ||
1108 | goto alloc_tx_failed; | ||
1109 | if (gelic_net_init_chain(card, &card->rx_chain, | ||
1110 | card->descr + GELIC_NET_RX_DESCRIPTORS, | ||
1111 | GELIC_NET_RX_DESCRIPTORS)) | ||
1112 | goto alloc_rx_failed; | ||
1113 | |||
1114 | /* head of chain */ | ||
1115 | card->tx_top = card->tx_chain.head; | ||
1116 | card->rx_top = card->rx_chain.head; | ||
1117 | dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n", | ||
1118 | card->rx_top, card->tx_top, sizeof(struct gelic_net_descr), | ||
1119 | GELIC_NET_RX_DESCRIPTORS); | ||
1120 | /* allocate rx skbs */ | ||
1121 | if (gelic_net_alloc_rx_skbs(card)) | ||
1122 | goto alloc_skbs_failed; | ||
1123 | |||
1124 | card->tx_dma_progress = 0; | ||
1125 | card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT; | ||
1126 | |||
1127 | gelic_net_set_irq_mask(card, card->ghiintmask); | ||
1128 | gelic_net_enable_rxdmac(card); | ||
1129 | |||
1130 | netif_start_queue(netdev); | ||
1131 | netif_carrier_on(netdev); | ||
1132 | netif_poll_enable(netdev); | ||
1133 | |||
1134 | return 0; | ||
1135 | |||
1136 | alloc_skbs_failed: | ||
1137 | gelic_net_free_chain(card, card->rx_top); | ||
1138 | alloc_rx_failed: | ||
1139 | gelic_net_free_chain(card, card->tx_top); | ||
1140 | alloc_tx_failed: | ||
1141 | return -ENOMEM; | ||
1142 | } | ||
1143 | |||
1144 | #ifdef GELIC_NET_ETHTOOL | ||
1145 | static void gelic_net_get_drvinfo (struct net_device *netdev, | ||
1146 | struct ethtool_drvinfo *info) | ||
1147 | { | ||
1148 | strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1); | ||
1149 | strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1); | ||
1150 | } | ||
1151 | |||
1152 | static int gelic_net_get_settings(struct net_device *netdev, | ||
1153 | struct ethtool_cmd *cmd) | ||
1154 | { | ||
1155 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1156 | int status; | ||
1157 | u64 v1, v2; | ||
1158 | int speed, duplex; | ||
1159 | |||
1160 | speed = duplex = -1; | ||
1161 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1162 | GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, | ||
1163 | &v1, &v2); | ||
1164 | if (status) { | ||
1165 | /* link down */ | ||
1166 | } else { | ||
1167 | if (v1 & GELIC_NET_FULL_DUPLEX) { | ||
1168 | duplex = DUPLEX_FULL; | ||
1169 | } else { | ||
1170 | duplex = DUPLEX_HALF; | ||
1171 | } | ||
1172 | |||
1173 | if (v1 & GELIC_NET_SPEED_10 ) { | ||
1174 | speed = SPEED_10; | ||
1175 | } else if (v1 & GELIC_NET_SPEED_100) { | ||
1176 | speed = SPEED_100; | ||
1177 | } else if (v1 & GELIC_NET_SPEED_1000) { | ||
1178 | speed = SPEED_1000; | ||
1179 | } | ||
1180 | } | ||
1181 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | | ||
1182 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | | ||
1183 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | | ||
1184 | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; | ||
1185 | cmd->advertising = cmd->supported; | ||
1186 | cmd->speed = speed; | ||
1187 | cmd->duplex = duplex; | ||
1188 | cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ | ||
1189 | cmd->port = PORT_TP; | ||
1190 | |||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | static u32 gelic_net_get_link(struct net_device *netdev) | ||
1195 | { | ||
1196 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1197 | int status; | ||
1198 | u64 v1, v2; | ||
1199 | int link; | ||
1200 | |||
1201 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1202 | GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, | ||
1203 | &v1, &v2); | ||
1204 | if (status) | ||
1205 | return 0; /* link down */ | ||
1206 | |||
1207 | if (v1 & GELIC_NET_LINK_UP) | ||
1208 | link = 1; | ||
1209 | else | ||
1210 | link = 0; | ||
1211 | |||
1212 | return link; | ||
1213 | } | ||
1214 | |||
1215 | static int gelic_net_nway_reset(struct net_device *netdev) | ||
1216 | { | ||
1217 | if (netif_running(netdev)) { | ||
1218 | gelic_net_stop(netdev); | ||
1219 | gelic_net_open(netdev); | ||
1220 | } | ||
1221 | return 0; | ||
1222 | } | ||
1223 | |||
1224 | static u32 gelic_net_get_tx_csum(struct net_device *netdev) | ||
1225 | { | ||
1226 | return (netdev->features & NETIF_F_IP_CSUM) != 0; | ||
1227 | } | ||
1228 | |||
1229 | static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data) | ||
1230 | { | ||
1231 | if (data) | ||
1232 | netdev->features |= NETIF_F_IP_CSUM; | ||
1233 | else | ||
1234 | netdev->features &= ~NETIF_F_IP_CSUM; | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | static u32 gelic_net_get_rx_csum(struct net_device *netdev) | ||
1240 | { | ||
1241 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1242 | |||
1243 | return card->rx_csum; | ||
1244 | } | ||
1245 | |||
1246 | static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) | ||
1247 | { | ||
1248 | struct gelic_net_card *card = netdev_priv(netdev); | ||
1249 | |||
1250 | card->rx_csum = data; | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | static struct ethtool_ops gelic_net_ethtool_ops = { | ||
1255 | .get_drvinfo = gelic_net_get_drvinfo, | ||
1256 | .get_settings = gelic_net_get_settings, | ||
1257 | .get_link = gelic_net_get_link, | ||
1258 | .nway_reset = gelic_net_nway_reset, | ||
1259 | .get_tx_csum = gelic_net_get_tx_csum, | ||
1260 | .set_tx_csum = gelic_net_set_tx_csum, | ||
1261 | .get_rx_csum = gelic_net_get_rx_csum, | ||
1262 | .set_rx_csum = gelic_net_set_rx_csum, | ||
1263 | }; | ||
1264 | #endif | ||
1265 | |||
1266 | /** | ||
1267 | * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout | ||
1268 | * function (to be called not under interrupt status) | ||
1269 | * @work: work is context of tx timout task | ||
1270 | * | ||
1271 | * called as task when tx hangs, resets interface (if interface is up) | ||
1272 | */ | ||
1273 | static void gelic_net_tx_timeout_task(struct work_struct *work) | ||
1274 | { | ||
1275 | struct gelic_net_card *card = | ||
1276 | container_of(work, struct gelic_net_card, tx_timeout_task); | ||
1277 | struct net_device *netdev = card->netdev; | ||
1278 | |||
1279 | dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); | ||
1280 | |||
1281 | if (!(netdev->flags & IFF_UP)) | ||
1282 | goto out; | ||
1283 | |||
1284 | netif_device_detach(netdev); | ||
1285 | gelic_net_stop(netdev); | ||
1286 | |||
1287 | gelic_net_open(netdev); | ||
1288 | netif_device_attach(netdev); | ||
1289 | |||
1290 | out: | ||
1291 | atomic_dec(&card->tx_timeout_task_counter); | ||
1292 | } | ||
1293 | |||
1294 | /** | ||
1295 | * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in. | ||
1296 | * @netdev: interface device structure | ||
1297 | * | ||
1298 | * called, if tx hangs. Schedules a task that resets the interface | ||
1299 | */ | ||
1300 | static void gelic_net_tx_timeout(struct net_device *netdev) | ||
1301 | { | ||
1302 | struct gelic_net_card *card; | ||
1303 | |||
1304 | card = netdev_priv(netdev); | ||
1305 | atomic_inc(&card->tx_timeout_task_counter); | ||
1306 | if (netdev->flags & IFF_UP) | ||
1307 | schedule_work(&card->tx_timeout_task); | ||
1308 | else | ||
1309 | atomic_dec(&card->tx_timeout_task_counter); | ||
1310 | } | ||
1311 | |||
1312 | /** | ||
1313 | * gelic_net_setup_netdev_ops - initialization of net_device operations | ||
1314 | * @netdev: net_device structure | ||
1315 | * | ||
1316 | * fills out function pointers in the net_device structure | ||
1317 | */ | ||
1318 | static void gelic_net_setup_netdev_ops(struct net_device *netdev) | ||
1319 | { | ||
1320 | netdev->open = &gelic_net_open; | ||
1321 | netdev->stop = &gelic_net_stop; | ||
1322 | netdev->hard_start_xmit = &gelic_net_xmit; | ||
1323 | netdev->get_stats = &gelic_net_get_stats; | ||
1324 | netdev->set_multicast_list = &gelic_net_set_multi; | ||
1325 | netdev->change_mtu = &gelic_net_change_mtu; | ||
1326 | /* tx watchdog */ | ||
1327 | netdev->tx_timeout = &gelic_net_tx_timeout; | ||
1328 | netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT; | ||
1329 | /* NAPI */ | ||
1330 | netdev->poll = &gelic_net_poll; | ||
1331 | netdev->weight = GELIC_NET_NAPI_WEIGHT; | ||
1332 | #ifdef GELIC_NET_ETHTOOL | ||
1333 | netdev->ethtool_ops = &gelic_net_ethtool_ops; | ||
1334 | #endif | ||
1335 | } | ||
1336 | |||
1337 | /** | ||
1338 | * gelic_net_setup_netdev - initialization of net_device | ||
1339 | * @card: card structure | ||
1340 | * | ||
1341 | * Returns 0 on success or <0 on failure | ||
1342 | * | ||
1343 | * gelic_net_setup_netdev initializes the net_device structure | ||
1344 | **/ | ||
1345 | static int gelic_net_setup_netdev(struct gelic_net_card *card) | ||
1346 | { | ||
1347 | struct net_device *netdev = card->netdev; | ||
1348 | struct sockaddr addr; | ||
1349 | unsigned int i; | ||
1350 | int status; | ||
1351 | u64 v1, v2; | ||
1352 | |||
1353 | SET_MODULE_OWNER(netdev); | ||
1354 | SET_NETDEV_DEV(netdev, &card->dev->core); | ||
1355 | spin_lock_init(&card->tx_dma_lock); | ||
1356 | |||
1357 | card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT; | ||
1358 | |||
1359 | gelic_net_setup_netdev_ops(netdev); | ||
1360 | |||
1361 | netdev->features = NETIF_F_IP_CSUM; | ||
1362 | |||
1363 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1364 | GELIC_NET_GET_MAC_ADDRESS, | ||
1365 | 0, 0, 0, &v1, &v2); | ||
1366 | if (status || !is_valid_ether_addr((u8 *)&v1)) { | ||
1367 | dev_info(ctodev(card), | ||
1368 | "%s:lv1_net_control GET_MAC_ADDR failed %d\n", | ||
1369 | __func__, status); | ||
1370 | return -EINVAL; | ||
1371 | } | ||
1372 | v1 <<= 16; | ||
1373 | memcpy(addr.sa_data, &v1, ETH_ALEN); | ||
1374 | memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN); | ||
1375 | dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
1376 | netdev->dev_addr[0], netdev->dev_addr[1], | ||
1377 | netdev->dev_addr[2], netdev->dev_addr[3], | ||
1378 | netdev->dev_addr[4], netdev->dev_addr[5]); | ||
1379 | |||
1380 | card->vlan_index = -1; /* no vlan */ | ||
1381 | for (i = 0; i < GELIC_NET_VLAN_MAX; i++) { | ||
1382 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1383 | GELIC_NET_GET_VLAN_ID, | ||
1384 | i + 1, /* index; one based */ | ||
1385 | 0, 0, &v1, &v2); | ||
1386 | if (status == GELIC_NET_VLAN_NO_ENTRY) { | ||
1387 | dev_dbg(ctodev(card), | ||
1388 | "GELIC_VLAN_ID no entry:%d, VLAN disabled\n", | ||
1389 | status); | ||
1390 | card->vlan_id[i] = 0; | ||
1391 | } else if (status) { | ||
1392 | dev_dbg(ctodev(card), | ||
1393 | "%s:GELIC_NET_VLAN_ID faild, status=%d\n", | ||
1394 | __func__, status); | ||
1395 | card->vlan_id[i] = 0; | ||
1396 | } else { | ||
1397 | card->vlan_id[i] = (u32)v1; | ||
1398 | dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1); | ||
1399 | } | ||
1400 | } | ||
1401 | if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) | ||
1402 | card->vlan_index = GELIC_NET_VLAN_WIRED - 1; | ||
1403 | |||
1404 | status = register_netdev(netdev); | ||
1405 | if (status) { | ||
1406 | dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n", | ||
1407 | __func__, status); | ||
1408 | return status; | ||
1409 | } | ||
1410 | |||
1411 | return 0; | ||
1412 | } | ||
1413 | |||
1414 | /** | ||
1415 | * gelic_net_alloc_card - allocates net_device and card structure | ||
1416 | * | ||
1417 | * returns the card structure or NULL in case of errors | ||
1418 | * | ||
1419 | * the card and net_device structures are linked to each other | ||
1420 | */ | ||
1421 | static struct gelic_net_card *gelic_net_alloc_card(void) | ||
1422 | { | ||
1423 | struct net_device *netdev; | ||
1424 | struct gelic_net_card *card; | ||
1425 | size_t alloc_size; | ||
1426 | |||
1427 | alloc_size = sizeof (*card) + | ||
1428 | sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS + | ||
1429 | sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS; | ||
1430 | /* | ||
1431 | * we assume private data is allocated 32 bytes (or more) aligned | ||
1432 | * so that gelic_net_descr should be 32 bytes aligned. | ||
1433 | * Current alloc_etherdev() does do it because NETDEV_ALIGN | ||
1434 | * is 32. | ||
1435 | * check this assumption here. | ||
1436 | */ | ||
1437 | BUILD_BUG_ON(NETDEV_ALIGN < 32); | ||
1438 | BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8); | ||
1439 | BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32); | ||
1440 | |||
1441 | netdev = alloc_etherdev(alloc_size); | ||
1442 | if (!netdev) | ||
1443 | return NULL; | ||
1444 | |||
1445 | card = netdev_priv(netdev); | ||
1446 | card->netdev = netdev; | ||
1447 | INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); | ||
1448 | init_waitqueue_head(&card->waitq); | ||
1449 | atomic_set(&card->tx_timeout_task_counter, 0); | ||
1450 | |||
1451 | return card; | ||
1452 | } | ||
1453 | |||
1454 | /** | ||
1455 | * ps3_gelic_driver_probe - add a device to the control of this driver | ||
1456 | */ | ||
1457 | static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev) | ||
1458 | { | ||
1459 | struct gelic_net_card *card = gelic_net_alloc_card(); | ||
1460 | int result; | ||
1461 | |||
1462 | if (!card) { | ||
1463 | dev_info(&dev->core, "gelic_net_alloc_card failed\n"); | ||
1464 | result = -ENOMEM; | ||
1465 | goto fail_alloc_card; | ||
1466 | } | ||
1467 | |||
1468 | ps3_system_bus_set_driver_data(dev, card); | ||
1469 | card->dev = dev; | ||
1470 | |||
1471 | result = ps3_open_hv_device(dev); | ||
1472 | |||
1473 | if (result) { | ||
1474 | dev_dbg(&dev->core, "ps3_open_hv_device failed\n"); | ||
1475 | goto fail_open; | ||
1476 | } | ||
1477 | |||
1478 | result = ps3_dma_region_create(dev->d_region); | ||
1479 | |||
1480 | if (result) { | ||
1481 | dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n", | ||
1482 | result); | ||
1483 | BUG_ON("check region type"); | ||
1484 | goto fail_dma_region; | ||
1485 | } | ||
1486 | |||
1487 | result = lv1_net_set_interrupt_status_indicator(bus_id(card), | ||
1488 | dev_id(card), | ||
1489 | ps3_mm_phys_to_lpar(__pa(&card->irq_status)), | ||
1490 | 0); | ||
1491 | |||
1492 | if (result) { | ||
1493 | dev_dbg(&dev->core, | ||
1494 | "lv1_net_set_interrupt_status_indicator failed: %s\n", | ||
1495 | ps3_result(result)); | ||
1496 | result = -EIO; | ||
1497 | goto fail_status_indicator; | ||
1498 | } | ||
1499 | |||
1500 | result = gelic_net_setup_netdev(card); | ||
1501 | |||
1502 | if (result) { | ||
1503 | dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " | ||
1504 | "(%d)\n", __func__, __LINE__, result); | ||
1505 | goto fail_setup_netdev; | ||
1506 | } | ||
1507 | |||
1508 | return 0; | ||
1509 | |||
1510 | fail_setup_netdev: | ||
1511 | lv1_net_set_interrupt_status_indicator(bus_id(card), | ||
1512 | bus_id(card), | ||
1513 | 0 , 0); | ||
1514 | fail_status_indicator: | ||
1515 | ps3_dma_region_free(dev->d_region); | ||
1516 | fail_dma_region: | ||
1517 | ps3_close_hv_device(dev); | ||
1518 | fail_open: | ||
1519 | ps3_system_bus_set_driver_data(dev, NULL); | ||
1520 | free_netdev(card->netdev); | ||
1521 | fail_alloc_card: | ||
1522 | return result; | ||
1523 | } | ||
1524 | |||
1525 | /** | ||
1526 | * ps3_gelic_driver_remove - remove a device from the control of this driver | ||
1527 | */ | ||
1528 | |||
1529 | static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev) | ||
1530 | { | ||
1531 | struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev); | ||
1532 | |||
1533 | wait_event(card->waitq, | ||
1534 | atomic_read(&card->tx_timeout_task_counter) == 0); | ||
1535 | |||
1536 | lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card), | ||
1537 | 0 , 0); | ||
1538 | |||
1539 | unregister_netdev(card->netdev); | ||
1540 | free_netdev(card->netdev); | ||
1541 | |||
1542 | ps3_system_bus_set_driver_data(dev, NULL); | ||
1543 | |||
1544 | ps3_dma_region_free(dev->d_region); | ||
1545 | |||
1546 | ps3_close_hv_device(dev); | ||
1547 | |||
1548 | return 0; | ||
1549 | } | ||
1550 | |||
1551 | static struct ps3_system_bus_driver ps3_gelic_driver = { | ||
1552 | .match_id = PS3_MATCH_ID_GELIC, | ||
1553 | .probe = ps3_gelic_driver_probe, | ||
1554 | .remove = ps3_gelic_driver_remove, | ||
1555 | .shutdown = ps3_gelic_driver_remove, | ||
1556 | .core.name = "ps3_gelic_driver", | ||
1557 | .core.owner = THIS_MODULE, | ||
1558 | }; | ||
1559 | |||
1560 | static int __init ps3_gelic_driver_init (void) | ||
1561 | { | ||
1562 | return firmware_has_feature(FW_FEATURE_PS3_LV1) | ||
1563 | ? ps3_system_bus_driver_register(&ps3_gelic_driver) | ||
1564 | : -ENODEV; | ||
1565 | } | ||
1566 | |||
1567 | static void __exit ps3_gelic_driver_exit (void) | ||
1568 | { | ||
1569 | ps3_system_bus_driver_unregister(&ps3_gelic_driver); | ||
1570 | } | ||
1571 | |||
1572 | module_init (ps3_gelic_driver_init); | ||
1573 | module_exit (ps3_gelic_driver_exit); | ||
1574 | |||
1575 | MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC); | ||
1576 | |||
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h new file mode 100644 index 000000000000..5e1c28654e16 --- /dev/null +++ b/drivers/net/ps3_gelic_net.h | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | * PS3 Platfom gelic network driver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006, 2007 Sony Corporation. | ||
6 | * | ||
7 | * This file is based on: spider_net.h | ||
8 | * | ||
9 | * (C) Copyright IBM Corp. 2005 | ||
10 | * | ||
11 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
12 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2, or (at your option) | ||
17 | * any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | #ifndef _GELIC_NET_H | ||
29 | #define _GELIC_NET_H | ||
30 | |||
31 | #define GELIC_NET_DRV_NAME "Gelic Network Driver" | ||
32 | #define GELIC_NET_DRV_VERSION "1.0" | ||
33 | |||
34 | #define GELIC_NET_ETHTOOL /* use ethtool */ | ||
35 | |||
36 | /* ioctl */ | ||
37 | #define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0) | ||
38 | #define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1) | ||
39 | |||
40 | /* descriptors */ | ||
41 | #define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */ | ||
42 | #define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */ | ||
43 | |||
44 | #define GELIC_NET_MAX_MTU 2308 | ||
45 | #define GELIC_NET_MIN_MTU 64 | ||
46 | #define GELIC_NET_RXBUF_ALIGN 128 | ||
47 | #define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */ | ||
48 | #define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ | ||
49 | #define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS) | ||
50 | #define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL | ||
51 | #define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2) | ||
52 | #define GELIC_NET_VLAN_MAX 4 | ||
53 | #define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */ | ||
54 | |||
55 | enum gelic_net_int0_status { | ||
56 | GELIC_NET_GDTDCEINT = 24, | ||
57 | GELIC_NET_GRFANMINT = 28, | ||
58 | }; | ||
59 | |||
60 | /* GHIINT1STS bits */ | ||
61 | enum gelic_net_int1_status { | ||
62 | GELIC_NET_GDADCEINT = 14, | ||
63 | }; | ||
64 | |||
65 | /* interrupt mask */ | ||
66 | #define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32)) | ||
67 | |||
68 | #define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32)) | ||
69 | #define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT) | ||
70 | #define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1) | ||
71 | |||
72 | /* RX descriptor data_status bits */ | ||
73 | #define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */ | ||
74 | #define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */ | ||
75 | #define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */ | ||
76 | #define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */ | ||
77 | #define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */ | ||
78 | #define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */ | ||
79 | #define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */ | ||
80 | #define GELIC_NET_RXSESPAH 0x01000000 /* | ||
81 | * IPsec ESP protocol auth | ||
82 | * performed | ||
83 | */ | ||
84 | |||
85 | #define GELIC_NET_RXWTPKT 0x00C00000 /* | ||
86 | * wakeup trigger packet | ||
87 | * 01: Magic Packet (TM) | ||
88 | * 10: ARP packet | ||
89 | * 11: Multicast MAC addr | ||
90 | */ | ||
91 | #define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */ | ||
92 | /* bit 20..16 reserved */ | ||
93 | #define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */ | ||
94 | /* bit 7..0 reserved */ | ||
95 | |||
96 | #define GELIC_NET_TXDESC_TAIL 0 | ||
97 | #define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK) | ||
98 | |||
99 | /* RX descriptor data_error bits */ | ||
100 | /* bit 31 reserved */ | ||
101 | #define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */ | ||
102 | #define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */ | ||
103 | #define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */ | ||
104 | #define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */ | ||
105 | #define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */ | ||
106 | #define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */ | ||
107 | #define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */ | ||
108 | #define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */ | ||
109 | #define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol | ||
110 | * processing */ | ||
111 | #define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol | ||
112 | * processing */ | ||
113 | #define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */ | ||
114 | #define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */ | ||
115 | /* bit 18 reserved */ | ||
116 | #define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */ | ||
117 | #define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length | ||
118 | * error */ | ||
119 | #define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */ | ||
120 | #define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */ | ||
121 | /* bit 13..0 reserved */ | ||
122 | #define GELIC_NET_DATA_ERROR_CHK_MASK \ | ||
123 | (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR) | ||
124 | |||
125 | |||
126 | /* tx descriptor command and status */ | ||
127 | #define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */ | ||
128 | #define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000 | ||
129 | #define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000 | ||
130 | #define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */ | ||
131 | |||
132 | #define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end | ||
133 | * interrupt status */ | ||
134 | |||
135 | #define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */ | ||
136 | #define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000 | ||
137 | #define GELIC_NET_DESCR_IND_PROC_SHIFT 28 | ||
138 | #define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff | ||
139 | |||
140 | |||
141 | enum gelic_net_descr_status { | ||
142 | GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ | ||
143 | GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ | ||
144 | GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ | ||
145 | GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */ | ||
146 | GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ | ||
147 | GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ | ||
148 | GELIC_NET_DESCR_NOT_IN_USE /* any other value */ | ||
149 | }; | ||
150 | /* for lv1_net_control */ | ||
151 | #define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001 | ||
152 | #define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002 | ||
153 | #define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003 | ||
154 | #define GELIC_NET_GET_VLAN_ID 0x0000000000000004 | ||
155 | |||
156 | #define GELIC_NET_LINK_UP 0x0000000000000001 | ||
157 | #define GELIC_NET_FULL_DUPLEX 0x0000000000000002 | ||
158 | #define GELIC_NET_AUTO_NEG 0x0000000000000004 | ||
159 | #define GELIC_NET_SPEED_10 0x0000000000000010 | ||
160 | #define GELIC_NET_SPEED_100 0x0000000000000020 | ||
161 | #define GELIC_NET_SPEED_1000 0x0000000000000040 | ||
162 | |||
163 | #define GELIC_NET_VLAN_ALL 0x0000000000000001 | ||
164 | #define GELIC_NET_VLAN_WIRED 0x0000000000000002 | ||
165 | #define GELIC_NET_VLAN_WIRELESS 0x0000000000000003 | ||
166 | #define GELIC_NET_VLAN_PSP 0x0000000000000004 | ||
167 | #define GELIC_NET_VLAN_PORT0 0x0000000000000010 | ||
168 | #define GELIC_NET_VLAN_PORT1 0x0000000000000011 | ||
169 | #define GELIC_NET_VLAN_PORT2 0x0000000000000012 | ||
170 | #define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013 | ||
171 | #define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014 | ||
172 | #define GELIC_NET_VLAN_NO_ENTRY -6 | ||
173 | |||
174 | #define GELIC_NET_PORT 2 /* for port status */ | ||
175 | |||
176 | /* size of hardware part of gelic descriptor */ | ||
177 | #define GELIC_NET_DESCR_SIZE (32) | ||
178 | struct gelic_net_descr { | ||
179 | /* as defined by the hardware */ | ||
180 | u32 buf_addr; | ||
181 | u32 buf_size; | ||
182 | u32 next_descr_addr; | ||
183 | u32 dmac_cmd_status; | ||
184 | u32 result_size; | ||
185 | u32 valid_size; /* all zeroes for tx */ | ||
186 | u32 data_status; | ||
187 | u32 data_error; /* all zeroes for tx */ | ||
188 | |||
189 | /* used in the driver */ | ||
190 | struct sk_buff *skb; | ||
191 | dma_addr_t bus_addr; | ||
192 | struct gelic_net_descr *next; | ||
193 | struct gelic_net_descr *prev; | ||
194 | struct vlan_ethhdr vlan; | ||
195 | } __attribute__((aligned(32))); | ||
196 | |||
197 | struct gelic_net_descr_chain { | ||
198 | /* we walk from tail to head */ | ||
199 | struct gelic_net_descr *head; | ||
200 | struct gelic_net_descr *tail; | ||
201 | }; | ||
202 | |||
203 | struct gelic_net_card { | ||
204 | struct net_device *netdev; | ||
205 | /* | ||
206 | * hypervisor requires irq_status should be | ||
207 | * 8 bytes aligned, but u64 member is | ||
208 | * always disposed in that manner | ||
209 | */ | ||
210 | u64 irq_status; | ||
211 | u64 ghiintmask; | ||
212 | |||
213 | struct ps3_system_bus_device *dev; | ||
214 | u32 vlan_id[GELIC_NET_VLAN_MAX]; | ||
215 | int vlan_index; | ||
216 | |||
217 | struct gelic_net_descr_chain tx_chain; | ||
218 | struct gelic_net_descr_chain rx_chain; | ||
219 | /* gurad dmac descriptor chain*/ | ||
220 | spinlock_t chain_lock; | ||
221 | |||
222 | struct net_device_stats netdev_stats; | ||
223 | int rx_csum; | ||
224 | /* guard tx_dma_progress */ | ||
225 | spinlock_t tx_dma_lock; | ||
226 | int tx_dma_progress; | ||
227 | |||
228 | struct work_struct tx_timeout_task; | ||
229 | atomic_t tx_timeout_task_counter; | ||
230 | wait_queue_head_t waitq; | ||
231 | |||
232 | struct gelic_net_descr *tx_top, *rx_top; | ||
233 | struct gelic_net_descr descr[0]; | ||
234 | }; | ||
235 | |||
236 | |||
237 | extern unsigned long p_to_lp(long pa); | ||
238 | |||
239 | #endif /* _GELIC_NET_H */ | ||