|
Thomas Bogendoerfer |
3237e1 |
From: Ganesh Goudar <ganeshgr@chelsio.com>
|
|
Thomas Bogendoerfer |
3237e1 |
Date: Sun, 20 Aug 2017 14:15:51 +0530
|
|
Thomas Bogendoerfer |
3237e1 |
Subject: cxgb4/cxgbvf: Handle 32-bit fw port capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
Patch-mainline: v4.14-rc1
|
|
Thomas Bogendoerfer |
3237e1 |
Git-commit: c3168cabe1af2683475d0e3048220c04b7fa4f51
|
|
Thomas Bogendoerfer |
3237e1 |
References: bsc#1046540 FATE#322930 bsc#1046542 FATE#322928
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
Implement new 32-bit Firmware Port Capabilities in order to
|
|
Thomas Bogendoerfer |
3237e1 |
handle new speeds which couldn't be represented in the old 16-bit
|
|
Thomas Bogendoerfer |
3237e1 |
Firmware Port Capabilities values.
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
Based on the original work of Casey Leedom <leedom@chelsio.com>
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
|
|
Thomas Bogendoerfer |
3237e1 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Thomas Bogendoerfer |
3237e1 |
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
|
|
Thomas Bogendoerfer |
3237e1 |
---
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 43 +
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 98 ++-
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 88 +--
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 578 +++++++++++++++-----
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 175 ++++++
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 50 +
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 86 +-
|
|
Thomas Bogendoerfer |
3237e1 |
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 458 ++++++++++++---
|
|
Thomas Bogendoerfer |
3237e1 |
8 files changed, 1220 insertions(+), 356 deletions(-)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -104,13 +104,13 @@ enum dev_state {
|
|
Thomas Bogendoerfer |
3237e1 |
DEV_STATE_ERR
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-enum {
|
|
Thomas Bogendoerfer |
3237e1 |
+enum cc_pause {
|
|
Thomas Bogendoerfer |
3237e1 |
PAUSE_RX = 1 << 0,
|
|
Thomas Bogendoerfer |
3237e1 |
PAUSE_TX = 1 << 1,
|
|
Thomas Bogendoerfer |
3237e1 |
PAUSE_AUTONEG = 1 << 2
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-enum {
|
|
Thomas Bogendoerfer |
3237e1 |
+enum cc_fec {
|
|
Thomas Bogendoerfer |
3237e1 |
FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
|
|
Thomas Bogendoerfer |
3237e1 |
FEC_RS = 1 << 1, /* Reed-Solomon */
|
|
Thomas Bogendoerfer |
3237e1 |
FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -366,6 +366,7 @@ struct adapter_params {
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int max_ordird_qp; /* Max read depth per RDMA QP */
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int max_ird_adapter; /* Max read depth per adapter */
|
|
Thomas Bogendoerfer |
3237e1 |
bool fr_nsmr_tpte_wr_support; /* FW support for FR_NSMR_TPTE_WR */
|
|
Thomas Bogendoerfer |
3237e1 |
+ u8 fw_caps_support; /* 32-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* MPS Buffer Group Map[per Port]. Bit i is set if buffer group i is
|
|
Thomas Bogendoerfer |
3237e1 |
* used by the Port
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -439,18 +440,34 @@ struct trace_params {
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned char port;
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+/* Firmware Port Capabilities types. */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
|
|
Thomas Bogendoerfer |
3237e1 |
+typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+enum fw_caps {
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+};
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
struct link_config {
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned short supported; /* link capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned short advertising; /* advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned short lp_advertising; /* peer advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int requested_speed; /* speed user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int speed; /* actual link speed */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char requested_fc; /* flow control user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char fc; /* actual link flow control */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char auto_fec; /* Forward Error Correction: */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char requested_fec; /* "automatic" (IEEE 802.3), */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char fec; /* requested, and actual in use */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps; /* link capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t def_acaps; /* default advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t acaps; /* advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t lpacaps; /* peer advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t speed_caps; /* speed(s) user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int speed; /* actual link speed (Mb/s) */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause requested_fc; /* flow control user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause fc; /* actual link flow control */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec requested_fec; /* Forward Error Correction: */
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec fec; /* requested and actual in use */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned char autoneg; /* autonegotiating? */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned char link_ok; /* link up? */
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned char link_down_rc; /* link down reason */
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1580,6 +1597,8 @@ int t4_ofld_eq_free(struct adapter *adap
|
|
Thomas Bogendoerfer |
3237e1 |
int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox);
|
|
Thomas Bogendoerfer |
3237e1 |
void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4_update_port_info(struct port_info *pi);
|
|
Thomas Bogendoerfer |
3237e1 |
+int t4_get_link_params(struct port_info *pi, unsigned int *link_okp,
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int *speedp, unsigned int *mtup);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
void t4_db_full(struct adapter *adapter);
|
|
Thomas Bogendoerfer |
3237e1 |
void t4_db_dropped(struct adapter *adapter);
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -533,17 +533,23 @@ static int from_fw_port_mod_type(enum fw
|
|
Thomas Bogendoerfer |
3237e1 |
static unsigned int speed_to_fw_caps(int speed)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 100)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_100M;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_100M;
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 1000)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_1G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_1G;
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 10000)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_10G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_10G;
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 25000)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_25G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_25G;
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 40000)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_40G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_40G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (speed == 50000)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_50G;
|
|
Thomas Bogendoerfer |
3237e1 |
if (speed == 100000)
|
|
Thomas Bogendoerfer |
3237e1 |
- return FW_PORT_CAP_SPEED_100G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_100G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (speed == 200000)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_200G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (speed == 400000)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_400G;
|
|
Thomas Bogendoerfer |
3237e1 |
return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -560,12 +566,13 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int fw_caps,
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned long *link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- #define SET_LMM(__lmm_name) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name \
|
|
Thomas Bogendoerfer |
3237e1 |
- ## _BIT, link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define SET_LMM(__lmm_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
do { \
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_caps & FW_PORT_CAP_ ## __fw_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
SET_LMM(__lmm_name); \
|
|
Thomas Bogendoerfer |
3237e1 |
} while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -645,7 +652,10 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
case FW_PORT_TYPE_KR4_100G:
|
|
Thomas Bogendoerfer |
3237e1 |
case FW_PORT_TYPE_CR4_QSFP:
|
|
Thomas Bogendoerfer |
3237e1 |
SET_LMM(FIBRE);
|
|
Thomas Bogendoerfer |
3237e1 |
- SET_LMM(100000baseCR4_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_TO_LMM(SPEED_100G, 100000baseCR4_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
default:
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -663,8 +673,7 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
* lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
* capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
- *
|
|
Thomas Bogendoerfer |
3237e1 |
- * @link_mode_mask: ethtool Link Mode Mask
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @et_lmm: ethtool Link Mode Mask
|
|
Thomas Bogendoerfer |
3237e1 |
*
|
|
Thomas Bogendoerfer |
3237e1 |
* Translate ethtool Link Mode Mask into a Firmware Port capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
* value.
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -677,7 +686,7 @@ static unsigned int lmm_to_fw_caps(const
|
|
Thomas Bogendoerfer |
3237e1 |
do { \
|
|
Thomas Bogendoerfer |
3237e1 |
if (test_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
|
|
Thomas Bogendoerfer |
3237e1 |
link_mode_mask)) \
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps |= FW_PORT_CAP_ ## __fw_name; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps |= FW_PORT_CAP32_ ## __fw_name; \
|
|
Thomas Bogendoerfer |
3237e1 |
} while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
LMM_TO_FW_CAPS(100baseT_Full, SPEED_100M);
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -685,6 +694,7 @@ static unsigned int lmm_to_fw_caps(const
|
|
Thomas Bogendoerfer |
3237e1 |
LMM_TO_FW_CAPS(10000baseT_Full, SPEED_10G);
|
|
Thomas Bogendoerfer |
3237e1 |
LMM_TO_FW_CAPS(40000baseSR4_Full, SPEED_40G);
|
|
Thomas Bogendoerfer |
3237e1 |
LMM_TO_FW_CAPS(25000baseCR_Full, SPEED_25G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ LMM_TO_FW_CAPS(50000baseCR2_Full, SPEED_50G);
|
|
Thomas Bogendoerfer |
3237e1 |
LMM_TO_FW_CAPS(100000baseCR4_Full, SPEED_100G);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
#undef LMM_TO_FW_CAPS
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -698,10 +708,6 @@ static int get_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = netdev_priv(dev);
|
|
Thomas Bogendoerfer |
3237e1 |
struct ethtool_link_settings *base = &link_ksettings->base;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
|
|
Thomas Bogendoerfer |
3237e1 |
- ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
- ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
/* For the nonce, the Firmware doesn't send up Port State changes
|
|
Thomas Bogendoerfer |
3237e1 |
* when the Virtual Interface attached to the Port is down. So
|
|
Thomas Bogendoerfer |
3237e1 |
* if it's down, let's grab any changes.
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -709,6 +715,10 @@ static int get_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
if (!netif_running(dev))
|
|
Thomas Bogendoerfer |
3237e1 |
(void)t4_update_port_info(pi);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
base->port = from_fw_port_mod_type(pi->port_type, pi->mod_type);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (pi->mdio_addr >= 0) {
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -721,11 +731,11 @@ static int get_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
base->mdio_support = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.supported,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.supported);
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.lp_advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.lp_advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (netif_carrier_ok(dev)) {
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -736,8 +746,24 @@ static int get_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
base->duplex = DUPLEX_UNKNOWN;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.fc & PAUSE_RX) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.fc & PAUSE_TX) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_add_link_mode(link_ksettings,
|
|
Thomas Bogendoerfer |
3237e1 |
+ advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ Pause);
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_add_link_mode(link_ksettings,
|
|
Thomas Bogendoerfer |
3237e1 |
+ advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ Asym_Pause);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else if (pi->link_cfg.fc & PAUSE_TX) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ ethtool_link_ksettings_add_link_mode(link_ksettings,
|
|
Thomas Bogendoerfer |
3237e1 |
+ advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ Asym_Pause);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
base->autoneg = pi->link_cfg.autoneg;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
|
Thomas Bogendoerfer |
3237e1 |
supported, Autoneg);
|
|
Thomas Bogendoerfer |
3237e1 |
if (pi->link_cfg.autoneg)
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -748,8 +774,7 @@ static int get_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
static int set_link_ksettings(struct net_device *dev,
|
|
Thomas Bogendoerfer |
3237e1 |
- const struct ethtool_link_ksettings
|
|
Thomas Bogendoerfer |
3237e1 |
- *link_ksettings)
|
|
Thomas Bogendoerfer |
3237e1 |
+ const struct ethtool_link_ksettings *link_ksettings)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = netdev_priv(dev);
|
|
Thomas Bogendoerfer |
3237e1 |
struct link_config *lc = &pi->link_cfg;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -762,12 +787,12 @@ static int set_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
if (base->duplex != DUPLEX_FULL)
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (!(lc->supported & FW_PORT_CAP_ANEG)) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
|
|
Thomas Bogendoerfer |
3237e1 |
/* PHY offers a single speed. See if that's what's
|
|
Thomas Bogendoerfer |
3237e1 |
* being requested.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
if (base->autoneg == AUTONEG_DISABLE &&
|
|
Thomas Bogendoerfer |
3237e1 |
- (lc->supported & speed_to_fw_caps(base->speed)))
|
|
Thomas Bogendoerfer |
3237e1 |
+ (lc->pcaps & speed_to_fw_caps(base->speed)))
|
|
Thomas Bogendoerfer |
3237e1 |
return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -776,18 +801,17 @@ static int set_link_ksettings(struct net
|
|
Thomas Bogendoerfer |
3237e1 |
if (base->autoneg == AUTONEG_DISABLE) {
|
|
Thomas Bogendoerfer |
3237e1 |
fw_caps = speed_to_fw_caps(base->speed);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (!(lc->supported & fw_caps))
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!(lc->pcaps & fw_caps))
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->requested_speed = fw_caps;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = fw_caps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
} else {
|
|
Thomas Bogendoerfer |
3237e1 |
fw_caps =
|
|
Thomas Bogendoerfer |
3237e1 |
- lmm_to_fw_caps(link_ksettings->link_modes.advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- if (!(lc->supported & fw_caps))
|
|
Thomas Bogendoerfer |
3237e1 |
+ lmm_to_fw_caps(link_ksettings->link_modes.advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!(lc->pcaps & fw_caps))
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->requested_speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = fw_caps | FW_PORT_CAP_ANEG;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = fw_caps | FW_PORT_CAP32_ANEG;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
lc->autoneg = base->autoneg;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -806,9 +830,9 @@ static inline unsigned int fwcap_to_eth_
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int eth_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_fec & FW_PORT_CAP_FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
eth_fec |= ETHTOOL_FEC_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
eth_fec |= ETHTOOL_FEC_BASER;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* if nothing is set, then FEC is off */
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -864,7 +888,7 @@ static int get_fecparam(struct net_devic
|
|
Thomas Bogendoerfer |
3237e1 |
* always support IEEE 802.3 "automatic" selection of Link FEC type if
|
|
Thomas Bogendoerfer |
3237e1 |
* any FEC is supported.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
- fec->fec = fwcap_to_eth_fec(lc->supported);
|
|
Thomas Bogendoerfer |
3237e1 |
+ fec->fec = fwcap_to_eth_fec(lc->pcaps);
|
|
Thomas Bogendoerfer |
3237e1 |
if (fec->fec != ETHTOOL_FEC_OFF)
|
|
Thomas Bogendoerfer |
3237e1 |
fec->fec |= ETHTOOL_FEC_AUTO;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -917,7 +941,7 @@ static int set_pauseparam(struct net_dev
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (epause->autoneg == AUTONEG_DISABLE)
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (lc->supported & FW_PORT_CAP_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+ else if (lc->pcaps & FW_PORT_CAP32_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc = PAUSE_AUTONEG;
|
|
Thomas Bogendoerfer |
3237e1 |
else
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -530,15 +530,22 @@ static int fwevtq_handler(struct sge_rsp
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_CMD_ACTION_G(ntohl(pcmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (cmd == FW_PORT_CMD &&
|
|
Thomas Bogendoerfer |
3237e1 |
- action == FW_PORT_ACTION_GET_PORT_INFO) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ (action == FW_PORT_ACTION_GET_PORT_INFO ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ action == FW_PORT_ACTION_GET_PORT_INFO32)) {
|
|
Thomas Bogendoerfer |
3237e1 |
int port = FW_PORT_CMD_PORTID_G(
|
|
Thomas Bogendoerfer |
3237e1 |
be32_to_cpu(pcmd->op_to_portid));
|
|
Thomas Bogendoerfer |
3237e1 |
- struct net_device *dev =
|
|
Thomas Bogendoerfer |
3237e1 |
- q->adap->port[q->adap->chan_map[port]];
|
|
Thomas Bogendoerfer |
3237e1 |
- int state_input = ((pcmd->u.info.dcbxdis_pkd &
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_DCBXDIS_F)
|
|
Thomas Bogendoerfer |
3237e1 |
- ? CXGB4_DCB_INPUT_FW_DISABLED
|
|
Thomas Bogendoerfer |
3237e1 |
- : CXGB4_DCB_INPUT_FW_ENABLED);
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct net_device *dev;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int dcbxdis, state_input;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev = q->adap->port[q->adap->chan_map[port]];
|
|
Thomas Bogendoerfer |
3237e1 |
+ dcbxdis = (action == FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? !!(pcmd->u.info.dcbxdis_pkd &
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_DCBXDIS_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ : !!(pcmd->u.info32.lstatus32_to_cbllen32 &
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_DCBXDIS32_F));
|
|
Thomas Bogendoerfer |
3237e1 |
+ state_input = (dcbxdis
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? CXGB4_DCB_INPUT_FW_DISABLED
|
|
Thomas Bogendoerfer |
3237e1 |
+ : CXGB4_DCB_INPUT_FW_ENABLED);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
cxgb4_dcb_state_fsm(dev, state_input);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2672,11 +2679,10 @@ static int cxgb_set_vf_rate(struct net_d
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = netdev_priv(dev);
|
|
Thomas Bogendoerfer |
3237e1 |
struct adapter *adap = pi->adapter;
|
|
Thomas Bogendoerfer |
3237e1 |
- struct fw_port_cmd port_cmd, port_rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
- u32 link_status, speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int link_ok, speed, mtu;
|
|
Thomas Bogendoerfer |
3237e1 |
u32 fw_pfvf, fw_class;
|
|
Thomas Bogendoerfer |
3237e1 |
int class_id = vf;
|
|
Thomas Bogendoerfer |
3237e1 |
- int link_ok, ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
u16 pktsize;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (vf >= adap->num_vfs)
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2688,41 +2694,18 @@ static int cxgb_set_vf_rate(struct net_d
|
|
Thomas Bogendoerfer |
3237e1 |
min_tx_rate, vf);
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
- /* Retrieve link details for VF port */
|
|
Thomas Bogendoerfer |
3237e1 |
- memset(&port_cmd, 0, sizeof(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
- port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_CMD_REQUEST_F |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_PORTID_V(pi->port_id));
|
|
Thomas Bogendoerfer |
3237e1 |
- port_cmd.action_to_len16 =
|
|
Thomas Bogendoerfer |
3237e1 |
- cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
- ret = t4_wr_mbox(adap, adap->mbox, &port_cmd, sizeof(port_cmd),
|
|
Thomas Bogendoerfer |
3237e1 |
- &port_rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4_get_link_params(pi, &link_ok, &speed, &mtu);
|
|
Thomas Bogendoerfer |
3237e1 |
if (ret != FW_SUCCESS) {
|
|
Thomas Bogendoerfer |
3237e1 |
dev_err(adap->pdev_dev,
|
|
Thomas Bogendoerfer |
3237e1 |
- "Failed to get link status for VF %d\n", vf);
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Failed to get link information for VF %d\n", vf);
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
- link_status = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
- link_ok = (link_status & FW_PORT_CMD_LSTATUS_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
if (!link_ok) {
|
|
Thomas Bogendoerfer |
3237e1 |
dev_err(adap->pdev_dev, "Link down for VF %d\n", vf);
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
- /* Determine link speed */
|
|
Thomas Bogendoerfer |
3237e1 |
- if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 1000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 10000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 25000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 40000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100000;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (max_tx_rate > speed) {
|
|
Thomas Bogendoerfer |
3237e1 |
dev_err(adap->pdev_dev,
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2730,7 +2713,8 @@ static int cxgb_set_vf_rate(struct net_d
|
|
Thomas Bogendoerfer |
3237e1 |
max_tx_rate, vf, speed);
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
- pktsize = be16_to_cpu(port_rpl.u.info.mtu);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ pktsize = mtu;
|
|
Thomas Bogendoerfer |
3237e1 |
/* subtract ethhdr size and 4 bytes crc since, f/w appends it */
|
|
Thomas Bogendoerfer |
3237e1 |
pktsize = pktsize - sizeof(struct ethhdr) - 4;
|
|
Thomas Bogendoerfer |
3237e1 |
/* subtract ipv4 hdr size, tcp hdr size to get typical IPv4 MSS size */
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2741,7 +2725,7 @@ static int cxgb_set_vf_rate(struct net_d
|
|
Thomas Bogendoerfer |
3237e1 |
SCHED_CLASS_MODE_CLASS,
|
|
Thomas Bogendoerfer |
3237e1 |
SCHED_CLASS_RATEUNIT_BITS,
|
|
Thomas Bogendoerfer |
3237e1 |
SCHED_CLASS_RATEMODE_ABS,
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->port_id, class_id, 0,
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->tx_chan, class_id, 0,
|
|
Thomas Bogendoerfer |
3237e1 |
max_tx_rate * 1000, 0, pktsize);
|
|
Thomas Bogendoerfer |
3237e1 |
if (ret) {
|
|
Thomas Bogendoerfer |
3237e1 |
dev_err(adap->pdev_dev, "Err %d for Traffic Class config\n",
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -4208,8 +4192,9 @@ static inline bool is_x_10g_port(const s
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int speeds, high_speeds;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported));
|
|
Thomas Bogendoerfer |
3237e1 |
- high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ speeds = FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_G(lc->pcaps));
|
|
Thomas Bogendoerfer |
3237e1 |
+ high_speeds = speeds &
|
|
Thomas Bogendoerfer |
3237e1 |
+ ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return high_speeds != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -4590,18 +4575,24 @@ static void print_port_info(const struct
|
|
Thomas Bogendoerfer |
3237e1 |
else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_8_0GB)
|
|
Thomas Bogendoerfer |
3237e1 |
spd = " 8 GT/s";
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100M)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "100M/");
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_1G)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "1G/");
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_10G)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "10G/");
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_25G)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "25G/");
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_40G)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "40G/");
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_50G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ bufp += sprintf(bufp, "50G/");
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100G)
|
|
Thomas Bogendoerfer |
3237e1 |
bufp += sprintf(bufp, "100G/");
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_200G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ bufp += sprintf(bufp, "200G/");
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_400G)
|
|
Thomas Bogendoerfer |
3237e1 |
+ bufp += sprintf(bufp, "400G/");
|
|
Thomas Bogendoerfer |
3237e1 |
if (bufp != buf)
|
|
Thomas Bogendoerfer |
3237e1 |
--bufp;
|
|
Thomas Bogendoerfer |
3237e1 |
sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type));
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -4707,10 +4698,11 @@ static int config_mgmt_dev(struct pci_de
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
pi = netdev_priv(netdev);
|
|
Thomas Bogendoerfer |
3237e1 |
pi->adapter = adap;
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->port_id = adap->pf % adap->params.nports;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->tx_chan = adap->pf % adap->params.nports;
|
|
Thomas Bogendoerfer |
3237e1 |
SET_NETDEV_DEV(netdev, &pdev->dev);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
adap->port[0] = netdev;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_id = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
err = register_netdev(adap->port[0]);
|
|
Thomas Bogendoerfer |
3237e1 |
if (err) {
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -3835,59 +3835,133 @@ void t4_ulprx_read_la(struct adapter *ad
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @caps16: a 16-bit Port Capabilities value
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Returns the equivalent 32-bit Port Capabilities value.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t caps32 = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define CAP16_TO_CAP32(__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (caps16 & FW_PORT_CAP_##__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ caps32 |= FW_PORT_CAP32_##__cap; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_100M);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_25G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_10G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_40G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_100G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FC_RX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FC_TX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(ANEG);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(MDIX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(MDIAUTO);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FEC_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FEC_BASER_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(802_3_PAUSE);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(802_3_ASM_DIR);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef CAP16_TO_CAP32
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return caps32;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @caps32: a 32-bit Port Capabilities value
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Returns the equivalent 16-bit Port Capabilities value. Note that
|
|
Thomas Bogendoerfer |
3237e1 |
+ * not all 32-bit Port Capabilities can be represented in the 16-bit
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Port Capabilities and some fields/values may not make it.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap16_t caps16 = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define CAP32_TO_CAP16(__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (caps32 & FW_PORT_CAP32_##__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ caps16 |= FW_PORT_CAP_##__cap; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_100M);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_10G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_25G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_40G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(SPEED_100G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(FC_RX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(FC_TX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(802_3_PAUSE);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(802_3_ASM_DIR);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(ANEG);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(MDIX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(MDIAUTO);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(FEC_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP32_TO_CAP16(FEC_BASER_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef CAP32_TO_CAP16
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return caps16;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Translate Firmware Port Capabilities Pause specification to Common Code */
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int cc_pause = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause cc_pause = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_pause & FW_PORT_CAP_FC_RX)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_pause & FW_PORT_CAP32_FC_RX)
|
|
Thomas Bogendoerfer |
3237e1 |
cc_pause |= PAUSE_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_pause & FW_PORT_CAP_FC_TX)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_pause & FW_PORT_CAP32_FC_TX)
|
|
Thomas Bogendoerfer |
3237e1 |
cc_pause |= PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return cc_pause;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Translate Common Code Pause specification into Firmware Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int fw_pause = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t fw_pause = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (cc_pause & PAUSE_RX)
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_pause |= FW_PORT_CAP_FC_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_pause |= FW_PORT_CAP32_FC_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
if (cc_pause & PAUSE_TX)
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_pause |= FW_PORT_CAP_FC_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_pause |= FW_PORT_CAP32_FC_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return fw_pause;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Translate Firmware Forward Error Correction specification to Common Code */
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int cc_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec cc_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_fec & FW_PORT_CAP_FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
cc_fec |= FEC_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
cc_fec |= FEC_BASER_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return cc_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Translate Common Code Forward Error Correction specification to Firmware */
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int fw_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t fw_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (cc_fec & FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_fec |= FW_PORT_CAP_FEC_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_fec |= FW_PORT_CAP32_FEC_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
if (cc_fec & FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return fw_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -3906,13 +3980,13 @@ static inline unsigned int cc_to_fwcap_f
|
|
Thomas Bogendoerfer |
3237e1 |
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
|
|
Thomas Bogendoerfer |
3237e1 |
* otherwise do it later based on the outcome of auto-negotiation.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
-int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
|
|
Thomas Bogendoerfer |
3237e1 |
- struct link_config *lc)
|
|
Thomas Bogendoerfer |
3237e1 |
+int t4_link_l1cfg(struct adapter *adapter, unsigned int mbox,
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int port, struct link_config *lc)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- struct fw_port_cmd c;
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int fw_mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO);
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int fw_fc, cc_fec, fw_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int rcap;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_cmd cmd;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_mdi = FW_PORT_CAP32_MDI_V(FW_PORT_CAP32_MDI_AUTO);
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
lc->link_ok = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -3929,36 +4003,41 @@ int t4_link_l1cfg(struct adapter *adap,
|
|
Thomas Bogendoerfer |
3237e1 |
* use whatever is in the current Requested FEC settings.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
if (lc->requested_fec & FEC_AUTO)
|
|
Thomas Bogendoerfer |
3237e1 |
- cc_fec = lc->auto_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ cc_fec = fwcap_to_cc_fec(lc->def_acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
else
|
|
Thomas Bogendoerfer |
3237e1 |
cc_fec = lc->requested_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
fw_fec = cc_to_fwcap_fec(cc_fec);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Figure out what our Requested Port Capabilities are going to be.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
- if (!(lc->supported & FW_PORT_CAP_ANEG)) {
|
|
Thomas Bogendoerfer |
3237e1 |
- rcap = (lc->supported & ADVERT_MASK) | fw_fc | fw_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->fec = cc_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
} else if (lc->autoneg == AUTONEG_DISABLE) {
|
|
Thomas Bogendoerfer |
3237e1 |
- rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ rcap = lc->speed_caps | fw_fc | fw_fec | fw_mdi;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->fec = cc_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
} else {
|
|
Thomas Bogendoerfer |
3237e1 |
- rcap = lc->advertising | fw_fc | fw_fec | fw_mdi;
|
|
Thomas Bogendoerfer |
3237e1 |
+ rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* And send that on to the Firmware ...
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
- memset(&c, 0, sizeof(c));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_PORTID_V(port));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.action_to_len16 =
|
|
Thomas Bogendoerfer |
3237e1 |
- cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_LEN16(c));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.u.l1cfg.rcap = cpu_to_be32(rcap);
|
|
Thomas Bogendoerfer |
3237e1 |
- return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
|
Thomas Bogendoerfer |
3237e1 |
+ memset(&cmd, 0, sizeof(cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_PORTID_V(port));
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.action_to_len16 =
|
|
Thomas Bogendoerfer |
3237e1 |
+ cpu_to_be32(FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_L1_CFG
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_L1_CFG32) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_LEN16(cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps == FW_CAPS16)
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ else
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
|
|
Thomas Bogendoerfer |
3237e1 |
+ return t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -3980,7 +4059,7 @@ int t4_restart_aneg(struct adapter *adap
|
|
Thomas Bogendoerfer |
3237e1 |
c.action_to_len16 =
|
|
Thomas Bogendoerfer |
3237e1 |
cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
|
|
Thomas Bogendoerfer |
3237e1 |
FW_LEN16(c));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.u.l1cfg.rcap = cpu_to_be32(FW_PORT_CAP_ANEG);
|
|
Thomas Bogendoerfer |
3237e1 |
+ c.u.l1cfg.rcap = cpu_to_be32(FW_PORT_CAP32_ANEG);
|
|
Thomas Bogendoerfer |
3237e1 |
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7697,6 +7776,98 @@ static const char *t4_link_down_rc_str(u
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Return the highest speed set in the port capabilities, in Mb/s.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define TEST_SPEED_RETURN(__caps_speed, __speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ return __speed; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(400G, 400000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(200G, 200000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100G, 100000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(50G, 50000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(40G, 40000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(25G, 25000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(10G, 10000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(1G, 1000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100M, 100);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef TEST_SPEED_RETURN
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * fwcap_to_fwspeed - return highest speed in Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @acaps: advertised Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Get the highest speed for the port from the advertised Port
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Capabilities. It will be either the highest speed from the list of
|
|
Thomas Bogendoerfer |
3237e1 |
+ * speeds or whatever user has set using ethtool.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define TEST_SPEED_RETURN(__caps_speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ return FW_PORT_CAP32_SPEED_##__caps_speed; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(400G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(200G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(50G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(40G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(25G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(10G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100M);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef TEST_SPEED_RETURN
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new
|
|
Thomas Bogendoerfer |
3237e1 |
+ * 32-bit Port Capabilities value.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static fw_port_cap32_t lstatus_to_fwcap(u32 lstatus)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t linkattr = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Unfortunately the format of the Link Status in the old
|
|
Thomas Bogendoerfer |
3237e1 |
+ * 16-bit Port Information message isn't the same as the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * 16-bit Port Capabilities bitfield used everywhere else ...
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_RXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_FC_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_TXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_FC_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_100M;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_1G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_10G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_25G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_40G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_100G;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return linkattr;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
* t4_handle_get_port_info - process a FW reply message
|
|
Thomas Bogendoerfer |
3237e1 |
* @pi: the port info
|
|
Thomas Bogendoerfer |
3237e1 |
* @rpl: start of the FW message
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7705,76 +7876,123 @@ static const char *t4_link_down_rc_str(u
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- const struct fw_port_cmd *p = (const void *)rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int acaps = be16_to_cpu(p->u.info.acap);
|
|
Thomas Bogendoerfer |
3237e1 |
- struct adapter *adap = pi->adapter;
|
|
Thomas Bogendoerfer |
3237e1 |
+ const struct fw_port_cmd *cmd = (const void *)rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct adapter *adapter = pi->adapter;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct link_config *lc = &pi->link_cfg;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int link_ok, linkdnrc;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_type port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_module_type mod_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int speed, fc, fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps, acaps, lpacaps, linkattr;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Extract the various fields from the Port Information message.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ switch (action) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_ACTION_GET_PORT_INFO: {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = (lstatus & FW_PORT_CMD_LSTATUS_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkdnrc = FW_PORT_CMD_LINKDNRC_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mod_type = FW_PORT_CMD_MODTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ lpacaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.lpacap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = lstatus_to_fwcap(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- /* link/module state change message */
|
|
Thomas Bogendoerfer |
3237e1 |
- int speed = 0, fc, fec;
|
|
Thomas Bogendoerfer |
3237e1 |
- struct link_config *lc;
|
|
Thomas Bogendoerfer |
3237e1 |
- u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
- int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- u32 mod = FW_PORT_CMD_MODTYPE_G(stat);
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- /* Unfortunately the format of the Link Status returned by the
|
|
Thomas Bogendoerfer |
3237e1 |
- * Firmware isn't the same as the Firmware Port Capabilities bitfield
|
|
Thomas Bogendoerfer |
3237e1 |
- * used everywhere else ...
|
|
Thomas Bogendoerfer |
3237e1 |
- */
|
|
Thomas Bogendoerfer |
3237e1 |
- fc = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_RXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
- fc |= PAUSE_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_TXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
- fc |= PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_ACTION_GET_PORT_INFO32: {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus32;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- fec = fwcap_to_cc_fec(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lstatus32 = be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = (lstatus32 & FW_PORT_CMD_LSTATUS32_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkdnrc = FW_PORT_CMD_LINKDNRC32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mod_type = FW_PORT_CMD_MODTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = be32_to_cpu(cmd->u.info32.acaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lpacaps = be32_to_cpu(cmd->u.info32.lpacaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 1000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 10000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 25000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 40000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100000;
|
|
Thomas Bogendoerfer |
3237e1 |
+ default:
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev_err(adapter->pdev_dev, "Handle Port Information: Bad Command/Action %#x\n",
|
|
Thomas Bogendoerfer |
3237e1 |
+ be32_to_cpu(cmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
+ return;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- lc = &pi->link_cfg;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fec = fwcap_to_cc_fec(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ fc = fwcap_to_cc_pause(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+ speed = fwcap_to_speed(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (mod_type != pi->mod_type) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* With the newer SFP28 and QSFP28 Transceiver Module Types,
|
|
Thomas Bogendoerfer |
3237e1 |
+ * various fundamental Port Capabilities which used to be
|
|
Thomas Bogendoerfer |
3237e1 |
+ * immutable can now change radically. We can now have
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Speeds, Auto-Negotiation, Forward Error Correction, etc.
|
|
Thomas Bogendoerfer |
3237e1 |
+ * all change based on what Transceiver Module is inserted.
|
|
Thomas Bogendoerfer |
3237e1 |
+ * So we need to record the Physical "Port" Capabilities on
|
|
Thomas Bogendoerfer |
3237e1 |
+ * every Transceiver Module change.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->pcaps = pcaps;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (mod != pi->mod_type) {
|
|
Thomas Bogendoerfer |
3237e1 |
/* When a new Transceiver Module is inserted, the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
- * will examine any Forward Error Correction parameters
|
|
Thomas Bogendoerfer |
3237e1 |
- * present in the Transceiver Module i2c EPROM and determine
|
|
Thomas Bogendoerfer |
3237e1 |
- * the supported and recommended FEC settings from those
|
|
Thomas Bogendoerfer |
3237e1 |
- * based on IEEE 802.3 standards. We always record the
|
|
Thomas Bogendoerfer |
3237e1 |
- * IEEE 802.3 recommended "automatic" settings.
|
|
Thomas Bogendoerfer |
3237e1 |
+ * will examine its i2c EPROM to determine its type and
|
|
Thomas Bogendoerfer |
3237e1 |
+ * general operating parameters including things like Forward
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Error Control, etc. Various IEEE 802.3 standards dictate
|
|
Thomas Bogendoerfer |
3237e1 |
+ * how to interpret these i2c values to determine default
|
|
Thomas Bogendoerfer |
3237e1 |
+ * "sutomatic" settings. We record these for future use when
|
|
Thomas Bogendoerfer |
3237e1 |
+ * the user explicitly requests these standards-based values.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->def_acaps = acaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Some versions of the early T6 Firmware "cheated" when
|
|
Thomas Bogendoerfer |
3237e1 |
+ * handling different Transceiver Modules by changing the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * underlaying Port Type reported to the Host Drivers. As
|
|
Thomas Bogendoerfer |
3237e1 |
+ * such we need to capture whatever Port Type the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * sends us and record it in case it's different from what we
|
|
Thomas Bogendoerfer |
3237e1 |
+ * were told earlier. Unfortunately, since Firmware is
|
|
Thomas Bogendoerfer |
3237e1 |
+ * forever, we'll need to keep this code here forever, but in
|
|
Thomas Bogendoerfer |
3237e1 |
+ * later T6 Firmware it should just be an assignment of the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * same value already recorded.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->auto_fec = fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_type = port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->mod_type = mod;
|
|
Thomas Bogendoerfer |
3237e1 |
- t4_os_portmod_changed(adap, pi->port_id);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->mod_type = mod_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4_os_portmod_changed(adapter, pi->port_id);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
if (link_ok != lc->link_ok || speed != lc->speed ||
|
|
Thomas Bogendoerfer |
3237e1 |
fc != lc->fc || fec != lc->fec) { /* something changed */
|
|
Thomas Bogendoerfer |
3237e1 |
if (!link_ok && lc->link_ok) {
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char rc = FW_PORT_CMD_LINKDNRC_G(stat);
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->link_down_rc = rc;
|
|
Thomas Bogendoerfer |
3237e1 |
- dev_warn(adap->pdev_dev,
|
|
Thomas Bogendoerfer |
3237e1 |
- "Port %d link down, reason: %s\n",
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->port_id, t4_link_down_rc_str(rc));
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->link_down_rc = linkdnrc;
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev_warn(adapter->pdev_dev, "Port %d link down, reason: %s\n",
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->tx_chan, t4_link_down_rc_str(linkdnrc));
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
lc->link_ok = link_ok;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->speed = speed;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->fc = fc;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->fec = fec;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->supported = be16_to_cpu(p->u.info.pcap);
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->lp_advertising = be16_to_cpu(p->u.info.lpacap);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->lpacaps = lpacaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = acaps & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- t4_os_link_changed(adap, pi->port_id, link_ok);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lc->acaps & FW_PORT_CAP32_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->autoneg = AUTONEG_ENABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* When Autoneg is disabled, user needs to set
|
|
Thomas Bogendoerfer |
3237e1 |
+ * single speed.
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Similar to cxgb4_ethtool.c: set_link_ksettings
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = fwcap_to_fwspeed(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->autoneg = AUTONEG_DISABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4_os_link_changed(adapter, pi->port_id, link_ok);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7788,15 +8006,18 @@ void t4_handle_get_port_info(struct port
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
int t4_update_port_info(struct port_info *pi)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = pi->adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
struct fw_port_cmd port_cmd;
|
|
Thomas Bogendoerfer |
3237e1 |
int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
memset(&port_cmd, 0, sizeof(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_PORTID_V(pi->port_id));
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_PORTID_V(pi->tx_chan));
|
|
Thomas Bogendoerfer |
3237e1 |
port_cmd.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_GET_PORT_INFO32) |
|
|
Thomas Bogendoerfer |
3237e1 |
FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
ret = t4_wr_mbox(pi->adapter, pi->adapter->mbox,
|
|
Thomas Bogendoerfer |
3237e1 |
&port_cmd, sizeof(port_cmd), &port_cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7808,6 +8029,65 @@ int t4_update_port_info(struct port_info
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * t4_get_link_params - retrieve basic link parameters for given port
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @pi: the port
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @link_okp: value return pointer for link up/down
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @speedp: value return pointer for speed (Mb/s)
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @mtup: value return pointer for mtu
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Retrieves basic link parameters for a port: link up/down, speed (Mb/s),
|
|
Thomas Bogendoerfer |
3237e1 |
+ * and MTU for a specified port. A negative error is returned on
|
|
Thomas Bogendoerfer |
3237e1 |
+ * failure; 0 on success.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+int t4_get_link_params(struct port_info *pi, unsigned int *link_okp,
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int *speedp, unsigned int *mtup)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = pi->adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_cmd port_cmd;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int action, link_ok, speed, mtu;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t linkattr;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ memset(&port_cmd, 0, sizeof(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_PORTID_V(pi->tx_chan));
|
|
Thomas Bogendoerfer |
3237e1 |
+ action = (fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_GET_PORT_INFO32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_cmd.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_ACTION_V(action) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4_wr_mbox(pi->adapter, pi->adapter->mbox,
|
|
Thomas Bogendoerfer |
3237e1 |
+ &port_cmd, sizeof(port_cmd), &port_cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (ret)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (action == FW_PORT_ACTION_GET_PORT_INFO) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus = be32_to_cpu(port_cmd.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = !!(lstatus & FW_PORT_CMD_LSTATUS_F);
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = lstatus_to_fwcap(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mtu = be16_to_cpu(port_cmd.u.info.mtu);
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus32 =
|
|
Thomas Bogendoerfer |
3237e1 |
+ be32_to_cpu(port_cmd.u.info32.lstatus32_to_cbllen32);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = !!(lstatus32 & FW_PORT_CMD_LSTATUS32_F);
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = be32_to_cpu(port_cmd.u.info32.linkattr32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mtu = FW_PORT_CMD_MTU32_G(
|
|
Thomas Bogendoerfer |
3237e1 |
+ be32_to_cpu(port_cmd.u.info32.auxlinfo32_mtu32));
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+ speed = fwcap_to_speed(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ *link_okp = link_ok;
|
|
Thomas Bogendoerfer |
3237e1 |
+ *speedp = fwcap_to_speed(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+ *mtup = mtu;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
* t4_handle_fw_rpl - process a FW reply message
|
|
Thomas Bogendoerfer |
3237e1 |
* @adap: the adapter
|
|
Thomas Bogendoerfer |
3237e1 |
* @rpl: start of the FW message
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7827,7 +8107,9 @@ int t4_handle_fw_rpl(struct adapter *ada
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int action =
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_CMD_ACTION_G(be32_to_cpu(p->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (opcode == FW_PORT_CMD &&
|
|
Thomas Bogendoerfer |
3237e1 |
+ (action == FW_PORT_ACTION_GET_PORT_INFO ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ action == FW_PORT_ACTION_GET_PORT_INFO32)) {
|
|
Thomas Bogendoerfer |
3237e1 |
int i;
|
|
Thomas Bogendoerfer |
3237e1 |
int chan = FW_PORT_CMD_PORTID_G(be32_to_cpu(p->op_to_portid));
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = NULL;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7840,7 +8122,8 @@ int t4_handle_fw_rpl(struct adapter *ada
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
t4_handle_get_port_info(pi, rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
} else {
|
|
Thomas Bogendoerfer |
3237e1 |
- dev_warn(adap->pdev_dev, "Unknown firmware reply %d\n", opcode);
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev_warn(adap->pdev_dev, "Unknown firmware reply %d\n",
|
|
Thomas Bogendoerfer |
3237e1 |
+ opcode);
|
|
Thomas Bogendoerfer |
3237e1 |
return -EINVAL;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -7859,35 +8142,35 @@ static void get_pci_mode(struct adapter
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
* init_link_config - initialize a link's SW state
|
|
Thomas Bogendoerfer |
3237e1 |
- * @lc: structure holding the link state
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @lc: pointer to structure holding the link state
|
|
Thomas Bogendoerfer |
3237e1 |
* @pcaps: link Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
* @acaps: link current Advertised Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
*
|
|
Thomas Bogendoerfer |
3237e1 |
* Initializes the SW state maintained for each link, including the link's
|
|
Thomas Bogendoerfer |
3237e1 |
* capabilities and default speed/flow-control/autonegotiation settings.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
-static void init_link_config(struct link_config *lc, unsigned int pcaps,
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int acaps)
|
|
Thomas Bogendoerfer |
3237e1 |
+static void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t acaps)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->supported = pcaps;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->lp_advertising = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->requested_speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->pcaps = pcaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->def_acaps = acaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->lpacaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* For Forward Error Control, we default to whatever the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
* tells us the Link is currently advertising.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->auto_fec = fwcap_to_cc_fec(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fec = FEC_AUTO;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->fec = lc->auto_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fec = fwcap_to_cc_fec(lc->def_acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- if (lc->supported & FW_PORT_CAP_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = lc->supported & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lc->pcaps & FW_PORT_CAP32_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = lc->pcaps & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->autoneg = AUTONEG_ENABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc |= PAUSE_AUTONEG;
|
|
Thomas Bogendoerfer |
3237e1 |
} else {
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->autoneg = AUTONEG_DISABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -8412,7 +8695,7 @@ int t4_init_rss_mode(struct adapter *ada
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
- * t4_init_portinfo - allocate a virtual interface amd initialize port_info
|
|
Thomas Bogendoerfer |
3237e1 |
+ * t4_init_portinfo - allocate a virtual interface and initialize port_info
|
|
Thomas Bogendoerfer |
3237e1 |
* @pi: the port_info
|
|
Thomas Bogendoerfer |
3237e1 |
* @mbox: mailbox to use for the FW command
|
|
Thomas Bogendoerfer |
3237e1 |
* @port: physical port associated with the VI
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -8428,21 +8711,67 @@ int t4_init_rss_mode(struct adapter *ada
|
|
Thomas Bogendoerfer |
3237e1 |
int t4_init_portinfo(struct port_info *pi, int mbox,
|
|
Thomas Bogendoerfer |
3237e1 |
int port, int pf, int vf, u8 mac[])
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
- struct fw_port_cmd c;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct adapter *adapter = pi->adapter;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_cmd cmd;
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int rss_size;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_type port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int mdio_addr;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps, acaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- memset(&c, 0, sizeof(c));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_PORTID_V(port));
|
|
Thomas Bogendoerfer |
3237e1 |
- c.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_LEN16(c));
|
|
Thomas Bogendoerfer |
3237e1 |
- ret = t4_wr_mbox(pi->adapter, mbox, &c, sizeof(c), &c);
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* If we haven't yet determined whether we're talking to Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * which knows the new 32-bit Port Capabilities, it's time to find
|
|
Thomas Bogendoerfer |
3237e1 |
+ * out now. This will also tell new Firmware to send us Port Status
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Updates using the new 32-bit Port Capabilities version of the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Port Information message.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps == FW_CAPS_UNKNOWN) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 param, val;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
|
|
Thomas Bogendoerfer |
3237e1 |
+ val = 1;
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4_set_params(adapter, mbox, pf, vf, 1, ¶m, &val;;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16);
|
|
Thomas Bogendoerfer |
3237e1 |
+ adapter->params.fw_caps_support = fw_caps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ memset(&cmd, 0, sizeof(cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_PORTID_V(port));
|
|
Thomas Bogendoerfer |
3237e1 |
+ cmd.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_GET_PORT_INFO32) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_LEN16(cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
if (ret)
|
|
Thomas Bogendoerfer |
3237e1 |
return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Extract the various fields from the Port Information message.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps == FW_CAPS16) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus = be32_to_cpu(cmd.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mdio_addr = ((lstatus & FW_PORT_CMD_MDIOCAP_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_CMD_MDIOADDR_G(lstatus)
|
|
Thomas Bogendoerfer |
3237e1 |
+ : -1);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd.u.info.pcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = fwcaps16_to_caps32(be16_to_cpu(cmd.u.info.acap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus32 = be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mdio_addr = ((lstatus32 & FW_PORT_CMD_MDIOCAP32_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_CMD_MDIOADDR32_G(lstatus32)
|
|
Thomas Bogendoerfer |
3237e1 |
+ : -1);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = be32_to_cpu(cmd.u.info32.acaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, mac, &rss_size);
|
|
Thomas Bogendoerfer |
3237e1 |
if (ret < 0)
|
|
Thomas Bogendoerfer |
3237e1 |
return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -8452,14 +8781,11 @@ int t4_init_portinfo(struct port_info *p
|
|
Thomas Bogendoerfer |
3237e1 |
pi->lport = port;
|
|
Thomas Bogendoerfer |
3237e1 |
pi->rss_size = rss_size;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ?
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_MDIOADDR_G(ret) : -1;
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->port_type = FW_PORT_CMD_PTYPE_G(ret);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_type = port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->mdio_addr = mdio_addr;
|
|
Thomas Bogendoerfer |
3237e1 |
pi->mod_type = FW_PORT_MOD_TYPE_NA;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- init_link_config(&pi->link_cfg, be16_to_cpu(c.u.info.pcap),
|
|
Thomas Bogendoerfer |
3237e1 |
- be16_to_cpu(c.u.info.acap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ init_link_config(&pi->link_cfg, pcaps, acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1173,7 +1173,8 @@ enum fw_params_param_pfvf {
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PARAMS_PARAM_PFVF_ACTIVE_FILTER_END = 0x2E,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PARAMS_PARAM_PFVF_ETHOFLD_END = 0x30,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PARAMS_PARAM_PFVF_NCRYPTO_LOOKASIDE = 0x32
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PARAMS_PARAM_PFVF_NCRYPTO_LOOKASIDE = 0x32,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A,
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/*
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2256,6 +2257,7 @@ struct fw_acl_vlan_cmd {
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_ACL_VLAN_CMD_FM_S 6
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+/* old 16-bit port capabilities bitmap (fw_port_cap16_t) */
|
|
Thomas Bogendoerfer |
3237e1 |
enum fw_port_cap {
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_CAP_SPEED_100M = 0x0001,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_CAP_SPEED_1G = 0x0002,
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2291,6 +2293,84 @@ enum fw_port_mdi {
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_PORT_CAP_MDI_S 9
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_PORT_CAP_MDI_V(x) ((x) << FW_PORT_CAP_MDI_S)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_100M 0x00000001UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_1G 0x00000002UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_10G 0x00000004UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_25G 0x00000008UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_40G 0x00000010UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_50G 0x00000020UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_100G 0x00000040UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_200G 0x00000080UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_400G 0x00000100UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_RESERVED1 0x00000200UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_RESERVED2 0x00000400UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_RESERVED3 0x00000800UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_RESERVED1 0x0000f000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_RX 0x00010000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_TX 0x00020000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_PAUSE 0x00040000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_ASM_DIR 0x00080000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_ANEG 0x00100000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDIX 0x00200000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDIAUTO 0x00400000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_RS 0x00800000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_RESERVED1 0x02000000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_RESERVED2 0x04000000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_RESERVED3 0x08000000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_RESERVED2 0xf0000000UL
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_S 0
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_M 0xfff
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_V(x) ((x) << FW_PORT_CAP32_SPEED_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_SPEED_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_SPEED_S) & FW_PORT_CAP32_SPEED_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_S 16
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_M 0x3
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_V(x) ((x) << FW_PORT_CAP32_FC_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FC_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_FC_S) & FW_PORT_CAP32_FC_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_S 18
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_M 0x3
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_V(x) ((x) << FW_PORT_CAP32_802_3_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_802_3_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_802_3_S) & FW_PORT_CAP32_802_3_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_ANEG_S 20
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_ANEG_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_ANEG_V(x) ((x) << FW_PORT_CAP32_ANEG_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_ANEG_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_ANEG_S) & FW_PORT_CAP32_ANEG_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+enum fw_port_mdi32 {
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_MDI_UNCHANGED,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_MDI_AUTO,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_MDI_F_STRAIGHT,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_MDI_F_CROSSOVER
|
|
Thomas Bogendoerfer |
3237e1 |
+};
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDI_S 21
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDI_M 3
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDI_V(x) ((x) << FW_PORT_CAP32_MDI_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_MDI_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_MDI_S) & FW_PORT_CAP32_MDI_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_S 23
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_M 0x1f
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_V(x) ((x) << FW_PORT_CAP32_FEC_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CAP32_FEC_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CAP32_FEC_S) & FW_PORT_CAP32_FEC_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/* macros to isolate various 32-bit Port Capabilities sub-fields */
|
|
Thomas Bogendoerfer |
3237e1 |
+#define CAP32_SPEED(__cap32) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) & __cap32)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define CAP32_FEC(__cap32) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (FW_PORT_CAP32_FEC_V(FW_PORT_CAP32_FEC_M) & __cap32)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
enum fw_port_action {
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_L1_CFG = 0x0001,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_L2_CFG = 0x0002,
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2300,6 +2380,8 @@ enum fw_port_action {
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_DCB_READ_TRANS = 0x0006,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_DCB_READ_RECV = 0x0007,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_DCB_READ_DET = 0x0008,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_ACTION_L1_CFG32 = 0x0009,
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_ACTION_GET_PORT_INFO32 = 0x000a,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012,
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2447,6 +2529,18 @@ struct fw_port_cmd {
|
|
Thomas Bogendoerfer |
3237e1 |
__be64 r12;
|
|
Thomas Bogendoerfer |
3237e1 |
} control;
|
|
Thomas Bogendoerfer |
3237e1 |
} dcb;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_l1cfg32 {
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 rcap32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 r;
|
|
Thomas Bogendoerfer |
3237e1 |
+ } l1cfg32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_info32 {
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 lstatus32_to_cbllen32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 auxlinfo32_mtu32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 linkattr32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 pcaps32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 acaps32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ __be32 lpacaps32;
|
|
Thomas Bogendoerfer |
3237e1 |
+ } info32;
|
|
Thomas Bogendoerfer |
3237e1 |
} u;
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -2555,6 +2649,85 @@ struct fw_port_cmd {
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_PORT_CMD_DCB_VERSION_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
(((x) >> FW_PORT_CMD_DCB_VERSION_S) & FW_PORT_CMD_DCB_VERSION_M)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LSTATUS32_S 31
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LSTATUS32_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LSTATUS32_V(x) ((x) << FW_PORT_CMD_LSTATUS32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LSTATUS32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_LSTATUS32_S) & FW_PORT_CMD_LSTATUS32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LSTATUS32_F FW_PORT_CMD_LSTATUS32_V(1U)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LINKDNRC32_S 28
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LINKDNRC32_M 0x7
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LINKDNRC32_V(x) ((x) << FW_PORT_CMD_LINKDNRC32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_LINKDNRC32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_LINKDNRC32_S) & FW_PORT_CMD_LINKDNRC32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_DCBXDIS32_S 27
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_DCBXDIS32_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_DCBXDIS32_V(x) ((x) << FW_PORT_CMD_DCBXDIS32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_DCBXDIS32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_DCBXDIS32_S) & FW_PORT_CMD_DCBXDIS32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_DCBXDIS32_F FW_PORT_CMD_DCBXDIS32_V(1U)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOCAP32_S 26
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOCAP32_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOCAP32_V(x) ((x) << FW_PORT_CMD_MDIOCAP32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOCAP32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_MDIOCAP32_S) & FW_PORT_CMD_MDIOCAP32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOCAP32_F FW_PORT_CMD_MDIOCAP32_V(1U)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOADDR32_S 21
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOADDR32_M 0x1f
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOADDR32_V(x) ((x) << FW_PORT_CMD_MDIOADDR32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MDIOADDR32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_MDIOADDR32_S) & FW_PORT_CMD_MDIOADDR32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_PORTTYPE32_S 13
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_PORTTYPE32_M 0xff
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_PORTTYPE32_V(x) ((x) << FW_PORT_CMD_PORTTYPE32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_PORTTYPE32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_PORTTYPE32_S) & FW_PORT_CMD_PORTTYPE32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MODTYPE32_S 8
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MODTYPE32_M 0x1f
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MODTYPE32_V(x) ((x) << FW_PORT_CMD_MODTYPE32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MODTYPE32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_MODTYPE32_S) & FW_PORT_CMD_MODTYPE32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_CBLLEN32_S 0
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_CBLLEN32_M 0xff
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_CBLLEN32_V(x) ((x) << FW_PORT_CMD_CBLLEN32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_CBLLEN32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_CBLLEN32_S) & FW_PORT_CMD_CBLLEN32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_AUXLINFO32_S 24
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_AUXLINFO32_M 0xff
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_AUXLINFO32_V(x) ((x) << FW_PORT_CMD_AUXLINFO32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_AUXLINFO32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_AUXLINFO32_S) & FW_PORT_CMD_AUXLINFO32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KX4_S 2
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KX4_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KX4_V(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ ((x) << FW_PORT_AUXLINFO32_KX4_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KX4_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_AUXLINFO32_KX4_S) & FW_PORT_AUXLINFO32_KX4_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KX4_F FW_PORT_AUXLINFO32_KX4_V(1U)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KR_S 1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KR_M 0x1
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KR_V(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ ((x) << FW_PORT_AUXLINFO32_KR_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KR_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_AUXLINFO32_KR_S) & FW_PORT_AUXLINFO32_KR_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_AUXLINFO32_KR_F FW_PORT_AUXLINFO32_KR_V(1U)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MTU32_S 0
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MTU32_M 0xffff
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MTU32_V(x) ((x) << FW_PORT_CMD_MTU32_S)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define FW_PORT_CMD_MTU32_G(x) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ (((x) >> FW_PORT_CMD_MTU32_S) & FW_PORT_CMD_MTU32_M)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
enum fw_port_type {
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_TYPE_FIBER_XFI,
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_TYPE_FIBER_XAUI,
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -182,7 +182,7 @@ void t4vf_os_link_changed(struct adapter
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- switch (pi->link_cfg.fc) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ switch ((int)pi->link_cfg.fc) {
|
|
Thomas Bogendoerfer |
3237e1 |
case PAUSE_RX:
|
|
Thomas Bogendoerfer |
3237e1 |
fc = "RX";
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -191,7 +191,7 @@ void t4vf_os_link_changed(struct adapter
|
|
Thomas Bogendoerfer |
3237e1 |
fc = "TX";
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- case PAUSE_RX|PAUSE_TX:
|
|
Thomas Bogendoerfer |
3237e1 |
+ case PAUSE_RX | PAUSE_TX:
|
|
Thomas Bogendoerfer |
3237e1 |
fc = "RX/TX";
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1213,7 +1213,11 @@ static int from_fw_port_mod_type(enum fw
|
|
Thomas Bogendoerfer |
3237e1 |
} else if (port_type == FW_PORT_TYPE_SFP ||
|
|
Thomas Bogendoerfer |
3237e1 |
port_type == FW_PORT_TYPE_QSFP_10G ||
|
|
Thomas Bogendoerfer |
3237e1 |
port_type == FW_PORT_TYPE_QSA ||
|
|
Thomas Bogendoerfer |
3237e1 |
- port_type == FW_PORT_TYPE_QSFP) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_QSFP ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_CR4_QSFP ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_CR_QSFP ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_CR2_QSFP ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_SFP28) {
|
|
Thomas Bogendoerfer |
3237e1 |
if (mod_type == FW_PORT_MOD_TYPE_LR ||
|
|
Thomas Bogendoerfer |
3237e1 |
mod_type == FW_PORT_MOD_TYPE_SR ||
|
|
Thomas Bogendoerfer |
3237e1 |
mod_type == FW_PORT_MOD_TYPE_ER ||
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1224,6 +1228,9 @@ static int from_fw_port_mod_type(enum fw
|
|
Thomas Bogendoerfer |
3237e1 |
return PORT_DA;
|
|
Thomas Bogendoerfer |
3237e1 |
else
|
|
Thomas Bogendoerfer |
3237e1 |
return PORT_OTHER;
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else if (port_type == FW_PORT_TYPE_KR4_100G ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type == FW_PORT_TYPE_KR_SFP28) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ return PORT_NONE;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
return PORT_OTHER;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1242,12 +1249,13 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int fw_caps,
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned long *link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- #define SET_LMM(__lmm_name) __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name\
|
|
Thomas Bogendoerfer |
3237e1 |
- ## _BIT, link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define SET_LMM(__lmm_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_mode_mask)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
#define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
do { \
|
|
Thomas Bogendoerfer |
3237e1 |
- if (fw_caps & FW_PORT_CAP_ ## __fw_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
|
|
Thomas Bogendoerfer |
3237e1 |
SET_LMM(__lmm_name); \
|
|
Thomas Bogendoerfer |
3237e1 |
} while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1310,6 +1318,16 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
SET_LMM(25000baseCR_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_TYPE_KR_SFP28:
|
|
Thomas Bogendoerfer |
3237e1 |
+ SET_LMM(Backplane);
|
|
Thomas Bogendoerfer |
3237e1 |
+ SET_LMM(25000baseKR_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_TYPE_CR2_QSFP:
|
|
Thomas Bogendoerfer |
3237e1 |
+ SET_LMM(FIBRE);
|
|
Thomas Bogendoerfer |
3237e1 |
+ SET_LMM(50000baseSR2_Full);
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
case FW_PORT_TYPE_KR4_100G:
|
|
Thomas Bogendoerfer |
3237e1 |
case FW_PORT_TYPE_CR4_QSFP:
|
|
Thomas Bogendoerfer |
3237e1 |
SET_LMM(FIBRE);
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1329,12 +1347,18 @@ static void fw_caps_to_lmm(enum fw_port_
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
static int cxgb4vf_get_link_ksettings(struct net_device *dev,
|
|
Thomas Bogendoerfer |
3237e1 |
- struct ethtool_link_ksettings
|
|
Thomas Bogendoerfer |
3237e1 |
- *link_ksettings)
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct ethtool_link_ksettings *link_ksettings)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
- const struct port_info *pi = netdev_priv(dev);
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct port_info *pi = netdev_priv(dev);
|
|
Thomas Bogendoerfer |
3237e1 |
struct ethtool_link_settings *base = &link_ksettings->base;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* For the nonce, the Firmware doesn't send up Port State changes
|
|
Thomas Bogendoerfer |
3237e1 |
+ * when the Virtual Interface attached to the Port is down. So
|
|
Thomas Bogendoerfer |
3237e1 |
+ * if it's down, let's grab any changes.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!netif_running(dev))
|
|
Thomas Bogendoerfer |
3237e1 |
+ (void)t4vf_update_port_info(pi);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
|
|
Thomas Bogendoerfer |
3237e1 |
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1351,11 +1375,11 @@ static int cxgb4vf_get_link_ksettings(st
|
|
Thomas Bogendoerfer |
3237e1 |
base->mdio_support = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.supported,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.supported);
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.lp_advertising,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
|
|
Thomas Bogendoerfer |
3237e1 |
link_ksettings->link_modes.lp_advertising);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (netif_carrier_ok(dev)) {
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1367,7 +1391,7 @@ static int cxgb4vf_get_link_ksettings(st
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
base->autoneg = pi->link_cfg.autoneg;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (pi->link_cfg.supported & FW_PORT_CAP_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
|
Thomas Bogendoerfer |
3237e1 |
supported, Autoneg);
|
|
Thomas Bogendoerfer |
3237e1 |
if (pi->link_cfg.autoneg)
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -104,24 +104,62 @@ struct t4vf_port_stats {
|
|
Thomas Bogendoerfer |
3237e1 |
/*
|
|
Thomas Bogendoerfer |
3237e1 |
* Per-"port" (Virtual Interface) link configuration ...
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
-struct link_config {
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int supported; /* link capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int advertising; /* advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned short lp_advertising; /* peer advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int requested_speed; /* speed user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int speed; /* actual link speed */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char requested_fc; /* flow control user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char fc; /* actual link flow control */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char autoneg; /* autonegotiating? */
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned char link_ok; /* link up? */
|
|
Thomas Bogendoerfer |
3237e1 |
+typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
|
|
Thomas Bogendoerfer |
3237e1 |
+typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+enum fw_caps {
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-enum {
|
|
Thomas Bogendoerfer |
3237e1 |
- PAUSE_RX = 1 << 0,
|
|
Thomas Bogendoerfer |
3237e1 |
- PAUSE_TX = 1 << 1,
|
|
Thomas Bogendoerfer |
3237e1 |
- PAUSE_AUTONEG = 1 << 2
|
|
Thomas Bogendoerfer |
3237e1 |
+enum cc_pause {
|
|
Thomas Bogendoerfer |
3237e1 |
+ PAUSE_RX = 1 << 0,
|
|
Thomas Bogendoerfer |
3237e1 |
+ PAUSE_TX = 1 << 1,
|
|
Thomas Bogendoerfer |
3237e1 |
+ PAUSE_AUTONEG = 1 << 2
|
|
Thomas Bogendoerfer |
3237e1 |
+};
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+enum cc_fec {
|
|
Thomas Bogendoerfer |
3237e1 |
+ FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FEC_RS = 1 << 1, /* Reed-Solomon */
|
|
Thomas Bogendoerfer |
3237e1 |
+ FEC_BASER_RS = 1 << 2, /* BaseR/Reed-Solomon */
|
|
Thomas Bogendoerfer |
3237e1 |
+};
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+struct link_config {
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps; /* link capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t acaps; /* advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t lpacaps; /* peer advertised capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t speed_caps; /* speed(s) user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 speed; /* actual link speed */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause requested_fc; /* flow control user has requested */
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause fc; /* actual link flow control */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec auto_fec; /* Forward Error Correction: */
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec requested_fec; /* "automatic" (IEEE 802.3), */
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec fec; /* requested, and actual in use */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned char autoneg; /* autonegotiating? */
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned char link_ok; /* link up? */
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned char link_down_rc; /* link down reason */
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+/* Return true if the Link Configuration supports "High Speeds" (those greater
|
|
Thomas Bogendoerfer |
3237e1 |
+ * than 1Gb/s).
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline bool is_x_10g_port(const struct link_config *lc)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t speeds, high_speeds;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ speeds = FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_G(lc->pcaps));
|
|
Thomas Bogendoerfer |
3237e1 |
+ high_speeds =
|
|
Thomas Bogendoerfer |
3237e1 |
+ speeds & ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return high_speeds != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
/*
|
|
Thomas Bogendoerfer |
3237e1 |
* General device parameters ...
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -227,6 +265,7 @@ struct adapter_params {
|
|
Thomas Bogendoerfer |
3237e1 |
struct arch_specific_params arch; /* chip specific params */
|
|
Thomas Bogendoerfer |
3237e1 |
enum chip_type chip; /* chip code */
|
|
Thomas Bogendoerfer |
3237e1 |
u8 nports; /* # of Ethernet "ports" */
|
|
Thomas Bogendoerfer |
3237e1 |
+ u8 fw_caps_support; /* 32-bit Port Capabilities */
|
|
Thomas Bogendoerfer |
3237e1 |
};
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/* Firmware Mailbox Command/Reply log. All values are in Host-Endian format.
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -266,24 +305,6 @@ static inline struct mbox_cmd *mbox_cmd_
|
|
Thomas Bogendoerfer |
3237e1 |
#define for_each_port(adapter, iter) \
|
|
Thomas Bogendoerfer |
3237e1 |
for (iter = 0; iter < (adapter)->params.nports; iter++)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline bool is_10g_port(const struct link_config *lc)
|
|
Thomas Bogendoerfer |
3237e1 |
-{
|
|
Thomas Bogendoerfer |
3237e1 |
- return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
-}
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
-/* Return true if the Link Configuration supports "High Speeds" (those greater
|
|
Thomas Bogendoerfer |
3237e1 |
- * than 1Gb/s).
|
|
Thomas Bogendoerfer |
3237e1 |
- */
|
|
Thomas Bogendoerfer |
3237e1 |
-static inline bool is_x_10g_port(const struct link_config *lc)
|
|
Thomas Bogendoerfer |
3237e1 |
-{
|
|
Thomas Bogendoerfer |
3237e1 |
- unsigned int speeds, high_speeds;
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported));
|
|
Thomas Bogendoerfer |
3237e1 |
- high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- return high_speeds != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
-}
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
static inline unsigned int core_ticks_per_usec(const struct adapter *adapter)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
return adapter->params.vpd.cclk / 1000;
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -387,6 +408,7 @@ int t4vf_iq_free(struct adapter *, unsig
|
|
Thomas Bogendoerfer |
3237e1 |
unsigned int);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4vf_eth_eq_free(struct adapter *, unsigned int);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+int t4vf_update_port_info(struct port_info *pi);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4vf_prep_adapter(struct adapter *);
|
|
Thomas Bogendoerfer |
3237e1 |
int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
|
|
Thomas Bogendoerfer |
3237e1 |
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
|
|
Thomas Bogendoerfer |
3237e1 |
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -313,32 +313,130 @@ int t4vf_wr_mbox_core(struct adapter *ad
|
|
Thomas Bogendoerfer |
3237e1 |
return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
-#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CAP_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
+#define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CAP32_ANEG)
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @caps16: a 16-bit Port Capabilities value
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Returns the equivalent 32-bit Port Capabilities value.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t caps32 = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define CAP16_TO_CAP32(__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (caps16 & FW_PORT_CAP_##__cap) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ caps32 |= FW_PORT_CAP32_##__cap; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_100M);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_1G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_25G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_10G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_40G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(SPEED_100G);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FC_RX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FC_TX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(ANEG);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(MDIX);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(MDIAUTO);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FEC_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(FEC_BASER_RS);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(802_3_PAUSE);
|
|
Thomas Bogendoerfer |
3237e1 |
+ CAP16_TO_CAP32(802_3_ASM_DIR);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef CAP16_TO_CAP32
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return caps32;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/* Translate Firmware Pause specification to Common Code */
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_pause cc_pause = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_pause & FW_PORT_CAP32_FC_RX)
|
|
Thomas Bogendoerfer |
3237e1 |
+ cc_pause |= PAUSE_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_pause & FW_PORT_CAP32_FC_TX)
|
|
Thomas Bogendoerfer |
3237e1 |
+ cc_pause |= PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return cc_pause;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/* Translate Firmware Forward Error Correction specification to Common Code */
|
|
Thomas Bogendoerfer |
3237e1 |
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum cc_fec cc_fec = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ cc_fec |= FEC_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ cc_fec |= FEC_BASER_RS;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return cc_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Return the highest speed set in the port capabilities, in Mb/s.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ #define TEST_SPEED_RETURN(__caps_speed, __speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ do { \
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
|
|
Thomas Bogendoerfer |
3237e1 |
+ return __speed; \
|
|
Thomas Bogendoerfer |
3237e1 |
+ } while (0)
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(400G, 400000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(200G, 200000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100G, 100000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(50G, 50000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(40G, 40000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(25G, 25000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(10G, 10000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(1G, 1000);
|
|
Thomas Bogendoerfer |
3237e1 |
+ TEST_SPEED_RETURN(100M, 100);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ #undef TEST_SPEED_RETURN
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/*
|
|
Thomas Bogendoerfer |
3237e1 |
* init_link_config - initialize a link's SW state
|
|
Thomas Bogendoerfer |
3237e1 |
* @lc: structure holding the link state
|
|
Thomas Bogendoerfer |
3237e1 |
- * @caps: link capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @pcaps: link Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @acaps: link current Advertised Port Capabilities
|
|
Thomas Bogendoerfer |
3237e1 |
*
|
|
Thomas Bogendoerfer |
3237e1 |
* Initializes the SW state maintained for each link, including the link's
|
|
Thomas Bogendoerfer |
3237e1 |
* capabilities and default speed/flow-control/autonegotiation settings.
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
-static void init_link_config(struct link_config *lc, unsigned int caps)
|
|
Thomas Bogendoerfer |
3237e1 |
-{
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->supported = caps;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->lp_advertising = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->requested_speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+static void init_link_config(struct link_config *lc,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps,
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t acaps)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->pcaps = pcaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->lpacaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (lc->supported & FW_PORT_CAP_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = lc->supported & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* For Forward Error Control, we default to whatever the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * tells us the Link is currently advertising.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->auto_fec = fwcap_to_cc_fec(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->requested_fec = FEC_AUTO;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fec = lc->auto_fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lc->pcaps & FW_PORT_CAP32_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = acaps & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->autoneg = AUTONEG_ENABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->requested_fc |= PAUSE_AUTONEG;
|
|
Thomas Bogendoerfer |
3237e1 |
} else {
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->advertising = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
lc->autoneg = AUTONEG_DISABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -351,9 +449,30 @@ static void init_link_config(struct link
|
|
Thomas Bogendoerfer |
3237e1 |
int t4vf_port_init(struct adapter *adapter, int pidx)
|
|
Thomas Bogendoerfer |
3237e1 |
{
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = adap2pinfo(adapter, pidx);
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
struct fw_vi_cmd vi_cmd, vi_rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
struct fw_port_cmd port_cmd, port_rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
- int v;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_type port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int mdio_addr;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps, acaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* If we haven't yet determined whether we're talking to Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * which knows the new 32-bit Port Capabilities, it's time to find
|
|
Thomas Bogendoerfer |
3237e1 |
+ * out now. This will also tell new Firmware to send us Port Status
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Updates using the new 32-bit Port Capabilities version of the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Port Information message.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps == FW_CAPS_UNKNOWN) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 param, val;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
|
|
Thomas Bogendoerfer |
3237e1 |
+ val = 1;
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4vf_set_params(adapter, 1, ¶m, &val;;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16);
|
|
Thomas Bogendoerfer |
3237e1 |
+ adapter->params.fw_caps_support = fw_caps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/*
|
|
Thomas Bogendoerfer |
3237e1 |
* Execute a VI Read command to get our Virtual Interface information
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -365,9 +484,9 @@ int t4vf_port_init(struct adapter *adapt
|
|
Thomas Bogendoerfer |
3237e1 |
FW_CMD_READ_F);
|
|
Thomas Bogendoerfer |
3237e1 |
vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(pi->viid));
|
|
Thomas Bogendoerfer |
3237e1 |
- v = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
- if (v)
|
|
Thomas Bogendoerfer |
3237e1 |
- return v;
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (ret != FW_SUCCESS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
BUG_ON(pi->port_id != FW_VI_CMD_PORTID_G(vi_rpl.portid_pkd));
|
|
Thomas Bogendoerfer |
3237e1 |
pi->rss_size = FW_VI_CMD_RSSSIZE_G(be16_to_cpu(vi_rpl.rsssize_pkd));
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -385,21 +504,42 @@ int t4vf_port_init(struct adapter *adapt
|
|
Thomas Bogendoerfer |
3237e1 |
FW_CMD_REQUEST_F |
|
|
Thomas Bogendoerfer |
3237e1 |
FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
FW_PORT_CMD_PORTID_V(pi->port_id));
|
|
Thomas Bogendoerfer |
3237e1 |
- port_cmd.action_to_len16 =
|
|
Thomas Bogendoerfer |
3237e1 |
- cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
- v = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
- if (v)
|
|
Thomas Bogendoerfer |
3237e1 |
- return v;
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_cmd.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_GET_PORT_INFO32) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (ret != FW_SUCCESS)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Extract the various fields from the Port Information message. */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (fw_caps == FW_CAPS16) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mdio_addr = ((lstatus & FW_PORT_CMD_MDIOCAP_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_CMD_MDIOADDR_G(lstatus)
|
|
Thomas Bogendoerfer |
3237e1 |
+ : -1);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = fwcaps16_to_caps32(be16_to_cpu(port_rpl.u.info.pcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = fwcaps16_to_caps32(be16_to_cpu(port_rpl.u.info.acap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus32 =
|
|
Thomas Bogendoerfer |
3237e1 |
+ be32_to_cpu(port_rpl.u.info32.lstatus32_to_cbllen32);
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->mdio_addr = (v & FW_PORT_CMD_MDIOCAP_F) ?
|
|
Thomas Bogendoerfer |
3237e1 |
- FW_PORT_CMD_MDIOADDR_G(v) : -1;
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->port_type = FW_PORT_CMD_PTYPE_G(v);
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->mod_type = FW_PORT_MOD_TYPE_NA;
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mdio_addr = ((lstatus32 & FW_PORT_CMD_MDIOCAP32_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_CMD_MDIOADDR32_G(lstatus32)
|
|
Thomas Bogendoerfer |
3237e1 |
+ : -1);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
- init_link_config(&pi->link_cfg, be16_to_cpu(port_rpl.u.info.pcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_type = port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->mdio_addr = mdio_addr;
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->mod_type = FW_PORT_MOD_TYPE_NA;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
+ init_link_config(&pi->link_cfg, pcaps, acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1667,6 +1807,202 @@ int t4vf_eth_eq_free(struct adapter *ada
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * t4vf_link_down_rc_str - return a string for a Link Down Reason Code
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @link_down_rc: Link Down Reason Code
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Returns a string representation of the Link Down Reason Code.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+const char *t4vf_link_down_rc_str(unsigned char link_down_rc)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ static const char * const reason[] = {
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Link Down",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Remote Fault",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Auto-negotiation Failure",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Reserved",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Insufficient Airflow",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Unable To Determine Reason",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "No RX Signal Detected",
|
|
Thomas Bogendoerfer |
3237e1 |
+ "Reserved",
|
|
Thomas Bogendoerfer |
3237e1 |
+ };
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (link_down_rc >= ARRAY_SIZE(reason))
|
|
Thomas Bogendoerfer |
3237e1 |
+ return "Bad Reason Code";
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ return reason[link_down_rc];
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * t4vf_handle_get_port_info - process a FW reply message
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @pi: the port info
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @rpl: start of the FW message
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Processes a GET_PORT_INFO FW reply message.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+void t4vf_handle_get_port_info(struct port_info *pi,
|
|
Thomas Bogendoerfer |
3237e1 |
+ const struct fw_port_cmd *cmd)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct adapter *adapter = pi->adapter;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct link_config *lc = &pi->link_cfg;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int link_ok, linkdnrc;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_type port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ enum fw_port_module_type mod_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int speed, fc, fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+ fw_port_cap32_t pcaps, acaps, lpacaps, linkattr;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Extract the various fields from the Port Information message. */
|
|
Thomas Bogendoerfer |
3237e1 |
+ switch (action) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_ACTION_GET_PORT_INFO: {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = (lstatus & FW_PORT_CMD_LSTATUS_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkdnrc = FW_PORT_CMD_LINKDNRC_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mod_type = FW_PORT_CMD_MODTYPE_G(lstatus);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
|
|
Thomas Bogendoerfer |
3237e1 |
+ lpacaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.lpacap));
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Unfortunately the format of the Link Status in the old
|
|
Thomas Bogendoerfer |
3237e1 |
+ * 16-bit Port Information message isn't the same as the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * 16-bit Port Capabilities bitfield used everywhere else ...
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_RXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_FC_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_TXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_FC_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_100M;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_1G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_10G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_25G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_40G;
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr |= FW_PORT_CAP32_SPEED_100G;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ case FW_PORT_ACTION_GET_PORT_INFO32: {
|
|
Thomas Bogendoerfer |
3237e1 |
+ u32 lstatus32;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ lstatus32 = be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ link_ok = (lstatus32 & FW_PORT_CMD_LSTATUS32_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkdnrc = FW_PORT_CMD_LINKDNRC32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ mod_type = FW_PORT_CMD_MODTYPE32_G(lstatus32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ acaps = be32_to_cpu(cmd->u.info32.acaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lpacaps = be32_to_cpu(cmd->u.info32.lpacaps32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
|
|
Thomas Bogendoerfer |
3237e1 |
+ break;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ default:
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev_err(adapter->pdev_dev, "Handle Port Information: Bad Command/Action %#x\n",
|
|
Thomas Bogendoerfer |
3237e1 |
+ be32_to_cpu(cmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
+ return;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ fec = fwcap_to_cc_fec(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ fc = fwcap_to_cc_pause(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+ speed = fwcap_to_speed(linkattr);
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (mod_type != pi->mod_type) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* When a new Transceiver Module is inserted, the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * will examine any Forward Error Correction parameters
|
|
Thomas Bogendoerfer |
3237e1 |
+ * present in the Transceiver Module i2c EPROM and determine
|
|
Thomas Bogendoerfer |
3237e1 |
+ * the supported and recommended FEC settings from those
|
|
Thomas Bogendoerfer |
3237e1 |
+ * based on IEEE 802.3 standards. We always record the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * IEEE 802.3 recommended "automatic" settings.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->auto_fec = fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* Some versions of the early T6 Firmware "cheated" when
|
|
Thomas Bogendoerfer |
3237e1 |
+ * handling different Transceiver Modules by changing the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * underlaying Port Type reported to the Host Drivers. As
|
|
Thomas Bogendoerfer |
3237e1 |
+ * such we need to capture whatever Port Type the Firmware
|
|
Thomas Bogendoerfer |
3237e1 |
+ * sends us and record it in case it's different from what we
|
|
Thomas Bogendoerfer |
3237e1 |
+ * were told earlier. Unfortunately, since Firmware is
|
|
Thomas Bogendoerfer |
3237e1 |
+ * forever, we'll need to keep this code here forever, but in
|
|
Thomas Bogendoerfer |
3237e1 |
+ * later T6 Firmware it should just be an assignment of the
|
|
Thomas Bogendoerfer |
3237e1 |
+ * same value already recorded.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_type = port_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->mod_type = mod_type;
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4vf_os_portmod_changed(adapter, pi->pidx);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (link_ok != lc->link_ok || speed != lc->speed ||
|
|
Thomas Bogendoerfer |
3237e1 |
+ fc != lc->fc || fec != lc->fec) { /* something changed */
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (!link_ok && lc->link_ok) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->link_down_rc = linkdnrc;
|
|
Thomas Bogendoerfer |
3237e1 |
+ dev_warn(adapter->pdev_dev, "Port %d link down, reason: %s\n",
|
|
Thomas Bogendoerfer |
3237e1 |
+ pi->port_id, t4vf_link_down_rc_str(linkdnrc));
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->link_ok = link_ok;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed = speed;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fc = fc;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->fec = fec;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->pcaps = pcaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->lpacaps = lpacaps;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = acaps & ADVERT_MASK;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (lc->acaps & FW_PORT_CAP32_ANEG) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->autoneg = AUTONEG_ENABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
+ } else {
|
|
Thomas Bogendoerfer |
3237e1 |
+ /* When Autoneg is disabled, user needs to set
|
|
Thomas Bogendoerfer |
3237e1 |
+ * single speed.
|
|
Thomas Bogendoerfer |
3237e1 |
+ * Similar to cxgb4_ethtool.c: set_link_ksettings
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->acaps = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->speed_caps = fwcap_to_speed(acaps);
|
|
Thomas Bogendoerfer |
3237e1 |
+ lc->autoneg = AUTONEG_DISABLE;
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4vf_os_link_changed(adapter, pi->pidx, link_ok);
|
|
Thomas Bogendoerfer |
3237e1 |
+ }
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
+ * t4vf_update_port_info - retrieve and update port information if changed
|
|
Thomas Bogendoerfer |
3237e1 |
+ * @pi: the port_info
|
|
Thomas Bogendoerfer |
3237e1 |
+ *
|
|
Thomas Bogendoerfer |
3237e1 |
+ * We issue a Get Port Information Command to the Firmware and, if
|
|
Thomas Bogendoerfer |
3237e1 |
+ * successful, we check to see if anything is different from what we
|
|
Thomas Bogendoerfer |
3237e1 |
+ * last recorded and update things accordingly.
|
|
Thomas Bogendoerfer |
3237e1 |
+ */
|
|
Thomas Bogendoerfer |
3237e1 |
+int t4vf_update_port_info(struct port_info *pi)
|
|
Thomas Bogendoerfer |
3237e1 |
+{
|
|
Thomas Bogendoerfer |
3237e1 |
+ unsigned int fw_caps = pi->adapter->params.fw_caps_support;
|
|
Thomas Bogendoerfer |
3237e1 |
+ struct fw_port_cmd port_cmd;
|
|
Thomas Bogendoerfer |
3237e1 |
+ int ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ memset(&port_cmd, 0, sizeof(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_PORTID_V(pi->port_id));
|
|
Thomas Bogendoerfer |
3237e1 |
+ port_cmd.action_to_len16 = cpu_to_be32(
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
|
|
Thomas Bogendoerfer |
3237e1 |
+ ? FW_PORT_ACTION_GET_PORT_INFO
|
|
Thomas Bogendoerfer |
3237e1 |
+ : FW_PORT_ACTION_GET_PORT_INFO32) |
|
|
Thomas Bogendoerfer |
3237e1 |
+ FW_LEN16(port_cmd));
|
|
Thomas Bogendoerfer |
3237e1 |
+ ret = t4vf_wr_mbox(pi->adapter, &port_cmd, sizeof(port_cmd),
|
|
Thomas Bogendoerfer |
3237e1 |
+ &port_cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (ret)
|
|
Thomas Bogendoerfer |
3237e1 |
+ return ret;
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4vf_handle_get_port_info(pi, &port_cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
+ return 0;
|
|
Thomas Bogendoerfer |
3237e1 |
+}
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+/**
|
|
Thomas Bogendoerfer |
3237e1 |
* t4vf_handle_fw_rpl - process a firmware reply message
|
|
Thomas Bogendoerfer |
3237e1 |
* @adapter: the adapter
|
|
Thomas Bogendoerfer |
3237e1 |
* @rpl: start of the firmware message
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1685,15 +2021,12 @@ int t4vf_handle_fw_rpl(struct adapter *a
|
|
Thomas Bogendoerfer |
3237e1 |
*/
|
|
Thomas Bogendoerfer |
3237e1 |
const struct fw_port_cmd *port_cmd =
|
|
Thomas Bogendoerfer |
3237e1 |
(const struct fw_port_cmd *)rpl;
|
|
Thomas Bogendoerfer |
3237e1 |
- u32 stat, mod;
|
|
Thomas Bogendoerfer |
3237e1 |
- int action, port_id, link_ok, speed, fc, pidx;
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- /*
|
|
Thomas Bogendoerfer |
3237e1 |
- * Extract various fields from port status change message.
|
|
Thomas Bogendoerfer |
3237e1 |
- */
|
|
Thomas Bogendoerfer |
3237e1 |
- action = FW_PORT_CMD_ACTION_G(
|
|
Thomas Bogendoerfer |
3237e1 |
+ int action = FW_PORT_CMD_ACTION_G(
|
|
Thomas Bogendoerfer |
3237e1 |
be32_to_cpu(port_cmd->action_to_len16));
|
|
Thomas Bogendoerfer |
3237e1 |
- if (action != FW_PORT_ACTION_GET_PORT_INFO) {
|
|
Thomas Bogendoerfer |
3237e1 |
+ int port_id, pidx;
|
|
Thomas Bogendoerfer |
3237e1 |
+
|
|
Thomas Bogendoerfer |
3237e1 |
+ if (action != FW_PORT_ACTION_GET_PORT_INFO &&
|
|
Thomas Bogendoerfer |
3237e1 |
+ action != FW_PORT_ACTION_GET_PORT_INFO32) {
|
|
Thomas Bogendoerfer |
3237e1 |
dev_err(adapter->pdev_dev,
|
|
Thomas Bogendoerfer |
3237e1 |
"Unknown firmware PORT reply action %x\n",
|
|
Thomas Bogendoerfer |
3237e1 |
action);
|
|
Thomas Bogendoerfer |
3237e1 |
@@ -1702,61 +2035,12 @@ int t4vf_handle_fw_rpl(struct adapter *a
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
port_id = FW_PORT_CMD_PORTID_G(
|
|
Thomas Bogendoerfer |
3237e1 |
be32_to_cpu(port_cmd->op_to_portid));
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- stat = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype);
|
|
Thomas Bogendoerfer |
3237e1 |
- link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- fc = 0;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_RXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
- fc |= PAUSE_RX;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_TXPAUSE_F)
|
|
Thomas Bogendoerfer |
3237e1 |
- fc |= PAUSE_TX;
|
|
Thomas Bogendoerfer |
3237e1 |
- if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 1000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 10000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 25000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 40000;
|
|
Thomas Bogendoerfer |
3237e1 |
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
|
|
Thomas Bogendoerfer |
3237e1 |
- speed = 100000;
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- /*
|
|
Thomas Bogendoerfer |
3237e1 |
- * Scan all of our "ports" (Virtual Interfaces) looking for
|
|
Thomas Bogendoerfer |
3237e1 |
- * those bound to the physical port which has changed. If
|
|
Thomas Bogendoerfer |
3237e1 |
- * our recorded state doesn't match the current state,
|
|
Thomas Bogendoerfer |
3237e1 |
- * signal that change to the OS code.
|
|
Thomas Bogendoerfer |
3237e1 |
- */
|
|
Thomas Bogendoerfer |
3237e1 |
for_each_port(adapter, pidx) {
|
|
Thomas Bogendoerfer |
3237e1 |
struct port_info *pi = adap2pinfo(adapter, pidx);
|
|
Thomas Bogendoerfer |
3237e1 |
- struct link_config *lc;
|
|
Thomas Bogendoerfer |
3237e1 |
|
|
Thomas Bogendoerfer |
3237e1 |
if (pi->port_id != port_id)
|
|
Thomas Bogendoerfer |
3237e1 |
continue;
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- lc = &pi->link_cfg;
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- mod = FW_PORT_CMD_MODTYPE_G(stat);
|
|
Thomas Bogendoerfer |
3237e1 |
- if (mod != pi->mod_type) {
|
|
Thomas Bogendoerfer |
3237e1 |
- pi->mod_type = mod;
|
|
Thomas Bogendoerfer |
3237e1 |
- t4vf_os_portmod_changed(adapter, pidx);
|
|
Thomas Bogendoerfer |
3237e1 |
- }
|
|
Thomas Bogendoerfer |
3237e1 |
-
|
|
Thomas Bogendoerfer |
3237e1 |
- if (link_ok != lc->link_ok || speed != lc->speed ||
|
|
Thomas Bogendoerfer |
3237e1 |
- fc != lc->fc) {
|
|
Thomas Bogendoerfer |
3237e1 |
- /* something changed */
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->link_ok = link_ok;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->speed = speed;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->fc = fc;
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->supported =
|
|
Thomas Bogendoerfer |
3237e1 |
- be16_to_cpu(port_cmd->u.info.pcap);
|
|
Thomas Bogendoerfer |
3237e1 |
- lc->lp_advertising =
|
|
Thomas Bogendoerfer |
3237e1 |
- be16_to_cpu(port_cmd->u.info.lpacap);
|
|
Thomas Bogendoerfer |
3237e1 |
- t4vf_os_link_changed(adapter, pidx, link_ok);
|
|
Thomas Bogendoerfer |
3237e1 |
- }
|
|
Thomas Bogendoerfer |
3237e1 |
+ t4vf_handle_get_port_info(pi, port_cmd);
|
|
Thomas Bogendoerfer |
3237e1 |
}
|
|
Thomas Bogendoerfer |
3237e1 |
break;
|
|
Thomas Bogendoerfer |
3237e1 |
}
|