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";
static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring)
{
int level = 0;
if ((sp->pkt_cnt[ring] - rxb_size) > 128) {
if ((sp->pkt_cnt[ring] - rxb_size) > 16) {
level = LOW;
if (rxb_size < sp->pkt_cnt[ring] / 8)
if ((sp->pkt_cnt[ring] - rxb_size) < MAX_RXDS_PER_BLOCK) {
level = PANIC;
}
}
return level;
}
......@@ -1916,12 +1917,8 @@ int wait_for_cmd_complete(nic_t * sp)
u64 val64;
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);
if (!val64) {
if (!(val64 & RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) {
ret = SUCCESS;
break;
}
......@@ -2192,14 +2189,11 @@ int s2io_close(struct net_device *dev)
register u64 val64 = 0;
u16 cnt = 0;
spin_lock(&sp->isr_lock);
netif_stop_queue(dev);
/* disable Tx and Rx traffic on the NIC */
stop_nic(sp);
spin_unlock(&sp->isr_lock);
/*
* If the device tasklet is running, wait till its done
* before killing it
......@@ -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;
nic_t *sp = dev->priv;
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;
struct config_param *config;
mac_control = &sp->mac_control;
config = &sp->config;
spin_lock(&sp->isr_lock);
/*
* Identify the cause for interrupt and call the appropriate
* 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)
if (!reason) {
/* The interrupt was not raised by Xena. */
spin_unlock(&sp->isr_lock);
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 (reason & GEN_INTR_TXTRAFFIC) {
tx_intr_handler(sp);
......@@ -2441,11 +2428,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
if (netif_rx_schedule_prep(dev)) {
en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR,
DISABLE_INTRS);
/*
* Here we take a snap shot of the general
* Intr Register.
*/
general_mask = readq(&bar0->general_int_mask);
__netif_rx_schedule(dev);
}
}
......@@ -2481,9 +2463,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
"%s:Out of memory",
dev->name);
DBG_PRINT(ERR_DBG, " in ISR!!\n");
writeq(general_mask,
&bar0->general_int_mask);
spin_unlock(&sp->isr_lock);
clear_bit(0,
(unsigned long *) (&sp->
tasklet_status));
return IRQ_HANDLED;
}
clear_bit(0,
......@@ -2501,10 +2483,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
tasklet_schedule(&sp->task);
#endif
/* Unmask all previously enabled interrupts on the NIC. */
writeq(general_mask, &bar0->general_int_mask);
spin_unlock(&sp->isr_lock);
return IRQ_HANDLED;
}
......@@ -3626,6 +3604,17 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
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 = {
.get_settings = s2io_ethtool_gset,
.set_settings = s2io_ethtool_sset,
......@@ -3641,7 +3630,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
.get_rx_csum = s2io_ethtool_get_rx_csum,
.set_rx_csum = s2io_ethtool_set_rx_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,
.set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO
......@@ -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;
}
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_put(skb, len);
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)
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.
* @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)
if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
netif_carrier_off(dev);
netif_stop_queue(dev);
} else {
DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
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;
......@@ -4357,7 +4325,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Initialize spinlocks */
spin_lock_init(&sp->tx_lock);
spin_lock_init(&sp->isr_lock);
/*
* SXE-002: Configure link and activity LED to init state
......
......@@ -612,7 +612,6 @@ typedef struct s2io_nic {
atomic_t rx_bufs_left[MAX_RX_RINGS];
spinlock_t tx_lock;
spinlock_t isr_lock;
#define PROMISC 1
#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