diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 795 |
1 files changed, 517 insertions, 278 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 72d9f48b80dc..4d32f3cc2fbd 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -49,13 +49,22 @@ char netxen_nic_driver_name[] = "netxen_nic"; | |||
49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " | 49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " |
50 | NETXEN_NIC_LINUX_VERSIONID; | 50 | NETXEN_NIC_LINUX_VERSIONID; |
51 | 51 | ||
52 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
53 | |||
54 | /* Default to restricted 1G auto-neg mode */ | ||
55 | static int wol_port_mode = 5; | ||
56 | |||
57 | static int use_msi = 1; | ||
58 | |||
59 | static int use_msi_x = 1; | ||
60 | |||
52 | #define NETXEN_NETDEV_WEIGHT 120 | 61 | #define NETXEN_NETDEV_WEIGHT 120 |
53 | #define NETXEN_ADAPTER_UP_MAGIC 777 | 62 | #define NETXEN_ADAPTER_UP_MAGIC 777 |
54 | #define NETXEN_NIC_PEG_TUNE 0 | 63 | #define NETXEN_NIC_PEG_TUNE 0 |
55 | 64 | ||
56 | /* Local functions to NetXen NIC driver */ | 65 | /* Local functions to NetXen NIC driver */ |
57 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 66 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
58 | const struct pci_device_id *ent); | 67 | const struct pci_device_id *ent); |
59 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 68 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
60 | static int netxen_nic_open(struct net_device *netdev); | 69 | static int netxen_nic_open(struct net_device *netdev); |
61 | static int netxen_nic_close(struct net_device *netdev); | 70 | static int netxen_nic_close(struct net_device *netdev); |
@@ -135,9 +144,11 @@ netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | |||
135 | adapter->crb_addr_cmd_consumer, crb_consumer); | 144 | adapter->crb_addr_cmd_consumer, crb_consumer); |
136 | } | 145 | } |
137 | 146 | ||
138 | static uint32_t msi_tgt_status[4] = { | 147 | static uint32_t msi_tgt_status[8] = { |
139 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | 148 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, |
140 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | 149 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, |
150 | ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, | ||
151 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | ||
141 | }; | 152 | }; |
142 | 153 | ||
143 | static uint32_t sw_int_mask[4] = { | 154 | static uint32_t sw_int_mask[4] = { |
@@ -145,6 +156,8 @@ static uint32_t sw_int_mask[4] = { | |||
145 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | 156 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 |
146 | }; | 157 | }; |
147 | 158 | ||
159 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; | ||
160 | |||
148 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 161 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
149 | { | 162 | { |
150 | u32 mask = 0x7ff; | 163 | u32 mask = 0x7ff; |
@@ -159,7 +172,7 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
159 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 172 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
160 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); | 173 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
161 | 174 | ||
162 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 175 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
163 | do { | 176 | do { |
164 | adapter->pci_write_immediate(adapter, | 177 | adapter->pci_write_immediate(adapter, |
165 | ISR_INT_TARGET_STATUS, 0xffffffff); | 178 | ISR_INT_TARGET_STATUS, 0xffffffff); |
@@ -208,7 +221,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
208 | 221 | ||
209 | adapter->pci_write_normalize(adapter, sw_int_mask[port], 0x1); | 222 | adapter->pci_write_normalize(adapter, sw_int_mask[port], 0x1); |
210 | 223 | ||
211 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 224 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
212 | mask = 0xbff; | 225 | mask = 0xbff; |
213 | if (adapter->intr_scheme != -1 && | 226 | if (adapter->intr_scheme != -1 && |
214 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | 227 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { |
@@ -222,6 +235,280 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
222 | DPRINTK(1, INFO, "Done with enable Int\n"); | 235 | DPRINTK(1, INFO, "Done with enable Int\n"); |
223 | } | 236 | } |
224 | 237 | ||
238 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | ||
239 | { | ||
240 | struct pci_dev *pdev = adapter->pdev; | ||
241 | int err; | ||
242 | uint64_t mask; | ||
243 | |||
244 | #ifdef CONFIG_IA64 | ||
245 | adapter->dma_mask = DMA_32BIT_MASK; | ||
246 | #else | ||
247 | if (revision_id >= NX_P3_B0) { | ||
248 | /* should go to DMA_64BIT_MASK */ | ||
249 | adapter->dma_mask = DMA_39BIT_MASK; | ||
250 | mask = DMA_39BIT_MASK; | ||
251 | } else if (revision_id == NX_P3_A2) { | ||
252 | adapter->dma_mask = DMA_39BIT_MASK; | ||
253 | mask = DMA_39BIT_MASK; | ||
254 | } else if (revision_id == NX_P2_C1) { | ||
255 | adapter->dma_mask = DMA_35BIT_MASK; | ||
256 | mask = DMA_35BIT_MASK; | ||
257 | } else { | ||
258 | adapter->dma_mask = DMA_32BIT_MASK; | ||
259 | mask = DMA_32BIT_MASK; | ||
260 | goto set_32_bit_mask; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
265 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
266 | * come off this pool. | ||
267 | */ | ||
268 | if (pci_set_dma_mask(pdev, mask) == 0 && | ||
269 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) { | ||
270 | adapter->pci_using_dac = 1; | ||
271 | return 0; | ||
272 | } | ||
273 | #endif /* CONFIG_IA64 */ | ||
274 | |||
275 | set_32_bit_mask: | ||
276 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
277 | if (!err) | ||
278 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
279 | if (err) { | ||
280 | DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err); | ||
281 | return err; | ||
282 | } | ||
283 | |||
284 | adapter->pci_using_dac = 0; | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static void netxen_check_options(struct netxen_adapter *adapter) | ||
289 | { | ||
290 | switch (adapter->ahw.boardcfg.board_type) { | ||
291 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
292 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
293 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
294 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
295 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
296 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
297 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
298 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
299 | adapter->msix_supported = !!use_msi_x; | ||
300 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
301 | break; | ||
302 | |||
303 | case NETXEN_BRDTYPE_P2_SB31_10G: | ||
304 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
305 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | ||
306 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
307 | adapter->msix_supported = 0; | ||
308 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
309 | break; | ||
310 | |||
311 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
312 | case NETXEN_BRDTYPE_P3_4_GB: | ||
313 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
314 | case NETXEN_BRDTYPE_P2_SB35_4G: | ||
315 | case NETXEN_BRDTYPE_P2_SB31_2G: | ||
316 | adapter->msix_supported = 0; | ||
317 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
318 | break; | ||
319 | |||
320 | default: | ||
321 | adapter->msix_supported = 0; | ||
322 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
323 | |||
324 | printk(KERN_WARNING "Unknown board type(0x%x)\n", | ||
325 | adapter->ahw.boardcfg.board_type); | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
330 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
331 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
332 | |||
333 | adapter->max_possible_rss_rings = 1; | ||
334 | return; | ||
335 | } | ||
336 | |||
337 | static int | ||
338 | netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | ||
339 | { | ||
340 | int ret = 0; | ||
341 | |||
342 | if (first_boot == 0x55555555) { | ||
343 | /* This is the first boot after power up */ | ||
344 | |||
345 | /* PCI bus master workaround */ | ||
346 | adapter->hw_read_wx(adapter, | ||
347 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
348 | if (!(first_boot & 0x4)) { | ||
349 | first_boot |= 0x4; | ||
350 | adapter->hw_write_wx(adapter, | ||
351 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
352 | adapter->hw_read_wx(adapter, | ||
353 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
354 | } | ||
355 | |||
356 | /* This is the first boot after power up */ | ||
357 | adapter->hw_read_wx(adapter, | ||
358 | NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4); | ||
359 | if (first_boot != 0x80000f) { | ||
360 | /* clear the register for future unloads/loads */ | ||
361 | adapter->pci_write_normalize(adapter, | ||
362 | NETXEN_CAM_RAM(0x1fc), 0); | ||
363 | ret = -1; | ||
364 | } | ||
365 | |||
366 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
367 | /* Start P2 boot loader */ | ||
368 | adapter->pci_write_normalize(adapter, | ||
369 | NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
370 | adapter->pci_write_normalize(adapter, | ||
371 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
372 | } | ||
373 | } | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static void netxen_set_port_mode(struct netxen_adapter *adapter) | ||
378 | { | ||
379 | u32 val, data; | ||
380 | |||
381 | val = adapter->ahw.boardcfg.board_type; | ||
382 | if ((val == NETXEN_BRDTYPE_P3_HMEZ) || | ||
383 | (val == NETXEN_BRDTYPE_P3_XG_LOM)) { | ||
384 | if (port_mode == NETXEN_PORT_MODE_802_3_AP) { | ||
385 | data = NETXEN_PORT_MODE_802_3_AP; | ||
386 | adapter->hw_write_wx(adapter, | ||
387 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
388 | } else if (port_mode == NETXEN_PORT_MODE_XG) { | ||
389 | data = NETXEN_PORT_MODE_XG; | ||
390 | adapter->hw_write_wx(adapter, | ||
391 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
392 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { | ||
393 | data = NETXEN_PORT_MODE_AUTO_NEG_1G; | ||
394 | adapter->hw_write_wx(adapter, | ||
395 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
396 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { | ||
397 | data = NETXEN_PORT_MODE_AUTO_NEG_XG; | ||
398 | adapter->hw_write_wx(adapter, | ||
399 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
400 | } else { | ||
401 | data = NETXEN_PORT_MODE_AUTO_NEG; | ||
402 | adapter->hw_write_wx(adapter, | ||
403 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
404 | } | ||
405 | |||
406 | if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && | ||
407 | (wol_port_mode != NETXEN_PORT_MODE_XG) && | ||
408 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) && | ||
409 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) { | ||
410 | wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
411 | } | ||
412 | adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, | ||
413 | &wol_port_mode, 4); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | #define PCI_CAP_ID_GEN 0x10 | ||
418 | |||
419 | static void netxen_pcie_strap_init(struct netxen_adapter *adapter) | ||
420 | { | ||
421 | u32 pdevfuncsave; | ||
422 | u32 c8c9value = 0; | ||
423 | u32 chicken = 0; | ||
424 | u32 control = 0; | ||
425 | int i, pos; | ||
426 | struct pci_dev *pdev; | ||
427 | |||
428 | pdev = pci_get_device(0x1166, 0x0140, NULL); | ||
429 | if (pdev) { | ||
430 | pci_dev_put(pdev); | ||
431 | adapter->hw_read_wx(adapter, | ||
432 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
433 | chicken |= 0x4000; | ||
434 | adapter->hw_write_wx(adapter, | ||
435 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
436 | } | ||
437 | |||
438 | pdev = adapter->pdev; | ||
439 | |||
440 | adapter->hw_read_wx(adapter, | ||
441 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
442 | /* clear chicken3.25:24 */ | ||
443 | chicken &= 0xFCFFFFFF; | ||
444 | /* | ||
445 | * if gen1 and B0, set F1020 - if gen 2, do nothing | ||
446 | * if gen2 set to F1000 | ||
447 | */ | ||
448 | pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); | ||
449 | if (pos == 0xC0) { | ||
450 | pci_read_config_dword(pdev, pos + 0x10, &control); | ||
451 | if ((control & 0x000F0000) != 0x00020000) { | ||
452 | /* set chicken3.24 if gen1 */ | ||
453 | chicken |= 0x01000000; | ||
454 | } | ||
455 | printk(KERN_INFO "%s Gen2 strapping detected\n", | ||
456 | netxen_nic_driver_name); | ||
457 | c8c9value = 0xF1000; | ||
458 | } else { | ||
459 | /* set chicken3.24 if gen1 */ | ||
460 | chicken |= 0x01000000; | ||
461 | printk(KERN_INFO "%s Gen1 strapping detected\n", | ||
462 | netxen_nic_driver_name); | ||
463 | if (adapter->ahw.revision_id == NX_P3_B0) | ||
464 | c8c9value = 0xF1020; | ||
465 | else | ||
466 | c8c9value = 0; | ||
467 | |||
468 | } | ||
469 | adapter->hw_write_wx(adapter, | ||
470 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
471 | |||
472 | if (!c8c9value) | ||
473 | return; | ||
474 | |||
475 | pdevfuncsave = pdev->devfn; | ||
476 | if (pdevfuncsave & 0x07) | ||
477 | return; | ||
478 | |||
479 | for (i = 0; i < 8; i++) { | ||
480 | pci_read_config_dword(pdev, pos + 8, &control); | ||
481 | pci_read_config_dword(pdev, pos + 8, &control); | ||
482 | pci_write_config_dword(pdev, pos + 8, c8c9value); | ||
483 | pdev->devfn++; | ||
484 | } | ||
485 | pdev->devfn = pdevfuncsave; | ||
486 | } | ||
487 | |||
488 | static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) | ||
489 | { | ||
490 | u32 control; | ||
491 | int pos; | ||
492 | |||
493 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
494 | if (pos) { | ||
495 | pci_read_config_dword(pdev, pos, &control); | ||
496 | if (enable) | ||
497 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
498 | else | ||
499 | control = 0; | ||
500 | pci_write_config_dword(pdev, pos, control); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static void netxen_init_msix_entries(struct netxen_adapter *adapter) | ||
505 | { | ||
506 | int i; | ||
507 | |||
508 | for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++) | ||
509 | adapter->msix_entries[i].entry = i; | ||
510 | } | ||
511 | |||
225 | /* | 512 | /* |
226 | * netxen_nic_probe() | 513 | * netxen_nic_probe() |
227 | * | 514 | * |
@@ -247,28 +534,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
247 | 534 | ||
248 | 535 | ||
249 | u8 __iomem *db_ptr = NULL; | 536 | u8 __iomem *db_ptr = NULL; |
250 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0; | 537 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; |
251 | int pci_using_dac, i = 0, err; | 538 | int i = 0, err; |
252 | int ring; | 539 | int first_driver, first_boot; |
253 | struct netxen_recv_context *recv_ctx = NULL; | ||
254 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | ||
255 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | ||
256 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; | 540 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; |
257 | int valid_mac = 0; | ||
258 | u32 val; | 541 | u32 val; |
259 | int pci_func_id = PCI_FUNC(pdev->devfn); | 542 | int pci_func_id = PCI_FUNC(pdev->devfn); |
260 | DECLARE_MAC_BUF(mac); | 543 | DECLARE_MAC_BUF(mac); |
544 | struct netxen_legacy_intr_set *legacy_intrp; | ||
545 | uint8_t revision_id; | ||
261 | 546 | ||
262 | if (pci_func_id == 0) | 547 | if (pci_func_id == 0) |
263 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 548 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
264 | 549 | ||
265 | if (pdev->class != 0x020000) { | 550 | if (pdev->class != 0x020000) { |
266 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | 551 | printk(KERN_DEBUG "NetXen function %d, class %x will not " |
267 | "be enabled.\n",pci_func_id, pdev->class); | 552 | "be enabled.\n",pci_func_id, pdev->class); |
268 | return -ENODEV; | 553 | return -ENODEV; |
269 | } | 554 | } |
555 | |||
270 | if ((err = pci_enable_device(pdev))) | 556 | if ((err = pci_enable_device(pdev))) |
271 | return err; | 557 | return err; |
558 | |||
272 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 559 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
273 | err = -ENODEV; | 560 | err = -ENODEV; |
274 | goto err_out_disable_pdev; | 561 | goto err_out_disable_pdev; |
@@ -278,18 +565,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
278 | goto err_out_disable_pdev; | 565 | goto err_out_disable_pdev; |
279 | 566 | ||
280 | pci_set_master(pdev); | 567 | pci_set_master(pdev); |
281 | if (pdev->revision == NX_P2_C1 && | ||
282 | (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && | ||
283 | (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { | ||
284 | pci_using_dac = 1; | ||
285 | } else { | ||
286 | if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || | ||
287 | (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) | ||
288 | goto err_out_free_res; | ||
289 | |||
290 | pci_using_dac = 0; | ||
291 | } | ||
292 | |||
293 | 568 | ||
294 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 569 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
295 | if(!netdev) { | 570 | if(!netdev) { |
@@ -302,8 +577,17 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
302 | SET_NETDEV_DEV(netdev, &pdev->dev); | 577 | SET_NETDEV_DEV(netdev, &pdev->dev); |
303 | 578 | ||
304 | adapter = netdev->priv; | 579 | adapter = netdev->priv; |
305 | 580 | adapter->netdev = netdev; | |
581 | adapter->pdev = pdev; | ||
306 | adapter->ahw.pci_func = pci_func_id; | 582 | adapter->ahw.pci_func = pci_func_id; |
583 | |||
584 | revision_id = pdev->revision; | ||
585 | adapter->ahw.revision_id = revision_id; | ||
586 | |||
587 | err = nx_set_dma_mask(adapter, revision_id); | ||
588 | if (err) | ||
589 | goto err_out_free_netdev; | ||
590 | |||
307 | rwlock_init(&adapter->adapter_lock); | 591 | rwlock_init(&adapter->adapter_lock); |
308 | adapter->ahw.qdr_sn_window = -1; | 592 | adapter->ahw.qdr_sn_window = -1; |
309 | adapter->ahw.ddr_mn_window = -1; | 593 | adapter->ahw.ddr_mn_window = -1; |
@@ -379,7 +663,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
379 | 663 | ||
380 | if (db_len == 0) { | 664 | if (db_len == 0) { |
381 | printk(KERN_ERR "%s: doorbell is disabled\n", | 665 | printk(KERN_ERR "%s: doorbell is disabled\n", |
382 | netxen_nic_driver_name); | 666 | netxen_nic_driver_name); |
383 | err = -EIO; | 667 | err = -EIO; |
384 | goto err_out_iounmap; | 668 | goto err_out_iounmap; |
385 | } | 669 | } |
@@ -389,7 +673,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
389 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); | 673 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); |
390 | if (!db_ptr) { | 674 | if (!db_ptr) { |
391 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", | 675 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", |
392 | netxen_nic_driver_name); | 676 | netxen_nic_driver_name); |
393 | err = -EIO; | 677 | err = -EIO; |
394 | goto err_out_iounmap; | 678 | goto err_out_iounmap; |
395 | } | 679 | } |
@@ -404,11 +688,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
404 | adapter->ahw.db_base = db_ptr; | 688 | adapter->ahw.db_base = db_ptr; |
405 | adapter->ahw.db_len = db_len; | 689 | adapter->ahw.db_len = db_len; |
406 | 690 | ||
407 | adapter->netdev = netdev; | ||
408 | adapter->pdev = pdev; | ||
409 | |||
410 | netif_napi_add(netdev, &adapter->napi, | 691 | netif_napi_add(netdev, &adapter->napi, |
411 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); | 692 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); |
693 | |||
694 | if (revision_id >= NX_P3_B0) | ||
695 | legacy_intrp = &legacy_intr[pci_func_id]; | ||
696 | else | ||
697 | legacy_intrp = &legacy_intr[0]; | ||
698 | |||
699 | adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit; | ||
700 | adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg; | ||
701 | adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg; | ||
702 | adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg; | ||
412 | 703 | ||
413 | /* this will be read from FW later */ | 704 | /* this will be read from FW later */ |
414 | adapter->intr_scheme = -1; | 705 | adapter->intr_scheme = -1; |
@@ -418,8 +709,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
418 | adapter->portnum = pci_func_id; | 709 | adapter->portnum = pci_func_id; |
419 | adapter->status &= ~NETXEN_NETDEV_STATUS; | 710 | adapter->status &= ~NETXEN_NETDEV_STATUS; |
420 | adapter->rx_csum = 1; | 711 | adapter->rx_csum = 1; |
421 | adapter->max_mc_count = 16; | ||
422 | adapter->mc_enabled = 0; | 712 | adapter->mc_enabled = 0; |
713 | if (NX_IS_REVISION_P3(revision_id)) | ||
714 | adapter->max_mc_count = 38; | ||
715 | else | ||
716 | adapter->max_mc_count = 16; | ||
423 | 717 | ||
424 | netdev->open = netxen_nic_open; | 718 | netdev->open = netxen_nic_open; |
425 | netdev->stop = netxen_nic_close; | 719 | netdev->stop = netxen_nic_close; |
@@ -441,18 +735,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
441 | netdev->features = NETIF_F_SG; | 735 | netdev->features = NETIF_F_SG; |
442 | netdev->features |= NETIF_F_IP_CSUM; | 736 | netdev->features |= NETIF_F_IP_CSUM; |
443 | netdev->features |= NETIF_F_TSO; | 737 | netdev->features |= NETIF_F_TSO; |
738 | if (NX_IS_REVISION_P3(revision_id)) | ||
739 | netdev->features |= NETIF_F_TSO6; | ||
444 | 740 | ||
445 | if (pci_using_dac) | 741 | if (adapter->pci_using_dac) |
446 | netdev->features |= NETIF_F_HIGHDMA; | 742 | netdev->features |= NETIF_F_HIGHDMA; |
447 | 743 | ||
448 | if (pci_enable_msi(pdev)) | ||
449 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | ||
450 | else | ||
451 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
452 | |||
453 | netdev->irq = pdev->irq; | ||
454 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
455 | |||
456 | /* | 744 | /* |
457 | * Set the CRB window to invalid. If any register in window 0 is | 745 | * Set the CRB window to invalid. If any register in window 0 is |
458 | * accessed it should set the window to 0 and then reset it to 1. | 746 | * accessed it should set the window to 0 and then reset it to 1. |
@@ -461,87 +749,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
461 | 749 | ||
462 | if (netxen_nic_get_board_info(adapter) != 0) { | 750 | if (netxen_nic_get_board_info(adapter) != 0) { |
463 | printk("%s: Error getting board config info.\n", | 751 | printk("%s: Error getting board config info.\n", |
464 | netxen_nic_driver_name); | 752 | netxen_nic_driver_name); |
465 | err = -EIO; | 753 | err = -EIO; |
466 | goto err_out_iounmap; | 754 | goto err_out_iounmap; |
467 | } | 755 | } |
468 | 756 | ||
469 | /* | ||
470 | * Adapter in our case is quad port so initialize it before | ||
471 | * initializing the ports | ||
472 | */ | ||
473 | |||
474 | netxen_initialize_adapter_ops(adapter); | 757 | netxen_initialize_adapter_ops(adapter); |
475 | 758 | ||
476 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
477 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | ||
478 | (adapter->ahw.boardcfg.board_type == | ||
479 | NETXEN_BRDTYPE_P2_SB31_2G)) | ||
480 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
481 | else | ||
482 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | ||
483 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
484 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
485 | |||
486 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | ||
487 | if (cmd_buf_arr == NULL) { | ||
488 | printk(KERN_ERR | ||
489 | "%s: Could not allocate cmd_buf_arr memory:%d\n", | ||
490 | netxen_nic_driver_name, (int)TX_RINGSIZE); | ||
491 | err = -ENOMEM; | ||
492 | goto err_out_free_adapter; | ||
493 | } | ||
494 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
495 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
496 | |||
497 | for (i = 0; i < MAX_RCV_CTX; ++i) { | ||
498 | recv_ctx = &adapter->recv_ctx[i]; | ||
499 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
500 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
501 | switch (RCV_DESC_TYPE(ring)) { | ||
502 | case RCV_DESC_NORMAL: | ||
503 | rcv_desc->max_rx_desc_count = | ||
504 | adapter->max_rx_desc_count; | ||
505 | rcv_desc->flags = RCV_DESC_NORMAL; | ||
506 | rcv_desc->dma_size = RX_DMA_MAP_LEN; | ||
507 | rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH; | ||
508 | break; | ||
509 | |||
510 | case RCV_DESC_JUMBO: | ||
511 | rcv_desc->max_rx_desc_count = | ||
512 | adapter->max_jumbo_rx_desc_count; | ||
513 | rcv_desc->flags = RCV_DESC_JUMBO; | ||
514 | rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN; | ||
515 | rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; | ||
516 | break; | ||
517 | |||
518 | case RCV_RING_LRO: | ||
519 | rcv_desc->max_rx_desc_count = | ||
520 | adapter->max_lro_rx_desc_count; | ||
521 | rcv_desc->flags = RCV_DESC_LRO; | ||
522 | rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; | ||
523 | rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
524 | break; | ||
525 | |||
526 | } | ||
527 | rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) | ||
528 | vmalloc(RCV_BUFFSIZE); | ||
529 | |||
530 | if (rcv_desc->rx_buf_arr == NULL) { | ||
531 | printk(KERN_ERR "%s: Could not allocate " | ||
532 | "rcv_desc->rx_buf_arr memory:%d\n", | ||
533 | netxen_nic_driver_name, | ||
534 | (int)RCV_BUFFSIZE); | ||
535 | err = -ENOMEM; | ||
536 | goto err_out_free_rx_buffer; | ||
537 | } | ||
538 | memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
539 | } | ||
540 | |||
541 | } | ||
542 | |||
543 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | ||
544 | |||
545 | /* Mezz cards have PCI function 0,2,3 enabled */ | 759 | /* Mezz cards have PCI function 0,2,3 enabled */ |
546 | switch (adapter->ahw.boardcfg.board_type) { | 760 | switch (adapter->ahw.boardcfg.board_type) { |
547 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 761 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
@@ -553,81 +767,51 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
553 | break; | 767 | break; |
554 | } | 768 | } |
555 | 769 | ||
556 | init_timer(&adapter->watchdog_timer); | 770 | /* |
557 | adapter->ahw.xg_linkup = 0; | 771 | * This call will setup various max rx/tx counts. |
558 | adapter->watchdog_timer.function = &netxen_watchdog; | 772 | * It must be done before any buffer/ring allocations. |
559 | adapter->watchdog_timer.data = (unsigned long)adapter; | 773 | */ |
560 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 774 | netxen_check_options(adapter); |
561 | adapter->ahw.revision_id = pdev->revision; | ||
562 | 775 | ||
776 | first_driver = 0; | ||
777 | if (NX_IS_REVISION_P3(revision_id)) { | ||
778 | if (adapter->ahw.pci_func == 0) | ||
779 | first_driver = 1; | ||
780 | } else { | ||
781 | if (adapter->portnum == 0) | ||
782 | first_driver = 1; | ||
783 | } | ||
563 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; | 784 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; |
564 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; | 785 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; |
565 | netxen_nic_update_cmd_producer(adapter, 0); | 786 | netxen_nic_update_cmd_producer(adapter, 0); |
566 | netxen_nic_update_cmd_consumer(adapter, 0); | 787 | netxen_nic_update_cmd_consumer(adapter, 0); |
567 | 788 | ||
568 | if (netxen_is_flash_supported(adapter) == 0 && | 789 | if (first_driver) { |
569 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 790 | first_boot = adapter->pci_read_normalize(adapter, |
570 | valid_mac = 1; | 791 | NETXEN_CAM_RAM(0x1fc)); |
571 | else | ||
572 | valid_mac = 0; | ||
573 | |||
574 | if (valid_mac) { | ||
575 | unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
576 | netdev->dev_addr[0] = *(p + 5); | ||
577 | netdev->dev_addr[1] = *(p + 4); | ||
578 | netdev->dev_addr[2] = *(p + 3); | ||
579 | netdev->dev_addr[3] = *(p + 2); | ||
580 | netdev->dev_addr[4] = *(p + 1); | ||
581 | netdev->dev_addr[5] = *(p + 0); | ||
582 | 792 | ||
583 | memcpy(netdev->perm_addr, netdev->dev_addr, | 793 | err = netxen_check_hw_init(adapter, first_boot); |
584 | netdev->addr_len); | 794 | if (err) { |
585 | if (!is_valid_ether_addr(netdev->perm_addr)) { | 795 | printk(KERN_ERR "%s: error in init HW init sequence\n", |
586 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | 796 | netxen_nic_driver_name); |
587 | netxen_nic_driver_name, | 797 | goto err_out_iounmap; |
588 | print_mac(mac, netdev->dev_addr)); | ||
589 | } else { | ||
590 | if (adapter->macaddr_set) | ||
591 | adapter->macaddr_set(adapter, | ||
592 | netdev->dev_addr); | ||
593 | } | 798 | } |
594 | } | ||
595 | 799 | ||
596 | if (adapter->portnum == 0) { | 800 | if (NX_IS_REVISION_P3(revision_id)) |
597 | err = netxen_initialize_adapter_offload(adapter); | 801 | netxen_set_port_mode(adapter); |
598 | if (err) | 802 | |
599 | goto err_out_free_rx_buffer; | 803 | if (first_boot != 0x55555555) { |
600 | val = adapter->pci_read_normalize(adapter, | ||
601 | NETXEN_CAM_RAM(0x1fc)); | ||
602 | if (val == 0x55555555) { | ||
603 | /* This is the first boot after power up */ | ||
604 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
605 | if (!(val & 0x4)) { | ||
606 | val |= 0x4; | ||
607 | netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); | ||
608 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
609 | if (!(val & 0x4)) | ||
610 | printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", | ||
611 | netxen_nic_driver_name); | ||
612 | } | ||
613 | val = adapter->pci_read_normalize(adapter, | ||
614 | NETXEN_ROMUSB_GLB_SW_RESET); | ||
615 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | ||
616 | if (val != 0x80000f) { | ||
617 | /* clear the register for future unloads/loads */ | ||
618 | adapter->pci_write_normalize(adapter, | ||
619 | NETXEN_CAM_RAM(0x1fc), 0); | ||
620 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | ||
621 | err = -ENODEV; | ||
622 | goto err_out_free_dev; | ||
623 | } | ||
624 | } else { | ||
625 | adapter->pci_write_normalize(adapter, | 804 | adapter->pci_write_normalize(adapter, |
626 | CRB_CMDPEG_STATE, 0); | 805 | CRB_CMDPEG_STATE, 0); |
627 | netxen_pinit_from_rom(adapter, 0); | 806 | netxen_pinit_from_rom(adapter, 0); |
628 | msleep(1); | 807 | msleep(1); |
629 | netxen_load_firmware(adapter); | 808 | netxen_load_firmware(adapter); |
630 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 809 | } |
810 | |||
811 | if (NX_IS_REVISION_P3(revision_id)) | ||
812 | netxen_pcie_strap_init(adapter); | ||
813 | |||
814 | if (NX_IS_REVISION_P2(revision_id)) { | ||
631 | 815 | ||
632 | /* Initialize multicast addr pool owners */ | 816 | /* Initialize multicast addr pool owners */ |
633 | val = 0x7654; | 817 | val = 0x7654; |
@@ -638,10 +822,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
638 | 822 | ||
639 | } | 823 | } |
640 | 824 | ||
641 | /* clear the register for future unloads/loads */ | 825 | if ((first_boot == 0x55555555) && |
642 | adapter->pci_write_normalize(adapter, NETXEN_CAM_RAM(0x1fc), 0); | 826 | (NX_IS_REVISION_P2(revision_id))) { |
643 | dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n", | 827 | /* Unlock the HW, prompting the boot sequence */ |
644 | adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE)); | 828 | adapter->pci_write_normalize(adapter, |
829 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
830 | } | ||
831 | |||
832 | err = netxen_initialize_adapter_offload(adapter); | ||
833 | if (err) | ||
834 | goto err_out_iounmap; | ||
645 | 835 | ||
646 | /* | 836 | /* |
647 | * Tell the hardware our version number. | 837 | * Tell the hardware our version number. |
@@ -651,12 +841,19 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
651 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 841 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
652 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); | 842 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); |
653 | 843 | ||
654 | /* Unlock the HW, prompting the boot sequence */ | ||
655 | adapter->pci_write_normalize(adapter, | ||
656 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
657 | /* Handshake with the card before we register the devices. */ | 844 | /* Handshake with the card before we register the devices. */ |
658 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 845 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
659 | } | 846 | |
847 | if (NX_IS_REVISION_P3(revision_id)) { | ||
848 | adapter->hw_read_wx(adapter, | ||
849 | NETXEN_MIU_MN_CONTROL, &val, 4); | ||
850 | adapter->ahw.cut_through = (val & 0x4) ? 1 : 0; | ||
851 | dev_info(&pdev->dev, "firmware running in %s mode\n", | ||
852 | adapter->ahw.cut_through ? "cut through" : "legacy"); | ||
853 | } | ||
854 | } /* first_driver */ | ||
855 | |||
856 | netxen_nic_flash_print(adapter); | ||
660 | 857 | ||
661 | /* | 858 | /* |
662 | * See if the firmware gave us a virtual-physical port mapping. | 859 | * See if the firmware gave us a virtual-physical port mapping. |
@@ -666,6 +863,76 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
666 | if (i != 0x55555555) | 863 | if (i != 0x55555555) |
667 | adapter->physical_port = i; | 864 | adapter->physical_port = i; |
668 | 865 | ||
866 | adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); | ||
867 | |||
868 | netxen_set_msix_bit(pdev, 0); | ||
869 | |||
870 | if (NX_IS_REVISION_P3(revision_id)) { | ||
871 | if ((mem_len != NETXEN_PCI_128MB_SIZE) && | ||
872 | mem_len != NETXEN_PCI_2MB_SIZE) | ||
873 | adapter->msix_supported = 0; | ||
874 | } | ||
875 | |||
876 | if (adapter->msix_supported) { | ||
877 | |||
878 | netxen_init_msix_entries(adapter); | ||
879 | |||
880 | if (pci_enable_msix(pdev, adapter->msix_entries, | ||
881 | MSIX_ENTRIES_PER_ADAPTER)) | ||
882 | goto request_msi; | ||
883 | |||
884 | adapter->flags |= NETXEN_NIC_MSIX_ENABLED; | ||
885 | netxen_set_msix_bit(pdev, 1); | ||
886 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | ||
887 | |||
888 | } else { | ||
889 | request_msi: | ||
890 | if (use_msi && !pci_enable_msi(pdev)) { | ||
891 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
892 | dev_info(&pdev->dev, "using msi interrupts\n"); | ||
893 | } else | ||
894 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
895 | } | ||
896 | |||
897 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
898 | netdev->irq = adapter->msix_entries[0].vector; | ||
899 | else | ||
900 | netdev->irq = pdev->irq; | ||
901 | |||
902 | err = netxen_receive_peg_ready(adapter); | ||
903 | if (err) | ||
904 | goto err_out_disable_msi; | ||
905 | |||
906 | init_timer(&adapter->watchdog_timer); | ||
907 | adapter->ahw.xg_linkup = 0; | ||
908 | adapter->watchdog_timer.function = &netxen_watchdog; | ||
909 | adapter->watchdog_timer.data = (unsigned long)adapter; | ||
910 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | ||
911 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
912 | |||
913 | if (netxen_is_flash_supported(adapter) == 0 && | ||
914 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { | ||
915 | unsigned char *p; | ||
916 | |||
917 | p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
918 | netdev->dev_addr[0] = *(p + 5); | ||
919 | netdev->dev_addr[1] = *(p + 4); | ||
920 | netdev->dev_addr[2] = *(p + 3); | ||
921 | netdev->dev_addr[3] = *(p + 2); | ||
922 | netdev->dev_addr[4] = *(p + 1); | ||
923 | netdev->dev_addr[5] = *(p + 0); | ||
924 | |||
925 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
926 | netdev->addr_len); | ||
927 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
928 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | ||
929 | netxen_nic_driver_name, | ||
930 | print_mac(mac, netdev->dev_addr)); | ||
931 | } else { | ||
932 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
933 | } | ||
934 | } | ||
935 | |||
669 | netif_carrier_off(netdev); | 936 | netif_carrier_off(netdev); |
670 | netif_stop_queue(netdev); | 937 | netif_stop_queue(netdev); |
671 | 938 | ||
@@ -674,41 +941,37 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
674 | " aborting\n", netxen_nic_driver_name, | 941 | " aborting\n", netxen_nic_driver_name, |
675 | adapter->portnum); | 942 | adapter->portnum); |
676 | err = -EIO; | 943 | err = -EIO; |
677 | goto err_out_free_dev; | 944 | goto err_out_disable_msi; |
678 | } | 945 | } |
679 | 946 | ||
680 | netxen_nic_flash_print(adapter); | ||
681 | pci_set_drvdata(pdev, adapter); | 947 | pci_set_drvdata(pdev, adapter); |
682 | 948 | ||
683 | return 0; | 949 | switch (adapter->ahw.board_type) { |
684 | 950 | case NETXEN_NIC_GBE: | |
685 | err_out_free_dev: | 951 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", |
686 | if (adapter->portnum == 0) | 952 | adapter->netdev->name); |
687 | netxen_free_adapter_offload(adapter); | 953 | break; |
688 | 954 | case NETXEN_NIC_XGBE: | |
689 | err_out_free_rx_buffer: | 955 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", |
690 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 956 | adapter->netdev->name); |
691 | recv_ctx = &adapter->recv_ctx[i]; | 957 | break; |
692 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
693 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
694 | if (rcv_desc->rx_buf_arr != NULL) { | ||
695 | vfree(rcv_desc->rx_buf_arr); | ||
696 | rcv_desc->rx_buf_arr = NULL; | ||
697 | } | ||
698 | } | ||
699 | } | 958 | } |
700 | vfree(cmd_buf_arr); | ||
701 | 959 | ||
702 | err_out_free_adapter: | 960 | return 0; |
961 | |||
962 | err_out_disable_msi: | ||
963 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
964 | pci_disable_msix(pdev); | ||
703 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 965 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
704 | pci_disable_msi(pdev); | 966 | pci_disable_msi(pdev); |
705 | 967 | ||
706 | pci_set_drvdata(pdev, NULL); | 968 | if (first_driver) |
969 | netxen_free_adapter_offload(adapter); | ||
707 | 970 | ||
971 | err_out_iounmap: | ||
708 | if (db_ptr) | 972 | if (db_ptr) |
709 | iounmap(db_ptr); | 973 | iounmap(db_ptr); |
710 | 974 | ||
711 | err_out_iounmap: | ||
712 | if (mem_ptr0) | 975 | if (mem_ptr0) |
713 | iounmap(mem_ptr0); | 976 | iounmap(mem_ptr0); |
714 | if (mem_ptr1) | 977 | if (mem_ptr1) |
@@ -723,6 +986,7 @@ err_out_free_res: | |||
723 | pci_release_regions(pdev); | 986 | pci_release_regions(pdev); |
724 | 987 | ||
725 | err_out_disable_pdev: | 988 | err_out_disable_pdev: |
989 | pci_set_drvdata(pdev, NULL); | ||
726 | pci_disable_device(pdev); | 990 | pci_disable_device(pdev); |
727 | return err; | 991 | return err; |
728 | } | 992 | } |
@@ -731,11 +995,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
731 | { | 995 | { |
732 | struct netxen_adapter *adapter; | 996 | struct netxen_adapter *adapter; |
733 | struct net_device *netdev; | 997 | struct net_device *netdev; |
734 | struct netxen_rx_buffer *buffer; | ||
735 | struct netxen_recv_context *recv_ctx; | ||
736 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
737 | int i, ctxid, ring; | ||
738 | static int init_firmware_done = 0; | ||
739 | 998 | ||
740 | adapter = pci_get_drvdata(pdev); | 999 | adapter = pci_get_drvdata(pdev); |
741 | if (adapter == NULL) | 1000 | if (adapter == NULL) |
@@ -746,36 +1005,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
746 | unregister_netdev(netdev); | 1005 | unregister_netdev(netdev); |
747 | 1006 | ||
748 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1007 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
749 | init_firmware_done++; | ||
750 | netxen_free_hw_resources(adapter); | 1008 | netxen_free_hw_resources(adapter); |
1009 | netxen_free_sw_resources(adapter); | ||
751 | } | 1010 | } |
752 | 1011 | ||
753 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | ||
754 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
755 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
756 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
757 | for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) { | ||
758 | buffer = &(rcv_desc->rx_buf_arr[i]); | ||
759 | if (buffer->state == NETXEN_BUFFER_FREE) | ||
760 | continue; | ||
761 | pci_unmap_single(pdev, buffer->dma, | ||
762 | rcv_desc->dma_size, | ||
763 | PCI_DMA_FROMDEVICE); | ||
764 | if (buffer->skb != NULL) | ||
765 | dev_kfree_skb_any(buffer->skb); | ||
766 | } | ||
767 | vfree(rcv_desc->rx_buf_arr); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | vfree(adapter->cmd_buf_arr); | ||
772 | |||
773 | if (adapter->portnum == 0) | 1012 | if (adapter->portnum == 0) |
774 | netxen_free_adapter_offload(adapter); | 1013 | netxen_free_adapter_offload(adapter); |
775 | 1014 | ||
776 | if (adapter->irq) | 1015 | if (adapter->irq) |
777 | free_irq(adapter->irq, adapter); | 1016 | free_irq(adapter->irq, adapter); |
778 | 1017 | ||
1018 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
1019 | pci_disable_msix(pdev); | ||
779 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 1020 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
780 | pci_disable_msi(pdev); | 1021 | pci_disable_msi(pdev); |
781 | 1022 | ||
@@ -813,52 +1054,67 @@ static int netxen_nic_open(struct net_device *netdev) | |||
813 | return -EIO; | 1054 | return -EIO; |
814 | } | 1055 | } |
815 | 1056 | ||
816 | /* setup all the resources for the Phantom... */ | 1057 | err = netxen_alloc_sw_resources(adapter); |
817 | /* this include the descriptors for rcv, tx, and status */ | ||
818 | netxen_nic_clear_stats(adapter); | ||
819 | err = netxen_nic_hw_resources(adapter); | ||
820 | if (err) { | 1058 | if (err) { |
821 | printk(KERN_ERR "Error in setting hw resources:%d\n", | 1059 | printk(KERN_ERR "%s: Error in setting sw resources\n", |
822 | err); | 1060 | netdev->name); |
823 | return err; | 1061 | return err; |
824 | } | 1062 | } |
1063 | |||
1064 | netxen_nic_clear_stats(adapter); | ||
1065 | |||
1066 | err = netxen_alloc_hw_resources(adapter); | ||
1067 | if (err) { | ||
1068 | printk(KERN_ERR "%s: Error in setting hw resources\n", | ||
1069 | netdev->name); | ||
1070 | goto err_out_free_sw; | ||
1071 | } | ||
1072 | |||
1073 | if (adapter->fw_major < 4) { | ||
1074 | adapter->crb_addr_cmd_producer = | ||
1075 | crb_cmd_producer[adapter->portnum]; | ||
1076 | adapter->crb_addr_cmd_consumer = | ||
1077 | crb_cmd_consumer[adapter->portnum]; | ||
1078 | } | ||
1079 | |||
1080 | netxen_nic_update_cmd_producer(adapter, 0); | ||
1081 | netxen_nic_update_cmd_consumer(adapter, 0); | ||
1082 | |||
825 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1083 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
826 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) | 1084 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) |
827 | netxen_post_rx_buffers(adapter, ctx, ring); | 1085 | netxen_post_rx_buffers(adapter, ctx, ring); |
828 | } | 1086 | } |
829 | adapter->irq = adapter->pdev->irq; | 1087 | if (NETXEN_IS_MSI_FAMILY(adapter)) |
830 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
831 | handler = netxen_msi_intr; | 1088 | handler = netxen_msi_intr; |
832 | else { | 1089 | else { |
833 | flags |= IRQF_SHARED; | 1090 | flags |= IRQF_SHARED; |
834 | handler = netxen_intr; | 1091 | handler = netxen_intr; |
835 | } | 1092 | } |
1093 | adapter->irq = netdev->irq; | ||
836 | err = request_irq(adapter->irq, handler, | 1094 | err = request_irq(adapter->irq, handler, |
837 | flags, netdev->name, adapter); | 1095 | flags, netdev->name, adapter); |
838 | if (err) { | 1096 | if (err) { |
839 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 1097 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
840 | netxen_free_hw_resources(adapter); | 1098 | goto err_out_free_hw; |
841 | return err; | ||
842 | } | 1099 | } |
843 | 1100 | ||
844 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 1101 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
845 | } | 1102 | } |
1103 | |||
846 | /* Done here again so that even if phantom sw overwrote it, | 1104 | /* Done here again so that even if phantom sw overwrote it, |
847 | * we set it */ | 1105 | * we set it */ |
848 | if (adapter->init_port | 1106 | err = adapter->init_port(adapter, adapter->portnum); |
849 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 1107 | if (err) { |
850 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 1108 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
851 | netxen_nic_driver_name, adapter->portnum); | 1109 | netxen_nic_driver_name, adapter->portnum); |
852 | return -EIO; | 1110 | goto err_out_free_irq; |
853 | } | 1111 | } |
854 | if (adapter->macaddr_set) | 1112 | adapter->macaddr_set(adapter, netdev->dev_addr); |
855 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
856 | 1113 | ||
857 | netxen_nic_set_link_parameters(adapter); | 1114 | netxen_nic_set_link_parameters(adapter); |
858 | 1115 | ||
859 | netxen_nic_set_multi(netdev); | 1116 | netxen_nic_set_multi(netdev); |
860 | if (adapter->set_mtu) | 1117 | adapter->set_mtu(adapter, netdev->mtu); |
861 | adapter->set_mtu(adapter, netdev->mtu); | ||
862 | 1118 | ||
863 | mod_timer(&adapter->watchdog_timer, jiffies); | 1119 | mod_timer(&adapter->watchdog_timer, jiffies); |
864 | 1120 | ||
@@ -868,6 +1124,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
868 | netif_start_queue(netdev); | 1124 | netif_start_queue(netdev); |
869 | 1125 | ||
870 | return 0; | 1126 | return 0; |
1127 | |||
1128 | err_out_free_irq: | ||
1129 | free_irq(adapter->irq, adapter); | ||
1130 | err_out_free_hw: | ||
1131 | netxen_free_hw_resources(adapter); | ||
1132 | err_out_free_sw: | ||
1133 | netxen_free_sw_resources(adapter); | ||
1134 | return err; | ||
871 | } | 1135 | } |
872 | 1136 | ||
873 | /* | 1137 | /* |
@@ -876,9 +1140,6 @@ static int netxen_nic_open(struct net_device *netdev) | |||
876 | static int netxen_nic_close(struct net_device *netdev) | 1140 | static int netxen_nic_close(struct net_device *netdev) |
877 | { | 1141 | { |
878 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1142 | struct netxen_adapter *adapter = netdev_priv(netdev); |
879 | int i, j; | ||
880 | struct netxen_cmd_buffer *cmd_buff; | ||
881 | struct netxen_skb_frag *buffrag; | ||
882 | 1143 | ||
883 | netif_carrier_off(netdev); | 1144 | netif_carrier_off(netdev); |
884 | netif_stop_queue(netdev); | 1145 | netif_stop_queue(netdev); |
@@ -889,30 +1150,8 @@ static int netxen_nic_close(struct net_device *netdev) | |||
889 | 1150 | ||
890 | netxen_nic_disable_int(adapter); | 1151 | netxen_nic_disable_int(adapter); |
891 | 1152 | ||
892 | cmd_buff = adapter->cmd_buf_arr; | 1153 | netxen_release_tx_buffers(adapter); |
893 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 1154 | |
894 | buffrag = cmd_buff->frag_array; | ||
895 | if (buffrag->dma) { | ||
896 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
897 | buffrag->length, PCI_DMA_TODEVICE); | ||
898 | buffrag->dma = 0ULL; | ||
899 | } | ||
900 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
901 | buffrag++; | ||
902 | if (buffrag->dma) { | ||
903 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
904 | buffrag->length, | ||
905 | PCI_DMA_TODEVICE); | ||
906 | buffrag->dma = 0ULL; | ||
907 | } | ||
908 | } | ||
909 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
910 | if (cmd_buff->skb) { | ||
911 | dev_kfree_skb_any(cmd_buff->skb); | ||
912 | cmd_buff->skb = NULL; | ||
913 | } | ||
914 | cmd_buff++; | ||
915 | } | ||
916 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1155 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
917 | FLUSH_SCHEDULED_WORK(); | 1156 | FLUSH_SCHEDULED_WORK(); |
918 | del_timer_sync(&adapter->watchdog_timer); | 1157 | del_timer_sync(&adapter->watchdog_timer); |