diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2008-03-17 22:59:49 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-03-25 23:16:16 -0400 |
commit | 05aaa02d799e8e9548d57ac92fcb05e783027341 (patch) | |
tree | becfc839727f798364c13549e332de0830d7676f /drivers/net/netxen/netxen_nic_init.c | |
parent | 443be7960be77f3345b44491c700ae4471b0fe57 (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.c | 76 |
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 | ||
979 | int 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 | |||
1001 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | 978 | static 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 | ||
1041 | void netxen_watchdog_task(struct work_struct *work) | 1018 | void 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 */ |
1247 | int netxen_process_cmd_ring(unsigned long data) | 1198 | int 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 | ||
1543 | int 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 | |||
1554 | void netxen_nic_clear_stats(struct netxen_adapter *adapter) | 1486 | void 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)); |