diff options
author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2008-05-12 13:41:32 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-22 06:26:19 -0400 |
commit | ac731ab66960547c33a4e2c504419389ae747067 (patch) | |
tree | bbede8dbb9ee6044838bc09f68adfaf4c5d87b32 /drivers/net/s2io.c | |
parent | 25c16fffa8ed82d3ef31980d76ff95d3c6430f00 (diff) |
S2io: Move all the transmit completions to a single msi-x (alarm) vector
- Move all the transmit completions to a single msi-x (alarm) vector.
- Enable the continuous timer interrupt for only one transmit fifo.
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 170 |
1 files changed, 102 insertions, 68 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 0f3d230a320d..e161a847c536 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -1220,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link) | |||
1220 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1220 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
1221 | TTI_DATA1_MEM_TX_URNG_C(0x30) | | 1221 | TTI_DATA1_MEM_TX_URNG_C(0x30) | |
1222 | TTI_DATA1_MEM_TX_TIMER_AC_EN; | 1222 | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
1223 | 1223 | if (i == 0) | |
1224 | if (use_continuous_tx_intrs && (link == LINK_UP)) | 1224 | if (use_continuous_tx_intrs && (link == LINK_UP)) |
1225 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1225 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; |
1226 | writeq(val64, &bar0->tti_data1_mem); | 1226 | writeq(val64, &bar0->tti_data1_mem); |
1227 | 1227 | ||
1228 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1228 | if (nic->config.intr_type == MSI_X) { |
1229 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1229 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
1230 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | 1230 | TTI_DATA2_MEM_TX_UFC_B(0x100) | |
1231 | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1231 | TTI_DATA2_MEM_TX_UFC_C(0x200) | |
1232 | TTI_DATA2_MEM_TX_UFC_D(0x300); | ||
1233 | } else { | ||
1234 | if ((nic->config.tx_steering_type == | ||
1235 | TX_DEFAULT_STEERING) && | ||
1236 | (config->tx_fifo_num > 1) && | ||
1237 | (i >= nic->udp_fifo_idx) && | ||
1238 | (i < (nic->udp_fifo_idx + | ||
1239 | nic->total_udp_fifos))) | ||
1240 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) | | ||
1241 | TTI_DATA2_MEM_TX_UFC_B(0x80) | | ||
1242 | TTI_DATA2_MEM_TX_UFC_C(0x100) | | ||
1243 | TTI_DATA2_MEM_TX_UFC_D(0x120); | ||
1244 | else | ||
1245 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1246 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1247 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | ||
1248 | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1249 | } | ||
1232 | 1250 | ||
1233 | writeq(val64, &bar0->tti_data2_mem); | 1251 | writeq(val64, &bar0->tti_data2_mem); |
1234 | 1252 | ||
@@ -3771,7 +3789,7 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3771 | static int s2io_enable_msi_x(struct s2io_nic *nic) | 3789 | static int s2io_enable_msi_x(struct s2io_nic *nic) |
3772 | { | 3790 | { |
3773 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3791 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3774 | u64 tx_mat, rx_mat; | 3792 | u64 rx_mat; |
3775 | u16 msi_control; /* Temp variable */ | 3793 | u16 msi_control; /* Temp variable */ |
3776 | int ret, i, j, msix_indx = 1; | 3794 | int ret, i, j, msix_indx = 1; |
3777 | 3795 | ||
@@ -3801,22 +3819,19 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3801 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3819 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3802 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3820 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); |
3803 | 3821 | ||
3804 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3822 | nic->entries[0].entry = 0; |
3823 | nic->s2io_entries[0].entry = 0; | ||
3824 | nic->s2io_entries[0].in_use = MSIX_FLG; | ||
3825 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; | ||
3826 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; | ||
3827 | |||
3828 | for (i = 1; i < MAX_REQUESTED_MSI_X; i++) { | ||
3805 | nic->entries[i].entry = i; | 3829 | nic->entries[i].entry = i; |
3806 | nic->s2io_entries[i].entry = i; | 3830 | nic->s2io_entries[i].entry = i; |
3807 | nic->s2io_entries[i].arg = NULL; | 3831 | nic->s2io_entries[i].arg = NULL; |
3808 | nic->s2io_entries[i].in_use = 0; | 3832 | nic->s2io_entries[i].in_use = 0; |
3809 | } | 3833 | } |
3810 | 3834 | ||
3811 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3812 | for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { | ||
3813 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3814 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; | ||
3815 | nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; | ||
3816 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3817 | } | ||
3818 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3819 | |||
3820 | rx_mat = readq(&bar0->rx_mat); | 3835 | rx_mat = readq(&bar0->rx_mat); |
3821 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { | 3836 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { |
3822 | rx_mat |= RX_MAT_SET(j, msix_indx); | 3837 | rx_mat |= RX_MAT_SET(j, msix_indx); |
@@ -4353,15 +4368,35 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | |||
4353 | 4368 | ||
4354 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | 4369 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) |
4355 | { | 4370 | { |
4356 | struct fifo_info *fifo = (struct fifo_info *)dev_id; | 4371 | int i; |
4357 | struct s2io_nic *sp = fifo->nic; | 4372 | struct fifo_info *fifos = (struct fifo_info *)dev_id; |
4373 | struct s2io_nic *sp = fifos->nic; | ||
4374 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4375 | struct config_param *config = &sp->config; | ||
4376 | u64 reason; | ||
4358 | 4377 | ||
4359 | if (!is_s2io_card_up(sp)) | 4378 | if (unlikely(!is_s2io_card_up(sp))) |
4379 | return IRQ_NONE; | ||
4380 | |||
4381 | reason = readq(&bar0->general_int_status); | ||
4382 | if (unlikely(reason == S2IO_MINUS_ONE)) | ||
4383 | /* Nothing much can be done. Get out */ | ||
4360 | return IRQ_HANDLED; | 4384 | return IRQ_HANDLED; |
4361 | 4385 | ||
4362 | tx_intr_handler(fifo); | 4386 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); |
4387 | |||
4388 | if (reason & GEN_INTR_TXTRAFFIC) | ||
4389 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | ||
4390 | |||
4391 | for (i = 0; i < config->tx_fifo_num; i++) | ||
4392 | tx_intr_handler(&fifos[i]); | ||
4393 | |||
4394 | writeq(sp->general_int_mask, &bar0->general_int_mask); | ||
4395 | readl(&bar0->general_int_status); | ||
4396 | |||
4363 | return IRQ_HANDLED; | 4397 | return IRQ_HANDLED; |
4364 | } | 4398 | } |
4399 | |||
4365 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4400 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) |
4366 | { | 4401 | { |
4367 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4402 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
@@ -6985,62 +7020,61 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6985 | 7020 | ||
6986 | /* After proper initialization of H/W, register ISR */ | 7021 | /* After proper initialization of H/W, register ISR */ |
6987 | if (sp->config.intr_type == MSI_X) { | 7022 | if (sp->config.intr_type == MSI_X) { |
6988 | int i, msix_tx_cnt=0,msix_rx_cnt=0; | 7023 | int i, msix_rx_cnt = 0; |
6989 | 7024 | ||
6990 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 7025 | for (i = 0; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { |
6991 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | 7026 | if (sp->s2io_entries[i].type == |
6992 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | 7027 | MSIX_RING_TYPE) { |
7028 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | ||
7029 | dev->name, i); | ||
7030 | err = request_irq(sp->entries[i].vector, | ||
7031 | s2io_msix_ring_handle, 0, | ||
7032 | sp->desc[i], | ||
7033 | sp->s2io_entries[i].arg); | ||
7034 | } else if (sp->s2io_entries[i].type == | ||
7035 | MSIX_ALARM_TYPE) { | ||
7036 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | ||
6993 | dev->name, i); | 7037 | dev->name, i); |
6994 | err = request_irq(sp->entries[i].vector, | 7038 | err = request_irq(sp->entries[i].vector, |
6995 | s2io_msix_fifo_handle, 0, sp->desc[i], | 7039 | s2io_msix_fifo_handle, 0, |
6996 | sp->s2io_entries[i].arg); | 7040 | sp->desc[i], |
6997 | /* If either data or addr is zero print it */ | 7041 | sp->s2io_entries[i].arg); |
6998 | if(!(sp->msix_info[i].addr && | 7042 | |
6999 | sp->msix_info[i].data)) { | ||
7000 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | ||
7001 | "Data:0x%llx\n",sp->desc[i], | ||
7002 | (unsigned long long) | ||
7003 | sp->msix_info[i].addr, | ||
7004 | (unsigned long long) | ||
7005 | sp->msix_info[i].data); | ||
7006 | } else { | ||
7007 | msix_tx_cnt++; | ||
7008 | } | 7043 | } |
7009 | } else { | 7044 | /* if either data or addr is zero print it. */ |
7010 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 7045 | if (!(sp->msix_info[i].addr && |
7011 | dev->name, i); | ||
7012 | err = request_irq(sp->entries[i].vector, | ||
7013 | s2io_msix_ring_handle, 0, sp->desc[i], | ||
7014 | sp->s2io_entries[i].arg); | ||
7015 | /* If either data or addr is zero print it */ | ||
7016 | if(!(sp->msix_info[i].addr && | ||
7017 | sp->msix_info[i].data)) { | 7046 | sp->msix_info[i].data)) { |
7018 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7047 | DBG_PRINT(ERR_DBG, |
7019 | "Data:0x%llx\n",sp->desc[i], | 7048 | "%s @Addr:0x%llx Data:0x%llx\n", |
7049 | sp->desc[i], | ||
7020 | (unsigned long long) | 7050 | (unsigned long long) |
7021 | sp->msix_info[i].addr, | 7051 | sp->msix_info[i].addr, |
7022 | (unsigned long long) | 7052 | (unsigned long long) |
7023 | sp->msix_info[i].data); | 7053 | ntohl(sp->msix_info[i].data)); |
7024 | } else { | 7054 | } else |
7025 | msix_rx_cnt++; | 7055 | msix_rx_cnt++; |
7056 | if (err) { | ||
7057 | remove_msix_isr(sp); | ||
7058 | |||
7059 | DBG_PRINT(ERR_DBG, | ||
7060 | "%s:MSI-X-%d registration " | ||
7061 | "failed\n", dev->name, i); | ||
7062 | |||
7063 | DBG_PRINT(ERR_DBG, | ||
7064 | "%s: Defaulting to INTA\n", | ||
7065 | dev->name); | ||
7066 | sp->config.intr_type = INTA; | ||
7067 | break; | ||
7026 | } | 7068 | } |
7027 | } | 7069 | sp->s2io_entries[i].in_use = |
7028 | if (err) { | 7070 | MSIX_REGISTERED_SUCCESS; |
7029 | remove_msix_isr(sp); | 7071 | |
7030 | DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " | ||
7031 | "failed\n", dev->name, i); | ||
7032 | DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n", | ||
7033 | dev->name); | ||
7034 | sp->config.intr_type = INTA; | ||
7035 | break; | ||
7036 | } | ||
7037 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
7038 | } | 7072 | } |
7039 | if (!err) { | 7073 | if (!err) { |
7040 | printk(KERN_INFO "MSI-X-TX %d entries enabled\n", | ||
7041 | msix_tx_cnt); | ||
7042 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", | 7074 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", |
7043 | msix_rx_cnt); | 7075 | --msix_rx_cnt); |
7076 | DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled" | ||
7077 | " through alarm vector\n"); | ||
7044 | } | 7078 | } |
7045 | } | 7079 | } |
7046 | if (sp->config.intr_type == INTA) { | 7080 | if (sp->config.intr_type == INTA) { |
@@ -7218,7 +7252,7 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7218 | /* Enable select interrupts */ | 7252 | /* Enable select interrupts */ |
7219 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7253 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7220 | if (sp->config.intr_type != INTA) | 7254 | if (sp->config.intr_type != INTA) |
7221 | en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); | 7255 | en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); |
7222 | else { | 7256 | else { |
7223 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 7257 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
7224 | interruptible |= TX_PIC_INTR; | 7258 | interruptible |= TX_PIC_INTR; |