aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorraghavendra.koushik@neterion.com <raghavendra.koushik@neterion.com>2005-08-03 15:32:00 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-11 00:10:44 -0400
commitfe113638328995b69d8797e6466b29661b1602d1 (patch)
treee9ebbbcd7ac3fce17c9f39e2cf1eca1ae209bae7
parent1ddc50d40a19b3524d302d1d6bfd52ac7bc6b6f7 (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>
-rw-r--r--drivers/net/s2io.c46
-rw-r--r--drivers/net/s2io.h5
2 files changed, 24 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)
2312static void tx_intr_handler(fifo_info_t *fifo_data) 2301static 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 }
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 69dd0e51dda0..ce9bf6d5ee00 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -13,6 +13,11 @@
13#ifndef _S2IO_H 13#ifndef _S2IO_H
14#define _S2IO_H 14#define _S2IO_H
15 15
16/* Enable 2 buffer mode by default for SGI system */
17#ifdef CONFIG_IA64_SGI_SN2
18#define CONFIG_2BUFF_MODE
19#endif
20
16#define TBD 0 21#define TBD 0
17#define BIT(loc) (0x8000000000000000ULL >> (loc)) 22#define BIT(loc) (0x8000000000000000ULL >> (loc))
18#define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) 23#define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz))