diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 312 |
1 files changed, 284 insertions, 28 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 23ea9caa5261..99371bcaa547 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -65,6 +65,10 @@ static int load_fw_file; | |||
65 | module_param(load_fw_file, int, 0644); | 65 | module_param(load_fw_file, int, 0644); |
66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); | 66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); |
67 | 67 | ||
68 | static int qlcnic_config_npars; | ||
69 | module_param(qlcnic_config_npars, int, 0644); | ||
70 | MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); | ||
71 | |||
68 | static int __devinit qlcnic_probe(struct pci_dev *pdev, | 72 | static int __devinit qlcnic_probe(struct pci_dev *pdev, |
69 | const struct pci_device_id *ent); | 73 | const struct pci_device_id *ent); |
70 | static void __devexit qlcnic_remove(struct pci_dev *pdev); | 74 | static void __devexit qlcnic_remove(struct pci_dev *pdev); |
@@ -99,7 +103,14 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data); | |||
99 | 103 | ||
100 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); | 104 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); |
101 | static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); | 105 | static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); |
102 | 106 | static int qlcnic_start_firmware(struct qlcnic_adapter *); | |
107 | |||
108 | static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); | ||
109 | static void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *); | ||
110 | static int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *); | ||
111 | static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); | ||
112 | static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); | ||
113 | static int qlcnicvf_start_firmware(struct qlcnic_adapter *); | ||
103 | /* PCI Device ID Table */ | 114 | /* PCI Device ID Table */ |
104 | #define ENTRY(device) \ | 115 | #define ENTRY(device) \ |
105 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ | 116 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ |
@@ -307,19 +318,14 @@ static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count) | |||
307 | static int | 318 | static int |
308 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | 319 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) |
309 | { | 320 | { |
310 | int i; | 321 | u8 mac_addr[ETH_ALEN]; |
311 | unsigned char *p; | ||
312 | u64 mac_addr; | ||
313 | struct net_device *netdev = adapter->netdev; | 322 | struct net_device *netdev = adapter->netdev; |
314 | struct pci_dev *pdev = adapter->pdev; | 323 | struct pci_dev *pdev = adapter->pdev; |
315 | 324 | ||
316 | if (qlcnic_get_mac_addr(adapter, &mac_addr) != 0) | 325 | if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0) |
317 | return -EIO; | 326 | return -EIO; |
318 | 327 | ||
319 | p = (unsigned char *)&mac_addr; | 328 | memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); |
320 | for (i = 0; i < 6; i++) | ||
321 | netdev->dev_addr[i] = *(p + 5 - i); | ||
322 | |||
323 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 329 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
324 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | 330 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); |
325 | 331 | ||
@@ -371,6 +377,33 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
371 | #endif | 377 | #endif |
372 | }; | 378 | }; |
373 | 379 | ||
380 | static struct qlcnic_nic_template qlcnic_ops = { | ||
381 | .get_mac_addr = qlcnic_get_mac_addr, | ||
382 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
383 | .config_led = qlcnic_config_led, | ||
384 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
385 | .clear_ilb_mode = qlcnic_clear_ilb_mode, | ||
386 | .start_firmware = qlcnic_start_firmware | ||
387 | }; | ||
388 | |||
389 | static struct qlcnic_nic_template qlcnic_pf_ops = { | ||
390 | .get_mac_addr = qlcnic_get_mac_address, | ||
391 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
392 | .config_led = qlcnic_config_led, | ||
393 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
394 | .clear_ilb_mode = qlcnic_clear_ilb_mode, | ||
395 | .start_firmware = qlcnic_start_firmware | ||
396 | }; | ||
397 | |||
398 | static struct qlcnic_nic_template qlcnic_vf_ops = { | ||
399 | .get_mac_addr = qlcnic_get_mac_address, | ||
400 | .config_bridged_mode = qlcnicvf_config_bridged_mode, | ||
401 | .config_led = qlcnicvf_config_led, | ||
402 | .set_ilb_mode = qlcnicvf_set_ilb_mode, | ||
403 | .clear_ilb_mode = qlcnicvf_clear_ilb_mode, | ||
404 | .start_firmware = qlcnicvf_start_firmware | ||
405 | }; | ||
406 | |||
374 | static void | 407 | static void |
375 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) | 408 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) |
376 | { | 409 | { |
@@ -453,6 +486,132 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
453 | } | 486 | } |
454 | 487 | ||
455 | static int | 488 | static int |
489 | qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | ||
490 | { | ||
491 | u8 id; | ||
492 | u32 ref_count; | ||
493 | int i, ret = 1; | ||
494 | u32 data = QLCNIC_MGMT_FUNC; | ||
495 | void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
496 | |||
497 | /* If other drivers are not in use set their privilege level */ | ||
498 | ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
499 | ret = qlcnic_api_lock(adapter); | ||
500 | if (ret) | ||
501 | goto err_lock; | ||
502 | if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func)) | ||
503 | goto err_npar; | ||
504 | |||
505 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
506 | id = adapter->npars[i].id; | ||
507 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || | ||
508 | id == adapter->ahw.pci_func) | ||
509 | continue; | ||
510 | data |= (qlcnic_config_npars & QLC_DEV_SET_DRV(0xf, id)); | ||
511 | } | ||
512 | writel(data, priv_op); | ||
513 | |||
514 | err_npar: | ||
515 | qlcnic_api_unlock(adapter); | ||
516 | err_lock: | ||
517 | return ret; | ||
518 | } | ||
519 | |||
520 | static u8 | ||
521 | qlcnic_set_mgmt_driver(struct qlcnic_adapter *adapter) | ||
522 | { | ||
523 | u8 i, ret = 0; | ||
524 | |||
525 | if (qlcnic_get_pci_info(adapter)) | ||
526 | return ret; | ||
527 | /* Set the eswitch */ | ||
528 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) { | ||
529 | if (!qlcnic_get_eswitch_capabilities(adapter, i, | ||
530 | &adapter->eswitch[i])) { | ||
531 | ret++; | ||
532 | qlcnic_toggle_eswitch(adapter, i, ret); | ||
533 | } | ||
534 | } | ||
535 | return ret; | ||
536 | } | ||
537 | |||
538 | static u32 | ||
539 | qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | ||
540 | { | ||
541 | void __iomem *msix_base_addr; | ||
542 | void __iomem *priv_op; | ||
543 | u32 func; | ||
544 | u32 msix_base; | ||
545 | u32 op_mode, priv_level; | ||
546 | |||
547 | /* Determine FW API version */ | ||
548 | adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API); | ||
549 | if (adapter->fw_hal_version == ~0) { | ||
550 | adapter->nic_ops = &qlcnic_ops; | ||
551 | adapter->fw_hal_version = QLCNIC_FW_BASE; | ||
552 | adapter->ahw.pci_func = PCI_FUNC(adapter->pdev->devfn); | ||
553 | dev_info(&adapter->pdev->dev, | ||
554 | "FW does not support nic partion\n"); | ||
555 | return adapter->fw_hal_version; | ||
556 | } | ||
557 | |||
558 | /* Find PCI function number */ | ||
559 | pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); | ||
560 | msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE; | ||
561 | msix_base = readl(msix_base_addr); | ||
562 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; | ||
563 | adapter->ahw.pci_func = func; | ||
564 | |||
565 | /* Determine function privilege level */ | ||
566 | priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
567 | op_mode = readl(priv_op); | ||
568 | if (op_mode == QLC_DEV_DRV_DEFAULT) { | ||
569 | priv_level = QLCNIC_MGMT_FUNC; | ||
570 | if (qlcnic_api_lock(adapter)) | ||
571 | return 0; | ||
572 | op_mode = (op_mode & ~QLC_DEV_SET_DRV(0xf, func)) | | ||
573 | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, func)); | ||
574 | writel(op_mode, priv_op); | ||
575 | qlcnic_api_unlock(adapter); | ||
576 | |||
577 | } else | ||
578 | priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); | ||
579 | |||
580 | switch (priv_level) { | ||
581 | case QLCNIC_MGMT_FUNC: | ||
582 | adapter->op_mode = QLCNIC_MGMT_FUNC; | ||
583 | adapter->nic_ops = &qlcnic_pf_ops; | ||
584 | /* Set privilege level for other functions */ | ||
585 | if (qlcnic_config_npars) | ||
586 | qlcnic_set_function_modes(adapter); | ||
587 | qlcnic_dev_set_npar_ready(adapter); | ||
588 | dev_info(&adapter->pdev->dev, | ||
589 | "HAL Version: %d, Management function\n", | ||
590 | adapter->fw_hal_version); | ||
591 | break; | ||
592 | case QLCNIC_PRIV_FUNC: | ||
593 | adapter->op_mode = QLCNIC_PRIV_FUNC; | ||
594 | dev_info(&adapter->pdev->dev, | ||
595 | "HAL Version: %d, Privileged function\n", | ||
596 | adapter->fw_hal_version); | ||
597 | adapter->nic_ops = &qlcnic_pf_ops; | ||
598 | break; | ||
599 | case QLCNIC_NON_PRIV_FUNC: | ||
600 | adapter->op_mode = QLCNIC_NON_PRIV_FUNC; | ||
601 | dev_info(&adapter->pdev->dev, | ||
602 | "HAL Version: %d Non Privileged function\n", | ||
603 | adapter->fw_hal_version); | ||
604 | adapter->nic_ops = &qlcnic_vf_ops; | ||
605 | break; | ||
606 | default: | ||
607 | dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", | ||
608 | priv_level); | ||
609 | return 0; | ||
610 | } | ||
611 | return adapter->fw_hal_version; | ||
612 | } | ||
613 | |||
614 | static int | ||
456 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | 615 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) |
457 | { | 616 | { |
458 | void __iomem *mem_ptr0 = NULL; | 617 | void __iomem *mem_ptr0 = NULL; |
@@ -460,7 +619,6 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
460 | unsigned long mem_len, pci_len0 = 0; | 619 | unsigned long mem_len, pci_len0 = 0; |
461 | 620 | ||
462 | struct pci_dev *pdev = adapter->pdev; | 621 | struct pci_dev *pdev = adapter->pdev; |
463 | int pci_func = adapter->ahw.pci_func; | ||
464 | 622 | ||
465 | /* remap phys address */ | 623 | /* remap phys address */ |
466 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 624 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
@@ -483,8 +641,13 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
483 | adapter->ahw.pci_base0 = mem_ptr0; | 641 | adapter->ahw.pci_base0 = mem_ptr0; |
484 | adapter->ahw.pci_len0 = pci_len0; | 642 | adapter->ahw.pci_len0 = pci_len0; |
485 | 643 | ||
644 | if (!qlcnic_get_driver_mode(adapter)) { | ||
645 | iounmap(adapter->ahw.pci_base0); | ||
646 | return -EIO; | ||
647 | } | ||
648 | |||
486 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, | 649 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, |
487 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | 650 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); |
488 | 651 | ||
489 | return 0; | 652 | return 0; |
490 | } | 653 | } |
@@ -553,7 +716,10 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
553 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", | 716 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", |
554 | fw_major, fw_minor, fw_build); | 717 | fw_major, fw_minor, fw_build); |
555 | 718 | ||
556 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | 719 | if (adapter->fw_hal_version == QLCNIC_FW_NPAR) |
720 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | ||
721 | else | ||
722 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
557 | 723 | ||
558 | adapter->flags &= ~QLCNIC_LRO_ENABLED; | 724 | adapter->flags &= ~QLCNIC_LRO_ENABLED; |
559 | 725 | ||
@@ -631,8 +797,14 @@ wait_init: | |||
631 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); | 797 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); |
632 | qlcnic_idc_debug_info(adapter, 1); | 798 | qlcnic_idc_debug_info(adapter, 1); |
633 | 799 | ||
800 | qlcnic_dev_set_npar_ready(adapter); | ||
801 | |||
634 | qlcnic_check_options(adapter); | 802 | qlcnic_check_options(adapter); |
635 | 803 | ||
804 | if (adapter->fw_hal_version != QLCNIC_FW_BASE && | ||
805 | adapter->op_mode == QLCNIC_MGMT_FUNC) | ||
806 | qlcnic_set_mgmt_driver(adapter); | ||
807 | |||
636 | adapter->need_fw_reset = 0; | 808 | adapter->need_fw_reset = 0; |
637 | 809 | ||
638 | qlcnic_release_firmware(adapter); | 810 | qlcnic_release_firmware(adapter); |
@@ -977,12 +1149,11 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | |||
977 | 1149 | ||
978 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); | 1150 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); |
979 | 1151 | ||
980 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | 1152 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
981 | netdev->features |= (NETIF_F_GRO); | 1153 | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6); |
982 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
983 | 1154 | ||
984 | netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1155 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
985 | netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1156 | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6); |
986 | 1157 | ||
987 | if (pci_using_dac) { | 1158 | if (pci_using_dac) { |
988 | netdev->features |= NETIF_F_HIGHDMA; | 1159 | netdev->features |= NETIF_F_HIGHDMA; |
@@ -1036,7 +1207,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1036 | struct net_device *netdev = NULL; | 1207 | struct net_device *netdev = NULL; |
1037 | struct qlcnic_adapter *adapter = NULL; | 1208 | struct qlcnic_adapter *adapter = NULL; |
1038 | int err; | 1209 | int err; |
1039 | int pci_func_id = PCI_FUNC(pdev->devfn); | ||
1040 | uint8_t revision_id; | 1210 | uint8_t revision_id; |
1041 | uint8_t pci_using_dac; | 1211 | uint8_t pci_using_dac; |
1042 | 1212 | ||
@@ -1072,7 +1242,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1072 | adapter->netdev = netdev; | 1242 | adapter->netdev = netdev; |
1073 | adapter->pdev = pdev; | 1243 | adapter->pdev = pdev; |
1074 | adapter->dev_rst_time = jiffies; | 1244 | adapter->dev_rst_time = jiffies; |
1075 | adapter->ahw.pci_func = pci_func_id; | ||
1076 | 1245 | ||
1077 | revision_id = pdev->revision; | 1246 | revision_id = pdev->revision; |
1078 | adapter->ahw.revision_id = revision_id; | 1247 | adapter->ahw.revision_id = revision_id; |
@@ -1088,7 +1257,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1088 | goto err_out_free_netdev; | 1257 | goto err_out_free_netdev; |
1089 | 1258 | ||
1090 | /* This will be reset for mezz cards */ | 1259 | /* This will be reset for mezz cards */ |
1091 | adapter->portnum = pci_func_id; | 1260 | adapter->portnum = adapter->ahw.pci_func; |
1092 | 1261 | ||
1093 | err = qlcnic_get_board_info(adapter); | 1262 | err = qlcnic_get_board_info(adapter); |
1094 | if (err) { | 1263 | if (err) { |
@@ -1102,7 +1271,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1102 | if (qlcnic_setup_idc_param(adapter)) | 1271 | if (qlcnic_setup_idc_param(adapter)) |
1103 | goto err_out_iounmap; | 1272 | goto err_out_iounmap; |
1104 | 1273 | ||
1105 | err = qlcnic_start_firmware(adapter); | 1274 | err = adapter->nic_ops->start_firmware(adapter); |
1106 | if (err) { | 1275 | if (err) { |
1107 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); | 1276 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); |
1108 | goto err_out_decr_ref; | 1277 | goto err_out_decr_ref; |
@@ -1175,6 +1344,11 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) | |||
1175 | 1344 | ||
1176 | qlcnic_detach(adapter); | 1345 | qlcnic_detach(adapter); |
1177 | 1346 | ||
1347 | if (adapter->npars != NULL) | ||
1348 | kfree(adapter->npars); | ||
1349 | if (adapter->eswitch != NULL) | ||
1350 | kfree(adapter->eswitch); | ||
1351 | |||
1178 | qlcnic_clr_all_drv_state(adapter); | 1352 | qlcnic_clr_all_drv_state(adapter); |
1179 | 1353 | ||
1180 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 1354 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
@@ -1263,7 +1437,7 @@ qlcnic_resume(struct pci_dev *pdev) | |||
1263 | pci_set_master(pdev); | 1437 | pci_set_master(pdev); |
1264 | pci_restore_state(pdev); | 1438 | pci_restore_state(pdev); |
1265 | 1439 | ||
1266 | err = qlcnic_start_firmware(adapter); | 1440 | err = adapter->nic_ops->start_firmware(adapter); |
1267 | if (err) { | 1441 | if (err) { |
1268 | dev_err(&pdev->dev, "failed to start firmware\n"); | 1442 | dev_err(&pdev->dev, "failed to start firmware\n"); |
1269 | return err; | 1443 | return err; |
@@ -1340,11 +1514,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1340 | u8 opcode = TX_ETHER_PKT; | 1514 | u8 opcode = TX_ETHER_PKT; |
1341 | __be16 protocol = skb->protocol; | 1515 | __be16 protocol = skb->protocol; |
1342 | u16 flags = 0, vid = 0; | 1516 | u16 flags = 0, vid = 0; |
1343 | u32 producer; | ||
1344 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | 1517 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; |
1345 | struct cmd_desc_type0 *hwdesc; | 1518 | struct cmd_desc_type0 *hwdesc; |
1346 | struct vlan_ethhdr *vh; | 1519 | struct vlan_ethhdr *vh; |
1347 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1520 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1521 | u32 producer = tx_ring->producer; | ||
1348 | 1522 | ||
1349 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | 1523 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { |
1350 | 1524 | ||
@@ -1360,6 +1534,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1360 | vlan_oob = 1; | 1534 | vlan_oob = 1; |
1361 | } | 1535 | } |
1362 | 1536 | ||
1537 | if (*(skb->data) & BIT_0) { | ||
1538 | flags |= BIT_0; | ||
1539 | memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); | ||
1540 | } | ||
1541 | |||
1363 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && | 1542 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1364 | skb_shinfo(skb)->gso_size > 0) { | 1543 | skb_shinfo(skb)->gso_size > 0) { |
1365 | 1544 | ||
@@ -1409,7 +1588,6 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1409 | /* For LSO, we need to copy the MAC/IP/TCP headers into | 1588 | /* For LSO, we need to copy the MAC/IP/TCP headers into |
1410 | * the descriptor ring | 1589 | * the descriptor ring |
1411 | */ | 1590 | */ |
1412 | producer = tx_ring->producer; | ||
1413 | copied = 0; | 1591 | copied = 0; |
1414 | offset = 2; | 1592 | offset = 2; |
1415 | 1593 | ||
@@ -2109,7 +2287,7 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2109 | { | 2287 | { |
2110 | struct qlcnic_adapter *adapter = container_of(work, | 2288 | struct qlcnic_adapter *adapter = container_of(work, |
2111 | struct qlcnic_adapter, fw_work.work); | 2289 | struct qlcnic_adapter, fw_work.work); |
2112 | u32 dev_state = 0xf; | 2290 | u32 dev_state = 0xf, npar_state; |
2113 | 2291 | ||
2114 | if (qlcnic_api_lock(adapter)) | 2292 | if (qlcnic_api_lock(adapter)) |
2115 | goto err_ret; | 2293 | goto err_ret; |
@@ -2122,6 +2300,19 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2122 | return; | 2300 | return; |
2123 | } | 2301 | } |
2124 | 2302 | ||
2303 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { | ||
2304 | npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2305 | if (npar_state == QLCNIC_DEV_NPAR_RDY) { | ||
2306 | qlcnic_api_unlock(adapter); | ||
2307 | goto wait_npar; | ||
2308 | } else { | ||
2309 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, | ||
2310 | FW_POLL_DELAY); | ||
2311 | qlcnic_api_unlock(adapter); | ||
2312 | return; | ||
2313 | } | ||
2314 | } | ||
2315 | |||
2125 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { | 2316 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { |
2126 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", | 2317 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", |
2127 | adapter->reset_ack_timeo); | 2318 | adapter->reset_ack_timeo); |
@@ -2154,7 +2345,7 @@ skip_ack_check: | |||
2154 | 2345 | ||
2155 | qlcnic_api_unlock(adapter); | 2346 | qlcnic_api_unlock(adapter); |
2156 | 2347 | ||
2157 | if (!qlcnic_start_firmware(adapter)) { | 2348 | if (!adapter->nic_ops->start_firmware(adapter)) { |
2158 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2349 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2159 | return; | 2350 | return; |
2160 | } | 2351 | } |
@@ -2163,6 +2354,7 @@ skip_ack_check: | |||
2163 | 2354 | ||
2164 | qlcnic_api_unlock(adapter); | 2355 | qlcnic_api_unlock(adapter); |
2165 | 2356 | ||
2357 | wait_npar: | ||
2166 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2358 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2167 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); | 2359 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); |
2168 | 2360 | ||
@@ -2177,7 +2369,7 @@ skip_ack_check: | |||
2177 | break; | 2369 | break; |
2178 | 2370 | ||
2179 | default: | 2371 | default: |
2180 | if (!qlcnic_start_firmware(adapter)) { | 2372 | if (!adapter->nic_ops->start_firmware(adapter)) { |
2181 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2373 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2182 | return; | 2374 | return; |
2183 | } | 2375 | } |
@@ -2251,6 +2443,30 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | |||
2251 | qlcnic_api_unlock(adapter); | 2443 | qlcnic_api_unlock(adapter); |
2252 | } | 2444 | } |
2253 | 2445 | ||
2446 | /* Transit to NPAR READY state from NPAR NOT READY state */ | ||
2447 | static void | ||
2448 | qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) | ||
2449 | { | ||
2450 | u32 state; | ||
2451 | |||
2452 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC || | ||
2453 | adapter->fw_hal_version == QLCNIC_FW_BASE) | ||
2454 | return; | ||
2455 | |||
2456 | if (qlcnic_api_lock(adapter)) | ||
2457 | return; | ||
2458 | |||
2459 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2460 | |||
2461 | if (state != QLCNIC_DEV_NPAR_RDY) { | ||
2462 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, | ||
2463 | QLCNIC_DEV_NPAR_RDY); | ||
2464 | QLCDB(adapter, DRV, "NPAR READY state set\n"); | ||
2465 | } | ||
2466 | |||
2467 | qlcnic_api_unlock(adapter); | ||
2468 | } | ||
2469 | |||
2254 | static void | 2470 | static void |
2255 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, | 2471 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, |
2256 | work_func_t func, int delay) | 2472 | work_func_t func, int delay) |
@@ -2365,6 +2581,46 @@ reschedule: | |||
2365 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | 2581 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); |
2366 | } | 2582 | } |
2367 | 2583 | ||
2584 | static int | ||
2585 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | ||
2586 | { | ||
2587 | int err; | ||
2588 | |||
2589 | err = qlcnic_can_start_firmware(adapter); | ||
2590 | if (err) | ||
2591 | return err; | ||
2592 | |||
2593 | qlcnic_check_options(adapter); | ||
2594 | |||
2595 | adapter->need_fw_reset = 0; | ||
2596 | |||
2597 | return err; | ||
2598 | } | ||
2599 | |||
2600 | static int | ||
2601 | qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) | ||
2602 | { | ||
2603 | return -EOPNOTSUPP; | ||
2604 | } | ||
2605 | |||
2606 | static int | ||
2607 | qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | ||
2608 | { | ||
2609 | return -EOPNOTSUPP; | ||
2610 | } | ||
2611 | |||
2612 | static int | ||
2613 | qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter) | ||
2614 | { | ||
2615 | return -EOPNOTSUPP; | ||
2616 | } | ||
2617 | |||
2618 | static void | ||
2619 | qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter) | ||
2620 | { | ||
2621 | return; | ||
2622 | } | ||
2623 | |||
2368 | static ssize_t | 2624 | static ssize_t |
2369 | qlcnic_store_bridged_mode(struct device *dev, | 2625 | qlcnic_store_bridged_mode(struct device *dev, |
2370 | struct device_attribute *attr, const char *buf, size_t len) | 2626 | struct device_attribute *attr, const char *buf, size_t len) |
@@ -2382,7 +2638,7 @@ qlcnic_store_bridged_mode(struct device *dev, | |||
2382 | if (strict_strtoul(buf, 2, &new)) | 2638 | if (strict_strtoul(buf, 2, &new)) |
2383 | goto err_out; | 2639 | goto err_out; |
2384 | 2640 | ||
2385 | if (!qlcnic_config_bridged_mode(adapter, !!new)) | 2641 | if (!adapter->nic_ops->config_bridged_mode(adapter, !!new)) |
2386 | ret = len; | 2642 | ret = len; |
2387 | 2643 | ||
2388 | err_out: | 2644 | err_out: |