diff options
author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2008-07-09 23:49:21 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-11 01:11:40 -0400 |
commit | 01e16faa0691c57fd8f9bac46b1953ff7692ab8a (patch) | |
tree | 3625bf5eb5fd6f1900815604cd51dc187d18777f /drivers/net | |
parent | 3f78d88575d99e17218a5bb2d79e251a781d16ad (diff) |
S2io: Enable msi-x link interrupts.
- Enable msi-x link interrupts because the timer based scheduler was getting
cancelled causing the link state to be lost with repetitive card up/downs
when changing the mtu.
- Unmask mac_rmac_link interrupts only for Xframe I and prevent a spurious
link interrupt in Xframe II.
- Stop the tx queue and indicate link down when card is down
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')
-rw-r--r-- | drivers/net/s2io.c | 47 | ||||
-rw-r--r-- | drivers/net/s2io.h | 1 |
2 files changed, 31 insertions, 17 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 685030bb1d5e..7f89b433bfc3 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -1891,8 +1891,6 @@ static int init_nic(struct s2io_nic *nic) | |||
1891 | 1891 | ||
1892 | static int s2io_link_fault_indication(struct s2io_nic *nic) | 1892 | static int s2io_link_fault_indication(struct s2io_nic *nic) |
1893 | { | 1893 | { |
1894 | if (nic->config.intr_type != INTA) | ||
1895 | return MAC_RMAC_ERR_TIMER; | ||
1896 | if (nic->device_type == XFRAME_II_DEVICE) | 1894 | if (nic->device_type == XFRAME_II_DEVICE) |
1897 | return LINK_UP_DOWN_INTERRUPT; | 1895 | return LINK_UP_DOWN_INTERRUPT; |
1898 | else | 1896 | else |
@@ -1925,7 +1923,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) | |||
1925 | { | 1923 | { |
1926 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 1924 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
1927 | register u64 gen_int_mask = 0; | 1925 | register u64 gen_int_mask = 0; |
1926 | u64 interruptible; | ||
1928 | 1927 | ||
1928 | writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask); | ||
1929 | if (mask & TX_DMA_INTR) { | 1929 | if (mask & TX_DMA_INTR) { |
1930 | 1930 | ||
1931 | gen_int_mask |= TXDMA_INT_M; | 1931 | gen_int_mask |= TXDMA_INT_M; |
@@ -2015,10 +2015,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) | |||
2015 | gen_int_mask |= RXMAC_INT_M; | 2015 | gen_int_mask |= RXMAC_INT_M; |
2016 | do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag, | 2016 | do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag, |
2017 | &bar0->mac_int_mask); | 2017 | &bar0->mac_int_mask); |
2018 | do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | | 2018 | interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | |
2019 | RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR | | 2019 | RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR | |
2020 | RMAC_DOUBLE_ECC_ERR | | 2020 | RMAC_DOUBLE_ECC_ERR; |
2021 | RMAC_LINK_STATE_CHANGE_INT, | 2021 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) |
2022 | interruptible |= RMAC_LINK_STATE_CHANGE_INT; | ||
2023 | do_s2io_write_bits(interruptible, | ||
2022 | flag, &bar0->mac_rmac_err_mask); | 2024 | flag, &bar0->mac_rmac_err_mask); |
2023 | } | 2025 | } |
2024 | 2026 | ||
@@ -4376,18 +4378,24 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | |||
4376 | /* Nothing much can be done. Get out */ | 4378 | /* Nothing much can be done. Get out */ |
4377 | return IRQ_HANDLED; | 4379 | return IRQ_HANDLED; |
4378 | 4380 | ||
4379 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); | 4381 | if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) { |
4382 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); | ||
4380 | 4383 | ||
4381 | if (reason & GEN_INTR_TXTRAFFIC) | 4384 | if (reason & GEN_INTR_TXPIC) |
4382 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | 4385 | s2io_txpic_intr_handle(sp); |
4383 | 4386 | ||
4384 | for (i = 0; i < config->tx_fifo_num; i++) | 4387 | if (reason & GEN_INTR_TXTRAFFIC) |
4385 | tx_intr_handler(&fifos[i]); | 4388 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); |
4386 | 4389 | ||
4387 | writeq(sp->general_int_mask, &bar0->general_int_mask); | 4390 | for (i = 0; i < config->tx_fifo_num; i++) |
4388 | readl(&bar0->general_int_status); | 4391 | tx_intr_handler(&fifos[i]); |
4389 | 4392 | ||
4390 | return IRQ_HANDLED; | 4393 | writeq(sp->general_int_mask, &bar0->general_int_mask); |
4394 | readl(&bar0->general_int_status); | ||
4395 | return IRQ_HANDLED; | ||
4396 | } | ||
4397 | /* The interrupt was not raised by us */ | ||
4398 | return IRQ_NONE; | ||
4391 | } | 4399 | } |
4392 | 4400 | ||
4393 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4401 | 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) | |||
7115 | 7123 | ||
7116 | s2io_rem_isr(sp); | 7124 | s2io_rem_isr(sp); |
7117 | 7125 | ||
7126 | /* stop the tx queue, indicate link down */ | ||
7127 | s2io_link(sp, LINK_DOWN); | ||
7128 | |||
7118 | /* Check if the device is Quiescent and then Reset the NIC */ | 7129 | /* Check if the device is Quiescent and then Reset the NIC */ |
7119 | while(do_io) { | 7130 | while(do_io) { |
7120 | /* As per the HW requirement we need to replenish the | 7131 | /* As per the HW requirement we need to replenish the |
@@ -7247,17 +7258,19 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7247 | 7258 | ||
7248 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); | 7259 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); |
7249 | 7260 | ||
7261 | set_bit(__S2IO_STATE_CARD_UP, &sp->state); | ||
7262 | |||
7250 | /* Enable select interrupts */ | 7263 | /* Enable select interrupts */ |
7251 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7264 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7252 | if (sp->config.intr_type != INTA) | 7265 | if (sp->config.intr_type != INTA) { |
7253 | en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); | 7266 | interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR; |
7254 | else { | 7267 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); |
7268 | } else { | ||
7255 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 7269 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
7256 | interruptible |= TX_PIC_INTR; | 7270 | interruptible |= TX_PIC_INTR; |
7257 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); | 7271 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); |
7258 | } | 7272 | } |
7259 | 7273 | ||
7260 | set_bit(__S2IO_STATE_CARD_UP, &sp->state); | ||
7261 | return 0; | 7274 | return 0; |
7262 | } | 7275 | } |
7263 | 7276 | ||
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 483b17c34ae8..6722a2f7d091 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -1107,6 +1107,7 @@ static int init_shared_mem(struct s2io_nic *sp); | |||
1107 | static void free_shared_mem(struct s2io_nic *sp); | 1107 | static void free_shared_mem(struct s2io_nic *sp); |
1108 | static int init_nic(struct s2io_nic *nic); | 1108 | static int init_nic(struct s2io_nic *nic); |
1109 | static int rx_intr_handler(struct ring_info *ring_data, int budget); | 1109 | static int rx_intr_handler(struct ring_info *ring_data, int budget); |
1110 | static void s2io_txpic_intr_handle(struct s2io_nic *sp); | ||
1110 | static void tx_intr_handler(struct fifo_info *fifo_data); | 1111 | static void tx_intr_handler(struct fifo_info *fifo_data); |
1111 | static void s2io_handle_errors(void * dev_id); | 1112 | static void s2io_handle_errors(void * dev_id); |
1112 | 1113 | ||