diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index b9615bd745ea..bf6d87adda4f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -473,48 +473,58 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
473 | static int | 473 | static int |
474 | qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | 474 | qlcnic_init_pci_info(struct qlcnic_adapter *adapter) |
475 | { | 475 | { |
476 | struct qlcnic_pci_info pci_info[QLCNIC_MAX_PCI_FUNC]; | 476 | struct qlcnic_pci_info *pci_info; |
477 | int i, ret = 0, err; | 477 | int i, ret = 0, err; |
478 | u8 pfn; | 478 | u8 pfn; |
479 | 479 | ||
480 | if (!adapter->npars) | 480 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); |
481 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * | 481 | if (!pci_info) |
482 | QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); | ||
483 | if (!adapter->npars) | ||
484 | return -ENOMEM; | 482 | return -ENOMEM; |
485 | 483 | ||
486 | if (!adapter->eswitch) | 484 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * |
487 | adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * | 485 | QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); |
486 | if (!adapter->npars) { | ||
487 | err = -ENOMEM; | ||
488 | goto err_pci_info; | ||
489 | } | ||
490 | |||
491 | adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * | ||
488 | QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); | 492 | QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); |
489 | if (!adapter->eswitch) { | 493 | if (!adapter->eswitch) { |
490 | err = -ENOMEM; | 494 | err = -ENOMEM; |
491 | goto err_eswitch; | 495 | goto err_npars; |
492 | } | 496 | } |
493 | 497 | ||
494 | ret = qlcnic_get_pci_info(adapter, pci_info); | 498 | ret = qlcnic_get_pci_info(adapter, pci_info); |
495 | if (!ret) { | 499 | if (ret) |
496 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 500 | goto err_eswitch; |
497 | pfn = pci_info[i].id; | ||
498 | if (pfn > QLCNIC_MAX_PCI_FUNC) | ||
499 | return QL_STATUS_INVALID_PARAM; | ||
500 | adapter->npars[pfn].active = pci_info[i].active; | ||
501 | adapter->npars[pfn].type = pci_info[i].type; | ||
502 | adapter->npars[pfn].phy_port = pci_info[i].default_port; | ||
503 | adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN; | ||
504 | adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; | ||
505 | adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; | ||
506 | } | ||
507 | |||
508 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) | ||
509 | adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; | ||
510 | 501 | ||
511 | return ret; | 502 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { |
503 | pfn = pci_info[i].id; | ||
504 | if (pfn > QLCNIC_MAX_PCI_FUNC) | ||
505 | return QL_STATUS_INVALID_PARAM; | ||
506 | adapter->npars[pfn].active = pci_info[i].active; | ||
507 | adapter->npars[pfn].type = pci_info[i].type; | ||
508 | adapter->npars[pfn].phy_port = pci_info[i].default_port; | ||
509 | adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN; | ||
510 | adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; | ||
511 | adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; | ||
512 | } | 512 | } |
513 | 513 | ||
514 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) | ||
515 | adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; | ||
516 | |||
517 | kfree(pci_info); | ||
518 | return 0; | ||
519 | |||
520 | err_eswitch: | ||
514 | kfree(adapter->eswitch); | 521 | kfree(adapter->eswitch); |
515 | adapter->eswitch = NULL; | 522 | adapter->eswitch = NULL; |
516 | err_eswitch: | 523 | err_npars: |
517 | kfree(adapter->npars); | 524 | kfree(adapter->npars); |
525 | adapter->npars = NULL; | ||
526 | err_pci_info: | ||
527 | kfree(pci_info); | ||
518 | 528 | ||
519 | return ret; | 529 | return ret; |
520 | } | 530 | } |
@@ -3361,15 +3371,21 @@ qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj, | |||
3361 | struct device *dev = container_of(kobj, struct device, kobj); | 3371 | struct device *dev = container_of(kobj, struct device, kobj); |
3362 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 3372 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
3363 | struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC]; | 3373 | struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC]; |
3364 | struct qlcnic_pci_info pci_info[QLCNIC_MAX_PCI_FUNC]; | 3374 | struct qlcnic_pci_info *pci_info; |
3365 | int i, ret; | 3375 | int i, ret; |
3366 | 3376 | ||
3367 | if (size != sizeof(pci_cfg)) | 3377 | if (size != sizeof(pci_cfg)) |
3368 | return QL_STATUS_INVALID_PARAM; | 3378 | return QL_STATUS_INVALID_PARAM; |
3369 | 3379 | ||
3380 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | ||
3381 | if (!pci_info) | ||
3382 | return -ENOMEM; | ||
3383 | |||
3370 | ret = qlcnic_get_pci_info(adapter, pci_info); | 3384 | ret = qlcnic_get_pci_info(adapter, pci_info); |
3371 | if (ret) | 3385 | if (ret) { |
3386 | kfree(pci_info); | ||
3372 | return ret; | 3387 | return ret; |
3388 | } | ||
3373 | 3389 | ||
3374 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { | 3390 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { |
3375 | pci_cfg[i].pci_func = pci_info[i].id; | 3391 | pci_cfg[i].pci_func = pci_info[i].id; |
@@ -3380,8 +3396,8 @@ qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj, | |||
3380 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); | 3396 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); |
3381 | } | 3397 | } |
3382 | memcpy(buf, &pci_cfg, size); | 3398 | memcpy(buf, &pci_cfg, size); |
3399 | kfree(pci_info); | ||
3383 | return size; | 3400 | return size; |
3384 | |||
3385 | } | 3401 | } |
3386 | static struct bin_attribute bin_attr_npar_config = { | 3402 | static struct bin_attribute bin_attr_npar_config = { |
3387 | .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)}, | 3403 | .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)}, |