Skip to content

Commit cc875c2

Browse files
Yuval Mintzdavem330
authored andcommitted
qed: Add link support
Physical link is handled by the management Firmware. This patch lays the infrastructure for attention handling in the driver, as link change notifications arrive via async. attentions, as well the handling of such notifications. This patch also extends the API with the protocol drivers by adding registered callbacks which the protocol driver passes to qed in order to be notified of async. events originating from the FW/HW. Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0d8e0aa commit cc875c2

File tree

8 files changed

+1102
-5
lines changed

8 files changed

+1102
-5
lines changed

drivers/net/ethernet/qlogic/qed/qed.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ enum QED_FEATURE {
108108
QED_MAX_FEATURES,
109109
};
110110

111+
enum QED_PORT_MODE {
112+
QED_PORT_MODE_DE_2X40G,
113+
QED_PORT_MODE_DE_2X50G,
114+
QED_PORT_MODE_DE_1X100G,
115+
QED_PORT_MODE_DE_4X10G_F,
116+
QED_PORT_MODE_DE_4X10G_E,
117+
QED_PORT_MODE_DE_4X20G,
118+
QED_PORT_MODE_DE_1X40G,
119+
QED_PORT_MODE_DE_2X25G,
120+
QED_PORT_MODE_DE_1X25G
121+
};
122+
111123
struct qed_hw_info {
112124
/* PCI personality */
113125
enum qed_pci_personality personality;
@@ -404,6 +416,13 @@ struct qed_dev {
404416
u8 protocol;
405417
#define IS_QED_ETH_IF(cdev) ((cdev)->protocol == QED_PROTOCOL_ETH)
406418

419+
/* Callbacks to protocol driver */
420+
union {
421+
struct qed_common_cb_ops *common;
422+
struct qed_eth_cb_ops *eth;
423+
} protocol_ops;
424+
void *ops_cookie;
425+
407426
const struct firmware *firmware;
408427
};
409428

@@ -453,6 +472,7 @@ static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev,
453472
/* Prototypes */
454473
int qed_fill_dev_info(struct qed_dev *cdev,
455474
struct qed_dev_info *dev_info);
475+
void qed_link_update(struct qed_hwfn *hwfn);
456476
u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
457477
u32 input_len, u8 *input_buf,
458478
u32 max_size, u8 *unzip_buf);

drivers/net/ethernet/qlogic/qed/qed_dev.c

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,8 +1039,9 @@ static void qed_hw_get_resc(struct qed_hwfn *p_hwfn)
10391039
static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn,
10401040
struct qed_ptt *p_ptt)
10411041
{
1042-
u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, nvm_cfg_addr;
1043-
u32 val;
1042+
u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg;
1043+
u32 port_cfg_addr, link_temp, val, nvm_cfg_addr;
1044+
struct qed_mcp_link_params *link;
10441045

10451046
/* Read global nvm_cfg address */
10461047
nvm_cfg_addr = qed_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
@@ -1060,6 +1061,48 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn,
10601061
offsetof(struct nvm_cfg1_glob, pci_id);
10611062
p_hwfn->hw_info.vendor_id = qed_rd(p_hwfn, p_ptt, addr) &
10621063
NVM_CFG1_GLOB_VENDOR_ID_MASK;
1064+
1065+
addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
1066+
offsetof(struct nvm_cfg1, glob) +
1067+
offsetof(struct nvm_cfg1_glob, core_cfg);
1068+
1069+
core_cfg = qed_rd(p_hwfn, p_ptt, addr);
1070+
1071+
switch ((core_cfg & NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK) >>
1072+
NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET) {
1073+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_2X40G:
1074+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X40G;
1075+
break;
1076+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_2X50G:
1077+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X50G;
1078+
break;
1079+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_1X100G:
1080+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G;
1081+
break;
1082+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_4X10G_F:
1083+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X10G_F;
1084+
break;
1085+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_4X10G_E:
1086+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X10G_E;
1087+
break;
1088+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_4X20G:
1089+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X20G;
1090+
break;
1091+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_1X40G:
1092+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X40G;
1093+
break;
1094+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_2X25G:
1095+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X25G;
1096+
break;
1097+
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_DE_1X25G:
1098+
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X25G;
1099+
break;
1100+
default:
1101+
DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n",
1102+
core_cfg);
1103+
break;
1104+
}
1105+
10631106
addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
10641107
offsetof(struct nvm_cfg1, func[MCP_PF_ID(p_hwfn)]) +
10651108
offsetof(struct nvm_cfg1_func, device_id);
@@ -1075,6 +1118,65 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn,
10751118
NVM_CFG1_FUNC_VENDOR_DEVICE_ID_OFFSET;
10761119
}
10771120

