Commit c3168cab authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller

cxgb4/cxgbvf: Handle 32-bit fw port capabilities

Implement new 32-bit Firmware Port Capabilities in order to
handle new speeds which couldn't be represented in the old 16-bit
Firmware Port Capabilities values.

Based on the original work of Casey Leedom <leedom@chelsio.com>
Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 274043c6
...@@ -104,13 +104,13 @@ enum dev_state { ...@@ -104,13 +104,13 @@ enum dev_state {
DEV_STATE_ERR DEV_STATE_ERR
}; };
enum { enum cc_pause {
PAUSE_RX = 1 << 0, PAUSE_RX = 1 << 0,
PAUSE_TX = 1 << 1, PAUSE_TX = 1 << 1,
PAUSE_AUTONEG = 1 << 2 PAUSE_AUTONEG = 1 << 2
}; };
enum { enum cc_fec {
FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */ FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
FEC_RS = 1 << 1, /* Reed-Solomon */ FEC_RS = 1 << 1, /* Reed-Solomon */
FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */ FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */
...@@ -366,6 +366,7 @@ struct adapter_params { ...@@ -366,6 +366,7 @@ struct adapter_params {
unsigned int max_ordird_qp; /* Max read depth per RDMA QP */ unsigned int max_ordird_qp; /* Max read depth per RDMA QP */
unsigned int max_ird_adapter; /* Max read depth per adapter */ unsigned int max_ird_adapter; /* Max read depth per adapter */
bool fr_nsmr_tpte_wr_support; /* FW support for FR_NSMR_TPTE_WR */ bool fr_nsmr_tpte_wr_support; /* FW support for FR_NSMR_TPTE_WR */
u8 fw_caps_support; /* 32-bit Port Capabilities */
/* MPS Buffer Group Map[per Port]. Bit i is set if buffer group i is /* MPS Buffer Group Map[per Port]. Bit i is set if buffer group i is
* used by the Port * used by the Port
...@@ -439,18 +440,34 @@ struct trace_params { ...@@ -439,18 +440,34 @@ struct trace_params {
unsigned char port; unsigned char port;
}; };
/* Firmware Port Capabilities types. */
typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
enum fw_caps {
FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */
FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */
FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */
};
struct link_config { struct link_config {
unsigned short supported; /* link capabilities */ fw_port_cap32_t pcaps; /* link capabilities */
unsigned short advertising; /* advertised capabilities */ fw_port_cap32_t def_acaps; /* default advertised capabilities */
unsigned short lp_advertising; /* peer advertised capabilities */ fw_port_cap32_t acaps; /* advertised capabilities */
unsigned int requested_speed; /* speed user has requested */ fw_port_cap32_t lpacaps; /* peer advertised capabilities */
unsigned int speed; /* actual link speed */
unsigned char requested_fc; /* flow control user has requested */ fw_port_cap32_t speed_caps; /* speed(s) user has requested */
unsigned char fc; /* actual link flow control */ unsigned int speed; /* actual link speed (Mb/s) */
unsigned char auto_fec; /* Forward Error Correction: */
unsigned char requested_fec; /* "automatic" (IEEE 802.3), */ enum cc_pause requested_fc; /* flow control user has requested */
unsigned char fec; /* requested, and actual in use */ enum cc_pause fc; /* actual link flow control */
enum cc_fec requested_fec; /* Forward Error Correction: */
enum cc_fec fec; /* requested and actual in use */
unsigned char autoneg; /* autonegotiating? */ unsigned char autoneg; /* autonegotiating? */
unsigned char link_ok; /* link up? */ unsigned char link_ok; /* link up? */
unsigned char link_down_rc; /* link down reason */ unsigned char link_down_rc; /* link down reason */
}; };
...@@ -1580,6 +1597,8 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, ...@@ -1580,6 +1597,8 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox); int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox);
void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl); void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl);
int t4_update_port_info(struct port_info *pi); int t4_update_port_info(struct port_info *pi);
int t4_get_link_params(struct port_info *pi, unsigned int *link_okp,
unsigned int *speedp, unsigned int *mtup);
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter); void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter); void t4_db_dropped(struct adapter *adapter);
......
...@@ -533,17 +533,23 @@ static int from_fw_port_mod_type(enum fw_port_type port_type, ...@@ -533,17 +533,23 @@ static int from_fw_port_mod_type(enum fw_port_type port_type,
static unsigned int speed_to_fw_caps(int speed) static unsigned int speed_to_fw_caps(int speed)
{ {
if (speed == 100) if (speed == 100)
return FW_PORT_CAP_SPEED_100M; return FW_PORT_CAP32_SPEED_100M;
if (speed == 1000) if (speed == 1000)
return FW_PORT_CAP_SPEED_1G; return FW_PORT_CAP32_SPEED_1G;
if (speed == 10000) if (speed == 10000)
return FW_PORT_CAP_SPEED_10G; return FW_PORT_CAP32_SPEED_10G;
if (speed == 25000) if (speed == 25000)
return FW_PORT_CAP_SPEED_25G; return FW_PORT_CAP32_SPEED_25G;
if (speed == 40000) if (speed == 40000)
return FW_PORT_CAP_SPEED_40G; return FW_PORT_CAP32_SPEED_40G;
if (speed == 50000)
return FW_PORT_CAP32_SPEED_50G;
if (speed == 100000) if (speed == 100000)
return FW_PORT_CAP_SPEED_100G; return FW_PORT_CAP32_SPEED_100G;
if (speed == 200000)
return FW_PORT_CAP32_SPEED_200G;
if (speed == 400000)
return FW_PORT_CAP32_SPEED_400G;
return 0; return 0;
} }
...@@ -560,12 +566,13 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -560,12 +566,13 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
unsigned int fw_caps, unsigned int fw_caps,
unsigned long *link_mode_mask) unsigned long *link_mode_mask)
{ {
#define SET_LMM(__lmm_name) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name \ #define SET_LMM(__lmm_name) \
## _BIT, link_mode_mask) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
link_mode_mask)
#define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \ #define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \
do { \ do { \
if (fw_caps & FW_PORT_CAP_ ## __fw_name) \ if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
SET_LMM(__lmm_name); \ SET_LMM(__lmm_name); \
} while (0) } while (0)
...@@ -645,7 +652,10 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -645,7 +652,10 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
case FW_PORT_TYPE_KR4_100G: case FW_PORT_TYPE_KR4_100G:
case FW_PORT_TYPE_CR4_QSFP: case FW_PORT_TYPE_CR4_QSFP:
SET_LMM(FIBRE); SET_LMM(FIBRE);
SET_LMM(100000baseCR4_Full); FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full);
FW_CAPS_TO_LMM(SPEED_100G, 100000baseCR4_Full);
break; break;
default: default:
...@@ -663,8 +673,7 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -663,8 +673,7 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
/** /**
* lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware * lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware
* capabilities * capabilities
* * @et_lmm: ethtool Link Mode Mask
* @link_mode_mask: ethtool Link Mode Mask
* *
* Translate ethtool Link Mode Mask into a Firmware Port capabilities * Translate ethtool Link Mode Mask into a Firmware Port capabilities
* value. * value.
...@@ -677,7 +686,7 @@ static unsigned int lmm_to_fw_caps(const unsigned long *link_mode_mask) ...@@ -677,7 +686,7 @@ static unsigned int lmm_to_fw_caps(const unsigned long *link_mode_mask)
do { \ do { \
if (test_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \ if (test_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
link_mode_mask)) \ link_mode_mask)) \
fw_caps |= FW_PORT_CAP_ ## __fw_name; \ fw_caps |= FW_PORT_CAP32_ ## __fw_name; \
} while (0) } while (0)
LMM_TO_FW_CAPS(100baseT_Full, SPEED_100M); LMM_TO_FW_CAPS(100baseT_Full, SPEED_100M);
...@@ -685,6 +694,7 @@ static unsigned int lmm_to_fw_caps(const unsigned long *link_mode_mask) ...@@ -685,6 +694,7 @@ static unsigned int lmm_to_fw_caps(const unsigned long *link_mode_mask)
LMM_TO_FW_CAPS(10000baseT_Full, SPEED_10G); LMM_TO_FW_CAPS(10000baseT_Full, SPEED_10G);
LMM_TO_FW_CAPS(40000baseSR4_Full, SPEED_40G); LMM_TO_FW_CAPS(40000baseSR4_Full, SPEED_40G);
LMM_TO_FW_CAPS(25000baseCR_Full, SPEED_25G); LMM_TO_FW_CAPS(25000baseCR_Full, SPEED_25G);
LMM_TO_FW_CAPS(50000baseCR2_Full, SPEED_50G);
LMM_TO_FW_CAPS(100000baseCR4_Full, SPEED_100G); LMM_TO_FW_CAPS(100000baseCR4_Full, SPEED_100G);
#undef LMM_TO_FW_CAPS #undef LMM_TO_FW_CAPS
...@@ -698,10 +708,6 @@ static int get_link_ksettings(struct net_device *dev, ...@@ -698,10 +708,6 @@ static int get_link_ksettings(struct net_device *dev,
struct port_info *pi = netdev_priv(dev); struct port_info *pi = netdev_priv(dev);
struct ethtool_link_settings *base = &link_ksettings->base; struct ethtool_link_settings *base = &link_ksettings->base;
ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
/* For the nonce, the Firmware doesn't send up Port State changes /* For the nonce, the Firmware doesn't send up Port State changes
* when the Virtual Interface attached to the Port is down. So * when the Virtual Interface attached to the Port is down. So
* if it's down, let's grab any changes. * if it's down, let's grab any changes.
...@@ -709,6 +715,10 @@ static int get_link_ksettings(struct net_device *dev, ...@@ -709,6 +715,10 @@ static int get_link_ksettings(struct net_device *dev,
if (!netif_running(dev)) if (!netif_running(dev))
(void)t4_update_port_info(pi); (void)t4_update_port_info(pi);
ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
base->port = from_fw_port_mod_type(pi->port_type, pi->mod_type); base->port = from_fw_port_mod_type(pi->port_type, pi->mod_type);
if (pi->mdio_addr >= 0) { if (pi->mdio_addr >= 0) {
...@@ -721,11 +731,11 @@ static int get_link_ksettings(struct net_device *dev, ...@@ -721,11 +731,11 @@ static int get_link_ksettings(struct net_device *dev,
base->mdio_support = 0; base->mdio_support = 0;
} }
fw_caps_to_lmm(pi->port_type, pi->link_cfg.supported, fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
link_ksettings->link_modes.supported); link_ksettings->link_modes.supported);
fw_caps_to_lmm(pi->port_type, pi->link_cfg.advertising, fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
link_ksettings->link_modes.advertising); link_ksettings->link_modes.advertising);
fw_caps_to_lmm(pi->port_type, pi->link_cfg.lp_advertising, fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
link_ksettings->link_modes.lp_advertising); link_ksettings->link_modes.lp_advertising);
if (netif_carrier_ok(dev)) { if (netif_carrier_ok(dev)) {
...@@ -736,8 +746,24 @@ static int get_link_ksettings(struct net_device *dev, ...@@ -736,8 +746,24 @@ static int get_link_ksettings(struct net_device *dev,
base->duplex = DUPLEX_UNKNOWN; base->duplex = DUPLEX_UNKNOWN;
} }
if (pi->link_cfg.fc & PAUSE_RX) {
if (pi->link_cfg.fc & PAUSE_TX) {
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising,
Pause);
} else {
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising,
Asym_Pause);
}
} else if (pi->link_cfg.fc & PAUSE_TX) {
ethtool_link_ksettings_add_link_mode(link_ksettings,
advertising,
Asym_Pause);
}
base->autoneg = pi->link_cfg.autoneg; base->autoneg = pi->link_cfg.autoneg;
if (pi->link_cfg.supported & FW_PORT_CAP_ANEG) if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
ethtool_link_ksettings_add_link_mode(link_ksettings, ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, Autoneg); supported, Autoneg);
if (pi->link_cfg.autoneg) if (pi->link_cfg.autoneg)
...@@ -748,8 +774,7 @@ static int get_link_ksettings(struct net_device *dev, ...@@ -748,8 +774,7 @@ static int get_link_ksettings(struct net_device *dev,
} }
static int set_link_ksettings(struct net_device *dev, static int set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings const struct ethtool_link_ksettings *link_ksettings)
*link_ksettings)
{ {
struct port_info *pi = netdev_priv(dev); struct port_info *pi = netdev_priv(dev);
struct link_config *lc = &pi->link_cfg; struct link_config *lc = &pi->link_cfg;
...@@ -762,12 +787,12 @@ static int set_link_ksettings(struct net_device *dev, ...@@ -762,12 +787,12 @@ static int set_link_ksettings(struct net_device *dev,
if (base->duplex != DUPLEX_FULL) if (base->duplex != DUPLEX_FULL)
return -EINVAL; return -EINVAL;
if (!(lc->supported & FW_PORT_CAP_ANEG)) { if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
/* PHY offers a single speed. See if that's what's /* PHY offers a single speed. See if that's what's
* being requested. * being requested.
*/ */
if (base->autoneg == AUTONEG_DISABLE && if (base->autoneg == AUTONEG_DISABLE &&
(lc->supported & speed_to_fw_caps(base->speed))) (lc->pcaps & speed_to_fw_caps(base->speed)))
return 0; return 0;
return -EINVAL; return -EINVAL;
} }
...@@ -776,18 +801,17 @@ static int set_link_ksettings(struct net_device *dev, ...@@ -776,18 +801,17 @@ static int set_link_ksettings(struct net_device *dev,
if (base->autoneg == AUTONEG_DISABLE) { if (base->autoneg == AUTONEG_DISABLE) {
fw_caps = speed_to_fw_caps(base->speed); fw_caps = speed_to_fw_caps(base->speed);
if (!(lc->supported & fw_caps)) if (!(lc->pcaps & fw_caps))
return -EINVAL; return -EINVAL;
lc->requested_speed = fw_caps; lc->speed_caps = fw_caps;
lc->advertising = 0; lc->acaps = 0;
} else { } else {
fw_caps = fw_caps =
lmm_to_fw_caps(link_ksettings->link_modes.advertising); lmm_to_fw_caps(link_ksettings->link_modes.advertising);
if (!(lc->pcaps & fw_caps))
if (!(lc->supported & fw_caps))
return -EINVAL; return -EINVAL;
lc->requested_speed = 0; lc->speed_caps = 0;
lc->advertising = fw_caps | FW_PORT_CAP_ANEG; lc->acaps = fw_caps | FW_PORT_CAP32_ANEG;
} }
lc->autoneg = base->autoneg; lc->autoneg = base->autoneg;
...@@ -806,9 +830,9 @@ static inline unsigned int fwcap_to_eth_fec(unsigned int fw_fec) ...@@ -806,9 +830,9 @@ static inline unsigned int fwcap_to_eth_fec(unsigned int fw_fec)
{ {
unsigned int eth_fec = 0; unsigned int eth_fec = 0;
if (fw_fec & FW_PORT_CAP_FEC_RS) if (fw_fec & FW_PORT_CAP32_FEC_RS)
eth_fec |= ETHTOOL_FEC_RS; eth_fec |= ETHTOOL_FEC_RS;
if (fw_fec & FW_PORT_CAP_FEC_BASER_RS) if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
eth_fec |= ETHTOOL_FEC_BASER; eth_fec |= ETHTOOL_FEC_BASER;
/* if nothing is set, then FEC is off */ /* if nothing is set, then FEC is off */
...@@ -864,7 +888,7 @@ static int get_fecparam(struct net_device *dev, struct ethtool_fecparam *fec) ...@@ -864,7 +888,7 @@ static int get_fecparam(struct net_device *dev, struct ethtool_fecparam *fec)
* always support IEEE 802.3 "automatic" selection of Link FEC type if * always support IEEE 802.3 "automatic" selection of Link FEC type if
* any FEC is supported. * any FEC is supported.
*/ */
fec->fec = fwcap_to_eth_fec(lc->supported); fec->fec = fwcap_to_eth_fec(lc->pcaps);
if (fec->fec != ETHTOOL_FEC_OFF) if (fec->fec != ETHTOOL_FEC_OFF)
fec->fec |= ETHTOOL_FEC_AUTO; fec->fec |= ETHTOOL_FEC_AUTO;
...@@ -917,7 +941,7 @@ static int set_pauseparam(struct net_device *dev, ...@@ -917,7 +941,7 @@ static int set_pauseparam(struct net_device *dev,
if (epause->autoneg == AUTONEG_DISABLE) if (epause->autoneg == AUTONEG_DISABLE)
lc->requested_fc = 0; lc->requested_fc = 0;
else if (lc->supported & FW_PORT_CAP_ANEG) else if (lc->pcaps & FW_PORT_CAP32_ANEG)
lc->requested_fc = PAUSE_AUTONEG; lc->requested_fc = PAUSE_AUTONEG;
else else
return -EINVAL; return -EINVAL;
......
...@@ -530,15 +530,22 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, ...@@ -530,15 +530,22 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
FW_PORT_CMD_ACTION_G(ntohl(pcmd->action_to_len16)); FW_PORT_CMD_ACTION_G(ntohl(pcmd->action_to_len16));
if (cmd == FW_PORT_CMD && if (cmd == FW_PORT_CMD &&
action == FW_PORT_ACTION_GET_PORT_INFO) { (action == FW_PORT_ACTION_GET_PORT_INFO ||
action == FW_PORT_ACTION_GET_PORT_INFO32)) {
int port = FW_PORT_CMD_PORTID_G( int port = FW_PORT_CMD_PORTID_G(
be32_to_cpu(pcmd->op_to_portid)); be32_to_cpu(pcmd->op_to_portid));
struct net_device *dev = struct net_device *dev;
q->adap->port[q->adap->chan_map[port]]; int dcbxdis, state_input;
int state_input = ((pcmd->u.info.dcbxdis_pkd &
FW_PORT_CMD_DCBXDIS_F) dev = q->adap->port[q->adap->chan_map[port]];
? CXGB4_DCB_INPUT_FW_DISABLED dcbxdis = (action == FW_PORT_ACTION_GET_PORT_INFO
: CXGB4_DCB_INPUT_FW_ENABLED); ? !!(pcmd->u.info.dcbxdis_pkd &
FW_PORT_CMD_DCBXDIS_F)
: !!(pcmd->u.info32.lstatus32_to_cbllen32 &
FW_PORT_CMD_DCBXDIS32_F));
state_input = (dcbxdis
? CXGB4_DCB_INPUT_FW_DISABLED
: CXGB4_DCB_INPUT_FW_ENABLED);
cxgb4_dcb_state_fsm(dev, state_input); cxgb4_dcb_state_fsm(dev, state_input);
} }
...@@ -2672,11 +2679,10 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, ...@@ -2672,11 +2679,10 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
{ {
struct port_info *pi = netdev_priv(dev); struct port_info *pi = netdev_priv(dev);
struct adapter *adap = pi->adapter; struct adapter *adap = pi->adapter;
struct fw_port_cmd port_cmd, port_rpl; unsigned int link_ok, speed, mtu;
u32 link_status, speed = 0;
u32 fw_pfvf, fw_class; u32 fw_pfvf, fw_class;
int class_id = vf; int class_id = vf;
int link_ok, ret; int ret;
u16 pktsize; u16 pktsize;
if (vf >= adap->num_vfs) if (vf >= adap->num_vfs)
...@@ -2688,41 +2694,18 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, ...@@ -2688,41 +2694,18 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
min_tx_rate, vf); min_tx_rate, vf);
return -EINVAL; return -EINVAL;
} }
/* Retrieve link details for VF port */
memset(&port_cmd, 0, sizeof(port_cmd)); ret = t4_get_link_params(pi, &link_ok, &speed, &mtu);
port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
FW_CMD_REQUEST_F |
FW_CMD_READ_F |
FW_PORT_CMD_PORTID_V(pi->port_id));
port_cmd.action_to_len16 =
cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
FW_LEN16(port_cmd));
ret = t4_wr_mbox(adap, adap->mbox, &port_cmd, sizeof(port_cmd),
&port_rpl);
if (ret != FW_SUCCESS) { if (ret != FW_SUCCESS) {
dev_err(adap->pdev_dev, dev_err(adap->pdev_dev,
"Failed to get link status for VF %d\n", vf); "Failed to get link information for VF %d\n", vf);
return -EINVAL; return -EINVAL;
} }
link_status = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
link_ok = (link_status & FW_PORT_CMD_LSTATUS_F) != 0;
if (!link_ok) { if (!link_ok) {
dev_err(adap->pdev_dev, "Link down for VF %d\n", vf); dev_err(adap->pdev_dev, "Link down for VF %d\n", vf);
return -EINVAL; return -EINVAL;
} }
/* Determine link speed */
if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
speed = 100;
else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
speed = 1000;
else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
speed = 10000;
else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
speed = 25000;
else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
speed = 40000;
else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
speed = 100000;
if (max_tx_rate > speed) { if (max_tx_rate > speed) {
dev_err(adap->pdev_dev, dev_err(adap->pdev_dev,
...@@ -2730,7 +2713,8 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, ...@@ -2730,7 +2713,8 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
max_tx_rate, vf, speed); max_tx_rate, vf, speed);
return -EINVAL; return -EINVAL;
} }
pktsize = be16_to_cpu(port_rpl.u.info.mtu);
pktsize = mtu;
/* subtract ethhdr size and 4 bytes crc since, f/w appends it */ /* subtract ethhdr size and 4 bytes crc since, f/w appends it */
pktsize = pktsize - sizeof(struct ethhdr) - 4; pktsize = pktsize - sizeof(struct ethhdr) - 4;
/* subtract ipv4 hdr size, tcp hdr size to get typical IPv4 MSS size */ /* subtract ipv4 hdr size, tcp hdr size to get typical IPv4 MSS size */
...@@ -2741,7 +2725,7 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, ...@@ -2741,7 +2725,7 @@ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
SCHED_CLASS_MODE_CLASS, SCHED_CLASS_MODE_CLASS,
SCHED_CLASS_RATEUNIT_BITS, SCHED_CLASS_RATEUNIT_BITS,
SCHED_CLASS_RATEMODE_ABS, SCHED_CLASS_RATEMODE_ABS,
pi->port_id, class_id, 0, pi->tx_chan, class_id, 0,
max_tx_rate * 1000, 0, pktsize); max_tx_rate * 1000, 0, pktsize);
if (ret) { if (ret) {
dev_err(adap->pdev_dev, "Err %d for Traffic Class config\n", dev_err(adap->pdev_dev, "Err %d for Traffic Class config\n",
...@@ -4208,8 +4192,9 @@ static inline bool is_x_10g_port(const struct link_config *lc) ...@@ -4208,8 +4192,9 @@ static inline bool is_x_10g_port(const struct link_config *lc)
{ {
unsigned int speeds, high_speeds; unsigned int speeds, high_speeds;
speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported)); speeds = FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_G(lc->pcaps));
high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G); high_speeds = speeds &
~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
return high_speeds != 0; return high_speeds != 0;
} }
...@@ -4590,18 +4575,24 @@ static void print_port_info(const struct net_device *dev) ...@@ -4590,18 +4575,24 @@ static void print_port_info(const struct net_device *dev)
else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_8_0GB) else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_8_0GB)
spd = " 8 GT/s"; spd = " 8 GT/s";
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100M)
bufp += sprintf(bufp, "100M/"); bufp += sprintf(bufp, "100M/");
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_1G)
bufp += sprintf(bufp, "1G/"); bufp += sprintf(bufp, "1G/");
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_10G)
bufp += sprintf(bufp, "10G/"); bufp += sprintf(bufp, "10G/");
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_25G)
bufp += sprintf(bufp, "25G/"); bufp += sprintf(bufp, "25G/");
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_40G)
bufp += sprintf(bufp, "40G/"); bufp += sprintf(bufp, "40G/");
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_50G)
bufp += sprintf(bufp, "50G/");
if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100G)
bufp += sprintf(bufp, "100G/"); bufp += sprintf(bufp, "100G/");
if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_200G)
bufp += sprintf(bufp, "200G/");
if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_400G)
bufp += sprintf(bufp, "400G/");
if (bufp != buf) if (bufp != buf)
--bufp; --bufp;
sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type)); sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type));
...@@ -4707,10 +4698,11 @@ static int config_mgmt_dev(struct pci_dev *pdev) ...@@ -4707,10 +4698,11 @@ static int config_mgmt_dev(struct pci_dev *pdev)
pi = netdev_priv(netdev); pi = netdev_priv(netdev);
pi->adapter = adap; pi->adapter = adap;
pi->port_id = adap->pf % adap->params.nports; pi->tx_chan = adap->pf % adap->params.nports;
SET_NETDEV_DEV(netdev, &pdev->dev); SET_NETDEV_DEV(netdev, &pdev->dev);
adap->port[0] = netdev; adap->port[0] = netdev;
pi->port_id = 0;
err = register_netdev(adap->port[0]); err = register_netdev(adap->port[0]);
if (err) { if (err) {
......
This diff is collapsed.
...@@ -1173,7 +1173,8 @@ enum fw_params_param_pfvf { ...@@ -1173,7 +1173,8 @@ enum fw_params_param_pfvf {
FW_PARAMS_PARAM_PFVF_ACTIVE_FILTER_END = 0x2E, FW_PARAMS_PARAM_PFVF_ACTIVE_FILTER_END = 0x2E,
FW_PARAMS_PARAM_PFVF_ETHOFLD_END = 0x30, FW_PARAMS_PARAM_PFVF_ETHOFLD_END = 0x30,
FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31, FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
FW_PARAMS_PARAM_PFVF_NCRYPTO_LOOKASIDE = 0x32 FW_PARAMS_PARAM_PFVF_NCRYPTO_LOOKASIDE = 0x32,
FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A,
}; };
/* /*
...@@ -2256,6 +2257,7 @@ struct fw_acl_vlan_cmd { ...@@ -2256,6 +2257,7 @@ struct fw_acl_vlan_cmd {
#define FW_ACL_VLAN_CMD_FM_S 6 #define FW_ACL_VLAN_CMD_FM_S 6
#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S) #define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S)
/* old 16-bit port capabilities bitmap (fw_port_cap16_t) */
enum fw_port_cap { enum fw_port_cap {
FW_PORT_CAP_SPEED_100M = 0x0001, FW_PORT_CAP_SPEED_100M = 0x0001,
FW_PORT_CAP_SPEED_1G = 0x0002, FW_PORT_CAP_SPEED_1G = 0x0002,
...@@ -2291,6 +2293,84 @@ enum fw_port_mdi { ...@@ -2291,6 +2293,84 @@ enum fw_port_mdi {
#define FW_PORT_CAP_MDI_S 9 #define FW_PORT_CAP_MDI_S 9
#define FW_PORT_CAP_MDI_V(x) ((x) << FW_PORT_CAP_MDI_S) #define FW_PORT_CAP_MDI_V(x) ((x) << FW_PORT_CAP_MDI_S)
/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */
#define FW_PORT_CAP32_SPEED_100M 0x00000001UL
#define FW_PORT_CAP32_SPEED_1G 0x00000002UL
#define FW_PORT_CAP32_SPEED_10G 0x00000004UL
#define FW_PORT_CAP32_SPEED_25G 0x00000008UL
#define FW_PORT_CAP32_SPEED_40G 0x00000010UL
#define FW_PORT_CAP32_SPEED_50G 0x00000020UL
#define FW_PORT_CAP32_SPEED_100G 0x00000040UL
#define FW_PORT_CAP32_SPEED_200G 0x00000080UL
#define FW_PORT_CAP32_SPEED_400G 0x00000100UL
#define FW_PORT_CAP32_SPEED_RESERVED1 0x00000200UL
#define FW_PORT_CAP32_SPEED_RESERVED2 0x00000400UL
#define FW_PORT_CAP32_SPEED_RESERVED3 0x00000800UL
#define FW_PORT_CAP32_RESERVED1 0x0000f000UL
#define FW_PORT_CAP32_FC_RX 0x00010000UL
#define FW_PORT_CAP32_FC_TX 0x00020000UL
#define FW_PORT_CAP32_802_3_PAUSE 0x00040000UL
#define FW_PORT_CAP32_802_3_ASM_DIR 0x00080000UL
#define FW_PORT_CAP32_ANEG 0x00100000UL
#define FW_PORT_CAP32_MDIX 0x00200000UL
#define FW_PORT_CAP32_MDIAUTO 0x00400000UL
#define FW_PORT_CAP32_FEC_RS 0x00800000UL
#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL
#define FW_PORT_CAP32_FEC_RESERVED1 0x02000000UL
#define FW_PORT_CAP32_FEC_RESERVED2 0x04000000UL
#define FW_PORT_CAP32_FEC_RESERVED3 0x08000000UL
#define FW_PORT_CAP32_RESERVED2 0xf0000000UL
#define FW_PORT_CAP32_SPEED_S 0
#define FW_PORT_CAP32_SPEED_M 0xfff
#define FW_PORT_CAP32_SPEED_V(x) ((x) << FW_PORT_CAP32_SPEED_S)
#define FW_PORT_CAP32_SPEED_G(x) \
(((x) >> FW_PORT_CAP32_SPEED_S) & FW_PORT_CAP32_SPEED_M)
#define FW_PORT_CAP32_FC_S 16
#define FW_PORT_CAP32_FC_M 0x3
#define FW_PORT_CAP32_FC_V(x) ((x) << FW_PORT_CAP32_FC_S)
#define FW_PORT_CAP32_FC_G(x) \
(((x) >> FW_PORT_CAP32_FC_S) & FW_PORT_CAP32_FC_M)
#define FW_PORT_CAP32_802_3_S 18
#define FW_PORT_CAP32_802_3_M 0x3
#define FW_PORT_CAP32_802_3_V(x) ((x) << FW_PORT_CAP32_802_3_S)
#define FW_PORT_CAP32_802_3_G(x) \
(((x) >> FW_PORT_CAP32_802_3_S) & FW_PORT_CAP32_802_3_M)
#define FW_PORT_CAP32_ANEG_S 20
#define FW_PORT_CAP32_ANEG_M 0x1
#define FW_PORT_CAP32_ANEG_V(x) ((x) << FW_PORT_CAP32_ANEG_S)
#define FW_PORT_CAP32_ANEG_G(x) \
(((x) >> FW_PORT_CAP32_ANEG_S) & FW_PORT_CAP32_ANEG_M)
enum fw_port_mdi32 {
FW_PORT_CAP32_MDI_UNCHANGED,
FW_PORT_CAP32_MDI_AUTO,
FW_PORT_CAP32_MDI_F_STRAIGHT,
FW_PORT_CAP32_MDI_F_CROSSOVER
};
#define FW_PORT_CAP32_MDI_S 21
#define FW_PORT_CAP32_MDI_M 3
#define FW_PORT_CAP32_MDI_V(x) ((x) << FW_PORT_CAP32_MDI_S)
#define FW_PORT_CAP32_MDI_G(x) \
(((x) >> FW_PORT_CAP32_MDI_S) & FW_PORT_CAP32_MDI_M)
#define FW_PORT_CAP32_FEC_S 23
#define FW_PORT_CAP32_FEC_M 0x1f
#define FW_PORT_CAP32_FEC_V(x) ((x) << FW_PORT_CAP32_FEC_S)
#define FW_PORT_CAP32_FEC_G(x) \
(((x) >> FW_PORT_CAP32_FEC_S) & FW_PORT_CAP32_FEC_M)
/* macros to isolate various 32-bit Port Capabilities sub-fields */
#define CAP32_SPEED(__cap32) \
(FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) & __cap32)
#define CAP32_FEC(__cap32) \
(FW_PORT_CAP32_FEC_V(FW_PORT_CAP32_FEC_M) & __cap32)
enum fw_port_action { enum fw_port_action {
FW_PORT_ACTION_L1_CFG = 0x0001, FW_PORT_ACTION_L1_CFG = 0x0001,
FW_PORT_ACTION_L2_CFG = 0x0002, FW_PORT_ACTION_L2_CFG = 0x0002,
...@@ -2300,6 +2380,8 @@ enum fw_port_action { ...@@ -2300,6 +2380,8 @@ enum fw_port_action {
FW_PORT_ACTION_DCB_READ_TRANS = 0x0006, FW_PORT_ACTION_DCB_READ_TRANS = 0x0006,
FW_PORT_ACTION_DCB_READ_RECV = 0x0007, FW_PORT_ACTION_DCB_READ_RECV = 0x0007,
FW_PORT_ACTION_DCB_READ_DET = 0x0008, FW_PORT_ACTION_DCB_READ_DET = 0x0008,
FW_PORT_ACTION_L1_CFG32 = 0x0009,
FW_PORT_ACTION_GET_PORT_INFO32 = 0x000a,
FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010, FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011, FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011,
FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012, FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012,
...@@ -2447,6 +2529,18 @@ struct fw_port_cmd { ...@@ -2447,6 +2529,18 @@ struct fw_port_cmd {
__be64 r12; __be64 r12;
} control; } control;
} dcb; } dcb;
struct fw_port_l1cfg32 {
__be32 rcap32;
__be32 r;
} l1cfg32;
struct fw_port_info32 {
__be32 lstatus32_to_cbllen32;
__be32 auxlinfo32_mtu32;
__be32 linkattr32;
__be32 pcaps32;
__be32 acaps32;
__be32 lpacaps32;
} info32;
} u; } u;
}; };
...@@ -2555,6 +2649,85 @@ struct fw_port_cmd { ...@@ -2555,6 +2649,85 @@ struct fw_port_cmd {
#define FW_PORT_CMD_DCB_VERSION_G(x) \ #define FW_PORT_CMD_DCB_VERSION_G(x) \
(((x) >> FW_PORT_CMD_DCB_VERSION_S) & FW_PORT_CMD_DCB_VERSION_M) (((x) >> FW_PORT_CMD_DCB_VERSION_S) & FW_PORT_CMD_DCB_VERSION_M)
#define FW_PORT_CMD_LSTATUS32_S 31
#define FW_PORT_CMD_LSTATUS32_M 0x1
#define FW_PORT_CMD_LSTATUS32_V(x) ((x) << FW_PORT_CMD_LSTATUS32_S)
#define FW_PORT_CMD_LSTATUS32_G(x) \
(((x) >> FW_PORT_CMD_LSTATUS32_S) & FW_PORT_CMD_LSTATUS32_M)
#define FW_PORT_CMD_LSTATUS32_F FW_PORT_CMD_LSTATUS32_V(1U)
#define FW_PORT_CMD_LINKDNRC32_S 28
#define FW_PORT_CMD_LINKDNRC32_M 0x7
#define FW_PORT_CMD_LINKDNRC32_V(x) ((x) << FW_PORT_CMD_LINKDNRC32_S)
#define FW_PORT_CMD_LINKDNRC32_G(x) \
(((x) >> FW_PORT_CMD_LINKDNRC32_S) & FW_PORT_CMD_LINKDNRC32_M)
#define FW_PORT_CMD_DCBXDIS32_S 27
#define FW_PORT_CMD_DCBXDIS32_M 0x1
#define FW_PORT_CMD_DCBXDIS32_V(x) ((x) << FW_PORT_CMD_DCBXDIS32_S)
#define FW_PORT_CMD_DCBXDIS32_G(x) \
(((x) >> FW_PORT_CMD_DCBXDIS32_S) & FW_PORT_CMD_DCBXDIS32_M)
#define FW_PORT_CMD_DCBXDIS32_F FW_PORT_CMD_DCBXDIS32_V(1U)
#define FW_PORT_CMD_MDIOCAP32_S 26
#define FW_PORT_CMD_MDIOCAP32_M 0x1
#define FW_PORT_CMD_MDIOCAP32_V(x) ((x) << FW_PORT_CMD_MDIOCAP32_S)
#define FW_PORT_CMD_MDIOCAP32_G(x) \
(((x) >> FW_PORT_CMD_MDIOCAP32_S) & FW_PORT_CMD_MDIOCAP32_M)
#define FW_PORT_CMD_MDIOCAP32_F FW_PORT_CMD_MDIOCAP32_V(1U)
#define FW_PORT_CMD_MDIOADDR32_S 21
#define FW_PORT_CMD_MDIOADDR32_M 0x1f
#define FW_PORT_CMD_MDIOADDR32_V(x) ((x) << FW_PORT_CMD_MDIOADDR32_S)
#define FW_PORT_CMD_MDIOADDR32_G(x) \
(((x) >> FW_PORT_CMD_MDIOADDR32_S) & FW_PORT_CMD_MDIOADDR32_M)
#define FW_PORT_CMD_PORTTYPE32_S 13
#define FW_PORT_CMD_PORTTYPE32_M 0xff
#define FW_PORT_CMD_PORTTYPE32_V(x) ((x) << FW_PORT_CMD_PORTTYPE32_S)
#define FW_PORT_CMD_PORTTYPE32_G(x) \
(((x) >> FW_PORT_CMD_PORTTYPE32_S) & FW_PORT_CMD_PORTTYPE32_M)
#define FW_PORT_CMD_MODTYPE32_S 8
#define FW_PORT_CMD_MODTYPE32_M 0x1f
#define FW_PORT_CMD_MODTYPE32_V(x) ((x) << FW_PORT_CMD_MODTYPE32_S)
#define FW_PORT_CMD_MODTYPE32_G(x) \
(((x) >> FW_PORT_CMD_MODTYPE32_S) & FW_PORT_CMD_MODTYPE32_M)
#define FW_PORT_CMD_CBLLEN32_S 0
#define FW_PORT_CMD_CBLLEN32_M 0xff
#define FW_PORT_CMD_CBLLEN32_V(x) ((x) << FW_PORT_CMD_CBLLEN32_S)
#define FW_PORT_CMD_CBLLEN32_G(x) \
(((x) >> FW_PORT_CMD_CBLLEN32_S) & FW_PORT_CMD_CBLLEN32_M)
#define FW_PORT_CMD_AUXLINFO32_S 24
#define FW_PORT_CMD_AUXLINFO32_M 0xff
#define FW_PORT_CMD_AUXLINFO32_V(x) ((x) << FW_PORT_CMD_AUXLINFO32_S)
#define FW_PORT_CMD_AUXLINFO32_G(x) \
(((x) >> FW_PORT_CMD_AUXLINFO32_S) & FW_PORT_CMD_AUXLINFO32_M)
#define FW_PORT_AUXLINFO32_KX4_S 2
#define FW_PORT_AUXLINFO32_KX4_M 0x1
#define FW_PORT_AUXLINFO32_KX4_V(x) \
((x) << FW_PORT_AUXLINFO32_KX4_S)
#define FW_PORT_AUXLINFO32_KX4_G(x) \
(((x) >> FW_PORT_AUXLINFO32_KX4_S) & FW_PORT_AUXLINFO32_KX4_M)
#define FW_PORT_AUXLINFO32_KX4_F FW_PORT_AUXLINFO32_KX4_V(1U)
#define FW_PORT_AUXLINFO32_KR_S 1
#define FW_PORT_AUXLINFO32_KR_M 0x1
#define FW_PORT_AUXLINFO32_KR_V(x) \
((x) << FW_PORT_AUXLINFO32_KR_S)
#define FW_PORT_AUXLINFO32_KR_G(x) \
(((x) >> FW_PORT_AUXLINFO32_KR_S) & FW_PORT_AUXLINFO32_KR_M)
#define FW_PORT_AUXLINFO32_KR_F FW_PORT_AUXLINFO32_KR_V(1U)
#define FW_PORT_CMD_MTU32_S 0
#define FW_PORT_CMD_MTU32_M 0xffff
#define FW_PORT_CMD_MTU32_V(x) ((x) << FW_PORT_CMD_MTU32_S)
#define FW_PORT_CMD_MTU32_G(x) \
(((x) >> FW_PORT_CMD_MTU32_S) & FW_PORT_CMD_MTU32_M)
enum fw_port_type { enum fw_port_type {
FW_PORT_TYPE_FIBER_XFI, FW_PORT_TYPE_FIBER_XFI,
FW_PORT_TYPE_FIBER_XAUI, FW_PORT_TYPE_FIBER_XAUI,
......
...@@ -182,7 +182,7 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) ...@@ -182,7 +182,7 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
break; break;
} }
switch (pi->link_cfg.fc) { switch ((int)pi->link_cfg.fc) {
case PAUSE_RX: case PAUSE_RX:
fc = "RX"; fc = "RX";
break; break;
...@@ -191,7 +191,7 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) ...@@ -191,7 +191,7 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
fc = "TX"; fc = "TX";
break; break;
case PAUSE_RX|PAUSE_TX: case PAUSE_RX | PAUSE_TX:
fc = "RX/TX"; fc = "RX/TX";
break; break;
...@@ -1213,7 +1213,11 @@ static int from_fw_port_mod_type(enum fw_port_type port_type, ...@@ -1213,7 +1213,11 @@ static int from_fw_port_mod_type(enum fw_port_type port_type,
} else if (port_type == FW_PORT_TYPE_SFP || } else if (port_type == FW_PORT_TYPE_SFP ||
port_type == FW_PORT_TYPE_QSFP_10G || port_type == FW_PORT_TYPE_QSFP_10G ||
port_type == FW_PORT_TYPE_QSA || port_type == FW_PORT_TYPE_QSA ||
port_type == FW_PORT_TYPE_QSFP) { port_type == FW_PORT_TYPE_QSFP ||
port_type == FW_PORT_TYPE_CR4_QSFP ||
port_type == FW_PORT_TYPE_CR_QSFP ||
port_type == FW_PORT_TYPE_CR2_QSFP ||
port_type == FW_PORT_TYPE_SFP28) {
if (mod_type == FW_PORT_MOD_TYPE_LR || if (mod_type == FW_PORT_MOD_TYPE_LR ||
mod_type == FW_PORT_MOD_TYPE_SR || mod_type == FW_PORT_MOD_TYPE_SR ||
mod_type == FW_PORT_MOD_TYPE_ER || mod_type == FW_PORT_MOD_TYPE_ER ||
...@@ -1224,6 +1228,9 @@ static int from_fw_port_mod_type(enum fw_port_type port_type, ...@@ -1224,6 +1228,9 @@ static int from_fw_port_mod_type(enum fw_port_type port_type,
return PORT_DA; return PORT_DA;
else else
return PORT_OTHER; return PORT_OTHER;
} else if (port_type == FW_PORT_TYPE_KR4_100G ||
port_type == FW_PORT_TYPE_KR_SFP28) {
return PORT_NONE;
} }
return PORT_OTHER; return PORT_OTHER;
...@@ -1242,12 +1249,13 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -1242,12 +1249,13 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
unsigned int fw_caps, unsigned int fw_caps,
unsigned long *link_mode_mask) unsigned long *link_mode_mask)
{ {
#define SET_LMM(__lmm_name) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name\ #define SET_LMM(__lmm_name) \
## _BIT, link_mode_mask) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
link_mode_mask)
#define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \ #define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \
do { \ do { \
if (fw_caps & FW_PORT_CAP_ ## __fw_name) \ if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
SET_LMM(__lmm_name); \ SET_LMM(__lmm_name); \
} while (0) } while (0)
...@@ -1310,6 +1318,16 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -1310,6 +1318,16 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
SET_LMM(25000baseCR_Full); SET_LMM(25000baseCR_Full);
break; break;
case FW_PORT_TYPE_KR_SFP28:
SET_LMM(Backplane);
SET_LMM(25000baseKR_Full);
break;
case FW_PORT_TYPE_CR2_QSFP:
SET_LMM(FIBRE);
SET_LMM(50000baseSR2_Full);
break;
case FW_PORT_TYPE_KR4_100G: case FW_PORT_TYPE_KR4_100G:
case FW_PORT_TYPE_CR4_QSFP: case FW_PORT_TYPE_CR4_QSFP:
SET_LMM(FIBRE); SET_LMM(FIBRE);
...@@ -1329,12 +1347,18 @@ static void fw_caps_to_lmm(enum fw_port_type port_type, ...@@ -1329,12 +1347,18 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
} }
static int cxgb4vf_get_link_ksettings(struct net_device *dev, static int cxgb4vf_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings struct ethtool_link_ksettings *link_ksettings)
*link_ksettings)
{ {
const struct port_info *pi = netdev_priv(dev); struct port_info *pi = netdev_priv(dev);
struct ethtool_link_settings *base = &link_ksettings->base; struct ethtool_link_settings *base = &link_ksettings->base;
/* For the nonce, the Firmware doesn't send up Port State changes
* when the Virtual Interface attached to the Port is down. So
* if it's down, let's grab any changes.
*/
if (!netif_running(dev))
(void)t4vf_update_port_info(pi);
ethtool_link_ksettings_zero_link_mode(link_ksettings, supported); ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising); ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
...@@ -1351,11 +1375,11 @@ static int cxgb4vf_get_link_ksettings(struct net_device *dev, ...@@ -1351,11 +1375,11 @@ static int cxgb4vf_get_link_ksettings(struct net_device *dev,
base->mdio_support = 0; base->mdio_support = 0;
} }
fw_caps_to_lmm(pi->port_type, pi->link_cfg.supported, fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
link_ksettings->link_modes.supported); link_ksettings->link_modes.supported);
fw_caps_to_lmm(pi->port_type, pi->link_cfg.advertising, fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
link_ksettings->link_modes.advertising); link_ksettings->link_modes.advertising);
fw_caps_to_lmm(pi->port_type, pi->link_cfg.lp_advertising, fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
link_ksettings->link_modes.lp_advertising); link_ksettings->link_modes.lp_advertising);
if (netif_carrier_ok(dev)) { if (netif_carrier_ok(dev)) {
...@@ -1367,7 +1391,7 @@ static int cxgb4vf_get_link_ksettings(struct net_device *dev, ...@@ -1367,7 +1391,7 @@ static int cxgb4vf_get_link_ksettings(struct net_device *dev,
} }
base->autoneg = pi->link_cfg.autoneg; base->autoneg = pi->link_cfg.autoneg;
if (pi->link_cfg.supported & FW_PORT_CAP_ANEG) if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
ethtool_link_ksettings_add_link_mode(link_ksettings, ethtool_link_ksettings_add_link_mode(link_ksettings,
supported, Autoneg); supported, Autoneg);
if (pi->link_cfg.autoneg) if (pi->link_cfg.autoneg)
......
...@@ -104,24 +104,62 @@ struct t4vf_port_stats { ...@@ -104,24 +104,62 @@ struct t4vf_port_stats {
/* /*
* Per-"port" (Virtual Interface) link configuration ... * Per-"port" (Virtual Interface) link configuration ...
*/ */
struct link_config { typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
unsigned int supported; /* link capabilities */ typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
unsigned int advertising; /* advertised capabilities */
unsigned short lp_advertising; /* peer advertised capabilities */ enum fw_caps {
unsigned int requested_speed; /* speed user has requested */ FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */
unsigned int speed; /* actual link speed */ FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */
unsigned char requested_fc; /* flow control user has requested */ FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */
unsigned char fc; /* actual link flow control */
unsigned char autoneg; /* autonegotiating? */
unsigned char link_ok; /* link up? */
}; };
enum { enum cc_pause {
PAUSE_RX = 1 << 0, PAUSE_RX = 1 << 0,
PAUSE_TX = 1 << 1, PAUSE_TX = 1 << 1,
PAUSE_AUTONEG = 1 << 2 PAUSE_AUTONEG = 1 << 2
};
enum cc_fec {
FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
FEC_RS = 1 << 1, /* Reed-Solomon */
FEC_BASER_RS = 1 << 2, /* BaseR/Reed-Solomon */
};
struct link_config {
fw_port_cap32_t pcaps; /* link capabilities */
fw_port_cap32_t acaps; /* advertised capabilities */
fw_port_cap32_t lpacaps; /* peer advertised capabilities */
fw_port_cap32_t speed_caps; /* speed(s) user has requested */
u32 speed; /* actual link speed */
enum cc_pause requested_fc; /* flow control user has requested */
enum cc_pause fc; /* actual link flow control */
enum cc_fec auto_fec; /* Forward Error Correction: */
enum cc_fec requested_fec; /* "automatic" (IEEE 802.3), */
enum cc_fec fec; /* requested, and actual in use */
unsigned char autoneg; /* autonegotiating? */
unsigned char link_ok; /* link up? */
unsigned char link_down_rc; /* link down reason */
}; };
/* Return true if the Link Configuration supports "High Speeds" (those greater
* than 1Gb/s).
*/
static inline bool is_x_10g_port(const struct link_config *lc)
{
fw_port_cap32_t speeds, high_speeds;
speeds = FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_G(lc->pcaps));
high_speeds =
speeds & ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
return high_speeds != 0;
}
/* /*
* General device parameters ... * General device parameters ...
*/ */
...@@ -227,6 +265,7 @@ struct adapter_params { ...@@ -227,6 +265,7 @@ struct adapter_params {
struct arch_specific_params arch; /* chip specific params */ struct arch_specific_params arch; /* chip specific params */
enum chip_type chip; /* chip code */ enum chip_type chip; /* chip code */
u8 nports; /* # of Ethernet "ports" */ u8 nports; /* # of Ethernet "ports" */
u8 fw_caps_support; /* 32-bit Port Capabilities */
}; };
/* Firmware Mailbox Command/Reply log. All values are in Host-Endian format. /* Firmware Mailbox Command/Reply log. All values are in Host-Endian format.
...@@ -266,24 +305,6 @@ static inline struct mbox_cmd *mbox_cmd_log_entry(struct mbox_cmd_log *log, ...@@ -266,24 +305,6 @@ static inline struct mbox_cmd *mbox_cmd_log_entry(struct mbox_cmd_log *log,
#define for_each_port(adapter, iter) \ #define for_each_port(adapter, iter) \
for (iter = 0; iter < (adapter)->params.nports; iter++) for (iter = 0; iter < (adapter)->params.nports; iter++)
static inline bool is_10g_port(const struct link_config *lc)
{
return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
}
/* Return true if the Link Configuration supports "High Speeds" (those greater
* than 1Gb/s).
*/
static inline bool is_x_10g_port(const struct link_config *lc)
{
unsigned int speeds, high_speeds;
speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported));
high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
return high_speeds != 0;
}
static inline unsigned int core_ticks_per_usec(const struct adapter *adapter) static inline unsigned int core_ticks_per_usec(const struct adapter *adapter)
{ {
return adapter->params.vpd.cclk / 1000; return adapter->params.vpd.cclk / 1000;
...@@ -387,6 +408,7 @@ int t4vf_iq_free(struct adapter *, unsigned int, unsigned int, unsigned int, ...@@ -387,6 +408,7 @@ int t4vf_iq_free(struct adapter *, unsigned int, unsigned int, unsigned int,
unsigned int); unsigned int);
int t4vf_eth_eq_free(struct adapter *, unsigned int); int t4vf_eth_eq_free(struct adapter *, unsigned int);
int t4vf_update_port_info(struct port_info *pi);
int t4vf_handle_fw_rpl(struct adapter *, const __be64 *); int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
int t4vf_prep_adapter(struct adapter *); int t4vf_prep_adapter(struct adapter *);
int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf, int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment