aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Farnsworth <dale@farnsworth.org>2006-01-27 03:10:47 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-27 11:11:16 -0500
commit9f8dd319459bb5ab9efcc1c345bed7895cc41768 (patch)
tree017ea7b2ca60f29110b8e43afbd6560737824489
parentf98e36f1f7903a319f7f87f96490e88f691ea106 (diff)
[PATCH] mv643xx_eth: Make port queue enable/disable code consistent
Add and use the following functions: mv643xx_eth_port_enable_tx() mv643xx_eth_port_enable_rx() mv643xx_eth_port_disable_tx() mv643xx_eth_port_disable_rx() so that ports are enabled/disabled consistently. Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/mv643xx_eth.c133
1 files changed, 79 insertions, 54 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 73c766b3cd11..2daa9b97d2c0 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -83,6 +83,12 @@ static int eth_port_link_is_up(unsigned int eth_port_num);
83static void eth_port_uc_addr_get(struct net_device *dev, 83static void eth_port_uc_addr_get(struct net_device *dev,
84 unsigned char *MacAddr); 84 unsigned char *MacAddr);
85static void eth_port_set_multicast_list(struct net_device *); 85static void eth_port_set_multicast_list(struct net_device *);
86static void mv643xx_eth_port_enable_tx(unsigned int port_num,
87 unsigned int channels);
88static void mv643xx_eth_port_enable_rx(unsigned int port_num,
89 unsigned int channels);
90static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num);
91static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num);
86static int mv643xx_eth_open(struct net_device *); 92static int mv643xx_eth_open(struct net_device *);
87static int mv643xx_eth_stop(struct net_device *); 93static int mv643xx_eth_stop(struct net_device *);
88static int mv643xx_eth_change_mtu(struct net_device *, int); 94static int mv643xx_eth_change_mtu(struct net_device *, int);
@@ -535,8 +541,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
535 netif_carrier_on(dev); 541 netif_carrier_on(dev);
536 netif_wake_queue(dev); 542 netif_wake_queue(dev);
537 /* Start TX queue */ 543 /* Start TX queue */
538 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG 544 mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command);
539 (port_num), 1);
540 } else { 545 } else {
541 netif_carrier_off(dev); 546 netif_carrier_off(dev);
542 netif_stop_queue(dev); 547 netif_stop_queue(dev);
@@ -668,8 +673,8 @@ static void ether_init_rx_desc_ring(struct mv643xx_private *mp)
668 673
669 mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc); 674 mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc);
670 675
671 /* Add the queue to the list of RX queues of this port */ 676 /* Enable queue 0 for this port */
672 mp->port_rx_queue_command |= 1; 677 mp->port_rx_queue_command = 1;
673} 678}
674 679
675/* 680/*
@@ -715,8 +720,8 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
715 720
716 mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc); 721 mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc);
717 722
718 /* Add the queue to the list of Tx queues of this port */ 723 /* Enable queue 0 for this port */
719 mp->port_tx_queue_command |= 1; 724 mp->port_tx_queue_command = 1;
720} 725}
721 726
722/* 727/*
@@ -747,9 +752,6 @@ static int mv643xx_eth_open(struct net_device *dev)
747 return -EAGAIN; 752 return -EAGAIN;
748 } 753 }
749 754
750 /* Stop RX Queues */
751 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
752
753 eth_port_init(mp); 755 eth_port_init(mp);
754 756
755 INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev); 757 INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev);
@@ -877,7 +879,7 @@ static void mv643xx_eth_free_tx_rings(struct net_device *dev)
877 struct sk_buff *skb; 879 struct sk_buff *skb;
878 880
879 /* Stop Tx Queues */ 881 /* Stop Tx Queues */
880 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00); 882 mv643xx_eth_port_disable_tx(port_num);
881 883
882 /* Free outstanding skb's on TX rings */ 884 /* Free outstanding skb's on TX rings */
883 for (curr = 0; mp->tx_desc_count && curr < mp->tx_ring_size; curr++) { 885 for (curr = 0; mp->tx_desc_count && curr < mp->tx_ring_size; curr++) {
@@ -907,7 +909,7 @@ static void mv643xx_eth_free_rx_rings(struct net_device *dev)
907 int curr; 909 int curr;
908 910
909 /* Stop RX Queues */ 911 /* Stop RX Queues */
910 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); 912 mv643xx_eth_port_disable_rx(port_num);
911 913
912 /* Free preallocated skb's on RX rings */ 914 /* Free preallocated skb's on RX rings */
913 for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { 915 for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) {
@@ -1719,13 +1721,6 @@ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
1719 * return_info Tx/Rx user resource return information. 1721 * return_info Tx/Rx user resource return information.
1720 */ 1722 */
1721 1723
1722/* defines */
1723/* SDMA command macros */
1724#define ETH_ENABLE_TX_QUEUE(eth_port) \
1725 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1)
1726
1727/* locals */
1728
1729/* PHY routines */ 1724/* PHY routines */
1730static int ethernet_phy_get(unsigned int eth_port_num); 1725static int ethernet_phy_get(unsigned int eth_port_num);
1731static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); 1726static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
@@ -1759,9 +1754,6 @@ static void eth_port_set_filter_table_entry(int table, unsigned char entry);
1759 */ 1754 */
1760static void eth_port_init(struct mv643xx_private *mp) 1755static void eth_port_init(struct mv643xx_private *mp)
1761{ 1756{
1762 mp->port_rx_queue_command = 0;
1763 mp->port_tx_queue_command = 0;
1764
1765 mp->rx_resource_err = 0; 1757 mp->rx_resource_err = 0;
1766 mp->tx_resource_err = 0; 1758 mp->tx_resource_err = 0;
1767 1759
@@ -1842,8 +1834,7 @@ static void eth_port_start(struct net_device *dev)
1842 mp->port_sdma_config); 1834 mp->port_sdma_config);
1843 1835
1844 /* Enable port Rx. */ 1836 /* Enable port Rx. */
1845 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 1837 mv643xx_eth_port_enable_rx(port_num, mp->port_rx_queue_command);
1846 mp->port_rx_queue_command);
1847 1838
1848 /* Disable port bandwidth limits by clearing MTU register */ 1839 /* Disable port bandwidth limits by clearing MTU register */
1849 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0); 1840 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
@@ -2320,6 +2311,67 @@ static void ethernet_phy_reset(unsigned int eth_port_num)
2320 eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data); 2311 eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data);
2321} 2312}
2322 2313
2314static void mv643xx_eth_port_enable_tx(unsigned int port_num,
2315 unsigned int channels)
2316{
2317 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), channels);
2318}
2319
2320static void mv643xx_eth_port_enable_rx(unsigned int port_num,
2321 unsigned int channels)
2322{
2323 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), channels);
2324}
2325
2326static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num)
2327{
2328 u32 channels;
2329
2330 /* Stop Tx port activity. Check port Tx activity. */
2331 channels = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
2332 & 0xFF;
2333 if (channels) {
2334 /* Issue stop command for active channels only */
2335 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num),
2336 (channels << 8));
2337
2338 /* Wait for all Tx activity to terminate. */
2339 /* Check port cause register that all Tx queues are stopped */
2340 while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
2341 & 0xFF)
2342 udelay(PHY_WAIT_MICRO_SECONDS);
2343
2344 /* Wait for Tx FIFO to empty */
2345 while (mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)) &
2346 ETH_PORT_TX_FIFO_EMPTY)
2347 udelay(PHY_WAIT_MICRO_SECONDS);
2348 }
2349
2350 return channels;
2351}
2352
2353static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num)
2354{
2355 u32 channels;
2356
2357 /* Stop Rx port activity. Check port Rx activity. */
2358 channels = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)
2359 & 0xFF);
2360 if (channels) {
2361 /* Issue stop command for active channels only */
2362 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
2363 (channels << 8));
2364
2365 /* Wait for all Rx activity to terminate. */
2366 /* Check port cause register that all Rx queues are stopped */
2367 while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num))
2368 & 0xFF)
2369 udelay(PHY_WAIT_MICRO_SECONDS);
2370 }
2371
2372 return channels;
2373}
2374
2323/* 2375/*
2324 * eth_port_reset - Reset Ethernet port 2376 * eth_port_reset - Reset Ethernet port
2325 * 2377 *
@@ -2342,35 +2394,8 @@ static void eth_port_reset(unsigned int port_num)
2342{ 2394{
2343 unsigned int reg_data; 2395 unsigned int reg_data;
2344 2396
2345 /* Stop Tx port activity. Check port Tx activity. */ 2397 mv643xx_eth_port_disable_tx(port_num);
2346 reg_data = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)); 2398 mv643xx_eth_port_disable_rx(port_num);
2347
2348 if (reg_data & 0xFF) {
2349 /* Issue stop command for active channels only */
2350 mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num),
2351 (reg_data << 8));
2352
2353 /* Wait for all Tx activity to terminate. */
2354 /* Check port cause register that all Tx queues are stopped */
2355 while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
2356 & 0xFF)
2357 udelay(10);
2358 }
2359
2360 /* Stop Rx port activity. Check port Rx activity. */
2361 reg_data = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num));
2362
2363 if (reg_data & 0xFF) {
2364 /* Issue stop command for active channels only */
2365 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
2366 (reg_data << 8));
2367
2368 /* Wait for all Rx activity to terminate. */
2369 /* Check port cause register that all Rx queues are stopped */
2370 while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num))
2371 & 0xFF)
2372 udelay(10);
2373 }
2374 2399
2375 /* Clear all MIB counters */ 2400 /* Clear all MIB counters */
2376 eth_clear_mib_counters(port_num); 2401 eth_clear_mib_counters(port_num);
@@ -2599,7 +2624,7 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2599 first_descriptor->cmd_sts = mp->tx_first_command; 2624 first_descriptor->cmd_sts = mp->tx_first_command;
2600 2625
2601 wmb(); 2626 wmb();
2602 ETH_ENABLE_TX_QUEUE(mp->port_num); 2627 mv643xx_eth_port_enable_tx(mp->port_num, mp->port_tx_queue_command);
2603 2628
2604 /* 2629 /*
2605 * Finish Tx packet. Update first desc in case of Tx resource 2630 * Finish Tx packet. Update first desc in case of Tx resource
@@ -2652,7 +2677,7 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2652 ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT; 2677 ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
2653 2678
2654 wmb(); 2679 wmb();
2655 ETH_ENABLE_TX_QUEUE(mp->port_num); 2680 mv643xx_eth_port_enable_tx(mp->port_num, mp->port_tx_queue_command);
2656 2681
2657 /* Finish Tx packet. Update first desc in case of Tx resource error */ 2682 /* Finish Tx packet. Update first desc in case of Tx resource error */
2658 tx_desc_curr = (tx_desc_curr + 1) % mp->tx_ring_size; 2683 tx_desc_curr = (tx_desc_curr + 1) % mp->tx_ring_size;