Skip to content

Commit

Permalink
netxen: napi and irq cleanup
Browse files Browse the repository at this point in the history
o separate and simpler irq handler for msi interrupts, avoids few checks
  than legacy mode.
o avoid redudant tx_has_work() and rx_has_work() checks in interrupt
  and napi, which can uncork irq based on racy (lockless) access to tx
  and rx ring indices. If we get interrupt, there's sufficient reason to
  schedule napi.
o replenish rx ring more often, remove self-imposed threshold rcv_free
  that prevents posting rx desc to card. This improves performance in
  low memory.

Signed-off-by: Dhananjay Phadke <[email protected]>
Tested-by: Vernon Mauery <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
  • Loading branch information
Dhananjay Phadke authored and Jeff Garzik committed Mar 26, 2008
1 parent 443be79 commit 05aaa02
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 163 deletions.
5 changes: 1 addition & 4 deletions drivers/net/netxen/netxen_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,6 @@ struct netxen_rcv_desc_ctx {
u32 flags;
u32 producer;
u32 rcv_pending; /* Num of bufs posted in phantom */
u32 rcv_free; /* Num of bufs in free list */
dma_addr_t phys_addr;
struct pci_dev *phys_pdev;
struct rcv_desc *desc_head; /* address of rx ring in Phantom */
Expand Down Expand Up @@ -1076,12 +1075,10 @@ void netxen_tso_check(struct netxen_adapter *adapter,
struct cmd_desc_type0 *desc, struct sk_buff *skb);
int netxen_nic_hw_resources(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
u32 ringid);
int netxen_process_cmd_ring(unsigned long data);
int netxen_process_cmd_ring(struct netxen_adapter *adapter);
u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
void netxen_nic_set_multi(struct net_device *netdev);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
Expand Down
76 changes: 4 additions & 72 deletions drivers/net/netxen/netxen_nic_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
struct netxen_rx_buffer *rx_buf;
rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
rcv_desc->begin_alloc = 0;
rx_buf = rcv_desc->rx_buf_arr;
num_rx_bufs = rcv_desc->max_rx_desc_count;
Expand Down Expand Up @@ -976,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
return 0;
}

int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
{
int ctx;

for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
struct netxen_recv_context *recv_ctx =
&(adapter->recv_ctx[ctx]);
u32 consumer;
struct status_desc *desc_head;
struct status_desc *desc;

consumer = recv_ctx->status_rx_consumer;
desc_head = recv_ctx->rcv_status_desc_head;
desc = &desc_head[consumer];

if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)
return 1;
}

return 0;
}

static int netxen_nic_check_temp(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
Expand Down Expand Up @@ -1040,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)

void netxen_watchdog_task(struct work_struct *work)
{
struct net_device *netdev;
struct netxen_adapter *adapter =
container_of(work, struct netxen_adapter, watchdog_task);

Expand All @@ -1050,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work)
if (adapter->handle_phy_intr)
adapter->handle_phy_intr(adapter);

netdev = adapter->netdev;
if ((netif_running(netdev)) && !netif_carrier_ok(netdev) &&
netxen_nic_link_ok(adapter) ) {
printk(KERN_INFO "%s %s (port %d), Link is up\n",
netxen_nic_driver_name, netdev->name, adapter->portnum);
netif_carrier_on(netdev);
netif_wake_queue(netdev);
} else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) {
printk(KERN_ERR "%s %s Link is Down\n",
netxen_nic_driver_name, netdev->name);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}

mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}

Expand Down Expand Up @@ -1177,7 +1139,6 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,

netdev->last_rx = jiffies;

rcv_desc->rcv_free++;
rcv_desc->rcv_pending--;

/*
Expand All @@ -1202,13 +1163,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
u32 producer = 0;
int count = 0, ring;

DPRINTK(INFO, "procesing receive\n");
/*
* we assume in this case that there is only one port and that is
* port #1...changes need to be done in firmware to indicate port
* number as part of the descriptor. This way we will be able to get
* the netdev which is associated with that device.
*/
while (count < max) {
desc = &desc_head[consumer];
if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
Expand All @@ -1221,10 +1175,8 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
count++;
}
if (count) {
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
}
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
}

/* update the consumer index in phantom */
Expand All @@ -1235,20 +1187,18 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
/* Window = 1 */
writel(consumer,
NETXEN_CRB_NORMALIZE(adapter,
recv_crb_registers[adapter->portnum].
recv_crb_registers[adapter->portnum].
crb_rcv_status_consumer));
wmb();
}

return count;
}

/* Process Command status ring */
int netxen_process_cmd_ring(unsigned long data)
int netxen_process_cmd_ring(struct netxen_adapter *adapter)
{
u32 last_consumer;
u32 consumer;
struct netxen_adapter *adapter = (struct netxen_adapter *)data;
int count1 = 0;
int count2 = 0;
struct netxen_cmd_buffer *buffer;
Expand Down Expand Up @@ -1435,8 +1385,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
rcv_desc->begin_alloc = index;
rcv_desc->rcv_pending += count;
rcv_desc->producer = producer;
if (rcv_desc->rcv_free >= 32) {
rcv_desc->rcv_free = 0;
/* Window = 1 */
writel((producer - 1) &
(rcv_desc->max_rx_desc_count - 1),
Expand All @@ -1460,8 +1408,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
writel(msg,
DB_NORMALIZE(adapter,
NETXEN_RCV_PRODUCER_OFFSET));
wmb();
}
}
}

Expand Down Expand Up @@ -1525,8 +1471,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
rcv_desc->begin_alloc = index;
rcv_desc->rcv_pending += count;
rcv_desc->producer = producer;
if (rcv_desc->rcv_free >= 32) {
rcv_desc->rcv_free = 0;
/* Window = 1 */
writel((producer - 1) &
(rcv_desc->max_rx_desc_count - 1),
Expand All @@ -1536,21 +1480,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
rcv_desc_crb[ringid].
crb_rcv_producer_offset));
wmb();
}
}
}

int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
{
if (find_diff_among(adapter->last_cmd_consumer,
adapter->cmd_producer,
adapter->max_tx_desc_count) > 0)
return 1;

return 0;
}


void netxen_nic_clear_stats(struct netxen_adapter *adapter)
{
memset(&adapter->stats, 0, sizeof(adapter->stats));
Expand Down
17 changes: 4 additions & 13 deletions drivers/net/netxen/netxen_nic_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,31 +193,22 @@ int netxen_nic_link_ok(struct netxen_adapter *adapter)
void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
u32 val, val1;
u32 val;

/* WINDOW = 1 */
val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
val >>= (physical_port[adapter->portnum] * 8);
val1 = val & 0xff;
val &= 0xff;

if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) {
printk(KERN_INFO "%s: %s NIC Link is down\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.xg_linkup = 0;
if (netif_running(netdev)) {
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
/* read twice to clear sticky bits */
/* WINDOW = 0 */
netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);

if ((val & 0xffb) != 0xffb) {
printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n",
netxen_nic_driver_name, val1);
}
} else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) {
} else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) {
printk(KERN_INFO "%s: %s NIC Link is up\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.xg_linkup = 1;
Expand Down
Loading

0 comments on commit 05aaa02

Please sign in to comment.