|
@@ -1891,8 +1891,6 @@ static int init_nic(struct s2io_nic *nic)
|
|
|
|
|
|
static int s2io_link_fault_indication(struct s2io_nic *nic)
|
|
|
{
|
|
|
- if (nic->config.intr_type != INTA)
|
|
|
- return MAC_RMAC_ERR_TIMER;
|
|
|
if (nic->device_type == XFRAME_II_DEVICE)
|
|
|
return LINK_UP_DOWN_INTERRUPT;
|
|
|
else
|
|
@@ -1925,7 +1923,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
|
|
|
{
|
|
|
struct XENA_dev_config __iomem *bar0 = nic->bar0;
|
|
|
register u64 gen_int_mask = 0;
|
|
|
+ u64 interruptible;
|
|
|
|
|
|
+ writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask);
|
|
|
if (mask & TX_DMA_INTR) {
|
|
|
|
|
|
gen_int_mask |= TXDMA_INT_M;
|
|
@@ -2015,10 +2015,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
|
|
|
gen_int_mask |= RXMAC_INT_M;
|
|
|
do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
|
|
|
&bar0->mac_int_mask);
|
|
|
- do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
|
|
|
+ interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
|
|
|
RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
|
|
|
- RMAC_DOUBLE_ECC_ERR |
|
|
|
- RMAC_LINK_STATE_CHANGE_INT,
|
|
|
+ RMAC_DOUBLE_ECC_ERR;
|
|
|
+ if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER)
|
|
|
+ interruptible |= RMAC_LINK_STATE_CHANGE_INT;
|
|
|
+ do_s2io_write_bits(interruptible,
|
|
|
flag, &bar0->mac_rmac_err_mask);
|
|
|
}
|
|
|
|
|
@@ -4376,18 +4378,24 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
|
|
|
/* Nothing much can be done. Get out */
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
|
- writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
|
|
|
+ if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) {
|
|
|
+ writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
|
|
|
|
|
|
- if (reason & GEN_INTR_TXTRAFFIC)
|
|
|
- writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
|
|
|
+ if (reason & GEN_INTR_TXPIC)
|
|
|
+ s2io_txpic_intr_handle(sp);
|
|
|
|
|
|
- for (i = 0; i < config->tx_fifo_num; i++)
|
|
|
- tx_intr_handler(&fifos[i]);
|
|
|
+ if (reason & GEN_INTR_TXTRAFFIC)
|
|
|
+ writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
|
|
|
|
|
|
- writeq(sp->general_int_mask, &bar0->general_int_mask);
|
|
|
- readl(&bar0->general_int_status);
|
|
|
+ for (i = 0; i < config->tx_fifo_num; i++)
|
|
|
+ tx_intr_handler(&fifos[i]);
|
|
|
|
|
|
- return IRQ_HANDLED;
|
|
|
+ writeq(sp->general_int_mask, &bar0->general_int_mask);
|
|
|
+ readl(&bar0->general_int_status);
|
|
|
+ return IRQ_HANDLED;
|
|
|
+ }
|
|
|
+ /* The interrupt was not raised by us */
|
|
|
+ return IRQ_NONE;
|
|
|
}
|
|
|
|
|
|
static void s2io_txpic_intr_handle(struct s2io_nic *sp)
|
|
@@ -7115,6 +7123,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
|
|
|
|
|
|
s2io_rem_isr(sp);
|
|
|
|
|
|
+ /* stop the tx queue, indicate link down */
|
|
|
+ s2io_link(sp, LINK_DOWN);
|
|
|
+
|
|
|
/* Check if the device is Quiescent and then Reset the NIC */
|
|
|
while(do_io) {
|
|
|
/* As per the HW requirement we need to replenish the
|
|
@@ -7247,17 +7258,19 @@ static int s2io_card_up(struct s2io_nic * sp)
|
|
|
|
|
|
S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
|
|
|
|
|
|
+ set_bit(__S2IO_STATE_CARD_UP, &sp->state);
|
|
|
+
|
|
|
/* Enable select interrupts */
|
|
|
en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
|
|
|
- if (sp->config.intr_type != INTA)
|
|
|
- en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
|
|
|
- else {
|
|
|
+ if (sp->config.intr_type != INTA) {
|
|
|
+ interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR;
|
|
|
+ en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
|
|
|
+ } else {
|
|
|
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
|
|
|
interruptible |= TX_PIC_INTR;
|
|
|
en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
|
|
|
}
|
|
|
|
|
|
- set_bit(__S2IO_STATE_CARD_UP, &sp->state);
|
|
|
return 0;
|
|
|
}
|
|
|
|