diff options
author | Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> | 2019-02-28 18:24:25 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-04-18 11:38:47 -0400 |
commit | 0deab659a615a480a68ae17ad36a0f3c37c62e01 (patch) | |
tree | 837c877583905327176338d59c7d6a579ea242ac /drivers/net/ethernet/intel/ice/ice_dcb_lib.c | |
parent | 7b9ffc76bf5998aad8feaa26d9d3fcb65ec7a21b (diff) |
ice: Add code for DCB initialization part 4/4
When the firmware doesn't support LLDP or DCBX, the driver should switch
to "software LLDP mode". This patch adds support for the same.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_dcb_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index 210487a0671d..c52bd5bb37c2 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c | |||
@@ -187,6 +187,50 @@ static int ice_dcb_init_cfg(struct ice_pf *pf) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | /** | 189 | /** |
190 | * ice_dcb_sw_default_config - Apply a default DCB config | ||
191 | * @pf: pf to apply config to | ||
192 | */ | ||
193 | static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf) | ||
194 | { | ||
195 | struct ice_aqc_port_ets_elem buf = { 0 }; | ||
196 | struct ice_dcbx_cfg *dcbcfg; | ||
197 | struct ice_port_info *pi; | ||
198 | struct ice_hw *hw; | ||
199 | int ret; | ||
200 | |||
201 | hw = &pf->hw; | ||
202 | pi = hw->port_info; | ||
203 | dcbcfg = devm_kzalloc(&pf->pdev->dev, sizeof(*dcbcfg), GFP_KERNEL); | ||
204 | |||
205 | memset(dcbcfg, 0, sizeof(*dcbcfg)); | ||
206 | memset(&pi->local_dcbx_cfg, 0, sizeof(*dcbcfg)); | ||
207 | |||
208 | dcbcfg->etscfg.willing = 1; | ||
209 | dcbcfg->etscfg.maxtcs = 8; | ||
210 | dcbcfg->etscfg.tcbwtable[0] = 100; | ||
211 | dcbcfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS; | ||
212 | |||
213 | memcpy(&dcbcfg->etsrec, &dcbcfg->etscfg, | ||
214 | sizeof(dcbcfg->etsrec)); | ||
215 | dcbcfg->etsrec.willing = 0; | ||
216 | |||
217 | dcbcfg->pfc.willing = 1; | ||
218 | dcbcfg->pfc.pfccap = IEEE_8021QAZ_MAX_TCS; | ||
219 | |||
220 | dcbcfg->numapps = 1; | ||
221 | dcbcfg->app[0].selector = ICE_APP_SEL_ETHTYPE; | ||
222 | dcbcfg->app[0].priority = 3; | ||
223 | dcbcfg->app[0].prot_id = ICE_APP_PROT_ID_FCOE; | ||
224 | |||
225 | ret = ice_pf_dcb_cfg(pf, dcbcfg); | ||
226 | devm_kfree(&pf->pdev->dev, dcbcfg); | ||
227 | if (ret) | ||
228 | return ret; | ||
229 | |||
230 | return ice_query_port_ets(pi, &buf, sizeof(buf), NULL); | ||
231 | } | ||
232 | |||
233 | /** | ||
190 | * ice_init_pf_dcb - initialize DCB for a PF | 234 | * ice_init_pf_dcb - initialize DCB for a PF |
191 | * @pf: pf to initiialize DCB for | 235 | * @pf: pf to initiialize DCB for |
192 | */ | 236 | */ |
@@ -195,6 +239,7 @@ int ice_init_pf_dcb(struct ice_pf *pf) | |||
195 | struct device *dev = &pf->pdev->dev; | 239 | struct device *dev = &pf->pdev->dev; |
196 | struct ice_port_info *port_info; | 240 | struct ice_port_info *port_info; |
197 | struct ice_hw *hw = &pf->hw; | 241 | struct ice_hw *hw = &pf->hw; |
242 | int sw_default = 0; | ||
198 | int err; | 243 | int err; |
199 | 244 | ||
200 | port_info = hw->port_info; | 245 | port_info = hw->port_info; |
@@ -223,8 +268,41 @@ int ice_init_pf_dcb(struct ice_pf *pf) | |||
223 | } | 268 | } |
224 | 269 | ||
225 | err = ice_init_dcb(hw); | 270 | err = ice_init_dcb(hw); |
226 | if (err) | 271 | if (err) { |
227 | goto dcb_init_err; | 272 | /* FW LLDP not in usable state, default to SW DCBx/LLDP */ |
273 | dev_info(&pf->pdev->dev, "FW LLDP not in usable state\n"); | ||
274 | hw->port_info->dcbx_status = ICE_DCBX_STATUS_NOT_STARTED; | ||
275 | hw->port_info->is_sw_lldp = true; | ||
276 | } | ||
277 | |||
278 | if (port_info->dcbx_status == ICE_DCBX_STATUS_DIS) | ||
279 | dev_info(&pf->pdev->dev, "DCBX disabled\n"); | ||
280 | |||
281 | /* LLDP disabled in FW */ | ||
282 | if (port_info->is_sw_lldp) { | ||
283 | sw_default = 1; | ||
284 | dev_info(&pf->pdev->dev, "DCBx/LLDP in SW mode.\n"); | ||
285 | } | ||
286 | |||
287 | if (port_info->dcbx_status == ICE_DCBX_STATUS_NOT_STARTED) { | ||
288 | sw_default = 1; | ||
289 | dev_info(&pf->pdev->dev, "DCBX not started\n"); | ||
290 | } | ||
291 | |||
292 | if (sw_default) { | ||
293 | err = ice_dcb_sw_dflt_cfg(pf); | ||
294 | if (err) { | ||
295 | dev_err(&pf->pdev->dev, | ||
296 | "Failed to set local DCB config %d\n", err); | ||
297 | err = -EIO; | ||
298 | goto dcb_init_err; | ||
299 | } | ||
300 | |||
301 | pf->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; | ||
302 | set_bit(ICE_FLAG_DCB_CAPABLE, pf->flags); | ||
303 | set_bit(ICE_FLAG_DCB_ENA, pf->flags); | ||
304 | return 0; | ||
305 | } | ||
228 | 306 | ||
229 | /* DCBX in FW and LLDP enabled in FW */ | 307 | /* DCBX in FW and LLDP enabled in FW */ |
230 | pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE; | 308 | pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE; |