aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/s2io.c
diff options
context:
space:
mode:
authorSreenivasa Honnur <Sreenivasa.Honnur@neterion.com>2008-05-12 13:41:32 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-22 06:26:19 -0400
commitac731ab66960547c33a4e2c504419389ae747067 (patch)
treebbede8dbb9ee6044838bc09f68adfaf4c5d87b32 /drivers/net/s2io.c
parent25c16fffa8ed82d3ef31980d76ff95d3c6430f00 (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.c170
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)
3771static int s2io_enable_msi_x(struct s2io_nic *nic) 3789static 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
4354static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) 4369static 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
4365static void s2io_txpic_intr_handle(struct s2io_nic *sp) 4400static 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;