diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 158 |
1 files changed, 10 insertions, 148 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 6bfb191634e7..724b44360a47 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -37,7 +37,7 @@ | |||
37 | * tx_fifo_len: This too is an array of 8. Each element defines the number of | 37 | * tx_fifo_len: This too is an array of 8. Each element defines the number of |
38 | * Tx descriptors that can be associated with each corresponding FIFO. | 38 | * Tx descriptors that can be associated with each corresponding FIFO. |
39 | * intr_type: This defines the type of interrupt. The values can be 0(INTA), | 39 | * intr_type: This defines the type of interrupt. The values can be 0(INTA), |
40 | * 1(MSI), 2(MSI_X). Default value is '0(INTA)' | 40 | * 2(MSI_X). Default value is '0(INTA)' |
41 | * lro: Specifies whether to enable Large Receive Offload (LRO) or not. | 41 | * lro: Specifies whether to enable Large Receive Offload (LRO) or not. |
42 | * Possible values '1' for enable '0' for disable. Default is '0' | 42 | * Possible values '1' for enable '0' for disable. Default is '0' |
43 | * lro_max_pkts: This parameter defines maximum number of packets can be | 43 | * lro_max_pkts: This parameter defines maximum number of packets can be |
@@ -426,7 +426,7 @@ S2IO_PARM_INT(bimodal, 0); | |||
426 | S2IO_PARM_INT(l3l4hdr_size, 128); | 426 | S2IO_PARM_INT(l3l4hdr_size, 128); |
427 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 427 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
428 | S2IO_PARM_INT(rxsync_frequency, 3); | 428 | S2IO_PARM_INT(rxsync_frequency, 3); |
429 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ | 429 | /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ |
430 | S2IO_PARM_INT(intr_type, 0); | 430 | S2IO_PARM_INT(intr_type, 0); |
431 | /* Large receive offload feature */ | 431 | /* Large receive offload feature */ |
432 | S2IO_PARM_INT(lro, 0); | 432 | S2IO_PARM_INT(lro, 0); |
@@ -3662,56 +3662,6 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3662 | } | 3662 | } |
3663 | } | 3663 | } |
3664 | 3664 | ||
3665 | int s2io_enable_msi(struct s2io_nic *nic) | ||
3666 | { | ||
3667 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
3668 | u16 msi_ctrl, msg_val; | ||
3669 | struct config_param *config = &nic->config; | ||
3670 | struct net_device *dev = nic->dev; | ||
3671 | u64 val64, tx_mat, rx_mat; | ||
3672 | int i, err; | ||
3673 | |||
3674 | val64 = readq(&bar0->pic_control); | ||
3675 | val64 &= ~BIT(1); | ||
3676 | writeq(val64, &bar0->pic_control); | ||
3677 | |||
3678 | err = pci_enable_msi(nic->pdev); | ||
3679 | if (err) { | ||
3680 | DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n", | ||
3681 | nic->dev->name); | ||
3682 | return err; | ||
3683 | } | ||
3684 | |||
3685 | /* | ||
3686 | * Enable MSI and use MSI-1 in stead of the standard MSI-0 | ||
3687 | * for interrupt handling. | ||
3688 | */ | ||
3689 | pci_read_config_word(nic->pdev, 0x4c, &msg_val); | ||
3690 | msg_val ^= 0x1; | ||
3691 | pci_write_config_word(nic->pdev, 0x4c, msg_val); | ||
3692 | pci_read_config_word(nic->pdev, 0x4c, &msg_val); | ||
3693 | |||
3694 | pci_read_config_word(nic->pdev, 0x42, &msi_ctrl); | ||
3695 | msi_ctrl |= 0x10; | ||
3696 | pci_write_config_word(nic->pdev, 0x42, msi_ctrl); | ||
3697 | |||
3698 | /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */ | ||
3699 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3700 | for (i=0; i<config->tx_fifo_num; i++) { | ||
3701 | tx_mat |= TX_MAT_SET(i, 1); | ||
3702 | } | ||
3703 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3704 | |||
3705 | rx_mat = readq(&bar0->rx_mat); | ||
3706 | for (i=0; i<config->rx_ring_num; i++) { | ||
3707 | rx_mat |= RX_MAT_SET(i, 1); | ||
3708 | } | ||
3709 | writeq(rx_mat, &bar0->rx_mat); | ||
3710 | |||
3711 | dev->irq = nic->pdev->irq; | ||
3712 | return 0; | ||
3713 | } | ||
3714 | |||
3715 | static int s2io_enable_msi_x(struct s2io_nic *nic) | 3665 | static int s2io_enable_msi_x(struct s2io_nic *nic) |
3716 | { | 3666 | { |
3717 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3667 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
@@ -4117,39 +4067,6 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) | |||
4117 | return 0; | 4067 | return 0; |
4118 | } | 4068 | } |
4119 | 4069 | ||
4120 | static irqreturn_t s2io_msi_handle(int irq, void *dev_id) | ||
4121 | { | ||
4122 | struct net_device *dev = (struct net_device *) dev_id; | ||
4123 | struct s2io_nic *sp = dev->priv; | ||
4124 | int i; | ||
4125 | struct mac_info *mac_control; | ||
4126 | struct config_param *config; | ||
4127 | |||
4128 | atomic_inc(&sp->isr_cnt); | ||
4129 | mac_control = &sp->mac_control; | ||
4130 | config = &sp->config; | ||
4131 | DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__); | ||
4132 | |||
4133 | /* If Intr is because of Rx Traffic */ | ||
4134 | for (i = 0; i < config->rx_ring_num; i++) | ||
4135 | rx_intr_handler(&mac_control->rings[i]); | ||
4136 | |||
4137 | /* If Intr is because of Tx Traffic */ | ||
4138 | for (i = 0; i < config->tx_fifo_num; i++) | ||
4139 | tx_intr_handler(&mac_control->fifos[i]); | ||
4140 | |||
4141 | /* | ||
4142 | * If the Rx buffer count is below the panic threshold then | ||
4143 | * reallocate the buffers from the interrupt handler itself, | ||
4144 | * else schedule a tasklet to reallocate the buffers. | ||
4145 | */ | ||
4146 | for (i = 0; i < config->rx_ring_num; i++) | ||
4147 | s2io_chk_rx_buffers(sp, i); | ||
4148 | |||
4149 | atomic_dec(&sp->isr_cnt); | ||
4150 | return IRQ_HANDLED; | ||
4151 | } | ||
4152 | |||
4153 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | 4070 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) |
4154 | { | 4071 | { |
4155 | struct ring_info *ring = (struct ring_info *)dev_id; | 4072 | struct ring_info *ring = (struct ring_info *)dev_id; |
@@ -6332,9 +6249,7 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6332 | struct net_device *dev = sp->dev; | 6249 | struct net_device *dev = sp->dev; |
6333 | int err = 0; | 6250 | int err = 0; |
6334 | 6251 | ||
6335 | if (sp->intr_type == MSI) | 6252 | if (sp->intr_type == MSI_X) |
6336 | ret = s2io_enable_msi(sp); | ||
6337 | else if (sp->intr_type == MSI_X) | ||
6338 | ret = s2io_enable_msi_x(sp); | 6253 | ret = s2io_enable_msi_x(sp); |
6339 | if (ret) { | 6254 | if (ret) { |
6340 | DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); | 6255 | DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); |
@@ -6345,16 +6260,6 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6345 | store_xmsi_data(sp); | 6260 | store_xmsi_data(sp); |
6346 | 6261 | ||
6347 | /* After proper initialization of H/W, register ISR */ | 6262 | /* After proper initialization of H/W, register ISR */ |
6348 | if (sp->intr_type == MSI) { | ||
6349 | err = request_irq((int) sp->pdev->irq, s2io_msi_handle, | ||
6350 | IRQF_SHARED, sp->name, dev); | ||
6351 | if (err) { | ||
6352 | pci_disable_msi(sp->pdev); | ||
6353 | DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n", | ||
6354 | dev->name); | ||
6355 | return -1; | ||
6356 | } | ||
6357 | } | ||
6358 | if (sp->intr_type == MSI_X) { | 6263 | if (sp->intr_type == MSI_X) { |
6359 | int i, msix_tx_cnt=0,msix_rx_cnt=0; | 6264 | int i, msix_tx_cnt=0,msix_rx_cnt=0; |
6360 | 6265 | ||
@@ -6441,14 +6346,6 @@ static void s2io_rem_isr(struct s2io_nic * sp) | |||
6441 | pci_disable_msix(sp->pdev); | 6346 | pci_disable_msix(sp->pdev); |
6442 | } else { | 6347 | } else { |
6443 | free_irq(sp->pdev->irq, dev); | 6348 | free_irq(sp->pdev->irq, dev); |
6444 | if (sp->intr_type == MSI) { | ||
6445 | u16 val; | ||
6446 | |||
6447 | pci_disable_msi(sp->pdev); | ||
6448 | pci_read_config_word(sp->pdev, 0x4c, &val); | ||
6449 | val ^= 0x1; | ||
6450 | pci_write_config_word(sp->pdev, 0x4c, val); | ||
6451 | } | ||
6452 | } | 6349 | } |
6453 | /* Waiting till all Interrupt handlers are complete */ | 6350 | /* Waiting till all Interrupt handlers are complete */ |
6454 | cnt = 0; | 6351 | cnt = 0; |
@@ -6994,7 +6891,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | |||
6994 | *dev_intr_type = INTA; | 6891 | *dev_intr_type = INTA; |
6995 | } | 6892 | } |
6996 | #else | 6893 | #else |
6997 | if (*dev_intr_type > MSI_X) { | 6894 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
6998 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 6895 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
6999 | "Defaulting to INTA\n"); | 6896 | "Defaulting to INTA\n"); |
7000 | *dev_intr_type = INTA; | 6897 | *dev_intr_type = INTA; |
@@ -7103,28 +7000,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7103 | pci_disable_device(pdev); | 7000 | pci_disable_device(pdev); |
7104 | return -ENOMEM; | 7001 | return -ENOMEM; |
7105 | } | 7002 | } |
7106 | if (dev_intr_type != MSI_X) { | 7003 | if ((ret = pci_request_regions(pdev, s2io_driver_name))) { |
7107 | if (pci_request_regions(pdev, s2io_driver_name)) { | 7004 | DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret); |
7108 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"); | 7005 | pci_disable_device(pdev); |
7109 | pci_disable_device(pdev); | 7006 | return -ENODEV; |
7110 | return -ENODEV; | ||
7111 | } | ||
7112 | } | ||
7113 | else { | ||
7114 | if (!(request_mem_region(pci_resource_start(pdev, 0), | ||
7115 | pci_resource_len(pdev, 0), s2io_driver_name))) { | ||
7116 | DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n"); | ||
7117 | pci_disable_device(pdev); | ||
7118 | return -ENODEV; | ||
7119 | } | ||
7120 | if (!(request_mem_region(pci_resource_start(pdev, 2), | ||
7121 | pci_resource_len(pdev, 2), s2io_driver_name))) { | ||
7122 | DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n"); | ||
7123 | release_mem_region(pci_resource_start(pdev, 0), | ||
7124 | pci_resource_len(pdev, 0)); | ||
7125 | pci_disable_device(pdev); | ||
7126 | return -ENODEV; | ||
7127 | } | ||
7128 | } | 7007 | } |
7129 | 7008 | ||
7130 | dev = alloc_etherdev(sizeof(struct s2io_nic)); | 7009 | dev = alloc_etherdev(sizeof(struct s2io_nic)); |
@@ -7434,9 +7313,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7434 | case INTA: | 7313 | case INTA: |
7435 | DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); | 7314 | DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); |
7436 | break; | 7315 | break; |
7437 | case MSI: | ||
7438 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); | ||
7439 | break; | ||
7440 | case MSI_X: | 7316 | case MSI_X: |
7441 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); | 7317 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); |
7442 | break; | 7318 | break; |
@@ -7476,14 +7352,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7476 | mem_alloc_failed: | 7352 | mem_alloc_failed: |
7477 | free_shared_mem(sp); | 7353 | free_shared_mem(sp); |
7478 | pci_disable_device(pdev); | 7354 | pci_disable_device(pdev); |
7479 | if (dev_intr_type != MSI_X) | 7355 | pci_release_regions(pdev); |
7480 | pci_release_regions(pdev); | ||
7481 | else { | ||
7482 | release_mem_region(pci_resource_start(pdev, 0), | ||
7483 | pci_resource_len(pdev, 0)); | ||
7484 | release_mem_region(pci_resource_start(pdev, 2), | ||
7485 | pci_resource_len(pdev, 2)); | ||
7486 | } | ||
7487 | pci_set_drvdata(pdev, NULL); | 7356 | pci_set_drvdata(pdev, NULL); |
7488 | free_netdev(dev); | 7357 | free_netdev(dev); |
7489 | 7358 | ||
@@ -7518,14 +7387,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) | |||
7518 | free_shared_mem(sp); | 7387 | free_shared_mem(sp); |
7519 | iounmap(sp->bar0); | 7388 | iounmap(sp->bar0); |
7520 | iounmap(sp->bar1); | 7389 | iounmap(sp->bar1); |
7521 | if (sp->intr_type != MSI_X) | 7390 | pci_release_regions(pdev); |
7522 | pci_release_regions(pdev); | ||
7523 | else { | ||
7524 | release_mem_region(pci_resource_start(pdev, 0), | ||
7525 | pci_resource_len(pdev, 0)); | ||
7526 | release_mem_region(pci_resource_start(pdev, 2), | ||
7527 | pci_resource_len(pdev, 2)); | ||
7528 | } | ||
7529 | pci_set_drvdata(pdev, NULL); | 7391 | pci_set_drvdata(pdev, NULL); |
7530 | free_netdev(dev); | 7392 | free_netdev(dev); |
7531 | pci_disable_device(pdev); | 7393 | pci_disable_device(pdev); |