cxgb3: More flexible support for PHY interrupts.
authorDivy Le Ray <divy@chelsio.com>
Thu, 9 Oct 2008 00:39:00 +0000 (17:39 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Oct 2008 00:39:00 +0000 (17:39 -0700)
Do not require PHY interrupts to be connected to GPIs in ascending order.
Base interrupt availability both on PHYs supporting them and on GPIs being
hooked up.  Allows boards to specify interrupt GPIs though the PHYs don't
use them.

Remove spurious PHY interrupts due to clearing T3DBG interrupts before
setting their polarity.

Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/cxgb3/common.h
drivers/net/cxgb3/regs.h
drivers/net/cxgb3/t3_hw.c

index e83a360bcc9e87ab4203d268fd1aebd794923f23..75b5ee61f45c6ecf4453410132059fe14cbb2659 100644 (file)
@@ -194,7 +194,7 @@ struct adapter_info {
        unsigned char nports;   /* # of ports */
        unsigned char phy_base_addr;    /* MDIO PHY base address */
        unsigned int gpio_out;  /* GPIO output settings */
-       unsigned int gpio_intr; /* GPIO IRQ enable mask */
+       unsigned char gpio_intr[MAX_NPORTS]; /* GPIO PHY IRQ pins */
        unsigned long caps;     /* adapter capabilities */
        const struct mdio_ops *mdio_ops;        /* MDIO operations */
        const char *desc;       /* product description */
@@ -517,7 +517,7 @@ enum {
        MAC_RXFIFO_SIZE = 32768
 };
 
-/* IEEE 802.3ae specified MDIO devices */
+/* IEEE 802.3 specified MDIO devices */
 enum {
        MDIO_DEV_PMA_PMD = 1,
        MDIO_DEV_WIS = 2,
index 4bda27c551c9de8485d8859db8f127f06e715e9b..a035d5c24442cf5e80dcf6d887586973618d6f2f 100644 (file)
 #define V_GPIO10(x) ((x) << S_GPIO10)
 #define F_GPIO10    V_GPIO10(1U)
 
+#define S_GPIO9    9
+#define V_GPIO9(x) ((x) << S_GPIO9)
+#define F_GPIO9    V_GPIO9(1U)
+
 #define S_GPIO7    7
 #define V_GPIO7(x) ((x) << S_GPIO7)
 #define F_GPIO7    V_GPIO7(1U)
index f7ced324227d02c839497c560a83aeb6fccca9c6..bfce761156a1c0ef0c3e38d612f4104e9049bfa7 100644 (file)
@@ -445,24 +445,22 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
 static const struct adapter_info t3_adap_info[] = {
        {2, 0,
         F_GPIO2_OEN | F_GPIO4_OEN |
-        F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
-        0,
+        F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
         &mi1_mdio_ops, "Chelsio PE9000"},
        {2, 0,
         F_GPIO2_OEN | F_GPIO4_OEN |
-        F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
-        0,
+        F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
         &mi1_mdio_ops, "Chelsio T302"},
        {1, 0,
         F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
         F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
-        0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+        { 0 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
         &mi1_mdio_ext_ops, "Chelsio T310"},
        {2, 0,
         F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
         F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
-        F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
-        SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+        F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
+        { S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
         &mi1_mdio_ext_ops, "Chelsio T320"},
 };
 
@@ -1684,19 +1682,15 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
  */
 int t3_phy_intr_handler(struct adapter *adapter)
 {
-       u32 mask, gpi = adapter_info(adapter)->gpio_intr;
        u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
 
        for_each_port(adapter, i) {
                struct port_info *p = adap2pinfo(adapter, i);
 
-               mask = gpi - (gpi & (gpi - 1));
-               gpi -= mask;
-
                if (!(p->phy.caps & SUPPORTED_IRQ))
                        continue;
 
-               if (cause & mask) {
+               if (cause & (1 << adapter_info(adapter)->gpio_intr[i])) {
                        int phy_cause = p->phy.ops->intr_handler(&p->phy);
 
                        if (phy_cause & cphy_cause_link_change)
@@ -1765,6 +1759,17 @@ int t3_slow_intr_handler(struct adapter *adapter)
        return 1;
 }
 
+static unsigned int calc_gpio_intr(struct adapter *adap)
+{
+       unsigned int i, gpi_intr = 0;
+
+       for_each_port(adap, i)
+               if ((adap2pinfo(adap, i)->phy.caps & SUPPORTED_IRQ) &&
+                   adapter_info(adap)->gpio_intr[i])
+                       gpi_intr |= 1 << adapter_info(adap)->gpio_intr[i];
+       return gpi_intr;
+}
+
 /**
  *     t3_intr_enable - enable interrupts
  *     @adapter: the adapter whose interrupts should be enabled
@@ -1807,10 +1812,8 @@ void t3_intr_enable(struct adapter *adapter)
                t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK);
        }
 
-       t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW,
-                    adapter_info(adapter)->gpio_intr);
-       t3_write_reg(adapter, A_T3DBG_INT_ENABLE,
-                    adapter_info(adapter)->gpio_intr);
+       t3_write_reg(adapter, A_T3DBG_INT_ENABLE, calc_gpio_intr(adapter));
+
        if (is_pcie(adapter))
                t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK);
        else
@@ -3331,6 +3334,8 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
        init_hw_for_avail_ports(adapter, adapter->params.nports);
        t3_sge_init(adapter, &adapter->params.sge);
 
+       t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
+
        t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params);
        t3_write_reg(adapter, A_CIM_BOOT_CFG,
                     V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));