net: hns: bug fix about getting hilink status for HNS v2
authorSheng Li <lisheng011@huawei.com>
Thu, 24 Mar 2016 11:08:06 +0000 (19:08 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Mar 2016 18:33:07 +0000 (14:33 -0400)
The hilink status reg in HNS V2 is different from HNS v1. In HNS V2, It
distinguishes differnt lane status according to the bit-field of the reg.
As is shown below:
[0:0] ---> lane0
[1:1] ---> lane1
...

But the current driver reads the reg to get the hilink status ONLY
concidering HNS V1 situation. Here is a patch to support both of them.

Signed-off-by: Sheng Li <lisheng011@huawei.com>
Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h

index 607c3be4224101279d2d7f55dd13766568156d78..e69b02287c44a78fcdd960948f7f29bc96152bb3 100644 (file)
@@ -244,31 +244,35 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val)
  */
 phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
 {
-       u32 hilink3_mode;
-       u32 hilink4_mode;
+       u32 mode;
+       u32 reg;
+       u32 shift;
+       bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
        void __iomem *sys_ctl_vaddr = mac_cb->sys_ctl_vaddr;
-       int dev_id = mac_cb->mac_id;
+       int mac_id = mac_cb->mac_id;
        phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
 
-       hilink3_mode = dsaf_read_reg(sys_ctl_vaddr, HNS_MAC_HILINK3_REG);
-       hilink4_mode = dsaf_read_reg(sys_ctl_vaddr, HNS_MAC_HILINK4_REG);
-       if (dev_id >= 0 && dev_id <= 3) {
-               if (hilink4_mode == 0)
-                       phy_if = PHY_INTERFACE_MODE_SGMII;
-               else
+       if (is_ver1 && (mac_id >= 6 && mac_id <= 7)) {
+               phy_if = PHY_INTERFACE_MODE_SGMII;
+       } else if (mac_id >= 0 && mac_id <= 3) {
+               reg = is_ver1 ? HNS_MAC_HILINK4_REG : HNS_MAC_HILINK4V2_REG;
+               mode = dsaf_read_reg(sys_ctl_vaddr, reg);
+               /* mac_id 0, 1, 2, 3 ---> hilink4 lane 0, 1, 2, 3 */
+               shift = is_ver1 ? 0 : mac_id;
+               if (dsaf_get_bit(mode, shift))
                        phy_if = PHY_INTERFACE_MODE_XGMII;
-       } else if (dev_id >= 4 && dev_id <= 5) {
-               if (hilink3_mode == 0)
-                       phy_if = PHY_INTERFACE_MODE_SGMII;
                else
+                       phy_if = PHY_INTERFACE_MODE_SGMII;
+       } else if (mac_id >= 4 && mac_id <= 7) {
+               reg = is_ver1 ? HNS_MAC_HILINK3_REG : HNS_MAC_HILINK3V2_REG;
+               mode = dsaf_read_reg(sys_ctl_vaddr, reg);
+               /* mac_id 4, 5, 6, 7 ---> hilink3 lane 2, 3, 0, 1 */
+               shift = is_ver1 ? 0 : mac_id <= 5 ? mac_id - 2 : mac_id - 6;
+               if (dsaf_get_bit(mode, shift))
                        phy_if = PHY_INTERFACE_MODE_XGMII;
-       } else {
-               phy_if = PHY_INTERFACE_MODE_SGMII;
+               else
+                       phy_if = PHY_INTERFACE_MODE_SGMII;
        }
-
-       dev_dbg(mac_cb->dev,
-               "hilink3_mode=%d, hilink4_mode=%d dev_id=%d, phy_if=%d\n",
-               hilink3_mode, hilink4_mode, dev_id, phy_if);
        return phy_if;
 }
 
index bf62687e5ea74483eff1332e5187a016549659f3..e2206f938a9c788cf1ee25b668bad8a013348753 100644 (file)
 /*serdes offset**/
 #define HNS_MAC_HILINK3_REG DSAF_SUB_SC_HILINK3_CRG_CTRL0_REG
 #define HNS_MAC_HILINK4_REG DSAF_SUB_SC_HILINK4_CRG_CTRL0_REG
+#define HNS_MAC_HILINK3V2_REG DSAF_SUB_SC_HILINK3_CRG_CTRL1_REG
+#define HNS_MAC_HILINK4V2_REG DSAF_SUB_SC_HILINK4_CRG_CTRL1_REG
 #define HNS_MAC_LANE0_CTLEDFE_REG 0x000BFFCCULL
 #define HNS_MAC_LANE1_CTLEDFE_REG 0x000BFFBCULL
 #define HNS_MAC_LANE2_CTLEDFE_REG 0x000BFFACULL