aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pasemi_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pasemi_mac.c')
-rw-r--r--drivers/net/pasemi_mac.c213
1 files changed, 103 insertions, 110 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index b2861e0df86c..c2a3524a5411 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -63,10 +63,10 @@
63 NETIF_MSG_RX_ERR | \ 63 NETIF_MSG_RX_ERR | \
64 NETIF_MSG_TX_ERR) 64 NETIF_MSG_TX_ERR)
65 65
66#define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)]) 66#define TX_RING(mac, num) ((mac)->tx->ring[(num) & (TX_RING_SIZE-1)])
67#define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)]) 67#define TX_RING_INFO(mac, num) ((mac)->tx->ring_info[(num) & (TX_RING_SIZE-1)])
68#define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)]) 68#define RX_RING(mac, num) ((mac)->rx->ring[(num) & (RX_RING_SIZE-1)])
69#define RX_DESC_INFO(mac, num) ((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)]) 69#define RX_RING_INFO(mac, num) ((mac)->rx->ring_info[(num) & (RX_RING_SIZE-1)])
70#define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)]) 70#define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
71 71
72#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ 72#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \
@@ -174,22 +174,21 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
174 spin_lock_init(&ring->lock); 174 spin_lock_init(&ring->lock);
175 175
176 ring->size = RX_RING_SIZE; 176 ring->size = RX_RING_SIZE;
177 ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) * 177 ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
178 RX_RING_SIZE, GFP_KERNEL); 178 RX_RING_SIZE, GFP_KERNEL);
179 179
180 if (!ring->desc_info) 180 if (!ring->ring_info)
181 goto out_desc_info; 181 goto out_ring_info;
182 182
183 /* Allocate descriptors */ 183 /* Allocate descriptors */
184 ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev, 184 ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
185 RX_RING_SIZE * 185 RX_RING_SIZE * sizeof(u64),
186 sizeof(struct pas_dma_xct_descr),
187 &ring->dma, GFP_KERNEL); 186 &ring->dma, GFP_KERNEL);
188 187
189 if (!ring->desc) 188 if (!ring->ring)
190 goto out_desc; 189 goto out_ring_desc;
191 190
192 memset(ring->desc, 0, RX_RING_SIZE * sizeof(struct pas_dma_xct_descr)); 191 memset(ring->ring, 0, RX_RING_SIZE * sizeof(u64));
193 192
194 ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev, 193 ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev,
195 RX_RING_SIZE * sizeof(u64), 194 RX_RING_SIZE * sizeof(u64),
@@ -203,7 +202,7 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
203 202
204 write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id), 203 write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id),
205 PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | 204 PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
206 PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2)); 205 PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
207 206
208 write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), 207 write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
209 PAS_DMA_RXCHAN_CFG_HBU(2)); 208 PAS_DMA_RXCHAN_CFG_HBU(2));
@@ -229,11 +228,11 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
229 228
230out_buffers: 229out_buffers:
231 dma_free_coherent(&mac->dma_pdev->dev, 230 dma_free_coherent(&mac->dma_pdev->dev,
232 RX_RING_SIZE * sizeof(struct pas_dma_xct_descr), 231 RX_RING_SIZE * sizeof(u64),
233 mac->rx->desc, mac->rx->dma); 232 mac->rx->ring, mac->rx->dma);
234out_desc: 233out_ring_desc:
235 kfree(ring->desc_info); 234 kfree(ring->ring_info);
236out_desc_info: 235out_ring_info:
237 kfree(ring); 236 kfree(ring);
238out_ring: 237out_ring:
239 return -ENOMEM; 238 return -ENOMEM;
@@ -254,25 +253,24 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
254 spin_lock_init(&ring->lock); 253 spin_lock_init(&ring->lock);
255 254
256 ring->size = TX_RING_SIZE; 255 ring->size = TX_RING_SIZE;
257 ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) * 256 ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
258 TX_RING_SIZE, GFP_KERNEL); 257 TX_RING_SIZE, GFP_KERNEL);
259 if (!ring->desc_info) 258 if (!ring->ring_info)
260 goto out_desc_info; 259 goto out_ring_info;
261 260
262 /* Allocate descriptors */ 261 /* Allocate descriptors */
263 ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev, 262 ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
264 TX_RING_SIZE * 263 TX_RING_SIZE * sizeof(u64),
265 sizeof(struct pas_dma_xct_descr),
266 &ring->dma, GFP_KERNEL); 264 &ring->dma, GFP_KERNEL);
267 if (!ring->desc) 265 if (!ring->ring)
268 goto out_desc; 266 goto out_ring_desc;
269 267
270 memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr)); 268 memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64));
271 269
272 write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id), 270 write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id),
273 PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); 271 PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
274 val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); 272 val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
275 val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2); 273 val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3);
276 274
277 write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); 275 write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
278 276
@@ -291,9 +289,9 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
291 289
292 return 0; 290 return 0;
293 291
294out_desc: 292out_ring_desc:
295 kfree(ring->desc_info); 293 kfree(ring->ring_info);
296out_desc_info: 294out_ring_info:
297 kfree(ring); 295 kfree(ring);
298out_ring: 296out_ring:
299 return -ENOMEM; 297 return -ENOMEM;
@@ -304,31 +302,27 @@ static void pasemi_mac_free_tx_resources(struct net_device *dev)
304 struct pasemi_mac *mac = netdev_priv(dev); 302 struct pasemi_mac *mac = netdev_priv(dev);
305 unsigned int i; 303 unsigned int i;
306 struct pasemi_mac_buffer *info; 304 struct pasemi_mac_buffer *info;
307 struct pas_dma_xct_descr *dp; 305
308 306 for (i = 0; i < TX_RING_SIZE; i += 2) {
309 for (i = 0; i < TX_RING_SIZE; i++) { 307 info = &TX_RING_INFO(mac, i+1);
310 info = &TX_DESC_INFO(mac, i); 308 if (info->dma && info->skb) {
311 dp = &TX_DESC(mac, i); 309 pci_unmap_single(mac->dma_pdev,
312 if (info->dma) { 310 info->dma,
313 if (info->skb) { 311 info->skb->len,
314 pci_unmap_single(mac->dma_pdev, 312 PCI_DMA_TODEVICE);
315 info->dma, 313 dev_kfree_skb_any(info->skb);
316 info->skb->len,
317 PCI_DMA_TODEVICE);
318 dev_kfree_skb_any(info->skb);
319 }
320 info->dma = 0;
321 info->skb = NULL;
322 dp->mactx = 0;
323 dp->ptr = 0;
324 } 314 }
315 TX_RING(mac, i) = 0;
316 TX_RING(mac, i+1) = 0;
317 info->dma = 0;
318 info->skb = NULL;
325 } 319 }
326 320
327 dma_free_coherent(&mac->dma_pdev->dev, 321 dma_free_coherent(&mac->dma_pdev->dev,
328 TX_RING_SIZE * sizeof(struct pas_dma_xct_descr), 322 TX_RING_SIZE * sizeof(u64),
329 mac->tx->desc, mac->tx->dma); 323 mac->tx->ring, mac->tx->dma);
330 324
331 kfree(mac->tx->desc_info); 325 kfree(mac->tx->ring_info);
332 kfree(mac->tx); 326 kfree(mac->tx);
333 mac->tx = NULL; 327 mac->tx = NULL;
334} 328}
@@ -338,34 +332,31 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
338 struct pasemi_mac *mac = netdev_priv(dev); 332 struct pasemi_mac *mac = netdev_priv(dev);
339 unsigned int i; 333 unsigned int i;
340 struct pasemi_mac_buffer *info; 334 struct pasemi_mac_buffer *info;
341 struct pas_dma_xct_descr *dp;
342 335
343 for (i = 0; i < RX_RING_SIZE; i++) { 336 for (i = 0; i < RX_RING_SIZE; i++) {
344 info = &RX_DESC_INFO(mac, i); 337 info = &RX_RING_INFO(mac, i);
345 dp = &RX_DESC(mac, i); 338 if (info->skb && info->dma) {
346 if (info->skb) { 339 pci_unmap_single(mac->dma_pdev,
347 if (info->dma) { 340 info->dma,
348 pci_unmap_single(mac->dma_pdev, 341 info->skb->len,
349 info->dma, 342 PCI_DMA_FROMDEVICE);
350 info->skb->len, 343 dev_kfree_skb_any(info->skb);
351 PCI_DMA_FROMDEVICE);
352 dev_kfree_skb_any(info->skb);
353 }
354 info->dma = 0;
355 info->skb = NULL;
356 dp->macrx = 0;
357 dp->ptr = 0;
358 } 344 }
345 info->dma = 0;
346 info->skb = NULL;
359 } 347 }
360 348
349 for (i = 0; i < RX_RING_SIZE; i++)
350 RX_RING(mac, i) = 0;
351
361 dma_free_coherent(&mac->dma_pdev->dev, 352 dma_free_coherent(&mac->dma_pdev->dev,
362 RX_RING_SIZE * sizeof(struct pas_dma_xct_descr), 353 RX_RING_SIZE * sizeof(u64),
363 mac->rx->desc, mac->rx->dma); 354 mac->rx->ring, mac->rx->dma);
364 355
365 dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), 356 dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
366 mac->rx->buffers, mac->rx->buf_dma); 357 mac->rx->buffers, mac->rx->buf_dma);
367 358
368 kfree(mac->rx->desc_info); 359 kfree(mac->rx->ring_info);
369 kfree(mac->rx); 360 kfree(mac->rx);
370 mac->rx = NULL; 361 mac->rx = NULL;
371} 362}
@@ -373,20 +364,22 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
373static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) 364static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
374{ 365{
375 struct pasemi_mac *mac = netdev_priv(dev); 366 struct pasemi_mac *mac = netdev_priv(dev);
376 unsigned int i;
377 int start = mac->rx->next_to_fill; 367 int start = mac->rx->next_to_fill;
378 int count; 368 unsigned int fill, count;
379 369
380 if (limit <= 0) 370 if (limit <= 0)
381 return; 371 return;
382 372
383 i = start; 373 fill = start;
384 for (count = 0; count < limit; count++) { 374 for (count = 0; count < limit; count++) {
385 struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i); 375 struct pasemi_mac_buffer *info = &RX_RING_INFO(mac, fill);
386 u64 *buff = &RX_BUFF(mac, i); 376 u64 *buff = &RX_BUFF(mac, fill);
387 struct sk_buff *skb; 377 struct sk_buff *skb;
388 dma_addr_t dma; 378 dma_addr_t dma;
389 379
380 /* Entry in use? */
381 WARN_ON(*buff);
382
390 /* skb might still be in there for recycle on short receives */ 383 /* skb might still be in there for recycle on short receives */
391 if (info->skb) 384 if (info->skb)
392 skb = info->skb; 385 skb = info->skb;
@@ -407,7 +400,7 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
407 info->skb = skb; 400 info->skb = skb;
408 info->dma = dma; 401 info->dma = dma;
409 *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); 402 *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
410 i++; 403 fill++;
411 } 404 }
412 405
413 wmb(); 406 wmb();
@@ -481,7 +474,6 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
481{ 474{
482 unsigned int n; 475 unsigned int n;
483 int count; 476 int count;
484 struct pas_dma_xct_descr *dp;
485 struct pasemi_mac_buffer *info; 477 struct pasemi_mac_buffer *info;
486 struct sk_buff *skb; 478 struct sk_buff *skb;
487 unsigned int i, len; 479 unsigned int i, len;
@@ -496,9 +488,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
496 488
497 rmb(); 489 rmb();
498 490
499 dp = &RX_DESC(mac, n); 491 macrx = RX_RING(mac, n);
500 prefetchw(dp);
501 macrx = dp->macrx;
502 492
503 if ((macrx & XCT_MACRX_E) || 493 if ((macrx & XCT_MACRX_E) ||
504 (*mac->rx_status & PAS_STATUS_ERROR)) 494 (*mac->rx_status & PAS_STATUS_ERROR))
@@ -516,12 +506,15 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
516 * interface ring. 506 * interface ring.
517 */ 507 */
518 508
519 dma = (dp->ptr & XCT_PTR_ADDR_M); 509 dma = (RX_RING(mac, n+1) & XCT_PTR_ADDR_M);
520 for (i = n; i < (n + RX_RING_SIZE); i++) { 510 for (i = mac->rx->next_to_fill;
521 info = &RX_DESC_INFO(mac, i); 511 i < (mac->rx->next_to_fill + RX_RING_SIZE);
512 i++) {
513 info = &RX_RING_INFO(mac, i);
522 if (info->dma == dma) 514 if (info->dma == dma)
523 break; 515 break;
524 } 516 }
517
525 prefetchw(info); 518 prefetchw(info);
526 519
527 skb = info->skb; 520 skb = info->skb;
@@ -546,6 +539,11 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
546 } else 539 } else
547 info->skb = NULL; 540 info->skb = NULL;
548 541
542 /* Need to zero it out since hardware doesn't, since the
543 * replenish loop uses it to tell when it's done.
544 */
545 RX_BUFF(mac, i) = 0;
546
549 skb_put(skb, len); 547 skb_put(skb, len);
550 548
551 if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) { 549 if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
@@ -561,13 +559,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
561 skb->protocol = eth_type_trans(skb, mac->netdev); 559 skb->protocol = eth_type_trans(skb, mac->netdev);
562 netif_receive_skb(skb); 560 netif_receive_skb(skb);
563 561
564 dp->ptr = 0; 562 RX_RING(mac, n) = 0;
565 dp->macrx = 0; 563 RX_RING(mac, n+1) = 0;
566 564
567 n++; 565 n += 2;
568 } 566 }
569 567
570 mac->rx->next_to_clean += limit - count; 568 mac->rx->next_to_clean = n;
571 pasemi_mac_replenish_rx_ring(mac->netdev, limit-count); 569 pasemi_mac_replenish_rx_ring(mac->netdev, limit-count);
572 570
573 spin_unlock(&mac->rx->lock); 571 spin_unlock(&mac->rx->lock);
@@ -579,7 +577,6 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
579{ 577{
580 int i; 578 int i;
581 struct pasemi_mac_buffer *info; 579 struct pasemi_mac_buffer *info;
582 struct pas_dma_xct_descr *dp;
583 unsigned int start, count, limit; 580 unsigned int start, count, limit;
584 unsigned int total_count; 581 unsigned int total_count;
585 unsigned long flags; 582 unsigned long flags;
@@ -595,29 +592,28 @@ restart:
595 592
596 count = 0; 593 count = 0;
597 594
598 for (i = start; i < limit; i++) { 595 for (i = start; i < limit; i += 2) {
599 dp = &TX_DESC(mac, i); 596 u64 mactx = TX_RING(mac, i);
600 597 if ((mactx & XCT_MACTX_E) ||
601 if ((dp->mactx & XCT_MACTX_E) ||
602 (*mac->tx_status & PAS_STATUS_ERROR)) 598 (*mac->tx_status & PAS_STATUS_ERROR))
603 pasemi_mac_tx_error(mac, dp->mactx); 599 pasemi_mac_tx_error(mac, mactx);
604 600
605 if (unlikely(dp->mactx & XCT_MACTX_O)) 601 if (unlikely(mactx & XCT_MACTX_O))
606 /* Not yet transmitted */ 602 /* Not yet transmitted */
607 break; 603 break;
608 604
609 info = &TX_DESC_INFO(mac, i); 605 info = &TX_RING_INFO(mac, i+1);
610 skbs[count] = info->skb; 606 skbs[count] = info->skb;
611 dmas[count] = info->dma; 607 dmas[count] = info->dma;
612 608
613 info->skb = NULL;
614 info->dma = 0; 609 info->dma = 0;
615 dp->mactx = 0; 610 TX_RING(mac, i) = 0;
616 dp->ptr = 0; 611 TX_RING(mac, i+1) = 0;
612
617 613
618 count++; 614 count++;
619 } 615 }
620 mac->tx->next_to_clean += count; 616 mac->tx->next_to_clean += count * 2;
621 spin_unlock_irqrestore(&mac->tx->lock, flags); 617 spin_unlock_irqrestore(&mac->tx->lock, flags);
622 netif_wake_queue(mac->netdev); 618 netif_wake_queue(mac->netdev);
623 619
@@ -1001,8 +997,6 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
1001{ 997{
1002 struct pasemi_mac *mac = netdev_priv(dev); 998 struct pasemi_mac *mac = netdev_priv(dev);
1003 struct pasemi_mac_txring *txring; 999 struct pasemi_mac_txring *txring;
1004 struct pasemi_mac_buffer *info;
1005 struct pas_dma_xct_descr *dp;
1006 u64 dflags, mactx, ptr; 1000 u64 dflags, mactx, ptr;
1007 dma_addr_t map; 1001 dma_addr_t map;
1008 unsigned long flags; 1002 unsigned long flags;
@@ -1038,13 +1032,13 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
1038 1032
1039 spin_lock_irqsave(&txring->lock, flags); 1033 spin_lock_irqsave(&txring->lock, flags);
1040 1034
1041 if (RING_AVAIL(txring) <= 1) { 1035 if (RING_AVAIL(txring) <= 2) {
1042 spin_unlock_irqrestore(&txring->lock, flags); 1036 spin_unlock_irqrestore(&txring->lock, flags);
1043 pasemi_mac_clean_tx(mac); 1037 pasemi_mac_clean_tx(mac);
1044 pasemi_mac_restart_tx_intr(mac); 1038 pasemi_mac_restart_tx_intr(mac);
1045 spin_lock_irqsave(&txring->lock, flags); 1039 spin_lock_irqsave(&txring->lock, flags);
1046 1040
1047 if (RING_AVAIL(txring) <= 1) { 1041 if (RING_AVAIL(txring) <= 2) {
1048 /* Still no room -- stop the queue and wait for tx 1042 /* Still no room -- stop the queue and wait for tx
1049 * intr when there's room. 1043 * intr when there's room.
1050 */ 1044 */
@@ -1053,15 +1047,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
1053 } 1047 }
1054 } 1048 }
1055 1049
1056 dp = &TX_DESC(mac, txring->next_to_fill); 1050 TX_RING(mac, txring->next_to_fill) = mactx;
1057 info = &TX_DESC_INFO(mac, txring->next_to_fill); 1051 TX_RING(mac, txring->next_to_fill+1) = ptr;
1052
1053 TX_RING_INFO(mac, txring->next_to_fill+1).dma = map;
1054 TX_RING_INFO(mac, txring->next_to_fill+1).skb = skb;
1058 1055
1059 dp->mactx = mactx; 1056 txring->next_to_fill += 2;
1060 dp->ptr = ptr;
1061 info->dma = map;
1062 info->skb = skb;
1063 1057
1064 txring->next_to_fill++;
1065 dev->stats.tx_packets++; 1058 dev->stats.tx_packets++;
1066 dev->stats.tx_bytes += skb->len; 1059 dev->stats.tx_bytes += skb->len;
1067 1060