20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/netdevice.h>
23 #include <linux/types.h>
24 #include <linux/errno.h>
25 #include <linux/rtnetlink.h>
33 static int bnx2x_dcbx_stop_hw_tx(
struct bnx2x *
bp);
34 static void bnx2x_pfc_set_pfc(
struct bnx2x *
bp);
35 static void bnx2x_dcbx_update_ets_params(
struct bnx2x *
bp);
36 static int bnx2x_dcbx_resume_hw_tx(
struct bnx2x *
bp);
37 static void bnx2x_dcbx_get_ets_pri_pg_tbl(
struct bnx2x *
bp,
38 u32 *set_configuration_ets_pg,
40 static void bnx2x_dcbx_get_num_pg_traf_type(
struct bnx2x *
bp,
41 u32 *pg_pri_orginal_spread,
43 static void bnx2x_dcbx_fill_cos_params(
struct bnx2x *
bp,
46 u32 *pg_pri_orginal_spread);
47 static void bnx2x_dcbx_separate_pauseable_from_non(
struct bnx2x *
bp,
49 u32 *pg_pri_orginal_spread,
51 static void bnx2x_dcbx_fw_struct(
struct bnx2x *
bp,
55 static void bnx2x_read_data(
struct bnx2x *
bp,
u32 *buff,
59 for (i = 0; i < len; i += 4, buff++)
60 *buff =
REG_RD(bp, addr + i);
63 static void bnx2x_write_data(
struct bnx2x *bp,
u32 *buff,
67 for (i = 0; i < len; i += 4, buff++)
68 REG_WR(bp, addr + i, *buff);
71 static void bnx2x_pfc_set(
struct bnx2x *bp)
116 static void bnx2x_pfc_clear(
struct bnx2x *bp)
126 static void bnx2x_dump_dcbx_drv_param(
struct bnx2x *bp,
135 "local_mib.features.ets.enabled %x\n", features->
ets.enabled);
138 "local_mib.features.ets.pg_bw_tbl[%d] %d\n", i,
142 "local_mib.features.ets.pri_pg_tbl[%d] %d\n", i,
147 features->
pfc.pri_en_bitmap);
149 features->
pfc.pfc_caps);
151 features->
pfc.enabled);
154 features->
app.default_pri);
156 features->
app.tc_supported);
158 features->
app.enabled);
161 "dcbx_features.app.app_pri_tbl[%x].app_id %x\n",
162 i, features->
app.app_pri_tbl[i].app_id);
164 "dcbx_features.app.app_pri_tbl[%x].pri_bitmap %x\n",
165 i, features->
app.app_pri_tbl[i].pri_bitmap);
167 "dcbx_features.app.app_pri_tbl[%x].appBitfield %x\n",
168 i, features->
app.app_pri_tbl[i].appBitfield);
172 static void bnx2x_dcbx_get_ap_priority(
struct bnx2x *bp,
182 while ((MAX_PFC_PRIORITIES == pri) && (0 != index)) {
183 pri_mask = 1 <<
index;
189 if (pri < MAX_PFC_PRIORITIES)
190 ttp[llfc_traf_type] =
max_t(
u32, ttp[llfc_traf_type], pri);
193 static void bnx2x_dcbx_get_ap_feature(
struct bnx2x *bp,
216 if (app->default_pri < MAX_PFC_PRIORITIES)
224 DCBX_APP_SF_ETH_TYPE) &&
226 bnx2x_dcbx_get_ap_priority(bp,
227 entry[index].pri_bitmap,
233 bnx2x_dcbx_get_ap_priority(bp,
234 entry[index].pri_bitmap,
245 static void bnx2x_dcbx_get_ets_feature(
struct bnx2x *bp,
277 bnx2x_dcbx_get_ets_pri_pg_tbl(bp,
278 pg_pri_orginal_spread,
281 bnx2x_dcbx_get_num_pg_traf_type(bp,
282 pg_pri_orginal_spread,
286 ets, pg_pri_orginal_spread);
298 static void bnx2x_dcbx_get_pfc_feature(
struct bnx2x *bp,
312 ~(pfc->pri_en_bitmap);
321 static void bnx2x_dcbx_map_nw(
struct bnx2x *bp)
332 unmapped &= ~(1 << ttp[i]);
339 "cos %d extended with 0x%08x\n", i, unmapped);
346 static void bnx2x_get_dcbx_drv_param(
struct bnx2x *bp,
350 bnx2x_dcbx_get_ap_feature(bp, &features->
app, error);
352 bnx2x_dcbx_get_pfc_feature(bp, &features->
pfc, error);
354 bnx2x_dcbx_get_ets_feature(bp, &features->
ets, error);
356 bnx2x_dcbx_map_nw(bp);
359 #define DCBX_LOCAL_MIB_MAX_TRY_READ (100)
360 static int bnx2x_dcbx_read_mib(
struct bnx2x *bp,
365 int max_try_read = 0;
366 u32 mib_size, prefix_seq_num, suffix_seq_num;
371 switch (read_mib_type) {
382 offset +=
BP_PORT(bp) * mib_size;
385 bnx2x_read_data(bp, base_mib_addr, offset, mib_size);
389 switch (read_mib_type) {
403 }
while ((prefix_seq_num != suffix_seq_num) &&
414 static void bnx2x_pfc_set_pfc(
struct bnx2x *bp)
427 static int bnx2x_dcbx_stop_hw_tx(
struct bnx2x *bp)
438 static int bnx2x_dcbx_resume_hw_tx(
struct bnx2x *bp)
447 bnx2x_dcbx_fw_struct(bp, tx_params);
453 static void bnx2x_dcbx_2cos_limit_update_ets_config(
struct bnx2x *bp)
472 BNX2X_ERR(
"all COS should have at least bw_limit or strict"
473 "ets->cos_params[0].strict= %x"
474 "ets->cos_params[0].bw_tbl= %x"
475 "ets->cos_params[1].strict= %x"
476 "ets->cos_params[1].bw_tbl= %x",
495 }
else if (bw_tbl_1 == 0) {
515 static void bnx2x_dcbx_update_ets_config(
struct bnx2x *bp)
527 BNX2X_ERR(
"COS can't be not BW and not SP\n");
532 ets_params.
cos[
i].params.sp_params.pri =
536 BNX2X_ERR(
"COS can't be not BW and not SP\n");
540 ets_params.
cos[
i].params.bw_params.bw =
548 BNX2X_ERR(
"bnx2x_ets_e3b0_config failed\n");
553 static void bnx2x_dcbx_update_ets_params(
struct bnx2x *bp)
562 bnx2x_dcbx_update_ets_config(bp);
564 bnx2x_dcbx_2cos_limit_update_ets_config(bp);
568 static int bnx2x_dcbx_read_shmem_remote_mib(
struct bnx2x *bp)
571 u32 dcbx_remote_mib_offset =
SHMEM2_RD(bp, dcbx_remote_mib_offset);
575 dcbx_remote_mib_offset);
578 BNX2X_ERR(
"FW doesn't support dcbx_remote_mib_offset\n");
582 rc = bnx2x_dcbx_read_mib(bp, (
u32 *)&remote_mib, dcbx_remote_mib_offset,
586 BNX2X_ERR(
"Faild to read remote mib from FW\n");
591 bp->dcbx_remote_feat = remote_mib.
features;
592 bp->dcbx_remote_flags = remote_mib.
flags;
597 static int bnx2x_dcbx_read_shmem_neg_results(
struct bnx2x *bp)
600 u32 dcbx_neg_res_offset =
SHMEM2_RD(bp, dcbx_neg_res_offset);
606 BNX2X_ERR(
"FW doesn't support dcbx_neg_res_offset\n");
610 rc = bnx2x_dcbx_read_mib(bp, (
u32 *)&local_mib, dcbx_neg_res_offset,
614 BNX2X_ERR(
"Faild to read local mib from FW\n");
632 for (pri = MAX_PFC_PRIORITIES - 1; pri > 0; pri--)
633 if (ent->pri_bitmap & (1 << pri))
641 return ((ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) ==
646 int bnx2x_dcbnl_update_applist(
struct bnx2x *bp,
bool delall)
650 for (i = 0; i < DCBX_MAX_APP_PROTOCOL && err == 0; i++) {
654 if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
655 u8 up = bnx2x_dcbx_dcbnl_app_up(ent);
660 app.selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
661 app.protocol = ent->app_id;
662 app.priority = delall ? 0 :
up;
671 static inline void bnx2x_dcbx_update_tc_mapping(
struct bnx2x *bp)
680 "tx_mapping %d --> %d\n", prio, cos);
704 bnx2x_dcbnl_update_applist(bp,
true);
707 if (bnx2x_dcbx_read_shmem_remote_mib(bp))
711 if (bnx2x_dcbx_read_shmem_neg_results(bp))
721 bnx2x_update_drv_flags(bp,
728 bnx2x_dcbnl_update_applist(bp,
false);
734 bnx2x_dcbx_update_tc_mapping(bp);
741 bnx2x_link_sync_notify(bp);
743 bnx2x_dcbx_stop_hw_tx(bp);
749 bnx2x_pfc_set_pfc(bp);
751 bnx2x_dcbx_update_ets_params(bp);
752 bnx2x_dcbx_resume_hw_tx(bp);
770 #define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \
771 BP_PORT(bp)*sizeof(struct lldp_admin_mib))
773 static void bnx2x_dcbx_admin_mib_updated_params(
struct bnx2x *bp,
774 u32 dcbx_lldp_params_offset)
787 bnx2x_read_data(bp, (
u32 *)&admin_mib, offset,
873 traf_type = other_traf_type++;
875 af->
app.app_pri_tbl[traf_type].app_id =
878 af->
app.app_pri_tbl[traf_type].pri_bitmap =
881 af->
app.app_pri_tbl[traf_type].appBitfield =
882 (DCBX_APP_ENTRY_VALID);
884 af->
app.app_pri_tbl[traf_type].appBitfield |=
886 DCBX_APP_SF_ETH_TYPE : DCBX_APP_SF_PORT;
895 bnx2x_write_data(bp, (
u32 *)&admin_mib, offset,
910 dcb_on ?
"ON" :
"OFF",
914 "on-chip with negotiation" :
"invalid");
992 dcbx_lldp_params_offset =
996 dcbx_lldp_params_offset);
1007 bnx2x_dcbx_admin_mib_updated_params(bp,
1008 dcbx_lldp_params_offset);
1022 bnx2x_dcbx_print_cos_params(
struct bnx2x *bp,
1029 "pfc_fw_cfg->dcb_version %x\n", pfc_fw_cfg->
dcb_version);
1031 "pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask %x\n",
1036 "pdev->params.dcbx_port_params.ets.cos_params[%d].pri_bitmask %x\n",
1040 "pdev->params.dcbx_port_params.ets.cos_params[%d].bw_tbl %x\n",
1044 "pdev->params.dcbx_port_params.ets.cos_params[%d].strict %x\n",
1048 "pdev->params.dcbx_port_params.ets.cos_params[%d].pauseable %x\n",
1054 "pfc_fw_cfg->traffic_type_to_priority_cos[%d].priority %x\n",
1058 "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n",
1064 static void bnx2x_dcbx_get_num_pg_traf_type(
struct bnx2x *bp,
1065 u32 *pg_pri_orginal_spread,
1068 bool pg_found =
false;
1069 u32 i, traf_type, add_traf_type, add_pg;
1077 for (add_traf_type = 0;
1080 if (ttp[add_traf_type] < MAX_PFC_PRIORITIES) {
1081 add_pg = (
u8)pg_pri_orginal_spread[ttp[add_traf_type]];
1085 if (data[traf_type].
pg == add_pg) {
1087 (1 << ttp[add_traf_type])))
1091 (1 << ttp[add_traf_type]);
1096 if (
false == pg_found) {
1099 (1 << ttp[add_traf_type]);
1105 "add_traf_type %d pg_found %s num_of_pg %d\n",
1106 add_traf_type, (
false == pg_found) ?
"NO" :
"YES",
1111 static void bnx2x_dcbx_ets_disabled_entry_data(
struct bnx2x *bp,
1116 cos_data->
data[0].pausable =
1118 cos_data->
data[0].pri_join_mask = pri_join_mask;
1119 cos_data->
data[0].cos_bw = 100;
1123 static inline void bnx2x_dcbx_add_to_cos_bw(
struct bnx2x *bp,
1133 static void bnx2x_dcbx_separate_pauseable_from_non(
struct bnx2x *bp,
1135 u32 *pg_pri_orginal_spread,
1144 cos_data->
data[0].pausable =
true;
1145 cos_data->
data[1].pausable =
false;
1146 cos_data->
data[0].pri_join_mask = cos_data->
data[1].pri_join_mask = 0;
1148 for (i = 0 ; i < num_of_pri ; i++) {
1150 app.traffic_type_priority[
i];
1153 cos_data->
data[1].pri_join_mask |= pri_tested;
1156 cos_data->
data[0].pri_join_mask |= pri_tested;
1160 app.traffic_type_priority[i]];
1162 if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES)
1163 bnx2x_dcbx_add_to_cos_bw(bp, &cos_data->
data[entry],
1171 if ((0 == cos_data->
data[0].pri_join_mask) &&
1172 (0 == cos_data->
data[1].pri_join_mask))
1173 BNX2X_ERR(
"dcbx error: Both groups must have priorities\n");
1178 #define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1))))
1181 static void bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params(
struct bnx2x *bp,
1189 u32 pri_mask_without_pri = 0;
1192 if (num_of_dif_pri == 1) {
1193 bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, pri_join_mask);
1197 if (pg_help_data->
data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) {
1204 cos_data->
data[0].pausable =
true;
1206 cos_data->
data[1].pausable =
false;
1208 if (2 == num_of_dif_pri) {
1209 cos_data->
data[0].cos_bw = 50;
1210 cos_data->
data[1].cos_bw = 50;
1213 if (3 == num_of_dif_pri) {
1216 cos_data->
data[0].cos_bw = 33;
1217 cos_data->
data[1].cos_bw = 67;
1219 cos_data->
data[0].cos_bw = 67;
1220 cos_data->
data[1].cos_bw = 33;
1229 if (2 == num_of_dif_pri) {
1230 cos_data->
data[0].cos_bw = 50;
1231 cos_data->
data[1].cos_bw = 50;
1233 cos_data->
data[0].cos_bw = 67;
1234 cos_data->
data[1].cos_bw = 33;
1236 cos_data->
data[1].pausable =
true;
1237 cos_data->
data[0].pausable =
true;
1239 cos_data->
data[0].pri_join_mask = (pri_join_mask &
1242 cos_data->
data[1].pri_join_mask =
1248 bnx2x_dcbx_ets_disabled_entry_data(bp,
1249 cos_data, pri_join_mask);
1260 cos_data->
data[0].strict =
1262 cos_data->
data[1].strict =
1266 cos_data->
data[0].strict =
1269 cos_data->
data[1].strict =
1273 cos_data->
data[0].pausable =
true;
1275 cos_data->
data[1].pausable =
false;
1282 cos_data->
data[0].pausable =
1283 cos_data->
data[1].pausable =
1288 app.traffic_type_priority[
i];
1290 pri_mask_without_pri =
1291 (pri_join_mask & ((
u8)(~pri_tested)));
1292 if (pri_mask_without_pri < pri_tested)
1296 if (i == LLFC_DRIVER_TRAFFIC_TYPE_MAX)
1297 BNX2X_ERR(
"Invalid value for pri_join_mask - could not find a priority\n");
1299 cos_data->
data[0].pri_join_mask = pri_mask_without_pri;
1300 cos_data->
data[1].pri_join_mask = pri_tested;
1305 cos_data->
data[0].strict =
1308 cos_data->
data[1].strict =
1314 static void bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params(
1319 u32 *pg_pri_orginal_spread,
1332 pg_help_data->
data[0].pg_priority) ||
1334 pg_help_data->
data[1].pg_priority)) {
1338 bnx2x_dcbx_separate_pauseable_from_non(bp, cos_data,
1339 pg_pri_orginal_spread, ets);
1345 cos_data->
data[0].pausable =
true;
1347 cos_data->
data[1].pausable =
false;
1349 pg_help_data->
data[0].pg_priority)) {
1351 cos_data->
data[0].pri_join_mask =
1352 pg_help_data->
data[0].pg_priority;
1353 pg[0] = pg_help_data->
data[0].pg;
1354 cos_data->
data[1].pri_join_mask =
1355 pg_help_data->
data[1].pg_priority;
1356 pg[1] = pg_help_data->
data[1].pg;
1358 cos_data->
data[0].pri_join_mask =
1359 pg_help_data->
data[1].pg_priority;
1360 pg[0] = pg_help_data->
data[1].pg;
1361 cos_data->
data[1].pri_join_mask =
1362 pg_help_data->
data[0].pg_priority;
1363 pg[1] = pg_help_data->
data[0].pg;
1369 cos_data->
data[0].pausable = cos_data->
data[1].pausable =
1371 cos_data->
data[0].pri_join_mask =
1372 pg_help_data->
data[0].pg_priority;
1373 pg[0] = pg_help_data->
data[0].pg;
1374 cos_data->
data[1].pri_join_mask =
1375 pg_help_data->
data[1].pg_priority;
1376 pg[1] = pg_help_data->
data[1].pg;
1381 if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES)
1382 cos_data->
data[
i].cos_bw =
1385 cos_data->
data[
i].strict =
1390 static int bnx2x_dcbx_join_pgs(
1393 struct pg_help_data *pg_help_data,
1394 u8 required_num_of_pg)
1397 u8 entry_removed = entry_joined + 1;
1403 BNX2X_ERR(
"required_num_of_pg can't be zero\n");
1407 while (required_num_of_pg < pg_help_data->num_of_pg) {
1408 entry_joined = pg_help_data->
num_of_pg - 2;
1409 entry_removed = entry_joined + 1;
1413 pg_help_data->
data[entry_joined].pg_priority |=
1414 pg_help_data->
data[entry_removed].pg_priority;
1416 pg_help_data->
data[entry_joined].num_of_dif_pri +=
1417 pg_help_data->
data[entry_removed].num_of_dif_pri;
1422 pg_help_data->
data[entry_joined].pg =
1427 pg_help_data->
data[entry_joined].pg) +
1429 pg_help_data->
data[entry_removed].pg);
1432 pg_help_data->
data[entry_joined].pg, pg_joined);
1441 static void bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params(
1443 struct pg_help_data *pg_help_data,
1446 u32 *pg_pri_orginal_spread,
1454 bool b_found_strict =
false;
1457 cos_data->
data[0].pri_join_mask = cos_data->
data[1].pri_join_mask = 0;
1463 bnx2x_dcbx_separate_pauseable_from_non(bp,
1464 cos_data, pg_pri_orginal_spread, ets);
1483 cos_data->
data[0].pausable = cos_data->
data[1].pausable =
1486 for (i = 0 ; i < num_of_pri; i++) {
1488 app.traffic_type_priority[
i];
1489 pg_entry = (
u8)pg_pri_orginal_spread[bp->
1490 dcbx_port_params.app.traffic_type_priority[i]];
1492 if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) {
1495 if (i == (num_of_pri-1) &&
1496 false == b_found_strict)
1503 bnx2x_dcbx_add_to_cos_bw(bp,
1504 &cos_data->
data[entry],
1508 b_found_strict =
true;
1509 cos_data->
data[1].pri_join_mask |= pri_tested;
1512 cos_data->
data[1].strict =
1520 static void bnx2x_dcbx_2cos_limit_cee_fill_cos_params(
struct bnx2x *bp,
1521 struct pg_help_data *help_data,
1524 u32 *pg_pri_orginal_spread,
1534 bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params(
1542 bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params(
1547 pg_pri_orginal_spread,
1553 bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params(
1558 pg_pri_orginal_spread,
1563 BNX2X_ERR(
"Wrong pg_help_data.num_of_pg\n");
1564 bnx2x_dcbx_ets_disabled_entry_data(bp,
1565 cos_data, pri_join_mask);
1569 static int bnx2x_dcbx_spread_strict_pri(
struct bnx2x *bp,
1572 u8 num_spread_of_entries,
1579 while (num_spread_of_entries && num_of_app_pri > 0) {
1580 app_pri_bit = 1 << (num_of_app_pri - 1);
1581 if (app_pri_bit & strict_app_pris) {
1584 num_spread_of_entries--;
1585 if (num_spread_of_entries == 0) {
1588 data->
strict = strict_pri;
1593 strict_app_pris &= ~app_pri_bit;
1596 data->
strict = strict_pri;
1610 if (num_spread_of_entries) {
1611 BNX2X_ERR(
"Didn't succeed to spread strict priorities\n");
1618 static u8 bnx2x_dcbx_cee_fill_strict_pri(
struct bnx2x *bp,
1621 u8 num_spread_of_entries,
1625 if (bnx2x_dcbx_spread_strict_pri(bp, cos_data, entry,
1626 num_spread_of_entries,
1639 return num_spread_of_entries;
1642 static void bnx2x_dcbx_cee_fill_cos_params(
struct bnx2x *bp,
1643 struct pg_help_data *help_data,
1649 u8 need_num_of_entries = 0;
1659 if (bnx2x_dcbx_join_pgs(bp, ets, help_data,
1661 BNX2X_ERR(
"Unable to reduce the number of PGs - we will disables ETS\n");
1662 bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data,
1668 for (i = 0 ; i < help_data->
num_of_pg; i++) {
1670 if (pg->
pg < DCBX_MAX_NUM_PG_BW_ENTRIES) {
1682 need_num_of_entries =
min_t(
u8,
1691 entry += bnx2x_dcbx_cee_fill_strict_pri(bp, cos_data,
1699 static void bnx2x_dcbx_fill_cos_params(
struct bnx2x *bp,
1700 struct pg_help_data *help_data,
1702 u32 *pg_pri_orginal_spread)
1706 u32 pri_join_mask = 0;
1707 u8 num_of_dif_pri = 0;
1709 memset(&cos_data, 0,
sizeof(cos_data));
1712 for (i = 0; i < help_data->
num_of_pg ; i++) {
1714 DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg)
1715 BNX2X_ERR(
"Invalid pg[%d] data %x\n", i,
1716 help_data->
data[i].pg);
1717 pri_join_mask |= help_data->
data[
i].pg_priority;
1718 num_of_dif_pri += help_data->
data[
i].num_of_dif_pri;
1724 cos_data.
data[
i].pri_join_mask = 0;
1725 cos_data.
data[
i].pausable =
false;
1731 bnx2x_dcbx_cee_fill_cos_params(bp, help_data, ets,
1732 &cos_data, pri_join_mask);
1734 bnx2x_dcbx_2cos_limit_cee_fill_cos_params(bp,
1737 pg_pri_orginal_spread,
1754 BNX2X_ERR(
"Invalid pri_bitmask for %d\n", i);
1761 BNX2X_ERR(
"Inconsistent config for pausable COS %d\n",
1767 BNX2X_ERR(
"Inconsistent config for nonpausable COS %d\n",
1774 i, cos_data.
data[i].pri_join_mask);
1777 "COS %d NONPAUSABLE prijoinmask 0x%x\n",
1778 i, cos_data.
data[i].pri_join_mask);
1784 static void bnx2x_dcbx_get_ets_pri_pg_tbl(
struct bnx2x *bp,
1785 u32 *set_configuration_ets_pg,
1794 i, set_configuration_ets_pg[i]);
1798 static void bnx2x_dcbx_fw_struct(
struct bnx2x *bp,
1802 u8 cos = 0, pri = 0;
1806 memset(pfc_fw_cfg, 0,
sizeof(*pfc_fw_cfg));
1828 pri_bitmask & pri_bit)
1835 bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg);
1846 if (bnx2x_dcbx_read_shmem_neg_results(bp))
1857 bnx2x_dcbnl_update_applist(bp,
false);
1867 bnx2x_dcbx_update_tc_mapping(bp);
1875 #define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \
1876 DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
1878 static inline bool bnx2x_dcbnl_set_valid(
struct bnx2x *bp)
1886 static u8 bnx2x_dcbnl_get_state(
struct net_device *netdev)
1888 struct bnx2x *bp = netdev_priv(netdev);
1895 struct bnx2x *bp = netdev_priv(netdev);
1902 static void bnx2x_dcbnl_get_perm_hw_addr(
struct net_device *netdev,
1905 struct bnx2x *bp = netdev_priv(netdev);
1917 static void bnx2x_dcbnl_set_pg_tccfg_tx(
struct net_device *netdev,
int prio,
1921 struct bnx2x *bp = netdev_priv(netdev);
1924 if (!bnx2x_dcbnl_set_valid(bp) || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
1944 static void bnx2x_dcbnl_set_pg_bwgcfg_tx(
struct net_device *netdev,
1945 int pgid,
u8 bw_pct)
1947 struct bnx2x *bp = netdev_priv(netdev);
1950 if (!bnx2x_dcbnl_set_valid(bp) || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
1957 static void bnx2x_dcbnl_set_pg_tccfg_rx(
struct net_device *netdev,
int prio,
1958 u8 prio_type,
u8 pgid,
u8 bw_pct,
1961 struct bnx2x *bp = netdev_priv(netdev);
1965 static void bnx2x_dcbnl_set_pg_bwgcfg_rx(
struct net_device *netdev,
1966 int pgid,
u8 bw_pct)
1968 struct bnx2x *bp = netdev_priv(netdev);
1972 static void bnx2x_dcbnl_get_pg_tccfg_tx(
struct net_device *netdev,
int prio,
1973 u8 *prio_type,
u8 *pgid,
u8 *bw_pct,
1976 struct bnx2x *bp = netdev_priv(netdev);
1991 *up_map = *bw_pct = *prio_type = *pgid = 0;
1993 if (!bp->
dcb_state || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
1999 static void bnx2x_dcbnl_get_pg_bwgcfg_tx(
struct net_device *netdev,
2000 int pgid,
u8 *bw_pct)
2002 struct bnx2x *bp = netdev_priv(netdev);
2007 if (!bp->
dcb_state || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
2013 static void bnx2x_dcbnl_get_pg_tccfg_rx(
struct net_device *netdev,
int prio,
2014 u8 *prio_type,
u8 *pgid,
u8 *bw_pct,
2017 struct bnx2x *bp = netdev_priv(netdev);
2020 *prio_type = *pgid = *bw_pct = *up_map = 0;
2023 static void bnx2x_dcbnl_get_pg_bwgcfg_rx(
struct net_device *netdev,
2024 int pgid,
u8 *bw_pct)
2026 struct bnx2x *bp = netdev_priv(netdev);
2032 static void bnx2x_dcbnl_set_pfc_cfg(
struct net_device *netdev,
int prio,
2035 struct bnx2x *bp = netdev_priv(netdev);
2038 if (!bnx2x_dcbnl_set_valid(bp) || prio >= MAX_PFC_PRIORITIES)
2047 static void bnx2x_dcbnl_get_pfc_cfg(
struct net_device *netdev,
int prio,
2050 struct bnx2x *bp = netdev_priv(netdev);
2055 if (!bp->
dcb_state || prio >= MAX_PFC_PRIORITIES)
2061 static u8 bnx2x_dcbnl_set_all(
struct net_device *netdev)
2063 struct bnx2x *bp = netdev_priv(netdev);
2068 if (!bnx2x_dcbnl_set_valid(bp))
2073 "Handling parity error recovery. Try again later\n");
2076 if (netif_running(bp->
dev))
2087 struct bnx2x *bp = netdev_priv(netdev);
2114 *cap = BNX2X_DCBX_CAPS;
2130 static int bnx2x_dcbnl_get_numtcs(
struct net_device *netdev,
int tcid,
u8 *num)
2132 struct bnx2x *bp = netdev_priv(netdev);
2160 static int bnx2x_dcbnl_set_numtcs(
struct net_device *netdev,
int tcid,
u8 num)
2162 struct bnx2x *bp = netdev_priv(netdev);
2167 static u8 bnx2x_dcbnl_get_pfc_state(
struct net_device *netdev)
2169 struct bnx2x *bp = netdev_priv(netdev);
2178 static void bnx2x_dcbnl_set_pfc_state(
struct net_device *netdev,
u8 state)
2180 struct bnx2x *bp = netdev_priv(netdev);
2183 if (!bnx2x_dcbnl_set_valid(bp))
2190 static void bnx2x_admin_app_set_ent(
2210 static bool bnx2x_admin_app_is_equal(
2212 u8 idtype,
u16 idval)
2214 if (!app_ent->
valid)
2229 if (app_ent->
app_id != idval)
2235 static int bnx2x_set_admin_app_up(
struct bnx2x *bp,
u8 idtype,
u16 idval,
u8 up)
2243 if (bnx2x_admin_app_is_equal(app_ent, idtype, idval))
2246 if (ff < 0 && !app_ent->
valid)
2249 if (i < DCBX_CONFIG_MAX_APP_PROTOCOL)
2252 admin_priority_app_table[
i].priority =
up;
2255 bnx2x_admin_app_set_ent(
2260 BNX2X_ERR(
"Application table is too large\n");
2271 static u8 bnx2x_dcbnl_set_app_up(
struct net_device *netdev,
u8 idtype,
2274 struct bnx2x *bp = netdev_priv(netdev);
2279 if (!bnx2x_dcbnl_set_valid(bp)) {
2293 return bnx2x_set_admin_app_up(bp, idtype, idval, up);
2296 static u8 bnx2x_dcbnl_get_dcbx(
struct net_device *netdev)
2298 struct bnx2x *bp = netdev_priv(netdev);
2309 static u8 bnx2x_dcbnl_set_dcbx(
struct net_device *netdev,
u8 state)
2311 struct bnx2x *bp = netdev_priv(netdev);
2316 if ((state & BNX2X_DCBX_CAPS) != state) {
2317 BNX2X_ERR(
"Requested DCBX mode %x is beyond advertised capabilities\n",
2323 BNX2X_ERR(
"DCB turned off, DCBX configuration is invalid\n");
2336 static u8 bnx2x_dcbnl_get_featcfg(
struct net_device *netdev,
int featid,
2339 struct bnx2x *bp = netdev_priv(netdev);
2380 static u8 bnx2x_dcbnl_set_featcfg(
struct net_device *netdev,
int featid,
2383 struct bnx2x *bp = netdev_priv(netdev);
2389 if (bnx2x_dcbnl_set_valid(bp)) {
2421 static int bnx2x_peer_appinfo(
struct net_device *netdev,
2425 struct bnx2x *bp = netdev_priv(netdev);
2434 if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
2435 DCBX_APP_ENTRY_VALID)
2440 static int bnx2x_peer_apptable(
struct net_device *netdev,
2444 struct bnx2x *bp = netdev_priv(netdev);
2450 &bp->dcbx_remote_feat.app.app_pri_tbl[
i];
2452 if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
2453 table[
j].
selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
2454 table[
j].
priority = bnx2x_dcbx_dcbnl_app_up(ent);
2461 static int bnx2x_cee_peer_getpg(
struct net_device *netdev,
struct cee_pg *pg)
2464 struct bnx2x *bp = netdev_priv(netdev);
2477 static int bnx2x_cee_peer_getpfc(
struct net_device *netdev,
2480 struct bnx2x *bp = netdev_priv(netdev);
2482 pfc->
pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
2488 .setstate = bnx2x_dcbnl_set_state,
2489 .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
2490 .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
2491 .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
2492 .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
2493 .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
2494 .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
2495 .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
2496 .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
2497 .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
2498 .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
2499 .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
2500 .setall = bnx2x_dcbnl_set_all,
2501 .getcap = bnx2x_dcbnl_get_cap,
2502 .getnumtcs = bnx2x_dcbnl_get_numtcs,
2503 .setnumtcs = bnx2x_dcbnl_set_numtcs,
2504 .getpfcstate = bnx2x_dcbnl_get_pfc_state,
2505 .setpfcstate = bnx2x_dcbnl_set_pfc_state,
2506 .setapp = bnx2x_dcbnl_set_app_up,
2507 .getdcbx = bnx2x_dcbnl_get_dcbx,
2508 .setdcbx = bnx2x_dcbnl_set_dcbx,
2509 .getfeatcfg = bnx2x_dcbnl_get_featcfg,
2510 .setfeatcfg = bnx2x_dcbnl_set_featcfg,
2511 .peer_getappinfo = bnx2x_peer_appinfo,
2512 .peer_getapptable = bnx2x_peer_apptable,
2513 .cee_peer_getpg = bnx2x_cee_peer_getpg,
2514 .cee_peer_getpfc = bnx2x_cee_peer_getpfc,