aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c139
1 files changed, 60 insertions, 79 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index fb6b232069d6..7c9dbc8c9423 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -58,11 +58,10 @@
58 58
59#define INT_CAUSE_UNMASK_ALL 0x0007ffff 59#define INT_CAUSE_UNMASK_ALL 0x0007ffff
60#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff 60#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
61#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
62#define INT_CAUSE_MASK_ALL 0x00000000 61#define INT_CAUSE_MASK_ALL 0x00000000
62#define INT_CAUSE_MASK_ALL_EXT 0x00000000
63#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL 63#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
64#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT 64#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
65#endif
66 65
67#ifdef MV643XX_CHECKSUM_OFFLOAD_TX 66#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
68#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1) 67#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
@@ -259,14 +258,13 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev)
259static void mv643xx_eth_set_rx_mode(struct net_device *dev) 258static void mv643xx_eth_set_rx_mode(struct net_device *dev)
260{ 259{
261 struct mv643xx_private *mp = netdev_priv(dev); 260 struct mv643xx_private *mp = netdev_priv(dev);
262 u32 config_reg;
263 261
264 config_reg = ethernet_get_config_reg(mp->port_num);
265 if (dev->flags & IFF_PROMISC) 262 if (dev->flags & IFF_PROMISC)
266 config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; 263 mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
267 else 264 else
268 config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; 265 mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
269 ethernet_set_config_reg(mp->port_num, config_reg); 266
267 mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
270} 268}
271 269
272/* 270/*
@@ -369,15 +367,6 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev,
369 367
370 dev_kfree_skb_irq(pkt_info.return_info); 368 dev_kfree_skb_irq(pkt_info.return_info);
371 released = 0; 369 released = 0;
372
373 /*
374 * Decrement the number of outstanding skbs counter on
375 * the TX queue.
376 */
377 if (mp->tx_ring_skbs == 0)
378 panic("ERROR - TX outstanding SKBs"
379 " counter is corrupted");
380 mp->tx_ring_skbs--;
381 } else 370 } else
382 dma_unmap_page(NULL, pkt_info.buf_ptr, 371 dma_unmap_page(NULL, pkt_info.buf_ptr,
383 pkt_info.byte_cnt, DMA_TO_DEVICE); 372 pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -412,15 +401,13 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
412 struct pkt_info pkt_info; 401 struct pkt_info pkt_info;
413 402
414#ifdef MV643XX_NAPI 403#ifdef MV643XX_NAPI
415 while (eth_port_receive(mp, &pkt_info) == ETH_OK && budget > 0) { 404 while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
416#else 405#else
417 while (eth_port_receive(mp, &pkt_info) == ETH_OK) { 406 while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
418#endif 407#endif
419 mp->rx_ring_skbs--; 408 mp->rx_ring_skbs--;
420 received_packets++; 409 received_packets++;
421#ifdef MV643XX_NAPI 410
422 budget--;
423#endif
424 /* Update statistics. Note byte count includes 4 byte CRC count */ 411 /* Update statistics. Note byte count includes 4 byte CRC count */
425 stats->rx_packets++; 412 stats->rx_packets++;
426 stats->rx_bytes += pkt_info.byte_cnt; 413 stats->rx_bytes += pkt_info.byte_cnt;
@@ -1044,9 +1031,6 @@ static void mv643xx_tx(struct net_device *dev)
1044 DMA_TO_DEVICE); 1031 DMA_TO_DEVICE);
1045 1032
1046 dev_kfree_skb_irq(pkt_info.return_info); 1033 dev_kfree_skb_irq(pkt_info.return_info);
1047
1048 if (mp->tx_ring_skbs)
1049 mp->tx_ring_skbs--;
1050 } else 1034 } else
1051 dma_unmap_page(NULL, pkt_info.buf_ptr, 1035 dma_unmap_page(NULL, pkt_info.buf_ptr,
1052 pkt_info.byte_cnt, DMA_TO_DEVICE); 1036 pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -1189,7 +1173,6 @@ linear:
1189 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, 1173 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
1190 DMA_TO_DEVICE); 1174 DMA_TO_DEVICE);
1191 pkt_info.return_info = skb; 1175 pkt_info.return_info = skb;
1192 mp->tx_ring_skbs++;
1193 status = eth_port_send(mp, &pkt_info); 1176 status = eth_port_send(mp, &pkt_info);
1194 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) 1177 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
1195 printk(KERN_ERR "%s: Error on transmitting packet\n", 1178 printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1274,7 +1257,6 @@ linear:
1274 pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT | 1257 pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
1275 ETH_TX_LAST_DESC; 1258 ETH_TX_LAST_DESC;
1276 pkt_info.return_info = skb; 1259 pkt_info.return_info = skb;
1277 mp->tx_ring_skbs++;
1278 } else { 1260 } else {
1279 pkt_info.return_info = 0; 1261 pkt_info.return_info = 0;
1280 } 1262 }
@@ -1311,7 +1293,6 @@ linear:
1311 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, 1293 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
1312 DMA_TO_DEVICE); 1294 DMA_TO_DEVICE);
1313 pkt_info.return_info = skb; 1295 pkt_info.return_info = skb;
1314 mp->tx_ring_skbs++;
1315 status = eth_port_send(mp, &pkt_info); 1296 status = eth_port_send(mp, &pkt_info);
1316 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) 1297 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
1317 printk(KERN_ERR "%s: Error on transmitting packet\n", 1298 printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1356,6 +1337,43 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
1356 return &mp->stats; 1337 return &mp->stats;
1357} 1338}
1358 1339
1340#ifdef CONFIG_NET_POLL_CONTROLLER
1341static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
1342{
1343 int port_num = mp->port_num;
1344 unsigned long flags;
1345
1346 spin_lock_irqsave(&mp->lock, flags);
1347 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
1348 INT_CAUSE_UNMASK_ALL);
1349 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
1350 INT_CAUSE_UNMASK_ALL_EXT);
1351 spin_unlock_irqrestore(&mp->lock, flags);
1352}
1353
1354static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
1355{
1356 int port_num = mp->port_num;
1357 unsigned long flags;
1358
1359 spin_lock_irqsave(&mp->lock, flags);
1360 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
1361 INT_CAUSE_MASK_ALL);
1362 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
1363 INT_CAUSE_MASK_ALL_EXT);
1364 spin_unlock_irqrestore(&mp->lock, flags);
1365}
1366
1367static void mv643xx_netpoll(struct net_device *netdev)
1368{
1369 struct mv643xx_private *mp = netdev_priv(netdev);
1370
1371 mv643xx_disable_irq(mp);
1372 mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
1373 mv643xx_enable_irq(mp);
1374}
1375#endif
1376
1359/*/ 1377/*/
1360 * mv643xx_eth_probe 1378 * mv643xx_eth_probe
1361 * 1379 *
@@ -1406,6 +1424,10 @@ static int mv643xx_eth_probe(struct device *ddev)
1406 dev->weight = 64; 1424 dev->weight = 64;
1407#endif 1425#endif
1408 1426
1427#ifdef CONFIG_NET_POLL_CONTROLLER
1428 dev->poll_controller = mv643xx_netpoll;
1429#endif
1430
1409 dev->watchdog_timeo = 2 * HZ; 1431 dev->watchdog_timeo = 2 * HZ;
1410 dev->tx_queue_len = mp->tx_ring_size; 1432 dev->tx_queue_len = mp->tx_ring_size;
1411 dev->base_addr = 0; 1433 dev->base_addr = 0;
@@ -1883,6 +1905,9 @@ static void eth_port_start(struct mv643xx_private *mp)
1883 /* Enable port Rx. */ 1905 /* Enable port Rx. */
1884 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 1906 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
1885 mp->port_rx_queue_command); 1907 mp->port_rx_queue_command);
1908
1909 /* Disable port bandwidth limits by clearing MTU register */
1910 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
1886} 1911}
1887 1912
1888/* 1913/*
@@ -2292,34 +2317,6 @@ static void eth_port_reset(unsigned int port_num)
2292 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data); 2317 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
2293} 2318}
2294 2319
2295/*
2296 * ethernet_set_config_reg - Set specified bits in configuration register.
2297 *
2298 * DESCRIPTION:
2299 * This function sets specified bits in the given ethernet
2300 * configuration register.
2301 *
2302 * INPUT:
2303 * unsigned int eth_port_num Ethernet Port number.
2304 * unsigned int value 32 bit value.
2305 *
2306 * OUTPUT:
2307 * The set bits in the value parameter are set in the configuration
2308 * register.
2309 *
2310 * RETURN:
2311 * None.
2312 *
2313 */
2314static void ethernet_set_config_reg(unsigned int eth_port_num,
2315 unsigned int value)
2316{
2317 unsigned int eth_config_reg;
2318
2319 eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num));
2320 eth_config_reg |= value;
2321 mv_write(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num), eth_config_reg);
2322}
2323 2320
2324static int eth_port_autoneg_supported(unsigned int eth_port_num) 2321static int eth_port_autoneg_supported(unsigned int eth_port_num)
2325{ 2322{
@@ -2346,31 +2343,6 @@ static int eth_port_link_is_up(unsigned int eth_port_num)
2346} 2343}
2347 2344
2348/* 2345/*
2349 * ethernet_get_config_reg - Get the port configuration register
2350 *
2351 * DESCRIPTION:
2352 * This function returns the configuration register value of the given
2353 * ethernet port.
2354 *
2355 * INPUT:
2356 * unsigned int eth_port_num Ethernet Port number.
2357 *
2358 * OUTPUT:
2359 * None.
2360 *
2361 * RETURN:
2362 * Port configuration register value.
2363 */
2364static unsigned int ethernet_get_config_reg(unsigned int eth_port_num)
2365{
2366 unsigned int eth_config_reg;
2367
2368 eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_EXTEND_REG
2369 (eth_port_num));
2370 return eth_config_reg;
2371}
2372
2373/*
2374 * eth_port_read_smi_reg - Read PHY registers 2346 * eth_port_read_smi_reg - Read PHY registers
2375 * 2347 *
2376 * DESCRIPTION: 2348 * DESCRIPTION:
@@ -2528,6 +2500,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2528 return ETH_ERROR; 2500 return ETH_ERROR;
2529 } 2501 }
2530 2502
2503 mp->tx_ring_skbs++;
2504 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2505
2531 /* Get the Tx Desc ring indexes */ 2506 /* Get the Tx Desc ring indexes */
2532 tx_desc_curr = mp->tx_curr_desc_q; 2507 tx_desc_curr = mp->tx_curr_desc_q;
2533 tx_desc_used = mp->tx_used_desc_q; 2508 tx_desc_used = mp->tx_used_desc_q;
@@ -2594,6 +2569,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2594 if (mp->tx_resource_err) 2569 if (mp->tx_resource_err)
2595 return ETH_QUEUE_FULL; 2570 return ETH_QUEUE_FULL;
2596 2571
2572 mp->tx_ring_skbs++;
2573 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2574
2597 /* Get the Tx Desc ring indexes */ 2575 /* Get the Tx Desc ring indexes */
2598 tx_desc_curr = mp->tx_curr_desc_q; 2576 tx_desc_curr = mp->tx_curr_desc_q;
2599 tx_desc_used = mp->tx_used_desc_q; 2577 tx_desc_used = mp->tx_used_desc_q;
@@ -2694,6 +2672,9 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
2694 /* Any Tx return cancels the Tx resource error status */ 2672 /* Any Tx return cancels the Tx resource error status */
2695 mp->tx_resource_err = 0; 2673 mp->tx_resource_err = 0;
2696 2674
2675 BUG_ON(mp->tx_ring_skbs == 0);
2676 mp->tx_ring_skbs--;
2677
2697 return ETH_OK; 2678 return ETH_OK;
2698} 2679}
2699 2680