diff options
author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2009-10-04 21:57:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-06 18:22:55 -0400 |
commit | eb5f10c21badd967aa466fd4f7eddfc724c8cb64 (patch) | |
tree | 743513fe60462e32ee81da71f78dda8a8dad88dc /drivers/net/vxge/vxge-main.c | |
parent | fa41fd10038ab575f043a62dace374e07e9193de (diff) |
vxge: Allow multiple functions with INTA.
- Allow multiple functions with INTA.
- Removed the condition to allow only one vpath with INTA
- Ensure that the alarm bit in titan_mask_all_int register is cleared when
driver exits.
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
-rw-r--r-- | drivers/net/vxge/vxge-main.c | 92 |
1 files changed, 36 insertions, 56 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 04ac4b6cf83a..63d0f891ffae 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
@@ -2435,7 +2435,6 @@ static int vxge_add_isr(struct vxgedev *vdev) | |||
2435 | int ret = 0; | 2435 | int ret = 0; |
2436 | #ifdef CONFIG_PCI_MSI | 2436 | #ifdef CONFIG_PCI_MSI |
2437 | int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0; | 2437 | int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0; |
2438 | u64 function_mode = vdev->config.device_hw_info.function_mode; | ||
2439 | int pci_fun = PCI_FUNC(vdev->pdev->devfn); | 2438 | int pci_fun = PCI_FUNC(vdev->pdev->devfn); |
2440 | 2439 | ||
2441 | if (vdev->config.intr_type == MSI_X) | 2440 | if (vdev->config.intr_type == MSI_X) |
@@ -2444,20 +2443,9 @@ static int vxge_add_isr(struct vxgedev *vdev) | |||
2444 | if (ret) { | 2443 | if (ret) { |
2445 | vxge_debug_init(VXGE_ERR, | 2444 | vxge_debug_init(VXGE_ERR, |
2446 | "%s: Enabling MSI-X Failed", VXGE_DRIVER_NAME); | 2445 | "%s: Enabling MSI-X Failed", VXGE_DRIVER_NAME); |
2447 | if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && | 2446 | vxge_debug_init(VXGE_ERR, |
2448 | test_and_set_bit(__VXGE_STATE_CARD_UP, | 2447 | "%s: Defaulting to INTA", VXGE_DRIVER_NAME); |
2449 | &driver_config->inta_dev_open)) | 2448 | vdev->config.intr_type = INTA; |
2450 | return VXGE_HW_FAIL; | ||
2451 | else { | ||
2452 | vxge_debug_init(VXGE_ERR, | ||
2453 | "%s: Defaulting to INTA", VXGE_DRIVER_NAME); | ||
2454 | vdev->config.intr_type = INTA; | ||
2455 | vxge_hw_device_set_intr_type(vdev->devh, | ||
2456 | VXGE_HW_INTR_MODE_IRQLINE); | ||
2457 | vxge_close_vpaths(vdev, 1); | ||
2458 | vdev->no_of_vpath = 1; | ||
2459 | vdev->stats.vpaths_open = 1; | ||
2460 | } | ||
2461 | } | 2449 | } |
2462 | 2450 | ||
2463 | if (vdev->config.intr_type == MSI_X) { | 2451 | if (vdev->config.intr_type == MSI_X) { |
@@ -2505,24 +2493,11 @@ static int vxge_add_isr(struct vxgedev *vdev) | |||
2505 | "%s: MSIX - %d Registration failed", | 2493 | "%s: MSIX - %d Registration failed", |
2506 | vdev->ndev->name, intr_cnt); | 2494 | vdev->ndev->name, intr_cnt); |
2507 | vxge_rem_msix_isr(vdev); | 2495 | vxge_rem_msix_isr(vdev); |
2508 | if ((function_mode == | 2496 | vdev->config.intr_type = INTA; |
2509 | VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && | 2497 | vxge_debug_init(VXGE_ERR, |
2510 | test_and_set_bit(__VXGE_STATE_CARD_UP, | 2498 | "%s: Defaulting to INTA" |
2511 | &driver_config->inta_dev_open)) | 2499 | , vdev->ndev->name); |
2512 | return VXGE_HW_FAIL; | ||
2513 | else { | ||
2514 | vxge_hw_device_set_intr_type( | ||
2515 | vdev->devh, | ||
2516 | VXGE_HW_INTR_MODE_IRQLINE); | ||
2517 | vdev->config.intr_type = INTA; | ||
2518 | vxge_debug_init(VXGE_ERR, | ||
2519 | "%s: Defaulting to INTA" | ||
2520 | , vdev->ndev->name); | ||
2521 | vxge_close_vpaths(vdev, 1); | ||
2522 | vdev->no_of_vpath = 1; | ||
2523 | vdev->stats.vpaths_open = 1; | ||
2524 | goto INTA_MODE; | 2500 | goto INTA_MODE; |
2525 | } | ||
2526 | } | 2501 | } |
2527 | 2502 | ||
2528 | if (irq_req) { | 2503 | if (irq_req) { |
@@ -2555,23 +2530,11 @@ static int vxge_add_isr(struct vxgedev *vdev) | |||
2555 | "%s: MSIX - %d Registration failed", | 2530 | "%s: MSIX - %d Registration failed", |
2556 | vdev->ndev->name, intr_cnt); | 2531 | vdev->ndev->name, intr_cnt); |
2557 | vxge_rem_msix_isr(vdev); | 2532 | vxge_rem_msix_isr(vdev); |
2558 | if ((function_mode == | 2533 | vdev->config.intr_type = INTA; |
2559 | VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && | 2534 | vxge_debug_init(VXGE_ERR, |
2560 | test_and_set_bit(__VXGE_STATE_CARD_UP, | 2535 | "%s: Defaulting to INTA", |
2561 | &driver_config->inta_dev_open)) | 2536 | vdev->ndev->name); |
2562 | return VXGE_HW_FAIL; | ||
2563 | else { | ||
2564 | vxge_hw_device_set_intr_type(vdev->devh, | ||
2565 | VXGE_HW_INTR_MODE_IRQLINE); | ||
2566 | vdev->config.intr_type = INTA; | ||
2567 | vxge_debug_init(VXGE_ERR, | ||
2568 | "%s: Defaulting to INTA", | ||
2569 | vdev->ndev->name); | ||
2570 | vxge_close_vpaths(vdev, 1); | ||
2571 | vdev->no_of_vpath = 1; | ||
2572 | vdev->stats.vpaths_open = 1; | ||
2573 | goto INTA_MODE; | 2537 | goto INTA_MODE; |
2574 | } | ||
2575 | } | 2538 | } |
2576 | 2539 | ||
2577 | vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle, | 2540 | vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle, |
@@ -2584,6 +2547,10 @@ INTA_MODE: | |||
2584 | snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name); | 2547 | snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name); |
2585 | 2548 | ||
2586 | if (vdev->config.intr_type == INTA) { | 2549 | if (vdev->config.intr_type == INTA) { |
2550 | vxge_hw_device_set_intr_type(vdev->devh, | ||
2551 | VXGE_HW_INTR_MODE_IRQLINE); | ||
2552 | vxge_hw_vpath_tti_ci_set(vdev->devh, | ||
2553 | vdev->vpaths[0].device_id); | ||
2587 | ret = request_irq((int) vdev->pdev->irq, | 2554 | ret = request_irq((int) vdev->pdev->irq, |
2588 | vxge_isr_napi, | 2555 | vxge_isr_napi, |
2589 | IRQF_SHARED, vdev->desc[0], vdev); | 2556 | IRQF_SHARED, vdev->desc[0], vdev); |
@@ -2688,13 +2655,6 @@ vxge_open(struct net_device *dev) | |||
2688 | * initialized */ | 2655 | * initialized */ |
2689 | netif_carrier_off(dev); | 2656 | netif_carrier_off(dev); |
2690 | 2657 | ||
2691 | /* Check for another device already opn with INTA */ | ||
2692 | if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && | ||
2693 | test_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open)) { | ||
2694 | ret = -EPERM; | ||
2695 | goto out0; | ||
2696 | } | ||
2697 | |||
2698 | /* Open VPATHs */ | 2658 | /* Open VPATHs */ |
2699 | status = vxge_open_vpaths(vdev); | 2659 | status = vxge_open_vpaths(vdev); |
2700 | if (status != VXGE_HW_OK) { | 2660 | if (status != VXGE_HW_OK) { |
@@ -2983,7 +2943,6 @@ int do_vxge_close(struct net_device *dev, int do_io) | |||
2983 | vxge_debug_entryexit(VXGE_TRACE, | 2943 | vxge_debug_entryexit(VXGE_TRACE, |
2984 | "%s: %s:%d Exiting...", dev->name, __func__, __LINE__); | 2944 | "%s: %s:%d Exiting...", dev->name, __func__, __LINE__); |
2985 | 2945 | ||
2986 | clear_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open); | ||
2987 | clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state); | 2946 | clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state); |
2988 | 2947 | ||
2989 | return 0; | 2948 | return 0; |
@@ -4397,6 +4356,27 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4397 | } | 4356 | } |
4398 | 4357 | ||
4399 | kfree(device_config); | 4358 | kfree(device_config); |
4359 | |||
4360 | /* | ||
4361 | * INTA is shared in multi-function mode. This is unlike the INTA | ||
4362 | * implementation in MR mode, where each VH has its own INTA message. | ||
4363 | * - INTA is masked (disabled) as long as at least one function sets | ||
4364 | * its TITAN_MASK_ALL_INT.ALARM bit. | ||
4365 | * - INTA is unmasked (enabled) when all enabled functions have cleared | ||
4366 | * their own TITAN_MASK_ALL_INT.ALARM bit. | ||
4367 | * The TITAN_MASK_ALL_INT ALARM & TRAFFIC bits are cleared on power up. | ||
4368 | * Though this driver leaves the top level interrupts unmasked while | ||
4369 | * leaving the required module interrupt bits masked on exit, there | ||
4370 | * could be a rougue driver around that does not follow this procedure | ||
4371 | * resulting in a failure to generate interrupts. The following code is | ||
4372 | * present to prevent such a failure. | ||
4373 | */ | ||
4374 | |||
4375 | if (ll_config.device_hw_info.function_mode == | ||
4376 | VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) | ||
4377 | if (vdev->config.intr_type == INTA) | ||
4378 | vxge_hw_device_unmask_all(hldev); | ||
4379 | |||
4400 | vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", | 4380 | vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", |
4401 | vdev->ndev->name, __func__, __LINE__); | 4381 | vdev->ndev->name, __func__, __LINE__); |
4402 | 4382 | ||