diff options
| author | Dale Farnsworth <dale@farnsworth.org> | 2006-01-27 03:10:47 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-27 11:11:16 -0500 |
| commit | 9f8dd319459bb5ab9efcc1c345bed7895cc41768 (patch) | |
| tree | 017ea7b2ca60f29110b8e43afbd6560737824489 | |
| parent | f98e36f1f7903a319f7f87f96490e88f691ea106 (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.c | 133 |
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); | |||
| 83 | static void eth_port_uc_addr_get(struct net_device *dev, | 83 | static void eth_port_uc_addr_get(struct net_device *dev, |
| 84 | unsigned char *MacAddr); | 84 | unsigned char *MacAddr); |
| 85 | static void eth_port_set_multicast_list(struct net_device *); | 85 | static void eth_port_set_multicast_list(struct net_device *); |
| 86 | static void mv643xx_eth_port_enable_tx(unsigned int port_num, | ||
| 87 | unsigned int channels); | ||
| 88 | static void mv643xx_eth_port_enable_rx(unsigned int port_num, | ||
| 89 | unsigned int channels); | ||
| 90 | static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num); | ||
| 91 | static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num); | ||
| 86 | static int mv643xx_eth_open(struct net_device *); | 92 | static int mv643xx_eth_open(struct net_device *); |
| 87 | static int mv643xx_eth_stop(struct net_device *); | 93 | static int mv643xx_eth_stop(struct net_device *); |
| 88 | static int mv643xx_eth_change_mtu(struct net_device *, int); | 94 | static 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 */ |
| 1730 | static int ethernet_phy_get(unsigned int eth_port_num); | 1725 | static int ethernet_phy_get(unsigned int eth_port_num); |
| 1731 | static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); | 1726 | static 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 | */ |
| 1760 | static void eth_port_init(struct mv643xx_private *mp) | 1755 | static 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 | ||
| 2314 | static 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 | |||
| 2320 | static 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 | |||
| 2326 | static 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 | |||
| 2353 | static 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; |
