net/cxgbe: rework and simplify link handling

Rework and simplify link handling code. Remove redundant
variables in link configuration structure and directly
extract information from the 32-bit link capabilities.

Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
This commit is contained in:
Karra Satwik 2020-12-21 04:17:41 +05:30 committed by Ferruh Yigit
parent 439009e4ef
commit a83041b1e9
7 changed files with 272 additions and 253 deletions

View File

@ -39,9 +39,6 @@ struct port_info {
short int xact_addr_filt; /* index of exact MAC address filter */
u16 viid; /* associated virtual interface id */
s8 mdio_addr; /* address of the PHY */
u8 port_type; /* firmware port type */
u8 mod_type; /* firmware module type */
u8 port_id; /* physical port ID */
u8 pidx; /* port index for this PF */
u8 tx_chan; /* associated channel */
@ -63,12 +60,6 @@ struct port_info {
u8 vivld;
};
/* Enable or disable autonegotiation. If this is set to enable,
* the forced link modes above are completely ignored.
*/
#define AUTONEG_DISABLE 0x00
#define AUTONEG_ENABLE 0x01
enum { /* adapter flags */
FULL_INIT_DONE = (1 << 0),
USING_MSI = (1 << 1),
@ -801,7 +792,6 @@ void t4_free_mem(void *addr);
#define t4_os_free(_ptr) t4_free_mem((_ptr))
void t4_os_portmod_changed(const struct adapter *adap, int port_id);
void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
void reclaim_completed_tx(struct sge_txq *q);
void t4_free_sge_resources(struct adapter *adap);

View File

@ -38,18 +38,6 @@ enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST };
enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR };
enum cc_pause {
PAUSE_RX = 1 << 0,
PAUSE_TX = 1 << 1,
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 */
};
enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 };
struct port_stats {
@ -281,28 +269,19 @@ struct adapter_params {
/* Firmware Port Capabilities types.
*/
typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
struct link_config {
fw_port_cap32_t pcaps; /* link capabilities */
fw_port_cap32_t acaps; /* advertised capabilities */
u32 pcaps; /* Physically supported link caps */
u32 acaps; /* Advertised link caps */
u32 requested_speed; /* speed (Mb/s) user has requested */
u32 speed; /* actual link speed (Mb/s) */
u32 link_caps; /* Current link caps */
u32 admin_caps; /* Admin configured link caps */
enum cc_pause requested_fc; /* flow control user has requested */
enum cc_pause fc; /* actual link flow control */
u8 mdio_addr; /* Address of the PHY */
u8 port_type; /* Firmware port type */
u8 mod_type; /* Firmware module type */
enum cc_fec auto_fec; /* Forward Error Correction
* "automatic" (IEEE 802.3)
*/
enum cc_fec requested_fec; /* Forward Error Correction requested */
enum cc_fec fec; /* Forward Error Correction actual */
unsigned char autoneg; /* autonegotiating? */
unsigned char link_ok; /* link up? */
unsigned char link_down_rc; /* link down reason */
u8 link_ok; /* Link up? */
u8 link_down_rc; /* Link down reason */
};
#include "adapter.h"
@ -338,8 +317,21 @@ void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
unsigned int mask, unsigned int val);
void t4_intr_enable(struct adapter *adapter);
void t4_intr_disable(struct adapter *adapter);
int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc);
int t4_link_l1cfg_core(struct port_info *pi, u32 caps, u8 sleep_ok);
static inline int t4_link_l1cfg(struct port_info *pi, u32 caps)
{
return t4_link_l1cfg_core(pi, caps, true);
}
static inline int t4_link_l1cfg_ns(struct port_info *pi, u32 caps)
{
return t4_link_l1cfg_core(pi, caps, false);
}
int t4_set_link_speed(struct port_info *pi, u32 speed, u32 *new_caps);
int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
u8 pause_rx, u32 *new_caps);
unsigned int t4_fwcap_to_speed(u32 caps);
void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
const unsigned short *alpha, const unsigned short *beta);
int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
@ -496,8 +488,8 @@ void t4_get_port_stats_offset(struct adapter *adap, int idx,
struct port_stats *stats,
struct port_stats *offset);
void t4_clr_port_stats(struct adapter *adap, int idx);
void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
fw_port_cap32_t acaps);
void t4_init_link_config(struct port_info *pi, u32 pcaps, u32 acaps,
u8 mdio_addr, u8 port_type, u8 mod_type);
void t4_reset_link_config(struct adapter *adap, int idx);
int t4_get_version_info(struct adapter *adapter);
void t4_dump_version_info(struct adapter *adapter);

