diff options
author | raghavendra.koushik@neterion.com <raghavendra.koushik@neterion.com> | 2005-08-03 15:32:00 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-11 00:10:44 -0400 |
commit | fe113638328995b69d8797e6466b29661b1602d1 (patch) | |
tree | e9ebbbcd7ac3fce17c9f39e2cf1eca1ae209bae7 /drivers/net/s2io.c | |
parent | 1ddc50d40a19b3524d302d1d6bfd52ac7bc6b6f7 (diff) |
[PATCH] S2io: Performance improvements
Hi,
This patch relates to mostly performance related changes.
1. Fixed incorrect computation of PANIC level in rx_buffer_level().
2. Removed unnecessary PIOs(read/write of tx_traffic_int and
rx_traffic_int) from interrupt handler and removed read of
general_int_status register from xmit routine.
3. Enable two-buffer mode(for Rx path) automatically for SGI
systems. This improves Rx performance dramatically on
SGI systems.
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 6668b99025c8..28d6d3746c80 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -100,8 +100,7 @@ static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) | |||
100 | mac_control = &sp->mac_control; | 100 | mac_control = &sp->mac_control; |
101 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { | 101 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { |
102 | level = LOW; | 102 | level = LOW; |
103 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) < | 103 | if (rxb_size <= MAX_RXDS_PER_BLOCK) { |
104 | MAX_RXDS_PER_BLOCK) { | ||
105 | level = PANIC; | 104 | level = PANIC; |
106 | } | 105 | } |
107 | } | 106 | } |
@@ -2193,7 +2192,6 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2193 | { | 2192 | { |
2194 | nic_t *nic = ring_data->nic; | 2193 | nic_t *nic = ring_data->nic; |
2195 | struct net_device *dev = (struct net_device *) nic->dev; | 2194 | struct net_device *dev = (struct net_device *) nic->dev; |
2196 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | ||
2197 | int get_block, get_offset, put_block, put_offset, ring_bufs; | 2195 | int get_block, get_offset, put_block, put_offset, ring_bufs; |
2198 | rx_curr_get_info_t get_info, put_info; | 2196 | rx_curr_get_info_t get_info, put_info; |
2199 | RxD_t *rxdp; | 2197 | RxD_t *rxdp; |
@@ -2201,8 +2199,6 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2201 | #ifndef CONFIG_S2IO_NAPI | 2199 | #ifndef CONFIG_S2IO_NAPI |
2202 | int pkt_cnt = 0; | 2200 | int pkt_cnt = 0; |
2203 | #endif | 2201 | #endif |
2204 | register u64 val64; | ||
2205 | |||
2206 | spin_lock(&nic->rx_lock); | 2202 | spin_lock(&nic->rx_lock); |
2207 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | 2203 | if (atomic_read(&nic->card_state) == CARD_DOWN) { |
2208 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", | 2204 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", |
@@ -2210,13 +2206,6 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2210 | spin_unlock(&nic->rx_lock); | 2206 | spin_unlock(&nic->rx_lock); |
2211 | } | 2207 | } |
2212 | 2208 | ||
2213 | /* | ||
2214 | * rx_traffic_int reg is an R1 register, hence we read and write | ||
2215 | * back the same value in the register to clear it | ||
2216 | */ | ||
2217 | val64 = readq(&bar0->tx_traffic_int); | ||
2218 | writeq(val64, &bar0->tx_traffic_int); | ||
2219 | |||
2220 | get_info = ring_data->rx_curr_get_info; | 2209 | get_info = ring_data->rx_curr_get_info; |
2221 | get_block = get_info.block_index; | 2210 | get_block = get_info.block_index; |
2222 | put_info = ring_data->rx_curr_put_info; | 2211 | put_info = ring_data->rx_curr_put_info; |
@@ -2312,20 +2301,11 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2312 | static void tx_intr_handler(fifo_info_t *fifo_data) | 2301 | static void tx_intr_handler(fifo_info_t *fifo_data) |
2313 | { | 2302 | { |
2314 | nic_t *nic = fifo_data->nic; | 2303 | nic_t *nic = fifo_data->nic; |
2315 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | ||
2316 | struct net_device *dev = (struct net_device *) nic->dev; | 2304 | struct net_device *dev = (struct net_device *) nic->dev; |
2317 | tx_curr_get_info_t get_info, put_info; | 2305 | tx_curr_get_info_t get_info, put_info; |
2318 | struct sk_buff *skb; | 2306 | struct sk_buff *skb; |
2319 | TxD_t *txdlp; | 2307 | TxD_t *txdlp; |
2320 | u16 j, frg_cnt; | 2308 | u16 j, frg_cnt; |
2321 | register u64 val64 = 0; | ||
2322 | |||
2323 | /* | ||
2324 | * tx_traffic_int reg is an R1 register, hence we read and write | ||
2325 | * back the same value in the register to clear it | ||
2326 | */ | ||
2327 | val64 = readq(&bar0->tx_traffic_int); | ||
2328 | writeq(val64, &bar0->tx_traffic_int); | ||
2329 | 2309 | ||
2330 | get_info = fifo_data->tx_curr_get_info; | 2310 | get_info = fifo_data->tx_curr_get_info; |
2331 | put_info = fifo_data->tx_curr_put_info; | 2311 | put_info = fifo_data->tx_curr_put_info; |
@@ -2818,7 +2798,6 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2818 | #endif | 2798 | #endif |
2819 | mac_info_t *mac_control; | 2799 | mac_info_t *mac_control; |
2820 | struct config_param *config; | 2800 | struct config_param *config; |
2821 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
2822 | 2801 | ||
2823 | mac_control = &sp->mac_control; | 2802 | mac_control = &sp->mac_control; |
2824 | config = &sp->config; | 2803 | config = &sp->config; |
@@ -2870,7 +2849,6 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2870 | } | 2849 | } |
2871 | 2850 | ||
2872 | txdp->Control_2 |= config->tx_intr_type; | 2851 | txdp->Control_2 |= config->tx_intr_type; |
2873 | |||
2874 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | | 2852 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | |
2875 | TXD_GATHER_CODE_FIRST); | 2853 | TXD_GATHER_CODE_FIRST); |
2876 | txdp->Control_1 |= TXD_LIST_OWN_XENA; | 2854 | txdp->Control_1 |= TXD_LIST_OWN_XENA; |
@@ -2890,6 +2868,8 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2890 | val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr; | 2868 | val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr; |
2891 | writeq(val64, &tx_fifo->TxDL_Pointer); | 2869 | writeq(val64, &tx_fifo->TxDL_Pointer); |
2892 | 2870 | ||
2871 | wmb(); | ||
2872 | |||
2893 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 2873 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
2894 | TX_FIFO_LAST_LIST); | 2874 | TX_FIFO_LAST_LIST); |
2895 | 2875 | ||
@@ -2899,9 +2879,6 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2899 | #endif | 2879 | #endif |
2900 | writeq(val64, &tx_fifo->List_Control); | 2880 | writeq(val64, &tx_fifo->List_Control); |
2901 | 2881 | ||
2902 | /* Perform a PCI read to flush previous writes */ | ||
2903 | val64 = readq(&bar0->general_int_status); | ||
2904 | |||
2905 | put_off++; | 2882 | put_off++; |
2906 | put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | 2883 | put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; |
2907 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; | 2884 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; |
@@ -2940,7 +2917,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2940 | nic_t *sp = dev->priv; | 2917 | nic_t *sp = dev->priv; |
2941 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2918 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2942 | int i; | 2919 | int i; |
2943 | u64 reason = 0; | 2920 | u64 reason = 0, val64; |
2944 | mac_info_t *mac_control; | 2921 | mac_info_t *mac_control; |
2945 | struct config_param *config; | 2922 | struct config_param *config; |
2946 | 2923 | ||
@@ -2978,6 +2955,13 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2978 | #else | 2955 | #else |
2979 | /* If Intr is because of Rx Traffic */ | 2956 | /* If Intr is because of Rx Traffic */ |
2980 | if (reason & GEN_INTR_RXTRAFFIC) { | 2957 | if (reason & GEN_INTR_RXTRAFFIC) { |
2958 | /* | ||
2959 | * rx_traffic_int reg is an R1 register, writing all 1's | ||
2960 | * will ensure that the actual interrupt causing bit get's | ||
2961 | * cleared and hence a read can be avoided. | ||
2962 | */ | ||
2963 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
2964 | writeq(val64, &bar0->rx_traffic_int); | ||
2981 | for (i = 0; i < config->rx_ring_num; i++) { | 2965 | for (i = 0; i < config->rx_ring_num; i++) { |
2982 | rx_intr_handler(&mac_control->rings[i]); | 2966 | rx_intr_handler(&mac_control->rings[i]); |
2983 | } | 2967 | } |
@@ -2986,6 +2970,14 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2986 | 2970 | ||
2987 | /* If Intr is because of Tx Traffic */ | 2971 | /* If Intr is because of Tx Traffic */ |
2988 | if (reason & GEN_INTR_TXTRAFFIC) { | 2972 | if (reason & GEN_INTR_TXTRAFFIC) { |
2973 | /* | ||
2974 | * tx_traffic_int reg is an R1 register, writing all 1's | ||
2975 | * will ensure that the actual interrupt causing bit get's | ||
2976 | * cleared and hence a read can be avoided. | ||
2977 | */ | ||
2978 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
2979 | writeq(val64, &bar0->tx_traffic_int); | ||
2980 | |||
2989 | for (i = 0; i < config->tx_fifo_num; i++) | 2981 | for (i = 0; i < config->tx_fifo_num; i++) |
2990 | tx_intr_handler(&mac_control->fifos[i]); | 2982 | tx_intr_handler(&mac_control->fifos[i]); |
2991 | } | 2983 | } |