aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_init.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2008-03-17 22:59:49 -0400
committerJeff Garzik <jeff@garzik.org>2008-03-25 23:16:16 -0400
commit05aaa02d799e8e9548d57ac92fcb05e783027341 (patch)
treebecfc839727f798364c13549e332de0830d7676f /drivers/net/netxen/netxen_nic_init.c
parent443be7960be77f3345b44491c700ae4471b0fe57 (diff)
netxen: napi and irq cleanup
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 <dhananjay@netxen.com> Tested-by: Vernon Mauery <mauery@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r--drivers/net/netxen/netxen_nic_init.c76
1 files changed, 4 insertions, 72 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 43eb1f65152d..64fc18d4afb6 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -185,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
185 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { 185 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
186 struct netxen_rx_buffer *rx_buf; 186 struct netxen_rx_buffer *rx_buf;
187 rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; 187 rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
188 rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
189 rcv_desc->begin_alloc = 0; 188 rcv_desc->begin_alloc = 0;
190 rx_buf = rcv_desc->rx_buf_arr; 189 rx_buf = rcv_desc->rx_buf_arr;
191 num_rx_bufs = rcv_desc->max_rx_desc_count; 190 num_rx_bufs = rcv_desc->max_rx_desc_count;
@@ -976,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
976 return 0; 975 return 0;
977} 976}
978 977
979int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
980{
981 int ctx;
982
983 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
984 struct netxen_recv_context *recv_ctx =
985 &(adapter->recv_ctx[ctx]);
986 u32 consumer;
987 struct status_desc *desc_head;
988 struct status_desc *desc;
989
990 consumer = recv_ctx->status_rx_consumer;
991 desc_head = recv_ctx->rcv_status_desc_head;
992 desc = &desc_head[consumer];
993
994 if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)
995 return 1;
996 }
997
998 return 0;
999}
1000
1001static int netxen_nic_check_temp(struct netxen_adapter *adapter) 978static int netxen_nic_check_temp(struct netxen_adapter *adapter)
1002{ 979{
1003 struct net_device *netdev = adapter->netdev; 980 struct net_device *netdev = adapter->netdev;
@@ -1040,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
1040 1017
1041void netxen_watchdog_task(struct work_struct *work) 1018void netxen_watchdog_task(struct work_struct *work)
1042{ 1019{
1043 struct net_device *netdev;
1044 struct netxen_adapter *adapter = 1020 struct netxen_adapter *adapter =
1045 container_of(work, struct netxen_adapter, watchdog_task); 1021 container_of(work, struct netxen_adapter, watchdog_task);
1046 1022
@@ -1050,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work)
1050 if (adapter->handle_phy_intr) 1026 if (adapter->handle_phy_intr)
1051 adapter->handle_phy_intr(adapter); 1027 adapter->handle_phy_intr(adapter);
1052 1028
1053 netdev = adapter->netdev;
1054 if ((netif_running(netdev)) && !netif_carrier_ok(netdev) &&
1055 netxen_nic_link_ok(adapter) ) {
1056 printk(KERN_INFO "%s %s (port %d), Link is up\n",
1057 netxen_nic_driver_name, netdev->name, adapter->portnum);
1058 netif_carrier_on(netdev);
1059 netif_wake_queue(netdev);
1060 } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) {
1061 printk(KERN_ERR "%s %s Link is Down\n",
1062 netxen_nic_driver_name, netdev->name);
1063 netif_carrier_off(netdev);
1064 netif_stop_queue(netdev);
1065 }
1066
1067 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1029 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
1068} 1030}
1069 1031
@@ -1177,7 +1139,6 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
1177 1139
1178 netdev->last_rx = jiffies; 1140 netdev->last_rx = jiffies;
1179 1141
1180 rcv_desc->rcv_free++;
1181 rcv_desc->rcv_pending--; 1142 rcv_desc->rcv_pending--;
1182 1143
1183 /* 1144 /*
@@ -1202,13 +1163,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
1202 u32 producer = 0; 1163 u32 producer = 0;
1203 int count = 0, ring; 1164 int count = 0, ring;
1204 1165
1205 DPRINTK(INFO, "procesing receive\n");
1206 /*
1207 * we assume in this case that there is only one port and that is
1208 * port #1...changes need to be done in firmware to indicate port
1209 * number as part of the descriptor. This way we will be able to get
1210 * the netdev which is associated with that device.
1211 */
1212 while (count < max) { 1166 while (count < max) {
1213 desc = &desc_head[consumer]; 1167 desc = &desc_head[consumer];
1214 if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { 1168 if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
@@ -1221,10 +1175,8 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
1221 consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); 1175 consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
1222 count++; 1176 count++;
1223 } 1177 }
1224 if (count) { 1178 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
1225 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { 1179 netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
1226 netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
1227 }
1228 } 1180 }
1229 1181
1230 /* update the consumer index in phantom */ 1182 /* update the consumer index in phantom */
@@ -1235,20 +1187,18 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
1235 /* Window = 1 */ 1187 /* Window = 1 */
1236 writel(consumer, 1188 writel(consumer,
1237 NETXEN_CRB_NORMALIZE(adapter, 1189 NETXEN_CRB_NORMALIZE(adapter,
1238 recv_crb_registers[adapter->portnum]. 1190 recv_crb_registers[adapter->portnum].
1239 crb_rcv_status_consumer)); 1191 crb_rcv_status_consumer));
1240 wmb();
1241 } 1192 }
1242 1193
1243 return count; 1194 return count;
1244} 1195}
1245 1196
1246/* Process Command status ring */ 1197/* Process Command status ring */
1247int netxen_process_cmd_ring(unsigned long data) 1198int netxen_process_cmd_ring(struct netxen_adapter *adapter)
1248{ 1199{
1249 u32 last_consumer; 1200 u32 last_consumer;
1250 u32 consumer; 1201 u32 consumer;
1251 struct netxen_adapter *adapter = (struct netxen_adapter *)data;
1252 int count1 = 0; 1202 int count1 = 0;
1253 int count2 = 0; 1203 int count2 = 0;
1254 struct netxen_cmd_buffer *buffer; 1204 struct netxen_cmd_buffer *buffer;
@@ -1435,8 +1385,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1435 rcv_desc->begin_alloc = index; 1385 rcv_desc->begin_alloc = index;
1436 rcv_desc->rcv_pending += count; 1386 rcv_desc->rcv_pending += count;
1437 rcv_desc->producer = producer; 1387 rcv_desc->producer = producer;
1438 if (rcv_desc->rcv_free >= 32) {
1439 rcv_desc->rcv_free = 0;
1440 /* Window = 1 */ 1388 /* Window = 1 */
1441 writel((producer - 1) & 1389 writel((producer - 1) &
1442 (rcv_desc->max_rx_desc_count - 1), 1390 (rcv_desc->max_rx_desc_count - 1),
@@ -1460,8 +1408,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1460 writel(msg, 1408 writel(msg,
1461 DB_NORMALIZE(adapter, 1409 DB_NORMALIZE(adapter,
1462 NETXEN_RCV_PRODUCER_OFFSET)); 1410 NETXEN_RCV_PRODUCER_OFFSET));
1463 wmb();
1464 }
1465 } 1411 }
1466} 1412}
1467 1413
@@ -1525,8 +1471,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
1525 rcv_desc->begin_alloc = index; 1471 rcv_desc->begin_alloc = index;
1526 rcv_desc->rcv_pending += count; 1472 rcv_desc->rcv_pending += count;
1527 rcv_desc->producer = producer; 1473 rcv_desc->producer = producer;
1528 if (rcv_desc->rcv_free >= 32) {
1529 rcv_desc->rcv_free = 0;
1530 /* Window = 1 */ 1474 /* Window = 1 */
1531 writel((producer - 1) & 1475 writel((producer - 1) &
1532 (rcv_desc->max_rx_desc_count - 1), 1476 (rcv_desc->max_rx_desc_count - 1),
@@ -1536,21 +1480,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
1536 rcv_desc_crb[ringid]. 1480 rcv_desc_crb[ringid].
1537 crb_rcv_producer_offset)); 1481 crb_rcv_producer_offset));
1538 wmb(); 1482 wmb();
1539 }
1540 } 1483 }
1541} 1484}
1542 1485
1543int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
1544{
1545 if (find_diff_among(adapter->last_cmd_consumer,
1546 adapter->cmd_producer,
1547 adapter->max_tx_desc_count) > 0)
1548 return 1;
1549
1550 return 0;
1551}
1552
1553
1554void netxen_nic_clear_stats(struct netxen_adapter *adapter) 1486void netxen_nic_clear_stats(struct netxen_adapter *adapter)
1555{ 1487{
1556 memset(&adapter->stats, 0, sizeof(adapter->stats)); 1488 memset(&adapter->stats, 0, sizeof(adapter->stats));