qlcnic: Update Link speed and port type info for 83xx adapter
o Update the port type information o Advertise correct link modes and autonegotiation o Add support to change link speed Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
10c51b5623
commit
cd6e7381fb
|
@ -35,6 +35,35 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
|
|||
#define QLC_SKIP_INACTIVE_PCI_REGS 7
|
||||
#define QLC_MAX_LEGACY_FUNC_SUPP 8
|
||||
|
||||
/* 83xx Module type */
|
||||
#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM 0x1 /* 10GBase-LRM */
|
||||
#define QLC_83XX_MODULE_FIBRE_10GBASE_LR 0x2 /* 10GBase-LR */
|
||||
#define QLC_83XX_MODULE_FIBRE_10GBASE_SR 0x3 /* 10GBase-SR */
|
||||
#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP 0x4 /* 10GE passive
|
||||
* copper(compliant)
|
||||
*/
|
||||
#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP 0x5 /* 10GE active limiting
|
||||
* copper(compliant)
|
||||
*/
|
||||
#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP 0x6 /* 10GE passive copper
|
||||
* (legacy, best effort)
|
||||
*/
|
||||
#define QLC_83XX_MODULE_FIBRE_1000BASE_SX 0x7 /* 1000Base-SX */
|
||||
#define QLC_83XX_MODULE_FIBRE_1000BASE_LX 0x8 /* 1000Base-LX */
|
||||
#define QLC_83XX_MODULE_FIBRE_1000BASE_CX 0x9 /* 1000Base-CX */
|
||||
#define QLC_83XX_MODULE_TP_1000BASE_T 0xa /* 1000Base-T*/
|
||||
#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP 0xb /* 1GE passive copper
|
||||
* (legacy, best effort)
|
||||
*/
|
||||
#define QLC_83XX_MODULE_UNKNOWN 0xf /* Unknown module type */
|
||||
|
||||
/* Port types */
|
||||
#define QLC_83XX_10_CAPABLE BIT_8
|
||||
#define QLC_83XX_100_CAPABLE BIT_9
|
||||
#define QLC_83XX_1G_CAPABLE BIT_10
|
||||
#define QLC_83XX_10G_CAPABLE BIT_11
|
||||
#define QLC_83XX_AUTONEG_ENABLE BIT_15
|
||||
|
||||
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
|
||||
{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
|
||||
{QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
|
||||
|
@ -667,6 +696,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
|
|||
|
||||
int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
|
||||
{
|
||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||
int status;
|
||||
|
||||
status = qlcnic_83xx_get_port_config(adapter);
|
||||
|
@ -674,13 +704,20 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
|
|||
dev_err(&adapter->pdev->dev,
|
||||
"Get Port Info failed\n");
|
||||
} else {
|
||||
if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
|
||||
adapter->ahw->port_type = QLCNIC_XGBE;
|
||||
else
|
||||
adapter->ahw->port_type = QLCNIC_GBE;
|
||||
|
||||
if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
|
||||
adapter->ahw->link_autoneg = AUTONEG_ENABLE;
|
||||
if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
|
||||
ahw->port_type = QLCNIC_XGBE;
|
||||
} else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
|
||||
ahw->port_config & QLC_83XX_100_CAPABLE ||
|
||||
ahw->port_config & QLC_83XX_1G_CAPABLE) {
|
||||
ahw->port_type = QLCNIC_GBE;
|
||||
} else {
|
||||
ahw->port_type = QLCNIC_XGBE;
|
||||
}
|
||||
|
||||
if (QLC_83XX_AUTONEG(ahw->port_config))
|
||||
ahw->link_autoneg = AUTONEG_ENABLE;
|
||||
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -3176,22 +3213,33 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
|
|||
break;
|
||||
}
|
||||
config = cmd.rsp.arg[3];
|
||||
if (QLC_83XX_SFP_PRESENT(config)) {
|
||||
switch (ahw->module_type) {
|
||||
case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
|
||||
case LINKEVENT_MODULE_OPTICAL_SRLR:
|
||||
case LINKEVENT_MODULE_OPTICAL_LRM:
|
||||
case LINKEVENT_MODULE_OPTICAL_SFP_1G:
|
||||
ahw->supported_type = PORT_FIBRE;
|
||||
break;
|
||||
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
|
||||
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
|
||||
case LINKEVENT_MODULE_TWINAX:
|
||||
ahw->supported_type = PORT_TP;
|
||||
break;
|
||||
default:
|
||||
ahw->supported_type = PORT_OTHER;
|
||||
}
|
||||
switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
|
||||
case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
|
||||
case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
|
||||
case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
|
||||
ahw->supported_type = PORT_FIBRE;
|
||||
ahw->port_type = QLCNIC_XGBE;
|
||||
break;
|
||||
case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
|
||||
case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
|
||||
case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
|
||||
ahw->supported_type = PORT_FIBRE;
|
||||
ahw->port_type = QLCNIC_GBE;
|
||||
break;
|
||||
case QLC_83XX_MODULE_TP_1000BASE_T:
|
||||
ahw->supported_type = PORT_TP;
|
||||
ahw->port_type = QLCNIC_GBE;
|
||||
break;
|
||||
case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
|
||||
case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
|
||||
case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
|
||||
case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
|
||||
ahw->supported_type = PORT_DA;
|
||||
ahw->port_type = QLCNIC_XGBE;
|
||||
break;
|
||||
default:
|
||||
ahw->supported_type = PORT_OTHER;
|
||||
ahw->port_type = QLCNIC_XGBE;
|
||||
}
|
||||
if (config & 1)
|
||||
err = 1;
|
||||
|
@ -3204,9 +3252,9 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
|
|||
int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
|
||||
struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||
u32 config = 0;
|
||||
int status = 0;
|
||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||
|
||||
if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
|
||||
/* Get port configuration info */
|
||||
|
@ -3229,20 +3277,41 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
|
|||
ecmd->autoneg = AUTONEG_DISABLE;
|
||||
}
|
||||
|
||||
if (ahw->port_type == QLCNIC_XGBE) {
|
||||
ecmd->supported = SUPPORTED_10000baseT_Full;
|
||||
ecmd->advertising = ADVERTISED_10000baseT_Full;
|
||||
ecmd->supported = (SUPPORTED_10baseT_Full |
|
||||
SUPPORTED_100baseT_Full |
|
||||
SUPPORTED_1000baseT_Full |
|
||||
SUPPORTED_10000baseT_Full |
|
||||
SUPPORTED_Autoneg);
|
||||
|
||||
if (ecmd->autoneg == AUTONEG_ENABLE) {
|
||||
if (ahw->port_config & QLC_83XX_10_CAPABLE)
|
||||
ecmd->advertising |= SUPPORTED_10baseT_Full;
|
||||
if (ahw->port_config & QLC_83XX_100_CAPABLE)
|
||||
ecmd->advertising |= SUPPORTED_100baseT_Full;
|
||||
if (ahw->port_config & QLC_83XX_1G_CAPABLE)
|
||||
ecmd->advertising |= SUPPORTED_1000baseT_Full;
|
||||
if (ahw->port_config & QLC_83XX_10G_CAPABLE)
|
||||
ecmd->advertising |= SUPPORTED_10000baseT_Full;
|
||||
if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
|
||||
ecmd->advertising |= ADVERTISED_Autoneg;
|
||||
} else {
|
||||
ecmd->supported = (SUPPORTED_10baseT_Half |
|
||||
SUPPORTED_10baseT_Full |
|
||||
SUPPORTED_100baseT_Half |
|
||||
SUPPORTED_100baseT_Full |
|
||||
SUPPORTED_1000baseT_Half |
|
||||
SUPPORTED_1000baseT_Full);
|
||||
ecmd->advertising = (ADVERTISED_100baseT_Half |
|
||||
ADVERTISED_100baseT_Full |
|
||||
ADVERTISED_1000baseT_Half |
|
||||
ADVERTISED_1000baseT_Full);
|
||||
switch (ahw->link_speed) {
|
||||
case SPEED_10:
|
||||
ecmd->advertising = SUPPORTED_10baseT_Full;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ecmd->advertising = SUPPORTED_100baseT_Full;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ecmd->advertising = SUPPORTED_1000baseT_Full;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
ecmd->advertising = SUPPORTED_10000baseT_Full;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (ahw->supported_type) {
|
||||
|
@ -3258,6 +3327,12 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
|
|||
ecmd->port = PORT_TP;
|
||||
ecmd->transceiver = XCVR_INTERNAL;
|
||||
break;
|
||||
case PORT_DA:
|
||||
ecmd->supported |= SUPPORTED_FIBRE;
|
||||
ecmd->advertising |= ADVERTISED_FIBRE;
|
||||
ecmd->port = PORT_DA;
|
||||
ecmd->transceiver = XCVR_EXTERNAL;
|
||||
break;
|
||||
default:
|
||||
ecmd->supported |= SUPPORTED_FIBRE;
|
||||
ecmd->advertising |= ADVERTISED_FIBRE;
|
||||
|
@ -3272,35 +3347,60 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
|
|||
int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
|
||||
struct ethtool_cmd *ecmd)
|
||||
{
|
||||
int status = 0;
|
||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||
u32 config = adapter->ahw->port_config;
|
||||
int status = 0;
|
||||
|
||||
if (ecmd->autoneg)
|
||||
adapter->ahw->port_config |= BIT_15;
|
||||
|
||||
switch (ethtool_cmd_speed(ecmd)) {
|
||||
case SPEED_10:
|
||||
adapter->ahw->port_config |= BIT_8;
|
||||
break;
|
||||
case SPEED_100:
|
||||
adapter->ahw->port_config |= BIT_9;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
adapter->ahw->port_config |= BIT_10;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
adapter->ahw->port_config |= BIT_11;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
/* 83xx devices do not support Half duplex */
|
||||
if (ecmd->duplex == DUPLEX_HALF) {
|
||||
netdev_info(adapter->netdev,
|
||||
"Half duplex mode not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ecmd->autoneg) {
|
||||
ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
|
||||
ahw->port_config |= (QLC_83XX_100_CAPABLE |
|
||||
QLC_83XX_1G_CAPABLE |
|
||||
QLC_83XX_10G_CAPABLE);
|
||||
} else { /* force speed */
|
||||
ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
|
||||
switch (ethtool_cmd_speed(ecmd)) {
|
||||
case SPEED_10:
|
||||
ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
|
||||
QLC_83XX_1G_CAPABLE |
|
||||
QLC_83XX_10G_CAPABLE);
|
||||
ahw->port_config |= QLC_83XX_10_CAPABLE;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
|
||||
QLC_83XX_1G_CAPABLE |
|
||||
QLC_83XX_10G_CAPABLE);
|
||||
ahw->port_config |= QLC_83XX_100_CAPABLE;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
|
||||
QLC_83XX_100_CAPABLE |
|
||||
QLC_83XX_10G_CAPABLE);
|
||||
ahw->port_config |= QLC_83XX_1G_CAPABLE;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
|
||||
QLC_83XX_100_CAPABLE |
|
||||
QLC_83XX_1G_CAPABLE);
|
||||
ahw->port_config |= QLC_83XX_10G_CAPABLE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
status = qlcnic_83xx_set_port_config(adapter);
|
||||
if (status) {
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Failed to Set Link Speed and autoneg.\n");
|
||||
adapter->ahw->port_config = config;
|
||||
netdev_info(adapter->netdev,
|
||||
"Failed to Set Link Speed and autoneg.\n");
|
||||
ahw->port_config = config;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -360,7 +360,6 @@ enum qlcnic_83xx_states {
|
|||
#define QLC_83XX_SFP_MODULE_TYPE(data) (((data) >> 4) & 0x1F)
|
||||
#define QLC_83XX_SFP_CU_LENGTH(data) (LSB((data) >> 16))
|
||||
#define QLC_83XX_SFP_TX_FAULT(data) ((data) & BIT_10)
|
||||
#define QLC_83XX_SFP_10G_CAPABLE(data) ((data) & BIT_11)
|
||||
#define QLC_83XX_LINK_STATS(data) ((data) & BIT_0)
|
||||
#define QLC_83XX_CURRENT_LINK_SPEED(data) (((data) >> 3) & 7)
|
||||
#define QLC_83XX_LINK_PAUSE(data) (((data) >> 6) & 3)
|
||||
|
|
Loading…
Reference in New Issue