1121+
/* Read default link configuration */
1122+
link = &p_hwfn->mcp_info->link_input;
1123+
port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
1124+
offsetof(struct nvm_cfg1, port[MFW_PORT(p_hwfn)]);
1125+
link_temp = qed_rd(p_hwfn, p_ptt,
1126+
port_cfg_addr +
1127+
offsetof(struct nvm_cfg1_port, speed_cap_mask));
1128+
link->speed.advertised_speeds =
1129+
link_temp & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK;
1130+
1131+
p_hwfn->mcp_info->link_capabilities.speed_capabilities =
1132+
link->speed.advertised_speeds;
1133+
1134+
link_temp = qed_rd(p_hwfn, p_ptt,
1135+
port_cfg_addr +
1136+
offsetof(struct nvm_cfg1_port, link_settings));
1137+
switch ((link_temp & NVM_CFG1_PORT_DRV_LINK_SPEED_MASK) >>
1138+
NVM_CFG1_PORT_DRV_LINK_SPEED_OFFSET) {
1139+
case NVM_CFG1_PORT_DRV_LINK_SPEED_AUTONEG:
1140+
link->speed.autoneg = true;
1141+
break;
1142+
case NVM_CFG1_PORT_DRV_LINK_SPEED_1G:
1143+
link->speed.forced_speed = 1000;
1144+
break;
1145+
case NVM_CFG1_PORT_DRV_LINK_SPEED_10G:
1146+
link->speed.forced_speed = 10000;
1147+
break;
1148+
case NVM_CFG1_PORT_DRV_LINK_SPEED_25G:
1149+
link->speed.forced_speed = 25000;
1150+
break;
1151+
case NVM_CFG1_PORT_DRV_LINK_SPEED_40G:
1152+
link->speed.forced_speed = 40000;
1153+
break;
1154+
case NVM_CFG1_PORT_DRV_LINK_SPEED_50G:
1155+
link->speed.forced_speed = 50000;
1156+
break;
1157+
case NVM_CFG1_PORT_DRV_LINK_SPEED_100G:
1158+
link->speed.forced_speed = 100000;
1159+
break;
1160+
default:
1161+
DP_NOTICE(p_hwfn, "Unknown Speed in 0x%08x\n",
1162+
link_temp);
1163+
}
1164+
1165+
link_temp &= NVM_CFG1_PORT_DRV_FLOW_CONTROL_MASK;
1166+
link_temp >>= NVM_CFG1_PORT_DRV_FLOW_CONTROL_OFFSET;
1167+
link->pause.autoneg = !!(link_temp &
1168+
NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG);
1169+
link->pause.forced_rx = !!(link_temp &
1170+
NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX);
1171+
link->pause.forced_tx = !!(link_temp &
1172+
NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX);
1173+
link->loopback_mode = 0;
1174+
1175+
DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
1176+
"Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x\n",
1177+
link->speed.forced_speed, link->speed.advertised_speeds,
1178+
link->speed.autoneg, link->pause.autoneg);
1179+
10781180
/* Read Multi-function information from shmem */
10791181
addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
10801182
offsetof(struct nvm_cfg1, glob) +

0 commit comments

Comments
 (0)