qlcnic: Support for GBE port settings

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>
This commit is contained in:
Sony Chacko 2011-04-28 11:48:19 +00:00 коммит произвёл David S. Miller
Родитель f94bc1e702
Коммит 7e610caaa5
3 изменённых файлов: 40 добавлений и 63 удалений

Просмотреть файл

@ -36,8 +36,8 @@
#define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0 #define _QLCNIC_LINUX_MINOR 0
#define _QLCNIC_LINUX_SUBVERSION 16 #define _QLCNIC_LINUX_SUBVERSION 17
#define QLCNIC_LINUX_VERSIONID "5.0.16" #define QLCNIC_LINUX_VERSIONID "5.0.17"
#define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@ -573,8 +573,10 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029 #define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
#define QLCNIC_CDRP_CMD_CONFIG_PORT 0x0000002E
#define QLCNIC_RCODE_SUCCESS 0 #define QLCNIC_RCODE_SUCCESS 0
#define QLCNIC_RCODE_NOT_SUPPORTED 9
#define QLCNIC_RCODE_TIMEOUT 17 #define QLCNIC_RCODE_TIMEOUT 17
#define QLCNIC_DESTROY_CTX_RESET 0 #define QLCNIC_DESTROY_CTX_RESET 0
@ -1155,8 +1157,7 @@ struct qlcnic_esw_statistics {
struct __qlcnic_esw_statistics tx; struct __qlcnic_esw_statistics tx;
}; };
int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config);
int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off); 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_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);

Просмотреть файл

@ -359,33 +359,15 @@ qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
} }
int int
qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val) qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
{
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)
{ {
return qlcnic_issue_cmd(adapter, return qlcnic_issue_cmd(adapter,
adapter->ahw->pci_func, adapter->ahw->pci_func,
adapter->fw_hal_version, adapter->fw_hal_version,
reg, config,
val,
0, 0,
QLCNIC_CDRP_CMD_WRITE_PHY); 0,
QLCNIC_CDRP_CMD_CONFIG_PORT);
} }
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)

Просмотреть файл

@ -284,50 +284,44 @@ skip:
static int static int
qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{ {
u32 config = 0;
u32 ret = 0;
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
__u32 status;
if (adapter->ahw->port_type != QLCNIC_GBE)
return -EOPNOTSUPP;
/* read which mode */ /* read which mode */
if (adapter->ahw->port_type == QLCNIC_GBE) { if (ecmd->duplex)
/* autonegotiation */ config |= 0x1;
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 (qlcnic_fw_cmd_query_phy(adapter, if (ecmd->autoneg)
QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, config |= 0x2;
&status) != 0)
return -EIO;
switch (ecmd->speed) { switch (ethtool_cmd_speed(ecmd)) {
case SPEED_10: case SPEED_10:
qlcnic_set_phy_speed(status, 0); config |= (0 << 8);
break; break;
case SPEED_100: case SPEED_100:
qlcnic_set_phy_speed(status, 1); config |= (1 << 8);
break; break;
case SPEED_1000: case SPEED_1000:
qlcnic_set_phy_speed(status, 2); config |= (10 << 8);
break; break;
default:
return -EIO;
} }
if (ecmd->duplex == DUPLEX_HALF) ret = qlcnic_fw_cmd_set_port(adapter, config);
qlcnic_clear_phy_duplex(status);
if (ecmd->duplex == DUPLEX_FULL) if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
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
return -EOPNOTSUPP; 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)) if (!netif_running(dev))
return 0; return 0;