diff options
author | Olof Johansson <olof@lixom.net> | 2007-11-28 21:54:28 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:04:19 -0500 |
commit | 72b05b9940f00fbfd71a1cb8ea80eb2cc1f90255 (patch) | |
tree | b137b06594dd6b662e70bb5673d90f2097e7f9fa /drivers | |
parent | 5f06eba4dce361bfc077868d044768476b41d698 (diff) |
pasemi_mac: RX/TX ring management cleanup
pasemi_mac: RX/TX ring management cleanup
Prepare a bit for supporting multiple TX queues by cleaning up some
of the ring management and shuffle things around a bit.
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/pasemi_mac.c | 277 | ||||
-rw-r--r-- | drivers/net/pasemi_mac.h | 19 |
2 files changed, 157 insertions, 139 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 816a59e801b2..a2527b53da8b 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c | |||
@@ -68,11 +68,11 @@ | |||
68 | NETIF_MSG_RX_ERR | \ | 68 | NETIF_MSG_RX_ERR | \ |
69 | NETIF_MSG_TX_ERR) | 69 | NETIF_MSG_TX_ERR) |
70 | 70 | ||
71 | #define TX_RING(mac, num) ((mac)->tx->ring[(num) & (TX_RING_SIZE-1)]) | 71 | #define TX_DESC(tx, num) ((tx)->ring[(num) & (TX_RING_SIZE-1)]) |
72 | #define TX_RING_INFO(mac, num) ((mac)->tx->ring_info[(num) & (TX_RING_SIZE-1)]) | 72 | #define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) |
73 | #define RX_RING(mac, num) ((mac)->rx->ring[(num) & (RX_RING_SIZE-1)]) | 73 | #define RX_DESC(rx, num) ((rx)->ring[(num) & (RX_RING_SIZE-1)]) |
74 | #define RX_RING_INFO(mac, num) ((mac)->rx->ring_info[(num) & (RX_RING_SIZE-1)]) | 74 | #define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) |
75 | #define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)]) | 75 | #define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) |
76 | 76 | ||
77 | #define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ | 77 | #define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ |
78 | & ((ring)->size - 1)) | 78 | & ((ring)->size - 1)) |
@@ -127,6 +127,16 @@ static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, | |||
127 | out_le32(mac->dma_regs+reg, val); | 127 | out_le32(mac->dma_regs+reg, val); |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct pasemi_mac_rxring *rx_ring(struct pasemi_mac *mac) | ||
131 | { | ||
132 | return mac->rx; | ||
133 | } | ||
134 | |||
135 | static struct pasemi_mac_txring *tx_ring(struct pasemi_mac *mac) | ||
136 | { | ||
137 | return mac->tx; | ||
138 | } | ||
139 | |||
130 | static int pasemi_get_mac_addr(struct pasemi_mac *mac) | 140 | static int pasemi_get_mac_addr(struct pasemi_mac *mac) |
131 | { | 141 | { |
132 | struct pci_dev *pdev = mac->pdev; | 142 | struct pci_dev *pdev = mac->pdev; |
@@ -269,8 +279,8 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev) | |||
269 | ring->next_to_fill = 0; | 279 | ring->next_to_fill = 0; |
270 | ring->next_to_clean = 0; | 280 | ring->next_to_clean = 0; |
271 | 281 | ||
272 | snprintf(ring->irq_name, sizeof(ring->irq_name), | 282 | ring->status = &dma_status->rx_sta[mac->dma_rxch]; |
273 | "%s rx", dev->name); | 283 | ring->mac = mac; |
274 | mac->rx = ring; | 284 | mac->rx = ring; |
275 | 285 | ||
276 | return 0; | 286 | return 0; |
@@ -278,7 +288,7 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev) | |||
278 | out_buffers: | 288 | out_buffers: |
279 | dma_free_coherent(&mac->dma_pdev->dev, | 289 | dma_free_coherent(&mac->dma_pdev->dev, |
280 | RX_RING_SIZE * sizeof(u64), | 290 | RX_RING_SIZE * sizeof(u64), |
281 | mac->rx->ring, mac->rx->dma); | 291 | rx_ring(mac)->ring, rx_ring(mac)->dma); |
282 | out_ring_desc: | 292 | out_ring_desc: |
283 | kfree(ring->ring_info); | 293 | kfree(ring->ring_info); |
284 | out_ring_info: | 294 | out_ring_info: |
@@ -287,12 +297,11 @@ out_ring: | |||
287 | return -ENOMEM; | 297 | return -ENOMEM; |
288 | } | 298 | } |
289 | 299 | ||
290 | 300 | static struct pasemi_mac_txring * | |
291 | static int pasemi_mac_setup_tx_resources(struct net_device *dev) | 301 | pasemi_mac_setup_tx_resources(struct net_device *dev, int txch) |
292 | { | 302 | { |
293 | struct pasemi_mac *mac = netdev_priv(dev); | 303 | struct pasemi_mac *mac = netdev_priv(dev); |
294 | u32 val; | 304 | u32 val; |
295 | int chan_id = mac->dma_txch; | ||
296 | struct pasemi_mac_txring *ring; | 305 | struct pasemi_mac_txring *ring; |
297 | unsigned int cfg; | 306 | unsigned int cfg; |
298 | 307 | ||
@@ -317,12 +326,12 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) | |||
317 | 326 | ||
318 | memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64)); | 327 | memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64)); |
319 | 328 | ||
320 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id), | 329 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(txch), |
321 | PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); | 330 | PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); |
322 | val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); | 331 | val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); |
323 | val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3); | 332 | val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3); |
324 | 333 | ||
325 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); | 334 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(txch), val); |
326 | 335 | ||
327 | cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE | | 336 | cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE | |
328 | PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | | 337 | PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | |
@@ -332,71 +341,70 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) | |||
332 | if (translation_enabled()) | 341 | if (translation_enabled()) |
333 | cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR; | 342 | cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR; |
334 | 343 | ||
335 | write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg); | 344 | write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(txch), cfg); |
336 | 345 | ||
337 | ring->next_to_fill = 0; | 346 | ring->next_to_fill = 0; |
338 | ring->next_to_clean = 0; | 347 | ring->next_to_clean = 0; |
348 | ring->status = &dma_status->tx_sta[txch]; | ||
349 | ring->chan = txch; | ||
350 | ring->mac = mac; | ||
339 | 351 | ||
340 | snprintf(ring->irq_name, sizeof(ring->irq_name), | 352 | return ring; |
341 | "%s tx", dev->name); | ||
342 | mac->tx = ring; | ||
343 | |||
344 | return 0; | ||
345 | 353 | ||
346 | out_ring_desc: | 354 | out_ring_desc: |
347 | kfree(ring->ring_info); | 355 | kfree(ring->ring_info); |
348 | out_ring_info: | 356 | out_ring_info: |
349 | kfree(ring); | 357 | kfree(ring); |
350 | out_ring: | 358 | out_ring: |
351 | return -ENOMEM; | 359 | return NULL; |
352 | } | 360 | } |
353 | 361 | ||
354 | static void pasemi_mac_free_tx_resources(struct net_device *dev) | 362 | static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac) |
355 | { | 363 | { |
356 | struct pasemi_mac *mac = netdev_priv(dev); | 364 | struct pasemi_mac_txring *txring = tx_ring(mac); |
357 | unsigned int i, j; | 365 | unsigned int i, j; |
358 | struct pasemi_mac_buffer *info; | 366 | struct pasemi_mac_buffer *info; |
359 | dma_addr_t dmas[MAX_SKB_FRAGS+1]; | 367 | dma_addr_t dmas[MAX_SKB_FRAGS+1]; |
360 | int freed; | 368 | int freed; |
361 | int start, limit; | 369 | int start, limit; |
362 | 370 | ||
363 | start = mac->tx->next_to_clean; | 371 | start = txring->next_to_clean; |
364 | limit = mac->tx->next_to_fill; | 372 | limit = txring->next_to_fill; |
365 | 373 | ||
366 | /* Compensate for when fill has wrapped and clean has not */ | 374 | /* Compensate for when fill has wrapped and clean has not */ |
367 | if (start > limit) | 375 | if (start > limit) |
368 | limit += TX_RING_SIZE; | 376 | limit += TX_RING_SIZE; |
369 | 377 | ||
370 | for (i = start; i < limit; i += freed) { | 378 | for (i = start; i < limit; i += freed) { |
371 | info = &TX_RING_INFO(mac, i+1); | 379 | info = &txring->ring_info[(i+1) & (TX_RING_SIZE-1)]; |
372 | if (info->dma && info->skb) { | 380 | if (info->dma && info->skb) { |
373 | for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++) | 381 | for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++) |
374 | dmas[j] = TX_RING_INFO(mac, i+1+j).dma; | 382 | dmas[j] = txring->ring_info[(i+1+j) & |
383 | (TX_RING_SIZE-1)].dma; | ||
375 | freed = pasemi_mac_unmap_tx_skb(mac, info->skb, dmas); | 384 | freed = pasemi_mac_unmap_tx_skb(mac, info->skb, dmas); |
376 | } else | 385 | } else |
377 | freed = 2; | 386 | freed = 2; |
378 | } | 387 | } |
379 | 388 | ||
380 | for (i = 0; i < TX_RING_SIZE; i++) | 389 | for (i = 0; i < TX_RING_SIZE; i++) |
381 | TX_RING(mac, i) = 0; | 390 | txring->ring[i] = 0; |
382 | 391 | ||
383 | dma_free_coherent(&mac->dma_pdev->dev, | 392 | dma_free_coherent(&mac->dma_pdev->dev, |
384 | TX_RING_SIZE * sizeof(u64), | 393 | TX_RING_SIZE * sizeof(u64), |
385 | mac->tx->ring, mac->tx->dma); | 394 | txring->ring, txring->dma); |
386 | 395 | ||
387 | kfree(mac->tx->ring_info); | 396 | kfree(txring->ring_info); |
388 | kfree(mac->tx); | 397 | kfree(txring); |
389 | mac->tx = NULL; | ||
390 | } | 398 | } |
391 | 399 | ||
392 | static void pasemi_mac_free_rx_resources(struct net_device *dev) | 400 | static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac) |
393 | { | 401 | { |
394 | struct pasemi_mac *mac = netdev_priv(dev); | 402 | struct pasemi_mac_rxring *rx = rx_ring(mac); |
395 | unsigned int i; | 403 | unsigned int i; |
396 | struct pasemi_mac_buffer *info; | 404 | struct pasemi_mac_buffer *info; |
397 | 405 | ||
398 | for (i = 0; i < RX_RING_SIZE; i++) { | 406 | for (i = 0; i < RX_RING_SIZE; i++) { |
399 | info = &RX_RING_INFO(mac, i); | 407 | info = &RX_DESC_INFO(rx, i); |
400 | if (info->skb && info->dma) { | 408 | if (info->skb && info->dma) { |
401 | pci_unmap_single(mac->dma_pdev, | 409 | pci_unmap_single(mac->dma_pdev, |
402 | info->dma, | 410 | info->dma, |
@@ -409,32 +417,33 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev) | |||
409 | } | 417 | } |
410 | 418 | ||
411 | for (i = 0; i < RX_RING_SIZE; i++) | 419 | for (i = 0; i < RX_RING_SIZE; i++) |
412 | RX_RING(mac, i) = 0; | 420 | RX_DESC(rx, i) = 0; |
413 | 421 | ||
414 | dma_free_coherent(&mac->dma_pdev->dev, | 422 | dma_free_coherent(&mac->dma_pdev->dev, |
415 | RX_RING_SIZE * sizeof(u64), | 423 | RX_RING_SIZE * sizeof(u64), |
416 | mac->rx->ring, mac->rx->dma); | 424 | rx_ring(mac)->ring, rx_ring(mac)->dma); |
417 | 425 | ||
418 | dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), | 426 | dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), |
419 | mac->rx->buffers, mac->rx->buf_dma); | 427 | rx_ring(mac)->buffers, rx_ring(mac)->buf_dma); |
420 | 428 | ||
421 | kfree(mac->rx->ring_info); | 429 | kfree(rx_ring(mac)->ring_info); |
422 | kfree(mac->rx); | 430 | kfree(rx_ring(mac)); |
423 | mac->rx = NULL; | 431 | mac->rx = NULL; |
424 | } | 432 | } |
425 | 433 | ||
426 | static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) | 434 | static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) |
427 | { | 435 | { |
428 | struct pasemi_mac *mac = netdev_priv(dev); | 436 | struct pasemi_mac *mac = netdev_priv(dev); |
437 | struct pasemi_mac_rxring *rx = rx_ring(mac); | ||
429 | int fill, count; | 438 | int fill, count; |
430 | 439 | ||
431 | if (limit <= 0) | 440 | if (limit <= 0) |
432 | return; | 441 | return; |
433 | 442 | ||
434 | fill = mac->rx->next_to_fill; | 443 | fill = rx_ring(mac)->next_to_fill; |
435 | for (count = 0; count < limit; count++) { | 444 | for (count = 0; count < limit; count++) { |
436 | struct pasemi_mac_buffer *info = &RX_RING_INFO(mac, fill); | 445 | struct pasemi_mac_buffer *info = &RX_DESC_INFO(rx, fill); |
437 | u64 *buff = &RX_BUFF(mac, fill); | 446 | u64 *buff = &RX_BUFF(rx, fill); |
438 | struct sk_buff *skb; | 447 | struct sk_buff *skb; |
439 | dma_addr_t dma; | 448 | dma_addr_t dma; |
440 | 449 | ||
@@ -471,7 +480,7 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) | |||
471 | 480 | ||
472 | write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count); | 481 | write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count); |
473 | 482 | ||
474 | mac->rx->next_to_fill = (mac->rx->next_to_fill + count) & | 483 | rx_ring(mac)->next_to_fill = (rx_ring(mac)->next_to_fill + count) & |
475 | (RX_RING_SIZE - 1); | 484 | (RX_RING_SIZE - 1); |
476 | } | 485 | } |
477 | 486 | ||
@@ -482,7 +491,7 @@ static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) | |||
482 | * ack the packet count interrupt we got in rx_intr. | 491 | * ack the packet count interrupt we got in rx_intr. |
483 | */ | 492 | */ |
484 | 493 | ||
485 | pcnt = *mac->rx_status & PAS_STATUS_PCNT_M; | 494 | pcnt = *rx_ring(mac)->status & PAS_STATUS_PCNT_M; |
486 | 495 | ||
487 | reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; | 496 | reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; |
488 | 497 | ||
@@ -494,11 +503,11 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) | |||
494 | unsigned int reg, pcnt; | 503 | unsigned int reg, pcnt; |
495 | 504 | ||
496 | /* Re-enable packet count interrupts */ | 505 | /* Re-enable packet count interrupts */ |
497 | pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; | 506 | pcnt = *tx_ring(mac)->status & PAS_STATUS_PCNT_M; |
498 | 507 | ||
499 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; | 508 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; |
500 | 509 | ||
501 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); | 510 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(tx_ring(mac)->chan), reg); |
502 | } | 511 | } |
503 | 512 | ||
504 | 513 | ||
@@ -513,7 +522,7 @@ static inline void pasemi_mac_rx_error(struct pasemi_mac *mac, u64 macrx) | |||
513 | ccmdsta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); | 522 | ccmdsta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); |
514 | 523 | ||
515 | printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", | 524 | printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", |
516 | macrx, *mac->rx_status); | 525 | macrx, *rx_ring(mac)->status); |
517 | 526 | ||
518 | printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", | 527 | printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", |
519 | rcmdsta, ccmdsta); | 528 | rcmdsta, ccmdsta); |
@@ -529,13 +538,14 @@ static inline void pasemi_mac_tx_error(struct pasemi_mac *mac, u64 mactx) | |||
529 | cmdsta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); | 538 | cmdsta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); |
530 | 539 | ||
531 | printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ | 540 | printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ |
532 | "tx status 0x%016lx\n", mactx, *mac->tx_status); | 541 | "tx status 0x%016lx\n", mactx, *tx_ring(mac)->status); |
533 | 542 | ||
534 | printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); | 543 | printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); |
535 | } | 544 | } |
536 | 545 | ||
537 | static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) | 546 | static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, int limit) |
538 | { | 547 | { |
548 | struct pasemi_mac *mac = rx->mac; | ||
539 | unsigned int n; | 549 | unsigned int n; |
540 | int count; | 550 | int count; |
541 | struct pasemi_mac_buffer *info; | 551 | struct pasemi_mac_buffer *info; |
@@ -546,17 +556,17 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) | |||
546 | int buf_index; | 556 | int buf_index; |
547 | u64 eval; | 557 | u64 eval; |
548 | 558 | ||
549 | spin_lock(&mac->rx->lock); | 559 | spin_lock(&rx->lock); |
550 | 560 | ||
551 | n = mac->rx->next_to_clean; | 561 | n = rx->next_to_clean; |
552 | 562 | ||
553 | prefetch(&RX_RING(mac, n)); | 563 | prefetch(&RX_DESC(rx, n)); |
554 | 564 | ||
555 | for (count = 0; count < limit; count++) { | 565 | for (count = 0; count < limit; count++) { |
556 | macrx = RX_RING(mac, n); | 566 | macrx = RX_DESC(rx, n); |
557 | 567 | ||
558 | if ((macrx & XCT_MACRX_E) || | 568 | if ((macrx & XCT_MACRX_E) || |
559 | (*mac->rx_status & PAS_STATUS_ERROR)) | 569 | (*rx_ring(mac)->status & PAS_STATUS_ERROR)) |
560 | pasemi_mac_rx_error(mac, macrx); | 570 | pasemi_mac_rx_error(mac, macrx); |
561 | 571 | ||
562 | if (!(macrx & XCT_MACRX_O)) | 572 | if (!(macrx & XCT_MACRX_O)) |
@@ -566,12 +576,12 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) | |||
566 | 576 | ||
567 | BUG_ON(!(macrx & XCT_MACRX_RR_8BRES)); | 577 | BUG_ON(!(macrx & XCT_MACRX_RR_8BRES)); |
568 | 578 | ||
569 | eval = (RX_RING(mac, n+1) & XCT_RXRES_8B_EVAL_M) >> | 579 | eval = (RX_DESC(rx, n+1) & XCT_RXRES_8B_EVAL_M) >> |
570 | XCT_RXRES_8B_EVAL_S; | 580 | XCT_RXRES_8B_EVAL_S; |
571 | buf_index = eval-1; | 581 | buf_index = eval-1; |
572 | 582 | ||
573 | dma = (RX_RING(mac, n+2) & XCT_PTR_ADDR_M); | 583 | dma = (RX_DESC(rx, n+2) & XCT_PTR_ADDR_M); |
574 | info = &RX_RING_INFO(mac, buf_index); | 584 | info = &RX_DESC_INFO(rx, buf_index); |
575 | 585 | ||
576 | skb = info->skb; | 586 | skb = info->skb; |
577 | 587 | ||
@@ -624,13 +634,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) | |||
624 | netif_receive_skb(skb); | 634 | netif_receive_skb(skb); |
625 | 635 | ||
626 | next: | 636 | next: |
627 | RX_RING(mac, n) = 0; | 637 | RX_DESC(rx, n) = 0; |
628 | RX_RING(mac, n+1) = 0; | 638 | RX_DESC(rx, n+1) = 0; |
629 | 639 | ||
630 | /* Need to zero it out since hardware doesn't, since the | 640 | /* Need to zero it out since hardware doesn't, since the |
631 | * replenish loop uses it to tell when it's done. | 641 | * replenish loop uses it to tell when it's done. |
632 | */ | 642 | */ |
633 | RX_BUFF(mac, buf_index) = 0; | 643 | RX_BUFF(rx, buf_index) = 0; |
634 | 644 | ||
635 | n += 4; | 645 | n += 4; |
636 | } | 646 | } |
@@ -641,7 +651,7 @@ next: | |||
641 | n &= (RX_RING_SIZE-1); | 651 | n &= (RX_RING_SIZE-1); |
642 | } | 652 | } |
643 | 653 | ||
644 | mac->rx->next_to_clean = n; | 654 | rx_ring(mac)->next_to_clean = n; |
645 | 655 | ||
646 | /* Increase is in number of 16-byte entries, and since each descriptor | 656 | /* Increase is in number of 16-byte entries, and since each descriptor |
647 | * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with | 657 | * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with |
@@ -651,7 +661,7 @@ next: | |||
651 | 661 | ||
652 | pasemi_mac_replenish_rx_ring(mac->netdev, count); | 662 | pasemi_mac_replenish_rx_ring(mac->netdev, count); |
653 | 663 | ||
654 | spin_unlock(&mac->rx->lock); | 664 | spin_unlock(&rx_ring(mac)->lock); |
655 | 665 | ||
656 | return count; | 666 | return count; |
657 | } | 667 | } |
@@ -659,8 +669,9 @@ next: | |||
659 | /* Can't make this too large or we blow the kernel stack limits */ | 669 | /* Can't make this too large or we blow the kernel stack limits */ |
660 | #define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS) | 670 | #define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS) |
661 | 671 | ||
662 | static int pasemi_mac_clean_tx(struct pasemi_mac *mac) | 672 | static int pasemi_mac_clean_tx(struct pasemi_mac_txring *txring) |
663 | { | 673 | { |
674 | struct pasemi_mac *mac = txring->mac; | ||
664 | int i, j; | 675 | int i, j; |
665 | unsigned int start, descr_count, buf_count, batch_limit; | 676 | unsigned int start, descr_count, buf_count, batch_limit; |
666 | unsigned int ring_limit; | 677 | unsigned int ring_limit; |
@@ -672,10 +683,10 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac) | |||
672 | total_count = 0; | 683 | total_count = 0; |
673 | batch_limit = TX_CLEAN_BATCHSIZE; | 684 | batch_limit = TX_CLEAN_BATCHSIZE; |
674 | restart: | 685 | restart: |
675 | spin_lock_irqsave(&mac->tx->lock, flags); | 686 | spin_lock_irqsave(&txring->lock, flags); |
676 | 687 | ||
677 | start = mac->tx->next_to_clean; | 688 | start = txring->next_to_clean; |
678 | ring_limit = mac->tx->next_to_fill; | 689 | ring_limit = txring->next_to_fill; |
679 | 690 | ||
680 | /* Compensate for when fill has wrapped but clean has not */ | 691 | /* Compensate for when fill has wrapped but clean has not */ |
681 | if (start > ring_limit) | 692 | if (start > ring_limit) |
@@ -687,26 +698,26 @@ restart: | |||
687 | for (i = start; | 698 | for (i = start; |
688 | descr_count < batch_limit && i < ring_limit; | 699 | descr_count < batch_limit && i < ring_limit; |
689 | i += buf_count) { | 700 | i += buf_count) { |
690 | u64 mactx = TX_RING(mac, i); | 701 | u64 mactx = TX_DESC(txring, i); |
691 | struct sk_buff *skb; | 702 | struct sk_buff *skb; |
692 | 703 | ||
693 | if ((mactx & XCT_MACTX_E) || | 704 | if ((mactx & XCT_MACTX_E) || |
694 | (*mac->tx_status & PAS_STATUS_ERROR)) | 705 | (*tx_ring(mac)->status & PAS_STATUS_ERROR)) |
695 | pasemi_mac_tx_error(mac, mactx); | 706 | pasemi_mac_tx_error(mac, mactx); |
696 | 707 | ||
697 | if (unlikely(mactx & XCT_MACTX_O)) | 708 | if (unlikely(mactx & XCT_MACTX_O)) |
698 | /* Not yet transmitted */ | 709 | /* Not yet transmitted */ |
699 | break; | 710 | break; |
700 | 711 | ||
701 | skb = TX_RING_INFO(mac, i+1).skb; | 712 | skb = TX_DESC_INFO(txring, i+1).skb; |
702 | skbs[descr_count] = skb; | 713 | skbs[descr_count] = skb; |
703 | 714 | ||
704 | buf_count = 2 + skb_shinfo(skb)->nr_frags; | 715 | buf_count = 2 + skb_shinfo(skb)->nr_frags; |
705 | for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++) | 716 | for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++) |
706 | dmas[descr_count][j] = TX_RING_INFO(mac, i+1+j).dma; | 717 | dmas[descr_count][j] = TX_DESC_INFO(txring, i+1+j).dma; |
707 | 718 | ||
708 | TX_RING(mac, i) = 0; | 719 | TX_DESC(txring, i) = 0; |
709 | TX_RING(mac, i+1) = 0; | 720 | TX_DESC(txring, i+1) = 0; |
710 | 721 | ||
711 | /* Since we always fill with an even number of entries, make | 722 | /* Since we always fill with an even number of entries, make |
712 | * sure we skip any unused one at the end as well. | 723 | * sure we skip any unused one at the end as well. |
@@ -715,9 +726,9 @@ restart: | |||
715 | buf_count++; | 726 | buf_count++; |
716 | descr_count++; | 727 | descr_count++; |
717 | } | 728 | } |
718 | mac->tx->next_to_clean = i & (TX_RING_SIZE-1); | 729 | txring->next_to_clean = i & (TX_RING_SIZE-1); |
719 | 730 | ||
720 | spin_unlock_irqrestore(&mac->tx->lock, flags); | 731 | spin_unlock_irqrestore(&txring->lock, flags); |
721 | netif_wake_queue(mac->netdev); | 732 | netif_wake_queue(mac->netdev); |
722 | 733 | ||
723 | for (i = 0; i < descr_count; i++) | 734 | for (i = 0; i < descr_count; i++) |
@@ -739,7 +750,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) | |||
739 | struct pasemi_mac *mac = netdev_priv(dev); | 750 | struct pasemi_mac *mac = netdev_priv(dev); |
740 | unsigned int reg; | 751 | unsigned int reg; |
741 | 752 | ||
742 | if (!(*mac->rx_status & PAS_STATUS_CAUSE_M)) | 753 | if (!(*rx_ring(mac)->status & PAS_STATUS_CAUSE_M)) |
743 | return IRQ_NONE; | 754 | return IRQ_NONE; |
744 | 755 | ||
745 | /* Don't reset packet count so it won't fire again but clear | 756 | /* Don't reset packet count so it won't fire again but clear |
@@ -747,11 +758,11 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) | |||
747 | */ | 758 | */ |
748 | 759 | ||
749 | reg = 0; | 760 | reg = 0; |
750 | if (*mac->rx_status & PAS_STATUS_SOFT) | 761 | if (*rx_ring(mac)->status & PAS_STATUS_SOFT) |
751 | reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; | 762 | reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; |
752 | if (*mac->rx_status & PAS_STATUS_ERROR) | 763 | if (*rx_ring(mac)->status & PAS_STATUS_ERROR) |
753 | reg |= PAS_IOB_DMA_RXCH_RESET_DINTC; | 764 | reg |= PAS_IOB_DMA_RXCH_RESET_DINTC; |
754 | if (*mac->rx_status & PAS_STATUS_TIMER) | 765 | if (*rx_ring(mac)->status & PAS_STATUS_TIMER) |
755 | reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; | 766 | reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; |
756 | 767 | ||
757 | netif_rx_schedule(dev, &mac->napi); | 768 | netif_rx_schedule(dev, &mac->napi); |
@@ -763,25 +774,25 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) | |||
763 | 774 | ||
764 | static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) | 775 | static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) |
765 | { | 776 | { |
766 | struct net_device *dev = data; | 777 | struct pasemi_mac_txring *txring = data; |
767 | struct pasemi_mac *mac = netdev_priv(dev); | 778 | struct pasemi_mac *mac = txring->mac; |
768 | unsigned int reg, pcnt; | 779 | unsigned int reg, pcnt; |
769 | 780 | ||
770 | if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) | 781 | if (!(*txring->status & PAS_STATUS_CAUSE_M)) |
771 | return IRQ_NONE; | 782 | return IRQ_NONE; |
772 | 783 | ||
773 | pasemi_mac_clean_tx(mac); | 784 | pasemi_mac_clean_tx(txring); |
774 | 785 | ||
775 | pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; | 786 | pcnt = *txring->status & PAS_STATUS_PCNT_M; |
776 | 787 | ||
777 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; | 788 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; |
778 | 789 | ||
779 | if (*mac->tx_status & PAS_STATUS_SOFT) | 790 | if (*txring->status & PAS_STATUS_SOFT) |
780 | reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; | 791 | reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; |
781 | if (*mac->tx_status & PAS_STATUS_ERROR) | 792 | if (*txring->status & PAS_STATUS_ERROR) |
782 | reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; | 793 | reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; |
783 | 794 | ||
784 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); | 795 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(txring->chan), reg); |
785 | 796 | ||
786 | return IRQ_HANDLED; | 797 | return IRQ_HANDLED; |
787 | } | 798 | } |
@@ -919,10 +930,6 @@ static int pasemi_mac_open(struct net_device *dev) | |||
919 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), | 930 | write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), |
920 | PAS_IOB_DMA_TXCH_CFG_CNTTH(128)); | 931 | PAS_IOB_DMA_TXCH_CFG_CNTTH(128)); |
921 | 932 | ||
922 | /* Clear out any residual packet count state from firmware */ | ||
923 | pasemi_mac_restart_rx_intr(mac); | ||
924 | pasemi_mac_restart_tx_intr(mac); | ||
925 | |||
926 | /* 0xffffff is max value, about 16ms */ | 933 | /* 0xffffff is max value, about 16ms */ |
927 | write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG, | 934 | write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG, |
928 | PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); | 935 | PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); |
@@ -931,9 +938,10 @@ static int pasemi_mac_open(struct net_device *dev) | |||
931 | if (ret) | 938 | if (ret) |
932 | goto out_rx_resources; | 939 | goto out_rx_resources; |
933 | 940 | ||
934 | ret = pasemi_mac_setup_tx_resources(dev); | 941 | mac->tx = pasemi_mac_setup_tx_resources(dev, mac->dma_txch); |
935 | if (ret) | 942 | |
936 | goto out_tx_resources; | 943 | if (!mac->tx) |
944 | goto out_tx_ring; | ||
937 | 945 | ||
938 | write_mac_reg(mac, PAS_MAC_IPC_CHNL, | 946 | write_mac_reg(mac, PAS_MAC_IPC_CHNL, |
939 | PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | | 947 | PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | |
@@ -967,6 +975,10 @@ static int pasemi_mac_open(struct net_device *dev) | |||
967 | 975 | ||
968 | write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), RX_RING_SIZE>>1); | 976 | write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), RX_RING_SIZE>>1); |
969 | 977 | ||
978 | /* Clear out any residual packet count state from firmware */ | ||
979 | pasemi_mac_restart_rx_intr(mac); | ||
980 | pasemi_mac_restart_tx_intr(mac); | ||
981 | |||
970 | flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE | | 982 | flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE | |
971 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; | 983 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; |
972 | 984 | ||
@@ -997,18 +1009,25 @@ static int pasemi_mac_open(struct net_device *dev) | |||
997 | base_irq = virq_to_hw(mac->dma_pdev->irq); | 1009 | base_irq = virq_to_hw(mac->dma_pdev->irq); |
998 | 1010 | ||
999 | mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch); | 1011 | mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch); |
1000 | mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch); | 1012 | |
1013 | snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx", | ||
1014 | dev->name); | ||
1001 | 1015 | ||
1002 | ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED, | 1016 | ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED, |
1003 | mac->tx->irq_name, dev); | 1017 | mac->tx_irq_name, mac->tx); |
1004 | if (ret) { | 1018 | if (ret) { |
1005 | dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", | 1019 | dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", |
1006 | base_irq + mac->dma_txch, ret); | 1020 | base_irq + mac->dma_txch, ret); |
1007 | goto out_tx_int; | 1021 | goto out_tx_int; |
1008 | } | 1022 | } |
1009 | 1023 | ||
1024 | mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_rxch); | ||
1025 | |||
1026 | snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx", | ||
1027 | dev->name); | ||
1028 | |||
1010 | ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED, | 1029 | ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED, |
1011 | mac->rx->irq_name, dev); | 1030 | mac->rx_irq_name, dev); |
1012 | if (ret) { | 1031 | if (ret) { |
1013 | dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", | 1032 | dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", |
1014 | base_irq + 20 + mac->dma_rxch, ret); | 1033 | base_irq + 20 + mac->dma_rxch, ret); |
@@ -1021,13 +1040,14 @@ static int pasemi_mac_open(struct net_device *dev) | |||
1021 | return 0; | 1040 | return 0; |
1022 | 1041 | ||
1023 | out_rx_int: | 1042 | out_rx_int: |
1024 | free_irq(mac->tx_irq, dev); | 1043 | free_irq(mac->tx_irq, mac->tx); |
1025 | out_tx_int: | 1044 | out_tx_int: |
1026 | napi_disable(&mac->napi); | 1045 | napi_disable(&mac->napi); |
1027 | netif_stop_queue(dev); | 1046 | netif_stop_queue(dev); |
1028 | pasemi_mac_free_tx_resources(dev); | 1047 | out_tx_ring: |
1029 | out_tx_resources: | 1048 | if (mac->tx) |
1030 | pasemi_mac_free_rx_resources(dev); | 1049 | pasemi_mac_free_tx_resources(mac); |
1050 | pasemi_mac_free_rx_resources(mac); | ||
1031 | out_rx_resources: | 1051 | out_rx_resources: |
1032 | 1052 | ||
1033 | return ret; | 1053 | return ret; |
@@ -1063,20 +1083,21 @@ static int pasemi_mac_close(struct net_device *dev) | |||
1063 | printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta); | 1083 | printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta); |
1064 | 1084 | ||
1065 | sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); | 1085 | sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); |
1066 | if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | | 1086 | if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | PAS_DMA_TXCHAN_TCMDSTA_DB | |
1067 | PAS_DMA_TXCHAN_TCMDSTA_DB | | 1087 | PAS_DMA_TXCHAN_TCMDSTA_DE | PAS_DMA_TXCHAN_TCMDSTA_DA)) |
1068 | PAS_DMA_TXCHAN_TCMDSTA_DE | | ||
1069 | PAS_DMA_TXCHAN_TCMDSTA_DA)) | ||
1070 | printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta); | 1088 | printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta); |
1071 | 1089 | ||
1072 | /* Clean out any pending buffers */ | 1090 | /* Clean out any pending buffers */ |
1073 | pasemi_mac_clean_tx(mac); | 1091 | pasemi_mac_clean_tx(tx_ring(mac)); |
1074 | pasemi_mac_clean_rx(mac, RX_RING_SIZE); | 1092 | pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE); |
1075 | 1093 | ||
1076 | /* Disable interface */ | 1094 | /* Disable interface */ |
1077 | write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST); | 1095 | write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), |
1078 | write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST); | 1096 | PAS_DMA_TXCHAN_TCMDSTA_ST); |
1079 | write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST); | 1097 | write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), |
1098 | PAS_DMA_RXINT_RCMDSTA_ST); | ||
1099 | write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), | ||
1100 | PAS_DMA_RXCHAN_CCMDSTA_ST); | ||
1080 | 1101 | ||
1081 | for (retries = 0; retries < MAX_RETRIES; retries++) { | 1102 | for (retries = 0; retries < MAX_RETRIES; retries++) { |
1082 | sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); | 1103 | sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); |
@@ -1086,7 +1107,8 @@ static int pasemi_mac_close(struct net_device *dev) | |||
1086 | } | 1107 | } |
1087 | 1108 | ||
1088 | if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT) | 1109 | if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT) |
1089 | dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); | 1110 | dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel %d\n", |
1111 | mac->dma_txch); | ||
1090 | 1112 | ||
1091 | for (retries = 0; retries < MAX_RETRIES; retries++) { | 1113 | for (retries = 0; retries < MAX_RETRIES; retries++) { |
1092 | sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); | 1114 | sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); |
@@ -1116,12 +1138,12 @@ static int pasemi_mac_close(struct net_device *dev) | |||
1116 | write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); | 1138 | write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); |
1117 | write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); | 1139 | write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); |
1118 | 1140 | ||
1119 | free_irq(mac->tx_irq, dev); | 1141 | free_irq(mac->tx_irq, mac->tx); |
1120 | free_irq(mac->rx_irq, dev); | 1142 | free_irq(mac->rx_irq, mac->rx); |
1121 | 1143 | ||
1122 | /* Free resources */ | 1144 | /* Free resources */ |
1123 | pasemi_mac_free_rx_resources(dev); | 1145 | pasemi_mac_free_rx_resources(mac); |
1124 | pasemi_mac_free_tx_resources(dev); | 1146 | pasemi_mac_free_tx_resources(mac); |
1125 | 1147 | ||
1126 | return 0; | 1148 | return 0; |
1127 | } | 1149 | } |
@@ -1178,7 +1200,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
1178 | 1200 | ||
1179 | mactx = dflags | XCT_MACTX_LLEN(skb->len); | 1201 | mactx = dflags | XCT_MACTX_LLEN(skb->len); |
1180 | 1202 | ||
1181 | txring = mac->tx; | 1203 | txring = tx_ring(mac); |
1182 | 1204 | ||
1183 | spin_lock_irqsave(&txring->lock, flags); | 1205 | spin_lock_irqsave(&txring->lock, flags); |
1184 | 1206 | ||
@@ -1192,13 +1214,13 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
1192 | goto out_err; | 1214 | goto out_err; |
1193 | } | 1215 | } |
1194 | 1216 | ||
1195 | TX_RING(mac, txring->next_to_fill) = mactx; | 1217 | TX_DESC(txring, txring->next_to_fill) = mactx; |
1196 | txring->next_to_fill++; | 1218 | txring->next_to_fill++; |
1197 | TX_RING_INFO(mac, txring->next_to_fill).skb = skb; | 1219 | TX_DESC_INFO(txring, txring->next_to_fill).skb = skb; |
1198 | for (i = 0; i <= nfrags; i++) { | 1220 | for (i = 0; i <= nfrags; i++) { |
1199 | TX_RING(mac, txring->next_to_fill+i) = | 1221 | TX_DESC(txring, txring->next_to_fill+i) = |
1200 | XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]); | 1222 | XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]); |
1201 | TX_RING_INFO(mac, txring->next_to_fill+i).dma = map[i]; | 1223 | TX_DESC_INFO(txring, txring->next_to_fill+i).dma = map[i]; |
1202 | } | 1224 | } |
1203 | 1225 | ||
1204 | /* We have to add an even number of 8-byte entries to the ring | 1226 | /* We have to add an even number of 8-byte entries to the ring |
@@ -1216,7 +1238,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
1216 | 1238 | ||
1217 | spin_unlock_irqrestore(&txring->lock, flags); | 1239 | spin_unlock_irqrestore(&txring->lock, flags); |
1218 | 1240 | ||
1219 | write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), (nfrags+2) >> 1); | 1241 | write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(txring->chan), (nfrags+2) >> 1); |
1220 | 1242 | ||
1221 | return NETDEV_TX_OK; | 1243 | return NETDEV_TX_OK; |
1222 | 1244 | ||
@@ -1253,8 +1275,8 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget) | |||
1253 | struct net_device *dev = mac->netdev; | 1275 | struct net_device *dev = mac->netdev; |
1254 | int pkts; | 1276 | int pkts; |
1255 | 1277 | ||
1256 | pasemi_mac_clean_tx(mac); | 1278 | pasemi_mac_clean_tx(tx_ring(mac)); |
1257 | pkts = pasemi_mac_clean_rx(mac, budget); | 1279 | pkts = pasemi_mac_clean_rx(rx_ring(mac), budget); |
1258 | if (pkts < budget) { | 1280 | if (pkts < budget) { |
1259 | /* all done, no more packets present */ | 1281 | /* all done, no more packets present */ |
1260 | netif_rx_complete(dev, napi); | 1282 | netif_rx_complete(dev, napi); |
@@ -1405,9 +1427,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1405 | if (err) | 1427 | if (err) |
1406 | goto out; | 1428 | goto out; |
1407 | 1429 | ||
1408 | mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; | ||
1409 | mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; | ||
1410 | |||
1411 | mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); | 1430 | mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); |
1412 | 1431 | ||
1413 | /* Enable most messages by default */ | 1432 | /* Enable most messages by default */ |
@@ -1420,11 +1439,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1420 | err); | 1439 | err); |
1421 | goto out; | 1440 | goto out; |
1422 | } else if netif_msg_probe(mac) | 1441 | } else if netif_msg_probe(mac) |
1423 | printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, " | 1442 | printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %s\n", |
1424 | "hw addr %s\n", | ||
1425 | dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", | 1443 | dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", |
1426 | mac->dma_if, mac->dma_txch, mac->dma_rxch, | 1444 | mac->dma_if, print_mac(mac_buf, dev->dev_addr)); |
1427 | print_mac(mac_buf, dev->dev_addr)); | ||
1428 | 1445 | ||
1429 | return err; | 1446 | return err; |
1430 | 1447 | ||
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 60368df72634..1269015fa5da 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h | |||
@@ -28,17 +28,20 @@ | |||
28 | 28 | ||
29 | struct pasemi_mac_txring { | 29 | struct pasemi_mac_txring { |
30 | spinlock_t lock; | 30 | spinlock_t lock; |
31 | u64 *status; /* Ptr to cacheable status area */ | ||
31 | u64 *ring; | 32 | u64 *ring; |
32 | dma_addr_t dma; | 33 | dma_addr_t dma; |
33 | unsigned int size; | 34 | unsigned int size; |
34 | unsigned int next_to_fill; | 35 | unsigned int next_to_fill; |
35 | unsigned int next_to_clean; | 36 | unsigned int next_to_clean; |
36 | struct pasemi_mac_buffer *ring_info; | 37 | struct pasemi_mac_buffer *ring_info; |
37 | char irq_name[10]; /* "eth%d tx" */ | 38 | int chan; |
39 | struct pasemi_mac *mac; /* Needed in intr handler */ | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | struct pasemi_mac_rxring { | 42 | struct pasemi_mac_rxring { |
41 | spinlock_t lock; | 43 | spinlock_t lock; |
44 | u64 *status; /* Ptr to cacheable status area */ | ||
42 | u64 *ring; /* RX channel descriptor ring */ | 45 | u64 *ring; /* RX channel descriptor ring */ |
43 | dma_addr_t dma; | 46 | dma_addr_t dma; |
44 | u64 *buffers; /* RX interface buffer ring */ | 47 | u64 *buffers; /* RX interface buffer ring */ |
@@ -47,7 +50,7 @@ struct pasemi_mac_rxring { | |||
47 | unsigned int next_to_fill; | 50 | unsigned int next_to_fill; |
48 | unsigned int next_to_clean; | 51 | unsigned int next_to_clean; |
49 | struct pasemi_mac_buffer *ring_info; | 52 | struct pasemi_mac_buffer *ring_info; |
50 | char irq_name[10]; /* "eth%d rx" */ | 53 | struct pasemi_mac *mac; /* Needed in intr handler */ |
51 | }; | 54 | }; |
52 | 55 | ||
53 | struct pasemi_mac { | 56 | struct pasemi_mac { |
@@ -61,16 +64,12 @@ struct pasemi_mac { | |||
61 | struct phy_device *phydev; | 64 | struct phy_device *phydev; |
62 | struct napi_struct napi; | 65 | struct napi_struct napi; |
63 | 66 | ||
64 | /* Pointer to the cacheable per-channel status registers */ | ||
65 | u64 *rx_status; | ||
66 | u64 *tx_status; | ||
67 | |||
68 | u8 type; | 67 | u8 type; |
69 | #define MAC_TYPE_GMAC 1 | 68 | #define MAC_TYPE_GMAC 1 |
70 | #define MAC_TYPE_XAUI 2 | 69 | #define MAC_TYPE_XAUI 2 |
71 | u32 dma_txch; | 70 | u32 dma_txch; |
72 | u32 dma_if; | ||
73 | u32 dma_rxch; | 71 | u32 dma_rxch; |
72 | u32 dma_if; | ||
74 | 73 | ||
75 | u8 mac_addr[6]; | 74 | u8 mac_addr[6]; |
76 | 75 | ||
@@ -78,8 +77,10 @@ struct pasemi_mac { | |||
78 | 77 | ||
79 | struct pasemi_mac_txring *tx; | 78 | struct pasemi_mac_txring *tx; |
80 | struct pasemi_mac_rxring *rx; | 79 | struct pasemi_mac_rxring *rx; |
81 | unsigned long tx_irq; | 80 | unsigned int tx_irq; |
82 | unsigned long rx_irq; | 81 | unsigned int rx_irq; |
82 | char tx_irq_name[10]; /* "eth%d tx" */ | ||
83 | char rx_irq_name[10]; /* "eth%d rx" */ | ||
83 | int link; | 84 | int link; |
84 | int speed; | 85 | int speed; |
85 | int duplex; | 86 | int duplex; |