diff options
author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2009-10-05 01:57:29 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-06 15:22:55 -0700 |
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 04ac4b6cf83..63d0f891ffa 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) int ret = 0; #ifdef CONFIG_PCI_MSI int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0; - u64 function_mode = vdev->config.device_hw_info.function_mode; int pci_fun = PCI_FUNC(vdev->pdev->devfn); if (vdev->config.intr_type == MSI_X) @@ -2444,20 +2443,9 @@ static int vxge_add_isr(struct vxgedev *vdev) if (ret) { vxge_debug_init(VXGE_ERR, "%s: Enabling MSI-X Failed", VXGE_DRIVER_NAME); - if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && - test_and_set_bit(__VXGE_STATE_CARD_UP, - &driver_config->inta_dev_open)) - return VXGE_HW_FAIL; - else { - vxge_debug_init(VXGE_ERR, - "%s: Defaulting to INTA", VXGE_DRIVER_NAME); - vdev->config.intr_type = INTA; - vxge_hw_device_set_intr_type(vdev->devh, - VXGE_HW_INTR_MODE_IRQLINE); - vxge_close_vpaths(vdev, 1); - vdev->no_of_vpath = 1; - vdev->stats.vpaths_open = 1; - } + vxge_debug_init(VXGE_ERR, + "%s: Defaulting to INTA", VXGE_DRIVER_NAME); + vdev->config.intr_type = INTA; } if (vdev->config.intr_type == MSI_X) { @@ -2505,24 +2493,11 @@ static int vxge_add_isr(struct vxgedev *vdev) "%s: MSIX - %d Registration failed", vdev->ndev->name, intr_cnt); vxge_rem_msix_isr(vdev); - if ((function_mode == - VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && - test_and_set_bit(__VXGE_STATE_CARD_UP, - &driver_config->inta_dev_open)) - return VXGE_HW_FAIL; - else { - vxge_hw_device_set_intr_type( - vdev->devh, - VXGE_HW_INTR_MODE_IRQLINE); - vdev->config.intr_type = INTA; - vxge_debug_init(VXGE_ERR, - "%s: Defaulting to INTA" - , vdev->ndev->name); - vxge_close_vpaths(vdev, 1); - vdev->no_of_vpath = 1; - vdev->stats.vpaths_open = 1; + vdev->config.intr_type = INTA; + vxge_debug_init(VXGE_ERR, + "%s: Defaulting to INTA" + , vdev->ndev->name); goto INTA_MODE; - } } if (irq_req) { @@ -2555,23 +2530,11 @@ static int vxge_add_isr(struct vxgedev *vdev) "%s: MSIX - %d Registration failed", vdev->ndev->name, intr_cnt); vxge_rem_msix_isr(vdev); - if ((function_mode == - VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && - test_and_set_bit(__VXGE_STATE_CARD_UP, - &driver_config->inta_dev_open)) - return VXGE_HW_FAIL; - else { - vxge_hw_device_set_intr_type(vdev->devh, - VXGE_HW_INTR_MODE_IRQLINE); - vdev->config.intr_type = INTA; - vxge_debug_init(VXGE_ERR, - "%s: Defaulting to INTA", - vdev->ndev->name); - vxge_close_vpaths(vdev, 1); - vdev->no_of_vpath = 1; - vdev->stats.vpaths_open = 1; + vdev->config.intr_type = INTA; + vxge_debug_init(VXGE_ERR, + "%s: Defaulting to INTA", + vdev->ndev->name); goto INTA_MODE; - } } vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle, @@ -2584,6 +2547,10 @@ INTA_MODE: snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name); if (vdev->config.intr_type == INTA) { + vxge_hw_device_set_intr_type(vdev->devh, + VXGE_HW_INTR_MODE_IRQLINE); + vxge_hw_vpath_tti_ci_set(vdev->devh, + vdev->vpaths[0].device_id); ret = request_irq((int) vdev->pdev->irq, vxge_isr_napi, IRQF_SHARED, vdev->desc[0], vdev); @@ -2688,13 +2655,6 @@ vxge_open(struct net_device *dev) * initialized */ netif_carrier_off(dev); - /* Check for another device already opn with INTA */ - if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) && - test_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open)) { - ret = -EPERM; - goto out0; - } - /* Open VPATHs */ status = vxge_open_vpaths(vdev); if (status != VXGE_HW_OK) { @@ -2983,7 +2943,6 @@ int do_vxge_close(struct net_device *dev, int do_io) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", dev->name, __func__, __LINE__); - clear_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open); clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state); return 0; @@ -4397,6 +4356,27 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) } kfree(device_config); + + /* + * INTA is shared in multi-function mode. This is unlike the INTA + * implementation in MR mode, where each VH has its own INTA message. + * - INTA is masked (disabled) as long as at least one function sets + * its TITAN_MASK_ALL_INT.ALARM bit. + * - INTA is unmasked (enabled) when all enabled functions have cleared + * their own TITAN_MASK_ALL_INT.ALARM bit. + * The TITAN_MASK_ALL_INT ALARM & TRAFFIC bits are cleared on power up. + * Though this driver leaves the top level interrupts unmasked while + * leaving the required module interrupt bits masked on exit, there + * could be a rougue driver around that does not follow this procedure + * resulting in a failure to generate interrupts. The following code is + * present to prevent such a failure. + */ + + if (ll_config.device_hw_info.function_mode == + VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) + if (vdev->config.intr_type == INTA) + vxge_hw_device_unmask_all(hldev); + vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__); |