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.c259
1 files changed, 187 insertions, 72 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index bb88a41b7591..2e39e0285d8f 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -62,6 +62,10 @@
62 62
63#define LRO_MAX_AGGR 64 63#define LRO_MAX_AGGR 64
64 64
65#define PE_MIN_MTU 64
66#define PE_MAX_MTU 1500
67#define PE_DEF_MTU ETH_DATA_LEN
68
65#define DEFAULT_MSG_ENABLE \ 69#define DEFAULT_MSG_ENABLE \
66 (NETIF_MSG_DRV | \ 70 (NETIF_MSG_DRV | \
67 NETIF_MSG_PROBE | \ 71 NETIF_MSG_PROBE | \
@@ -82,8 +86,6 @@
82 & ((ring)->size - 1)) 86 & ((ring)->size - 1))
83#define RING_AVAIL(ring) ((ring->size) - RING_USED(ring)) 87#define RING_AVAIL(ring) ((ring->size) - RING_USED(ring))
84 88
85#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
86
87MODULE_LICENSE("GPL"); 89MODULE_LICENSE("GPL");
88MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); 90MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
89MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); 91MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
@@ -175,6 +177,24 @@ static int mac_to_intf(struct pasemi_mac *mac)
175 return -1; 177 return -1;
176} 178}
177 179
180static void pasemi_mac_intf_disable(struct pasemi_mac *mac)
181{
182 unsigned int flags;
183
184 flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
185 flags &= ~PAS_MAC_CFG_PCFG_PE;
186 write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
187}
188
189static void pasemi_mac_intf_enable(struct pasemi_mac *mac)
190{
191 unsigned int flags;
192
193 flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
194 flags |= PAS_MAC_CFG_PCFG_PE;
195 write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
196}
197
178static int pasemi_get_mac_addr(struct pasemi_mac *mac) 198static int pasemi_get_mac_addr(struct pasemi_mac *mac)
179{ 199{
180 struct pci_dev *pdev = mac->pdev; 200 struct pci_dev *pdev = mac->pdev;
@@ -221,6 +241,33 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
221 return 0; 241 return 0;
222} 242}
223 243
244static int pasemi_mac_set_mac_addr(struct net_device *dev, void *p)
245{
246 struct pasemi_mac *mac = netdev_priv(dev);
247 struct sockaddr *addr = p;
248 unsigned int adr0, adr1;
249
250 if (!is_valid_ether_addr(addr->sa_data))
251 return -EINVAL;
252
253 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
254
255 adr0 = dev->dev_addr[2] << 24 |
256 dev->dev_addr[3] << 16 |
257 dev->dev_addr[4] << 8 |
258 dev->dev_addr[5];
259 adr1 = read_mac_reg(mac, PAS_MAC_CFG_ADR1);
260 adr1 &= ~0xffff;
261 adr1 |= dev->dev_addr[0] << 8 | dev->dev_addr[1];
262
263 pasemi_mac_intf_disable(mac);
264 write_mac_reg(mac, PAS_MAC_CFG_ADR0, adr0);
265 write_mac_reg(mac, PAS_MAC_CFG_ADR1, adr1);
266 pasemi_mac_intf_enable(mac);
267
268 return 0;
269}
270
224static int get_skb_hdr(struct sk_buff *skb, void **iphdr, 271static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
225 void **tcph, u64 *hdr_flags, void *data) 272 void **tcph, u64 *hdr_flags, void *data)
226{ 273{
@@ -453,7 +500,7 @@ static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac)
453 500
454} 501}
455 502
456static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac) 503static void pasemi_mac_free_rx_buffers(struct pasemi_mac *mac)
457{ 504{
458 struct pasemi_mac_rxring *rx = rx_ring(mac); 505 struct pasemi_mac_rxring *rx = rx_ring(mac);
459 unsigned int i; 506 unsigned int i;
@@ -473,7 +520,12 @@ static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac)
473 } 520 }
474 521
475 for (i = 0; i < RX_RING_SIZE; i++) 522 for (i = 0; i < RX_RING_SIZE; i++)
476 RX_DESC(rx, i) = 0; 523 RX_BUFF(rx, i) = 0;
524}
525
526static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac)
527{
528 pasemi_mac_free_rx_buffers(mac);
477 529
478 dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), 530 dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
479 rx_ring(mac)->buffers, rx_ring(mac)->buf_dma); 531 rx_ring(mac)->buffers, rx_ring(mac)->buf_dma);
@@ -503,14 +555,14 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev,
503 /* Entry in use? */ 555 /* Entry in use? */
504 WARN_ON(*buff); 556 WARN_ON(*buff);
505 557
506 skb = dev_alloc_skb(BUF_SIZE); 558 skb = dev_alloc_skb(mac->bufsz);
507 skb_reserve(skb, LOCAL_SKB_ALIGN); 559 skb_reserve(skb, LOCAL_SKB_ALIGN);
508 560
509 if (unlikely(!skb)) 561 if (unlikely(!skb))
510 break; 562 break;
511 563
512 dma = pci_map_single(mac->dma_pdev, skb->data, 564 dma = pci_map_single(mac->dma_pdev, skb->data,
513 BUF_SIZE - LOCAL_SKB_ALIGN, 565 mac->bufsz - LOCAL_SKB_ALIGN,
514 PCI_DMA_FROMDEVICE); 566 PCI_DMA_FROMDEVICE);
515 567
516 if (unlikely(dma_mapping_error(dma))) { 568 if (unlikely(dma_mapping_error(dma))) {
@@ -520,7 +572,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev,
520 572
521 info->skb = skb; 573 info->skb = skb;
522 info->dma = dma; 574 info->dma = dma;
523 *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); 575 *buff = XCT_RXB_LEN(mac->bufsz) | XCT_RXB_ADDR(dma);
524 fill++; 576 fill++;
525 } 577 }
526 578
@@ -650,7 +702,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx,
650 702
651 len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; 703 len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
652 704
653 pci_unmap_single(pdev, dma, BUF_SIZE-LOCAL_SKB_ALIGN, 705 pci_unmap_single(pdev, dma, mac->bufsz - LOCAL_SKB_ALIGN,
654 PCI_DMA_FROMDEVICE); 706 PCI_DMA_FROMDEVICE);
655 707
656 if (macrx & XCT_MACRX_CRC) { 708 if (macrx & XCT_MACRX_CRC) {
@@ -874,24 +926,6 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
874 return IRQ_HANDLED; 926 return IRQ_HANDLED;
875} 927}
876 928
877static void pasemi_mac_intf_disable(struct pasemi_mac *mac)
878{
879 unsigned int flags;
880
881 flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
882 flags &= ~PAS_MAC_CFG_PCFG_PE;
883 write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
884}
885
886static void pasemi_mac_intf_enable(struct pasemi_mac *mac)
887{
888 unsigned int flags;
889
890 flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
891 flags |= PAS_MAC_CFG_PCFG_PE;
892 write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
893}
894
895static void pasemi_adjust_link(struct net_device *dev) 929static void pasemi_adjust_link(struct net_device *dev)
896{ 930{
897 struct pasemi_mac *mac = netdev_priv(dev); 931 struct pasemi_mac *mac = netdev_priv(dev);
@@ -1148,11 +1182,71 @@ out_rx_resources:
1148 1182
1149#define MAX_RETRIES 5000 1183#define MAX_RETRIES 5000
1150 1184
1185static void pasemi_mac_pause_txchan(struct pasemi_mac *mac)
1186{
1187 unsigned int sta, retries;
1188 int txch = tx_ring(mac)->chan.chno;
1189
1190 write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch),
1191 PAS_DMA_TXCHAN_TCMDSTA_ST);
1192
1193 for (retries = 0; retries < MAX_RETRIES; retries++) {
1194 sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch));
1195 if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT))
1196 break;
1197 cond_resched();
1198 }
1199
1200 if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)
1201 dev_err(&mac->dma_pdev->dev,
1202 "Failed to stop tx channel, tcmdsta %08x\n", sta);
1203
1204 write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 0);
1205}
1206
1207static void pasemi_mac_pause_rxchan(struct pasemi_mac *mac)
1208{
1209 unsigned int sta, retries;
1210 int rxch = rx_ring(mac)->chan.chno;
1211
1212 write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch),
1213 PAS_DMA_RXCHAN_CCMDSTA_ST);
1214 for (retries = 0; retries < MAX_RETRIES; retries++) {
1215 sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
1216 if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT))
1217 break;
1218 cond_resched();
1219 }
1220
1221 if (sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)
1222 dev_err(&mac->dma_pdev->dev,
1223 "Failed to stop rx channel, ccmdsta 08%x\n", sta);
1224 write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), 0);
1225}
1226
1227static void pasemi_mac_pause_rxint(struct pasemi_mac *mac)
1228{
1229 unsigned int sta, retries;
1230
1231 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
1232 PAS_DMA_RXINT_RCMDSTA_ST);
1233 for (retries = 0; retries < MAX_RETRIES; retries++) {
1234 sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
1235 if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT))
1236 break;
1237 cond_resched();
1238 }
1239
1240 if (sta & PAS_DMA_RXINT_RCMDSTA_ACT)
1241 dev_err(&mac->dma_pdev->dev,
1242 "Failed to stop rx interface, rcmdsta %08x\n", sta);
1243 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
1244}
1245
1151static int pasemi_mac_close(struct net_device *dev) 1246static int pasemi_mac_close(struct net_device *dev)
1152{ 1247{
1153 struct pasemi_mac *mac = netdev_priv(dev); 1248 struct pasemi_mac *mac = netdev_priv(dev);
1154 unsigned int sta; 1249 unsigned int sta;
1155 int retries;
1156 int rxch, txch; 1250 int rxch, txch;
1157 1251
1158 rxch = rx_ring(mac)->chan.chno; 1252 rxch = rx_ring(mac)->chan.chno;
@@ -1190,51 +1284,10 @@ static int pasemi_mac_close(struct net_device *dev)
1190 pasemi_mac_clean_tx(tx_ring(mac)); 1284 pasemi_mac_clean_tx(tx_ring(mac));
1191 pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE); 1285 pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
1192 1286
1193 /* Disable interface */ 1287 pasemi_mac_pause_txchan(mac);
1194 write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 1288 pasemi_mac_pause_rxint(mac);
1195 PAS_DMA_TXCHAN_TCMDSTA_ST); 1289 pasemi_mac_pause_rxchan(mac);
1196 write_dma_reg( PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 1290 pasemi_mac_intf_disable(mac);
1197 PAS_DMA_RXINT_RCMDSTA_ST);
1198 write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch),
1199 PAS_DMA_RXCHAN_CCMDSTA_ST);
1200
1201 for (retries = 0; retries < MAX_RETRIES; retries++) {
1202 sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(rxch));
1203 if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT))
1204 break;
1205 cond_resched();
1206 }
1207
1208 if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)
1209 dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
1210
1211 for (retries = 0; retries < MAX_RETRIES; retries++) {
1212 sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
1213 if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT))
1214 break;
1215 cond_resched();
1216 }
1217
1218 if (sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)
1219 dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
1220
1221 for (retries = 0; retries < MAX_RETRIES; retries++) {
1222 sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
1223 if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT))
1224 break;
1225 cond_resched();
1226 }
1227
1228 if (sta & PAS_DMA_RXINT_RCMDSTA_ACT)
1229 dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n");
1230
1231 /* Then, disable the channel. This must be done separately from
1232 * stopping, since you can't disable when active.
1233 */
1234
1235 write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 0);
1236 write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), 0);
1237 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
1238 1291
1239 free_irq(mac->tx->chan.irq, mac->tx); 1292 free_irq(mac->tx->chan.irq, mac->tx);
1240 free_irq(mac->rx->chan.irq, mac->rx); 1293 free_irq(mac->rx->chan.irq, mac->rx);
@@ -1388,6 +1441,62 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1388 return pkts; 1441 return pkts;
1389} 1442}
1390 1443
1444static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
1445{
1446 struct pasemi_mac *mac = netdev_priv(dev);
1447 unsigned int reg;
1448 unsigned int rcmdsta;
1449 int running;
1450
1451 if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU)
1452 return -EINVAL;
1453
1454 running = netif_running(dev);
1455
1456 if (running) {
1457 /* Need to stop the interface, clean out all already
1458 * received buffers, free all unused buffers on the RX
1459 * interface ring, then finally re-fill the rx ring with
1460 * the new-size buffers and restart.
1461 */
1462
1463 napi_disable(&mac->napi);
1464 netif_tx_disable(dev);
1465 pasemi_mac_intf_disable(mac);
1466
1467 rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
1468 pasemi_mac_pause_rxint(mac);
1469 pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
1470 pasemi_mac_free_rx_buffers(mac);
1471 }
1472
1473 /* Change maxf, i.e. what size frames are accepted.
1474 * Need room for ethernet header and CRC word
1475 */
1476 reg = read_mac_reg(mac, PAS_MAC_CFG_MACCFG);
1477 reg &= ~PAS_MAC_CFG_MACCFG_MAXF_M;
1478 reg |= PAS_MAC_CFG_MACCFG_MAXF(new_mtu + ETH_HLEN + 4);
1479 write_mac_reg(mac, PAS_MAC_CFG_MACCFG, reg);
1480
1481 dev->mtu = new_mtu;
1482 /* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
1483 mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
1484
1485 if (running) {
1486 write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
1487 rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN);
1488
1489 rx_ring(mac)->next_to_fill = 0;
1490 pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE-1);
1491
1492 napi_enable(&mac->napi);
1493 netif_start_queue(dev);
1494 pasemi_mac_intf_enable(mac);
1495 }
1496
1497 return 0;
1498}
1499
1391static int __devinit 1500static int __devinit
1392pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1501pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1393{ 1502{
@@ -1475,6 +1584,12 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1475 dev->stop = pasemi_mac_close; 1584 dev->stop = pasemi_mac_close;
1476 dev->hard_start_xmit = pasemi_mac_start_tx; 1585 dev->hard_start_xmit = pasemi_mac_start_tx;
1477 dev->set_multicast_list = pasemi_mac_set_rx_mode; 1586 dev->set_multicast_list = pasemi_mac_set_rx_mode;
1587 dev->set_mac_address = pasemi_mac_set_mac_addr;
1588 dev->mtu = PE_DEF_MTU;
1589 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
1590 mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
1591
1592 dev->change_mtu = pasemi_mac_change_mtu;
1478 1593
1479 if (err) 1594 if (err)
1480 goto out; 1595 goto out;