1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2013 - 2021 Intel Corporation. */
8 #define I40E_DCBNL_STATUS_SUCCESS 0
9 #define I40E_DCBNL_STATUS_ERROR 1
10 static bool i40e_dcbnl_find_app(struct i40e_dcbx_config
*cfg
,
11 struct i40e_dcb_app_priority_table
*app
);
13 * i40e_get_pfc_delay - retrieve PFC Link Delay
14 * @hw: pointer to hardware struct
15 * @delay: holds the PFC Link delay value
17 * Returns PFC Link Delay from the PRTDCB_GENC.PFCLDA
19 static void i40e_get_pfc_delay(struct i40e_hw
*hw
, u16
*delay
)
23 val
= rd32(hw
, I40E_PRTDCB_GENC
);
24 *delay
= FIELD_GET(I40E_PRTDCB_GENC_PFCLDA_MASK
, val
);
28 * i40e_dcbnl_ieee_getets - retrieve local IEEE ETS configuration
29 * @dev: the corresponding netdev
30 * @ets: structure to hold the ETS information
32 * Returns local IEEE ETS configuration
34 static int i40e_dcbnl_ieee_getets(struct net_device
*dev
,
37 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
38 struct i40e_dcbx_config
*dcbxcfg
;
40 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
))
43 dcbxcfg
= &pf
->hw
.local_dcbx_config
;
44 ets
->willing
= dcbxcfg
->etscfg
.willing
;
45 ets
->ets_cap
= I40E_MAX_TRAFFIC_CLASS
;
46 ets
->cbs
= dcbxcfg
->etscfg
.cbs
;
47 memcpy(ets
->tc_tx_bw
, dcbxcfg
->etscfg
.tcbwtable
,
48 sizeof(ets
->tc_tx_bw
));
49 memcpy(ets
->tc_rx_bw
, dcbxcfg
->etscfg
.tcbwtable
,
50 sizeof(ets
->tc_rx_bw
));
51 memcpy(ets
->tc_tsa
, dcbxcfg
->etscfg
.tsatable
,
53 memcpy(ets
->prio_tc
, dcbxcfg
->etscfg
.prioritytable
,
54 sizeof(ets
->prio_tc
));
55 memcpy(ets
->tc_reco_bw
, dcbxcfg
->etsrec
.tcbwtable
,
56 sizeof(ets
->tc_reco_bw
));
57 memcpy(ets
->tc_reco_tsa
, dcbxcfg
->etsrec
.tsatable
,
58 sizeof(ets
->tc_reco_tsa
));
59 memcpy(ets
->reco_prio_tc
, dcbxcfg
->etscfg
.prioritytable
,
60 sizeof(ets
->reco_prio_tc
));
66 * i40e_dcbnl_ieee_getpfc - retrieve local IEEE PFC configuration
67 * @dev: the corresponding netdev
68 * @pfc: structure to hold the PFC information
70 * Returns local IEEE PFC configuration
72 static int i40e_dcbnl_ieee_getpfc(struct net_device
*dev
,
75 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
76 struct i40e_dcbx_config
*dcbxcfg
;
77 struct i40e_hw
*hw
= &pf
->hw
;
80 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
))
83 dcbxcfg
= &hw
->local_dcbx_config
;
84 pfc
->pfc_cap
= dcbxcfg
->pfc
.pfccap
;
85 pfc
->pfc_en
= dcbxcfg
->pfc
.pfcenable
;
86 pfc
->mbc
= dcbxcfg
->pfc
.mbc
;
87 i40e_get_pfc_delay(hw
, &pfc
->delay
);
89 /* Get Requests/Indications */
90 for (i
= 0; i
< I40E_MAX_TRAFFIC_CLASS
; i
++) {
91 pfc
->requests
[i
] = pf
->stats
.priority_xoff_tx
[i
];
92 pfc
->indications
[i
] = pf
->stats
.priority_xoff_rx
[i
];
99 * i40e_dcbnl_ieee_setets - set IEEE ETS configuration
100 * @netdev: the corresponding netdev
101 * @ets: structure to hold the ETS information
103 * Set IEEE ETS configuration
105 static int i40e_dcbnl_ieee_setets(struct net_device
*netdev
,
106 struct ieee_ets
*ets
)
108 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
109 struct i40e_dcbx_config
*old_cfg
;
112 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
113 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
116 old_cfg
= &pf
->hw
.local_dcbx_config
;
117 /* Copy current config into temp */
118 pf
->tmp_cfg
= *old_cfg
;
120 /* Update the ETS configuration for temp */
121 pf
->tmp_cfg
.etscfg
.willing
= ets
->willing
;
122 pf
->tmp_cfg
.etscfg
.maxtcs
= I40E_MAX_TRAFFIC_CLASS
;
123 pf
->tmp_cfg
.etscfg
.cbs
= ets
->cbs
;
124 for (i
= 0; i
< I40E_MAX_TRAFFIC_CLASS
; i
++) {
125 pf
->tmp_cfg
.etscfg
.tcbwtable
[i
] = ets
->tc_tx_bw
[i
];
126 pf
->tmp_cfg
.etscfg
.tsatable
[i
] = ets
->tc_tsa
[i
];
127 pf
->tmp_cfg
.etscfg
.prioritytable
[i
] = ets
->prio_tc
[i
];
128 pf
->tmp_cfg
.etsrec
.tcbwtable
[i
] = ets
->tc_reco_bw
[i
];
129 pf
->tmp_cfg
.etsrec
.tsatable
[i
] = ets
->tc_reco_tsa
[i
];
130 pf
->tmp_cfg
.etsrec
.prioritytable
[i
] = ets
->reco_prio_tc
[i
];
133 /* Commit changes to HW */
134 ret
= i40e_hw_dcb_config(pf
, &pf
->tmp_cfg
);
136 dev_info(&pf
->pdev
->dev
,
137 "Failed setting DCB ETS configuration err %pe aq_err %s\n",
139 i40e_aq_str(&pf
->hw
, pf
->hw
.aq
.asq_last_status
));
147 * i40e_dcbnl_ieee_setpfc - set local IEEE PFC configuration
148 * @netdev: the corresponding netdev
149 * @pfc: structure to hold the PFC information
151 * Sets local IEEE PFC configuration
153 static int i40e_dcbnl_ieee_setpfc(struct net_device
*netdev
,
154 struct ieee_pfc
*pfc
)
156 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
157 struct i40e_dcbx_config
*old_cfg
;
160 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
161 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
164 old_cfg
= &pf
->hw
.local_dcbx_config
;
165 /* Copy current config into temp */
166 pf
->tmp_cfg
= *old_cfg
;
168 pf
->tmp_cfg
.pfc
.pfccap
= pfc
->pfc_cap
;
170 pf
->tmp_cfg
.pfc
.pfccap
= I40E_MAX_TRAFFIC_CLASS
;
171 pf
->tmp_cfg
.pfc
.pfcenable
= pfc
->pfc_en
;
173 ret
= i40e_hw_dcb_config(pf
, &pf
->tmp_cfg
);
175 dev_info(&pf
->pdev
->dev
,
176 "Failed setting DCB PFC configuration err %pe aq_err %s\n",
178 i40e_aq_str(&pf
->hw
, pf
->hw
.aq
.asq_last_status
));
186 * i40e_dcbnl_ieee_setapp - set local IEEE App configuration
187 * @netdev: the corresponding netdev
188 * @app: structure to hold the Application information
190 * Sets local IEEE App configuration
192 static int i40e_dcbnl_ieee_setapp(struct net_device
*netdev
,
195 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
196 struct i40e_dcb_app_priority_table new_app
;
197 struct i40e_dcbx_config
*old_cfg
;
200 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
201 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
204 old_cfg
= &pf
->hw
.local_dcbx_config
;
205 if (old_cfg
->numapps
== I40E_DCBX_MAX_APPS
)
208 ret
= dcb_ieee_setapp(netdev
, app
);
212 new_app
.selector
= app
->selector
;
213 new_app
.protocolid
= app
->protocol
;
214 new_app
.priority
= app
->priority
;
215 /* Already internally available */
216 if (i40e_dcbnl_find_app(old_cfg
, &new_app
))
219 /* Copy current config into temp */
220 pf
->tmp_cfg
= *old_cfg
;
222 pf
->tmp_cfg
.app
[pf
->tmp_cfg
.numapps
++] = new_app
;
224 ret
= i40e_hw_dcb_config(pf
, &pf
->tmp_cfg
);
226 dev_info(&pf
->pdev
->dev
,
227 "Failed setting DCB configuration err %pe aq_err %s\n",
229 i40e_aq_str(&pf
->hw
, pf
->hw
.aq
.asq_last_status
));
237 * i40e_dcbnl_ieee_delapp - delete local IEEE App configuration
238 * @netdev: the corresponding netdev
239 * @app: structure to hold the Application information
241 * Deletes local IEEE App configuration other than the first application
242 * required by firmware
244 static int i40e_dcbnl_ieee_delapp(struct net_device
*netdev
,
247 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
248 struct i40e_dcbx_config
*old_cfg
;
251 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
252 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
255 ret
= dcb_ieee_delapp(netdev
, app
);
259 old_cfg
= &pf
->hw
.local_dcbx_config
;
260 /* Need one app for FW so keep it */
261 if (old_cfg
->numapps
== 1)
264 /* Copy current config into temp */
265 pf
->tmp_cfg
= *old_cfg
;
267 /* Find and reset the app */
268 for (i
= 1; i
< pf
->tmp_cfg
.numapps
; i
++) {
269 if (app
->selector
== pf
->tmp_cfg
.app
[i
].selector
&&
270 app
->protocol
== pf
->tmp_cfg
.app
[i
].protocolid
&&
271 app
->priority
== pf
->tmp_cfg
.app
[i
].priority
) {
272 /* Reset the app data */
273 pf
->tmp_cfg
.app
[i
].selector
= 0;
274 pf
->tmp_cfg
.app
[i
].protocolid
= 0;
275 pf
->tmp_cfg
.app
[i
].priority
= 0;
280 /* If the specific DCB app not found */
281 if (i
== pf
->tmp_cfg
.numapps
)
284 pf
->tmp_cfg
.numapps
--;
285 /* Overwrite the tmp_cfg app */
286 for (j
= i
; j
< pf
->tmp_cfg
.numapps
; j
++)
287 pf
->tmp_cfg
.app
[j
] = old_cfg
->app
[j
+ 1];
289 ret
= i40e_hw_dcb_config(pf
, &pf
->tmp_cfg
);
291 dev_info(&pf
->pdev
->dev
,
292 "Failed setting DCB configuration err %pe aq_err %s\n",
294 i40e_aq_str(&pf
->hw
, pf
->hw
.aq
.asq_last_status
));
302 * i40e_dcbnl_getstate - Get DCB enabled state
303 * @netdev: the corresponding netdev
305 * Get the current DCB enabled state
307 static u8
i40e_dcbnl_getstate(struct net_device
*netdev
)
309 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
311 dev_dbg(&pf
->pdev
->dev
, "DCB state=%d\n",
312 test_bit(I40E_FLAG_DCB_ENA
, pf
->flags
) ? 1 : 0);
313 return test_bit(I40E_FLAG_DCB_ENA
, pf
->flags
) ? 1 : 0;
317 * i40e_dcbnl_setstate - Set DCB state
318 * @netdev: the corresponding netdev
319 * @state: enable or disable
323 static u8
i40e_dcbnl_setstate(struct net_device
*netdev
, u8 state
)
325 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
326 int ret
= I40E_DCBNL_STATUS_SUCCESS
;
328 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
329 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
332 dev_dbg(&pf
->pdev
->dev
, "new state=%d current state=%d\n",
333 state
, test_bit(I40E_FLAG_DCB_ENA
, pf
->flags
) ? 1 : 0);
335 if (!state
== !test_bit(I40E_FLAG_DCB_ENA
, pf
->flags
))
338 if (i40e_is_sw_dcb(pf
)) {
340 set_bit(I40E_FLAG_DCB_ENA
, pf
->flags
);
341 memcpy(&pf
->hw
.desired_dcbx_config
,
342 &pf
->hw
.local_dcbx_config
,
343 sizeof(struct i40e_dcbx_config
));
345 clear_bit(I40E_FLAG_DCB_ENA
, pf
->flags
);
348 /* Cannot directly manipulate FW LLDP Agent */
349 ret
= I40E_DCBNL_STATUS_ERROR
;
355 * i40e_dcbnl_set_pg_tc_cfg_tx - Set CEE PG Tx config
356 * @netdev: the corresponding netdev
357 * @tc: the corresponding traffic class
358 * @prio_type: the traffic priority type
359 * @bwg_id: the BW group id the traffic class belongs to
360 * @bw_pct: the BW percentage for the corresponding BWG
361 * @up_map: prio mapped to corresponding tc
363 * Set Tx PG settings for CEE mode
365 static void i40e_dcbnl_set_pg_tc_cfg_tx(struct net_device
*netdev
, int tc
,
366 u8 prio_type
, u8 bwg_id
, u8 bw_pct
,
369 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
372 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
373 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
376 /* LLTC not supported yet */
377 if (tc
>= I40E_MAX_TRAFFIC_CLASS
)
380 /* prio_type, bwg_id and bw_pct per UP are not supported */
382 /* Use only up_map to map tc */
383 for (i
= 0; i
< I40E_MAX_TRAFFIC_CLASS
; i
++) {
385 pf
->tmp_cfg
.etscfg
.prioritytable
[i
] = tc
;
387 pf
->tmp_cfg
.etscfg
.tsatable
[tc
] = I40E_IEEE_TSA_ETS
;
388 dev_dbg(&pf
->pdev
->dev
,
389 "Set PG config tc=%d bwg_id=%d prio_type=%d bw_pct=%d up_map=%d\n",
390 tc
, bwg_id
, prio_type
, bw_pct
, up_map
);
394 * i40e_dcbnl_set_pg_bwg_cfg_tx - Set CEE PG Tx BW config
395 * @netdev: the corresponding netdev
396 * @pgid: the corresponding traffic class
397 * @bw_pct: the BW percentage for the specified traffic class
399 * Set Tx BW settings for CEE mode
401 static void i40e_dcbnl_set_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
404 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
406 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
407 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
410 /* LLTC not supported yet */
411 if (pgid
>= I40E_MAX_TRAFFIC_CLASS
)
414 pf
->tmp_cfg
.etscfg
.tcbwtable
[pgid
] = bw_pct
;
415 dev_dbg(&pf
->pdev
->dev
, "Set PG BW config tc=%d bw_pct=%d\n",
420 * i40e_dcbnl_set_pg_tc_cfg_rx - Set CEE PG Rx config
421 * @netdev: the corresponding netdev
422 * @prio: the corresponding traffic class
423 * @prio_type: the traffic priority type
424 * @pgid: the BW group id the traffic class belongs to
425 * @bw_pct: the BW percentage for the corresponding BWG
426 * @up_map: prio mapped to corresponding tc
428 * Set Rx BW settings for CEE mode. The hardware does not support this
429 * so we won't allow setting of this parameter.
431 static void i40e_dcbnl_set_pg_tc_cfg_rx(struct net_device
*netdev
,
432 int __always_unused prio
,
433 u8 __always_unused prio_type
,
434 u8 __always_unused pgid
,
435 u8 __always_unused bw_pct
,
436 u8 __always_unused up_map
)
438 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
440 dev_dbg(&pf
->pdev
->dev
, "Rx TC PG Config Not Supported.\n");
444 * i40e_dcbnl_set_pg_bwg_cfg_rx - Set CEE PG Rx config
445 * @netdev: the corresponding netdev
446 * @pgid: the corresponding traffic class
447 * @bw_pct: the BW percentage for the specified traffic class
449 * Set Rx BW settings for CEE mode. The hardware does not support this
450 * so we won't allow setting of this parameter.
452 static void i40e_dcbnl_set_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
,
455 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
457 dev_dbg(&pf
->pdev
->dev
, "Rx BWG PG Config Not Supported.\n");
461 * i40e_dcbnl_get_pg_tc_cfg_tx - Get CEE PG Tx config
462 * @netdev: the corresponding netdev
463 * @prio: the corresponding user priority
464 * @prio_type: traffic priority type
465 * @pgid: the BW group ID the traffic class belongs to
466 * @bw_pct: BW percentage for the corresponding BWG
467 * @up_map: prio mapped to corresponding TC
469 * Get Tx PG settings for CEE mode
471 static void i40e_dcbnl_get_pg_tc_cfg_tx(struct net_device
*netdev
, int prio
,
472 u8 __always_unused
*prio_type
,
474 u8 __always_unused
*bw_pct
,
475 u8 __always_unused
*up_map
)
477 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
479 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
480 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
483 if (prio
>= I40E_MAX_USER_PRIORITY
)
486 *pgid
= pf
->hw
.local_dcbx_config
.etscfg
.prioritytable
[prio
];
487 dev_dbg(&pf
->pdev
->dev
, "Get PG config prio=%d tc=%d\n",
492 * i40e_dcbnl_get_pg_bwg_cfg_tx - Get CEE PG BW config
493 * @netdev: the corresponding netdev
494 * @pgid: the corresponding traffic class
495 * @bw_pct: the BW percentage for the corresponding TC
497 * Get Tx BW settings for given TC in CEE mode
499 static void i40e_dcbnl_get_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
502 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
504 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
505 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
508 if (pgid
>= I40E_MAX_TRAFFIC_CLASS
)
511 *bw_pct
= pf
->hw
.local_dcbx_config
.etscfg
.tcbwtable
[pgid
];
512 dev_dbg(&pf
->pdev
->dev
, "Get PG BW config tc=%d bw_pct=%d\n",
517 * i40e_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config
518 * @netdev: the corresponding netdev
519 * @prio: the corresponding user priority
520 * @prio_type: the traffic priority type
522 * @bw_pct: the BW percentage for the corresponding BWG
523 * @up_map: prio mapped to corresponding TC
525 * Get Rx PG settings for CEE mode. The UP2TC map is applied in same
526 * manner for Tx and Rx (symmetrical) so return the TC information for
527 * given priority accordingly.
529 static void i40e_dcbnl_get_pg_tc_cfg_rx(struct net_device
*netdev
, int prio
,
530 u8
*prio_type
, u8
*pgid
, u8
*bw_pct
,
533 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
535 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
536 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
539 if (prio
>= I40E_MAX_USER_PRIORITY
)
542 *pgid
= pf
->hw
.local_dcbx_config
.etscfg
.prioritytable
[prio
];
546 * i40e_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config
547 * @netdev: the corresponding netdev
548 * @pgid: the corresponding traffic class
549 * @bw_pct: the BW percentage for the corresponding TC
551 * Get Rx BW settings for given TC in CEE mode
552 * The adapter doesn't support Rx ETS and runs in strict priority
553 * mode in Rx path and hence just return 0.
555 static void i40e_dcbnl_get_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
,
558 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
560 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
561 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
567 * i40e_dcbnl_set_pfc_cfg - Set CEE PFC configuration
568 * @netdev: the corresponding netdev
569 * @prio: the corresponding user priority
570 * @setting: the PFC setting for given priority
572 * Set the PFC enabled/disabled setting for given user priority
574 static void i40e_dcbnl_set_pfc_cfg(struct net_device
*netdev
, int prio
,
577 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
579 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
580 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
583 if (prio
>= I40E_MAX_USER_PRIORITY
)
586 pf
->tmp_cfg
.pfc
.pfccap
= I40E_MAX_TRAFFIC_CLASS
;
588 pf
->tmp_cfg
.pfc
.pfcenable
|= BIT(prio
);
590 pf
->tmp_cfg
.pfc
.pfcenable
&= ~BIT(prio
);
591 dev_dbg(&pf
->pdev
->dev
,
592 "Set PFC Config up=%d setting=%d pfcenable=0x%x\n",
593 prio
, setting
, pf
->tmp_cfg
.pfc
.pfcenable
);
597 * i40e_dcbnl_get_pfc_cfg - Get CEE PFC configuration
598 * @netdev: the corresponding netdev
599 * @prio: the corresponding user priority
600 * @setting: the PFC setting for given priority
602 * Get the PFC enabled/disabled setting for given user priority
604 static void i40e_dcbnl_get_pfc_cfg(struct net_device
*netdev
, int prio
,
607 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
609 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
610 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
613 if (prio
>= I40E_MAX_USER_PRIORITY
)
616 *setting
= (pf
->hw
.local_dcbx_config
.pfc
.pfcenable
>> prio
) & 0x1;
617 dev_dbg(&pf
->pdev
->dev
,
618 "Get PFC Config up=%d setting=%d pfcenable=0x%x\n",
619 prio
, *setting
, pf
->hw
.local_dcbx_config
.pfc
.pfcenable
);
623 * i40e_dcbnl_cee_set_all - Commit CEE DCB settings to hardware
624 * @netdev: the corresponding netdev
626 * Commit the current DCB configuration to hardware
628 static u8
i40e_dcbnl_cee_set_all(struct net_device
*netdev
)
630 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
633 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
634 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
635 return I40E_DCBNL_STATUS_ERROR
;
637 dev_dbg(&pf
->pdev
->dev
, "Commit DCB Configuration to the hardware\n");
638 err
= i40e_hw_dcb_config(pf
, &pf
->tmp_cfg
);
640 return err
? I40E_DCBNL_STATUS_ERROR
: I40E_DCBNL_STATUS_SUCCESS
;
644 * i40e_dcbnl_get_cap - Get DCBX capabilities of adapter
645 * @netdev: the corresponding netdev
646 * @capid: the capability type
647 * @cap: the capability value
649 * Return the capability value for a given capability type
651 static u8
i40e_dcbnl_get_cap(struct net_device
*netdev
, int capid
, u8
*cap
)
653 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
655 if (!test_bit(I40E_FLAG_DCB_CAPABLE
, pf
->flags
))
656 return I40E_DCBNL_STATUS_ERROR
;
659 case DCB_CAP_ATTR_PG
:
660 case DCB_CAP_ATTR_PFC
:
663 case DCB_CAP_ATTR_PG_TCS
:
664 case DCB_CAP_ATTR_PFC_TCS
:
667 case DCB_CAP_ATTR_DCBX
:
670 case DCB_CAP_ATTR_UP2TC
:
671 case DCB_CAP_ATTR_GSP
:
672 case DCB_CAP_ATTR_BCN
:
678 dev_dbg(&pf
->pdev
->dev
, "Get Capability cap=%d capval=0x%x\n",
680 return I40E_DCBNL_STATUS_SUCCESS
;
684 * i40e_dcbnl_getnumtcs - Get max number of traffic classes supported
685 * @netdev: the corresponding netdev
687 * @num: total number of TCs supported by the device
689 * Return the total number of TCs supported by the adapter
691 static int i40e_dcbnl_getnumtcs(struct net_device
*netdev
, int tcid
, u8
*num
)
693 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
695 if (!test_bit(I40E_FLAG_DCB_CAPABLE
, pf
->flags
))
698 *num
= I40E_MAX_TRAFFIC_CLASS
;
703 * i40e_dcbnl_setnumtcs - Set CEE number of traffic classes
704 * @netdev: the corresponding netdev
706 * @num: total number of TCs
708 * Set the total number of TCs (Unsupported)
710 static int i40e_dcbnl_setnumtcs(struct net_device
*netdev
, int tcid
, u8 num
)
716 * i40e_dcbnl_getpfcstate - Get CEE PFC mode
717 * @netdev: the corresponding netdev
719 * Get the current PFC enabled state
721 static u8
i40e_dcbnl_getpfcstate(struct net_device
*netdev
)
723 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
725 /* Return enabled if any PFC enabled UP */
726 if (pf
->hw
.local_dcbx_config
.pfc
.pfcenable
)
733 * i40e_dcbnl_setpfcstate - Set CEE PFC mode
734 * @netdev: the corresponding netdev
735 * @state: required state
737 * The PFC state to be set; this is enabled/disabled based on the PFC
738 * priority settings and not via this call for i40e driver
740 static void i40e_dcbnl_setpfcstate(struct net_device
*netdev
, u8 state
)
742 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
744 dev_dbg(&pf
->pdev
->dev
, "PFC State is modified via PFC config.\n");
748 * i40e_dcbnl_getapp - Get CEE APP
749 * @netdev: the corresponding netdev
750 * @idtype: the App selector
751 * @id: the App ethtype or port number
753 * Return the CEE mode app for the given idtype and id
755 static int i40e_dcbnl_getapp(struct net_device
*netdev
, u8 idtype
, u16 id
)
757 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
758 struct dcb_app app
= {
763 if (!(pf
->dcbx_cap
& DCB_CAP_DCBX_VER_CEE
) ||
764 (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
))
767 return dcb_getapp(netdev
, &app
);
771 * i40e_dcbnl_setdcbx - set required DCBx capability
772 * @netdev: the corresponding netdev
773 * @mode: new DCB mode managed or CEE+IEEE
775 * Set DCBx capability features
777 static u8
i40e_dcbnl_setdcbx(struct net_device
*netdev
, u8 mode
)
779 struct i40e_pf
*pf
= i40e_netdev_to_pf(netdev
);
781 /* Do not allow to set mode if managed by Firmware */
782 if (pf
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
)
783 return I40E_DCBNL_STATUS_ERROR
;
785 /* No support for LLD_MANAGED modes or CEE+IEEE */
786 if ((mode
& DCB_CAP_DCBX_LLD_MANAGED
) ||
787 ((mode
& DCB_CAP_DCBX_VER_IEEE
) && (mode
& DCB_CAP_DCBX_VER_CEE
)) ||
788 !(mode
& DCB_CAP_DCBX_HOST
))
789 return I40E_DCBNL_STATUS_ERROR
;
791 /* Already set to the given mode no change */
792 if (mode
== pf
->dcbx_cap
)
793 return I40E_DCBNL_STATUS_SUCCESS
;
796 if (mode
& DCB_CAP_DCBX_VER_CEE
)
797 pf
->hw
.local_dcbx_config
.dcbx_mode
= I40E_DCBX_MODE_CEE
;
799 pf
->hw
.local_dcbx_config
.dcbx_mode
= I40E_DCBX_MODE_IEEE
;
801 dev_dbg(&pf
->pdev
->dev
, "mode=%d\n", mode
);
802 return I40E_DCBNL_STATUS_SUCCESS
;
806 * i40e_dcbnl_getdcbx - retrieve current DCBx capability
807 * @dev: the corresponding netdev
809 * Returns DCBx capability features
811 static u8
i40e_dcbnl_getdcbx(struct net_device
*dev
)
813 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
819 * i40e_dcbnl_get_perm_hw_addr - MAC address used by DCBx
820 * @dev: the corresponding netdev
821 * @perm_addr: buffer to store the MAC address
823 * Returns the SAN MAC address used for LLDP exchange
825 static void i40e_dcbnl_get_perm_hw_addr(struct net_device
*dev
,
828 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
831 memset(perm_addr
, 0xff, MAX_ADDR_LEN
);
833 for (i
= 0; i
< dev
->addr_len
; i
++)
834 perm_addr
[i
] = pf
->hw
.mac
.perm_addr
[i
];
837 static const struct dcbnl_rtnl_ops dcbnl_ops
= {
838 .ieee_getets
= i40e_dcbnl_ieee_getets
,
839 .ieee_getpfc
= i40e_dcbnl_ieee_getpfc
,
840 .getdcbx
= i40e_dcbnl_getdcbx
,
841 .getpermhwaddr
= i40e_dcbnl_get_perm_hw_addr
,
842 .ieee_setets
= i40e_dcbnl_ieee_setets
,
843 .ieee_setpfc
= i40e_dcbnl_ieee_setpfc
,
844 .ieee_setapp
= i40e_dcbnl_ieee_setapp
,
845 .ieee_delapp
= i40e_dcbnl_ieee_delapp
,
846 .getstate
= i40e_dcbnl_getstate
,
847 .setstate
= i40e_dcbnl_setstate
,
848 .setpgtccfgtx
= i40e_dcbnl_set_pg_tc_cfg_tx
,
849 .setpgbwgcfgtx
= i40e_dcbnl_set_pg_bwg_cfg_tx
,
850 .setpgtccfgrx
= i40e_dcbnl_set_pg_tc_cfg_rx
,
851 .setpgbwgcfgrx
= i40e_dcbnl_set_pg_bwg_cfg_rx
,
852 .getpgtccfgtx
= i40e_dcbnl_get_pg_tc_cfg_tx
,
853 .getpgbwgcfgtx
= i40e_dcbnl_get_pg_bwg_cfg_tx
,
854 .getpgtccfgrx
= i40e_dcbnl_get_pg_tc_cfg_rx
,
855 .getpgbwgcfgrx
= i40e_dcbnl_get_pg_bwg_cfg_rx
,
856 .setpfccfg
= i40e_dcbnl_set_pfc_cfg
,
857 .getpfccfg
= i40e_dcbnl_get_pfc_cfg
,
858 .setall
= i40e_dcbnl_cee_set_all
,
859 .getcap
= i40e_dcbnl_get_cap
,
860 .getnumtcs
= i40e_dcbnl_getnumtcs
,
861 .setnumtcs
= i40e_dcbnl_setnumtcs
,
862 .getpfcstate
= i40e_dcbnl_getpfcstate
,
863 .setpfcstate
= i40e_dcbnl_setpfcstate
,
864 .getapp
= i40e_dcbnl_getapp
,
865 .setdcbx
= i40e_dcbnl_setdcbx
,
869 * i40e_dcbnl_set_all - set all the apps and ieee data from DCBx config
870 * @vsi: the corresponding vsi
872 * Set up all the IEEE APPs in the DCBNL App Table and generate event for
875 void i40e_dcbnl_set_all(struct i40e_vsi
*vsi
)
877 struct net_device
*dev
= vsi
->netdev
;
878 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
879 struct i40e_dcbx_config
*dcbxcfg
;
880 struct i40e_hw
*hw
= &pf
->hw
;
885 /* SW DCB taken care by DCBNL set calls */
886 if (pf
->dcbx_cap
& DCB_CAP_DCBX_HOST
)
889 /* DCB not enabled */
890 if (!test_bit(I40E_FLAG_DCB_ENA
, pf
->flags
))
893 /* MFP mode but not an iSCSI PF so return */
894 if (test_bit(I40E_FLAG_MFP_ENA
, pf
->flags
) && !(hw
->func_caps
.iscsi
))
897 dcbxcfg
= &hw
->local_dcbx_config
;
899 /* Set up all the App TLVs if DCBx is negotiated */
900 for (i
= 0; i
< dcbxcfg
->numapps
; i
++) {
901 prio
= dcbxcfg
->app
[i
].priority
;
902 tc_map
= BIT(dcbxcfg
->etscfg
.prioritytable
[prio
]);
904 /* Add APP only if the TC is enabled for this VSI */
905 if (tc_map
& vsi
->tc_config
.enabled_tc
) {
906 sapp
.selector
= dcbxcfg
->app
[i
].selector
;
907 sapp
.protocol
= dcbxcfg
->app
[i
].protocolid
;
908 sapp
.priority
= prio
;
909 dcb_ieee_setapp(dev
, &sapp
);
913 /* Notify user-space of the changes */
914 dcbnl_ieee_notify(dev
, RTM_SETDCB
, DCB_CMD_IEEE_SET
, 0, 0);
918 * i40e_dcbnl_vsi_del_app - Delete APP for given VSI
919 * @vsi: the corresponding vsi
920 * @app: APP to delete
922 * Delete given APP from the DCBNL APP table for given
925 static int i40e_dcbnl_vsi_del_app(struct i40e_vsi
*vsi
,
926 struct i40e_dcb_app_priority_table
*app
)
928 struct net_device
*dev
= vsi
->netdev
;
934 sapp
.selector
= app
->selector
;
935 sapp
.protocol
= app
->protocolid
;
936 sapp
.priority
= app
->priority
;
937 return dcb_ieee_delapp(dev
, &sapp
);
941 * i40e_dcbnl_del_app - Delete APP on all VSIs
942 * @pf: the corresponding PF
943 * @app: APP to delete
945 * Delete given APP from all the VSIs for given PF
947 static void i40e_dcbnl_del_app(struct i40e_pf
*pf
,
948 struct i40e_dcb_app_priority_table
*app
)
950 struct i40e_vsi
*vsi
;
953 i40e_pf_for_each_vsi(pf
, v
, vsi
)
955 err
= i40e_dcbnl_vsi_del_app(vsi
, app
);
956 dev_dbg(&pf
->pdev
->dev
, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n",
957 vsi
->seid
, err
, app
->selector
,
958 app
->protocolid
, app
->priority
);
963 * i40e_dcbnl_find_app - Search APP in given DCB config
964 * @cfg: DCBX configuration data
965 * @app: APP to search for
967 * Find given APP in the DCB configuration
969 static bool i40e_dcbnl_find_app(struct i40e_dcbx_config
*cfg
,
970 struct i40e_dcb_app_priority_table
*app
)
974 for (i
= 0; i
< cfg
->numapps
; i
++) {
975 if (app
->selector
== cfg
->app
[i
].selector
&&
976 app
->protocolid
== cfg
->app
[i
].protocolid
&&
977 app
->priority
== cfg
->app
[i
].priority
)
985 * i40e_dcbnl_flush_apps - Delete all removed APPs
986 * @pf: the corresponding PF
987 * @old_cfg: old DCBX configuration data
988 * @new_cfg: new DCBX configuration data
990 * Find and delete all APPs that are not present in the passed
993 void i40e_dcbnl_flush_apps(struct i40e_pf
*pf
,
994 struct i40e_dcbx_config
*old_cfg
,
995 struct i40e_dcbx_config
*new_cfg
)
997 struct i40e_dcb_app_priority_table app
;
1000 /* MFP mode but not an iSCSI PF so return */
1001 if (test_bit(I40E_FLAG_MFP_ENA
, pf
->flags
) && !(pf
->hw
.func_caps
.iscsi
))
1004 for (i
= 0; i
< old_cfg
->numapps
; i
++) {
1005 app
= old_cfg
->app
[i
];
1006 /* The APP is not available anymore delete it */
1007 if (!i40e_dcbnl_find_app(new_cfg
, &app
))
1008 i40e_dcbnl_del_app(pf
, &app
);
1013 * i40e_dcbnl_setup - DCBNL setup
1014 * @vsi: the corresponding vsi
1016 * Set up DCBNL ops and initial APP TLVs
1018 void i40e_dcbnl_setup(struct i40e_vsi
*vsi
)
1020 struct net_device
*dev
= vsi
->netdev
;
1021 struct i40e_pf
*pf
= i40e_netdev_to_pf(dev
);
1023 /* Not DCB capable */
1024 if (!test_bit(I40E_FLAG_DCB_CAPABLE
, pf
->flags
))
1027 dev
->dcbnl_ops
= &dcbnl_ops
;
1029 /* Set initial IEEE DCB settings */
1030 i40e_dcbnl_set_all(vsi
);
1032 #endif /* CONFIG_I40E_DCB */