Commit ac731ab6 authored by Sreenivasa Honnur's avatar Sreenivasa Honnur Committed by Jeff Garzik

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: default avatarSantosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: default avatarRamkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 25c16fff
...@@ -1220,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link) ...@@ -1220,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link)
TTI_DATA1_MEM_TX_URNG_B(0x10) | TTI_DATA1_MEM_TX_URNG_B(0x10) |
TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_URNG_C(0x30) |
TTI_DATA1_MEM_TX_TIMER_AC_EN; TTI_DATA1_MEM_TX_TIMER_AC_EN;
if (i == 0)
if (use_continuous_tx_intrs && (link == LINK_UP)) if (use_continuous_tx_intrs && (link == LINK_UP))
val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
writeq(val64, &bar0->tti_data1_mem); writeq(val64, &bar0->tti_data1_mem);
if (nic->config.intr_type == MSI_X) {
val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
TTI_DATA2_MEM_TX_UFC_B(0x100) |
TTI_DATA2_MEM_TX_UFC_C(0x200) |
TTI_DATA2_MEM_TX_UFC_D(0x300);
} else {
if ((nic->config.tx_steering_type ==
TX_DEFAULT_STEERING) &&
(config->tx_fifo_num > 1) &&
(i >= nic->udp_fifo_idx) &&
(i < (nic->udp_fifo_idx +
nic->total_udp_fifos)))
val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) |
TTI_DATA2_MEM_TX_UFC_B(0x80) |
TTI_DATA2_MEM_TX_UFC_C(0x100) |
TTI_DATA2_MEM_TX_UFC_D(0x120);
else
val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
TTI_DATA2_MEM_TX_UFC_B(0x20) | TTI_DATA2_MEM_TX_UFC_B(0x20) |
TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_C(0x40) |
TTI_DATA2_MEM_TX_UFC_D(0x80); TTI_DATA2_MEM_TX_UFC_D(0x80);
}
writeq(val64, &bar0->tti_data2_mem); writeq(val64, &bar0->tti_data2_mem);
...@@ -3771,7 +3789,7 @@ static void store_xmsi_data(struct s2io_nic *nic) ...@@ -3771,7 +3789,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
static int s2io_enable_msi_x(struct s2io_nic *nic) static int s2io_enable_msi_x(struct s2io_nic *nic)
{ {
struct XENA_dev_config __iomem *bar0 = nic->bar0; struct XENA_dev_config __iomem *bar0 = nic->bar0;
u64 tx_mat, rx_mat; u64 rx_mat;
u16 msi_control; /* Temp variable */ u16 msi_control; /* Temp variable */
int ret, i, j, msix_indx = 1; int ret, i, j, msix_indx = 1;
...@@ -3801,22 +3819,19 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) ...@@ -3801,22 +3819,19 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
nic->mac_control.stats_info->sw_stat.mem_allocated nic->mac_control.stats_info->sw_stat.mem_allocated
+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
for (i=0; i< MAX_REQUESTED_MSI_X; i++) { nic->entries[0].entry = 0;
nic->s2io_entries[0].entry = 0;
nic->s2io_entries[0].in_use = MSIX_FLG;
nic->s2io_entries[0].type = MSIX_ALARM_TYPE;
nic->s2io_entries[0].arg = &nic->mac_control.fifos;
for (i = 1; i < MAX_REQUESTED_MSI_X; i++) {
nic->entries[i].entry = i; nic->entries[i].entry = i;
nic->s2io_entries[i].entry = i; nic->s2io_entries[i].entry = i;
nic->s2io_entries[i].arg = NULL; nic->s2io_entries[i].arg = NULL;
nic->s2io_entries[i].in_use = 0; nic->s2io_entries[i].in_use = 0;
} }
tx_mat = readq(&bar0->tx_mat0_n[0]);
for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
tx_mat |= TX_MAT_SET(i, msix_indx);
nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
}
writeq(tx_mat, &bar0->tx_mat0_n[0]);
rx_mat = readq(&bar0->rx_mat); rx_mat = readq(&bar0->rx_mat);
for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) {
rx_mat |= RX_MAT_SET(j, msix_indx); 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,15 +4368,35 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
{ {
struct fifo_info *fifo = (struct fifo_info *)dev_id; int i;
struct s2io_nic *sp = fifo->nic; struct fifo_info *fifos = (struct fifo_info *)dev_id;
struct s2io_nic *sp = fifos->nic;
struct XENA_dev_config __iomem *bar0 = sp->bar0;
struct config_param *config = &sp->config;
u64 reason;
if (!is_s2io_card_up(sp)) if (unlikely(!is_s2io_card_up(sp)))
return IRQ_NONE;
reason = readq(&bar0->general_int_status);
if (unlikely(reason == S2IO_MINUS_ONE))
/* Nothing much can be done. Get out */
return IRQ_HANDLED; return IRQ_HANDLED;
tx_intr_handler(fifo); writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
if (reason & GEN_INTR_TXTRAFFIC)
writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
for (i = 0; i < config->tx_fifo_num; i++)
tx_intr_handler(&fifos[i]);
writeq(sp->general_int_mask, &bar0->general_int_mask);
readl(&bar0->general_int_status);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void s2io_txpic_intr_handle(struct s2io_nic *sp) static void s2io_txpic_intr_handle(struct s2io_nic *sp)
{ {
struct XENA_dev_config __iomem *bar0 = sp->bar0; struct XENA_dev_config __iomem *bar0 = sp->bar0;
...@@ -6985,62 +7020,61 @@ static int s2io_add_isr(struct s2io_nic * sp) ...@@ -6985,62 +7020,61 @@ static int s2io_add_isr(struct s2io_nic * sp)
/* After proper initialization of H/W, register ISR */ /* After proper initialization of H/W, register ISR */
if (sp->config.intr_type == MSI_X) { if (sp->config.intr_type == MSI_X) {
int i, msix_tx_cnt=0,msix_rx_cnt=0; int i, msix_rx_cnt = 0;
for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { for (i = 0; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { if (sp->s2io_entries[i].type ==
sprintf(sp->desc[i], "%s:MSI-X-%d-TX", MSIX_RING_TYPE) {
sprintf(sp->desc[i], "%s:MSI-X-%d-RX",
dev->name, i); dev->name, i);
err = request_irq(sp->entries[i].vector, err = request_irq(sp->entries[i].vector,
s2io_msix_fifo_handle, 0, sp->desc[i], s2io_msix_ring_handle, 0,
sp->desc[i],
sp->s2io_entries[i].arg); sp->s2io_entries[i].arg);
/* If either data or addr is zero print it */ } else if (sp->s2io_entries[i].type ==
if(!(sp->msix_info[i].addr && MSIX_ALARM_TYPE) {
sp->msix_info[i].data)) { sprintf(sp->desc[i], "%s:MSI-X-%d-TX",
DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx "
"Data:0x%llx\n",sp->desc[i],
(unsigned long long)
sp->msix_info[i].addr,
(unsigned long long)
sp->msix_info[i].data);
} else {
msix_tx_cnt++;
}
} else {
sprintf(sp->desc[i], "%s:MSI-X-%d-RX",
dev->name, i); dev->name, i);
err = request_irq(sp->entries[i].vector, err = request_irq(sp->entries[i].vector,
s2io_msix_ring_handle, 0, sp->desc[i], s2io_msix_fifo_handle, 0,
sp->desc[i],
sp->s2io_entries[i].arg); sp->s2io_entries[i].arg);
/* If either data or addr is zero print it */
if(!(sp->msix_info[i].addr && }
/* if either data or addr is zero print it. */
if (!(sp->msix_info[i].addr &&
sp->msix_info[i].data)) { sp->msix_info[i].data)) {
DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " DBG_PRINT(ERR_DBG,
"Data:0x%llx\n",sp->desc[i], "%s @Addr:0x%llx Data:0x%llx\n",
sp->desc[i],
(unsigned long long) (unsigned long long)
sp->msix_info[i].addr, sp->msix_info[i].addr,
(unsigned long long) (unsigned long long)
sp->msix_info[i].data); ntohl(sp->msix_info[i].data));
} else { } else
msix_rx_cnt++; msix_rx_cnt++;
}
}
if (err) { if (err) {
remove_msix_isr(sp); remove_msix_isr(sp);
DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration "
DBG_PRINT(ERR_DBG,
"%s:MSI-X-%d registration "
"failed\n", dev->name, i); "failed\n", dev->name, i);
DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n",
DBG_PRINT(ERR_DBG,
"%s: Defaulting to INTA\n",
dev->name); dev->name);
sp->config.intr_type = INTA; sp->config.intr_type = INTA;
break; break;
} }
sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; sp->s2io_entries[i].in_use =
MSIX_REGISTERED_SUCCESS;
} }
if (!err) { if (!err) {
printk(KERN_INFO "MSI-X-TX %d entries enabled\n",
msix_tx_cnt);
printk(KERN_INFO "MSI-X-RX %d entries enabled\n", printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
msix_rx_cnt); --msix_rx_cnt);
DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled"
" through alarm vector\n");
} }
} }
if (sp->config.intr_type == INTA) { if (sp->config.intr_type == INTA) {
...@@ -7218,7 +7252,7 @@ static int s2io_card_up(struct s2io_nic * sp) ...@@ -7218,7 +7252,7 @@ static int s2io_card_up(struct s2io_nic * sp)
/* Enable select interrupts */ /* Enable select interrupts */
en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
if (sp->config.intr_type != INTA) if (sp->config.intr_type != INTA)
en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
else { else {
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
interruptible |= TX_PIC_INTR; interruptible |= TX_PIC_INTR;
......
...@@ -849,7 +849,7 @@ struct s2io_msix_entry ...@@ -849,7 +849,7 @@ struct s2io_msix_entry
void *arg; void *arg;
u8 type; u8 type;
#define MSIX_FIFO_TYPE 1 #define MSIX_ALARM_TYPE 1
#define MSIX_RING_TYPE 2 #define MSIX_RING_TYPE 2
u8 in_use; u8 in_use;
...@@ -982,6 +982,7 @@ struct s2io_nic { ...@@ -982,6 +982,7 @@ struct s2io_nic {
u16 lro_max_aggr_per_sess; u16 lro_max_aggr_per_sess;
volatile unsigned long state; volatile unsigned long state;
u64 general_int_mask; u64 general_int_mask;
#define VPD_STRING_LEN 80 #define VPD_STRING_LEN 80
u8 product_name[VPD_STRING_LEN]; u8 product_name[VPD_STRING_LEN];
u8 serial_num[VPD_STRING_LEN]; u8 serial_num[VPD_STRING_LEN];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment