Commit b3ea38cb authored by Raghavendra Koushik's avatar Raghavendra Koushik Committed by Jeff Garzik

[PATCH] S2io: optimizations

1. Definitions of LOW and PANIC levels of the Rx buffers have changed.

2. In wait_for_cmd_complete there is no longer a writeq but just a
read and wait for strobe bit to reset.

3. In s2io_isr, the isr_lock has been done away with also the NICs
interrupt are no longer disabled explicitly on entering the interrupt
handler and re-enabled again before leaving it.

4. Also clearing the semaphore "tasklet_status" when exiting
erroneously from s2io_isr after failing fill_rx_buffer call.

5. The set/reset Tx Csum function through ethtool was added to the
ethtool_ops structure.

6. Added a Rx side error code in the rx_osm_handler function.

7. No longer stopping and waking Tx queue when link state changes in
s2io_link function.

8. removed the isr_lock spinlock from the s2io_nic structure.

9. changed parameters which determine thresholds(LOW and PANIC)
to replenish Rx buffers.
   This has been found to result in better performance.
Signed-off-by: default avatarRaghavendra Koushik <raghavendra.koushik@s2io.com>
Signed-off-by: default avatarRavinandan Arakali <ravinandan.arakali@s2io.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 10a7bfef
...@@ -80,11 +80,12 @@ static char s2io_driver_version[] = "Version 1.7.5.1"; ...@@ -80,11 +80,12 @@ static char s2io_driver_version[] = "Version 1.7.5.1";
static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring)
{ {
int level = 0; int level = 0;
if ((sp->pkt_cnt[ring] - rxb_size) > 128) { if ((sp->pkt_cnt[ring] - rxb_size) > 16) {
level = LOW; level = LOW;
if (rxb_size < sp->pkt_cnt[ring] / 8) if ((sp->pkt_cnt[ring] - rxb_size) < MAX_RXDS_PER_BLOCK) {
level = PANIC; level = PANIC;
} }
}
return level; return level;
} }
...@@ -1916,12 +1917,8 @@ int wait_for_cmd_complete(nic_t * sp) ...@@ -1916,12 +1917,8 @@ int wait_for_cmd_complete(nic_t * sp)
u64 val64; u64 val64;
while (TRUE) { while (TRUE) {
val64 =
RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD
| RMAC_ADDR_CMD_MEM_OFFSET(0);
writeq(val64, &bar0->rmac_addr_cmd_mem);
val64 = readq(&bar0->rmac_addr_cmd_mem); val64 = readq(&bar0->rmac_addr_cmd_mem);
if (!val64) { if (!(val64 & RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) {
ret = SUCCESS; ret = SUCCESS;
break; break;
} }
...@@ -2192,14 +2189,11 @@ int s2io_close(struct net_device *dev) ...@@ -2192,14 +2189,11 @@ int s2io_close(struct net_device *dev)
register u64 val64 = 0; register u64 val64 = 0;
u16 cnt = 0; u16 cnt = 0;
spin_lock(&sp->isr_lock);
netif_stop_queue(dev); netif_stop_queue(dev);
/* disable Tx and Rx traffic on the NIC */ /* disable Tx and Rx traffic on the NIC */
stop_nic(sp); stop_nic(sp);
spin_unlock(&sp->isr_lock);
/* /*
* If the device tasklet is running, wait till its done * If the device tasklet is running, wait till its done
* before killing it * before killing it
...@@ -2398,15 +2392,13 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2398,15 +2392,13 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
struct net_device *dev = (struct net_device *) dev_id; struct net_device *dev = (struct net_device *) dev_id;
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
u64 reason = 0, general_mask = 0; u64 reason = 0;
mac_info_t *mac_control; mac_info_t *mac_control;
struct config_param *config; struct config_param *config;
mac_control = &sp->mac_control; mac_control = &sp->mac_control;
config = &sp->config; config = &sp->config;
spin_lock(&sp->isr_lock);
/* /*
* Identify the cause for interrupt and call the appropriate * Identify the cause for interrupt and call the appropriate
* interrupt handler. Causes for the interrupt could be; * interrupt handler. Causes for the interrupt could be;
...@@ -2419,14 +2411,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2419,14 +2411,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
if (!reason) { if (!reason) {
/* The interrupt was not raised by Xena. */ /* The interrupt was not raised by Xena. */
spin_unlock(&sp->isr_lock);
return IRQ_NONE; return IRQ_NONE;
} }
/* Mask the Interrupts on the NIC. */
general_mask = readq(&bar0->general_int_mask);
writeq(0xFFFFFFFFFFFFFFFFULL, &bar0->general_int_mask);
/* If Intr is because of Tx Traffic */ /* If Intr is because of Tx Traffic */
if (reason & GEN_INTR_TXTRAFFIC) { if (reason & GEN_INTR_TXTRAFFIC) {
tx_intr_handler(sp); tx_intr_handler(sp);
...@@ -2441,11 +2428,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2441,11 +2428,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
if (netif_rx_schedule_prep(dev)) { if (netif_rx_schedule_prep(dev)) {
en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR, en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR,
DISABLE_INTRS); DISABLE_INTRS);
/*
* Here we take a snap shot of the general
* Intr Register.
*/
general_mask = readq(&bar0->general_int_mask);
__netif_rx_schedule(dev); __netif_rx_schedule(dev);
} }
} }
...@@ -2481,9 +2463,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2481,9 +2463,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
"%s:Out of memory", "%s:Out of memory",
dev->name); dev->name);
DBG_PRINT(ERR_DBG, " in ISR!!\n"); DBG_PRINT(ERR_DBG, " in ISR!!\n");
writeq(general_mask, clear_bit(0,
&bar0->general_int_mask); (unsigned long *) (&sp->
spin_unlock(&sp->isr_lock); tasklet_status));
return IRQ_HANDLED; return IRQ_HANDLED;
} }
clear_bit(0, clear_bit(0,
...@@ -2501,10 +2483,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2501,10 +2483,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
tasklet_schedule(&sp->task); tasklet_schedule(&sp->task);
#endif #endif
/* Unmask all previously enabled interrupts on the NIC. */
writeq(general_mask, &bar0->general_int_mask);
spin_unlock(&sp->isr_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -3626,6 +3604,17 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev) ...@@ -3626,6 +3604,17 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
return (S2IO_STAT_LEN); return (S2IO_STAT_LEN);
} }
int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
{
if (data)
dev->features |= NETIF_F_IP_CSUM;
else
dev->features &= ~NETIF_F_IP_CSUM;
return 0;
}
static struct ethtool_ops netdev_ethtool_ops = { static struct ethtool_ops netdev_ethtool_ops = {
.get_settings = s2io_ethtool_gset, .get_settings = s2io_ethtool_gset,
.set_settings = s2io_ethtool_sset, .set_settings = s2io_ethtool_sset,
...@@ -3641,7 +3630,7 @@ static struct ethtool_ops netdev_ethtool_ops = { ...@@ -3641,7 +3630,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
.get_rx_csum = s2io_ethtool_get_rx_csum, .get_rx_csum = s2io_ethtool_get_rx_csum,
.set_rx_csum = s2io_ethtool_set_rx_csum, .set_rx_csum = s2io_ethtool_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum, .get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum, .set_tx_csum = s2io_ethtool_op_set_tx_csum,
.get_sg = ethtool_op_get_sg, .get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg, .set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
...@@ -3902,6 +3891,12 @@ static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) ...@@ -3902,6 +3891,12 @@ static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no)
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
} }
if (rxdp->Control_1 & RXD_T_CODE) {
unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n",
dev->name, err);
}
skb->dev = dev; skb->dev = dev;
skb_put(skb, len); skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
...@@ -3922,25 +3917,6 @@ static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) ...@@ -3922,25 +3917,6 @@ static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no)
return SUCCESS; return SUCCESS;
} }
int check_for_tx_space(nic_t * sp)
{
u32 put_off, get_off, queue_len;
int ret = TRUE, i;
for (i = 0; i < sp->config.tx_fifo_num; i++) {
queue_len = sp->mac_control.tx_curr_put_info[i].fifo_len
+ 1;
put_off = sp->mac_control.tx_curr_put_info[i].offset;
get_off = sp->mac_control.tx_curr_get_info[i].offset;
if (((put_off + 1) % queue_len) == get_off) {
ret = FALSE;
break;
}
}
return ret;
}
/** /**
* s2io_link - stops/starts the Tx queue. * s2io_link - stops/starts the Tx queue.
* @sp : private member of the device structure, which is a pointer to the * @sp : private member of the device structure, which is a pointer to the
...@@ -3962,17 +3938,9 @@ void s2io_link(nic_t * sp, int link) ...@@ -3962,17 +3938,9 @@ void s2io_link(nic_t * sp, int link)
if (link == LINK_DOWN) { if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
netif_carrier_off(dev); netif_carrier_off(dev);
netif_stop_queue(dev);
} else { } else {
DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name); DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
netif_carrier_on(dev); netif_carrier_on(dev);
if (check_for_tx_space(sp) == TRUE) {
/*
* Dont wake the queue if we know there
* are no free TxDs available.
*/
netif_wake_queue(dev);
}
} }
} }
sp->last_link_state = link; sp->last_link_state = link;
...@@ -4357,7 +4325,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) ...@@ -4357,7 +4325,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Initialize spinlocks */ /* Initialize spinlocks */
spin_lock_init(&sp->tx_lock); spin_lock_init(&sp->tx_lock);
spin_lock_init(&sp->isr_lock);
/* /*
* SXE-002: Configure link and activity LED to init state * SXE-002: Configure link and activity LED to init state
......
...@@ -612,7 +612,6 @@ typedef struct s2io_nic { ...@@ -612,7 +612,6 @@ typedef struct s2io_nic {
atomic_t rx_bufs_left[MAX_RX_RINGS]; atomic_t rx_bufs_left[MAX_RX_RINGS];
spinlock_t tx_lock; spinlock_t tx_lock;
spinlock_t isr_lock;
#define PROMISC 1 #define PROMISC 1
#define ALL_MULTI 2 #define ALL_MULTI 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment