Enable setting speed and auto negotiation parameters for GbE ports.
Hardware do not support half duplex setting currently.
o Update driver version to 5.0.17.
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 16
-#define QLCNIC_LINUX_VERSIONID "5.0.16"
+#define _QLCNIC_LINUX_SUBVERSION 17
+#define QLCNIC_LINUX_VERSIONID "5.0.17"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
+#define QLCNIC_CDRP_CMD_CONFIG_PORT 0x0000002E
#define QLCNIC_RCODE_SUCCESS 0
+#define QLCNIC_RCODE_NOT_SUPPORTED 9
#define QLCNIC_RCODE_TIMEOUT 17
#define QLCNIC_DESTROY_CTX_RESET 0
struct __qlcnic_esw_statistics tx;
};
-int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
-int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
+int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config);
u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off);
int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);
}
int
-qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
-{
-
- if (qlcnic_issue_cmd(adapter,
- adapter->ahw->pci_func,
- adapter->fw_hal_version,
- reg,
- 0,
- 0,
- QLCNIC_CDRP_CMD_READ_PHY)) {
-
- return -EIO;
- }
-
- return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
-}
-
-int
-qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val)
+qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
{
return qlcnic_issue_cmd(adapter,
adapter->ahw->pci_func,
adapter->fw_hal_version,
- reg,
- val,
+ config,
+ 0,
0,
- QLCNIC_CDRP_CMD_WRITE_PHY);
+ QLCNIC_CDRP_CMD_CONFIG_PORT);
}
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
static int
qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
+ u32 config = 0;
+ u32 ret = 0;
struct qlcnic_adapter *adapter = netdev_priv(dev);
- __u32 status;
+
+ if (adapter->ahw->port_type != QLCNIC_GBE)
+ return -EOPNOTSUPP;
/* read which mode */
- if (adapter->ahw->port_type == QLCNIC_GBE) {
- /* autonegotiation */
- if (qlcnic_fw_cmd_set_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
- ecmd->autoneg) != 0)
- return -EIO;
- else
- adapter->link_autoneg = ecmd->autoneg;
+ if (ecmd->duplex)
+ config |= 0x1;
- if (qlcnic_fw_cmd_query_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) != 0)
- return -EIO;
+ if (ecmd->autoneg)
+ config |= 0x2;
- switch (ecmd->speed) {
- case SPEED_10:
- qlcnic_set_phy_speed(status, 0);
- break;
- case SPEED_100:
- qlcnic_set_phy_speed(status, 1);
- break;
- case SPEED_1000:
- qlcnic_set_phy_speed(status, 2);
- break;
- }
+ switch (ethtool_cmd_speed(ecmd)) {
+ case SPEED_10:
+ config |= (0 << 8);
+ break;
+ case SPEED_100:
+ config |= (1 << 8);
+ break;
+ case SPEED_1000:
+ config |= (10 << 8);
+ break;
+ default:
+ return -EIO;
+ }
- if (ecmd->duplex == DUPLEX_HALF)
- qlcnic_clear_phy_duplex(status);
- if (ecmd->duplex == DUPLEX_FULL)
- qlcnic_set_phy_duplex(status);
- if (qlcnic_fw_cmd_set_phy(adapter,
- QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- *((int *)&status)) != 0)
- return -EIO;
- else {
- adapter->link_speed = ecmd->speed;
- adapter->link_duplex = ecmd->duplex;
- }
- } else
+ ret = qlcnic_fw_cmd_set_port(adapter, config);
+
+ if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
return -EOPNOTSUPP;
+ else if (ret)
+ return -EIO;
+
+ adapter->link_speed = ethtool_cmd_speed(ecmd);
+ adapter->link_duplex = ecmd->duplex;
+ adapter->link_autoneg = ecmd->autoneg;
if (!netif_running(dev))
return 0;