cxgbe(4): Add support for additional port types and link speeds.

Sponsored by:	Chelsio Communications.
This commit is contained in:
np 2016-09-11 23:08:57 +00:00
parent 431192f386
commit 9dfee01db0
4 changed files with 127 additions and 3 deletions

View File

@ -1039,6 +1039,13 @@ is_10G_port(const struct port_info *pi)
return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) != 0);
}
static inline bool
is_25G_port(const struct port_info *pi)
{
return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) != 0);
}
static inline bool
is_40G_port(const struct port_info *pi)
{
@ -1046,6 +1053,13 @@ is_40G_port(const struct port_info *pi)
return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) != 0);
}
static inline bool
is_100G_port(const struct port_info *pi)
{
return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) != 0);
}
static inline int
port_top_speed(const struct port_info *pi)
{
@ -1054,6 +1068,8 @@ port_top_speed(const struct port_info *pi)
return (100);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
return (40);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
return (25);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
return (10);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)

View File

@ -3669,8 +3669,9 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
}
#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \
FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG)
FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \
FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
FW_PORT_CAP_ANEG)
/**
* t4_link_l1cfg - apply link configuration to MAC/PHY
@ -5775,6 +5776,11 @@ const char *t4_get_port_type_description(enum fw_port_type port_type)
"QSA",
"QSFP",
"BP40_BA",
"KR4_100G",
"CR4_QSFP",
"CR_QSFP",
"CR2_QSFP",
"SFP28",
};
if (port_type < ARRAY_SIZE(port_type_description))
@ -7462,8 +7468,12 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
speed = 1000;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
speed = 10000;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
speed = 25000;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
speed = 40000;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
speed = 100000;
for_each_port(adap, i) {
pi = adap2pinfo(adap, i);

View File

@ -6305,7 +6305,7 @@ struct fw_acl_vlan_cmd {
enum fw_port_cap {
FW_PORT_CAP_SPEED_100M = 0x0001,
FW_PORT_CAP_SPEED_1G = 0x0002,
FW_PORT_CAP_SPEED_2_5G = 0x0004,
FW_PORT_CAP_SPEED_25G = 0x0004,
FW_PORT_CAP_SPEED_10G = 0x0008,
FW_PORT_CAP_SPEED_40G = 0x0010,
FW_PORT_CAP_SPEED_100G = 0x0020,
@ -6776,6 +6776,11 @@ enum fw_port_type {
FW_PORT_TYPE_QSA = 13, /* No, 1, Yes, No, No, No, 10G */
FW_PORT_TYPE_QSFP = 14, /* No, 4, Yes, No, No, No, 40G */
FW_PORT_TYPE_BP40_BA = 15, /* No, 4, No, No, Yes, Yes, 40G/10G/1G, BP ANGE */
FW_PORT_TYPE_KR4_100G = 16, /* No, 4, 100G */
FW_PORT_TYPE_CR4_QSFP = 17, /* No, 4, 100G */
FW_PORT_TYPE_CR_QSFP = 18, /* No, 1, 25G */
FW_PORT_TYPE_CR2_QSFP = 19, /* No, 2, 50G */
FW_PORT_TYPE_SFP28 = 20, /* No, 1, 25G */
FW_PORT_TYPE_NONE = M_FW_PORT_CMD_PTYPE
};

View File

@ -3460,6 +3460,38 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
}
break;
case FW_PORT_TYPE_CR_QSFP:
case FW_PORT_TYPE_SFP28:
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_SR:
MPASS(pi->port_type == FW_PORT_TYPE_SFP28);
ifmedia_add(media, m | IFM_25G_SR, 0, NULL);
ifmedia_set(media, m | IFM_25G_SR);
break;
case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
ifmedia_add(media, m | IFM_25G_CR, 0, NULL);
ifmedia_set(media, m | IFM_25G_CR);
break;
case FW_PORT_MOD_TYPE_NONE:
m &= ~IFM_FDX;
ifmedia_add(media, m | IFM_NONE, 0, NULL);
ifmedia_set(media, m | IFM_NONE);
break;
default:
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n",
pi->port_type, pi->mod_type);
ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
break;
case FW_PORT_TYPE_QSFP:
switch (pi->mod_type) {
@ -3495,6 +3527,67 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
}
break;
case FW_PORT_TYPE_CR2_QSFP:
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
ifmedia_add(media, m | IFM_50G_CR2, 0, NULL);
ifmedia_set(media, m | IFM_50G_CR2);
break;
case FW_PORT_MOD_TYPE_NONE:
m &= ~IFM_FDX;
ifmedia_add(media, m | IFM_NONE, 0, NULL);
ifmedia_set(media, m | IFM_NONE);
break;
default:
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n",
pi->port_type, pi->mod_type);
ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
break;
case FW_PORT_TYPE_KR4_100G:
case FW_PORT_TYPE_CR4_QSFP:
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_LR:
ifmedia_add(media, m | IFM_100G_LR4, 0, NULL);
ifmedia_set(media, m | IFM_100G_LR4);
break;
case FW_PORT_MOD_TYPE_SR:
ifmedia_add(media, m | IFM_100G_SR4, 0, NULL);
ifmedia_set(media, m | IFM_100G_SR4);
break;
case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
ifmedia_add(media, m | IFM_100G_CR4, 0, NULL);
ifmedia_set(media, m | IFM_100G_CR4);
break;
case FW_PORT_MOD_TYPE_NONE:
m &= ~IFM_FDX;
ifmedia_add(media, m | IFM_NONE, 0, NULL);
ifmedia_set(media, m | IFM_NONE);
break;
default:
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n",
pi->port_type, pi->mod_type);
ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
break;
default:
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n", pi->port_type,