qlcnic: Fix link configuration with autoneg disabled
authorChopra, Manish <Manish.Chopra@cavium.com>
Thu, 11 May 2017 14:12:47 +0000 (07:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 12 May 2017 01:39:53 +0000 (21:39 -0400)
Currently driver returns error on speed configurations
for 83xx adapter's non XGBE ports, due to this link doesn't
come up on the ports using 1000Base-T as a connector with
autoneg disabled. This patch fixes this with initializing
appropriate port type based on queried module/connector
types from hardware before any speed/autoneg configuration.

Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c

index 718bf58a7da66284e121f3aab8e79de7a6221c67..4fb68797630e9531e7ffc4e7bc7c015313a44063 100644 (file)
@@ -3168,6 +3168,40 @@ int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
        return 0;
 }
 
+void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+       struct qlcnic_cmd_args cmd;
+       u32 config;
+       int err;
+
+       err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
+       if (err)
+               return;
+
+       err = qlcnic_issue_cmd(adapter, &cmd);
+       if (err) {
+               dev_info(&adapter->pdev->dev,
+                        "Get Link Status Command failed: 0x%x\n", err);
+               goto out;
+       } else {
+               config = cmd.rsp.arg[3];
+
+               switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
+               case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
+               case QLC_83XX_MODULE_TP_1000BASE_T:
+                       ahw->port_type = QLCNIC_GBE;
+                       break;
+               default:
+                       ahw->port_type = QLCNIC_XGBE;
+               }
+       }
+out:
+       qlcnic_free_mbx_args(&cmd);
+}
+
 int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
 {
        u8 pci_func;
index 3dfe8e27b51c68de0af32af949b096d247e3ccb0..b75a812468569de7728fd9c654b6f1c7e353729f 100644 (file)
@@ -637,6 +637,7 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *,
 int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *,
                               struct ethtool_pauseparam *);
 int qlcnic_83xx_test_link(struct qlcnic_adapter *);
+void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter);
 int qlcnic_83xx_reg_test(struct qlcnic_adapter *);
 int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *);
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *);
index 9a869c15d8bfbfc64b48a831a2b4eb7b38160714..7f7deeaf1cf07913454a13b4f7801c7b3b07545f 100644 (file)
@@ -486,6 +486,9 @@ static int qlcnic_set_link_ksettings(struct net_device *dev,
        u32 ret = 0;
        struct qlcnic_adapter *adapter = netdev_priv(dev);
 
+       if (qlcnic_83xx_check(adapter))
+               qlcnic_83xx_get_port_type(adapter);
+
        if (adapter->ahw->port_type != QLCNIC_GBE)
                return -EOPNOTSUPP;