View File

@ -2809,67 +2809,11 @@ void t4_dump_version_info(struct adapter *adapter)
G_FW_HDR_FW_VER_BUILD(adapter->params.er_vers));
}
#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
FW_PORT_CAP32_ANEG)
/* Translate Firmware Pause specification to Common Code */
static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
{
enum cc_pause cc_pause = 0;
if (fw_pause & FW_PORT_CAP32_FC_RX)
cc_pause |= PAUSE_RX;
if (fw_pause & FW_PORT_CAP32_FC_TX)
cc_pause |= PAUSE_TX;
return cc_pause;
}
/* Translate Common Code Pause Frame specification into Firmware */
static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
{
fw_port_cap32_t fw_pause = 0;
if (cc_pause & PAUSE_RX)
fw_pause |= FW_PORT_CAP32_FC_RX;
if (cc_pause & PAUSE_TX)
fw_pause |= FW_PORT_CAP32_FC_TX;
return fw_pause;
}
/* Translate Firmware Forward Error Correction specification to Common Code */
static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
{
enum cc_fec cc_fec = 0;
if (fw_fec & FW_PORT_CAP32_FEC_RS)
cc_fec |= FEC_RS;
if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
cc_fec |= FEC_BASER_RS;
return cc_fec;
}
/* Translate Common Code Forward Error Correction specification to Firmware */
static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
{
fw_port_cap32_t fw_fec = 0;
if (cc_fec & FEC_RS)
fw_fec |= FW_PORT_CAP32_FEC_RS;
if (cc_fec & FEC_BASER_RS)
fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
return fw_fec;
}
/**
* t4_link_l1cfg - apply link configuration to MAC/PHY
* @adapter: the adapter
* @mbox: the Firmware Mailbox to use
* @port: the Port ID
* @lc: the Port's Link Configuration
* t4_link_l1cfg_core - apply link configuration to MAC/PHY
* @pi: the port info
* @caps: link capabilities to configure
* @sleep_ok: if true we may sleep while awaiting command completion
*
* Set up a port's MAC and PHY according to a desired link configuration.
* - If the PHY can auto-negotiate first decide what to advertise, then
@ -2878,57 +2822,36 @@ static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
* otherwise do it later based on the outcome of auto-negotiation.
*/
int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc)
int t4_link_l1cfg_core(struct port_info *pi, u32 caps, u8 sleep_ok)
{
unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
struct link_config *lc = &pi->link_cfg;
struct adapter *adap = pi->adapter;
struct fw_port_cmd cmd;
int ret;
lc->link_ok = 0;
fw_fc = cc_to_fwcap_pause(lc->requested_fc);
/* Convert Common Code Forward Error Control settings into the
* Firmware's API. If the current Requested FEC has "Automatic"
* (IEEE 802.3) specified, then we use whatever the Firmware
* sent us as part of it's IEEE 802.3-based interpratation of
* the Transceiver Module EPROM FEC parameters. Otherwise we
* use whatever is in the current Requested FEC settings.
*/
if (lc->requested_fec & FEC_AUTO)
cc_fec = lc->auto_fec;
else
cc_fec = lc->requested_fec;
fw_fec = cc_to_fwcap_fec(cc_fec);
/* Figure out what our Requested Port Capabilities are going to be.
*/
if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
lc->fec = cc_fec;
} else if (lc->autoneg == AUTONEG_DISABLE) {
rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi;
lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
lc->fec = cc_fec;
} else {
rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
}
/* And send that on to the Firmware ...
*/
memset(&cmd, 0, sizeof(cmd));
cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
V_FW_PORT_CMD_PORTID(port));
V_FW_PORT_CMD_PORTID(pi->port_id));
cmd.action_to_len16 =
cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) |
FW_LEN16(cmd));
cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
cmd.u.l1cfg32.rcap32 = cpu_to_be32(caps);
return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
if (sleep_ok)
ret = t4_wr_mbox(adap, adap->mbox, &cmd, sizeof(cmd), NULL);
else
ret = t4_wr_mbox_ns(adap, adap->mbox, &cmd, sizeof(cmd), NULL);
if (ret == FW_SUCCESS)
lc->link_caps = caps;
else
dev_err(adap,
"Requested Port Capabilities %#x rejected, error %d\n",
caps, ret);
return ret;
}
/**
@ -4426,8 +4349,32 @@ static const char *t4_link_down_rc_str(unsigned char link_down_rc)
return reason[link_down_rc];
}
static u32 t4_speed_to_fwcap(u32 speed)
{
switch (speed) {
case 100000:
return FW_PORT_CAP32_SPEED_100G;
case 50000:
return FW_PORT_CAP32_SPEED_50G;
case 40000:
return FW_PORT_CAP32_SPEED_40G;
case 25000:
return FW_PORT_CAP32_SPEED_25G;
case 10000:
return FW_PORT_CAP32_SPEED_10G;
case 1000:
return FW_PORT_CAP32_SPEED_1G;
case 100:
return FW_PORT_CAP32_SPEED_100M;
default:
break;
}
return 0;
}
/* Return the highest speed set in the port capabilities, in Mb/s. */
static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
unsigned int t4_fwcap_to_speed(u32 caps)
{
#define TEST_SPEED_RETURN(__caps_speed, __speed) \
do { \
@ -4448,6 +4395,84 @@ static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
return 0;
}
static void t4_set_link_autoneg_speed(struct port_info *pi, u32 *new_caps)
{
struct link_config *lc = &pi->link_cfg;
u32 caps = *new_caps;
caps &= ~V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED);
caps |= G_FW_PORT_CAP32_SPEED(lc->acaps);
*new_caps = caps;
}
int t4_set_link_speed(struct port_info *pi, u32 speed, u32 *new_caps)
{
u32 fw_speed_cap = t4_speed_to_fwcap(speed);
struct link_config *lc = &pi->link_cfg;
u32 caps = *new_caps;
if (!(lc->pcaps & fw_speed_cap))
return -EOPNOTSUPP;
caps &= ~V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED);
caps |= fw_speed_cap;
*new_caps = caps;
return 0;
}
int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
u8 pause_rx, u32 *new_caps)
{
struct link_config *lc = &pi->link_cfg;
u32 caps = *new_caps;
u32 max_speed;
max_speed = t4_fwcap_to_speed(lc->link_caps);
if (autoneg) {
if (!(lc->pcaps & FW_PORT_CAP32_ANEG))
return -EINVAL;
caps |= FW_PORT_CAP32_ANEG;
t4_set_link_autoneg_speed(pi, &caps);
} else {
if (!max_speed)
max_speed = t4_fwcap_to_speed(lc->acaps);
caps &= ~FW_PORT_CAP32_ANEG;
t4_set_link_speed(pi, max_speed, &caps);
}
if (lc->pcaps & FW_PORT_CAP32_MDIAUTO)
caps |= V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
caps &= ~V_FW_PORT_CAP32_FC(M_FW_PORT_CAP32_FC);
caps &= ~V_FW_PORT_CAP32_802_3(M_FW_PORT_CAP32_802_3);
if (pause_tx && pause_rx) {
caps |= FW_PORT_CAP32_FC_TX | FW_PORT_CAP32_FC_RX;
if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
caps |= FW_PORT_CAP32_802_3_PAUSE;
} else if (pause_tx) {
caps |= FW_PORT_CAP32_FC_TX;
if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
caps |= FW_PORT_CAP32_802_3_ASM_DIR;
} else if (pause_rx) {
caps |= FW_PORT_CAP32_FC_RX;
if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
caps |= FW_PORT_CAP32_802_3_PAUSE;
if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
caps |= FW_PORT_CAP32_802_3_ASM_DIR;
}
*new_caps = caps;
return 0;
}
/**
* t4_handle_get_port_info - process a FW reply message
* @pi: the port info
@ -4459,10 +4484,10 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
{
const struct fw_port_cmd *cmd = (const void *)rpl;
u8 link_ok, link_down_rc, mod_type, port_type;
u32 action, pcaps, acaps, linkattr, lstatus;
u32 action, pcaps, acaps, link_caps, lstatus;
struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
unsigned int speed, fc, fec;
u8 mod_changed = 0;
/* Extract the various fields from the Port Information message.
*/
@ -4481,21 +4506,16 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
acaps = be32_to_cpu(cmd->u.info32.acaps32);
linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
link_caps = be32_to_cpu(cmd->u.info32.linkattr32);
fec = fwcap_to_cc_fec(acaps);
fc = fwcap_to_cc_pause(linkattr);
speed = fwcap_to_speed(linkattr);
if (mod_type != pi->mod_type) {
lc->auto_fec = fec;
pi->port_type = port_type;
pi->mod_type = mod_type;
if (mod_type != lc->mod_type) {
t4_init_link_config(pi, pcaps, acaps, lc->mdio_addr,
port_type, mod_type);
t4_os_portmod_changed(adapter, pi->pidx);
mod_changed = 1;
}
if (link_ok != lc->link_ok || speed != lc->speed ||
fc != lc->fc || fec != lc->fec) { /* something changed */
if (link_ok != lc->link_ok || acaps != lc->acaps ||
link_caps != lc->link_caps) { /* something changed */
if (!link_ok && lc->link_ok) {
lc->link_down_rc = link_down_rc;
dev_warn(adap, "Port %d link down, reason: %s\n",
@ -4503,23 +4523,19 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
t4_link_down_rc_str(link_down_rc));
}
lc->link_ok = link_ok;
lc->speed = speed;
lc->fc = fc;
lc->fec = fec;
lc->pcaps = pcaps;
lc->acaps = acaps & ADVERT_MASK;
lc->acaps = acaps;
lc->link_caps = link_caps;
}
if (lc->acaps & FW_PORT_CAP32_ANEG) {
lc->autoneg = AUTONEG_ENABLE;
} else {
/* When Autoneg is disabled, user needs to set
* single speed.
* Similar to cxgb4_ethtool.c: set_link_ksettings
*/
lc->acaps = 0;
lc->requested_speed = fwcap_to_speed(acaps);
lc->autoneg = AUTONEG_DISABLE;
}
if (mod_changed) {
u32 mod_caps = lc->admin_caps;
int ret;
ret = t4_link_l1cfg_ns(pi, mod_caps);
if (ret != FW_SUCCESS)
dev_warn(adapter,
"Attempt to update new Transceiver Module settings %#x failed with error: %d\n",
mod_caps, ret);
}
}
@ -4595,45 +4611,49 @@ void t4_reset_link_config(struct adapter *adap, int idx)
struct link_config *lc = &pi->link_cfg;
lc->link_ok = 0;
lc->requested_speed = 0;
lc->requested_fc = 0;
lc->speed = 0;
lc->fc = 0;
lc->link_down_rc = 0;
lc->link_caps = 0;
}
/**
* init_link_config - initialize a link's SW state
* @lc: structure holding the link state
* t4_init_link_config - initialize a link's SW state
* @pi: the port info
* @pcaps: link Port Capabilities
* @acaps: link current Advertised Port Capabilities
* @mdio_addr : address of the PHY
* @port_type : firmware port type
* @mod_type : firmware module type
*
* Initializes the SW state maintained for each link, including the link's
* capabilities and default speed/flow-control/autonegotiation settings.
*/
void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
fw_port_cap32_t acaps)
void t4_init_link_config(struct port_info *pi, u32 pcaps, u32 acaps,
u8 mdio_addr, u8 port_type, u8 mod_type)
{
struct link_config *lc = &pi->link_cfg;
lc->pcaps = pcaps;
lc->requested_speed = 0;
lc->speed = 0;
lc->requested_fc = 0;
lc->fc = 0;
lc->acaps = acaps;
lc->admin_caps = acaps;
lc->link_caps = 0;
/**
* For Forward Error Control, we default to whatever the Firmware
* tells us the Link is currently advertising.
*/
lc->auto_fec = fwcap_to_cc_fec(acaps);
lc->requested_fec = FEC_AUTO;
lc->fec = lc->auto_fec;
lc->mdio_addr = mdio_addr;
lc->port_type = port_type;
lc->mod_type = mod_type;
if (lc->pcaps & FW_PORT_CAP32_ANEG) {
lc->acaps = lc->pcaps & ADVERT_MASK;
lc->autoneg = AUTONEG_ENABLE;
lc->requested_fc |= PAUSE_AUTONEG;
} else {
lc->acaps = 0;
lc->autoneg = AUTONEG_DISABLE;
lc->link_ok = 0;
lc->link_down_rc = 0;
/* Turn Tx and Rx pause off by default */
lc->admin_caps &= ~V_FW_PORT_CAP32_FC(M_FW_PORT_CAP32_FC);
lc->admin_caps &= ~V_FW_PORT_CAP32_802_3(M_FW_PORT_CAP32_802_3);
if (lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)
lc->admin_caps &= ~FW_PORT_CAP32_FORCE_PAUSE;
/* Reset MDI to AUTO */
if (lc->pcaps & FW_PORT_CAP32_MDIAUTO) {
lc->admin_caps &= ~V_FW_PORT_CAP32_MDI(M_FW_PORT_CAP32_MDI);
lc->admin_caps |= V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
}
}
@ -5271,12 +5291,11 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
{
fw_port_cap32_t pcaps, acaps;
u32 param, val, pcaps, acaps;
enum fw_port_type port_type;
struct fw_port_cmd cmd;
u8 vivld = 0, vin = 0;
int ret, i, j = 0;
u32 param, val;
int mdio_addr;
u8 addr[6];
@ -5342,11 +5361,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
pi->vin = G_FW_VIID_VIN(pi->viid);
}
pi->port_type = port_type;
pi->mdio_addr = mdio_addr;
pi->mod_type = FW_PORT_MOD_TYPE_NA;
init_link_config(&pi->link_cfg, pcaps, acaps);
t4_init_link_config(pi, pcaps, acaps, mdio_addr, port_type,
FW_PORT_MOD_TYPE_NA);
j++;
}
return 0;

