aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/pasemi_mac.c294
-rw-r--r--drivers/net/pasemi_mac.h15
-rw-r--r--include/asm-powerpc/pasemi_dma.h60
3 files changed, 333 insertions, 36 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 6ea822addde5..54904ad29ea7 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -59,11 +59,12 @@
59/* Must be a power of two */ 59/* Must be a power of two */
60#define RX_RING_SIZE 2048 60#define RX_RING_SIZE 2048
61#define TX_RING_SIZE 4096 61#define TX_RING_SIZE 4096
62#define CS_RING_SIZE (TX_RING_SIZE*2)
62 63
63#define LRO_MAX_AGGR 64 64#define LRO_MAX_AGGR 64
64 65
65#define PE_MIN_MTU 64 66#define PE_MIN_MTU 64
66#define PE_MAX_MTU 1500 67#define PE_MAX_MTU 9000
67#define PE_DEF_MTU ETH_DATA_LEN 68#define PE_DEF_MTU ETH_DATA_LEN
68 69
69#define DEFAULT_MSG_ENABLE \ 70#define DEFAULT_MSG_ENABLE \
@@ -81,6 +82,7 @@
81#define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) 82#define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
82#define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) 83#define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
83#define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) 84#define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)])
85#define CS_DESC(cs, num) ((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
84 86
85#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ 87#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \
86 & ((ring)->size - 1)) 88 & ((ring)->size - 1))
@@ -322,6 +324,103 @@ static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac,
322 return (nfrags + 3) & ~1; 324 return (nfrags + 3) & ~1;
323} 325}
324 326
327static struct pasemi_mac_csring *pasemi_mac_setup_csring(struct pasemi_mac *mac)
328{
329 struct pasemi_mac_csring *ring;
330 u32 val;
331 unsigned int cfg;
332 int chno;
333
334 ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_csring),
335 offsetof(struct pasemi_mac_csring, chan));
336
337 if (!ring) {
338 dev_err(&mac->pdev->dev, "Can't allocate checksum channel\n");
339 goto out_chan;
340 }
341
342 chno = ring->chan.chno;
343
344 ring->size = CS_RING_SIZE;
345 ring->next_to_fill = 0;
346
347 /* Allocate descriptors */
348 if (pasemi_dma_alloc_ring(&ring->chan, CS_RING_SIZE))
349 goto out_ring_desc;
350
351 write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
352 PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
353 val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
354 val |= PAS_DMA_TXCHAN_BASEU_SIZ(CS_RING_SIZE >> 3);
355
356 write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
357
358 ring->events[0] = pasemi_dma_alloc_flag();
359 ring->events[1] = pasemi_dma_alloc_flag();
360 if (ring->events[0] < 0 || ring->events[1] < 0)
361 goto out_flags;
362
363 pasemi_dma_clear_flag(ring->events[0]);
364 pasemi_dma_clear_flag(ring->events[1]);
365
366 ring->fun = pasemi_dma_alloc_fun();
367 if (ring->fun < 0)
368 goto out_fun;
369
370 cfg = PAS_DMA_TXCHAN_CFG_TY_FUNC | PAS_DMA_TXCHAN_CFG_UP |
371 PAS_DMA_TXCHAN_CFG_TATTR(ring->fun) |
372 PAS_DMA_TXCHAN_CFG_LPSQ | PAS_DMA_TXCHAN_CFG_LPDQ;
373
374 if (translation_enabled())
375 cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
376
377 write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
378
379 /* enable channel */
380 pasemi_dma_start_chan(&ring->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
381 PAS_DMA_TXCHAN_TCMDSTA_DB |
382 PAS_DMA_TXCHAN_TCMDSTA_DE |
383 PAS_DMA_TXCHAN_TCMDSTA_DA);
384
385 return ring;
386
387out_fun:
388out_flags:
389 if (ring->events[0] >= 0)
390 pasemi_dma_free_flag(ring->events[0]);
391 if (ring->events[1] >= 0)
392 pasemi_dma_free_flag(ring->events[1]);
393 pasemi_dma_free_ring(&ring->chan);
394out_ring_desc:
395 pasemi_dma_free_chan(&ring->chan);
396out_chan:
397
398 return NULL;
399}
400
401static void pasemi_mac_setup_csrings(struct pasemi_mac *mac)
402{
403 int i;
404 mac->cs[0] = pasemi_mac_setup_csring(mac);
405 if (mac->type == MAC_TYPE_XAUI)
406 mac->cs[1] = pasemi_mac_setup_csring(mac);
407 else
408 mac->cs[1] = 0;
409
410 for (i = 0; i < MAX_CS; i++)
411 if (mac->cs[i])
412 mac->num_cs++;
413}
414
415static void pasemi_mac_free_csring(struct pasemi_mac_csring *csring)
416{
417 pasemi_dma_stop_chan(&csring->chan);
418 pasemi_dma_free_flag(csring->events[0]);
419 pasemi_dma_free_flag(csring->events[1]);
420 pasemi_dma_free_ring(&csring->chan);
421 pasemi_dma_free_chan(&csring->chan);
422}
423
325static int pasemi_mac_setup_rx_resources(const struct net_device *dev) 424static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
326{ 425{
327 struct pasemi_mac_rxring *ring; 426 struct pasemi_mac_rxring *ring;
@@ -445,7 +544,7 @@ pasemi_mac_setup_tx_resources(const struct net_device *dev)
445 cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE | 544 cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
446 PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | 545 PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
447 PAS_DMA_TXCHAN_CFG_UP | 546 PAS_DMA_TXCHAN_CFG_UP |
448 PAS_DMA_TXCHAN_CFG_WT(2); 547 PAS_DMA_TXCHAN_CFG_WT(4);
449 548
450 if (translation_enabled()) 549 if (translation_enabled())
451 cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR; 550 cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
@@ -810,13 +909,21 @@ restart:
810 u64 mactx = TX_DESC(txring, i); 909 u64 mactx = TX_DESC(txring, i);
811 struct sk_buff *skb; 910 struct sk_buff *skb;
812 911
813 skb = TX_DESC_INFO(txring, i+1).skb;
814 nr_frags = TX_DESC_INFO(txring, i).dma;
815
816 if ((mactx & XCT_MACTX_E) || 912 if ((mactx & XCT_MACTX_E) ||
817 (*chan->status & PAS_STATUS_ERROR)) 913 (*chan->status & PAS_STATUS_ERROR))
818 pasemi_mac_tx_error(mac, mactx); 914 pasemi_mac_tx_error(mac, mactx);
819 915
916 /* Skip over control descriptors */
917 if (!(mactx & XCT_MACTX_LLEN_M)) {
918 TX_DESC(txring, i) = 0;
919 TX_DESC(txring, i+1) = 0;
920 buf_count = 2;
921 continue;
922 }
923
924 skb = TX_DESC_INFO(txring, i+1).skb;
925 nr_frags = TX_DESC_INFO(txring, i).dma;
926
820 if (unlikely(mactx & XCT_MACTX_O)) 927 if (unlikely(mactx & XCT_MACTX_O))
821 /* Not yet transmitted */ 928 /* Not yet transmitted */
822 break; 929 break;
@@ -1058,6 +1165,12 @@ static int pasemi_mac_open(struct net_device *dev)
1058 if (!mac->tx) 1165 if (!mac->tx)
1059 goto out_tx_ring; 1166 goto out_tx_ring;
1060 1167
1168 if (dev->mtu > 1500) {
1169 pasemi_mac_setup_csrings(mac);
1170 if (!mac->num_cs)
1171 goto out_tx_ring;
1172 }
1173
1061 /* 0x3ff with 33MHz clock is about 31us */ 1174 /* 0x3ff with 33MHz clock is about 31us */
1062 write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG, 1175 write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
1063 PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff)); 1176 PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1241,7 +1354,7 @@ static int pasemi_mac_close(struct net_device *dev)
1241{ 1354{
1242 struct pasemi_mac *mac = netdev_priv(dev); 1355 struct pasemi_mac *mac = netdev_priv(dev);
1243 unsigned int sta; 1356 unsigned int sta;
1244 int rxch, txch; 1357 int rxch, txch, i;
1245 1358
1246 rxch = rx_ring(mac)->chan.chno; 1359 rxch = rx_ring(mac)->chan.chno;
1247 txch = tx_ring(mac)->chan.chno; 1360 txch = tx_ring(mac)->chan.chno;
@@ -1286,6 +1399,9 @@ static int pasemi_mac_close(struct net_device *dev)
1286 free_irq(mac->tx->chan.irq, mac->tx); 1399 free_irq(mac->tx->chan.irq, mac->tx);
1287 free_irq(mac->rx->chan.irq, mac->rx); 1400 free_irq(mac->rx->chan.irq, mac->rx);
1288 1401
1402 for (i = 0; i < mac->num_cs; i++)
1403 pasemi_mac_free_csring(mac->cs[i]);
1404
1289 /* Free resources */ 1405 /* Free resources */
1290 pasemi_mac_free_rx_resources(mac); 1406 pasemi_mac_free_rx_resources(mac);
1291 pasemi_mac_free_tx_resources(mac); 1407 pasemi_mac_free_tx_resources(mac);
@@ -1293,35 +1409,113 @@ static int pasemi_mac_close(struct net_device *dev)
1293 return 0; 1409 return 0;
1294} 1410}
1295 1411
1412static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
1413 const dma_addr_t *map,
1414 const unsigned int *map_size,
1415 struct pasemi_mac_txring *txring,
1416 struct pasemi_mac_csring *csring)
1417{
1418 u64 fund;
1419 dma_addr_t cs_dest;
1420 const int nh_off = skb_network_offset(skb);
1421 const int nh_len = skb_network_header_len(skb);
1422 const int nfrags = skb_shinfo(skb)->nr_frags;
1423 int cs_size, i, fill, hdr, cpyhdr, evt;
1424 dma_addr_t csdma;
1425
1426 fund = XCT_FUN_ST | XCT_FUN_RR_8BRES |
1427 XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
1428 XCT_FUN_CRM_SIG | XCT_FUN_LLEN(skb->len - nh_off) |
1429 XCT_FUN_SHL(nh_len >> 2) | XCT_FUN_SE;
1430
1431 switch (ip_hdr(skb)->protocol) {
1432 case IPPROTO_TCP:
1433 fund |= XCT_FUN_SIG_TCP4;
1434 /* TCP checksum is 16 bytes into the header */
1435 cs_dest = map[0] + skb_transport_offset(skb) + 16;
1436 break;
1437 case IPPROTO_UDP:
1438 fund |= XCT_FUN_SIG_UDP4;
1439 /* UDP checksum is 6 bytes into the header */
1440 cs_dest = map[0] + skb_transport_offset(skb) + 6;
1441 break;
1442 default:
1443 BUG();
1444 }
1445
1446 /* Do the checksum offloaded */
1447 fill = csring->next_to_fill;
1448 hdr = fill;
1449
1450 CS_DESC(csring, fill++) = fund;
1451 /* Room for 8BRES. Checksum result is really 2 bytes into it */
1452 csdma = csring->chan.ring_dma + (fill & (CS_RING_SIZE-1)) * 8 + 2;
1453 CS_DESC(csring, fill++) = 0;
1454
1455 CS_DESC(csring, fill) = XCT_PTR_LEN(map_size[0]-nh_off) | XCT_PTR_ADDR(map[0]+nh_off);
1456 for (i = 1; i <= nfrags; i++)
1457 CS_DESC(csring, fill+i) = XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
1458
1459 fill += i;
1460 if (fill & 1)
1461 fill++;
1462
1463 /* Copy the result into the TCP packet */
1464 cpyhdr = fill;
1465 CS_DESC(csring, fill++) = XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
1466 XCT_FUN_LLEN(2) | XCT_FUN_SE;
1467 CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(cs_dest) | XCT_PTR_T;
1468 CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(csdma);
1469 fill++;
1470
1471 evt = !csring->last_event;
1472 csring->last_event = evt;
1473
1474 /* Event handshaking with MAC TX */
1475 CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
1476 CTRL_CMD_ETYPE_SET | CTRL_CMD_REG(csring->events[evt]);
1477 CS_DESC(csring, fill++) = 0;
1478 CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
1479 CTRL_CMD_ETYPE_WCLR | CTRL_CMD_REG(csring->events[!evt]);
1480 CS_DESC(csring, fill++) = 0;
1481 csring->next_to_fill = fill & (CS_RING_SIZE-1);
1482
1483 cs_size = fill - hdr;
1484 write_dma_reg(PAS_DMA_TXCHAN_INCR(csring->chan.chno), (cs_size) >> 1);
1485
1486 /* TX-side event handshaking */
1487 fill = txring->next_to_fill;
1488 TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
1489 CTRL_CMD_ETYPE_WSET | CTRL_CMD_REG(csring->events[evt]);
1490 TX_DESC(txring, fill++) = 0;
1491 TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
1492 CTRL_CMD_ETYPE_CLR | CTRL_CMD_REG(csring->events[!evt]);
1493 TX_DESC(txring, fill++) = 0;
1494 txring->next_to_fill = fill;
1495
1496 write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
1497
1498 return;
1499}
1500
1296static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) 1501static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
1297{ 1502{
1298 struct pasemi_mac *mac = netdev_priv(dev); 1503 struct pasemi_mac * const mac = netdev_priv(dev);
1299 struct pasemi_mac_txring *txring; 1504 struct pasemi_mac_txring * const txring = tx_ring(mac);
1300 u64 dflags, mactx; 1505 struct pasemi_mac_csring *csring;
1506 u64 dflags = 0;
1507 u64 mactx;
1301 dma_addr_t map[MAX_SKB_FRAGS+1]; 1508 dma_addr_t map[MAX_SKB_FRAGS+1];
1302 unsigned int map_size[MAX_SKB_FRAGS+1]; 1509 unsigned int map_size[MAX_SKB_FRAGS+1];
1303 unsigned long flags; 1510 unsigned long flags;
1304 int i, nfrags; 1511 int i, nfrags;
1305 int fill; 1512 int fill;
1513 const int nh_off = skb_network_offset(skb);
1514 const int nh_len = skb_network_header_len(skb);
1306 1515
1307 dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD; 1516 prefetch(&txring->ring_info);
1308
1309 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1310 const unsigned char *nh = skb_network_header(skb);
1311 1517
1312 switch (ip_hdr(skb)->protocol) { 1518 dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
1313 case IPPROTO_TCP:
1314 dflags |= XCT_MACTX_CSUM_TCP;
1315 dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
1316 dflags |= XCT_MACTX_IPO(nh - skb->data);
1317 break;
1318 case IPPROTO_UDP:
1319 dflags |= XCT_MACTX_CSUM_UDP;
1320 dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
1321 dflags |= XCT_MACTX_IPO(nh - skb->data);
1322 break;
1323 }
1324 }
1325 1519
1326 nfrags = skb_shinfo(skb)->nr_frags; 1520 nfrags = skb_shinfo(skb)->nr_frags;
1327 1521
@@ -1344,24 +1538,46 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
1344 } 1538 }
1345 } 1539 }
1346 1540
1347 mactx = dflags | XCT_MACTX_LLEN(skb->len); 1541 if (skb->ip_summed == CHECKSUM_PARTIAL && skb->len <= 1540) {
1542 switch (ip_hdr(skb)->protocol) {
1543 case IPPROTO_TCP:
1544 dflags |= XCT_MACTX_CSUM_TCP;
1545 dflags |= XCT_MACTX_IPH(nh_len >> 2);
1546 dflags |= XCT_MACTX_IPO(nh_off);
1547 break;
1548 case IPPROTO_UDP:
1549 dflags |= XCT_MACTX_CSUM_UDP;
1550 dflags |= XCT_MACTX_IPH(nh_len >> 2);
1551 dflags |= XCT_MACTX_IPO(nh_off);
1552 break;
1553 default:
1554 WARN_ON(1);
1555 }
1556 }
1348 1557
1349 txring = tx_ring(mac); 1558 mactx = dflags | XCT_MACTX_LLEN(skb->len);
1350 1559
1351 spin_lock_irqsave(&txring->lock, flags); 1560 spin_lock_irqsave(&txring->lock, flags);
1352 1561
1353 fill = txring->next_to_fill;
1354
1355 /* Avoid stepping on the same cache line that the DMA controller 1562 /* Avoid stepping on the same cache line that the DMA controller
1356 * is currently about to send, so leave at least 8 words available. 1563 * is currently about to send, so leave at least 8 words available.
1357 * Total free space needed is mactx + fragments + 8 1564 * Total free space needed is mactx + fragments + 8
1358 */ 1565 */
1359 if (RING_AVAIL(txring) < nfrags + 10) { 1566 if (RING_AVAIL(txring) < nfrags + 14) {
1360 /* no room -- stop the queue and wait for tx intr */ 1567 /* no room -- stop the queue and wait for tx intr */
1361 netif_stop_queue(dev); 1568 netif_stop_queue(dev);
1362 goto out_err; 1569 goto out_err;
1363 } 1570 }
1364 1571
1572 /* Queue up checksum + event descriptors, if needed */
1573 if (mac->num_cs && skb->ip_summed == CHECKSUM_PARTIAL && skb->len > 1540) {
1574 csring = mac->cs[mac->last_cs];
1575 mac->last_cs = (mac->last_cs + 1) % mac->num_cs;
1576
1577 pasemi_mac_queue_csdesc(skb, map, map_size, txring, csring);
1578 }
1579
1580 fill = txring->next_to_fill;
1365 TX_DESC(txring, fill) = mactx; 1581 TX_DESC(txring, fill) = mactx;
1366 TX_DESC_INFO(txring, fill).dma = nfrags; 1582 TX_DESC_INFO(txring, fill).dma = nfrags;
1367 fill++; 1583 fill++;
@@ -1439,8 +1655,9 @@ static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
1439{ 1655{
1440 struct pasemi_mac *mac = netdev_priv(dev); 1656 struct pasemi_mac *mac = netdev_priv(dev);
1441 unsigned int reg; 1657 unsigned int reg;
1442 unsigned int rcmdsta; 1658 unsigned int rcmdsta = 0;
1443 int running; 1659 int running;
1660 int ret = 0;
1444 1661
1445 if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU) 1662 if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU)
1446 return -EINVAL; 1663 return -EINVAL;
@@ -1462,6 +1679,16 @@ static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
1462 pasemi_mac_pause_rxint(mac); 1679 pasemi_mac_pause_rxint(mac);
1463 pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE); 1680 pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
1464 pasemi_mac_free_rx_buffers(mac); 1681 pasemi_mac_free_rx_buffers(mac);
1682
1683 }
1684
1685 /* Setup checksum channels if large MTU and none already allocated */
1686 if (new_mtu > 1500 && !mac->num_cs) {
1687 pasemi_mac_setup_csrings(mac);
1688 if (!mac->num_cs) {
1689 ret = -ENOMEM;
1690 goto out;
1691 }
1465 } 1692 }
1466 1693
1467 /* Change maxf, i.e. what size frames are accepted. 1694 /* Change maxf, i.e. what size frames are accepted.
@@ -1476,6 +1703,7 @@ static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
1476 /* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ 1703 /* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
1477 mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128; 1704 mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
1478 1705
1706out:
1479 if (running) { 1707 if (running) {
1480 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 1708 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
1481 rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN); 1709 rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN);
@@ -1488,7 +1716,7 @@ static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
1488 pasemi_mac_intf_enable(mac); 1716 pasemi_mac_intf_enable(mac);
1489 } 1717 }
1490 1718
1491 return 0; 1719 return ret;
1492} 1720}
1493 1721
1494static int __devinit 1722static int __devinit
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 99e7b9329a6f..90c51670a1e7 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -27,6 +27,7 @@
27#include <linux/phy.h> 27#include <linux/phy.h>
28 28
29#define MAX_LRO_DESCRIPTORS 8 29#define MAX_LRO_DESCRIPTORS 8
30#define MAX_CS 2
30 31
31struct pasemi_mac_txring { 32struct pasemi_mac_txring {
32 struct pasemi_dmachan chan; /* Must be first */ 33 struct pasemi_dmachan chan; /* Must be first */
@@ -51,6 +52,15 @@ struct pasemi_mac_rxring {
51 struct pasemi_mac *mac; /* Needed in intr handler */ 52 struct pasemi_mac *mac; /* Needed in intr handler */
52}; 53};
53 54
55struct pasemi_mac_csring {
56 struct pasemi_dmachan chan;
57 unsigned int size;
58 unsigned int next_to_fill;
59 int events[2];
60 int last_event;
61 int fun;
62};
63
54struct pasemi_mac { 64struct pasemi_mac {
55 struct net_device *netdev; 65 struct net_device *netdev;
56 struct pci_dev *pdev; 66 struct pci_dev *pdev;
@@ -60,10 +70,12 @@ struct pasemi_mac {
60 struct napi_struct napi; 70 struct napi_struct napi;
61 71
62 int bufsz; /* RX ring buffer size */ 72 int bufsz; /* RX ring buffer size */
73 int last_cs;
74 int num_cs;
75 u32 dma_if;
63 u8 type; 76 u8 type;
64#define MAC_TYPE_GMAC 1 77#define MAC_TYPE_GMAC 1
65#define MAC_TYPE_XAUI 2 78#define MAC_TYPE_XAUI 2
66 u32 dma_if;
67 79
68 u8 mac_addr[6]; 80 u8 mac_addr[6];
69 81
@@ -74,6 +86,7 @@ struct pasemi_mac {
74 86
75 struct pasemi_mac_txring *tx; 87 struct pasemi_mac_txring *tx;
76 struct pasemi_mac_rxring *rx; 88 struct pasemi_mac_rxring *rx;
89 struct pasemi_mac_csring *cs[MAX_CS];
77 char tx_irq_name[10]; /* "eth%d tx" */ 90 char tx_irq_name[10]; /* "eth%d tx" */
78 char rx_irq_name[10]; /* "eth%d rx" */ 91 char rx_irq_name[10]; /* "eth%d rx" */
79 int link; 92 int link;
diff --git a/include/asm-powerpc/pasemi_dma.h b/include/asm-powerpc/pasemi_dma.h
index facb2bdea45c..19fd7933e2d9 100644
--- a/include/asm-powerpc/pasemi_dma.h
+++ b/include/asm-powerpc/pasemi_dma.h
@@ -128,11 +128,16 @@ enum {
128#define PAS_DMA_TXCHAN_TCMDSTA_DA 0x00000100 128#define PAS_DMA_TXCHAN_TCMDSTA_DA 0x00000100
129#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE) 129#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
130#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */ 130#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
131#define PAS_DMA_TXCHAN_CFG_TY_COPY 0x00000001 /* Type = copy only */
132#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = function */
133#define PAS_DMA_TXCHAN_CFG_TY_XOR 0x00000003 /* Type = xor only */
131#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c 134#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
132#define PAS_DMA_TXCHAN_CFG_TATTR_S 2 135#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
133#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \ 136#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
134 PAS_DMA_TXCHAN_CFG_TATTR_M) 137 PAS_DMA_TXCHAN_CFG_TATTR_M)
135#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0 138#define PAS_DMA_TXCHAN_CFG_LPDQ 0x00000800
139#define PAS_DMA_TXCHAN_CFG_LPSQ 0x00000400
140#define PAS_DMA_TXCHAN_CFG_WT_M 0x000003c0
136#define PAS_DMA_TXCHAN_CFG_WT_S 6 141#define PAS_DMA_TXCHAN_CFG_WT_S 6
137#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \ 142#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
138 PAS_DMA_TXCHAN_CFG_WT_M) 143 PAS_DMA_TXCHAN_CFG_WT_M)
@@ -399,11 +404,62 @@ enum {
399 XCT_COPY_LLEN_M) 404 XCT_COPY_LLEN_M)
400#define XCT_COPY_SE 0x0000000000000001ull 405#define XCT_COPY_SE 0x0000000000000001ull
401 406
407/* Function descriptor fields */
408#define XCT_FUN_T 0x8000000000000000ull
409#define XCT_FUN_ST 0x4000000000000000ull
410#define XCT_FUN_RR_M 0x3000000000000000ull
411#define XCT_FUN_RR_NORES 0x0000000000000000ull
412#define XCT_FUN_RR_8BRES 0x1000000000000000ull
413#define XCT_FUN_RR_24BRES 0x2000000000000000ull
414#define XCT_FUN_RR_40BRES 0x3000000000000000ull
415#define XCT_FUN_I 0x0800000000000000ull
416#define XCT_FUN_O 0x0400000000000000ull
417#define XCT_FUN_E 0x0200000000000000ull
418#define XCT_FUN_FUN_M 0x01c0000000000000ull
419#define XCT_FUN_FUN_S 54
420#define XCT_FUN_FUN(x) ((((long)(x)) << XCT_FUN_FUN_S) & XCT_FUN_FUN_M)
421#define XCT_FUN_CRM_M 0x0038000000000000ull
422#define XCT_FUN_CRM_NOP 0x0000000000000000ull
423#define XCT_FUN_CRM_SIG 0x0008000000000000ull
424#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
425#define XCT_FUN_LLEN_S 32
426#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & XCT_FUN_LLEN_M)
427#define XCT_FUN_SHL_M 0x00000000f8000000ull
428#define XCT_FUN_SHL_S 27
429#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & XCT_FUN_SHL_M)
430#define XCT_FUN_CHL_M 0x0000000007c00000ull
431#define XCT_FUN_HSZ_M 0x00000000003c0000ull
432#define XCT_FUN_ALG_M 0x0000000000038000ull
433#define XCT_FUN_HP 0x0000000000004000ull
434#define XCT_FUN_BCM_M 0x0000000000003800ull
435#define XCT_FUN_BCP_M 0x0000000000000600ull
436#define XCT_FUN_SIG_M 0x00000000000001f0ull
437#define XCT_FUN_SIG_TCP4 0x0000000000000140ull
438#define XCT_FUN_SIG_TCP6 0x0000000000000150ull
439#define XCT_FUN_SIG_UDP4 0x0000000000000160ull
440#define XCT_FUN_SIG_UDP6 0x0000000000000170ull
441#define XCT_FUN_A 0x0000000000000008ull
442#define XCT_FUN_C 0x0000000000000004ull
443#define XCT_FUN_AL2 0x0000000000000002ull
444#define XCT_FUN_SE 0x0000000000000001ull
445
446/* Function descriptor 8byte result fields */
447#define XCT_FUNRES_8B_CS_M 0x0000ffff00000000ull
448#define XCT_FUNRES_8B_CS_S 32
449#define XCT_FUNRES_8B_CRC_M 0x00000000ffffffffull
450#define XCT_FUNRES_8B_CRC_S 0
451
402/* Control descriptor fields */ 452/* Control descriptor fields */
403#define CTRL_CMD_T 0x8000000000000000ull 453#define CTRL_CMD_T 0x8000000000000000ull
404#define CTRL_CMD_META_EVT 0x2000000000000000ull 454#define CTRL_CMD_META_EVT 0x2000000000000000ull
405#define CTRL_CMD_O 0x0400000000000000ull 455#define CTRL_CMD_O 0x0400000000000000ull
406#define CTRL_CMD_REG_M 0x000000000000000full 456#define CTRL_CMD_ETYPE_M 0x0038000000000000ull
457#define CTRL_CMD_ETYPE_EXT 0x0000000000000000ull
458#define CTRL_CMD_ETYPE_WSET 0x0020000000000000ull
459#define CTRL_CMD_ETYPE_WCLR 0x0028000000000000ull
460#define CTRL_CMD_ETYPE_SET 0x0030000000000000ull
461#define CTRL_CMD_ETYPE_CLR 0x0038000000000000ull
462#define CTRL_CMD_REG_M 0x000000000000007full
407#define CTRL_CMD_REG_S 0 463#define CTRL_CMD_REG_S 0
408#define CTRL_CMD_REG(x) ((((long)(x)) << CTRL_CMD_REG_S) & \ 464#define CTRL_CMD_REG(x) ((((long)(x)) << CTRL_CMD_REG_S) & \
409 CTRL_CMD_REG_M) 465 CTRL_CMD_REG_M)