diff options
author | raghavendra.koushik@neterion.com <raghavendra.koushik@neterion.com> | 2005-08-03 15:38:59 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-11 00:10:45 -0400 |
commit | a371a07de9bce837ea4e84569a2b390a42e360ef (patch) | |
tree | d8b8f2f18d6a1ff620e53363f22288321730ddb1 | |
parent | b6e3f9828b9dc188cfe80364365cc68bf45df949 (diff) |
[PATCH] S2io: New link handling scheme for Xframe II
Hi,
The below patch implements a new "Link state change handling"
scheme supported by the Xframe II adapter. It also bumps up the
driver version to 2.0.2.0.
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/net/s2io-regs.h | 8 | ||||
-rw-r--r-- | drivers/net/s2io.c | 147 |
2 files changed, 121 insertions, 34 deletions
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 159d87648f64..2234a8f05eb2 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -167,7 +167,11 @@ typedef struct _XENA_dev_config { | |||
167 | u8 unused4[0x08]; | 167 | u8 unused4[0x08]; |
168 | 168 | ||
169 | u64 gpio_int_reg; | 169 | u64 gpio_int_reg; |
170 | #define GPIO_INT_REG_LINK_DOWN BIT(1) | ||
171 | #define GPIO_INT_REG_LINK_UP BIT(2) | ||
170 | u64 gpio_int_mask; | 172 | u64 gpio_int_mask; |
173 | #define GPIO_INT_MASK_LINK_DOWN BIT(1) | ||
174 | #define GPIO_INT_MASK_LINK_UP BIT(2) | ||
171 | u64 gpio_alarms; | 175 | u64 gpio_alarms; |
172 | 176 | ||
173 | u8 unused5[0x38]; | 177 | u8 unused5[0x38]; |
@@ -279,8 +283,10 @@ typedef struct _XENA_dev_config { | |||
279 | 283 | ||
280 | u64 gpio_control; | 284 | u64 gpio_control; |
281 | #define GPIO_CTRL_GPIO_0 BIT(8) | 285 | #define GPIO_CTRL_GPIO_0 BIT(8) |
286 | u64 misc_control; | ||
287 | #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) | ||
282 | 288 | ||
283 | u8 unused7_1[0x240 - 0x200]; | 289 | u8 unused7_1[0x240 - 0x208]; |
284 | 290 | ||
285 | u64 wreq_split_mask; | 291 | u64 wreq_split_mask; |
286 | #define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12) | 292 | #define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12) |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index f430ffe7d6f8..e7c428561e3f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -67,7 +67,7 @@ | |||
67 | 67 | ||
68 | /* S2io Driver name & version. */ | 68 | /* S2io Driver name & version. */ |
69 | static char s2io_driver_name[] = "Neterion"; | 69 | static char s2io_driver_name[] = "Neterion"; |
70 | static char s2io_driver_version[] = "Version 1.7.7"; | 70 | static char s2io_driver_version[] = "Version 2.0.2.0"; |
71 | 71 | ||
72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) | 72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) |
73 | { | 73 | { |
@@ -1456,8 +1456,28 @@ static int init_nic(struct s2io_nic *nic) | |||
1456 | writeq(val64, &bar0->wreq_split_mask); | 1456 | writeq(val64, &bar0->wreq_split_mask); |
1457 | } | 1457 | } |
1458 | 1458 | ||
1459 | /* Setting Link stability period to 64 ms */ | ||
1460 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1461 | val64 = MISC_LINK_STABILITY_PRD(3); | ||
1462 | writeq(val64, &bar0->misc_control); | ||
1463 | } | ||
1464 | |||
1459 | return SUCCESS; | 1465 | return SUCCESS; |
1460 | } | 1466 | } |
1467 | #define LINK_UP_DOWN_INTERRUPT 1 | ||
1468 | #define MAC_RMAC_ERR_TIMER 2 | ||
1469 | |||
1470 | #if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE) | ||
1471 | #define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER | ||
1472 | #else | ||
1473 | int s2io_link_fault_indication(nic_t *nic) | ||
1474 | { | ||
1475 | if (nic->device_type == XFRAME_II_DEVICE) | ||
1476 | return LINK_UP_DOWN_INTERRUPT; | ||
1477 | else | ||
1478 | return MAC_RMAC_ERR_TIMER; | ||
1479 | } | ||
1480 | #endif | ||
1461 | 1481 | ||
1462 | /** | 1482 | /** |
1463 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | 1483 | * en_dis_able_nic_intrs - Enable or Disable the interrupts |
@@ -1485,11 +1505,22 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1485 | temp64 &= ~((u64) val64); | 1505 | temp64 &= ~((u64) val64); |
1486 | writeq(temp64, &bar0->general_int_mask); | 1506 | writeq(temp64, &bar0->general_int_mask); |
1487 | /* | 1507 | /* |
1488 | * Disabled all PCIX, Flash, MDIO, IIC and GPIO | 1508 | * If Hercules adapter enable GPIO otherwise |
1509 | * disabled all PCIX, Flash, MDIO, IIC and GPIO | ||
1489 | * interrupts for now. | 1510 | * interrupts for now. |
1490 | * TODO | 1511 | * TODO |
1491 | */ | 1512 | */ |
1492 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | 1513 | if (s2io_link_fault_indication(nic) == |
1514 | LINK_UP_DOWN_INTERRUPT ) { | ||
1515 | temp64 = readq(&bar0->pic_int_mask); | ||
1516 | temp64 &= ~((u64) PIC_INT_GPIO); | ||
1517 | writeq(temp64, &bar0->pic_int_mask); | ||
1518 | temp64 = readq(&bar0->gpio_int_mask); | ||
1519 | temp64 &= ~((u64) GPIO_INT_MASK_LINK_UP); | ||
1520 | writeq(temp64, &bar0->gpio_int_mask); | ||
1521 | } else { | ||
1522 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | ||
1523 | } | ||
1493 | /* | 1524 | /* |
1494 | * No MSI Support is available presently, so TTI and | 1525 | * No MSI Support is available presently, so TTI and |
1495 | * RTI interrupts are also disabled. | 1526 | * RTI interrupts are also disabled. |
@@ -1580,17 +1611,8 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1580 | writeq(temp64, &bar0->general_int_mask); | 1611 | writeq(temp64, &bar0->general_int_mask); |
1581 | /* | 1612 | /* |
1582 | * All MAC block error interrupts are disabled for now | 1613 | * All MAC block error interrupts are disabled for now |
1583 | * except the link status change interrupt. | ||
1584 | * TODO | 1614 | * TODO |
1585 | */ | 1615 | */ |
1586 | val64 = MAC_INT_STATUS_RMAC_INT; | ||
1587 | temp64 = readq(&bar0->mac_int_mask); | ||
1588 | temp64 &= ~((u64) val64); | ||
1589 | writeq(temp64, &bar0->mac_int_mask); | ||
1590 | |||
1591 | val64 = readq(&bar0->mac_rmac_err_mask); | ||
1592 | val64 &= ~((u64) RMAC_LINK_STATE_CHANGE_INT); | ||
1593 | writeq(val64, &bar0->mac_rmac_err_mask); | ||
1594 | } else if (flag == DISABLE_INTRS) { | 1616 | } else if (flag == DISABLE_INTRS) { |
1595 | /* | 1617 | /* |
1596 | * Disable MAC Intrs in the general intr mask register | 1618 | * Disable MAC Intrs in the general intr mask register |
@@ -1879,8 +1901,10 @@ static int start_nic(struct s2io_nic *nic) | |||
1879 | } | 1901 | } |
1880 | 1902 | ||
1881 | /* Enable select interrupts */ | 1903 | /* Enable select interrupts */ |
1882 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 1904 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | MC_INTR; |
1883 | RX_MAC_INTR | MC_INTR; | 1905 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
1906 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1907 | |||
1884 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | 1908 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); |
1885 | 1909 | ||
1886 | /* | 1910 | /* |
@@ -2004,8 +2028,9 @@ static void stop_nic(struct s2io_nic *nic) | |||
2004 | config = &nic->config; | 2028 | config = &nic->config; |
2005 | 2029 | ||
2006 | /* Disable all interrupts */ | 2030 | /* Disable all interrupts */ |
2007 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 2031 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | MC_INTR; |
2008 | RX_MAC_INTR | MC_INTR; | 2032 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
2033 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
2009 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); | 2034 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); |
2010 | 2035 | ||
2011 | /* Disable PRCs */ | 2036 | /* Disable PRCs */ |
@@ -2618,10 +2643,12 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2618 | register u64 val64 = 0, err_reg = 0; | 2643 | register u64 val64 = 0, err_reg = 0; |
2619 | 2644 | ||
2620 | /* Handling link status change error Intr */ | 2645 | /* Handling link status change error Intr */ |
2621 | err_reg = readq(&bar0->mac_rmac_err_reg); | 2646 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
2622 | writeq(err_reg, &bar0->mac_rmac_err_reg); | 2647 | err_reg = readq(&bar0->mac_rmac_err_reg); |
2623 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { | 2648 | writeq(err_reg, &bar0->mac_rmac_err_reg); |
2624 | schedule_work(&nic->set_link_task); | 2649 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { |
2650 | schedule_work(&nic->set_link_task); | ||
2651 | } | ||
2625 | } | 2652 | } |
2626 | 2653 | ||
2627 | /* Handling Ecc errors */ | 2654 | /* Handling Ecc errors */ |
@@ -2947,7 +2974,7 @@ int s2io_open(struct net_device *dev) | |||
2947 | * Nic is initialized | 2974 | * Nic is initialized |
2948 | */ | 2975 | */ |
2949 | netif_carrier_off(dev); | 2976 | netif_carrier_off(dev); |
2950 | sp->last_link_state = 0; /* Unkown link state */ | 2977 | sp->last_link_state = LINK_DOWN; |
2951 | 2978 | ||
2952 | /* Initialize H/W and enable interrupts */ | 2979 | /* Initialize H/W and enable interrupts */ |
2953 | if (s2io_card_up(sp)) { | 2980 | if (s2io_card_up(sp)) { |
@@ -3159,6 +3186,53 @@ s2io_alarm_handle(unsigned long data) | |||
3159 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 3186 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
3160 | } | 3187 | } |
3161 | 3188 | ||
3189 | static void s2io_txpic_intr_handle(nic_t *sp) | ||
3190 | { | ||
3191 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; | ||
3192 | u64 val64; | ||
3193 | |||
3194 | val64 = readq(&bar0->pic_int_status); | ||
3195 | if (val64 & PIC_INT_GPIO) { | ||
3196 | val64 = readq(&bar0->gpio_int_reg); | ||
3197 | if ((val64 & GPIO_INT_REG_LINK_DOWN) && | ||
3198 | (val64 & GPIO_INT_REG_LINK_UP)) { | ||
3199 | val64 |= GPIO_INT_REG_LINK_DOWN; | ||
3200 | val64 |= GPIO_INT_REG_LINK_UP; | ||
3201 | writeq(val64, &bar0->gpio_int_reg); | ||
3202 | goto masking; | ||
3203 | } | ||
3204 | |||
3205 | if (((sp->last_link_state == LINK_UP) && | ||
3206 | (val64 & GPIO_INT_REG_LINK_DOWN)) || | ||
3207 | ((sp->last_link_state == LINK_DOWN) && | ||
3208 | (val64 & GPIO_INT_REG_LINK_UP))) { | ||
3209 | val64 = readq(&bar0->gpio_int_mask); | ||
3210 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3211 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3212 | writeq(val64, &bar0->gpio_int_mask); | ||
3213 | s2io_set_link((unsigned long)sp); | ||
3214 | } | ||
3215 | masking: | ||
3216 | if (sp->last_link_state == LINK_UP) { | ||
3217 | /*enable down interrupt */ | ||
3218 | val64 = readq(&bar0->gpio_int_mask); | ||
3219 | /* unmasks link down intr */ | ||
3220 | val64 &= ~GPIO_INT_MASK_LINK_DOWN; | ||
3221 | /* masks link up intr */ | ||
3222 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3223 | writeq(val64, &bar0->gpio_int_mask); | ||
3224 | } else { | ||
3225 | /*enable UP Interrupt */ | ||
3226 | val64 = readq(&bar0->gpio_int_mask); | ||
3227 | /* unmasks link up interrupt */ | ||
3228 | val64 &= ~GPIO_INT_MASK_LINK_UP; | ||
3229 | /* masks link down interrupt */ | ||
3230 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3231 | writeq(val64, &bar0->gpio_int_mask); | ||
3232 | } | ||
3233 | } | ||
3234 | } | ||
3235 | |||
3162 | /** | 3236 | /** |
3163 | * s2io_isr - ISR handler of the device . | 3237 | * s2io_isr - ISR handler of the device . |
3164 | * @irq: the irq of the device. | 3238 | * @irq: the irq of the device. |
@@ -3241,6 +3315,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
3241 | tx_intr_handler(&mac_control->fifos[i]); | 3315 | tx_intr_handler(&mac_control->fifos[i]); |
3242 | } | 3316 | } |
3243 | 3317 | ||
3318 | if (reason & GEN_INTR_TXPIC) | ||
3319 | s2io_txpic_intr_handle(sp); | ||
3244 | /* | 3320 | /* |
3245 | * If the Rx buffer count is below the panic threshold then | 3321 | * If the Rx buffer count is below the panic threshold then |
3246 | * reallocate the buffers from the interrupt handler itself, | 3322 | * reallocate the buffers from the interrupt handler itself, |
@@ -4644,11 +4720,13 @@ static void s2io_set_link(unsigned long data) | |||
4644 | } | 4720 | } |
4645 | 4721 | ||
4646 | subid = nic->pdev->subsystem_device; | 4722 | subid = nic->pdev->subsystem_device; |
4647 | /* | 4723 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
4648 | * Allow a small delay for the NICs self initiated | 4724 | /* |
4649 | * cleanup to complete. | 4725 | * Allow a small delay for the NICs self initiated |
4650 | */ | 4726 | * cleanup to complete. |
4651 | msleep(100); | 4727 | */ |
4728 | msleep(100); | ||
4729 | } | ||
4652 | 4730 | ||
4653 | val64 = readq(&bar0->adapter_status); | 4731 | val64 = readq(&bar0->adapter_status); |
4654 | if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { | 4732 | if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { |
@@ -4666,13 +4744,16 @@ static void s2io_set_link(unsigned long data) | |||
4666 | val64 |= ADAPTER_LED_ON; | 4744 | val64 |= ADAPTER_LED_ON; |
4667 | writeq(val64, &bar0->adapter_control); | 4745 | writeq(val64, &bar0->adapter_control); |
4668 | } | 4746 | } |
4669 | val64 = readq(&bar0->adapter_status); | 4747 | if (s2io_link_fault_indication(nic) == |
4670 | if (!LINK_IS_UP(val64)) { | 4748 | MAC_RMAC_ERR_TIMER) { |
4671 | DBG_PRINT(ERR_DBG, "%s:", dev->name); | 4749 | val64 = readq(&bar0->adapter_status); |
4672 | DBG_PRINT(ERR_DBG, " Link down"); | 4750 | if (!LINK_IS_UP(val64)) { |
4673 | DBG_PRINT(ERR_DBG, "after "); | 4751 | DBG_PRINT(ERR_DBG, "%s:", dev->name); |
4674 | DBG_PRINT(ERR_DBG, "enabling "); | 4752 | DBG_PRINT(ERR_DBG, " Link down"); |
4675 | DBG_PRINT(ERR_DBG, "device \n"); | 4753 | DBG_PRINT(ERR_DBG, "after "); |
4754 | DBG_PRINT(ERR_DBG, "enabling "); | ||
4755 | DBG_PRINT(ERR_DBG, "device \n"); | ||
4756 | } | ||
4676 | } | 4757 | } |
4677 | if (nic->device_enabled_once == FALSE) { | 4758 | if (nic->device_enabled_once == FALSE) { |
4678 | nic->device_enabled_once = TRUE; | 4759 | nic->device_enabled_once = TRUE; |