return status;
}
+int be_cmd_query_cable_type(struct be_adapter *adapter)
+{
+ u8 page_data[PAGE_DATA_LEN];
+ int status;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+ page_data);
+ if (!status) {
+ switch (adapter->phy.interface_type) {
+ case PHY_TYPE_QSFP:
+ adapter->phy.cable_type =
+ page_data[QSFP_PLUS_CABLE_TYPE_OFFSET];
+ break;
+ case PHY_TYPE_SFP_PLUS_10GB:
+ adapter->phy.cable_type =
+ page_data[SFP_PLUS_CABLE_TYPE_OFFSET];
+ break;
+ default:
+ adapter->phy.cable_type = 0;
+ break;
+ }
+ }
+ return status;
+}
+
int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
{
struct lancer_cmd_req_delete_object *req;
TR_PAGE_A2 = 0xa2
};
+/* From SFF-8436 QSFP+ spec */
+#define QSFP_PLUS_CABLE_TYPE_OFFSET 0x83
+#define QSFP_PLUS_CR4_CABLE 0x8
+#define QSFP_PLUS_SR4_CABLE 0x4
+#define QSFP_PLUS_LR4_CABLE 0x2
+
/* From SFF-8472 spec */
-#define SFP_PLUS_SFF_8472_COMP 0x5E
+#define SFP_PLUS_SFF_8472_COMP 0x5E
+#define SFP_PLUS_CABLE_TYPE_OFFSET 0x8
+#define SFP_PLUS_COPPER_CABLE 0x4
#define PAGE_DATA_LEN 256
struct be_cmd_resp_port_type {
PHY_TYPE_BASET_1GB,
PHY_TYPE_BASEX_1GB,
PHY_TYPE_SGMII,
+ PHY_TYPE_QSFP,
+ PHY_TYPE_KR4_40GB,
+ PHY_TYPE_KR2_20GB,
PHY_TYPE_DISABLED = 255
};
#define BE_SUPPORTED_SPEED_100MBPS 2
#define BE_SUPPORTED_SPEED_1GBPS 4
#define BE_SUPPORTED_SPEED_10GBPS 8
+#define BE_SUPPORTED_SPEED_40GBPS 0x20
#define BE_AN_EN 0x2
#define BE_PAUSE_SYM_EN 0x80
u32 *state);
int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
u8 page_num, u8 *data);
+int be_cmd_query_cable_type(struct be_adapter *adapter);
int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_oper, u32 flash_opcode, u32 buf_size);
int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
}
}
-static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len)
+static u32 be_get_port_type(struct be_adapter *adapter)
{
u32 port;
- switch (phy_type) {
+ switch (adapter->phy.interface_type) {
case PHY_TYPE_BASET_1GB:
case PHY_TYPE_BASEX_1GB:
case PHY_TYPE_SGMII:
port = PORT_TP;
break;
case PHY_TYPE_SFP_PLUS_10GB:
- port = dac_cable_len ? PORT_DA : PORT_FIBRE;
+ if (adapter->phy.cable_type & SFP_PLUS_COPPER_CABLE)
+ port = PORT_DA;
+ else
+ port = PORT_FIBRE;
+ break;
+ case PHY_TYPE_QSFP:
+ if (adapter->phy.cable_type & QSFP_PLUS_CR4_CABLE)
+ port = PORT_DA;
+ else
+ port = PORT_FIBRE;
break;
case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB:
return port;
}
-static u32 convert_to_et_setting(u32 if_type, u32 if_speeds)
+static u32 convert_to_et_setting(struct be_adapter *adapter, u32 if_speeds)
{
u32 val = 0;
- switch (if_type) {
+ switch (adapter->phy.interface_type) {
case PHY_TYPE_BASET_1GB:
case PHY_TYPE_BASEX_1GB:
case PHY_TYPE_SGMII:
val |= SUPPORTED_Backplane |
SUPPORTED_10000baseKR_Full;
break;
+ case PHY_TYPE_QSFP:
+ if (if_speeds & BE_SUPPORTED_SPEED_40GBPS) {
+ switch (adapter->phy.cable_type) {
+ case QSFP_PLUS_CR4_CABLE:
+ val |= SUPPORTED_40000baseCR4_Full;
+ break;
+ case QSFP_PLUS_LR4_CABLE:
+ val |= SUPPORTED_40000baseLR4_Full;
+ break;
+ default:
+ val |= SUPPORTED_40000baseSR4_Full;
+ break;
+ }
+ }
case PHY_TYPE_SFP_PLUS_10GB:
case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB:
int status;
u32 auto_speeds;
u32 fixed_speeds;
- u32 dac_cable_len;
- u16 interface_type;
if (adapter->phy.link_speed < 0) {
status = be_cmd_link_status_query(adapter, &link_speed,
status = be_cmd_get_phy_info(adapter);
if (!status) {
- interface_type = adapter->phy.interface_type;
auto_speeds = adapter->phy.auto_speeds_supported;
fixed_speeds = adapter->phy.fixed_speeds_supported;
- dac_cable_len = adapter->phy.dac_cable_len;
+
+ be_cmd_query_cable_type(adapter);
ecmd->supported =
- convert_to_et_setting(interface_type,
+ convert_to_et_setting(adapter,
auto_speeds |
fixed_speeds);
ecmd->advertising =
- convert_to_et_setting(interface_type,
- auto_speeds);
+ convert_to_et_setting(adapter, auto_speeds);
- ecmd->port = be_get_port_type(interface_type,
- dac_cable_len);
+ ecmd->port = be_get_port_type(adapter);
if (adapter->phy.auto_speeds_supported) {
ecmd->supported |= SUPPORTED_Autoneg;