1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2001,2002,2003,2004 Broadcom Corporation |
4 | * Copyright (c) 2006, 2007 Maciej W. Rozycki |
5 | * |
6 | * This driver is designed for the Broadcom SiByte SOC built-in |
7 | * Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp. |
8 | * |
9 | * Updated to the driver model and the PHY abstraction layer |
10 | * by Maciej W. Rozycki. |
11 | */ |
12 | |
13 | #include <linux/bug.h> |
14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> |
16 | #include <linux/string.h> |
17 | #include <linux/timer.h> |
18 | #include <linux/errno.h> |
19 | #include <linux/ioport.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/interrupt.h> |
22 | #include <linux/netdevice.h> |
23 | #include <linux/etherdevice.h> |
24 | #include <linux/skbuff.h> |
25 | #include <linux/bitops.h> |
26 | #include <linux/err.h> |
27 | #include <linux/ethtool.h> |
28 | #include <linux/mii.h> |
29 | #include <linux/phy.h> |
30 | #include <linux/platform_device.h> |
31 | #include <linux/prefetch.h> |
32 | |
33 | #include <asm/cache.h> |
34 | #include <asm/io.h> |
35 | #include <asm/processor.h> /* Processor type for cache alignment. */ |
36 | |
37 | /* Operational parameters that usually are not changed. */ |
38 | |
39 | #define CONFIG_SBMAC_COALESCE |
40 | |
41 | /* Time in jiffies before concluding the transmitter is hung. */ |
42 | #define TX_TIMEOUT (2*HZ) |
43 | |
44 | |
45 | MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)" ); |
46 | MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver" ); |
47 | |
48 | /* A few user-configurable values which may be modified when a driver |
49 | module is loaded. */ |
50 | |
51 | /* 1 normal messages, 0 quiet .. 7 verbose. */ |
52 | static int debug = 1; |
53 | module_param(debug, int, 0444); |
54 | MODULE_PARM_DESC(debug, "Debug messages" ); |
55 | |
56 | #ifdef CONFIG_SBMAC_COALESCE |
57 | static int int_pktcnt_tx = 255; |
58 | module_param(int_pktcnt_tx, int, 0444); |
59 | MODULE_PARM_DESC(int_pktcnt_tx, "TX packet count" ); |
60 | |
61 | static int int_timeout_tx = 255; |
62 | module_param(int_timeout_tx, int, 0444); |
63 | MODULE_PARM_DESC(int_timeout_tx, "TX timeout value" ); |
64 | |
65 | static int int_pktcnt_rx = 64; |
66 | module_param(int_pktcnt_rx, int, 0444); |
67 | MODULE_PARM_DESC(int_pktcnt_rx, "RX packet count" ); |
68 | |
69 | static int int_timeout_rx = 64; |
70 | module_param(int_timeout_rx, int, 0444); |
71 | MODULE_PARM_DESC(int_timeout_rx, "RX timeout value" ); |
72 | #endif |
73 | |
74 | #include <asm/sibyte/board.h> |
75 | #include <asm/sibyte/sb1250.h> |
76 | #if defined(CONFIG_SIBYTE_BCM1x80) |
77 | #include <asm/sibyte/bcm1480_regs.h> |
78 | #include <asm/sibyte/bcm1480_int.h> |
79 | #define R_MAC_DMA_OODPKTLOST_RX R_MAC_DMA_OODPKTLOST |
80 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) |
81 | #include <asm/sibyte/sb1250_regs.h> |
82 | #include <asm/sibyte/sb1250_int.h> |
83 | #else |
84 | #error invalid SiByte MAC configuration |
85 | #endif |
86 | #include <asm/sibyte/sb1250_scd.h> |
87 | #include <asm/sibyte/sb1250_mac.h> |
88 | #include <asm/sibyte/sb1250_dma.h> |
89 | |
90 | #if defined(CONFIG_SIBYTE_BCM1x80) |
91 | #define UNIT_INT(n) (K_BCM1480_INT_MAC_0 + ((n) * 2)) |
92 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) |
93 | #define UNIT_INT(n) (K_INT_MAC_0 + (n)) |
94 | #else |
95 | #error invalid SiByte MAC configuration |
96 | #endif |
97 | |
98 | #ifdef K_INT_PHY |
99 | #define SBMAC_PHY_INT K_INT_PHY |
100 | #else |
101 | #define SBMAC_PHY_INT PHY_POLL |
102 | #endif |
103 | |
104 | /********************************************************************** |
105 | * Simple types |
106 | ********************************************************************* */ |
107 | |
108 | enum sbmac_speed { |
109 | sbmac_speed_none = 0, |
110 | sbmac_speed_10 = SPEED_10, |
111 | sbmac_speed_100 = SPEED_100, |
112 | sbmac_speed_1000 = SPEED_1000, |
113 | }; |
114 | |
115 | enum sbmac_duplex { |
116 | sbmac_duplex_none = -1, |
117 | sbmac_duplex_half = DUPLEX_HALF, |
118 | sbmac_duplex_full = DUPLEX_FULL, |
119 | }; |
120 | |
121 | enum sbmac_fc { |
122 | sbmac_fc_none, |
123 | sbmac_fc_disabled, |
124 | sbmac_fc_frame, |
125 | sbmac_fc_collision, |
126 | sbmac_fc_carrier, |
127 | }; |
128 | |
129 | enum sbmac_state { |
130 | sbmac_state_uninit, |
131 | sbmac_state_off, |
132 | sbmac_state_on, |
133 | sbmac_state_broken, |
134 | }; |
135 | |
136 | |
137 | /********************************************************************** |
138 | * Macros |
139 | ********************************************************************* */ |
140 | |
141 | |
142 | #define SBDMA_NEXTBUF(d,f) ((((d)->f+1) == (d)->sbdma_dscrtable_end) ? \ |
143 | (d)->sbdma_dscrtable : (d)->f+1) |
144 | |
145 | |
146 | #define NUMCACHEBLKS(x) DIV_ROUND_UP(x, SMP_CACHE_BYTES) |
147 | |
148 | #define SBMAC_MAX_TXDESCR 256 |
149 | #define SBMAC_MAX_RXDESCR 256 |
150 | |
151 | #define ENET_PACKET_SIZE 1518 |
152 | /*#define ENET_PACKET_SIZE 9216 */ |
153 | |
154 | /********************************************************************** |
155 | * DMA Descriptor structure |
156 | ********************************************************************* */ |
157 | |
158 | struct sbdmadscr { |
159 | uint64_t dscr_a; |
160 | uint64_t dscr_b; |
161 | }; |
162 | |
163 | /********************************************************************** |
164 | * DMA Controller structure |
165 | ********************************************************************* */ |
166 | |
167 | struct sbmacdma { |
168 | |
169 | /* |
170 | * This stuff is used to identify the channel and the registers |
171 | * associated with it. |
172 | */ |
173 | struct sbmac_softc *sbdma_eth; /* back pointer to associated |
174 | MAC */ |
175 | int sbdma_channel; /* channel number */ |
176 | int sbdma_txdir; /* direction (1=transmit) */ |
177 | int sbdma_maxdescr; /* total # of descriptors |
178 | in ring */ |
179 | #ifdef CONFIG_SBMAC_COALESCE |
180 | int sbdma_int_pktcnt; |
181 | /* # descriptors rx/tx |
182 | before interrupt */ |
183 | int sbdma_int_timeout; |
184 | /* # usec rx/tx interrupt */ |
185 | #endif |
186 | void __iomem *sbdma_config0; /* DMA config register 0 */ |
187 | void __iomem *sbdma_config1; /* DMA config register 1 */ |
188 | void __iomem *sbdma_dscrbase; |
189 | /* descriptor base address */ |
190 | void __iomem *sbdma_dscrcnt; /* descriptor count register */ |
191 | void __iomem *sbdma_curdscr; /* current descriptor |
192 | address */ |
193 | void __iomem *sbdma_oodpktlost; |
194 | /* pkt drop (rx only) */ |
195 | |
196 | /* |
197 | * This stuff is for maintenance of the ring |
198 | */ |
199 | void *sbdma_dscrtable_unaligned; |
200 | struct sbdmadscr *sbdma_dscrtable; |
201 | /* base of descriptor table */ |
202 | struct sbdmadscr *sbdma_dscrtable_end; |
203 | /* end of descriptor table */ |
204 | struct sk_buff **sbdma_ctxtable; |
205 | /* context table, one |
206 | per descr */ |
207 | dma_addr_t sbdma_dscrtable_phys; |
208 | /* and also the phys addr */ |
209 | struct sbdmadscr *sbdma_addptr; /* next dscr for sw to add */ |
210 | struct sbdmadscr *sbdma_remptr; /* next dscr for sw |
211 | to remove */ |
212 | }; |
213 | |
214 | |
215 | /********************************************************************** |
216 | * Ethernet softc structure |
217 | ********************************************************************* */ |
218 | |
219 | struct sbmac_softc { |
220 | |
221 | /* |
222 | * Linux-specific things |
223 | */ |
224 | struct net_device *sbm_dev; /* pointer to linux device */ |
225 | struct napi_struct napi; |
226 | struct phy_device *phy_dev; /* the associated PHY device */ |
227 | struct mii_bus *mii_bus; /* the MII bus */ |
228 | spinlock_t sbm_lock; /* spin lock */ |
229 | int sbm_devflags; /* current device flags */ |
230 | |
231 | /* |
232 | * Controller-specific things |
233 | */ |
234 | void __iomem *sbm_base; /* MAC's base address */ |
235 | enum sbmac_state sbm_state; /* current state */ |
236 | |
237 | void __iomem *sbm_macenable; /* MAC Enable Register */ |
238 | void __iomem *sbm_maccfg; /* MAC Config Register */ |
239 | void __iomem *sbm_fifocfg; /* FIFO Config Register */ |
240 | void __iomem *sbm_framecfg; /* Frame Config Register */ |
241 | void __iomem *sbm_rxfilter; /* Receive Filter Register */ |
242 | void __iomem *sbm_isr; /* Interrupt Status Register */ |
243 | void __iomem *sbm_imr; /* Interrupt Mask Register */ |
244 | void __iomem *sbm_mdio; /* MDIO Register */ |
245 | |
246 | enum sbmac_speed sbm_speed; /* current speed */ |
247 | enum sbmac_duplex sbm_duplex; /* current duplex */ |
248 | enum sbmac_fc sbm_fc; /* cur. flow control setting */ |
249 | int sbm_pause; /* current pause setting */ |
250 | int sbm_link; /* current link state */ |
251 | |
252 | unsigned char sbm_hwaddr[ETH_ALEN]; |
253 | |
254 | struct sbmacdma sbm_txdma; /* only channel 0 for now */ |
255 | struct sbmacdma sbm_rxdma; |
256 | int rx_hw_checksum; |
257 | int sbe_idx; |
258 | }; |
259 | |
260 | |
261 | /********************************************************************** |
262 | * Externs |
263 | ********************************************************************* */ |
264 | |
265 | /********************************************************************** |
266 | * Prototypes |
267 | ********************************************************************* */ |
268 | |
269 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, |
270 | int txrx, int maxdescr); |
271 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx); |
272 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
273 | struct sk_buff *m); |
274 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); |
275 | static void sbdma_emptyring(struct sbmacdma *d); |
276 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d); |
277 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
278 | int work_to_do, int poll); |
279 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
280 | int poll); |
281 | static int sbmac_initctx(struct sbmac_softc *s); |
282 | static void sbmac_channel_start(struct sbmac_softc *s); |
283 | static void sbmac_channel_stop(struct sbmac_softc *s); |
284 | static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *, |
285 | enum sbmac_state); |
286 | static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff); |
287 | static uint64_t sbmac_addr2reg(unsigned char *ptr); |
288 | static irqreturn_t sbmac_intr(int irq, void *dev_instance); |
289 | static netdev_tx_t sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); |
290 | static void sbmac_setmulti(struct sbmac_softc *sc); |
291 | static int sbmac_init(struct platform_device *pldev, long long base); |
292 | static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed); |
293 | static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex, |
294 | enum sbmac_fc fc); |
295 | |
296 | static int sbmac_open(struct net_device *dev); |
297 | static void sbmac_tx_timeout (struct net_device *dev, unsigned int txqueue); |
298 | static void sbmac_set_rx_mode(struct net_device *dev); |
299 | static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
300 | static int sbmac_close(struct net_device *dev); |
301 | static int sbmac_poll(struct napi_struct *napi, int budget); |
302 | |
303 | static void sbmac_mii_poll(struct net_device *dev); |
304 | static int sbmac_mii_probe(struct net_device *dev); |
305 | |
306 | static void sbmac_mii_sync(void __iomem *sbm_mdio); |
307 | static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data, |
308 | int bitcnt); |
309 | static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx); |
310 | static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, |
311 | u16 val); |
312 | |
313 | |
314 | /********************************************************************** |
315 | * Globals |
316 | ********************************************************************* */ |
317 | |
318 | static char sbmac_string[] = "sb1250-mac" ; |
319 | |
320 | static char sbmac_mdio_string[] = "sb1250-mac-mdio" ; |
321 | |
322 | |
323 | /********************************************************************** |
324 | * MDIO constants |
325 | ********************************************************************* */ |
326 | |
327 | #define MII_COMMAND_START 0x01 |
328 | #define MII_COMMAND_READ 0x02 |
329 | #define MII_COMMAND_WRITE 0x01 |
330 | #define MII_COMMAND_ACK 0x02 |
331 | |
332 | #define M_MAC_MDIO_DIR_OUTPUT 0 /* for clarity */ |
333 | |
334 | #define ENABLE 1 |
335 | #define DISABLE 0 |
336 | |
337 | /********************************************************************** |
338 | * SBMAC_MII_SYNC(sbm_mdio) |
339 | * |
340 | * Synchronize with the MII - send a pattern of bits to the MII |
341 | * that will guarantee that it is ready to accept a command. |
342 | * |
343 | * Input parameters: |
344 | * sbm_mdio - address of the MAC's MDIO register |
345 | * |
346 | * Return value: |
347 | * nothing |
348 | ********************************************************************* */ |
349 | |
350 | static void sbmac_mii_sync(void __iomem *sbm_mdio) |
351 | { |
352 | int cnt; |
353 | uint64_t bits; |
354 | int mac_mdio_genc; |
355 | |
356 | mac_mdio_genc = __raw_readq(addr: sbm_mdio) & M_MAC_GENC; |
357 | |
358 | bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT; |
359 | |
360 | __raw_writeq(val: bits | mac_mdio_genc, addr: sbm_mdio); |
361 | |
362 | for (cnt = 0; cnt < 32; cnt++) { |
363 | __raw_writeq(val: bits | M_MAC_MDC | mac_mdio_genc, addr: sbm_mdio); |
364 | __raw_writeq(val: bits | mac_mdio_genc, addr: sbm_mdio); |
365 | } |
366 | } |
367 | |
368 | /********************************************************************** |
369 | * SBMAC_MII_SENDDATA(sbm_mdio, data, bitcnt) |
370 | * |
371 | * Send some bits to the MII. The bits to be sent are right- |
372 | * justified in the 'data' parameter. |
373 | * |
374 | * Input parameters: |
375 | * sbm_mdio - address of the MAC's MDIO register |
376 | * data - data to send |
377 | * bitcnt - number of bits to send |
378 | ********************************************************************* */ |
379 | |
380 | static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data, |
381 | int bitcnt) |
382 | { |
383 | int i; |
384 | uint64_t bits; |
385 | unsigned int curmask; |
386 | int mac_mdio_genc; |
387 | |
388 | mac_mdio_genc = __raw_readq(addr: sbm_mdio) & M_MAC_GENC; |
389 | |
390 | bits = M_MAC_MDIO_DIR_OUTPUT; |
391 | __raw_writeq(val: bits | mac_mdio_genc, addr: sbm_mdio); |
392 | |
393 | curmask = 1 << (bitcnt - 1); |
394 | |
395 | for (i = 0; i < bitcnt; i++) { |
396 | if (data & curmask) |
397 | bits |= M_MAC_MDIO_OUT; |
398 | else bits &= ~M_MAC_MDIO_OUT; |
399 | __raw_writeq(val: bits | mac_mdio_genc, addr: sbm_mdio); |
400 | __raw_writeq(val: bits | M_MAC_MDC | mac_mdio_genc, addr: sbm_mdio); |
401 | __raw_writeq(val: bits | mac_mdio_genc, addr: sbm_mdio); |
402 | curmask >>= 1; |
403 | } |
404 | } |
405 | |
406 | |
407 | |
408 | /********************************************************************** |
409 | * SBMAC_MII_READ(bus, phyaddr, regidx) |
410 | * Read a PHY register. |
411 | * |
412 | * Input parameters: |
413 | * bus - MDIO bus handle |
414 | * phyaddr - PHY's address |
415 | * regnum - index of register to read |
416 | * |
417 | * Return value: |
418 | * value read, or 0xffff if an error occurred. |
419 | ********************************************************************* */ |
420 | |
421 | static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx) |
422 | { |
423 | struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; |
424 | void __iomem *sbm_mdio = sc->sbm_mdio; |
425 | int idx; |
426 | int error; |
427 | int regval; |
428 | int mac_mdio_genc; |
429 | |
430 | /* |
431 | * Synchronize ourselves so that the PHY knows the next |
432 | * thing coming down is a command |
433 | */ |
434 | sbmac_mii_sync(sbm_mdio); |
435 | |
436 | /* |
437 | * Send the data to the PHY. The sequence is |
438 | * a "start" command (2 bits) |
439 | * a "read" command (2 bits) |
440 | * the PHY addr (5 bits) |
441 | * the register index (5 bits) |
442 | */ |
443 | sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, bitcnt: 2); |
444 | sbmac_mii_senddata(sbm_mdio, MII_COMMAND_READ, bitcnt: 2); |
445 | sbmac_mii_senddata(sbm_mdio, data: phyaddr, bitcnt: 5); |
446 | sbmac_mii_senddata(sbm_mdio, data: regidx, bitcnt: 5); |
447 | |
448 | mac_mdio_genc = __raw_readq(addr: sbm_mdio) & M_MAC_GENC; |
449 | |
450 | /* |
451 | * Switch the port around without a clock transition. |
452 | */ |
453 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, addr: sbm_mdio); |
454 | |
455 | /* |
456 | * Send out a clock pulse to signal we want the status |
457 | */ |
458 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, |
459 | addr: sbm_mdio); |
460 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, addr: sbm_mdio); |
461 | |
462 | /* |
463 | * If an error occurred, the PHY will signal '1' back |
464 | */ |
465 | error = __raw_readq(addr: sbm_mdio) & M_MAC_MDIO_IN; |
466 | |
467 | /* |
468 | * Issue an 'idle' clock pulse, but keep the direction |
469 | * the same. |
470 | */ |
471 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, |
472 | addr: sbm_mdio); |
473 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, addr: sbm_mdio); |
474 | |
475 | regval = 0; |
476 | |
477 | for (idx = 0; idx < 16; idx++) { |
478 | regval <<= 1; |
479 | |
480 | if (error == 0) { |
481 | if (__raw_readq(addr: sbm_mdio) & M_MAC_MDIO_IN) |
482 | regval |= 1; |
483 | } |
484 | |
485 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, |
486 | addr: sbm_mdio); |
487 | __raw_writeq(val: M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, addr: sbm_mdio); |
488 | } |
489 | |
490 | /* Switch back to output */ |
491 | __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, addr: sbm_mdio); |
492 | |
493 | if (error == 0) |
494 | return regval; |
495 | return 0xffff; |
496 | } |
497 | |
498 | |
499 | /********************************************************************** |
500 | * SBMAC_MII_WRITE(bus, phyaddr, regidx, regval) |
501 | * |
502 | * Write a value to a PHY register. |
503 | * |
504 | * Input parameters: |
505 | * bus - MDIO bus handle |
506 | * phyaddr - PHY to use |
507 | * regidx - register within the PHY |
508 | * regval - data to write to register |
509 | * |
510 | * Return value: |
511 | * 0 for success |
512 | ********************************************************************* */ |
513 | |
514 | static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, |
515 | u16 regval) |
516 | { |
517 | struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; |
518 | void __iomem *sbm_mdio = sc->sbm_mdio; |
519 | int mac_mdio_genc; |
520 | |
521 | sbmac_mii_sync(sbm_mdio); |
522 | |
523 | sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, bitcnt: 2); |
524 | sbmac_mii_senddata(sbm_mdio, MII_COMMAND_WRITE, bitcnt: 2); |
525 | sbmac_mii_senddata(sbm_mdio, data: phyaddr, bitcnt: 5); |
526 | sbmac_mii_senddata(sbm_mdio, data: regidx, bitcnt: 5); |
527 | sbmac_mii_senddata(sbm_mdio, MII_COMMAND_ACK, bitcnt: 2); |
528 | sbmac_mii_senddata(sbm_mdio, data: regval, bitcnt: 16); |
529 | |
530 | mac_mdio_genc = __raw_readq(addr: sbm_mdio) & M_MAC_GENC; |
531 | |
532 | __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, addr: sbm_mdio); |
533 | |
534 | return 0; |
535 | } |
536 | |
537 | |
538 | |
539 | /********************************************************************** |
540 | * SBDMA_INITCTX(d,s,chan,txrx,maxdescr) |
541 | * |
542 | * Initialize a DMA channel context. Since there are potentially |
543 | * eight DMA channels per MAC, it's nice to do this in a standard |
544 | * way. |
545 | * |
546 | * Input parameters: |
547 | * d - struct sbmacdma (DMA channel context) |
548 | * s - struct sbmac_softc (pointer to a MAC) |
549 | * chan - channel number (0..1 right now) |
550 | * txrx - Identifies DMA_TX or DMA_RX for channel direction |
551 | * maxdescr - number of descriptors |
552 | * |
553 | * Return value: |
554 | * nothing |
555 | ********************************************************************* */ |
556 | |
557 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, |
558 | int txrx, int maxdescr) |
559 | { |
560 | #ifdef CONFIG_SBMAC_COALESCE |
561 | int int_pktcnt, int_timeout; |
562 | #endif |
563 | |
564 | /* |
565 | * Save away interesting stuff in the structure |
566 | */ |
567 | |
568 | d->sbdma_eth = s; |
569 | d->sbdma_channel = chan; |
570 | d->sbdma_txdir = txrx; |
571 | |
572 | #if 0 |
573 | /* RMON clearing */ |
574 | s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; |
575 | #endif |
576 | |
577 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_BYTES); |
578 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_COLLISIONS); |
579 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_LATE_COL); |
580 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_EX_COL); |
581 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_FCS_ERROR); |
582 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_ABORT); |
583 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_BAD); |
584 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_GOOD); |
585 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_RUNT); |
586 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_TX_OVERSIZE); |
587 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_BYTES); |
588 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_MCAST); |
589 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_BCAST); |
590 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_BAD); |
591 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_GOOD); |
592 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_RUNT); |
593 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_OVERSIZE); |
594 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_FCS_ERROR); |
595 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_LENGTH_ERROR); |
596 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_CODE_ERROR); |
597 | __raw_writeq(val: 0, addr: s->sbm_base + R_MAC_RMON_RX_ALIGN_ERROR); |
598 | |
599 | /* |
600 | * initialize register pointers |
601 | */ |
602 | |
603 | d->sbdma_config0 = |
604 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); |
605 | d->sbdma_config1 = |
606 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); |
607 | d->sbdma_dscrbase = |
608 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); |
609 | d->sbdma_dscrcnt = |
610 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); |
611 | d->sbdma_curdscr = |
612 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); |
613 | if (d->sbdma_txdir) |
614 | d->sbdma_oodpktlost = NULL; |
615 | else |
616 | d->sbdma_oodpktlost = |
617 | s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_OODPKTLOST_RX); |
618 | |
619 | /* |
620 | * Allocate memory for the ring |
621 | */ |
622 | |
623 | d->sbdma_maxdescr = maxdescr; |
624 | |
625 | d->sbdma_dscrtable_unaligned = kcalloc(n: d->sbdma_maxdescr + 1, |
626 | size: sizeof(*d->sbdma_dscrtable), |
627 | GFP_KERNEL); |
628 | |
629 | /* |
630 | * The descriptor table must be aligned to at least 16 bytes or the |
631 | * MAC will corrupt it. |
632 | */ |
633 | d->sbdma_dscrtable = (struct sbdmadscr *) |
634 | ALIGN((unsigned long)d->sbdma_dscrtable_unaligned, |
635 | sizeof(*d->sbdma_dscrtable)); |
636 | |
637 | d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; |
638 | |
639 | d->sbdma_dscrtable_phys = virt_to_phys(address: d->sbdma_dscrtable); |
640 | |
641 | /* |
642 | * And context table |
643 | */ |
644 | |
645 | d->sbdma_ctxtable = kcalloc(n: d->sbdma_maxdescr, |
646 | size: sizeof(*d->sbdma_ctxtable), GFP_KERNEL); |
647 | |
648 | #ifdef CONFIG_SBMAC_COALESCE |
649 | /* |
650 | * Setup Rx/Tx DMA coalescing defaults |
651 | */ |
652 | |
653 | int_pktcnt = (txrx == DMA_TX) ? int_pktcnt_tx : int_pktcnt_rx; |
654 | if ( int_pktcnt ) { |
655 | d->sbdma_int_pktcnt = int_pktcnt; |
656 | } else { |
657 | d->sbdma_int_pktcnt = 1; |
658 | } |
659 | |
660 | int_timeout = (txrx == DMA_TX) ? int_timeout_tx : int_timeout_rx; |
661 | if ( int_timeout ) { |
662 | d->sbdma_int_timeout = int_timeout; |
663 | } else { |
664 | d->sbdma_int_timeout = 0; |
665 | } |
666 | #endif |
667 | |
668 | } |
669 | |
670 | /********************************************************************** |
671 | * SBDMA_CHANNEL_START(d) |
672 | * |
673 | * Initialize the hardware registers for a DMA channel. |
674 | * |
675 | * Input parameters: |
676 | * d - DMA channel to init (context must be previously init'd |
677 | * rxtx - DMA_RX or DMA_TX depending on what type of channel |
678 | * |
679 | * Return value: |
680 | * nothing |
681 | ********************************************************************* */ |
682 | |
683 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx) |
684 | { |
685 | /* |
686 | * Turn on the DMA channel |
687 | */ |
688 | |
689 | #ifdef CONFIG_SBMAC_COALESCE |
690 | __raw_writeq(val: V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | |
691 | 0, addr: d->sbdma_config1); |
692 | __raw_writeq(M_DMA_EOP_INT_EN | |
693 | V_DMA_RINGSZ(d->sbdma_maxdescr) | |
694 | V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | |
695 | 0, d->sbdma_config0); |
696 | #else |
697 | __raw_writeq(0, d->sbdma_config1); |
698 | __raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) | |
699 | 0, d->sbdma_config0); |
700 | #endif |
701 | |
702 | __raw_writeq(val: d->sbdma_dscrtable_phys, addr: d->sbdma_dscrbase); |
703 | |
704 | /* |
705 | * Initialize ring pointers |
706 | */ |
707 | |
708 | d->sbdma_addptr = d->sbdma_dscrtable; |
709 | d->sbdma_remptr = d->sbdma_dscrtable; |
710 | } |
711 | |
712 | /********************************************************************** |
713 | * SBDMA_CHANNEL_STOP(d) |
714 | * |
715 | * Initialize the hardware registers for a DMA channel. |
716 | * |
717 | * Input parameters: |
718 | * d - DMA channel to init (context must be previously init'd |
719 | * |
720 | * Return value: |
721 | * nothing |
722 | ********************************************************************* */ |
723 | |
724 | static void sbdma_channel_stop(struct sbmacdma *d) |
725 | { |
726 | /* |
727 | * Turn off the DMA channel |
728 | */ |
729 | |
730 | __raw_writeq(val: 0, addr: d->sbdma_config1); |
731 | |
732 | __raw_writeq(val: 0, addr: d->sbdma_dscrbase); |
733 | |
734 | __raw_writeq(val: 0, addr: d->sbdma_config0); |
735 | |
736 | /* |
737 | * Zero ring pointers |
738 | */ |
739 | |
740 | d->sbdma_addptr = NULL; |
741 | d->sbdma_remptr = NULL; |
742 | } |
743 | |
744 | static inline void sbdma_align_skb(struct sk_buff *skb, |
745 | unsigned int power2, unsigned int offset) |
746 | { |
747 | unsigned char *addr = skb->data; |
748 | unsigned char *newaddr = PTR_ALIGN(addr, power2); |
749 | |
750 | skb_reserve(skb, len: newaddr - addr + offset); |
751 | } |
752 | |
753 | |
754 | /********************************************************************** |
755 | * SBDMA_ADD_RCVBUFFER(d,sb) |
756 | * |
757 | * Add a buffer to the specified DMA channel. For receive channels, |
758 | * this queues a buffer for inbound packets. |
759 | * |
760 | * Input parameters: |
761 | * sc - softc structure |
762 | * d - DMA channel descriptor |
763 | * sb - sk_buff to add, or NULL if we should allocate one |
764 | * |
765 | * Return value: |
766 | * 0 if buffer could not be added (ring is full) |
767 | * 1 if buffer added successfully |
768 | ********************************************************************* */ |
769 | |
770 | |
771 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
772 | struct sk_buff *sb) |
773 | { |
774 | struct net_device *dev = sc->sbm_dev; |
775 | struct sbdmadscr *dsc; |
776 | struct sbdmadscr *nextdsc; |
777 | struct sk_buff *sb_new = NULL; |
778 | int pktsize = ENET_PACKET_SIZE; |
779 | |
780 | /* get pointer to our current place in the ring */ |
781 | |
782 | dsc = d->sbdma_addptr; |
783 | nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr); |
784 | |
785 | /* |
786 | * figure out if the ring is full - if the next descriptor |
787 | * is the same as the one that we're going to remove from |
788 | * the ring, the ring is full |
789 | */ |
790 | |
791 | if (nextdsc == d->sbdma_remptr) { |
792 | return -ENOSPC; |
793 | } |
794 | |
795 | /* |
796 | * Allocate a sk_buff if we don't already have one. |
797 | * If we do have an sk_buff, reset it so that it's empty. |
798 | * |
799 | * Note: sk_buffs don't seem to be guaranteed to have any sort |
800 | * of alignment when they are allocated. Therefore, allocate enough |
801 | * extra space to make sure that: |
802 | * |
803 | * 1. the data does not start in the middle of a cache line. |
804 | * 2. The data does not end in the middle of a cache line |
805 | * 3. The buffer can be aligned such that the IP addresses are |
806 | * naturally aligned. |
807 | * |
808 | * Remember, the SOCs MAC writes whole cache lines at a time, |
809 | * without reading the old contents first. So, if the sk_buff's |
810 | * data portion starts in the middle of a cache line, the SOC |
811 | * DMA will trash the beginning (and ending) portions. |
812 | */ |
813 | |
814 | if (sb == NULL) { |
815 | sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE + |
816 | SMP_CACHE_BYTES * 2 + |
817 | NET_IP_ALIGN); |
818 | if (sb_new == NULL) |
819 | return -ENOBUFS; |
820 | |
821 | sbdma_align_skb(skb: sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN); |
822 | } |
823 | else { |
824 | sb_new = sb; |
825 | /* |
826 | * nothing special to reinit buffer, it's already aligned |
827 | * and sb->data already points to a good place. |
828 | */ |
829 | } |
830 | |
831 | /* |
832 | * fill in the descriptor |
833 | */ |
834 | |
835 | #ifdef CONFIG_SBMAC_COALESCE |
836 | /* |
837 | * Do not interrupt per DMA transfer. |
838 | */ |
839 | dsc->dscr_a = virt_to_phys(address: sb_new->data) | |
840 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | 0; |
841 | #else |
842 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
843 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | |
844 | M_DMA_DSCRA_INTERRUPT; |
845 | #endif |
846 | |
847 | /* receiving: no options */ |
848 | dsc->dscr_b = 0; |
849 | |
850 | /* |
851 | * fill in the context |
852 | */ |
853 | |
854 | d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new; |
855 | |
856 | /* |
857 | * point at next packet |
858 | */ |
859 | |
860 | d->sbdma_addptr = nextdsc; |
861 | |
862 | /* |
863 | * Give the buffer to the DMA engine. |
864 | */ |
865 | |
866 | __raw_writeq(val: 1, addr: d->sbdma_dscrcnt); |
867 | |
868 | return 0; /* we did it */ |
869 | } |
870 | |
871 | /********************************************************************** |
872 | * SBDMA_ADD_TXBUFFER(d,sb) |
873 | * |
874 | * Add a transmit buffer to the specified DMA channel, causing a |
875 | * transmit to start. |
876 | * |
877 | * Input parameters: |
878 | * d - DMA channel descriptor |
879 | * sb - sk_buff to add |
880 | * |
881 | * Return value: |
882 | * 0 transmit queued successfully |
883 | * otherwise error code |
884 | ********************************************************************* */ |
885 | |
886 | |
887 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *sb) |
888 | { |
889 | struct sbdmadscr *dsc; |
890 | struct sbdmadscr *nextdsc; |
891 | uint64_t phys; |
892 | uint64_t ncb; |
893 | int length; |
894 | |
895 | /* get pointer to our current place in the ring */ |
896 | |
897 | dsc = d->sbdma_addptr; |
898 | nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr); |
899 | |
900 | /* |
901 | * figure out if the ring is full - if the next descriptor |
902 | * is the same as the one that we're going to remove from |
903 | * the ring, the ring is full |
904 | */ |
905 | |
906 | if (nextdsc == d->sbdma_remptr) { |
907 | return -ENOSPC; |
908 | } |
909 | |
910 | /* |
911 | * Under Linux, it's not necessary to copy/coalesce buffers |
912 | * like it is on NetBSD. We think they're all contiguous, |
913 | * but that may not be true for GBE. |
914 | */ |
915 | |
916 | length = sb->len; |
917 | |
918 | /* |
919 | * fill in the descriptor. Note that the number of cache |
920 | * blocks in the descriptor is the number of blocks |
921 | * *spanned*, so we need to add in the offset (if any) |
922 | * while doing the calculation. |
923 | */ |
924 | |
925 | phys = virt_to_phys(address: sb->data); |
926 | ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); |
927 | |
928 | dsc->dscr_a = phys | |
929 | V_DMA_DSCRA_A_SIZE(ncb) | |
930 | #ifndef CONFIG_SBMAC_COALESCE |
931 | M_DMA_DSCRA_INTERRUPT | |
932 | #endif |
933 | M_DMA_ETHTX_SOP; |
934 | |
935 | /* transmitting: set outbound options and length */ |
936 | |
937 | dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) | |
938 | V_DMA_DSCRB_PKT_SIZE(length); |
939 | |
940 | /* |
941 | * fill in the context |
942 | */ |
943 | |
944 | d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb; |
945 | |
946 | /* |
947 | * point at next packet |
948 | */ |
949 | |
950 | d->sbdma_addptr = nextdsc; |
951 | |
952 | /* |
953 | * Give the buffer to the DMA engine. |
954 | */ |
955 | |
956 | __raw_writeq(val: 1, addr: d->sbdma_dscrcnt); |
957 | |
958 | return 0; /* we did it */ |
959 | } |
960 | |
961 | |
962 | |
963 | |
964 | /********************************************************************** |
965 | * SBDMA_EMPTYRING(d) |
966 | * |
967 | * Free all allocated sk_buffs on the specified DMA channel; |
968 | * |
969 | * Input parameters: |
970 | * d - DMA channel |
971 | * |
972 | * Return value: |
973 | * nothing |
974 | ********************************************************************* */ |
975 | |
976 | static void sbdma_emptyring(struct sbmacdma *d) |
977 | { |
978 | int idx; |
979 | struct sk_buff *sb; |
980 | |
981 | for (idx = 0; idx < d->sbdma_maxdescr; idx++) { |
982 | sb = d->sbdma_ctxtable[idx]; |
983 | if (sb) { |
984 | dev_kfree_skb(sb); |
985 | d->sbdma_ctxtable[idx] = NULL; |
986 | } |
987 | } |
988 | } |
989 | |
990 | |
991 | /********************************************************************** |
992 | * SBDMA_FILLRING(d) |
993 | * |
994 | * Fill the specified DMA channel (must be receive channel) |
995 | * with sk_buffs |
996 | * |
997 | * Input parameters: |
998 | * sc - softc structure |
999 | * d - DMA channel |
1000 | * |
1001 | * Return value: |
1002 | * nothing |
1003 | ********************************************************************* */ |
1004 | |
1005 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d) |
1006 | { |
1007 | int idx; |
1008 | |
1009 | for (idx = 0; idx < SBMAC_MAX_RXDESCR - 1; idx++) { |
1010 | if (sbdma_add_rcvbuffer(sc, d, NULL) != 0) |
1011 | break; |
1012 | } |
1013 | } |
1014 | |
1015 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1016 | static void sbmac_netpoll(struct net_device *netdev) |
1017 | { |
1018 | struct sbmac_softc *sc = netdev_priv(dev: netdev); |
1019 | int irq = sc->sbm_dev->irq; |
1020 | |
1021 | __raw_writeq(val: 0, addr: sc->sbm_imr); |
1022 | |
1023 | sbmac_intr(irq, dev_instance: netdev); |
1024 | |
1025 | #ifdef CONFIG_SBMAC_COALESCE |
1026 | __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | |
1027 | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), |
1028 | sc->sbm_imr); |
1029 | #else |
1030 | __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | |
1031 | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); |
1032 | #endif |
1033 | } |
1034 | #endif |
1035 | |
1036 | /********************************************************************** |
1037 | * SBDMA_RX_PROCESS(sc,d,work_to_do,poll) |
1038 | * |
1039 | * Process "completed" receive buffers on the specified DMA channel. |
1040 | * |
1041 | * Input parameters: |
1042 | * sc - softc structure |
1043 | * d - DMA channel context |
1044 | * work_to_do - no. of packets to process before enabling interrupt |
1045 | * again (for NAPI) |
1046 | * poll - 1: using polling (for NAPI) |
1047 | * |
1048 | * Return value: |
1049 | * nothing |
1050 | ********************************************************************* */ |
1051 | |
1052 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
1053 | int work_to_do, int poll) |
1054 | { |
1055 | struct net_device *dev = sc->sbm_dev; |
1056 | int curidx; |
1057 | int hwidx; |
1058 | struct sbdmadscr *dsc; |
1059 | struct sk_buff *sb; |
1060 | int len; |
1061 | int work_done = 0; |
1062 | int dropped = 0; |
1063 | |
1064 | prefetch(d); |
1065 | |
1066 | again: |
1067 | /* Check if the HW dropped any frames */ |
1068 | dev->stats.rx_fifo_errors |
1069 | += __raw_readq(addr: sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff; |
1070 | __raw_writeq(val: 0, addr: sc->sbm_rxdma.sbdma_oodpktlost); |
1071 | |
1072 | while (work_to_do-- > 0) { |
1073 | /* |
1074 | * figure out where we are (as an index) and where |
1075 | * the hardware is (also as an index) |
1076 | * |
1077 | * This could be done faster if (for example) the |
1078 | * descriptor table was page-aligned and contiguous in |
1079 | * both virtual and physical memory -- you could then |
1080 | * just compare the low-order bits of the virtual address |
1081 | * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) |
1082 | */ |
1083 | |
1084 | dsc = d->sbdma_remptr; |
1085 | curidx = dsc - d->sbdma_dscrtable; |
1086 | |
1087 | prefetch(dsc); |
1088 | prefetch(&d->sbdma_ctxtable[curidx]); |
1089 | |
1090 | hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - |
1091 | d->sbdma_dscrtable_phys) / |
1092 | sizeof(*d->sbdma_dscrtable); |
1093 | |
1094 | /* |
1095 | * If they're the same, that means we've processed all |
1096 | * of the descriptors up to (but not including) the one that |
1097 | * the hardware is working on right now. |
1098 | */ |
1099 | |
1100 | if (curidx == hwidx) |
1101 | goto done; |
1102 | |
1103 | /* |
1104 | * Otherwise, get the packet's sk_buff ptr back |
1105 | */ |
1106 | |
1107 | sb = d->sbdma_ctxtable[curidx]; |
1108 | d->sbdma_ctxtable[curidx] = NULL; |
1109 | |
1110 | len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4; |
1111 | |
1112 | /* |
1113 | * Check packet status. If good, process it. |
1114 | * If not, silently drop it and put it back on the |
1115 | * receive ring. |
1116 | */ |
1117 | |
1118 | if (likely (!(dsc->dscr_a & M_DMA_ETHRX_BAD))) { |
1119 | |
1120 | /* |
1121 | * Add a new buffer to replace the old one. If we fail |
1122 | * to allocate a buffer, we're going to drop this |
1123 | * packet and put it right back on the receive ring. |
1124 | */ |
1125 | |
1126 | if (unlikely(sbdma_add_rcvbuffer(sc, d, NULL) == |
1127 | -ENOBUFS)) { |
1128 | dev->stats.rx_dropped++; |
1129 | /* Re-add old buffer */ |
1130 | sbdma_add_rcvbuffer(sc, d, sb); |
1131 | /* No point in continuing at the moment */ |
1132 | printk(KERN_ERR "dropped packet (1)\n" ); |
1133 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
1134 | goto done; |
1135 | } else { |
1136 | /* |
1137 | * Set length into the packet |
1138 | */ |
1139 | skb_put(skb: sb,len); |
1140 | |
1141 | /* |
1142 | * Buffer has been replaced on the |
1143 | * receive ring. Pass the buffer to |
1144 | * the kernel |
1145 | */ |
1146 | sb->protocol = eth_type_trans(skb: sb,dev: d->sbdma_eth->sbm_dev); |
1147 | /* Check hw IPv4/TCP checksum if supported */ |
1148 | if (sc->rx_hw_checksum == ENABLE) { |
1149 | if (!((dsc->dscr_a) & M_DMA_ETHRX_BADIP4CS) && |
1150 | !((dsc->dscr_a) & M_DMA_ETHRX_BADTCPCS)) { |
1151 | sb->ip_summed = CHECKSUM_UNNECESSARY; |
1152 | /* don't need to set sb->csum */ |
1153 | } else { |
1154 | skb_checksum_none_assert(skb: sb); |
1155 | } |
1156 | } |
1157 | prefetch(sb->data); |
1158 | prefetch((const void *)(((char *)sb->data)+32)); |
1159 | if (poll) |
1160 | dropped = netif_receive_skb(skb: sb); |
1161 | else |
1162 | dropped = netif_rx(skb: sb); |
1163 | |
1164 | if (dropped == NET_RX_DROP) { |
1165 | dev->stats.rx_dropped++; |
1166 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
1167 | goto done; |
1168 | } |
1169 | else { |
1170 | dev->stats.rx_bytes += len; |
1171 | dev->stats.rx_packets++; |
1172 | } |
1173 | } |
1174 | } else { |
1175 | /* |
1176 | * Packet was mangled somehow. Just drop it and |
1177 | * put it back on the receive ring. |
1178 | */ |
1179 | dev->stats.rx_errors++; |
1180 | sbdma_add_rcvbuffer(sc, d, sb); |
1181 | } |
1182 | |
1183 | |
1184 | /* |
1185 | * .. and advance to the next buffer. |
1186 | */ |
1187 | |
1188 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
1189 | work_done++; |
1190 | } |
1191 | if (!poll) { |
1192 | work_to_do = 32; |
1193 | goto again; /* collect fifo drop statistics again */ |
1194 | } |
1195 | done: |
1196 | return work_done; |
1197 | } |
1198 | |
1199 | /********************************************************************** |
1200 | * SBDMA_TX_PROCESS(sc,d) |
1201 | * |
1202 | * Process "completed" transmit buffers on the specified DMA channel. |
1203 | * This is normally called within the interrupt service routine. |
1204 | * Note that this isn't really ideal for priority channels, since |
1205 | * it processes all of the packets on a given channel before |
1206 | * returning. |
1207 | * |
1208 | * Input parameters: |
1209 | * sc - softc structure |
1210 | * d - DMA channel context |
1211 | * poll - 1: using polling (for NAPI) |
1212 | * |
1213 | * Return value: |
1214 | * nothing |
1215 | ********************************************************************* */ |
1216 | |
1217 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
1218 | int poll) |
1219 | { |
1220 | struct net_device *dev = sc->sbm_dev; |
1221 | int curidx; |
1222 | int hwidx; |
1223 | struct sbdmadscr *dsc; |
1224 | struct sk_buff *sb; |
1225 | unsigned long flags; |
1226 | int packets_handled = 0; |
1227 | |
1228 | spin_lock_irqsave(&(sc->sbm_lock), flags); |
1229 | |
1230 | if (d->sbdma_remptr == d->sbdma_addptr) |
1231 | goto end_unlock; |
1232 | |
1233 | hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - |
1234 | d->sbdma_dscrtable_phys) / sizeof(*d->sbdma_dscrtable); |
1235 | |
1236 | for (;;) { |
1237 | /* |
1238 | * figure out where we are (as an index) and where |
1239 | * the hardware is (also as an index) |
1240 | * |
1241 | * This could be done faster if (for example) the |
1242 | * descriptor table was page-aligned and contiguous in |
1243 | * both virtual and physical memory -- you could then |
1244 | * just compare the low-order bits of the virtual address |
1245 | * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) |
1246 | */ |
1247 | |
1248 | curidx = d->sbdma_remptr - d->sbdma_dscrtable; |
1249 | |
1250 | /* |
1251 | * If they're the same, that means we've processed all |
1252 | * of the descriptors up to (but not including) the one that |
1253 | * the hardware is working on right now. |
1254 | */ |
1255 | |
1256 | if (curidx == hwidx) |
1257 | break; |
1258 | |
1259 | /* |
1260 | * Otherwise, get the packet's sk_buff ptr back |
1261 | */ |
1262 | |
1263 | dsc = &(d->sbdma_dscrtable[curidx]); |
1264 | sb = d->sbdma_ctxtable[curidx]; |
1265 | d->sbdma_ctxtable[curidx] = NULL; |
1266 | |
1267 | /* |
1268 | * Stats |
1269 | */ |
1270 | |
1271 | dev->stats.tx_bytes += sb->len; |
1272 | dev->stats.tx_packets++; |
1273 | |
1274 | /* |
1275 | * for transmits, we just free buffers. |
1276 | */ |
1277 | |
1278 | dev_consume_skb_irq(skb: sb); |
1279 | |
1280 | /* |
1281 | * .. and advance to the next buffer. |
1282 | */ |
1283 | |
1284 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
1285 | |
1286 | packets_handled++; |
1287 | |
1288 | } |
1289 | |
1290 | /* |
1291 | * Decide if we should wake up the protocol or not. |
1292 | * Other drivers seem to do this when we reach a low |
1293 | * watermark on the transmit queue. |
1294 | */ |
1295 | |
1296 | if (packets_handled) |
1297 | netif_wake_queue(dev: d->sbdma_eth->sbm_dev); |
1298 | |
1299 | end_unlock: |
1300 | spin_unlock_irqrestore(lock: &(sc->sbm_lock), flags); |
1301 | |
1302 | } |
1303 | |
1304 | |
1305 | |
1306 | /********************************************************************** |
1307 | * SBMAC_INITCTX(s) |
1308 | * |
1309 | * Initialize an Ethernet context structure - this is called |
1310 | * once per MAC on the 1250. Memory is allocated here, so don't |
1311 | * call it again from inside the ioctl routines that bring the |
1312 | * interface up/down |
1313 | * |
1314 | * Input parameters: |
1315 | * s - sbmac context structure |
1316 | * |
1317 | * Return value: |
1318 | * 0 |
1319 | ********************************************************************* */ |
1320 | |
1321 | static int sbmac_initctx(struct sbmac_softc *s) |
1322 | { |
1323 | |
1324 | /* |
1325 | * figure out the addresses of some ports |
1326 | */ |
1327 | |
1328 | s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; |
1329 | s->sbm_maccfg = s->sbm_base + R_MAC_CFG; |
1330 | s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; |
1331 | s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; |
1332 | s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; |
1333 | s->sbm_isr = s->sbm_base + R_MAC_STATUS; |
1334 | s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; |
1335 | s->sbm_mdio = s->sbm_base + R_MAC_MDIO; |
1336 | |
1337 | /* |
1338 | * Initialize the DMA channels. Right now, only one per MAC is used |
1339 | * Note: Only do this _once_, as it allocates memory from the kernel! |
1340 | */ |
1341 | |
1342 | sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR); |
1343 | sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR); |
1344 | |
1345 | /* |
1346 | * initial state is OFF |
1347 | */ |
1348 | |
1349 | s->sbm_state = sbmac_state_off; |
1350 | |
1351 | return 0; |
1352 | } |
1353 | |
1354 | |
1355 | static void sbdma_uninitctx(struct sbmacdma *d) |
1356 | { |
1357 | kfree(objp: d->sbdma_dscrtable_unaligned); |
1358 | d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = NULL; |
1359 | |
1360 | kfree(objp: d->sbdma_ctxtable); |
1361 | d->sbdma_ctxtable = NULL; |
1362 | } |
1363 | |
1364 | |
1365 | static void sbmac_uninitctx(struct sbmac_softc *sc) |
1366 | { |
1367 | sbdma_uninitctx(d: &(sc->sbm_txdma)); |
1368 | sbdma_uninitctx(d: &(sc->sbm_rxdma)); |
1369 | } |
1370 | |
1371 | |
1372 | /********************************************************************** |
1373 | * SBMAC_CHANNEL_START(s) |
1374 | * |
1375 | * Start packet processing on this MAC. |
1376 | * |
1377 | * Input parameters: |
1378 | * s - sbmac structure |
1379 | * |
1380 | * Return value: |
1381 | * nothing |
1382 | ********************************************************************* */ |
1383 | |
1384 | static void sbmac_channel_start(struct sbmac_softc *s) |
1385 | { |
1386 | uint64_t reg; |
1387 | void __iomem *port; |
1388 | uint64_t cfg,fifo,framecfg; |
1389 | int idx, th_value; |
1390 | |
1391 | /* |
1392 | * Don't do this if running |
1393 | */ |
1394 | |
1395 | if (s->sbm_state == sbmac_state_on) |
1396 | return; |
1397 | |
1398 | /* |
1399 | * Bring the controller out of reset, but leave it off. |
1400 | */ |
1401 | |
1402 | __raw_writeq(val: 0, addr: s->sbm_macenable); |
1403 | |
1404 | /* |
1405 | * Ignore all received packets |
1406 | */ |
1407 | |
1408 | __raw_writeq(val: 0, addr: s->sbm_rxfilter); |
1409 | |
1410 | /* |
1411 | * Calculate values for various control registers. |
1412 | */ |
1413 | |
1414 | cfg = M_MAC_RETRY_EN | |
1415 | M_MAC_TX_HOLD_SOP_EN | |
1416 | V_MAC_TX_PAUSE_CNT_16K | |
1417 | M_MAC_AP_STAT_EN | |
1418 | M_MAC_FAST_SYNC | |
1419 | M_MAC_SS_EN | |
1420 | 0; |
1421 | |
1422 | /* |
1423 | * Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars |
1424 | * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above |
1425 | * Use a larger RD_THRSH for gigabit |
1426 | */ |
1427 | if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) |
1428 | th_value = 28; |
1429 | else |
1430 | th_value = 64; |
1431 | |
1432 | fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ |
1433 | ((s->sbm_speed == sbmac_speed_1000) |
1434 | ? V_MAC_TX_RD_THRSH(th_value) : V_MAC_TX_RD_THRSH(4)) | |
1435 | V_MAC_TX_RL_THRSH(4) | |
1436 | V_MAC_RX_PL_THRSH(4) | |
1437 | V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ |
1438 | V_MAC_RX_RL_THRSH(8) | |
1439 | 0; |
1440 | |
1441 | framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | |
1442 | V_MAC_MAX_FRAMESZ_DEFAULT | |
1443 | V_MAC_BACKOFF_SEL(1); |
1444 | |
1445 | /* |
1446 | * Clear out the hash address map |
1447 | */ |
1448 | |
1449 | port = s->sbm_base + R_MAC_HASH_BASE; |
1450 | for (idx = 0; idx < MAC_HASH_COUNT; idx++) { |
1451 | __raw_writeq(0, port); |
1452 | port += sizeof(uint64_t); |
1453 | } |
1454 | |
1455 | /* |
1456 | * Clear out the exact-match table |
1457 | */ |
1458 | |
1459 | port = s->sbm_base + R_MAC_ADDR_BASE; |
1460 | for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { |
1461 | __raw_writeq(0, port); |
1462 | port += sizeof(uint64_t); |
1463 | } |
1464 | |
1465 | /* |
1466 | * Clear out the DMA Channel mapping table registers |
1467 | */ |
1468 | |
1469 | port = s->sbm_base + R_MAC_CHUP0_BASE; |
1470 | for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { |
1471 | __raw_writeq(0, port); |
1472 | port += sizeof(uint64_t); |
1473 | } |
1474 | |
1475 | |
1476 | port = s->sbm_base + R_MAC_CHLO0_BASE; |
1477 | for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { |
1478 | __raw_writeq(0, port); |
1479 | port += sizeof(uint64_t); |
1480 | } |
1481 | |
1482 | /* |
1483 | * Program the hardware address. It goes into the hardware-address |
1484 | * register as well as the first filter register. |
1485 | */ |
1486 | |
1487 | reg = sbmac_addr2reg(ptr: s->sbm_hwaddr); |
1488 | |
1489 | port = s->sbm_base + R_MAC_ADDR_BASE; |
1490 | __raw_writeq(val: reg, addr: port); |
1491 | port = s->sbm_base + R_MAC_ETHERNET_ADDR; |
1492 | |
1493 | __raw_writeq(val: reg, addr: port); |
1494 | |
1495 | /* |
1496 | * Set the receive filter for no packets, and write values |
1497 | * to the various config registers |
1498 | */ |
1499 | |
1500 | __raw_writeq(val: 0, addr: s->sbm_rxfilter); |
1501 | __raw_writeq(val: 0, addr: s->sbm_imr); |
1502 | __raw_writeq(val: framecfg, addr: s->sbm_framecfg); |
1503 | __raw_writeq(val: fifo, addr: s->sbm_fifocfg); |
1504 | __raw_writeq(val: cfg, addr: s->sbm_maccfg); |
1505 | |
1506 | /* |
1507 | * Initialize DMA channels (rings should be ok now) |
1508 | */ |
1509 | |
1510 | sbdma_channel_start(&(s->sbm_rxdma), DMA_RX); |
1511 | sbdma_channel_start(&(s->sbm_txdma), DMA_TX); |
1512 | |
1513 | /* |
1514 | * Configure the speed, duplex, and flow control |
1515 | */ |
1516 | |
1517 | sbmac_set_speed(s,speed: s->sbm_speed); |
1518 | sbmac_set_duplex(s,duplex: s->sbm_duplex,fc: s->sbm_fc); |
1519 | |
1520 | /* |
1521 | * Fill the receive ring |
1522 | */ |
1523 | |
1524 | sbdma_fillring(sc: s, d: &(s->sbm_rxdma)); |
1525 | |
1526 | /* |
1527 | * Turn on the rest of the bits in the enable register |
1528 | */ |
1529 | |
1530 | #if defined(CONFIG_SIBYTE_BCM1x80) |
1531 | __raw_writeq(M_MAC_RXDMA_EN0 | |
1532 | M_MAC_TXDMA_EN0, s->sbm_macenable); |
1533 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) |
1534 | __raw_writeq(M_MAC_RXDMA_EN0 | |
1535 | M_MAC_TXDMA_EN0 | |
1536 | M_MAC_RX_ENABLE | |
1537 | M_MAC_TX_ENABLE, s->sbm_macenable); |
1538 | #else |
1539 | #error invalid SiByte MAC configuration |
1540 | #endif |
1541 | |
1542 | #ifdef CONFIG_SBMAC_COALESCE |
1543 | __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | |
1544 | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr); |
1545 | #else |
1546 | __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | |
1547 | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr); |
1548 | #endif |
1549 | |
1550 | /* |
1551 | * Enable receiving unicasts and broadcasts |
1552 | */ |
1553 | |
1554 | __raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter); |
1555 | |
1556 | /* |
1557 | * we're running now. |
1558 | */ |
1559 | |
1560 | s->sbm_state = sbmac_state_on; |
1561 | |
1562 | /* |
1563 | * Program multicast addresses |
1564 | */ |
1565 | |
1566 | sbmac_setmulti(sc: s); |
1567 | |
1568 | /* |
1569 | * If channel was in promiscuous mode before, turn that on |
1570 | */ |
1571 | |
1572 | if (s->sbm_devflags & IFF_PROMISC) { |
1573 | sbmac_promiscuous_mode(sc: s,onoff: 1); |
1574 | } |
1575 | |
1576 | } |
1577 | |
1578 | |
1579 | /********************************************************************** |
1580 | * SBMAC_CHANNEL_STOP(s) |
1581 | * |
1582 | * Stop packet processing on this MAC. |
1583 | * |
1584 | * Input parameters: |
1585 | * s - sbmac structure |
1586 | * |
1587 | * Return value: |
1588 | * nothing |
1589 | ********************************************************************* */ |
1590 | |
1591 | static void sbmac_channel_stop(struct sbmac_softc *s) |
1592 | { |
1593 | /* don't do this if already stopped */ |
1594 | |
1595 | if (s->sbm_state == sbmac_state_off) |
1596 | return; |
1597 | |
1598 | /* don't accept any packets, disable all interrupts */ |
1599 | |
1600 | __raw_writeq(val: 0, addr: s->sbm_rxfilter); |
1601 | __raw_writeq(val: 0, addr: s->sbm_imr); |
1602 | |
1603 | /* Turn off ticker */ |
1604 | |
1605 | /* XXX */ |
1606 | |
1607 | /* turn off receiver and transmitter */ |
1608 | |
1609 | __raw_writeq(val: 0, addr: s->sbm_macenable); |
1610 | |
1611 | /* We're stopped now. */ |
1612 | |
1613 | s->sbm_state = sbmac_state_off; |
1614 | |
1615 | /* |
1616 | * Stop DMA channels (rings should be ok now) |
1617 | */ |
1618 | |
1619 | sbdma_channel_stop(d: &(s->sbm_rxdma)); |
1620 | sbdma_channel_stop(d: &(s->sbm_txdma)); |
1621 | |
1622 | /* Empty the receive and transmit rings */ |
1623 | |
1624 | sbdma_emptyring(d: &(s->sbm_rxdma)); |
1625 | sbdma_emptyring(d: &(s->sbm_txdma)); |
1626 | |
1627 | } |
1628 | |
1629 | /********************************************************************** |
1630 | * SBMAC_SET_CHANNEL_STATE(state) |
1631 | * |
1632 | * Set the channel's state ON or OFF |
1633 | * |
1634 | * Input parameters: |
1635 | * state - new state |
1636 | * |
1637 | * Return value: |
1638 | * old state |
1639 | ********************************************************************* */ |
1640 | static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *sc, |
1641 | enum sbmac_state state) |
1642 | { |
1643 | enum sbmac_state oldstate = sc->sbm_state; |
1644 | |
1645 | /* |
1646 | * If same as previous state, return |
1647 | */ |
1648 | |
1649 | if (state == oldstate) { |
1650 | return oldstate; |
1651 | } |
1652 | |
1653 | /* |
1654 | * If new state is ON, turn channel on |
1655 | */ |
1656 | |
1657 | if (state == sbmac_state_on) { |
1658 | sbmac_channel_start(s: sc); |
1659 | } |
1660 | else { |
1661 | sbmac_channel_stop(s: sc); |
1662 | } |
1663 | |
1664 | /* |
1665 | * Return previous state |
1666 | */ |
1667 | |
1668 | return oldstate; |
1669 | } |
1670 | |
1671 | |
1672 | /********************************************************************** |
1673 | * SBMAC_PROMISCUOUS_MODE(sc,onoff) |
1674 | * |
1675 | * Turn on or off promiscuous mode |
1676 | * |
1677 | * Input parameters: |
1678 | * sc - softc |
1679 | * onoff - 1 to turn on, 0 to turn off |
1680 | * |
1681 | * Return value: |
1682 | * nothing |
1683 | ********************************************************************* */ |
1684 | |
1685 | static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff) |
1686 | { |
1687 | uint64_t reg; |
1688 | |
1689 | if (sc->sbm_state != sbmac_state_on) |
1690 | return; |
1691 | |
1692 | if (onoff) { |
1693 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
1694 | reg |= M_MAC_ALLPKT_EN; |
1695 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
1696 | } |
1697 | else { |
1698 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
1699 | reg &= ~M_MAC_ALLPKT_EN; |
1700 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
1701 | } |
1702 | } |
1703 | |
1704 | /********************************************************************** |
1705 | * SBMAC_SETIPHDR_OFFSET(sc,onoff) |
1706 | * |
1707 | * Set the iphdr offset as 15 assuming ethernet encapsulation |
1708 | * |
1709 | * Input parameters: |
1710 | * sc - softc |
1711 | * |
1712 | * Return value: |
1713 | * nothing |
1714 | ********************************************************************* */ |
1715 | |
1716 | static void sbmac_set_iphdr_offset(struct sbmac_softc *sc) |
1717 | { |
1718 | uint64_t reg; |
1719 | |
1720 | /* Hard code the off set to 15 for now */ |
1721 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
1722 | reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); |
1723 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
1724 | |
1725 | /* BCM1250 pass1 didn't have hardware checksum. Everything |
1726 | later does. */ |
1727 | if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) { |
1728 | sc->rx_hw_checksum = DISABLE; |
1729 | } else { |
1730 | sc->rx_hw_checksum = ENABLE; |
1731 | } |
1732 | } |
1733 | |
1734 | |
1735 | /********************************************************************** |
1736 | * SBMAC_ADDR2REG(ptr) |
1737 | * |
1738 | * Convert six bytes into the 64-bit register value that |
1739 | * we typically write into the SBMAC's address/mcast registers |
1740 | * |
1741 | * Input parameters: |
1742 | * ptr - pointer to 6 bytes |
1743 | * |
1744 | * Return value: |
1745 | * register value |
1746 | ********************************************************************* */ |
1747 | |
1748 | static uint64_t sbmac_addr2reg(unsigned char *ptr) |
1749 | { |
1750 | uint64_t reg = 0; |
1751 | |
1752 | ptr += 6; |
1753 | |
1754 | reg |= (uint64_t) *(--ptr); |
1755 | reg <<= 8; |
1756 | reg |= (uint64_t) *(--ptr); |
1757 | reg <<= 8; |
1758 | reg |= (uint64_t) *(--ptr); |
1759 | reg <<= 8; |
1760 | reg |= (uint64_t) *(--ptr); |
1761 | reg <<= 8; |
1762 | reg |= (uint64_t) *(--ptr); |
1763 | reg <<= 8; |
1764 | reg |= (uint64_t) *(--ptr); |
1765 | |
1766 | return reg; |
1767 | } |
1768 | |
1769 | |
1770 | /********************************************************************** |
1771 | * SBMAC_SET_SPEED(s,speed) |
1772 | * |
1773 | * Configure LAN speed for the specified MAC. |
1774 | * Warning: must be called when MAC is off! |
1775 | * |
1776 | * Input parameters: |
1777 | * s - sbmac structure |
1778 | * speed - speed to set MAC to (see enum sbmac_speed) |
1779 | * |
1780 | * Return value: |
1781 | * 1 if successful |
1782 | * 0 indicates invalid parameters |
1783 | ********************************************************************* */ |
1784 | |
1785 | static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed) |
1786 | { |
1787 | uint64_t cfg; |
1788 | uint64_t framecfg; |
1789 | |
1790 | /* |
1791 | * Save new current values |
1792 | */ |
1793 | |
1794 | s->sbm_speed = speed; |
1795 | |
1796 | if (s->sbm_state == sbmac_state_on) |
1797 | return 0; /* save for next restart */ |
1798 | |
1799 | /* |
1800 | * Read current register values |
1801 | */ |
1802 | |
1803 | cfg = __raw_readq(addr: s->sbm_maccfg); |
1804 | framecfg = __raw_readq(addr: s->sbm_framecfg); |
1805 | |
1806 | /* |
1807 | * Mask out the stuff we want to change |
1808 | */ |
1809 | |
1810 | cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL); |
1811 | framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH | |
1812 | M_MAC_SLOT_SIZE); |
1813 | |
1814 | /* |
1815 | * Now add in the new bits |
1816 | */ |
1817 | |
1818 | switch (speed) { |
1819 | case sbmac_speed_10: |
1820 | framecfg |= V_MAC_IFG_RX_10 | |
1821 | V_MAC_IFG_TX_10 | |
1822 | K_MAC_IFG_THRSH_10 | |
1823 | V_MAC_SLOT_SIZE_10; |
1824 | cfg |= V_MAC_SPEED_SEL_10MBPS; |
1825 | break; |
1826 | |
1827 | case sbmac_speed_100: |
1828 | framecfg |= V_MAC_IFG_RX_100 | |
1829 | V_MAC_IFG_TX_100 | |
1830 | V_MAC_IFG_THRSH_100 | |
1831 | V_MAC_SLOT_SIZE_100; |
1832 | cfg |= V_MAC_SPEED_SEL_100MBPS ; |
1833 | break; |
1834 | |
1835 | case sbmac_speed_1000: |
1836 | framecfg |= V_MAC_IFG_RX_1000 | |
1837 | V_MAC_IFG_TX_1000 | |
1838 | V_MAC_IFG_THRSH_1000 | |
1839 | V_MAC_SLOT_SIZE_1000; |
1840 | cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN; |
1841 | break; |
1842 | |
1843 | default: |
1844 | return 0; |
1845 | } |
1846 | |
1847 | /* |
1848 | * Send the bits back to the hardware |
1849 | */ |
1850 | |
1851 | __raw_writeq(val: framecfg, addr: s->sbm_framecfg); |
1852 | __raw_writeq(val: cfg, addr: s->sbm_maccfg); |
1853 | |
1854 | return 1; |
1855 | } |
1856 | |
1857 | /********************************************************************** |
1858 | * SBMAC_SET_DUPLEX(s,duplex,fc) |
1859 | * |
1860 | * Set Ethernet duplex and flow control options for this MAC |
1861 | * Warning: must be called when MAC is off! |
1862 | * |
1863 | * Input parameters: |
1864 | * s - sbmac structure |
1865 | * duplex - duplex setting (see enum sbmac_duplex) |
1866 | * fc - flow control setting (see enum sbmac_fc) |
1867 | * |
1868 | * Return value: |
1869 | * 1 if ok |
1870 | * 0 if an invalid parameter combination was specified |
1871 | ********************************************************************* */ |
1872 | |
1873 | static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex, |
1874 | enum sbmac_fc fc) |
1875 | { |
1876 | uint64_t cfg; |
1877 | |
1878 | /* |
1879 | * Save new current values |
1880 | */ |
1881 | |
1882 | s->sbm_duplex = duplex; |
1883 | s->sbm_fc = fc; |
1884 | |
1885 | if (s->sbm_state == sbmac_state_on) |
1886 | return 0; /* save for next restart */ |
1887 | |
1888 | /* |
1889 | * Read current register values |
1890 | */ |
1891 | |
1892 | cfg = __raw_readq(addr: s->sbm_maccfg); |
1893 | |
1894 | /* |
1895 | * Mask off the stuff we're about to change |
1896 | */ |
1897 | |
1898 | cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN); |
1899 | |
1900 | |
1901 | switch (duplex) { |
1902 | case sbmac_duplex_half: |
1903 | switch (fc) { |
1904 | case sbmac_fc_disabled: |
1905 | cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED; |
1906 | break; |
1907 | |
1908 | case sbmac_fc_collision: |
1909 | cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED; |
1910 | break; |
1911 | |
1912 | case sbmac_fc_carrier: |
1913 | cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR; |
1914 | break; |
1915 | |
1916 | case sbmac_fc_frame: /* not valid in half duplex */ |
1917 | default: /* invalid selection */ |
1918 | return 0; |
1919 | } |
1920 | break; |
1921 | |
1922 | case sbmac_duplex_full: |
1923 | switch (fc) { |
1924 | case sbmac_fc_disabled: |
1925 | cfg |= V_MAC_FC_CMD_DISABLED; |
1926 | break; |
1927 | |
1928 | case sbmac_fc_frame: |
1929 | cfg |= V_MAC_FC_CMD_ENABLED; |
1930 | break; |
1931 | |
1932 | case sbmac_fc_collision: /* not valid in full duplex */ |
1933 | case sbmac_fc_carrier: /* not valid in full duplex */ |
1934 | default: |
1935 | return 0; |
1936 | } |
1937 | break; |
1938 | default: |
1939 | return 0; |
1940 | } |
1941 | |
1942 | /* |
1943 | * Send the bits back to the hardware |
1944 | */ |
1945 | |
1946 | __raw_writeq(val: cfg, addr: s->sbm_maccfg); |
1947 | |
1948 | return 1; |
1949 | } |
1950 | |
1951 | |
1952 | |
1953 | |
1954 | /********************************************************************** |
1955 | * SBMAC_INTR() |
1956 | * |
1957 | * Interrupt handler for MAC interrupts |
1958 | * |
1959 | * Input parameters: |
1960 | * MAC structure |
1961 | * |
1962 | * Return value: |
1963 | * nothing |
1964 | ********************************************************************* */ |
1965 | static irqreturn_t sbmac_intr(int irq,void *dev_instance) |
1966 | { |
1967 | struct net_device *dev = (struct net_device *) dev_instance; |
1968 | struct sbmac_softc *sc = netdev_priv(dev); |
1969 | uint64_t isr; |
1970 | int handled = 0; |
1971 | |
1972 | /* |
1973 | * Read the ISR (this clears the bits in the real |
1974 | * register, except for counter addr) |
1975 | */ |
1976 | |
1977 | isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; |
1978 | |
1979 | if (isr == 0) |
1980 | return IRQ_RETVAL(0); |
1981 | handled = 1; |
1982 | |
1983 | /* |
1984 | * Transmits on channel 0 |
1985 | */ |
1986 | |
1987 | if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) |
1988 | sbdma_tx_process(sc,d: &(sc->sbm_txdma), poll: 0); |
1989 | |
1990 | if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) { |
1991 | if (napi_schedule_prep(n: &sc->napi)) { |
1992 | __raw_writeq(val: 0, addr: sc->sbm_imr); |
1993 | __napi_schedule(n: &sc->napi); |
1994 | /* Depend on the exit from poll to reenable intr */ |
1995 | } |
1996 | else { |
1997 | /* may leave some packets behind */ |
1998 | sbdma_rx_process(sc,d: &(sc->sbm_rxdma), |
1999 | SBMAC_MAX_RXDESCR * 2, poll: 0); |
2000 | } |
2001 | } |
2002 | return IRQ_RETVAL(handled); |
2003 | } |
2004 | |
2005 | /********************************************************************** |
2006 | * SBMAC_START_TX(skb,dev) |
2007 | * |
2008 | * Start output on the specified interface. Basically, we |
2009 | * queue as many buffers as we can until the ring fills up, or |
2010 | * we run off the end of the queue, whichever comes first. |
2011 | * |
2012 | * Input parameters: |
2013 | * |
2014 | * |
2015 | * Return value: |
2016 | * nothing |
2017 | ********************************************************************* */ |
2018 | static netdev_tx_t sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) |
2019 | { |
2020 | struct sbmac_softc *sc = netdev_priv(dev); |
2021 | unsigned long flags; |
2022 | |
2023 | /* lock eth irq */ |
2024 | spin_lock_irqsave(&sc->sbm_lock, flags); |
2025 | |
2026 | /* |
2027 | * Put the buffer on the transmit ring. If we |
2028 | * don't have room, stop the queue. |
2029 | */ |
2030 | |
2031 | if (sbdma_add_txbuffer(d: &(sc->sbm_txdma),sb: skb)) { |
2032 | /* XXX save skb that we could not send */ |
2033 | netif_stop_queue(dev); |
2034 | spin_unlock_irqrestore(lock: &sc->sbm_lock, flags); |
2035 | |
2036 | return NETDEV_TX_BUSY; |
2037 | } |
2038 | |
2039 | spin_unlock_irqrestore(lock: &sc->sbm_lock, flags); |
2040 | |
2041 | return NETDEV_TX_OK; |
2042 | } |
2043 | |
2044 | /********************************************************************** |
2045 | * SBMAC_SETMULTI(sc) |
2046 | * |
2047 | * Reprogram the multicast table into the hardware, given |
2048 | * the list of multicasts associated with the interface |
2049 | * structure. |
2050 | * |
2051 | * Input parameters: |
2052 | * sc - softc |
2053 | * |
2054 | * Return value: |
2055 | * nothing |
2056 | ********************************************************************* */ |
2057 | |
2058 | static void sbmac_setmulti(struct sbmac_softc *sc) |
2059 | { |
2060 | uint64_t reg; |
2061 | void __iomem *port; |
2062 | int idx; |
2063 | struct netdev_hw_addr *ha; |
2064 | struct net_device *dev = sc->sbm_dev; |
2065 | |
2066 | /* |
2067 | * Clear out entire multicast table. We do this by nuking |
2068 | * the entire hash table and all the direct matches except |
2069 | * the first one, which is used for our station address |
2070 | */ |
2071 | |
2072 | for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { |
2073 | port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); |
2074 | __raw_writeq(0, port); |
2075 | } |
2076 | |
2077 | for (idx = 0; idx < MAC_HASH_COUNT; idx++) { |
2078 | port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); |
2079 | __raw_writeq(0, port); |
2080 | } |
2081 | |
2082 | /* |
2083 | * Clear the filter to say we don't want any multicasts. |
2084 | */ |
2085 | |
2086 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
2087 | reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN); |
2088 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
2089 | |
2090 | if (dev->flags & IFF_ALLMULTI) { |
2091 | /* |
2092 | * Enable ALL multicasts. Do this by inverting the |
2093 | * multicast enable bit. |
2094 | */ |
2095 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
2096 | reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN); |
2097 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
2098 | return; |
2099 | } |
2100 | |
2101 | |
2102 | /* |
2103 | * Progam new multicast entries. For now, only use the |
2104 | * perfect filter. In the future we'll need to use the |
2105 | * hash filter if the perfect filter overflows |
2106 | */ |
2107 | |
2108 | /* XXX only using perfect filter for now, need to use hash |
2109 | * XXX if the table overflows */ |
2110 | |
2111 | idx = 1; /* skip station address */ |
2112 | netdev_for_each_mc_addr(ha, dev) { |
2113 | if (idx == MAC_ADDR_COUNT) |
2114 | break; |
2115 | reg = sbmac_addr2reg(ptr: ha->addr); |
2116 | port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); |
2117 | __raw_writeq(val: reg, addr: port); |
2118 | idx++; |
2119 | } |
2120 | |
2121 | /* |
2122 | * Enable the "accept multicast bits" if we programmed at least one |
2123 | * multicast. |
2124 | */ |
2125 | |
2126 | if (idx > 1) { |
2127 | reg = __raw_readq(addr: sc->sbm_rxfilter); |
2128 | reg |= M_MAC_MCAST_EN; |
2129 | __raw_writeq(val: reg, addr: sc->sbm_rxfilter); |
2130 | } |
2131 | } |
2132 | |
2133 | static const struct net_device_ops sbmac_netdev_ops = { |
2134 | .ndo_open = sbmac_open, |
2135 | .ndo_stop = sbmac_close, |
2136 | .ndo_start_xmit = sbmac_start_tx, |
2137 | .ndo_set_rx_mode = sbmac_set_rx_mode, |
2138 | .ndo_tx_timeout = sbmac_tx_timeout, |
2139 | .ndo_eth_ioctl = sbmac_mii_ioctl, |
2140 | .ndo_validate_addr = eth_validate_addr, |
2141 | .ndo_set_mac_address = eth_mac_addr, |
2142 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2143 | .ndo_poll_controller = sbmac_netpoll, |
2144 | #endif |
2145 | }; |
2146 | |
2147 | /********************************************************************** |
2148 | * SBMAC_INIT(dev) |
2149 | * |
2150 | * Attach routine - init hardware and hook ourselves into linux |
2151 | * |
2152 | * Input parameters: |
2153 | * dev - net_device structure |
2154 | * |
2155 | * Return value: |
2156 | * status |
2157 | ********************************************************************* */ |
2158 | |
2159 | static int sbmac_init(struct platform_device *pldev, long long base) |
2160 | { |
2161 | struct net_device *dev = platform_get_drvdata(pdev: pldev); |
2162 | int idx = pldev->id; |
2163 | struct sbmac_softc *sc = netdev_priv(dev); |
2164 | unsigned char *eaddr; |
2165 | uint64_t ea_reg; |
2166 | int i; |
2167 | int err; |
2168 | |
2169 | sc->sbm_dev = dev; |
2170 | sc->sbe_idx = idx; |
2171 | |
2172 | eaddr = sc->sbm_hwaddr; |
2173 | |
2174 | /* |
2175 | * Read the ethernet address. The firmware left this programmed |
2176 | * for us in the ethernet address register for each mac. |
2177 | */ |
2178 | |
2179 | ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR); |
2180 | __raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR); |
2181 | for (i = 0; i < 6; i++) { |
2182 | eaddr[i] = (uint8_t) (ea_reg & 0xFF); |
2183 | ea_reg >>= 8; |
2184 | } |
2185 | |
2186 | eth_hw_addr_set(dev, addr: eaddr); |
2187 | |
2188 | /* |
2189 | * Initialize context (get pointers to registers and stuff), then |
2190 | * allocate the memory for the descriptor tables. |
2191 | */ |
2192 | |
2193 | sbmac_initctx(s: sc); |
2194 | |
2195 | /* |
2196 | * Set up Linux device callins |
2197 | */ |
2198 | |
2199 | spin_lock_init(&(sc->sbm_lock)); |
2200 | |
2201 | dev->netdev_ops = &sbmac_netdev_ops; |
2202 | dev->watchdog_timeo = TX_TIMEOUT; |
2203 | dev->min_mtu = 0; |
2204 | dev->max_mtu = ENET_PACKET_SIZE; |
2205 | |
2206 | netif_napi_add_weight(dev, napi: &sc->napi, poll: sbmac_poll, weight: 16); |
2207 | |
2208 | dev->irq = UNIT_INT(idx); |
2209 | |
2210 | /* This is needed for PASS2 for Rx H/W checksum feature */ |
2211 | sbmac_set_iphdr_offset(sc); |
2212 | |
2213 | sc->mii_bus = mdiobus_alloc(); |
2214 | if (sc->mii_bus == NULL) { |
2215 | err = -ENOMEM; |
2216 | goto uninit_ctx; |
2217 | } |
2218 | |
2219 | sc->mii_bus->name = sbmac_mdio_string; |
2220 | snprintf(buf: sc->mii_bus->id, MII_BUS_ID_SIZE, fmt: "%s-%x" , |
2221 | pldev->name, idx); |
2222 | sc->mii_bus->priv = sc; |
2223 | sc->mii_bus->read = sbmac_mii_read; |
2224 | sc->mii_bus->write = sbmac_mii_write; |
2225 | |
2226 | sc->mii_bus->parent = &pldev->dev; |
2227 | /* |
2228 | * Probe PHY address |
2229 | */ |
2230 | err = mdiobus_register(sc->mii_bus); |
2231 | if (err) { |
2232 | printk(KERN_ERR "%s: unable to register MDIO bus\n" , |
2233 | dev->name); |
2234 | goto free_mdio; |
2235 | } |
2236 | platform_set_drvdata(pdev: pldev, data: sc->mii_bus); |
2237 | |
2238 | err = register_netdev(dev); |
2239 | if (err) { |
2240 | printk(KERN_ERR "%s.%d: unable to register netdev\n" , |
2241 | sbmac_string, idx); |
2242 | goto unreg_mdio; |
2243 | } |
2244 | |
2245 | pr_info("%s.%d: registered as %s\n" , sbmac_string, idx, dev->name); |
2246 | |
2247 | if (sc->rx_hw_checksum == ENABLE) |
2248 | pr_info("%s: enabling TCP rcv checksum\n" , dev->name); |
2249 | |
2250 | /* |
2251 | * Display Ethernet address (this is called during the config |
2252 | * process so we need to finish off the config message that |
2253 | * was being displayed) |
2254 | */ |
2255 | pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n" , |
2256 | dev->name, base, eaddr); |
2257 | |
2258 | return 0; |
2259 | unreg_mdio: |
2260 | mdiobus_unregister(bus: sc->mii_bus); |
2261 | free_mdio: |
2262 | mdiobus_free(bus: sc->mii_bus); |
2263 | uninit_ctx: |
2264 | sbmac_uninitctx(sc); |
2265 | return err; |
2266 | } |
2267 | |
2268 | |
2269 | static int sbmac_open(struct net_device *dev) |
2270 | { |
2271 | struct sbmac_softc *sc = netdev_priv(dev); |
2272 | int err; |
2273 | |
2274 | if (debug > 1) |
2275 | pr_debug("%s: sbmac_open() irq %d.\n" , dev->name, dev->irq); |
2276 | |
2277 | /* |
2278 | * map/route interrupt (clear status first, in case something |
2279 | * weird is pending; we haven't initialized the mac registers |
2280 | * yet) |
2281 | */ |
2282 | |
2283 | __raw_readq(addr: sc->sbm_isr); |
2284 | err = request_irq(irq: dev->irq, handler: sbmac_intr, IRQF_SHARED, name: dev->name, dev); |
2285 | if (err) { |
2286 | printk(KERN_ERR "%s: unable to get IRQ %d\n" , dev->name, |
2287 | dev->irq); |
2288 | goto out_err; |
2289 | } |
2290 | |
2291 | sc->sbm_speed = sbmac_speed_none; |
2292 | sc->sbm_duplex = sbmac_duplex_none; |
2293 | sc->sbm_fc = sbmac_fc_none; |
2294 | sc->sbm_pause = -1; |
2295 | sc->sbm_link = 0; |
2296 | |
2297 | /* |
2298 | * Attach to the PHY |
2299 | */ |
2300 | err = sbmac_mii_probe(dev); |
2301 | if (err) |
2302 | goto out_unregister; |
2303 | |
2304 | /* |
2305 | * Turn on the channel |
2306 | */ |
2307 | |
2308 | sbmac_set_channel_state(sc,state: sbmac_state_on); |
2309 | |
2310 | netif_start_queue(dev); |
2311 | |
2312 | sbmac_set_rx_mode(dev); |
2313 | |
2314 | phy_start(phydev: sc->phy_dev); |
2315 | |
2316 | napi_enable(n: &sc->napi); |
2317 | |
2318 | return 0; |
2319 | |
2320 | out_unregister: |
2321 | free_irq(dev->irq, dev); |
2322 | out_err: |
2323 | return err; |
2324 | } |
2325 | |
2326 | static int sbmac_mii_probe(struct net_device *dev) |
2327 | { |
2328 | struct sbmac_softc *sc = netdev_priv(dev); |
2329 | struct phy_device *phy_dev; |
2330 | |
2331 | phy_dev = phy_find_first(bus: sc->mii_bus); |
2332 | if (!phy_dev) { |
2333 | printk(KERN_ERR "%s: no PHY found\n" , dev->name); |
2334 | return -ENXIO; |
2335 | } |
2336 | |
2337 | phy_dev = phy_connect(dev, bus_id: dev_name(dev: &phy_dev->mdio.dev), |
2338 | handler: &sbmac_mii_poll, interface: PHY_INTERFACE_MODE_GMII); |
2339 | if (IS_ERR(ptr: phy_dev)) { |
2340 | printk(KERN_ERR "%s: could not attach to PHY\n" , dev->name); |
2341 | return PTR_ERR(ptr: phy_dev); |
2342 | } |
2343 | |
2344 | /* Remove any features not supported by the controller */ |
2345 | phy_set_max_speed(phydev: phy_dev, SPEED_1000); |
2346 | phy_support_asym_pause(phydev: phy_dev); |
2347 | |
2348 | phy_attached_info(phydev: phy_dev); |
2349 | |
2350 | sc->phy_dev = phy_dev; |
2351 | |
2352 | return 0; |
2353 | } |
2354 | |
2355 | |
2356 | static void sbmac_mii_poll(struct net_device *dev) |
2357 | { |
2358 | struct sbmac_softc *sc = netdev_priv(dev); |
2359 | struct phy_device *phy_dev = sc->phy_dev; |
2360 | unsigned long flags; |
2361 | enum sbmac_fc fc; |
2362 | int link_chg, speed_chg, duplex_chg, pause_chg, fc_chg; |
2363 | |
2364 | link_chg = (sc->sbm_link != phy_dev->link); |
2365 | speed_chg = (sc->sbm_speed != phy_dev->speed); |
2366 | duplex_chg = (sc->sbm_duplex != phy_dev->duplex); |
2367 | pause_chg = (sc->sbm_pause != phy_dev->pause); |
2368 | |
2369 | if (!link_chg && !speed_chg && !duplex_chg && !pause_chg) |
2370 | return; /* Hmmm... */ |
2371 | |
2372 | if (!phy_dev->link) { |
2373 | if (link_chg) { |
2374 | sc->sbm_link = phy_dev->link; |
2375 | sc->sbm_speed = sbmac_speed_none; |
2376 | sc->sbm_duplex = sbmac_duplex_none; |
2377 | sc->sbm_fc = sbmac_fc_disabled; |
2378 | sc->sbm_pause = -1; |
2379 | pr_info("%s: link unavailable\n" , dev->name); |
2380 | } |
2381 | return; |
2382 | } |
2383 | |
2384 | if (phy_dev->duplex == DUPLEX_FULL) { |
2385 | if (phy_dev->pause) |
2386 | fc = sbmac_fc_frame; |
2387 | else |
2388 | fc = sbmac_fc_disabled; |
2389 | } else |
2390 | fc = sbmac_fc_collision; |
2391 | fc_chg = (sc->sbm_fc != fc); |
2392 | |
2393 | pr_info("%s: link available: %dbase-%cD\n" , dev->name, phy_dev->speed, |
2394 | phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H'); |
2395 | |
2396 | spin_lock_irqsave(&sc->sbm_lock, flags); |
2397 | |
2398 | sc->sbm_speed = phy_dev->speed; |
2399 | sc->sbm_duplex = phy_dev->duplex; |
2400 | sc->sbm_fc = fc; |
2401 | sc->sbm_pause = phy_dev->pause; |
2402 | sc->sbm_link = phy_dev->link; |
2403 | |
2404 | if ((speed_chg || duplex_chg || fc_chg) && |
2405 | sc->sbm_state != sbmac_state_off) { |
2406 | /* |
2407 | * something changed, restart the channel |
2408 | */ |
2409 | if (debug > 1) |
2410 | pr_debug("%s: restarting channel " |
2411 | "because PHY state changed\n" , dev->name); |
2412 | sbmac_channel_stop(s: sc); |
2413 | sbmac_channel_start(s: sc); |
2414 | } |
2415 | |
2416 | spin_unlock_irqrestore(lock: &sc->sbm_lock, flags); |
2417 | } |
2418 | |
2419 | |
2420 | static void sbmac_tx_timeout (struct net_device *dev, unsigned int txqueue) |
2421 | { |
2422 | struct sbmac_softc *sc = netdev_priv(dev); |
2423 | unsigned long flags; |
2424 | |
2425 | spin_lock_irqsave(&sc->sbm_lock, flags); |
2426 | |
2427 | |
2428 | netif_trans_update(dev); /* prevent tx timeout */ |
2429 | dev->stats.tx_errors++; |
2430 | |
2431 | spin_unlock_irqrestore(lock: &sc->sbm_lock, flags); |
2432 | |
2433 | printk (KERN_WARNING "%s: Transmit timed out\n" ,dev->name); |
2434 | } |
2435 | |
2436 | |
2437 | |
2438 | |
2439 | static void sbmac_set_rx_mode(struct net_device *dev) |
2440 | { |
2441 | unsigned long flags; |
2442 | struct sbmac_softc *sc = netdev_priv(dev); |
2443 | |
2444 | spin_lock_irqsave(&sc->sbm_lock, flags); |
2445 | if ((dev->flags ^ sc->sbm_devflags) & IFF_PROMISC) { |
2446 | /* |
2447 | * Promiscuous changed. |
2448 | */ |
2449 | |
2450 | if (dev->flags & IFF_PROMISC) { |
2451 | sbmac_promiscuous_mode(sc,onoff: 1); |
2452 | } |
2453 | else { |
2454 | sbmac_promiscuous_mode(sc,onoff: 0); |
2455 | } |
2456 | } |
2457 | spin_unlock_irqrestore(lock: &sc->sbm_lock, flags); |
2458 | |
2459 | /* |
2460 | * Program the multicasts. Do this every time. |
2461 | */ |
2462 | |
2463 | sbmac_setmulti(sc); |
2464 | |
2465 | } |
2466 | |
2467 | static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
2468 | { |
2469 | struct sbmac_softc *sc = netdev_priv(dev); |
2470 | |
2471 | if (!netif_running(dev) || !sc->phy_dev) |
2472 | return -EINVAL; |
2473 | |
2474 | return phy_mii_ioctl(phydev: sc->phy_dev, ifr: rq, cmd); |
2475 | } |
2476 | |
2477 | static int sbmac_close(struct net_device *dev) |
2478 | { |
2479 | struct sbmac_softc *sc = netdev_priv(dev); |
2480 | |
2481 | napi_disable(n: &sc->napi); |
2482 | |
2483 | phy_stop(phydev: sc->phy_dev); |
2484 | |
2485 | sbmac_set_channel_state(sc, state: sbmac_state_off); |
2486 | |
2487 | netif_stop_queue(dev); |
2488 | |
2489 | if (debug > 1) |
2490 | pr_debug("%s: Shutting down ethercard\n" , dev->name); |
2491 | |
2492 | phy_disconnect(phydev: sc->phy_dev); |
2493 | sc->phy_dev = NULL; |
2494 | free_irq(dev->irq, dev); |
2495 | |
2496 | sbdma_emptyring(d: &(sc->sbm_txdma)); |
2497 | sbdma_emptyring(d: &(sc->sbm_rxdma)); |
2498 | |
2499 | return 0; |
2500 | } |
2501 | |
2502 | static int sbmac_poll(struct napi_struct *napi, int budget) |
2503 | { |
2504 | struct sbmac_softc *sc = container_of(napi, struct sbmac_softc, napi); |
2505 | int work_done; |
2506 | |
2507 | work_done = sbdma_rx_process(sc, d: &(sc->sbm_rxdma), work_to_do: budget, poll: 1); |
2508 | sbdma_tx_process(sc, d: &(sc->sbm_txdma), poll: 1); |
2509 | |
2510 | if (work_done < budget) { |
2511 | napi_complete_done(n: napi, work_done); |
2512 | |
2513 | #ifdef CONFIG_SBMAC_COALESCE |
2514 | __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | |
2515 | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), |
2516 | sc->sbm_imr); |
2517 | #else |
2518 | __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | |
2519 | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); |
2520 | #endif |
2521 | } |
2522 | |
2523 | return work_done; |
2524 | } |
2525 | |
2526 | |
2527 | static int sbmac_probe(struct platform_device *pldev) |
2528 | { |
2529 | struct net_device *dev; |
2530 | struct sbmac_softc *sc; |
2531 | void __iomem *sbm_base; |
2532 | struct resource *res; |
2533 | u64 sbmac_orig_hwaddr; |
2534 | int err; |
2535 | |
2536 | res = platform_get_resource(pldev, IORESOURCE_MEM, 0); |
2537 | if (!res) { |
2538 | printk(KERN_ERR "%s: failed to get resource\n" , |
2539 | dev_name(&pldev->dev)); |
2540 | err = -EINVAL; |
2541 | goto out_out; |
2542 | } |
2543 | sbm_base = ioremap(offset: res->start, size: resource_size(res)); |
2544 | if (!sbm_base) { |
2545 | printk(KERN_ERR "%s: unable to map device registers\n" , |
2546 | dev_name(&pldev->dev)); |
2547 | err = -ENOMEM; |
2548 | goto out_out; |
2549 | } |
2550 | |
2551 | /* |
2552 | * The R_MAC_ETHERNET_ADDR register will be set to some nonzero |
2553 | * value for us by the firmware if we're going to use this MAC. |
2554 | * If we find a zero, skip this MAC. |
2555 | */ |
2556 | sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR); |
2557 | pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n" , dev_name(&pldev->dev), |
2558 | sbmac_orig_hwaddr ? "" : "not " , (long long)res->start); |
2559 | if (sbmac_orig_hwaddr == 0) { |
2560 | err = 0; |
2561 | goto out_unmap; |
2562 | } |
2563 | |
2564 | /* |
2565 | * Okay, cool. Initialize this MAC. |
2566 | */ |
2567 | dev = alloc_etherdev(sizeof(struct sbmac_softc)); |
2568 | if (!dev) { |
2569 | err = -ENOMEM; |
2570 | goto out_unmap; |
2571 | } |
2572 | |
2573 | platform_set_drvdata(pdev: pldev, data: dev); |
2574 | SET_NETDEV_DEV(dev, &pldev->dev); |
2575 | |
2576 | sc = netdev_priv(dev); |
2577 | sc->sbm_base = sbm_base; |
2578 | |
2579 | err = sbmac_init(pldev, base: res->start); |
2580 | if (err) |
2581 | goto out_kfree; |
2582 | |
2583 | return 0; |
2584 | |
2585 | out_kfree: |
2586 | free_netdev(dev); |
2587 | __raw_writeq(sbmac_orig_hwaddr, sbm_base + R_MAC_ETHERNET_ADDR); |
2588 | |
2589 | out_unmap: |
2590 | iounmap(addr: sbm_base); |
2591 | |
2592 | out_out: |
2593 | return err; |
2594 | } |
2595 | |
2596 | static void sbmac_remove(struct platform_device *pldev) |
2597 | { |
2598 | struct net_device *dev = platform_get_drvdata(pdev: pldev); |
2599 | struct sbmac_softc *sc = netdev_priv(dev); |
2600 | |
2601 | unregister_netdev(dev); |
2602 | sbmac_uninitctx(sc); |
2603 | mdiobus_unregister(bus: sc->mii_bus); |
2604 | mdiobus_free(bus: sc->mii_bus); |
2605 | iounmap(addr: sc->sbm_base); |
2606 | free_netdev(dev); |
2607 | } |
2608 | |
2609 | static struct platform_driver sbmac_driver = { |
2610 | .probe = sbmac_probe, |
2611 | .remove_new = sbmac_remove, |
2612 | .driver = { |
2613 | .name = sbmac_string, |
2614 | }, |
2615 | }; |
2616 | |
2617 | module_platform_driver(sbmac_driver); |
2618 | MODULE_LICENSE("GPL" ); |
2619 | |