diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 526 |
1 files changed, 269 insertions, 257 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index ab25c225a07..514cb393f48 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "netxen_nic_hw.h" | 36 | #include "netxen_nic_hw.h" |
37 | 37 | ||
38 | #include "netxen_nic.h" | 38 | #include "netxen_nic.h" |
39 | #define DEFINE_GLOBAL_RECV_CRB | ||
40 | #include "netxen_nic_phan_reg.h" | 39 | #include "netxen_nic_phan_reg.h" |
41 | 40 | ||
42 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
@@ -94,6 +93,67 @@ MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); | |||
94 | struct workqueue_struct *netxen_workq; | 93 | struct workqueue_struct *netxen_workq; |
95 | static void netxen_watchdog(unsigned long); | 94 | static void netxen_watchdog(unsigned long); |
96 | 95 | ||
96 | static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | ||
97 | uint32_t crb_producer) | ||
98 | { | ||
99 | switch (adapter->portnum) { | ||
100 | case 0: | ||
101 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
102 | (adapter, CRB_CMD_PRODUCER_OFFSET)); | ||
103 | return; | ||
104 | case 1: | ||
105 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
106 | (adapter, CRB_CMD_PRODUCER_OFFSET_1)); | ||
107 | return; | ||
108 | case 2: | ||
109 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
110 | (adapter, CRB_CMD_PRODUCER_OFFSET_2)); | ||
111 | return; | ||
112 | case 3: | ||
113 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
114 | (adapter, CRB_CMD_PRODUCER_OFFSET_3)); | ||
115 | return; | ||
116 | default: | ||
117 | printk(KERN_WARNING "We tried to update " | ||
118 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
119 | "PCI function id %d\n", | ||
120 | adapter->portnum); | ||
121 | return; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | ||
126 | u32 crb_consumer) | ||
127 | { | ||
128 | switch (adapter->portnum) { | ||
129 | case 0: | ||
130 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
131 | (adapter, CRB_CMD_CONSUMER_OFFSET)); | ||
132 | return; | ||
133 | case 1: | ||
134 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
135 | (adapter, CRB_CMD_CONSUMER_OFFSET_1)); | ||
136 | return; | ||
137 | case 2: | ||
138 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
139 | (adapter, CRB_CMD_CONSUMER_OFFSET_2)); | ||
140 | return; | ||
141 | case 3: | ||
142 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
143 | (adapter, CRB_CMD_CONSUMER_OFFSET_3)); | ||
144 | return; | ||
145 | default: | ||
146 | printk(KERN_WARNING "We tried to update " | ||
147 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
148 | "PCI function id %d\n", | ||
149 | adapter->portnum); | ||
150 | return; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | #define ADAPTER_LIST_SIZE 12 | ||
155 | int netxen_cards_found; | ||
156 | |||
97 | /* | 157 | /* |
98 | * netxen_nic_probe() | 158 | * netxen_nic_probe() |
99 | * | 159 | * |
@@ -111,26 +171,26 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
111 | { | 171 | { |
112 | struct net_device *netdev = NULL; | 172 | struct net_device *netdev = NULL; |
113 | struct netxen_adapter *adapter = NULL; | 173 | struct netxen_adapter *adapter = NULL; |
114 | struct netxen_port *port = NULL; | ||
115 | void __iomem *mem_ptr0 = NULL; | 174 | void __iomem *mem_ptr0 = NULL; |
116 | void __iomem *mem_ptr1 = NULL; | 175 | void __iomem *mem_ptr1 = NULL; |
117 | void __iomem *mem_ptr2 = NULL; | 176 | void __iomem *mem_ptr2 = NULL; |
118 | 177 | ||
119 | u8 __iomem *db_ptr = NULL; | 178 | u8 __iomem *db_ptr = NULL; |
120 | unsigned long mem_base, mem_len, db_base, db_len; | 179 | unsigned long mem_base, mem_len, db_base, db_len; |
121 | int pci_using_dac, i, err; | 180 | int pci_using_dac, i = 0, err; |
122 | int ring; | 181 | int ring; |
123 | struct netxen_recv_context *recv_ctx = NULL; | 182 | struct netxen_recv_context *recv_ctx = NULL; |
124 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | 183 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; |
125 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | 184 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; |
126 | u64 mac_addr[FLASH_NUM_PORTS + 1]; | 185 | u64 mac_addr[FLASH_NUM_PORTS + 1]; |
127 | int valid_mac = 0; | 186 | static int valid_mac = 0; |
187 | static int netxen_probe_flag; | ||
188 | int pci_func_id = PCI_FUNC(pdev->devfn); | ||
128 | 189 | ||
129 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 190 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); |
130 | /* In current scheme, we use only PCI function 0 */ | 191 | if (pdev->class != 0x020000) { |
131 | if (PCI_FUNC(pdev->devfn) != 0) { | 192 | printk(KERN_ERR"NetXen function %d, class %x will not" |
132 | DPRINTK(ERR, "NetXen function %d will not be enabled.\n", | 193 | "be enabled.\n",pci_func_id, pdev->class); |
133 | PCI_FUNC(pdev->devfn)); | ||
134 | return -ENODEV; | 194 | return -ENODEV; |
135 | } | 195 | } |
136 | if ((err = pci_enable_device(pdev))) | 196 | if ((err = pci_enable_device(pdev))) |
@@ -157,6 +217,22 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
157 | pci_using_dac = 0; | 217 | pci_using_dac = 0; |
158 | } | 218 | } |
159 | 219 | ||
220 | |||
221 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | ||
222 | if(!netdev) { | ||
223 | printk(KERN_ERR"%s: Failed to allocate memory for the " | ||
224 | "device block.Check system memory resource" | ||
225 | " usage.\n", netxen_nic_driver_name); | ||
226 | goto err_out_free_res; | ||
227 | } | ||
228 | |||
229 | SET_MODULE_OWNER(netdev); | ||
230 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
231 | |||
232 | adapter = netdev->priv; | ||
233 | memset(adapter, 0 , sizeof(struct netxen_adapter)); | ||
234 | |||
235 | adapter->ahw.pdev = pdev; | ||
160 | /* remap phys address */ | 236 | /* remap phys address */ |
161 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 237 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
162 | mem_len = pci_resource_len(pdev, 0); | 238 | mem_len = pci_resource_len(pdev, 0); |
@@ -198,23 +274,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
198 | } | 274 | } |
199 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); | 275 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); |
200 | 276 | ||
201 | /* | ||
202 | * Allocate a adapter structure which will manage all the initialization | ||
203 | * as well as the common resources for all ports... | ||
204 | * all the ports will have pointer to this adapter as well as Adapter | ||
205 | * will have pointers of all the ports structures. | ||
206 | */ | ||
207 | |||
208 | /* One adapter structure for all 4 ports.... */ | ||
209 | adapter = kzalloc(sizeof(struct netxen_adapter), GFP_KERNEL); | ||
210 | if (adapter == NULL) { | ||
211 | printk(KERN_ERR "%s: Could not allocate adapter memory:%d\n", | ||
212 | netxen_nic_driver_name, | ||
213 | (int)sizeof(struct netxen_adapter)); | ||
214 | err = -ENOMEM; | ||
215 | goto err_out_dbunmap; | ||
216 | } | ||
217 | |||
218 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; | 277 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; |
219 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | 278 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; |
220 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | 279 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; |
@@ -222,6 +281,42 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
222 | 281 | ||
223 | pci_set_drvdata(pdev, adapter); | 282 | pci_set_drvdata(pdev, adapter); |
224 | 283 | ||
284 | adapter->netdev = netdev; | ||
285 | adapter->pdev = pdev; | ||
286 | adapter->portnum = pci_func_id; | ||
287 | |||
288 | netdev->open = netxen_nic_open; | ||
289 | netdev->stop = netxen_nic_close; | ||
290 | netdev->hard_start_xmit = netxen_nic_xmit_frame; | ||
291 | netdev->set_multicast_list = netxen_nic_set_multi; | ||
292 | netdev->set_mac_address = netxen_nic_set_mac; | ||
293 | netdev->change_mtu = netxen_nic_change_mtu; | ||
294 | netdev->tx_timeout = netxen_tx_timeout; | ||
295 | netdev->watchdog_timeo = HZ; | ||
296 | |||
297 | netxen_nic_change_mtu(netdev, netdev->mtu); | ||
298 | |||
299 | SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); | ||
300 | netdev->poll = netxen_nic_poll; | ||
301 | netdev->weight = NETXEN_NETDEV_WEIGHT; | ||
302 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
303 | netdev->poll_controller = netxen_nic_poll_controller; | ||
304 | #endif | ||
305 | /* ScatterGather support */ | ||
306 | netdev->features = NETIF_F_SG; | ||
307 | netdev->features |= NETIF_F_IP_CSUM; | ||
308 | netdev->features |= NETIF_F_TSO; | ||
309 | |||
310 | if (pci_using_dac) | ||
311 | netdev->features |= NETIF_F_HIGHDMA; | ||
312 | |||
313 | if (pci_enable_msi(pdev)) { | ||
314 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | ||
315 | printk(KERN_WARNING "%s: unable to allocate MSI interrupt" | ||
316 | " error\n", netxen_nic_driver_name); | ||
317 | } else | ||
318 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
319 | |||
225 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | 320 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); |
226 | if (cmd_buf_arr == NULL) { | 321 | if (cmd_buf_arr == NULL) { |
227 | printk(KERN_ERR | 322 | printk(KERN_ERR |
@@ -288,9 +383,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
288 | spin_lock_init(&adapter->lock); | 383 | spin_lock_init(&adapter->lock); |
289 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | 384 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ |
290 | #ifdef CONFIG_IA64 | 385 | #ifdef CONFIG_IA64 |
291 | netxen_pinit_from_rom(adapter, 0); | 386 | if(netxen_probe_flag == 0) { |
292 | udelay(500); | 387 | netxen_pinit_from_rom(adapter, 0); |
293 | netxen_load_firmware(adapter); | 388 | udelay(500); |
389 | netxen_load_firmware(adapter); | ||
390 | } | ||
294 | #endif | 391 | #endif |
295 | 392 | ||
296 | /* | 393 | /* |
@@ -304,6 +401,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
304 | */ | 401 | */ |
305 | netxen_initialize_adapter_hw(adapter); /* initialize the adapter */ | 402 | netxen_initialize_adapter_hw(adapter); /* initialize the adapter */ |
306 | 403 | ||
404 | if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) | ||
405 | if (pci_func_id >= 2) | ||
406 | adapter->portnum = pci_func_id - 2; | ||
407 | |||
307 | netxen_initialize_adapter_ops(adapter); | 408 | netxen_initialize_adapter_ops(adapter); |
308 | 409 | ||
309 | init_timer(&adapter->watchdog_timer); | 410 | init_timer(&adapter->watchdog_timer); |
@@ -315,12 +416,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
315 | adapter->proc_cmd_buf_counter = 0; | 416 | adapter->proc_cmd_buf_counter = 0; |
316 | adapter->ahw.revision_id = nx_p2_id; | 417 | adapter->ahw.revision_id = nx_p2_id; |
317 | 418 | ||
318 | if (pci_enable_msi(pdev)) { | 419 | netxen_nic_update_cmd_producer(adapter, 0); |
319 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | 420 | netxen_nic_update_cmd_consumer(adapter, 0); |
320 | printk(KERN_WARNING "%s: unable to allocate MSI interrupt" | ||
321 | " error\n", netxen_nic_driver_name); | ||
322 | } else | ||
323 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
324 | 421 | ||
325 | if (netxen_is_flash_supported(adapter) == 0 && | 422 | if (netxen_is_flash_supported(adapter) == 0 && |
326 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 423 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) |
@@ -328,6 +425,34 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
328 | else | 425 | else |
329 | valid_mac = 0; | 426 | valid_mac = 0; |
330 | 427 | ||
428 | if (valid_mac) { | ||
429 | unsigned char *p = (unsigned char *)&mac_addr[i]; | ||
430 | netdev->dev_addr[0] = *(p + 5); | ||
431 | netdev->dev_addr[1] = *(p + 4); | ||
432 | netdev->dev_addr[2] = *(p + 3); | ||
433 | netdev->dev_addr[3] = *(p + 2); | ||
434 | netdev->dev_addr[4] = *(p + 1); | ||
435 | netdev->dev_addr[5] = *(p + 0); | ||
436 | |||
437 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
438 | netdev->addr_len); | ||
439 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
440 | printk(KERN_ERR "%s: Bad MAC address " | ||
441 | "%02x:%02x:%02x:%02x:%02x:%02x.\n", | ||
442 | netxen_nic_driver_name, | ||
443 | netdev->dev_addr[0], | ||
444 | netdev->dev_addr[1], | ||
445 | netdev->dev_addr[2], | ||
446 | netdev->dev_addr[3], | ||
447 | netdev->dev_addr[4], | ||
448 | netdev->dev_addr[5]); | ||
449 | } else { | ||
450 | if (adapter->macaddr_set) | ||
451 | adapter->macaddr_set(adapter, | ||
452 | netdev->dev_addr); | ||
453 | } | ||
454 | } | ||
455 | |||
331 | /* | 456 | /* |
332 | * Initialize all the CRB registers here. | 457 | * Initialize all the CRB registers here. |
333 | */ | 458 | */ |
@@ -337,140 +462,62 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
337 | 462 | ||
338 | /* do this before waking up pegs so that we have valid dummy dma addr */ | 463 | /* do this before waking up pegs so that we have valid dummy dma addr */ |
339 | err = netxen_initialize_adapter_offload(adapter); | 464 | err = netxen_initialize_adapter_offload(adapter); |
340 | if (err) { | 465 | if (err) |
341 | goto err_out_free_dev; | 466 | goto err_out_free_dev; |
342 | } | ||
343 | |||
344 | /* Unlock the HW, prompting the boot sequence */ | ||
345 | writel(1, | ||
346 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
347 | |||
348 | /* Handshake with the card before we register the devices. */ | ||
349 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
350 | |||
351 | /* initialize the all the ports */ | ||
352 | adapter->active_ports = 0; | ||
353 | |||
354 | for (i = 0; i < adapter->ahw.max_ports; i++) { | ||
355 | netdev = alloc_etherdev(sizeof(struct netxen_port)); | ||
356 | if (!netdev) { | ||
357 | printk(KERN_ERR "%s: could not allocate netdev for port" | ||
358 | " %d\n", netxen_nic_driver_name, i + 1); | ||
359 | goto err_out_free_dev; | ||
360 | } | ||
361 | 467 | ||
362 | SET_MODULE_OWNER(netdev); | 468 | if (netxen_probe_flag == 0) { |
363 | SET_NETDEV_DEV(netdev, &pdev->dev); | 469 | /* Unlock the HW, prompting the boot sequence */ |
364 | 470 | writel(1, | |
365 | port = netdev_priv(netdev); | 471 | NETXEN_CRB_NORMALIZE(adapter, |
366 | port->netdev = netdev; | 472 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); |
367 | port->pdev = pdev; | 473 | /* Handshake with the card before we register the devices. */ |
368 | port->adapter = adapter; | 474 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
369 | port->portnum = i; /* Gigabit port number from 0-3 */ | 475 | } |
370 | |||
371 | netdev->open = netxen_nic_open; | ||
372 | netdev->stop = netxen_nic_close; | ||
373 | netdev->hard_start_xmit = netxen_nic_xmit_frame; | ||
374 | netdev->get_stats = netxen_nic_get_stats; | ||
375 | netdev->set_multicast_list = netxen_nic_set_multi; | ||
376 | netdev->set_mac_address = netxen_nic_set_mac; | ||
377 | netdev->change_mtu = netxen_nic_change_mtu; | ||
378 | netdev->tx_timeout = netxen_tx_timeout; | ||
379 | netdev->watchdog_timeo = HZ; | ||
380 | |||
381 | netxen_nic_change_mtu(netdev, netdev->mtu); | ||
382 | |||
383 | SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); | ||
384 | netdev->poll = netxen_nic_poll; | ||
385 | netdev->weight = NETXEN_NETDEV_WEIGHT; | ||
386 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
387 | netdev->poll_controller = netxen_nic_poll_controller; | ||
388 | #endif | ||
389 | /* ScatterGather support */ | ||
390 | netdev->features = NETIF_F_SG; | ||
391 | netdev->features |= NETIF_F_IP_CSUM; | ||
392 | netdev->features |= NETIF_F_TSO; | ||
393 | |||
394 | if (pci_using_dac) | ||
395 | netdev->features |= NETIF_F_HIGHDMA; | ||
396 | |||
397 | if (valid_mac) { | ||
398 | unsigned char *p = (unsigned char *)&mac_addr[i]; | ||
399 | netdev->dev_addr[0] = *(p + 5); | ||
400 | netdev->dev_addr[1] = *(p + 4); | ||
401 | netdev->dev_addr[2] = *(p + 3); | ||
402 | netdev->dev_addr[3] = *(p + 2); | ||
403 | netdev->dev_addr[4] = *(p + 1); | ||
404 | netdev->dev_addr[5] = *(p + 0); | ||
405 | |||
406 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
407 | netdev->addr_len); | ||
408 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
409 | printk(KERN_ERR "%s: Bad MAC address " | ||
410 | "%02x:%02x:%02x:%02x:%02x:%02x.\n", | ||
411 | netxen_nic_driver_name, | ||
412 | netdev->dev_addr[0], | ||
413 | netdev->dev_addr[1], | ||
414 | netdev->dev_addr[2], | ||
415 | netdev->dev_addr[3], | ||
416 | netdev->dev_addr[4], | ||
417 | netdev->dev_addr[5]); | ||
418 | } else { | ||
419 | if (adapter->macaddr_set) | ||
420 | adapter->macaddr_set(port, | ||
421 | netdev->dev_addr); | ||
422 | } | ||
423 | } | ||
424 | INIT_WORK(&port->tx_timeout_task, netxen_tx_timeout_task); | ||
425 | netif_carrier_off(netdev); | ||
426 | netif_stop_queue(netdev); | ||
427 | 476 | ||
428 | if ((err = register_netdev(netdev))) { | 477 | if(netxen_probe_flag == 0) { |
429 | printk(KERN_ERR "%s: register_netdev failed port #%d" | 478 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); |
430 | " aborting\n", netxen_nic_driver_name, i + 1); | 479 | netxen_pinit_from_rom(adapter, 0); |
431 | err = -EIO; | 480 | udelay(500); |
432 | free_netdev(netdev); | 481 | netxen_load_firmware(adapter); |
433 | goto err_out_free_dev; | 482 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
434 | } | ||
435 | adapter->port_count++; | ||
436 | adapter->port[i] = port; | ||
437 | } | 483 | } |
438 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
439 | netxen_pinit_from_rom(adapter, 0); | ||
440 | udelay(500); | ||
441 | netxen_load_firmware(adapter); | ||
442 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
443 | /* | 484 | /* |
444 | * delay a while to ensure that the Pegs are up & running. | 485 | * delay a while to ensure that the Pegs are up & running. |
445 | * Otherwise, we might see some flaky behaviour. | 486 | * Otherwise, we might see some flaky behaviour. |
446 | */ | 487 | */ |
447 | udelay(100); | 488 | udelay(100); |
489 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
490 | netif_carrier_off(netdev); | ||
491 | netif_stop_queue(netdev); | ||
492 | |||
493 | if((err = register_netdev(netdev))) | ||
494 | DPRINTK(1, ERR, "register_netdev failed port #%d" | ||
495 | " aborting\n", i+1); | ||
448 | 496 | ||
449 | switch (adapter->ahw.board_type) { | 497 | switch (adapter->ahw.board_type) { |
450 | case NETXEN_NIC_GBE: | 498 | case NETXEN_NIC_GBE: |
451 | printk("%s: QUAD GbE board initialized\n", | 499 | printk(KERN_INFO "%s: QUAD GbE board initialized\n", |
452 | netxen_nic_driver_name); | 500 | netxen_nic_driver_name); |
453 | break; | 501 | break; |
454 | 502 | ||
455 | case NETXEN_NIC_XGBE: | 503 | case NETXEN_NIC_XGBE: |
456 | printk("%s: XGbE board initialized\n", netxen_nic_driver_name); | 504 | printk(KERN_INFO "%s: XGbE board initialized\n", |
457 | break; | 505 | netxen_nic_driver_name); |
506 | break; | ||
458 | } | 507 | } |
459 | 508 | ||
460 | adapter->driver_mismatch = 0; | 509 | adapter->driver_mismatch = 0; |
510 | if(netxen_probe_flag == 0) | ||
511 | netxen_probe_flag ++; | ||
461 | 512 | ||
462 | return 0; | 513 | return 0; |
463 | 514 | ||
464 | err_out_free_dev: | 515 | err_out_free_dev: |
465 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 516 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
466 | pci_disable_msi(pdev); | 517 | pci_disable_msi(pdev); |
467 | for (i = 0; i < adapter->port_count; i++) { | 518 | |
468 | port = adapter->port[i]; | 519 | unregister_netdev(adapter->netdev); |
469 | if ((port) && (port->netdev)) { | 520 | free_netdev(adapter->netdev); |
470 | unregister_netdev(port->netdev); | ||
471 | free_netdev(port->netdev); | ||
472 | } | ||
473 | } | ||
474 | 521 | ||
475 | netxen_free_adapter_offload(adapter); | 522 | netxen_free_adapter_offload(adapter); |
476 | 523 | ||
@@ -491,7 +538,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
491 | pci_set_drvdata(pdev, NULL); | 538 | pci_set_drvdata(pdev, NULL); |
492 | kfree(adapter); | 539 | kfree(adapter); |
493 | 540 | ||
494 | err_out_dbunmap: | ||
495 | if (db_ptr) | 541 | if (db_ptr) |
496 | iounmap(db_ptr); | 542 | iounmap(db_ptr); |
497 | 543 | ||
@@ -513,35 +559,32 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
513 | static void __devexit netxen_nic_remove(struct pci_dev *pdev) | 559 | static void __devexit netxen_nic_remove(struct pci_dev *pdev) |
514 | { | 560 | { |
515 | struct netxen_adapter *adapter; | 561 | struct netxen_adapter *adapter; |
516 | struct netxen_port *port; | 562 | struct net_device *netdev; |
517 | struct netxen_rx_buffer *buffer; | 563 | struct netxen_rx_buffer *buffer; |
518 | struct netxen_recv_context *recv_ctx; | 564 | struct netxen_recv_context *recv_ctx; |
519 | struct netxen_rcv_desc_ctx *rcv_desc; | 565 | struct netxen_rcv_desc_ctx *rcv_desc; |
520 | int i; | 566 | int i; |
521 | int ctxid, ring; | 567 | int ctxid, ring; |
522 | 568 | ||
523 | adapter = pci_get_drvdata(pdev); | 569 | netdev = pci_get_drvdata(pdev); |
570 | adapter = netdev_priv(netdev); | ||
524 | if (adapter == NULL) | 571 | if (adapter == NULL) |
525 | return; | 572 | return; |
526 | 573 | ||
574 | if (adapter->stop_port) | ||
575 | adapter->stop_port(adapter); | ||
576 | |||
527 | if (adapter->irq) | 577 | if (adapter->irq) |
528 | free_irq(adapter->irq, adapter); | 578 | free_irq(adapter->irq, adapter); |
529 | netxen_nic_stop_all_ports(adapter); | ||
530 | /* leave the hw in the same state as reboot */ | 579 | /* leave the hw in the same state as reboot */ |
531 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 580 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); |
532 | netxen_pinit_from_rom(adapter, 0); | 581 | netxen_pinit_from_rom(adapter, 0); |
533 | udelay(500); | ||
534 | netxen_load_firmware(adapter); | 582 | netxen_load_firmware(adapter); |
535 | netxen_free_adapter_offload(adapter); | 583 | netxen_free_adapter_offload(adapter); |
536 | 584 | ||
537 | mdelay(1000); /* Delay for a while to drain the DMA engines */ | 585 | udelay(500); |
538 | for (i = 0; i < adapter->port_count; i++) { | 586 | unregister_netdev(netdev); |
539 | port = adapter->port[i]; | 587 | free_netdev(netdev); |
540 | if ((port) && (port->netdev)) { | ||
541 | unregister_netdev(port->netdev); | ||
542 | free_netdev(port->netdev); | ||
543 | } | ||
544 | } | ||
545 | 588 | ||
546 | if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) | 589 | if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) |
547 | pci_disable_msi(pdev); | 590 | pci_disable_msi(pdev); |
@@ -585,8 +628,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
585 | */ | 628 | */ |
586 | static int netxen_nic_open(struct net_device *netdev) | 629 | static int netxen_nic_open(struct net_device *netdev) |
587 | { | 630 | { |
588 | struct netxen_port *port = netdev_priv(netdev); | 631 | struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; |
589 | struct netxen_adapter *adapter = port->adapter; | ||
590 | int err = 0; | 632 | int err = 0; |
591 | int ctx, ring; | 633 | int ctx, ring; |
592 | 634 | ||
@@ -610,9 +652,9 @@ static int netxen_nic_open(struct net_device *netdev) | |||
610 | return err; | 652 | return err; |
611 | } | 653 | } |
612 | if (adapter->init_port | 654 | if (adapter->init_port |
613 | && adapter->init_port(adapter, port->portnum) != 0) { | 655 | && adapter->init_port(adapter, adapter->portnum) != 0) { |
614 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 656 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
615 | netxen_nic_driver_name, port->portnum); | 657 | netxen_nic_driver_name, adapter->portnum); |
616 | netxen_free_hw_resources(adapter); | 658 | netxen_free_hw_resources(adapter); |
617 | return -EIO; | 659 | return -EIO; |
618 | } | 660 | } |
@@ -632,23 +674,20 @@ static int netxen_nic_open(struct net_device *netdev) | |||
632 | 674 | ||
633 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 675 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
634 | } | 676 | } |
635 | adapter->active_ports++; | 677 | if (!adapter->driver_mismatch) |
636 | if (adapter->active_ports == 1) { | 678 | mod_timer(&adapter->watchdog_timer, jiffies); |
637 | if (!adapter->driver_mismatch) | ||
638 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
639 | 679 | ||
640 | netxen_nic_enable_int(adapter); | 680 | netxen_nic_enable_int(adapter); |
641 | } | ||
642 | 681 | ||
643 | /* Done here again so that even if phantom sw overwrote it, | 682 | /* Done here again so that even if phantom sw overwrote it, |
644 | * we set it */ | 683 | * we set it */ |
645 | if (adapter->macaddr_set) | 684 | if (adapter->macaddr_set) |
646 | adapter->macaddr_set(port, netdev->dev_addr); | 685 | adapter->macaddr_set(adapter, netdev->dev_addr); |
647 | netxen_nic_set_link_parameters(port); | 686 | netxen_nic_set_link_parameters(adapter); |
648 | 687 | ||
649 | netxen_nic_set_multi(netdev); | 688 | netxen_nic_set_multi(netdev); |
650 | if (adapter->set_mtu) | 689 | if (adapter->set_mtu) |
651 | adapter->set_mtu(port, netdev->mtu); | 690 | adapter->set_mtu(adapter, netdev->mtu); |
652 | 691 | ||
653 | if (!adapter->driver_mismatch) | 692 | if (!adapter->driver_mismatch) |
654 | netif_start_queue(netdev); | 693 | netif_start_queue(netdev); |
@@ -661,8 +700,7 @@ static int netxen_nic_open(struct net_device *netdev) | |||
661 | */ | 700 | */ |
662 | static int netxen_nic_close(struct net_device *netdev) | 701 | static int netxen_nic_close(struct net_device *netdev) |
663 | { | 702 | { |
664 | struct netxen_port *port = netdev_priv(netdev); | 703 | struct netxen_adapter *adapter = netdev_priv(netdev); |
665 | struct netxen_adapter *adapter = port->adapter; | ||
666 | int i, j; | 704 | int i, j; |
667 | struct netxen_cmd_buffer *cmd_buff; | 705 | struct netxen_cmd_buffer *cmd_buff; |
668 | struct netxen_skb_frag *buffrag; | 706 | struct netxen_skb_frag *buffrag; |
@@ -670,47 +708,43 @@ static int netxen_nic_close(struct net_device *netdev) | |||
670 | netif_carrier_off(netdev); | 708 | netif_carrier_off(netdev); |
671 | netif_stop_queue(netdev); | 709 | netif_stop_queue(netdev); |
672 | 710 | ||
673 | adapter->active_ports--; | 711 | netxen_nic_disable_int(adapter); |
674 | 712 | if (adapter->irq) | |
675 | if (!adapter->active_ports) { | 713 | free_irq(adapter->irq, adapter); |
676 | netxen_nic_disable_int(adapter); | 714 | |
677 | cmd_buff = adapter->cmd_buf_arr; | 715 | cmd_buff = adapter->cmd_buf_arr; |
678 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 716 | for (i = 0; i < adapter->max_tx_desc_count; i++) { |
679 | buffrag = cmd_buff->frag_array; | 717 | buffrag = cmd_buff->frag_array; |
718 | if (buffrag->dma) { | ||
719 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
720 | buffrag->length, PCI_DMA_TODEVICE); | ||
721 | buffrag->dma = (u64) NULL; | ||
722 | } | ||
723 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
724 | buffrag++; | ||
680 | if (buffrag->dma) { | 725 | if (buffrag->dma) { |
681 | pci_unmap_single(port->pdev, buffrag->dma, | 726 | pci_unmap_page(adapter->pdev, buffrag->dma, |
682 | buffrag->length, | 727 | buffrag->length, |
683 | PCI_DMA_TODEVICE); | 728 | PCI_DMA_TODEVICE); |
684 | buffrag->dma = (u64) NULL; | 729 | buffrag->dma = (u64) NULL; |
685 | } | 730 | } |
686 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
687 | buffrag++; | ||
688 | if (buffrag->dma) { | ||
689 | pci_unmap_page(port->pdev, | ||
690 | buffrag->dma, | ||
691 | buffrag->length, | ||
692 | PCI_DMA_TODEVICE); | ||
693 | buffrag->dma = (u64) NULL; | ||
694 | } | ||
695 | } | ||
696 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
697 | if (cmd_buff->skb) { | ||
698 | dev_kfree_skb_any(cmd_buff->skb); | ||
699 | cmd_buff->skb = NULL; | ||
700 | } | ||
701 | cmd_buff++; | ||
702 | } | 731 | } |
703 | FLUSH_SCHEDULED_WORK(); | 732 | /* Free the skb we received in netxen_nic_xmit_frame */ |
704 | del_timer_sync(&adapter->watchdog_timer); | 733 | if (cmd_buff->skb) { |
734 | dev_kfree_skb_any(cmd_buff->skb); | ||
735 | cmd_buff->skb = NULL; | ||
736 | } | ||
737 | cmd_buff++; | ||
705 | } | 738 | } |
739 | FLUSH_SCHEDULED_WORK(); | ||
740 | del_timer_sync(&adapter->watchdog_timer); | ||
706 | 741 | ||
707 | return 0; | 742 | return 0; |
708 | } | 743 | } |
709 | 744 | ||
710 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 745 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
711 | { | 746 | { |
712 | struct netxen_port *port = netdev_priv(netdev); | 747 | struct netxen_adapter *adapter = netdev_priv(netdev); |
713 | struct netxen_adapter *adapter = port->adapter; | ||
714 | struct netxen_hardware_context *hw = &adapter->ahw; | 748 | struct netxen_hardware_context *hw = &adapter->ahw; |
715 | unsigned int first_seg_len = skb->len - skb->data_len; | 749 | unsigned int first_seg_len = skb->len - skb->data_len; |
716 | struct netxen_skb_frag *buffrag; | 750 | struct netxen_skb_frag *buffrag; |
@@ -728,12 +762,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
728 | u32 last_cmd_consumer = 0; | 762 | u32 last_cmd_consumer = 0; |
729 | int no_of_desc; | 763 | int no_of_desc; |
730 | 764 | ||
731 | port->stats.xmitcalled++; | 765 | adapter->stats.xmitcalled++; |
732 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 766 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
733 | 767 | ||
734 | if (unlikely(skb->len <= 0)) { | 768 | if (unlikely(skb->len <= 0)) { |
735 | dev_kfree_skb_any(skb); | 769 | dev_kfree_skb_any(skb); |
736 | port->stats.badskblen++; | 770 | adapter->stats.badskblen++; |
737 | return NETDEV_TX_OK; | 771 | return NETDEV_TX_OK; |
738 | } | 772 | } |
739 | 773 | ||
@@ -742,7 +776,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
742 | "too large, can handle only %d frags\n", | 776 | "too large, can handle only %d frags\n", |
743 | netxen_nic_driver_name, netdev->name, | 777 | netxen_nic_driver_name, netdev->name, |
744 | frag_count, MAX_BUFFERS_PER_CMD); | 778 | frag_count, MAX_BUFFERS_PER_CMD); |
745 | port->stats.txdropped++; | 779 | adapter->stats.txdropped++; |
746 | if ((++dropped_packet & 0xff) == 0xff) | 780 | if ((++dropped_packet & 0xff) == 0xff) |
747 | printk("%s: %s droppped packets = %d\n", | 781 | printk("%s: %s droppped packets = %d\n", |
748 | netxen_nic_driver_name, netdev->name, | 782 | netxen_nic_driver_name, netdev->name, |
@@ -759,7 +793,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
759 | */ | 793 | */ |
760 | retry_getting_window: | 794 | retry_getting_window: |
761 | spin_lock_bh(&adapter->tx_lock); | 795 | spin_lock_bh(&adapter->tx_lock); |
762 | if (adapter->total_threads == MAX_XMIT_PRODUCERS) { | 796 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { |
763 | spin_unlock_bh(&adapter->tx_lock); | 797 | spin_unlock_bh(&adapter->tx_lock); |
764 | /* | 798 | /* |
765 | * Yield CPU | 799 | * Yield CPU |
@@ -792,15 +826,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
792 | if ((k + no_of_desc) >= | 826 | if ((k + no_of_desc) >= |
793 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : | 827 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : |
794 | last_cmd_consumer)) { | 828 | last_cmd_consumer)) { |
795 | port->stats.nocmddescriptor++; | ||
796 | DPRINTK(ERR, "No command descriptors available," | ||
797 | " producer = %d, consumer = %d count=%llu," | ||
798 | " dropping packet\n", producer, | ||
799 | adapter->last_cmd_consumer, | ||
800 | port->stats.nocmddescriptor); | ||
801 | |||
802 | netif_stop_queue(netdev); | 829 | netif_stop_queue(netdev); |
803 | port->flags |= NETXEN_NETDEV_STATUS; | 830 | adapter->flags |= NETXEN_NETDEV_STATUS; |
804 | spin_unlock_bh(&adapter->tx_lock); | 831 | spin_unlock_bh(&adapter->tx_lock); |
805 | return NETDEV_TX_BUSY; | 832 | return NETDEV_TX_BUSY; |
806 | } | 833 | } |
@@ -828,16 +855,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
828 | pbuf->skb = skb; | 855 | pbuf->skb = skb; |
829 | pbuf->cmd = TX_ETHER_PKT; | 856 | pbuf->cmd = TX_ETHER_PKT; |
830 | pbuf->frag_count = frag_count; | 857 | pbuf->frag_count = frag_count; |
831 | pbuf->port = port->portnum; | 858 | pbuf->port = adapter->portnum; |
832 | buffrag = &pbuf->frag_array[0]; | 859 | buffrag = &pbuf->frag_array[0]; |
833 | buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len, | 860 | buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, |
834 | PCI_DMA_TODEVICE); | 861 | PCI_DMA_TODEVICE); |
835 | buffrag->length = first_seg_len; | 862 | buffrag->length = first_seg_len; |
836 | netxen_set_cmd_desc_totallength(hwdesc, skb->len); | 863 | netxen_set_cmd_desc_totallength(hwdesc, skb->len); |
837 | netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); | 864 | netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); |
838 | netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); | 865 | netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); |
839 | 866 | ||
840 | netxen_set_cmd_desc_port(hwdesc, port->portnum); | 867 | netxen_set_cmd_desc_port(hwdesc, adapter->portnum); |
841 | hwdesc->buffer1_length = cpu_to_le16(first_seg_len); | 868 | hwdesc->buffer1_length = cpu_to_le16(first_seg_len); |
842 | hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); | 869 | hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); |
843 | 870 | ||
@@ -860,7 +887,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
860 | offset = frag->page_offset; | 887 | offset = frag->page_offset; |
861 | 888 | ||
862 | temp_len = len; | 889 | temp_len = len; |
863 | temp_dma = pci_map_page(port->pdev, frag->page, offset, | 890 | temp_dma = pci_map_page(adapter->pdev, frag->page, offset, |
864 | len, PCI_DMA_TODEVICE); | 891 | len, PCI_DMA_TODEVICE); |
865 | 892 | ||
866 | buffrag++; | 893 | buffrag++; |
@@ -928,20 +955,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
928 | } | 955 | } |
929 | } | 956 | } |
930 | spin_lock_bh(&adapter->tx_lock); | 957 | spin_lock_bh(&adapter->tx_lock); |
931 | port->stats.txbytes += | 958 | adapter->stats.txbytes += |
932 | netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); | 959 | netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); |
933 | /* Code to update the adapter considering how many producer threads | 960 | /* Code to update the adapter considering how many producer threads |
934 | are currently working */ | 961 | are currently working */ |
935 | if ((--adapter->num_threads) == 0) { | 962 | if ((--adapter->num_threads) == 0) { |
936 | /* This is the last thread */ | 963 | /* This is the last thread */ |
937 | u32 crb_producer = adapter->cmd_producer; | 964 | u32 crb_producer = adapter->cmd_producer; |
938 | writel(crb_producer, | 965 | netxen_nic_update_cmd_producer(adapter, crb_producer); |
939 | NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); | ||
940 | wmb(); | 966 | wmb(); |
941 | adapter->total_threads = 0; | 967 | adapter->total_threads = 0; |
942 | } | 968 | } |
943 | 969 | ||
944 | port->stats.xmitfinished++; | 970 | adapter->stats.xmitfinished++; |
945 | spin_unlock_bh(&adapter->tx_lock); | 971 | spin_unlock_bh(&adapter->tx_lock); |
946 | 972 | ||
947 | netdev->trans_start = jiffies; | 973 | netdev->trans_start = jiffies; |
@@ -961,25 +987,25 @@ static void netxen_watchdog(unsigned long v) | |||
961 | 987 | ||
962 | static void netxen_tx_timeout(struct net_device *netdev) | 988 | static void netxen_tx_timeout(struct net_device *netdev) |
963 | { | 989 | { |
964 | struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); | 990 | struct netxen_adapter *adapter = (struct netxen_adapter *) |
965 | 991 | netdev_priv(netdev); | |
966 | SCHEDULE_WORK(&port->tx_timeout_task); | 992 | SCHEDULE_WORK(&adapter->tx_timeout_task); |
967 | } | 993 | } |
968 | 994 | ||
969 | static void netxen_tx_timeout_task(struct work_struct *work) | 995 | static void netxen_tx_timeout_task(struct work_struct *work) |
970 | { | 996 | { |
971 | struct netxen_port *port = | 997 | struct netxen_adapter *adapter = |
972 | container_of(work, struct netxen_port, tx_timeout_task); | 998 | container_of(work, struct netxen_adapter, tx_timeout_task); |
973 | struct net_device *netdev = port->netdev; | 999 | struct net_device *netdev = adapter->netdev; |
974 | unsigned long flags; | 1000 | unsigned long flags; |
975 | 1001 | ||
976 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1002 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
977 | netxen_nic_driver_name, netdev->name); | 1003 | netxen_nic_driver_name, netdev->name); |
978 | 1004 | ||
979 | spin_lock_irqsave(&port->adapter->lock, flags); | 1005 | spin_lock_irqsave(&adapter->lock, flags); |
980 | netxen_nic_close(netdev); | 1006 | netxen_nic_close(netdev); |
981 | netxen_nic_open(netdev); | 1007 | netxen_nic_open(netdev); |
982 | spin_unlock_irqrestore(&port->adapter->lock, flags); | 1008 | spin_unlock_irqrestore(&adapter->lock, flags); |
983 | netdev->trans_start = jiffies; | 1009 | netdev->trans_start = jiffies; |
984 | netif_wake_queue(netdev); | 1010 | netif_wake_queue(netdev); |
985 | } | 1011 | } |
@@ -991,16 +1017,14 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | |||
991 | 1017 | ||
992 | DPRINTK(INFO, "Entered handle ISR\n"); | 1018 | DPRINTK(INFO, "Entered handle ISR\n"); |
993 | 1019 | ||
994 | adapter->stats.ints++; | ||
995 | |||
996 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1020 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
997 | int count = 0; | 1021 | int count = 0; |
998 | u32 mask; | 1022 | u32 mask; |
999 | mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); | 1023 | u32 our_int = 0; |
1000 | if ((mask & 0x80) == 0) { | 1024 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
1001 | /* not our interrupt */ | 1025 | /* not our interrupt */ |
1026 | if ((our_int & (0x80 << adapter->portnum)) == 0) | ||
1002 | return ret; | 1027 | return ret; |
1003 | } | ||
1004 | netxen_nic_disable_int(adapter); | 1028 | netxen_nic_disable_int(adapter); |
1005 | /* Window = 0 or 1 */ | 1029 | /* Window = 0 or 1 */ |
1006 | do { | 1030 | do { |
@@ -1012,7 +1036,6 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | |||
1012 | printk("Could not disable interrupt completely\n"); | 1036 | printk("Could not disable interrupt completely\n"); |
1013 | 1037 | ||
1014 | } | 1038 | } |
1015 | adapter->stats.hostints++; | ||
1016 | 1039 | ||
1017 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { | 1040 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { |
1018 | if (netif_rx_schedule_prep(netdev)) { | 1041 | if (netif_rx_schedule_prep(netdev)) { |
@@ -1046,33 +1069,24 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | |||
1046 | irqreturn_t netxen_intr(int irq, void *data) | 1069 | irqreturn_t netxen_intr(int irq, void *data) |
1047 | { | 1070 | { |
1048 | struct netxen_adapter *adapter; | 1071 | struct netxen_adapter *adapter; |
1049 | struct netxen_port *port; | ||
1050 | struct net_device *netdev; | 1072 | struct net_device *netdev; |
1051 | int i; | ||
1052 | 1073 | ||
1053 | if (unlikely(!irq)) { | 1074 | if (unlikely(!irq)) { |
1054 | return IRQ_NONE; /* Not our interrupt */ | 1075 | return IRQ_NONE; /* Not our interrupt */ |
1055 | } | 1076 | } |
1056 | 1077 | ||
1057 | adapter = (struct netxen_adapter *)data; | 1078 | adapter = (struct netxen_adapter *)data; |
1058 | for (i = 0; i < adapter->ahw.max_ports; i++) { | 1079 | netdev = adapter->netdev; |
1059 | port = adapter->port[i]; | 1080 | /* process our status queue (for all 4 ports) */ |
1060 | netdev = port->netdev; | 1081 | if (netif_running(netdev)) |
1061 | 1082 | netxen_handle_int(adapter, netdev); | |
1062 | /* process our status queue (for all 4 ports) */ | ||
1063 | if (netif_running(netdev)) { | ||
1064 | netxen_handle_int(adapter, netdev); | ||
1065 | break; | ||
1066 | } | ||
1067 | } | ||
1068 | 1083 | ||
1069 | return IRQ_HANDLED; | 1084 | return IRQ_HANDLED; |
1070 | } | 1085 | } |
1071 | 1086 | ||
1072 | static int netxen_nic_poll(struct net_device *netdev, int *budget) | 1087 | static int netxen_nic_poll(struct net_device *netdev, int *budget) |
1073 | { | 1088 | { |
1074 | struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); | 1089 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1075 | struct netxen_adapter *adapter = port->adapter; | ||
1076 | int work_to_do = min(*budget, netdev->quota); | 1090 | int work_to_do = min(*budget, netdev->quota); |
1077 | int done = 1; | 1091 | int done = 1; |
1078 | int ctx; | 1092 | int ctx; |
@@ -1080,7 +1094,6 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) | |||
1080 | int work_done = 0; | 1094 | int work_done = 0; |
1081 | 1095 | ||
1082 | DPRINTK(INFO, "polling for %d descriptors\n", *budget); | 1096 | DPRINTK(INFO, "polling for %d descriptors\n", *budget); |
1083 | port->stats.polled++; | ||
1084 | 1097 | ||
1085 | work_done = 0; | 1098 | work_done = 0; |
1086 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1099 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
@@ -1124,8 +1137,7 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) | |||
1124 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1137 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1125 | static void netxen_nic_poll_controller(struct net_device *netdev) | 1138 | static void netxen_nic_poll_controller(struct net_device *netdev) |
1126 | { | 1139 | { |
1127 | struct netxen_port *port = netdev_priv(netdev); | 1140 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1128 | struct netxen_adapter *adapter = port->adapter; | ||
1129 | disable_irq(adapter->irq); | 1141 | disable_irq(adapter->irq); |
1130 | netxen_intr(adapter->irq, adapter); | 1142 | netxen_intr(adapter->irq, adapter); |
1131 | enable_irq(adapter->irq); | 1143 | enable_irq(adapter->irq); |