View File

@ -1615,6 +1615,7 @@ struct fw_vi_stats_cmd {
#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_FORCE_PAUSE 0x10000000UL
#define S_FW_PORT_CAP32_SPEED 0
#define M_FW_PORT_CAP32_SPEED 0xfff
@ -1622,8 +1623,16 @@ struct fw_vi_stats_cmd {
#define G_FW_PORT_CAP32_SPEED(x) \
(((x) >> S_FW_PORT_CAP32_SPEED) & M_FW_PORT_CAP32_SPEED)
#define S_FW_PORT_CAP32_FC 16
#define M_FW_PORT_CAP32_FC 0x3
#define V_FW_PORT_CAP32_FC(x) ((x) << S_FW_PORT_CAP32_FC)
#define S_FW_PORT_CAP32_802_3 18
#define M_FW_PORT_CAP32_802_3 0x3
#define V_FW_PORT_CAP32_802_3(x) ((x) << S_FW_PORT_CAP32_802_3)
enum fw_port_mdi32 {
FW_PORT_CAP32_MDI_AUTO,
FW_PORT_CAP32_MDI_AUTO = 1,
};
#define S_FW_PORT_CAP32_MDI 21

View File

@ -768,9 +768,8 @@ int t4vf_port_init(struct adapter *adapter)
{
struct fw_port_cmd port_cmd, port_rpl, rpl;
struct fw_vi_cmd vi_cmd, vi_rpl;
fw_port_cap32_t pcaps, acaps;
u32 param, val, pcaps, acaps;
enum fw_port_type port_type;
u32 param, val;
int mdio_addr;
int ret, i;
@ -844,10 +843,8 @@ int t4vf_port_init(struct adapter *adapter)
pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
p->port_type = port_type;
p->mdio_addr = mdio_addr;
p->mod_type = FW_PORT_MOD_TYPE_NA;
init_link_config(&p->link_cfg, pcaps, acaps);
t4_init_link_config(p, pcaps, acaps, mdio_addr, port_type,
FW_PORT_MOD_TYPE_NA);
}
return 0;
}

View File

@ -193,11 +193,12 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
int wait_to_complete)
{
struct port_info *pi = eth_dev->data->dev_private;
struct adapter *adapter = pi->adapter;
struct sge *s = &adapter->sge;
struct rte_eth_link new_link = { 0 };
unsigned int i, work_done, budget = 32;
struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
struct rte_eth_link new_link = { 0 };
u8 old_link = pi->link_cfg.link_ok;
struct sge *s = &adapter->sge;
for (i = 0; i < CXGBE_LINK_STATUS_POLL_CNT; i++) {
if (!s->fw_evtq.desc)
@ -218,9 +219,9 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
new_link.link_status = cxgbe_force_linkup(adapter) ?
ETH_LINK_UP : pi->link_cfg.link_ok;
new_link.link_autoneg = pi->link_cfg.autoneg;
new_link.link_autoneg = (lc->link_caps & FW_PORT_CAP32_ANEG) ? 1 : 0;
new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
new_link.link_speed = pi->link_cfg.speed;
new_link.link_speed = t4_fwcap_to_speed(lc->link_caps);
return rte_eth_linkstatus_set(eth_dev, &new_link);
}
@ -787,11 +788,17 @@ static int cxgbe_flow_ctrl_get(struct rte_eth_dev *eth_dev,
{
struct port_info *pi = eth_dev->data->dev_private;
struct link_config *lc = &pi->link_cfg;
int rx_pause, tx_pause;
u8 rx_pause = 0, tx_pause = 0;
u32 caps = lc->link_caps;
fc_conf->autoneg = lc->fc & PAUSE_AUTONEG;
rx_pause = lc->fc & PAUSE_RX;
tx_pause = lc->fc & PAUSE_TX;
if (caps & FW_PORT_CAP32_ANEG)
fc_conf->autoneg = 1;
if (caps & FW_PORT_CAP32_FC_TX)
tx_pause = 1;
if (caps & FW_PORT_CAP32_FC_RX)
rx_pause = 1;
if (rx_pause && tx_pause)
fc_conf->mode = RTE_FC_FULL;
@ -808,30 +815,39 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
struct rte_eth_fc_conf *fc_conf)
{
struct port_info *pi = eth_dev->data->dev_private;
struct adapter *adapter = pi->adapter;
struct link_config *lc = &pi->link_cfg;
u32 new_caps = lc->admin_caps;
u8 tx_pause = 0, rx_pause = 0;
int ret;
if (lc->pcaps & FW_PORT_CAP32_ANEG) {
if (fc_conf->autoneg)
lc->requested_fc |= PAUSE_AUTONEG;
else
lc->requested_fc &= ~PAUSE_AUTONEG;
if (fc_conf->mode == RTE_FC_FULL) {
tx_pause = 1;
rx_pause = 1;
} else if (fc_conf->mode == RTE_FC_TX_PAUSE) {
tx_pause = 1;
} else if (fc_conf->mode == RTE_FC_RX_PAUSE) {
rx_pause = 1;
}
if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
(fc_conf->mode & RTE_FC_RX_PAUSE))
lc->requested_fc |= PAUSE_RX;
else
lc->requested_fc &= ~PAUSE_RX;
ret = t4_set_link_pause(pi, fc_conf->autoneg, tx_pause,
rx_pause, &new_caps);
if (ret != 0)
return ret;
if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
(fc_conf->mode & RTE_FC_TX_PAUSE))
lc->requested_fc |= PAUSE_TX;
else
lc->requested_fc &= ~PAUSE_TX;
if (!fc_conf->autoneg) {
if (lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)
new_caps |= FW_PORT_CAP32_FORCE_PAUSE;
} else {
new_caps &= ~FW_PORT_CAP32_FORCE_PAUSE;
}
return t4_link_l1cfg(adapter, adapter->mbox, pi->tx_chan,
&pi->link_cfg);
if (new_caps != lc->admin_caps) {
ret = t4_link_l1cfg(pi, new_caps);
if (ret == 0)
lc->admin_caps = new_caps;
}
return ret;
}
const uint32_t *

View File

@ -732,7 +732,7 @@ void cxgbe_print_port_info(struct adapter *adap)
--bufp;
sprintf(bufp, "BASE-%s",
t4_get_port_type_description(
(enum fw_port_type)pi->port_type));
(enum fw_port_type)pi->link_cfg.port_type));
dev_info(adap,
" " PCI_PRI_FMT " Chelsio rev %d %s %s\n",
@ -1575,23 +1575,23 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
const struct port_info *pi = adap2pinfo(adap, port_id);
if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_NONE)
dev_info(adap, "Port%d: port module unplugged\n", pi->port_id);
else if (pi->mod_type < ARRAY_SIZE(mod_str))
else if (pi->link_cfg.mod_type < ARRAY_SIZE(mod_str))
dev_info(adap, "Port%d: %s port module inserted\n", pi->port_id,
mod_str[pi->mod_type]);
else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
mod_str[pi->link_cfg.mod_type]);
else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
dev_info(adap, "Port%d: unsupported port module inserted\n",
pi->port_id);
else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
dev_info(adap, "Port%d: unknown port module inserted\n",
pi->port_id);
else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR)
else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_ERROR)
dev_info(adap, "Port%d: transceiver module error\n",
pi->port_id);
else
dev_info(adap, "Port%d: unknown module type %d inserted\n",
pi->port_id, pi->mod_type);
pi->port_id, pi->link_cfg.mod_type);
}
bool cxgbe_force_linkup(struct adapter *adap)
@ -1636,8 +1636,7 @@ int cxgbe_link_start(struct port_info *pi)
}
}
if (ret == 0 && is_pf4(adapter))
ret = t4_link_l1cfg(adapter, adapter->mbox, pi->tx_chan,
&pi->link_cfg);
ret = t4_link_l1cfg(pi, pi->link_cfg.admin_caps);
if (ret == 0) {
/*
* Enabling a Virtual Interface can result in an interrupt
@ -1905,7 +1904,7 @@ void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps)
{
*speed_caps = 0;
fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.pcaps,
fw_caps_to_speed_caps(pi->link_cfg.port_type, pi->link_cfg.pcaps,
speed_caps);
if (!(pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG))