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 {
/* 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 requested_speed; /* speed (Mb/s) user has requested */
- u32 speed; /* actual link speed (Mb/s) */
-
- enum cc_pause requested_fc; /* flow control user has requested */
- enum cc_pause fc; /* actual link flow control */
+ u32 pcaps; /* Physically supported link caps */
+ u32 acaps; /* Advertised link caps */
- 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 */
+ u32 link_caps; /* Current link caps */
+ u32 admin_caps; /* Admin configured link caps */
- unsigned char autoneg; /* autonegotiating? */
+ u8 mdio_addr; /* Address of the PHY */
+ u8 port_type; /* Firmware port type */
+ u8 mod_type; /* Firmware module type */
- 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"
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,
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);
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
* - 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;
}
/**
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 { \
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
{
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.
*/
pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
acaps = be32_to_cpu(cmd->u.info32.acaps32);
- linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
-
- fec = fwcap_to_cc_fec(acaps);
-
- fc = fwcap_to_cc_pause(linkattr);
- speed = fwcap_to_speed(linkattr);
+ link_caps = be32_to_cpu(cmd->u.info32.linkattr32);
- 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",
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;
-
- 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;
- }
+ lc->acaps = acaps;
+ lc->link_caps = link_caps;
+ }
+
+ 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);
}
}
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;
-
- 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->mdio_addr = mdio_addr;
+ lc->port_type = port_type;
+ lc->mod_type = mod_type;
+
+ 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);
}
}
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];
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;
int wait_to_complete)
{
struct port_info *pi = eth_dev->data->dev_private;
+ unsigned int i, work_done, budget = 32;
+ struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
- struct sge *s = &adapter->sge;
struct rte_eth_link new_link = { 0 };
- unsigned int i, work_done, budget = 32;
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)
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);
}
{
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;
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;
+ }
+
+ if (new_caps != lc->admin_caps) {
+ ret = t4_link_l1cfg(pi, new_caps);
+ if (ret == 0)
+ lc->admin_caps = new_caps;
+ }
- return t4_link_l1cfg(adapter, adapter->mbox, pi->tx_chan,
- &pi->link_cfg);
+ return ret;
}
const uint32_t *