diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/arm | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/arm')
-rw-r--r-- | drivers/net/arm/am79c961a.c | 168 | ||||
-rw-r--r-- | drivers/net/arm/am79c961a.h | 1 | ||||
-rw-r--r-- | drivers/net/arm/ep93xx_eth.c | 121 | ||||
-rw-r--r-- | drivers/net/arm/ether1.c | 34 | ||||
-rw-r--r-- | drivers/net/arm/ether1.h | 1 | ||||
-rw-r--r-- | drivers/net/arm/ether3.c | 33 | ||||
-rw-r--r-- | drivers/net/arm/ether3.h | 1 | ||||
-rw-r--r-- | drivers/net/arm/etherh.c | 9 | ||||
-rw-r--r-- | drivers/net/arm/ixp4xx_eth.c | 199 | ||||
-rw-r--r-- | drivers/net/arm/ks8695net.c | 291 | ||||
-rw-r--r-- | drivers/net/arm/w90p910_ether.c | 2 |
11 files changed, 456 insertions, 404 deletions
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 8c496fb1ac9e..7b3e23f38913 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c | |||
@@ -50,7 +50,7 @@ static const char version[] = | |||
50 | #ifdef __arm__ | 50 | #ifdef __arm__ |
51 | static void write_rreg(u_long base, u_int reg, u_int val) | 51 | static void write_rreg(u_long base, u_int reg, u_int val) |
52 | { | 52 | { |
53 | __asm__( | 53 | asm volatile( |
54 | "str%?h %1, [%2] @ NET_RAP\n\t" | 54 | "str%?h %1, [%2] @ NET_RAP\n\t" |
55 | "str%?h %0, [%2, #-4] @ NET_RDP" | 55 | "str%?h %0, [%2, #-4] @ NET_RDP" |
56 | : | 56 | : |
@@ -60,7 +60,7 @@ static void write_rreg(u_long base, u_int reg, u_int val) | |||
60 | static inline unsigned short read_rreg(u_long base_addr, u_int reg) | 60 | static inline unsigned short read_rreg(u_long base_addr, u_int reg) |
61 | { | 61 | { |
62 | unsigned short v; | 62 | unsigned short v; |
63 | __asm__( | 63 | asm volatile( |
64 | "str%?h %1, [%2] @ NET_RAP\n\t" | 64 | "str%?h %1, [%2] @ NET_RAP\n\t" |
65 | "ldr%?h %0, [%2, #-4] @ NET_RDP" | 65 | "ldr%?h %0, [%2, #-4] @ NET_RDP" |
66 | : "=r" (v) | 66 | : "=r" (v) |
@@ -70,7 +70,7 @@ static inline unsigned short read_rreg(u_long base_addr, u_int reg) | |||
70 | 70 | ||
71 | static inline void write_ireg(u_long base, u_int reg, u_int val) | 71 | static inline void write_ireg(u_long base, u_int reg, u_int val) |
72 | { | 72 | { |
73 | __asm__( | 73 | asm volatile( |
74 | "str%?h %1, [%2] @ NET_RAP\n\t" | 74 | "str%?h %1, [%2] @ NET_RAP\n\t" |
75 | "str%?h %0, [%2, #8] @ NET_IDP" | 75 | "str%?h %0, [%2, #8] @ NET_IDP" |
76 | : | 76 | : |
@@ -80,7 +80,7 @@ static inline void write_ireg(u_long base, u_int reg, u_int val) | |||
80 | static inline unsigned short read_ireg(u_long base_addr, u_int reg) | 80 | static inline unsigned short read_ireg(u_long base_addr, u_int reg) |
81 | { | 81 | { |
82 | u_short v; | 82 | u_short v; |
83 | __asm__( | 83 | asm volatile( |
84 | "str%?h %1, [%2] @ NAT_RAP\n\t" | 84 | "str%?h %1, [%2] @ NAT_RAP\n\t" |
85 | "ldr%?h %0, [%2, #8] @ NET_IDP\n\t" | 85 | "ldr%?h %0, [%2, #8] @ NET_IDP\n\t" |
86 | : "=r" (v) | 86 | : "=r" (v) |
@@ -91,47 +91,48 @@ static inline unsigned short read_ireg(u_long base_addr, u_int reg) | |||
91 | #define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1)) | 91 | #define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1)) |
92 | #define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1)) | 92 | #define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1)) |
93 | 93 | ||
94 | static inline void | 94 | static void |
95 | am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length) | 95 | am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length) |
96 | { | 96 | { |
97 | offset = ISAMEM_BASE + (offset << 1); | 97 | offset = ISAMEM_BASE + (offset << 1); |
98 | length = (length + 1) & ~1; | 98 | length = (length + 1) & ~1; |
99 | if ((int)buf & 2) { | 99 | if ((int)buf & 2) { |
100 | __asm__ __volatile__("str%?h %2, [%0], #4" | 100 | asm volatile("str%?h %2, [%0], #4" |
101 | : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8))); | 101 | : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8))); |
102 | buf += 2; | 102 | buf += 2; |
103 | length -= 2; | 103 | length -= 2; |
104 | } | 104 | } |
105 | while (length > 8) { | 105 | while (length > 8) { |
106 | unsigned int tmp, tmp2; | 106 | register unsigned int tmp asm("r2"), tmp2 asm("r3"); |
107 | __asm__ __volatile__( | 107 | asm volatile( |
108 | "ldm%?ia %1!, {%2, %3}\n\t" | 108 | "ldm%?ia %0!, {%1, %2}" |
109 | : "+r" (buf), "=&r" (tmp), "=&r" (tmp2)); | ||
110 | length -= 8; | ||
111 | asm volatile( | ||
112 | "str%?h %1, [%0], #4\n\t" | ||
113 | "mov%? %1, %1, lsr #16\n\t" | ||
114 | "str%?h %1, [%0], #4\n\t" | ||
109 | "str%?h %2, [%0], #4\n\t" | 115 | "str%?h %2, [%0], #4\n\t" |
110 | "mov%? %2, %2, lsr #16\n\t" | 116 | "mov%? %2, %2, lsr #16\n\t" |
111 | "str%?h %2, [%0], #4\n\t" | 117 | "str%?h %2, [%0], #4" |
112 | "str%?h %3, [%0], #4\n\t" | 118 | : "+r" (offset), "=&r" (tmp), "=&r" (tmp2)); |
113 | "mov%? %3, %3, lsr #16\n\t" | ||
114 | "str%?h %3, [%0], #4" | ||
115 | : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2) | ||
116 | : "0" (offset), "1" (buf)); | ||
117 | length -= 8; | ||
118 | } | 119 | } |
119 | while (length > 0) { | 120 | while (length > 0) { |
120 | __asm__ __volatile__("str%?h %2, [%0], #4" | 121 | asm volatile("str%?h %2, [%0], #4" |
121 | : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8))); | 122 | : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8))); |
122 | buf += 2; | 123 | buf += 2; |
123 | length -= 2; | 124 | length -= 2; |
124 | } | 125 | } |
125 | } | 126 | } |
126 | 127 | ||
127 | static inline void | 128 | static void |
128 | am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length) | 129 | am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length) |
129 | { | 130 | { |
130 | offset = ISAMEM_BASE + (offset << 1); | 131 | offset = ISAMEM_BASE + (offset << 1); |
131 | length = (length + 1) & ~1; | 132 | length = (length + 1) & ~1; |
132 | if ((int)buf & 2) { | 133 | if ((int)buf & 2) { |
133 | unsigned int tmp; | 134 | unsigned int tmp; |
134 | __asm__ __volatile__( | 135 | asm volatile( |
135 | "ldr%?h %2, [%0], #4\n\t" | 136 | "ldr%?h %2, [%0], #4\n\t" |
136 | "str%?b %2, [%1], #1\n\t" | 137 | "str%?b %2, [%1], #1\n\t" |
137 | "mov%? %2, %2, lsr #8\n\t" | 138 | "mov%? %2, %2, lsr #8\n\t" |
@@ -140,12 +141,12 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned | |||
140 | length -= 2; | 141 | length -= 2; |
141 | } | 142 | } |
142 | while (length > 8) { | 143 | while (length > 8) { |
143 | unsigned int tmp, tmp2, tmp3; | 144 | register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3; |
144 | __asm__ __volatile__( | 145 | asm volatile( |
145 | "ldr%?h %2, [%0], #4\n\t" | 146 | "ldr%?h %2, [%0], #4\n\t" |
147 | "ldr%?h %4, [%0], #4\n\t" | ||
146 | "ldr%?h %3, [%0], #4\n\t" | 148 | "ldr%?h %3, [%0], #4\n\t" |
147 | "orr%? %2, %2, %3, lsl #16\n\t" | 149 | "orr%? %2, %2, %4, lsl #16\n\t" |
148 | "ldr%?h %3, [%0], #4\n\t" | ||
149 | "ldr%?h %4, [%0], #4\n\t" | 150 | "ldr%?h %4, [%0], #4\n\t" |
150 | "orr%? %3, %3, %4, lsl #16\n\t" | 151 | "orr%? %3, %3, %4, lsl #16\n\t" |
151 | "stm%?ia %1!, {%2, %3}" | 152 | "stm%?ia %1!, {%2, %3}" |
@@ -155,7 +156,7 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned | |||
155 | } | 156 | } |
156 | while (length > 0) { | 157 | while (length > 0) { |
157 | unsigned int tmp; | 158 | unsigned int tmp; |
158 | __asm__ __volatile__( | 159 | asm volatile( |
159 | "ldr%?h %2, [%0], #4\n\t" | 160 | "ldr%?h %2, [%0], #4\n\t" |
160 | "str%?b %2, [%1], #1\n\t" | 161 | "str%?b %2, [%1], #1\n\t" |
161 | "mov%? %2, %2, lsr #8\n\t" | 162 | "mov%? %2, %2, lsr #8\n\t" |
@@ -196,6 +197,42 @@ am79c961_ramtest(struct net_device *dev, unsigned int val) | |||
196 | return errorcount; | 197 | return errorcount; |
197 | } | 198 | } |
198 | 199 | ||
200 | static void am79c961_mc_hash(char *addr, u16 *hash) | ||
201 | { | ||
202 | if (addr[0] & 0x01) { | ||
203 | int idx, bit; | ||
204 | u32 crc; | ||
205 | |||
206 | crc = ether_crc_le(ETH_ALEN, addr); | ||
207 | |||
208 | idx = crc >> 30; | ||
209 | bit = (crc >> 26) & 15; | ||
210 | |||
211 | hash[idx] |= 1 << bit; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash) | ||
216 | { | ||
217 | unsigned int mode = MODE_PORT_10BT; | ||
218 | |||
219 | if (dev->flags & IFF_PROMISC) { | ||
220 | mode |= MODE_PROMISC; | ||
221 | memset(hash, 0xff, 4 * sizeof(*hash)); | ||
222 | } else if (dev->flags & IFF_ALLMULTI) { | ||
223 | memset(hash, 0xff, 4 * sizeof(*hash)); | ||
224 | } else { | ||
225 | struct netdev_hw_addr *ha; | ||
226 | |||
227 | memset(hash, 0, 4 * sizeof(*hash)); | ||
228 | |||
229 | netdev_for_each_mc_addr(ha, dev) | ||
230 | am79c961_mc_hash(ha->addr, hash); | ||
231 | } | ||
232 | |||
233 | return mode; | ||
234 | } | ||
235 | |||
199 | static void | 236 | static void |
200 | am79c961_init_for_open(struct net_device *dev) | 237 | am79c961_init_for_open(struct net_device *dev) |
201 | { | 238 | { |
@@ -203,6 +240,7 @@ am79c961_init_for_open(struct net_device *dev) | |||
203 | unsigned long flags; | 240 | unsigned long flags; |
204 | unsigned char *p; | 241 | unsigned char *p; |
205 | u_int hdr_addr, first_free_addr; | 242 | u_int hdr_addr, first_free_addr; |
243 | u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash); | ||
206 | int i; | 244 | int i; |
207 | 245 | ||
208 | /* | 246 | /* |
@@ -218,16 +256,12 @@ am79c961_init_for_open(struct net_device *dev) | |||
218 | write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */ | 256 | write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */ |
219 | 257 | ||
220 | for (i = LADRL; i <= LADRH; i++) | 258 | for (i = LADRL; i <= LADRH; i++) |
221 | write_rreg (dev->base_addr, i, 0); | 259 | write_rreg (dev->base_addr, i, multi_hash[i - LADRL]); |
222 | 260 | ||
223 | for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2) | 261 | for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2) |
224 | write_rreg (dev->base_addr, i, p[0] | (p[1] << 8)); | 262 | write_rreg (dev->base_addr, i, p[0] | (p[1] << 8)); |
225 | 263 | ||
226 | i = MODE_PORT_10BT; | 264 | write_rreg (dev->base_addr, MODE, mode); |
227 | if (dev->flags & IFF_PROMISC) | ||
228 | i |= MODE_PROMISC; | ||
229 | |||
230 | write_rreg (dev->base_addr, MODE, i); | ||
231 | write_rreg (dev->base_addr, POLLINT, 0); | 265 | write_rreg (dev->base_addr, POLLINT, 0); |
232 | write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS); | 266 | write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS); |
233 | write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS); | 267 | write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS); |
@@ -300,8 +334,6 @@ am79c961_open(struct net_device *dev) | |||
300 | struct dev_priv *priv = netdev_priv(dev); | 334 | struct dev_priv *priv = netdev_priv(dev); |
301 | int ret; | 335 | int ret; |
302 | 336 | ||
303 | memset (&priv->stats, 0, sizeof (priv->stats)); | ||
304 | |||
305 | ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev); | 337 | ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev); |
306 | if (ret) | 338 | if (ret) |
307 | return ret; | 339 | return ret; |
@@ -343,54 +375,15 @@ am79c961_close(struct net_device *dev) | |||
343 | } | 375 | } |
344 | 376 | ||
345 | /* | 377 | /* |
346 | * Get the current statistics. | ||
347 | */ | ||
348 | static struct net_device_stats *am79c961_getstats (struct net_device *dev) | ||
349 | { | ||
350 | struct dev_priv *priv = netdev_priv(dev); | ||
351 | return &priv->stats; | ||
352 | } | ||
353 | |||
354 | static void am79c961_mc_hash(char *addr, unsigned short *hash) | ||
355 | { | ||
356 | if (addr[0] & 0x01) { | ||
357 | int idx, bit; | ||
358 | u32 crc; | ||
359 | |||
360 | crc = ether_crc_le(ETH_ALEN, addr); | ||
361 | |||
362 | idx = crc >> 30; | ||
363 | bit = (crc >> 26) & 15; | ||
364 | |||
365 | hash[idx] |= 1 << bit; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | /* | ||
370 | * Set or clear promiscuous/multicast mode filter for this adapter. | 378 | * Set or clear promiscuous/multicast mode filter for this adapter. |
371 | */ | 379 | */ |
372 | static void am79c961_setmulticastlist (struct net_device *dev) | 380 | static void am79c961_setmulticastlist (struct net_device *dev) |
373 | { | 381 | { |
374 | struct dev_priv *priv = netdev_priv(dev); | 382 | struct dev_priv *priv = netdev_priv(dev); |
375 | unsigned long flags; | 383 | unsigned long flags; |
376 | unsigned short multi_hash[4], mode; | 384 | u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash); |
377 | int i, stopped; | 385 | int i, stopped; |
378 | 386 | ||
379 | mode = MODE_PORT_10BT; | ||
380 | |||
381 | if (dev->flags & IFF_PROMISC) { | ||
382 | mode |= MODE_PROMISC; | ||
383 | } else if (dev->flags & IFF_ALLMULTI) { | ||
384 | memset(multi_hash, 0xff, sizeof(multi_hash)); | ||
385 | } else { | ||
386 | struct netdev_hw_addr *ha; | ||
387 | |||
388 | memset(multi_hash, 0x00, sizeof(multi_hash)); | ||
389 | |||
390 | netdev_for_each_mc_addr(ha, dev) | ||
391 | am79c961_mc_hash(ha->addr, multi_hash); | ||
392 | } | ||
393 | |||
394 | spin_lock_irqsave(&priv->chip_lock, flags); | 387 | spin_lock_irqsave(&priv->chip_lock, flags); |
395 | 388 | ||
396 | stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP; | 389 | stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP; |
@@ -510,14 +503,14 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) | |||
510 | 503 | ||
511 | if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) { | 504 | if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) { |
512 | am_writeword (dev, hdraddr + 2, RMD_OWN); | 505 | am_writeword (dev, hdraddr + 2, RMD_OWN); |
513 | priv->stats.rx_errors ++; | 506 | dev->stats.rx_errors++; |
514 | if (status & RMD_ERR) { | 507 | if (status & RMD_ERR) { |
515 | if (status & RMD_FRAM) | 508 | if (status & RMD_FRAM) |
516 | priv->stats.rx_frame_errors ++; | 509 | dev->stats.rx_frame_errors++; |
517 | if (status & RMD_CRC) | 510 | if (status & RMD_CRC) |
518 | priv->stats.rx_crc_errors ++; | 511 | dev->stats.rx_crc_errors++; |
519 | } else if (status & RMD_STP) | 512 | } else if (status & RMD_STP) |
520 | priv->stats.rx_length_errors ++; | 513 | dev->stats.rx_length_errors++; |
521 | continue; | 514 | continue; |
522 | } | 515 | } |
523 | 516 | ||
@@ -531,12 +524,12 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) | |||
531 | am_writeword(dev, hdraddr + 2, RMD_OWN); | 524 | am_writeword(dev, hdraddr + 2, RMD_OWN); |
532 | skb->protocol = eth_type_trans(skb, dev); | 525 | skb->protocol = eth_type_trans(skb, dev); |
533 | netif_rx(skb); | 526 | netif_rx(skb); |
534 | priv->stats.rx_bytes += len; | 527 | dev->stats.rx_bytes += len; |
535 | priv->stats.rx_packets ++; | 528 | dev->stats.rx_packets++; |
536 | } else { | 529 | } else { |
537 | am_writeword (dev, hdraddr + 2, RMD_OWN); | 530 | am_writeword (dev, hdraddr + 2, RMD_OWN); |
538 | printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); | 531 | printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); |
539 | priv->stats.rx_dropped ++; | 532 | dev->stats.rx_dropped++; |
540 | break; | 533 | break; |
541 | } | 534 | } |
542 | } while (1); | 535 | } while (1); |
@@ -565,7 +558,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) | |||
565 | if (status & TMD_ERR) { | 558 | if (status & TMD_ERR) { |
566 | u_int status2; | 559 | u_int status2; |
567 | 560 | ||
568 | priv->stats.tx_errors ++; | 561 | dev->stats.tx_errors++; |
569 | 562 | ||
570 | status2 = am_readword (dev, hdraddr + 6); | 563 | status2 = am_readword (dev, hdraddr + 6); |
571 | 564 | ||
@@ -575,18 +568,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) | |||
575 | am_writeword (dev, hdraddr + 6, 0); | 568 | am_writeword (dev, hdraddr + 6, 0); |
576 | 569 | ||
577 | if (status2 & TST_RTRY) | 570 | if (status2 & TST_RTRY) |
578 | priv->stats.collisions += 16; | 571 | dev->stats.collisions += 16; |
579 | if (status2 & TST_LCOL) | 572 | if (status2 & TST_LCOL) |
580 | priv->stats.tx_window_errors ++; | 573 | dev->stats.tx_window_errors++; |
581 | if (status2 & TST_LCAR) | 574 | if (status2 & TST_LCAR) |
582 | priv->stats.tx_carrier_errors ++; | 575 | dev->stats.tx_carrier_errors++; |
583 | if (status2 & TST_UFLO) | 576 | if (status2 & TST_UFLO) |
584 | priv->stats.tx_fifo_errors ++; | 577 | dev->stats.tx_fifo_errors++; |
585 | continue; | 578 | continue; |
586 | } | 579 | } |
587 | priv->stats.tx_packets ++; | 580 | dev->stats.tx_packets++; |
588 | len = am_readword (dev, hdraddr + 4); | 581 | len = am_readword (dev, hdraddr + 4); |
589 | priv->stats.tx_bytes += -len; | 582 | dev->stats.tx_bytes += -len; |
590 | } while (priv->txtail != priv->txhead); | 583 | } while (priv->txtail != priv->txhead); |
591 | 584 | ||
592 | netif_wake_queue(dev); | 585 | netif_wake_queue(dev); |
@@ -616,7 +609,7 @@ am79c961_interrupt(int irq, void *dev_id) | |||
616 | } | 609 | } |
617 | if (status & CSR0_MISS) { | 610 | if (status & CSR0_MISS) { |
618 | handled = 1; | 611 | handled = 1; |
619 | priv->stats.rx_dropped ++; | 612 | dev->stats.rx_dropped++; |
620 | } | 613 | } |
621 | if (status & CSR0_CERR) { | 614 | if (status & CSR0_CERR) { |
622 | handled = 1; | 615 | handled = 1; |
@@ -668,7 +661,6 @@ static const struct net_device_ops am79c961_netdev_ops = { | |||
668 | .ndo_open = am79c961_open, | 661 | .ndo_open = am79c961_open, |
669 | .ndo_stop = am79c961_close, | 662 | .ndo_stop = am79c961_close, |
670 | .ndo_start_xmit = am79c961_sendpacket, | 663 | .ndo_start_xmit = am79c961_sendpacket, |
671 | .ndo_get_stats = am79c961_getstats, | ||
672 | .ndo_set_multicast_list = am79c961_setmulticastlist, | 664 | .ndo_set_multicast_list = am79c961_setmulticastlist, |
673 | .ndo_tx_timeout = am79c961_timeout, | 665 | .ndo_tx_timeout = am79c961_timeout, |
674 | .ndo_validate_addr = eth_validate_addr, | 666 | .ndo_validate_addr = eth_validate_addr, |
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h index 483009fe6ec2..fd634d32756b 100644 --- a/drivers/net/arm/am79c961a.h +++ b/drivers/net/arm/am79c961a.h | |||
@@ -130,7 +130,6 @@ | |||
130 | #define ISALED0_LNKST 0x8000 | 130 | #define ISALED0_LNKST 0x8000 |
131 | 131 | ||
132 | struct dev_priv { | 132 | struct dev_priv { |
133 | struct net_device_stats stats; | ||
134 | unsigned long rxbuffer[RX_BUFFERS]; | 133 | unsigned long rxbuffer[RX_BUFFERS]; |
135 | unsigned long txbuffer[TX_BUFFERS]; | 134 | unsigned long txbuffer[TX_BUFFERS]; |
136 | unsigned char txhead; | 135 | unsigned char txhead; |
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 4a5ec9470aa1..0b46b8ea0e80 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c | |||
@@ -175,8 +175,6 @@ struct ep93xx_priv | |||
175 | struct net_device *dev; | 175 | struct net_device *dev; |
176 | struct napi_struct napi; | 176 | struct napi_struct napi; |
177 | 177 | ||
178 | struct net_device_stats stats; | ||
179 | |||
180 | struct mii_if_info mii; | 178 | struct mii_if_info mii; |
181 | u8 mdc_divisor; | 179 | u8 mdc_divisor; |
182 | }; | 180 | }; |
@@ -230,12 +228,6 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d | |||
230 | pr_info("mdio write timed out\n"); | 228 | pr_info("mdio write timed out\n"); |
231 | } | 229 | } |
232 | 230 | ||
233 | static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) | ||
234 | { | ||
235 | struct ep93xx_priv *ep = netdev_priv(dev); | ||
236 | return &(ep->stats); | ||
237 | } | ||
238 | |||
239 | static int ep93xx_rx(struct net_device *dev, int processed, int budget) | 231 | static int ep93xx_rx(struct net_device *dev, int processed, int budget) |
240 | { | 232 | { |
241 | struct ep93xx_priv *ep = netdev_priv(dev); | 233 | struct ep93xx_priv *ep = netdev_priv(dev); |
@@ -267,15 +259,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) | |||
267 | pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1); | 259 | pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1); |
268 | 260 | ||
269 | if (!(rstat0 & RSTAT0_RWE)) { | 261 | if (!(rstat0 & RSTAT0_RWE)) { |
270 | ep->stats.rx_errors++; | 262 | dev->stats.rx_errors++; |
271 | if (rstat0 & RSTAT0_OE) | 263 | if (rstat0 & RSTAT0_OE) |
272 | ep->stats.rx_fifo_errors++; | 264 | dev->stats.rx_fifo_errors++; |
273 | if (rstat0 & RSTAT0_FE) | 265 | if (rstat0 & RSTAT0_FE) |
274 | ep->stats.rx_frame_errors++; | 266 | dev->stats.rx_frame_errors++; |
275 | if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA)) | 267 | if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA)) |
276 | ep->stats.rx_length_errors++; | 268 | dev->stats.rx_length_errors++; |
277 | if (rstat0 & RSTAT0_CRCE) | 269 | if (rstat0 & RSTAT0_CRCE) |
278 | ep->stats.rx_crc_errors++; | 270 | dev->stats.rx_crc_errors++; |
279 | goto err; | 271 | goto err; |
280 | } | 272 | } |
281 | 273 | ||
@@ -291,19 +283,23 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) | |||
291 | 283 | ||
292 | skb = dev_alloc_skb(length + 2); | 284 | skb = dev_alloc_skb(length + 2); |
293 | if (likely(skb != NULL)) { | 285 | if (likely(skb != NULL)) { |
286 | struct ep93xx_rdesc *rxd = &ep->descs->rdesc[entry]; | ||
294 | skb_reserve(skb, 2); | 287 | skb_reserve(skb, 2); |
295 | dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr, | 288 | dma_sync_single_for_cpu(dev->dev.parent, rxd->buf_addr, |
296 | length, DMA_FROM_DEVICE); | 289 | length, DMA_FROM_DEVICE); |
297 | skb_copy_to_linear_data(skb, ep->rx_buf[entry], length); | 290 | skb_copy_to_linear_data(skb, ep->rx_buf[entry], length); |
291 | dma_sync_single_for_device(dev->dev.parent, | ||
292 | rxd->buf_addr, length, | ||
293 | DMA_FROM_DEVICE); | ||
298 | skb_put(skb, length); | 294 | skb_put(skb, length); |
299 | skb->protocol = eth_type_trans(skb, dev); | 295 | skb->protocol = eth_type_trans(skb, dev); |
300 | 296 | ||
301 | netif_receive_skb(skb); | 297 | netif_receive_skb(skb); |
302 | 298 | ||
303 | ep->stats.rx_packets++; | 299 | dev->stats.rx_packets++; |
304 | ep->stats.rx_bytes += length; | 300 | dev->stats.rx_bytes += length; |
305 | } else { | 301 | } else { |
306 | ep->stats.rx_dropped++; | 302 | dev->stats.rx_dropped++; |
307 | } | 303 | } |
308 | 304 | ||
309 | err: | 305 | err: |
@@ -356,10 +352,11 @@ poll_some_more: | |||
356 | static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) | 352 | static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) |
357 | { | 353 | { |
358 | struct ep93xx_priv *ep = netdev_priv(dev); | 354 | struct ep93xx_priv *ep = netdev_priv(dev); |
355 | struct ep93xx_tdesc *txd; | ||
359 | int entry; | 356 | int entry; |
360 | 357 | ||
361 | if (unlikely(skb->len > MAX_PKT_SIZE)) { | 358 | if (unlikely(skb->len > MAX_PKT_SIZE)) { |
362 | ep->stats.tx_dropped++; | 359 | dev->stats.tx_dropped++; |
363 | dev_kfree_skb(skb); | 360 | dev_kfree_skb(skb); |
364 | return NETDEV_TX_OK; | 361 | return NETDEV_TX_OK; |
365 | } | 362 | } |
@@ -367,11 +364,14 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) | |||
367 | entry = ep->tx_pointer; | 364 | entry = ep->tx_pointer; |
368 | ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1); | 365 | ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1); |
369 | 366 | ||
370 | ep->descs->tdesc[entry].tdesc1 = | 367 | txd = &ep->descs->tdesc[entry]; |
371 | TDESC1_EOF | (entry << 16) | (skb->len & 0xfff); | 368 | |
369 | txd->tdesc1 = TDESC1_EOF | (entry << 16) | (skb->len & 0xfff); | ||
370 | dma_sync_single_for_cpu(dev->dev.parent, txd->buf_addr, skb->len, | ||
371 | DMA_TO_DEVICE); | ||
372 | skb_copy_and_csum_dev(skb, ep->tx_buf[entry]); | 372 | skb_copy_and_csum_dev(skb, ep->tx_buf[entry]); |
373 | dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr, | 373 | dma_sync_single_for_device(dev->dev.parent, txd->buf_addr, skb->len, |
374 | skb->len, DMA_TO_DEVICE); | 374 | DMA_TO_DEVICE); |
375 | dev_kfree_skb(skb); | 375 | dev_kfree_skb(skb); |
376 | 376 | ||
377 | spin_lock_irq(&ep->tx_pending_lock); | 377 | spin_lock_irq(&ep->tx_pending_lock); |
@@ -415,17 +415,17 @@ static void ep93xx_tx_complete(struct net_device *dev) | |||
415 | if (tstat0 & TSTAT0_TXWE) { | 415 | if (tstat0 & TSTAT0_TXWE) { |
416 | int length = ep->descs->tdesc[entry].tdesc1 & 0xfff; | 416 | int length = ep->descs->tdesc[entry].tdesc1 & 0xfff; |
417 | 417 | ||
418 | ep->stats.tx_packets++; | 418 | dev->stats.tx_packets++; |
419 | ep->stats.tx_bytes += length; | 419 | dev->stats.tx_bytes += length; |
420 | } else { | 420 | } else { |
421 | ep->stats.tx_errors++; | 421 | dev->stats.tx_errors++; |
422 | } | 422 | } |
423 | 423 | ||
424 | if (tstat0 & TSTAT0_OW) | 424 | if (tstat0 & TSTAT0_OW) |
425 | ep->stats.tx_window_errors++; | 425 | dev->stats.tx_window_errors++; |
426 | if (tstat0 & TSTAT0_TXU) | 426 | if (tstat0 & TSTAT0_TXU) |
427 | ep->stats.tx_fifo_errors++; | 427 | dev->stats.tx_fifo_errors++; |
428 | ep->stats.collisions += (tstat0 >> 16) & 0x1f; | 428 | dev->stats.collisions += (tstat0 >> 16) & 0x1f; |
429 | 429 | ||
430 | ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1); | 430 | ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1); |
431 | if (ep->tx_pending == TX_QUEUE_ENTRIES) | 431 | if (ep->tx_pending == TX_QUEUE_ENTRIES) |
@@ -465,89 +465,80 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id) | |||
465 | 465 | ||
466 | static void ep93xx_free_buffers(struct ep93xx_priv *ep) | 466 | static void ep93xx_free_buffers(struct ep93xx_priv *ep) |
467 | { | 467 | { |
468 | struct device *dev = ep->dev->dev.parent; | ||
468 | int i; | 469 | int i; |
469 | 470 | ||
470 | for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) { | 471 | for (i = 0; i < RX_QUEUE_ENTRIES; i++) { |
471 | dma_addr_t d; | 472 | dma_addr_t d; |
472 | 473 | ||
473 | d = ep->descs->rdesc[i].buf_addr; | 474 | d = ep->descs->rdesc[i].buf_addr; |
474 | if (d) | 475 | if (d) |
475 | dma_unmap_single(NULL, d, PAGE_SIZE, DMA_FROM_DEVICE); | 476 | dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_FROM_DEVICE); |
476 | 477 | ||
477 | if (ep->rx_buf[i] != NULL) | 478 | if (ep->rx_buf[i] != NULL) |
478 | free_page((unsigned long)ep->rx_buf[i]); | 479 | kfree(ep->rx_buf[i]); |
479 | } | 480 | } |
480 | 481 | ||
481 | for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) { | 482 | for (i = 0; i < TX_QUEUE_ENTRIES; i++) { |
482 | dma_addr_t d; | 483 | dma_addr_t d; |
483 | 484 | ||
484 | d = ep->descs->tdesc[i].buf_addr; | 485 | d = ep->descs->tdesc[i].buf_addr; |
485 | if (d) | 486 | if (d) |
486 | dma_unmap_single(NULL, d, PAGE_SIZE, DMA_TO_DEVICE); | 487 | dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_TO_DEVICE); |
487 | 488 | ||
488 | if (ep->tx_buf[i] != NULL) | 489 | if (ep->tx_buf[i] != NULL) |
489 | free_page((unsigned long)ep->tx_buf[i]); | 490 | kfree(ep->tx_buf[i]); |
490 | } | 491 | } |
491 | 492 | ||
492 | dma_free_coherent(NULL, sizeof(struct ep93xx_descs), ep->descs, | 493 | dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs, |
493 | ep->descs_dma_addr); | 494 | ep->descs_dma_addr); |
494 | } | 495 | } |
495 | 496 | ||
496 | /* | ||
497 | * The hardware enforces a sub-2K maximum packet size, so we put | ||
498 | * two buffers on every hardware page. | ||
499 | */ | ||
500 | static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) | 497 | static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) |
501 | { | 498 | { |
499 | struct device *dev = ep->dev->dev.parent; | ||
502 | int i; | 500 | int i; |
503 | 501 | ||
504 | ep->descs = dma_alloc_coherent(NULL, sizeof(struct ep93xx_descs), | 502 | ep->descs = dma_alloc_coherent(dev, sizeof(struct ep93xx_descs), |
505 | &ep->descs_dma_addr, GFP_KERNEL | GFP_DMA); | 503 | &ep->descs_dma_addr, GFP_KERNEL); |
506 | if (ep->descs == NULL) | 504 | if (ep->descs == NULL) |
507 | return 1; | 505 | return 1; |
508 | 506 | ||
509 | for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) { | 507 | for (i = 0; i < RX_QUEUE_ENTRIES; i++) { |
510 | void *page; | 508 | void *buf; |
511 | dma_addr_t d; | 509 | dma_addr_t d; |
512 | 510 | ||
513 | page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); | 511 | buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL); |
514 | if (page == NULL) | 512 | if (buf == NULL) |
515 | goto err; | 513 | goto err; |
516 | 514 | ||
517 | d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE); | 515 | d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_FROM_DEVICE); |
518 | if (dma_mapping_error(NULL, d)) { | 516 | if (dma_mapping_error(dev, d)) { |
519 | free_page((unsigned long)page); | 517 | kfree(buf); |
520 | goto err; | 518 | goto err; |
521 | } | 519 | } |
522 | 520 | ||
523 | ep->rx_buf[i] = page; | 521 | ep->rx_buf[i] = buf; |
524 | ep->descs->rdesc[i].buf_addr = d; | 522 | ep->descs->rdesc[i].buf_addr = d; |
525 | ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE; | 523 | ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE; |
526 | |||
527 | ep->rx_buf[i + 1] = page + PKT_BUF_SIZE; | ||
528 | ep->descs->rdesc[i + 1].buf_addr = d + PKT_BUF_SIZE; | ||
529 | ep->descs->rdesc[i + 1].rdesc1 = ((i + 1) << 16) | PKT_BUF_SIZE; | ||
530 | } | 524 | } |
531 | 525 | ||
532 | for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) { | 526 | for (i = 0; i < TX_QUEUE_ENTRIES; i++) { |
533 | void *page; | 527 | void *buf; |
534 | dma_addr_t d; | 528 | dma_addr_t d; |
535 | 529 | ||
536 | page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); | 530 | buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL); |
537 | if (page == NULL) | 531 | if (buf == NULL) |
538 | goto err; | 532 | goto err; |
539 | 533 | ||
540 | d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE); | 534 | d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_TO_DEVICE); |
541 | if (dma_mapping_error(NULL, d)) { | 535 | if (dma_mapping_error(dev, d)) { |
542 | free_page((unsigned long)page); | 536 | kfree(buf); |
543 | goto err; | 537 | goto err; |
544 | } | 538 | } |
545 | 539 | ||
546 | ep->tx_buf[i] = page; | 540 | ep->tx_buf[i] = buf; |
547 | ep->descs->tdesc[i].buf_addr = d; | 541 | ep->descs->tdesc[i].buf_addr = d; |
548 | |||
549 | ep->tx_buf[i + 1] = page + PKT_BUF_SIZE; | ||
550 | ep->descs->tdesc[i + 1].buf_addr = d + PKT_BUF_SIZE; | ||
551 | } | 542 | } |
552 | 543 | ||
553 | return 0; | 544 | return 0; |
@@ -758,7 +749,6 @@ static const struct net_device_ops ep93xx_netdev_ops = { | |||
758 | .ndo_open = ep93xx_open, | 749 | .ndo_open = ep93xx_open, |
759 | .ndo_stop = ep93xx_close, | 750 | .ndo_stop = ep93xx_close, |
760 | .ndo_start_xmit = ep93xx_xmit, | 751 | .ndo_start_xmit = ep93xx_xmit, |
761 | .ndo_get_stats = ep93xx_get_stats, | ||
762 | .ndo_do_ioctl = ep93xx_ioctl, | 752 | .ndo_do_ioctl = ep93xx_ioctl, |
763 | .ndo_validate_addr = eth_validate_addr, | 753 | .ndo_validate_addr = eth_validate_addr, |
764 | .ndo_change_mtu = eth_change_mtu, | 754 | .ndo_change_mtu = eth_change_mtu, |
@@ -838,6 +828,7 @@ static int ep93xx_eth_probe(struct platform_device *pdev) | |||
838 | } | 828 | } |
839 | ep = netdev_priv(dev); | 829 | ep = netdev_priv(dev); |
840 | ep->dev = dev; | 830 | ep->dev = dev; |
831 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
841 | netif_napi_add(dev, &ep->napi, ep93xx_poll, 64); | 832 | netif_napi_add(dev, &ep->napi, ep93xx_poll, 64); |
842 | 833 | ||
843 | platform_set_drvdata(pdev, dev); | 834 | platform_set_drvdata(pdev, dev); |
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index b17ab5153f51..b00781c02d5d 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c | |||
@@ -68,7 +68,6 @@ static int ether1_open(struct net_device *dev); | |||
68 | static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); | 68 | static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); |
69 | static irqreturn_t ether1_interrupt(int irq, void *dev_id); | 69 | static irqreturn_t ether1_interrupt(int irq, void *dev_id); |
70 | static int ether1_close(struct net_device *dev); | 70 | static int ether1_close(struct net_device *dev); |
71 | static struct net_device_stats *ether1_getstats(struct net_device *dev); | ||
72 | static void ether1_setmulticastlist(struct net_device *dev); | 71 | static void ether1_setmulticastlist(struct net_device *dev); |
73 | static void ether1_timeout(struct net_device *dev); | 72 | static void ether1_timeout(struct net_device *dev); |
74 | 73 | ||
@@ -649,8 +648,6 @@ ether1_open (struct net_device *dev) | |||
649 | if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) | 648 | if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) |
650 | return -EAGAIN; | 649 | return -EAGAIN; |
651 | 650 | ||
652 | memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats)); | ||
653 | |||
654 | if (ether1_init_for_open (dev)) { | 651 | if (ether1_init_for_open (dev)) { |
655 | free_irq (dev->irq, dev); | 652 | free_irq (dev->irq, dev); |
656 | return -EAGAIN; | 653 | return -EAGAIN; |
@@ -673,7 +670,7 @@ ether1_timeout(struct net_device *dev) | |||
673 | if (ether1_init_for_open (dev)) | 670 | if (ether1_init_for_open (dev)) |
674 | printk (KERN_ERR "%s: unable to restart interface\n", dev->name); | 671 | printk (KERN_ERR "%s: unable to restart interface\n", dev->name); |
675 | 672 | ||
676 | priv(dev)->stats.tx_errors++; | 673 | dev->stats.tx_errors++; |
677 | netif_wake_queue(dev); | 674 | netif_wake_queue(dev); |
678 | } | 675 | } |
679 | 676 | ||
@@ -802,21 +799,21 @@ again: | |||
802 | 799 | ||
803 | while (nop.nop_status & STAT_COMPLETE) { | 800 | while (nop.nop_status & STAT_COMPLETE) { |
804 | if (nop.nop_status & STAT_OK) { | 801 | if (nop.nop_status & STAT_OK) { |
805 | priv(dev)->stats.tx_packets ++; | 802 | dev->stats.tx_packets++; |
806 | priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS); | 803 | dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS); |
807 | } else { | 804 | } else { |
808 | priv(dev)->stats.tx_errors ++; | 805 | dev->stats.tx_errors++; |
809 | 806 | ||
810 | if (nop.nop_status & STAT_COLLAFTERTX) | 807 | if (nop.nop_status & STAT_COLLAFTERTX) |
811 | priv(dev)->stats.collisions ++; | 808 | dev->stats.collisions++; |
812 | if (nop.nop_status & STAT_NOCARRIER) | 809 | if (nop.nop_status & STAT_NOCARRIER) |
813 | priv(dev)->stats.tx_carrier_errors ++; | 810 | dev->stats.tx_carrier_errors++; |
814 | if (nop.nop_status & STAT_TXLOSTCTS) | 811 | if (nop.nop_status & STAT_TXLOSTCTS) |
815 | printk (KERN_WARNING "%s: cts lost\n", dev->name); | 812 | printk (KERN_WARNING "%s: cts lost\n", dev->name); |
816 | if (nop.nop_status & STAT_TXSLOWDMA) | 813 | if (nop.nop_status & STAT_TXSLOWDMA) |
817 | priv(dev)->stats.tx_fifo_errors ++; | 814 | dev->stats.tx_fifo_errors++; |
818 | if (nop.nop_status & STAT_COLLEXCESSIVE) | 815 | if (nop.nop_status & STAT_COLLEXCESSIVE) |
819 | priv(dev)->stats.collisions += 16; | 816 | dev->stats.collisions += 16; |
820 | } | 817 | } |
821 | 818 | ||
822 | if (nop.nop_link == caddr) { | 819 | if (nop.nop_link == caddr) { |
@@ -879,13 +876,13 @@ ether1_recv_done (struct net_device *dev) | |||
879 | 876 | ||
880 | skb->protocol = eth_type_trans (skb, dev); | 877 | skb->protocol = eth_type_trans (skb, dev); |
881 | netif_rx (skb); | 878 | netif_rx (skb); |
882 | priv(dev)->stats.rx_packets ++; | 879 | dev->stats.rx_packets++; |
883 | } else | 880 | } else |
884 | priv(dev)->stats.rx_dropped ++; | 881 | dev->stats.rx_dropped++; |
885 | } else { | 882 | } else { |
886 | printk(KERN_WARNING "%s: %s\n", dev->name, | 883 | printk(KERN_WARNING "%s: %s\n", dev->name, |
887 | (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid"); | 884 | (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid"); |
888 | priv(dev)->stats.rx_dropped ++; | 885 | dev->stats.rx_dropped++; |
889 | } | 886 | } |
890 | 887 | ||
891 | nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS); | 888 | nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS); |
@@ -939,7 +936,7 @@ ether1_interrupt (int irq, void *dev_id) | |||
939 | printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name); | 936 | printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name); |
940 | ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS); | 937 | ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS); |
941 | writeb(CTRL_CA, REG_CONTROL); | 938 | writeb(CTRL_CA, REG_CONTROL); |
942 | priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */ | 939 | dev->stats.rx_dropped++; /* we suspended due to lack of buffer space */ |
943 | } else | 940 | } else |
944 | printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name, | 941 | printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name, |
945 | ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS)); | 942 | ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS)); |
@@ -962,12 +959,6 @@ ether1_close (struct net_device *dev) | |||
962 | return 0; | 959 | return 0; |
963 | } | 960 | } |
964 | 961 | ||
965 | static struct net_device_stats * | ||
966 | ether1_getstats (struct net_device *dev) | ||
967 | { | ||
968 | return &priv(dev)->stats; | ||
969 | } | ||
970 | |||
971 | /* | 962 | /* |
972 | * Set or clear the multicast filter for this adaptor. | 963 | * Set or clear the multicast filter for this adaptor. |
973 | * num_addrs == -1 Promiscuous mode, receive all packets. | 964 | * num_addrs == -1 Promiscuous mode, receive all packets. |
@@ -994,7 +985,6 @@ static const struct net_device_ops ether1_netdev_ops = { | |||
994 | .ndo_open = ether1_open, | 985 | .ndo_open = ether1_open, |
995 | .ndo_stop = ether1_close, | 986 | .ndo_stop = ether1_close, |
996 | .ndo_start_xmit = ether1_sendpacket, | 987 | .ndo_start_xmit = ether1_sendpacket, |
997 | .ndo_get_stats = ether1_getstats, | ||
998 | .ndo_set_multicast_list = ether1_setmulticastlist, | 988 | .ndo_set_multicast_list = ether1_setmulticastlist, |
999 | .ndo_tx_timeout = ether1_timeout, | 989 | .ndo_tx_timeout = ether1_timeout, |
1000 | .ndo_validate_addr = eth_validate_addr, | 990 | .ndo_validate_addr = eth_validate_addr, |
diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h index c8a4b2389d85..3a5830ab3dc7 100644 --- a/drivers/net/arm/ether1.h +++ b/drivers/net/arm/ether1.h | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | struct ether1_priv { | 39 | struct ether1_priv { |
40 | void __iomem *base; | 40 | void __iomem *base; |
41 | struct net_device_stats stats; | ||
42 | unsigned int tx_link; | 41 | unsigned int tx_link; |
43 | unsigned int tx_head; | 42 | unsigned int tx_head; |
44 | volatile unsigned int tx_tail; | 43 | volatile unsigned int tx_tail; |
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 1361b7367c28..44a8746f4014 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c | |||
@@ -81,7 +81,6 @@ static int ether3_open (struct net_device *dev); | |||
81 | static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); | 81 | static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); |
82 | static irqreturn_t ether3_interrupt (int irq, void *dev_id); | 82 | static irqreturn_t ether3_interrupt (int irq, void *dev_id); |
83 | static int ether3_close (struct net_device *dev); | 83 | static int ether3_close (struct net_device *dev); |
84 | static struct net_device_stats *ether3_getstats (struct net_device *dev); | ||
85 | static void ether3_setmulticastlist (struct net_device *dev); | 84 | static void ether3_setmulticastlist (struct net_device *dev); |
86 | static void ether3_timeout(struct net_device *dev); | 85 | static void ether3_timeout(struct net_device *dev); |
87 | 86 | ||
@@ -323,8 +322,6 @@ ether3_init_for_open(struct net_device *dev) | |||
323 | { | 322 | { |
324 | int i; | 323 | int i; |
325 | 324 | ||
326 | memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats)); | ||
327 | |||
328 | /* Reset the chip */ | 325 | /* Reset the chip */ |
329 | ether3_outw(CFG2_RESET, REG_CONFIG2); | 326 | ether3_outw(CFG2_RESET, REG_CONFIG2); |
330 | udelay(4); | 327 | udelay(4); |
@@ -442,15 +439,6 @@ ether3_close(struct net_device *dev) | |||
442 | } | 439 | } |
443 | 440 | ||
444 | /* | 441 | /* |
445 | * Get the current statistics. This may be called with the card open or | ||
446 | * closed. | ||
447 | */ | ||
448 | static struct net_device_stats *ether3_getstats(struct net_device *dev) | ||
449 | { | ||
450 | return &priv(dev)->stats; | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * Set or clear promiscuous/multicast mode filter for this adaptor. | 442 | * Set or clear promiscuous/multicast mode filter for this adaptor. |
455 | * | 443 | * |
456 | * We don't attempt any packet filtering. The card may have a SEEQ 8004 | 444 | * We don't attempt any packet filtering. The card may have a SEEQ 8004 |
@@ -490,7 +478,7 @@ static void ether3_timeout(struct net_device *dev) | |||
490 | local_irq_restore(flags); | 478 | local_irq_restore(flags); |
491 | 479 | ||
492 | priv(dev)->regs.config2 |= CFG2_CTRLO; | 480 | priv(dev)->regs.config2 |= CFG2_CTRLO; |
493 | priv(dev)->stats.tx_errors += 1; | 481 | dev->stats.tx_errors += 1; |
494 | ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); | 482 | ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); |
495 | priv(dev)->tx_head = priv(dev)->tx_tail = 0; | 483 | priv(dev)->tx_head = priv(dev)->tx_tail = 0; |
496 | 484 | ||
@@ -509,7 +497,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) | |||
509 | 497 | ||
510 | if (priv(dev)->broken) { | 498 | if (priv(dev)->broken) { |
511 | dev_kfree_skb(skb); | 499 | dev_kfree_skb(skb); |
512 | priv(dev)->stats.tx_dropped ++; | 500 | dev->stats.tx_dropped++; |
513 | netif_start_queue(dev); | 501 | netif_start_queue(dev); |
514 | return NETDEV_TX_OK; | 502 | return NETDEV_TX_OK; |
515 | } | 503 | } |
@@ -673,7 +661,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { | |||
673 | } else | 661 | } else |
674 | goto dropping; | 662 | goto dropping; |
675 | } else { | 663 | } else { |
676 | struct net_device_stats *stats = &priv(dev)->stats; | 664 | struct net_device_stats *stats = &dev->stats; |
677 | ether3_outw(next_ptr >> 8, REG_RECVEND); | 665 | ether3_outw(next_ptr >> 8, REG_RECVEND); |
678 | if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; | 666 | if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; |
679 | if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; | 667 | if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; |
@@ -685,14 +673,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { | |||
685 | while (-- maxcnt); | 673 | while (-- maxcnt); |
686 | 674 | ||
687 | done: | 675 | done: |
688 | priv(dev)->stats.rx_packets += received; | 676 | dev->stats.rx_packets += received; |
689 | priv(dev)->rx_head = next_ptr; | 677 | priv(dev)->rx_head = next_ptr; |
690 | /* | 678 | /* |
691 | * If rx went off line, then that means that the buffer may be full. We | 679 | * If rx went off line, then that means that the buffer may be full. We |
692 | * have dropped at least one packet. | 680 | * have dropped at least one packet. |
693 | */ | 681 | */ |
694 | if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { | 682 | if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { |
695 | priv(dev)->stats.rx_dropped ++; | 683 | dev->stats.rx_dropped++; |
696 | ether3_outw(next_ptr, REG_RECVPTR); | 684 | ether3_outw(next_ptr, REG_RECVPTR); |
697 | ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); | 685 | ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); |
698 | } | 686 | } |
@@ -710,7 +698,7 @@ dropping:{ | |||
710 | last_warned = jiffies; | 698 | last_warned = jiffies; |
711 | printk("%s: memory squeeze, dropping packet.\n", dev->name); | 699 | printk("%s: memory squeeze, dropping packet.\n", dev->name); |
712 | } | 700 | } |
713 | priv(dev)->stats.rx_dropped ++; | 701 | dev->stats.rx_dropped++; |
714 | goto done; | 702 | goto done; |
715 | } | 703 | } |
716 | } | 704 | } |
@@ -743,13 +731,13 @@ static void ether3_tx(struct net_device *dev) | |||
743 | * Update errors | 731 | * Update errors |
744 | */ | 732 | */ |
745 | if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS))) | 733 | if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS))) |
746 | priv(dev)->stats.tx_packets++; | 734 | dev->stats.tx_packets++; |
747 | else { | 735 | else { |
748 | priv(dev)->stats.tx_errors ++; | 736 | dev->stats.tx_errors++; |
749 | if (status & TXSTAT_16COLLISIONS) | 737 | if (status & TXSTAT_16COLLISIONS) |
750 | priv(dev)->stats.collisions += 16; | 738 | dev->stats.collisions += 16; |
751 | if (status & TXSTAT_BABBLED) | 739 | if (status & TXSTAT_BABBLED) |
752 | priv(dev)->stats.tx_fifo_errors ++; | 740 | dev->stats.tx_fifo_errors++; |
753 | } | 741 | } |
754 | 742 | ||
755 | tx_tail = (tx_tail + 1) & 15; | 743 | tx_tail = (tx_tail + 1) & 15; |
@@ -773,7 +761,6 @@ static const struct net_device_ops ether3_netdev_ops = { | |||
773 | .ndo_open = ether3_open, | 761 | .ndo_open = ether3_open, |
774 | .ndo_stop = ether3_close, | 762 | .ndo_stop = ether3_close, |
775 | .ndo_start_xmit = ether3_sendpacket, | 763 | .ndo_start_xmit = ether3_sendpacket, |
776 | .ndo_get_stats = ether3_getstats, | ||
777 | .ndo_set_multicast_list = ether3_setmulticastlist, | 764 | .ndo_set_multicast_list = ether3_setmulticastlist, |
778 | .ndo_tx_timeout = ether3_timeout, | 765 | .ndo_tx_timeout = ether3_timeout, |
779 | .ndo_validate_addr = eth_validate_addr, | 766 | .ndo_validate_addr = eth_validate_addr, |
diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h index 1921a3a07da7..2db63b08bdf3 100644 --- a/drivers/net/arm/ether3.h +++ b/drivers/net/arm/ether3.h | |||
@@ -164,7 +164,6 @@ struct dev_priv { | |||
164 | unsigned char tx_head; /* buffer nr to insert next packet */ | 164 | unsigned char tx_head; /* buffer nr to insert next packet */ |
165 | unsigned char tx_tail; /* buffer nr of transmitting packet */ | 165 | unsigned char tx_tail; /* buffer nr of transmitting packet */ |
166 | unsigned int rx_head; /* address to fetch next packet from */ | 166 | unsigned int rx_head; /* address to fetch next packet from */ |
167 | struct net_device_stats stats; | ||
168 | struct timer_list timer; | 167 | struct timer_list timer; |
169 | int broken; /* 0 = ok, 1 = something went wrong */ | 168 | int broken; /* 0 = ok, 1 = something went wrong */ |
170 | }; | 169 | }; |
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 4af235d41fda..03e217a868d4 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c | |||
@@ -527,7 +527,7 @@ static void __init etherh_banner(void) | |||
527 | * Read the ethernet address string from the on board rom. | 527 | * Read the ethernet address string from the on board rom. |
528 | * This is an ascii string... | 528 | * This is an ascii string... |
529 | */ | 529 | */ |
530 | static int __init etherh_addr(char *addr, struct expansion_card *ec) | 530 | static int __devinit etherh_addr(char *addr, struct expansion_card *ec) |
531 | { | 531 | { |
532 | struct in_chunk_dir cd; | 532 | struct in_chunk_dir cd; |
533 | char *s; | 533 | char *s; |
@@ -591,10 +591,11 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i | |||
591 | static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 591 | static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
592 | { | 592 | { |
593 | cmd->supported = etherh_priv(dev)->supported; | 593 | cmd->supported = etherh_priv(dev)->supported; |
594 | cmd->speed = SPEED_10; | 594 | ethtool_cmd_speed_set(cmd, SPEED_10); |
595 | cmd->duplex = DUPLEX_HALF; | 595 | cmd->duplex = DUPLEX_HALF; |
596 | cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; | 596 | cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; |
597 | cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE; | 597 | cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ? |
598 | AUTONEG_ENABLE : AUTONEG_DISABLE); | ||
598 | return 0; | 599 | return 0; |
599 | } | 600 | } |
600 | 601 | ||
@@ -655,7 +656,7 @@ static const struct net_device_ops etherh_netdev_ops = { | |||
655 | static u32 etherh_regoffsets[16]; | 656 | static u32 etherh_regoffsets[16]; |
656 | static u32 etherm_regoffsets[16]; | 657 | static u32 etherm_regoffsets[16]; |
657 | 658 | ||
658 | static int __init | 659 | static int __devinit |
659 | etherh_probe(struct expansion_card *ec, const struct ecard_id *id) | 660 | etherh_probe(struct expansion_card *ec, const struct ecard_id *id) |
660 | { | 661 | { |
661 | const struct etherh_data *data = id->data; | 662 | const struct etherh_data *data = id->data; |
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 6028226a7270..de51e8453c13 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c | |||
@@ -30,9 +30,12 @@ | |||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/net_tstamp.h> | ||
33 | #include <linux/phy.h> | 34 | #include <linux/phy.h> |
34 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/ptp_classify.h> | ||
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <mach/ixp46x_ts.h> | ||
36 | #include <mach/npe.h> | 39 | #include <mach/npe.h> |
37 | #include <mach/qmgr.h> | 40 | #include <mach/qmgr.h> |
38 | 41 | ||
@@ -67,6 +70,10 @@ | |||
67 | #define RXFREE_QUEUE(port_id) (NPE_ID(port_id) + 26) | 70 | #define RXFREE_QUEUE(port_id) (NPE_ID(port_id) + 26) |
68 | #define TXDONE_QUEUE 31 | 71 | #define TXDONE_QUEUE 31 |
69 | 72 | ||
73 | #define PTP_SLAVE_MODE 1 | ||
74 | #define PTP_MASTER_MODE 2 | ||
75 | #define PORT2CHANNEL(p) NPE_ID(p->id) | ||
76 | |||
70 | /* TX Control Registers */ | 77 | /* TX Control Registers */ |
71 | #define TX_CNTRL0_TX_EN 0x01 | 78 | #define TX_CNTRL0_TX_EN 0x01 |
72 | #define TX_CNTRL0_HALFDUPLEX 0x02 | 79 | #define TX_CNTRL0_HALFDUPLEX 0x02 |
@@ -171,6 +178,8 @@ struct port { | |||
171 | int id; /* logical port ID */ | 178 | int id; /* logical port ID */ |
172 | int speed, duplex; | 179 | int speed, duplex; |
173 | u8 firmware[4]; | 180 | u8 firmware[4]; |
181 | int hwts_tx_en; | ||
182 | int hwts_rx_en; | ||
174 | }; | 183 | }; |
175 | 184 | ||
176 | /* NPE message structure */ | 185 | /* NPE message structure */ |
@@ -246,6 +255,172 @@ static int ports_open; | |||
246 | static struct port *npe_port_tab[MAX_NPES]; | 255 | static struct port *npe_port_tab[MAX_NPES]; |
247 | static struct dma_pool *dma_pool; | 256 | static struct dma_pool *dma_pool; |
248 | 257 | ||
258 | static struct sock_filter ptp_filter[] = { | ||
259 | PTP_FILTER | ||
260 | }; | ||
261 | |||
262 | static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) | ||
263 | { | ||
264 | u8 *data = skb->data; | ||
265 | unsigned int offset; | ||
266 | u16 *hi, *id; | ||
267 | u32 lo; | ||
268 | |||
269 | if (sk_run_filter(skb, ptp_filter) != PTP_CLASS_V1_IPV4) | ||
270 | return 0; | ||
271 | |||
272 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; | ||
273 | |||
274 | if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid)) | ||
275 | return 0; | ||
276 | |||
277 | hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID); | ||
278 | id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); | ||
279 | |||
280 | memcpy(&lo, &hi[1], sizeof(lo)); | ||
281 | |||
282 | return (uid_hi == ntohs(*hi) && | ||
283 | uid_lo == ntohl(lo) && | ||
284 | seqid == ntohs(*id)); | ||
285 | } | ||
286 | |||
287 | static void ixp_rx_timestamp(struct port *port, struct sk_buff *skb) | ||
288 | { | ||
289 | struct skb_shared_hwtstamps *shhwtstamps; | ||
290 | struct ixp46x_ts_regs *regs; | ||
291 | u64 ns; | ||
292 | u32 ch, hi, lo, val; | ||
293 | u16 uid, seq; | ||
294 | |||
295 | if (!port->hwts_rx_en) | ||
296 | return; | ||
297 | |||
298 | ch = PORT2CHANNEL(port); | ||
299 | |||
300 | regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT; | ||
301 | |||
302 | val = __raw_readl(®s->channel[ch].ch_event); | ||
303 | |||
304 | if (!(val & RX_SNAPSHOT_LOCKED)) | ||
305 | return; | ||
306 | |||
307 | lo = __raw_readl(®s->channel[ch].src_uuid_lo); | ||
308 | hi = __raw_readl(®s->channel[ch].src_uuid_hi); | ||
309 | |||
310 | uid = hi & 0xffff; | ||
311 | seq = (hi >> 16) & 0xffff; | ||
312 | |||
313 | if (!ixp_ptp_match(skb, htons(uid), htonl(lo), htons(seq))) | ||
314 | goto out; | ||
315 | |||
316 | lo = __raw_readl(®s->channel[ch].rx_snap_lo); | ||
317 | hi = __raw_readl(®s->channel[ch].rx_snap_hi); | ||
318 | ns = ((u64) hi) << 32; | ||
319 | ns |= lo; | ||
320 | ns <<= TICKS_NS_SHIFT; | ||
321 | |||
322 | shhwtstamps = skb_hwtstamps(skb); | ||
323 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | ||
324 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | ||
325 | out: | ||
326 | __raw_writel(RX_SNAPSHOT_LOCKED, ®s->channel[ch].ch_event); | ||
327 | } | ||
328 | |||
329 | static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb) | ||
330 | { | ||
331 | struct skb_shared_hwtstamps shhwtstamps; | ||
332 | struct ixp46x_ts_regs *regs; | ||
333 | struct skb_shared_info *shtx; | ||
334 | u64 ns; | ||
335 | u32 ch, cnt, hi, lo, val; | ||
336 | |||
337 | shtx = skb_shinfo(skb); | ||
338 | if (unlikely(shtx->tx_flags & SKBTX_HW_TSTAMP && port->hwts_tx_en)) | ||
339 | shtx->tx_flags |= SKBTX_IN_PROGRESS; | ||
340 | else | ||
341 | return; | ||
342 | |||
343 | ch = PORT2CHANNEL(port); | ||
344 | |||
345 | regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT; | ||
346 | |||
347 | /* | ||
348 | * This really stinks, but we have to poll for the Tx time stamp. | ||
349 | * Usually, the time stamp is ready after 4 to 6 microseconds. | ||
350 | */ | ||
351 | for (cnt = 0; cnt < 100; cnt++) { | ||
352 | val = __raw_readl(®s->channel[ch].ch_event); | ||
353 | if (val & TX_SNAPSHOT_LOCKED) | ||
354 | break; | ||
355 | udelay(1); | ||
356 | } | ||
357 | if (!(val & TX_SNAPSHOT_LOCKED)) { | ||
358 | shtx->tx_flags &= ~SKBTX_IN_PROGRESS; | ||
359 | return; | ||
360 | } | ||
361 | |||
362 | lo = __raw_readl(®s->channel[ch].tx_snap_lo); | ||
363 | hi = __raw_readl(®s->channel[ch].tx_snap_hi); | ||
364 | ns = ((u64) hi) << 32; | ||
365 | ns |= lo; | ||
366 | ns <<= TICKS_NS_SHIFT; | ||
367 | |||
368 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | ||
369 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | ||
370 | skb_tstamp_tx(skb, &shhwtstamps); | ||
371 | |||
372 | __raw_writel(TX_SNAPSHOT_LOCKED, ®s->channel[ch].ch_event); | ||
373 | } | ||
374 | |||
375 | static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
376 | { | ||
377 | struct hwtstamp_config cfg; | ||
378 | struct ixp46x_ts_regs *regs; | ||
379 | struct port *port = netdev_priv(netdev); | ||
380 | int ch; | ||
381 | |||
382 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) | ||
383 | return -EFAULT; | ||
384 | |||
385 | if (cfg.flags) /* reserved for future extensions */ | ||
386 | return -EINVAL; | ||
387 | |||
388 | ch = PORT2CHANNEL(port); | ||
389 | regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT; | ||
390 | |||
391 | switch (cfg.tx_type) { | ||
392 | case HWTSTAMP_TX_OFF: | ||
393 | port->hwts_tx_en = 0; | ||
394 | break; | ||
395 | case HWTSTAMP_TX_ON: | ||
396 | port->hwts_tx_en = 1; | ||
397 | break; | ||
398 | default: | ||
399 | return -ERANGE; | ||
400 | } | ||
401 | |||
402 | switch (cfg.rx_filter) { | ||
403 | case HWTSTAMP_FILTER_NONE: | ||
404 | port->hwts_rx_en = 0; | ||
405 | break; | ||
406 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
407 | port->hwts_rx_en = PTP_SLAVE_MODE; | ||
408 | __raw_writel(0, ®s->channel[ch].ch_control); | ||
409 | break; | ||
410 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
411 | port->hwts_rx_en = PTP_MASTER_MODE; | ||
412 | __raw_writel(MASTER_MODE, ®s->channel[ch].ch_control); | ||
413 | break; | ||
414 | default: | ||
415 | return -ERANGE; | ||
416 | } | ||
417 | |||
418 | /* Clear out any old time stamps. */ | ||
419 | __raw_writel(TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED, | ||
420 | ®s->channel[ch].ch_event); | ||
421 | |||
422 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | ||
423 | } | ||
249 | 424 | ||
250 | static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location, | 425 | static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location, |
251 | int write, u16 cmd) | 426 | int write, u16 cmd) |
@@ -573,6 +748,7 @@ static int eth_poll(struct napi_struct *napi, int budget) | |||
573 | 748 | ||
574 | debug_pkt(dev, "eth_poll", skb->data, skb->len); | 749 | debug_pkt(dev, "eth_poll", skb->data, skb->len); |
575 | 750 | ||
751 | ixp_rx_timestamp(port, skb); | ||
576 | skb->protocol = eth_type_trans(skb, dev); | 752 | skb->protocol = eth_type_trans(skb, dev); |
577 | dev->stats.rx_packets++; | 753 | dev->stats.rx_packets++; |
578 | dev->stats.rx_bytes += skb->len; | 754 | dev->stats.rx_bytes += skb->len; |
@@ -679,14 +855,12 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
679 | return NETDEV_TX_OK; | 855 | return NETDEV_TX_OK; |
680 | } | 856 | } |
681 | memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4); | 857 | memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4); |
682 | dev_kfree_skb(skb); | ||
683 | #endif | 858 | #endif |
684 | 859 | ||
685 | phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE); | 860 | phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE); |
686 | if (dma_mapping_error(&dev->dev, phys)) { | 861 | if (dma_mapping_error(&dev->dev, phys)) { |
687 | #ifdef __ARMEB__ | ||
688 | dev_kfree_skb(skb); | 862 | dev_kfree_skb(skb); |
689 | #else | 863 | #ifndef __ARMEB__ |
690 | kfree(mem); | 864 | kfree(mem); |
691 | #endif | 865 | #endif |
692 | dev->stats.tx_dropped++; | 866 | dev->stats.tx_dropped++; |
@@ -728,6 +902,13 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
728 | #if DEBUG_TX | 902 | #if DEBUG_TX |
729 | printk(KERN_DEBUG "%s: eth_xmit end\n", dev->name); | 903 | printk(KERN_DEBUG "%s: eth_xmit end\n", dev->name); |
730 | #endif | 904 | #endif |
905 | |||
906 | ixp_tx_timestamp(port, skb); | ||
907 | skb_tx_timestamp(skb); | ||
908 | |||
909 | #ifndef __ARMEB__ | ||
910 | dev_kfree_skb(skb); | ||
911 | #endif | ||
731 | return NETDEV_TX_OK; | 912 | return NETDEV_TX_OK; |
732 | } | 913 | } |
733 | 914 | ||
@@ -783,6 +964,9 @@ static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | |||
783 | if (!netif_running(dev)) | 964 | if (!netif_running(dev)) |
784 | return -EINVAL; | 965 | return -EINVAL; |
785 | 966 | ||
967 | if (cpu_is_ixp46x() && cmd == SIOCSHWTSTAMP) | ||
968 | return hwtstamp_ioctl(dev, req, cmd); | ||
969 | |||
786 | return phy_mii_ioctl(port->phydev, req, cmd); | 970 | return phy_mii_ioctl(port->phydev, req, cmd); |
787 | } | 971 | } |
788 | 972 | ||
@@ -1171,6 +1355,11 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1171 | char phy_id[MII_BUS_ID_SIZE + 3]; | 1355 | char phy_id[MII_BUS_ID_SIZE + 3]; |
1172 | int err; | 1356 | int err; |
1173 | 1357 | ||
1358 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | ||
1359 | pr_err("ixp4xx_eth: bad ptp filter\n"); | ||
1360 | return -EINVAL; | ||
1361 | } | ||
1362 | |||
1174 | if (!(dev = alloc_etherdev(sizeof(struct port)))) | 1363 | if (!(dev = alloc_etherdev(sizeof(struct port)))) |
1175 | return -ENOMEM; | 1364 | return -ENOMEM; |
1176 | 1365 | ||
@@ -1229,8 +1418,10 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1229 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); | 1418 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); |
1230 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, | 1419 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, |
1231 | PHY_INTERFACE_MODE_MII); | 1420 | PHY_INTERFACE_MODE_MII); |
1232 | if ((err = IS_ERR(port->phydev))) | 1421 | if (IS_ERR(port->phydev)) { |
1422 | err = PTR_ERR(port->phydev); | ||
1233 | goto err_free_mem; | 1423 | goto err_free_mem; |
1424 | } | ||
1234 | 1425 | ||
1235 | port->phydev->irq = PHY_POLL; | 1426 | port->phydev->irq = PHY_POLL; |
1236 | 1427 | ||
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 54c6d849cf25..a7b0caa18179 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value) | |||
854 | } | 854 | } |
855 | 855 | ||
856 | /** | 856 | /** |
857 | * ks8695_get_settings - Get device-specific settings. | 857 | * ks8695_wan_get_settings - Get device-specific settings. |
858 | * @ndev: The network device to read settings from | 858 | * @ndev: The network device to read settings from |
859 | * @cmd: The ethtool structure to read into | 859 | * @cmd: The ethtool structure to read into |
860 | */ | 860 | */ |
861 | static int | 861 | static int |
862 | ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | 862 | ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) |
863 | { | 863 | { |
864 | struct ks8695_priv *ksp = netdev_priv(ndev); | 864 | struct ks8695_priv *ksp = netdev_priv(ndev); |
865 | u32 ctrl; | 865 | u32 ctrl; |
@@ -870,69 +870,51 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | |||
870 | SUPPORTED_TP | SUPPORTED_MII); | 870 | SUPPORTED_TP | SUPPORTED_MII); |
871 | cmd->transceiver = XCVR_INTERNAL; | 871 | cmd->transceiver = XCVR_INTERNAL; |
872 | 872 | ||
873 | /* Port specific extras */ | 873 | cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; |
874 | switch (ksp->dtype) { | 874 | cmd->port = PORT_MII; |
875 | case KS8695_DTYPE_HPNA: | 875 | cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); |
876 | cmd->phy_address = 0; | 876 | cmd->phy_address = 0; |
877 | /* not supported for HPNA */ | ||
878 | cmd->autoneg = AUTONEG_DISABLE; | ||
879 | 877 | ||
880 | /* BUG: Erm, dtype hpna implies no phy regs */ | 878 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
881 | /* | 879 | if ((ctrl & WMC_WAND) == 0) { |
882 | ctrl = readl(KS8695_MISC_VA + KS8695_HMC); | 880 | /* auto-negotiation is enabled */ |
883 | cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10; | 881 | cmd->advertising |= ADVERTISED_Autoneg; |
884 | cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF; | 882 | if (ctrl & WMC_WANA100F) |
885 | */ | 883 | cmd->advertising |= ADVERTISED_100baseT_Full; |
886 | return -EOPNOTSUPP; | 884 | if (ctrl & WMC_WANA100H) |
887 | case KS8695_DTYPE_WAN: | 885 | cmd->advertising |= ADVERTISED_100baseT_Half; |
888 | cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; | 886 | if (ctrl & WMC_WANA10F) |
889 | cmd->port = PORT_MII; | 887 | cmd->advertising |= ADVERTISED_10baseT_Full; |
890 | cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); | 888 | if (ctrl & WMC_WANA10H) |
891 | cmd->phy_address = 0; | 889 | cmd->advertising |= ADVERTISED_10baseT_Half; |
890 | if (ctrl & WMC_WANAP) | ||
891 | cmd->advertising |= ADVERTISED_Pause; | ||
892 | cmd->autoneg = AUTONEG_ENABLE; | ||
893 | |||
894 | ethtool_cmd_speed_set(cmd, | ||
895 | (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10); | ||
896 | cmd->duplex = (ctrl & WMC_WDS) ? | ||
897 | DUPLEX_FULL : DUPLEX_HALF; | ||
898 | } else { | ||
899 | /* auto-negotiation is disabled */ | ||
900 | cmd->autoneg = AUTONEG_DISABLE; | ||
892 | 901 | ||
893 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | 902 | ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ? |
894 | if ((ctrl & WMC_WAND) == 0) { | 903 | SPEED_100 : SPEED_10)); |
895 | /* auto-negotiation is enabled */ | 904 | cmd->duplex = (ctrl & WMC_WANFF) ? |
896 | cmd->advertising |= ADVERTISED_Autoneg; | 905 | DUPLEX_FULL : DUPLEX_HALF; |
897 | if (ctrl & WMC_WANA100F) | ||
898 | cmd->advertising |= ADVERTISED_100baseT_Full; | ||
899 | if (ctrl & WMC_WANA100H) | ||
900 | cmd->advertising |= ADVERTISED_100baseT_Half; | ||
901 | if (ctrl & WMC_WANA10F) | ||
902 | cmd->advertising |= ADVERTISED_10baseT_Full; | ||
903 | if (ctrl & WMC_WANA10H) | ||
904 | cmd->advertising |= ADVERTISED_10baseT_Half; | ||
905 | if (ctrl & WMC_WANAP) | ||
906 | cmd->advertising |= ADVERTISED_Pause; | ||
907 | cmd->autoneg = AUTONEG_ENABLE; | ||
908 | |||
909 | cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10; | ||
910 | cmd->duplex = (ctrl & WMC_WDS) ? | ||
911 | DUPLEX_FULL : DUPLEX_HALF; | ||
912 | } else { | ||
913 | /* auto-negotiation is disabled */ | ||
914 | cmd->autoneg = AUTONEG_DISABLE; | ||
915 | |||
916 | cmd->speed = (ctrl & WMC_WANF100) ? | ||
917 | SPEED_100 : SPEED_10; | ||
918 | cmd->duplex = (ctrl & WMC_WANFF) ? | ||
919 | DUPLEX_FULL : DUPLEX_HALF; | ||
920 | } | ||
921 | break; | ||
922 | case KS8695_DTYPE_LAN: | ||
923 | return -EOPNOTSUPP; | ||
924 | } | 906 | } |
925 | 907 | ||
926 | return 0; | 908 | return 0; |
927 | } | 909 | } |
928 | 910 | ||
929 | /** | 911 | /** |
930 | * ks8695_set_settings - Set device-specific settings. | 912 | * ks8695_wan_set_settings - Set device-specific settings. |
931 | * @ndev: The network device to configure | 913 | * @ndev: The network device to configure |
932 | * @cmd: The settings to configure | 914 | * @cmd: The settings to configure |
933 | */ | 915 | */ |
934 | static int | 916 | static int |
935 | ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | 917 | ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) |
936 | { | 918 | { |
937 | struct ks8695_priv *ksp = netdev_priv(ndev); | 919 | struct ks8695_priv *ksp = netdev_priv(ndev); |
938 | u32 ctrl; | 920 | u32 ctrl; |
@@ -956,171 +938,85 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | |||
956 | ADVERTISED_100baseT_Full)) == 0) | 938 | ADVERTISED_100baseT_Full)) == 0) |
957 | return -EINVAL; | 939 | return -EINVAL; |
958 | 940 | ||
959 | switch (ksp->dtype) { | 941 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
960 | case KS8695_DTYPE_HPNA: | ||
961 | /* HPNA does not support auto-negotiation. */ | ||
962 | return -EINVAL; | ||
963 | case KS8695_DTYPE_WAN: | ||
964 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
965 | |||
966 | ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | | ||
967 | WMC_WANA10F | WMC_WANA10H); | ||
968 | if (cmd->advertising & ADVERTISED_100baseT_Full) | ||
969 | ctrl |= WMC_WANA100F; | ||
970 | if (cmd->advertising & ADVERTISED_100baseT_Half) | ||
971 | ctrl |= WMC_WANA100H; | ||
972 | if (cmd->advertising & ADVERTISED_10baseT_Full) | ||
973 | ctrl |= WMC_WANA10F; | ||
974 | if (cmd->advertising & ADVERTISED_10baseT_Half) | ||
975 | ctrl |= WMC_WANA10H; | ||
976 | |||
977 | /* force a re-negotiation */ | ||
978 | ctrl |= WMC_WANR; | ||
979 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
980 | break; | ||
981 | case KS8695_DTYPE_LAN: | ||
982 | return -EOPNOTSUPP; | ||
983 | } | ||
984 | 942 | ||
943 | ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | | ||
944 | WMC_WANA10F | WMC_WANA10H); | ||
945 | if (cmd->advertising & ADVERTISED_100baseT_Full) | ||
946 | ctrl |= WMC_WANA100F; | ||
947 | if (cmd->advertising & ADVERTISED_100baseT_Half) | ||
948 | ctrl |= WMC_WANA100H; | ||
949 | if (cmd->advertising & ADVERTISED_10baseT_Full) | ||
950 | ctrl |= WMC_WANA10F; | ||
951 | if (cmd->advertising & ADVERTISED_10baseT_Half) | ||
952 | ctrl |= WMC_WANA10H; | ||
953 | |||
954 | /* force a re-negotiation */ | ||
955 | ctrl |= WMC_WANR; | ||
956 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
985 | } else { | 957 | } else { |
986 | switch (ksp->dtype) { | 958 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
987 | case KS8695_DTYPE_HPNA: | 959 | |
988 | /* BUG: dtype_hpna implies no phy registers */ | 960 | /* disable auto-negotiation */ |
989 | /* | 961 | ctrl |= WMC_WAND; |
990 | ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); | 962 | ctrl &= ~(WMC_WANF100 | WMC_WANFF); |
991 | 963 | ||
992 | ctrl &= ~(HMC_HSS | HMC_HDS); | 964 | if (cmd->speed == SPEED_100) |
993 | if (cmd->speed == SPEED_100) | 965 | ctrl |= WMC_WANF100; |
994 | ctrl |= HMC_HSS; | 966 | if (cmd->duplex == DUPLEX_FULL) |
995 | if (cmd->duplex == DUPLEX_FULL) | 967 | ctrl |= WMC_WANFF; |
996 | ctrl |= HMC_HDS; | 968 | |
997 | 969 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | |
998 | __raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC); | ||
999 | */ | ||
1000 | return -EOPNOTSUPP; | ||
1001 | case KS8695_DTYPE_WAN: | ||
1002 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
1003 | |||
1004 | /* disable auto-negotiation */ | ||
1005 | ctrl |= WMC_WAND; | ||
1006 | ctrl &= ~(WMC_WANF100 | WMC_WANFF); | ||
1007 | |||
1008 | if (cmd->speed == SPEED_100) | ||
1009 | ctrl |= WMC_WANF100; | ||
1010 | if (cmd->duplex == DUPLEX_FULL) | ||
1011 | ctrl |= WMC_WANFF; | ||
1012 | |||
1013 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
1014 | break; | ||
1015 | case KS8695_DTYPE_LAN: | ||
1016 | return -EOPNOTSUPP; | ||
1017 | } | ||
1018 | } | 970 | } |
1019 | 971 | ||
1020 | return 0; | 972 | return 0; |
1021 | } | 973 | } |
1022 | 974 | ||
1023 | /** | 975 | /** |
1024 | * ks8695_nwayreset - Restart the autonegotiation on the port. | 976 | * ks8695_wan_nwayreset - Restart the autonegotiation on the port. |
1025 | * @ndev: The network device to restart autoneotiation on | 977 | * @ndev: The network device to restart autoneotiation on |
1026 | */ | 978 | */ |
1027 | static int | 979 | static int |
1028 | ks8695_nwayreset(struct net_device *ndev) | 980 | ks8695_wan_nwayreset(struct net_device *ndev) |
1029 | { | 981 | { |
1030 | struct ks8695_priv *ksp = netdev_priv(ndev); | 982 | struct ks8695_priv *ksp = netdev_priv(ndev); |
1031 | u32 ctrl; | 983 | u32 ctrl; |
1032 | 984 | ||
1033 | switch (ksp->dtype) { | 985 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
1034 | case KS8695_DTYPE_HPNA: | ||
1035 | /* No phy means no autonegotiation on hpna */ | ||
1036 | return -EINVAL; | ||
1037 | case KS8695_DTYPE_WAN: | ||
1038 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
1039 | |||
1040 | if ((ctrl & WMC_WAND) == 0) | ||
1041 | writel(ctrl | WMC_WANR, | ||
1042 | ksp->phyiface_regs + KS8695_WMC); | ||
1043 | else | ||
1044 | /* auto-negotiation not enabled */ | ||
1045 | return -EINVAL; | ||
1046 | break; | ||
1047 | case KS8695_DTYPE_LAN: | ||
1048 | return -EOPNOTSUPP; | ||
1049 | } | ||
1050 | |||
1051 | return 0; | ||
1052 | } | ||
1053 | 986 | ||
1054 | /** | 987 | if ((ctrl & WMC_WAND) == 0) |
1055 | * ks8695_get_link - Retrieve link status of network interface | 988 | writel(ctrl | WMC_WANR, |
1056 | * @ndev: The network interface to retrive the link status of. | 989 | ksp->phyiface_regs + KS8695_WMC); |
1057 | */ | 990 | else |
1058 | static u32 | 991 | /* auto-negotiation not enabled */ |
1059 | ks8695_get_link(struct net_device *ndev) | 992 | return -EINVAL; |
1060 | { | ||
1061 | struct ks8695_priv *ksp = netdev_priv(ndev); | ||
1062 | u32 ctrl; | ||
1063 | 993 | ||
1064 | switch (ksp->dtype) { | ||
1065 | case KS8695_DTYPE_HPNA: | ||
1066 | /* HPNA always has link */ | ||
1067 | return 1; | ||
1068 | case KS8695_DTYPE_WAN: | ||
1069 | /* WAN we can read the PHY for */ | ||
1070 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
1071 | return ctrl & WMC_WLS; | ||
1072 | case KS8695_DTYPE_LAN: | ||
1073 | return -EOPNOTSUPP; | ||
1074 | } | ||
1075 | return 0; | 994 | return 0; |
1076 | } | 995 | } |
1077 | 996 | ||
1078 | /** | 997 | /** |
1079 | * ks8695_get_pause - Retrieve network pause/flow-control advertising | 998 | * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising |
1080 | * @ndev: The device to retrieve settings from | 999 | * @ndev: The device to retrieve settings from |
1081 | * @param: The structure to fill out with the information | 1000 | * @param: The structure to fill out with the information |
1082 | */ | 1001 | */ |
1083 | static void | 1002 | static void |
1084 | ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) | 1003 | ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) |
1085 | { | 1004 | { |
1086 | struct ks8695_priv *ksp = netdev_priv(ndev); | 1005 | struct ks8695_priv *ksp = netdev_priv(ndev); |
1087 | u32 ctrl; | 1006 | u32 ctrl; |
1088 | 1007 | ||
1089 | switch (ksp->dtype) { | 1008 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
1090 | case KS8695_DTYPE_HPNA: | ||
1091 | /* No phy link on hpna to configure */ | ||
1092 | return; | ||
1093 | case KS8695_DTYPE_WAN: | ||
1094 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
1095 | |||
1096 | /* advertise Pause */ | ||
1097 | param->autoneg = (ctrl & WMC_WANAP); | ||
1098 | 1009 | ||
1099 | /* current Rx Flow-control */ | 1010 | /* advertise Pause */ |
1100 | ctrl = ks8695_readreg(ksp, KS8695_DRXC); | 1011 | param->autoneg = (ctrl & WMC_WANAP); |
1101 | param->rx_pause = (ctrl & DRXC_RFCE); | ||
1102 | 1012 | ||
1103 | /* current Tx Flow-control */ | 1013 | /* current Rx Flow-control */ |
1104 | ctrl = ks8695_readreg(ksp, KS8695_DTXC); | 1014 | ctrl = ks8695_readreg(ksp, KS8695_DRXC); |
1105 | param->tx_pause = (ctrl & DTXC_TFCE); | 1015 | param->rx_pause = (ctrl & DRXC_RFCE); |
1106 | break; | ||
1107 | case KS8695_DTYPE_LAN: | ||
1108 | /* The LAN's "phy" is a direct-attached switch */ | ||
1109 | return; | ||
1110 | } | ||
1111 | } | ||
1112 | 1016 | ||
1113 | /** | 1017 | /* current Tx Flow-control */ |
1114 | * ks8695_set_pause - Configure pause/flow-control | 1018 | ctrl = ks8695_readreg(ksp, KS8695_DTXC); |
1115 | * @ndev: The device to configure | 1019 | param->tx_pause = (ctrl & DTXC_TFCE); |
1116 | * @param: The pause parameters to set | ||
1117 | * | ||
1118 | * TODO: Implement this | ||
1119 | */ | ||
1120 | static int | ||
1121 | ks8695_set_pause(struct net_device *ndev, struct ethtool_pauseparam *param) | ||
1122 | { | ||
1123 | return -EOPNOTSUPP; | ||
1124 | } | 1020 | } |
1125 | 1021 | ||
1126 | /** | 1022 | /** |
@@ -1140,12 +1036,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) | |||
1140 | static const struct ethtool_ops ks8695_ethtool_ops = { | 1036 | static const struct ethtool_ops ks8695_ethtool_ops = { |
1141 | .get_msglevel = ks8695_get_msglevel, | 1037 | .get_msglevel = ks8695_get_msglevel, |
1142 | .set_msglevel = ks8695_set_msglevel, | 1038 | .set_msglevel = ks8695_set_msglevel, |
1143 | .get_settings = ks8695_get_settings, | 1039 | .get_drvinfo = ks8695_get_drvinfo, |
1144 | .set_settings = ks8695_set_settings, | 1040 | }; |
1145 | .nway_reset = ks8695_nwayreset, | 1041 | |
1146 | .get_link = ks8695_get_link, | 1042 | static const struct ethtool_ops ks8695_wan_ethtool_ops = { |
1147 | .get_pauseparam = ks8695_get_pause, | 1043 | .get_msglevel = ks8695_get_msglevel, |
1148 | .set_pauseparam = ks8695_set_pause, | 1044 | .set_msglevel = ks8695_set_msglevel, |
1045 | .get_settings = ks8695_wan_get_settings, | ||
1046 | .set_settings = ks8695_wan_set_settings, | ||
1047 | .nway_reset = ks8695_wan_nwayreset, | ||
1048 | .get_link = ethtool_op_get_link, | ||
1049 | .get_pauseparam = ks8695_wan_get_pause, | ||
1149 | .get_drvinfo = ks8695_get_drvinfo, | 1050 | .get_drvinfo = ks8695_get_drvinfo, |
1150 | }; | 1051 | }; |
1151 | 1052 | ||
@@ -1541,7 +1442,6 @@ ks8695_probe(struct platform_device *pdev) | |||
1541 | 1442 | ||
1542 | /* driver system setup */ | 1443 | /* driver system setup */ |
1543 | ndev->netdev_ops = &ks8695_netdev_ops; | 1444 | ndev->netdev_ops = &ks8695_netdev_ops; |
1544 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
1545 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); | 1445 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); |
1546 | 1446 | ||
1547 | netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); | 1447 | netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); |
@@ -1608,12 +1508,15 @@ ks8695_probe(struct platform_device *pdev) | |||
1608 | if (ksp->phyiface_regs && ksp->link_irq == -1) { | 1508 | if (ksp->phyiface_regs && ksp->link_irq == -1) { |
1609 | ks8695_init_switch(ksp); | 1509 | ks8695_init_switch(ksp); |
1610 | ksp->dtype = KS8695_DTYPE_LAN; | 1510 | ksp->dtype = KS8695_DTYPE_LAN; |
1511 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
1611 | } else if (ksp->phyiface_regs && ksp->link_irq != -1) { | 1512 | } else if (ksp->phyiface_regs && ksp->link_irq != -1) { |
1612 | ks8695_init_wan_phy(ksp); | 1513 | ks8695_init_wan_phy(ksp); |
1613 | ksp->dtype = KS8695_DTYPE_WAN; | 1514 | ksp->dtype = KS8695_DTYPE_WAN; |
1515 | SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops); | ||
1614 | } else { | 1516 | } else { |
1615 | /* No initialisation since HPNA does not have a PHY */ | 1517 | /* No initialisation since HPNA does not have a PHY */ |
1616 | ksp->dtype = KS8695_DTYPE_HPNA; | 1518 | ksp->dtype = KS8695_DTYPE_HPNA; |
1519 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
1617 | } | 1520 | } |
1618 | 1521 | ||
1619 | /* And bring up the net_device with the net core */ | 1522 | /* And bring up the net_device with the net core */ |
@@ -1742,7 +1645,7 @@ ks8695_cleanup(void) | |||
1742 | module_init(ks8695_init); | 1645 | module_init(ks8695_init); |
1743 | module_exit(ks8695_cleanup); | 1646 | module_exit(ks8695_cleanup); |
1744 | 1647 | ||
1745 | MODULE_AUTHOR("Simtec Electronics") | 1648 | MODULE_AUTHOR("Simtec Electronics"); |
1746 | MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); | 1649 | MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); |
1747 | MODULE_LICENSE("GPL"); | 1650 | MODULE_LICENSE("GPL"); |
1748 | MODULE_ALIAS("platform:" MODULENAME); | 1651 | MODULE_ALIAS("platform:" MODULENAME); |
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index 4545d5a06c24..bfea499a3513 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c | |||
@@ -117,7 +117,7 @@ | |||
117 | #define TX_DESC_SIZE 10 | 117 | #define TX_DESC_SIZE 10 |
118 | #define MAX_RBUFF_SZ 0x600 | 118 | #define MAX_RBUFF_SZ 0x600 |
119 | #define MAX_TBUFF_SZ 0x600 | 119 | #define MAX_TBUFF_SZ 0x600 |
120 | #define TX_TIMEOUT 50 | 120 | #define TX_TIMEOUT (HZ/2) |
121 | #define DELAY 1000 | 121 | #define DELAY 1000 |
122 | #define CAM0 0x0 | 122 | #define CAM0 0x0 |
123 | 123 | ||