1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 /* QLogic qed NIC Driver 3 * Copyright (c) 2015-2017 QLogic Corporation 4 * Copyright (c) 2019-2020 Marvell International Ltd. 5 */ 6 7 #include <linux/types.h> 8 #include <asm/byteorder.h> 9 #include <linux/bitops.h> 10 #include <linux/dcbnl.h> 11 #include <linux/errno.h> 12 #include <linux/kernel.h> 13 #include <linux/slab.h> 14 #include <linux/string.h> 15 #include "qed.h" 16 #include "qed_cxt.h" 17 #include "qed_dcbx.h" 18 #include "qed_hsi.h" 19 #include "qed_sp.h" 20 #include "qed_sriov.h" 21 #include "qed_rdma.h" 22 #ifdef CONFIG_DCB 23 #include <linux/qed/qed_eth_if.h> 24 #endif 25 26 #define QED_DCBX_MAX_MIB_READ_TRY (100) 27 #define QED_ETH_TYPE_DEFAULT (0) 28 #define QED_ETH_TYPE_ROCE (0x8915) 29 #define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7) 30 #define QED_ETH_TYPE_FCOE (0x8906) 31 #define QED_TCP_PORT_ISCSI (0xCBC) 32 33 #define QED_DCBX_INVALID_PRIORITY 0xFF 34 35 /* Get Traffic Class from priority traffic class table, 4 bits represent 36 * the traffic class corresponding to the priority. 37 */ 38 #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \ 39 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7) 40 41 static const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = { 42 {DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_ISCSI}, 43 {DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_FCOE}, 44 {DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_ETH_ROCE}, 45 {DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_ETH_ROCE}, 46 {DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH}, 47 }; 48 49 static bool qed_dcbx_app_ethtype(u32 app_info_bitmap) 50 { 51 return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 52 DCBX_APP_SF_ETHTYPE); 53 } 54 55 static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap) 56 { 57 u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 58 59 /* Old MFW */ 60 if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 61 return qed_dcbx_app_ethtype(app_info_bitmap); 62 63 return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE); 64 } 65 66 static bool qed_dcbx_app_port(u32 app_info_bitmap) 67 { 68 return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 69 DCBX_APP_SF_PORT); 70 } 71 72 static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type) 73 { 74 u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 75 76 /* Old MFW */ 77 if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 78 return qed_dcbx_app_port(app_info_bitmap); 79 80 return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT); 81 } 82 83 static bool qed_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 84 { 85 bool ethtype; 86 87 if (ieee) 88 ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 89 else 90 ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 91 92 return !!(ethtype && (proto_id == QED_ETH_TYPE_DEFAULT)); 93 } 94 95 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 96 { 97 bool port; 98 99 if (ieee) 100 port = qed_dcbx_ieee_app_port(app_info_bitmap, 101 DCBX_APP_SF_IEEE_TCP_PORT); 102 else 103 port = qed_dcbx_app_port(app_info_bitmap); 104 105 return !!(port && (proto_id == QED_TCP_PORT_ISCSI)); 106 } 107 108 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 109 { 110 bool ethtype; 111 112 if (ieee) 113 ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 114 else 115 ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 116 117 return !!(ethtype && (proto_id == QED_ETH_TYPE_FCOE)); 118 } 119 120 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 121 { 122 bool ethtype; 123 124 if (ieee) 125 ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 126 else 127 ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 128 129 return !!(ethtype && (proto_id == QED_ETH_TYPE_ROCE)); 130 } 131 132 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 133 { 134 bool port; 135 136 if (ieee) 137 port = qed_dcbx_ieee_app_port(app_info_bitmap, 138 DCBX_APP_SF_IEEE_UDP_PORT); 139 else 140 port = qed_dcbx_app_port(app_info_bitmap); 141 142 return !!(port && (proto_id == QED_UDP_PORT_TYPE_ROCE_V2)); 143 } 144 145 static void 146 qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data) 147 { 148 enum dcbx_protocol_type id; 149 int i; 150 151 DP_VERBOSE(p_hwfn, QED_MSG_DCB, "DCBX negotiated: %d\n", 152 p_data->dcbx_enabled); 153 154 for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 155 id = qed_dcbx_app_update[i].id; 156 157 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 158 "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n", 159 qed_dcbx_app_update[i].name, p_data->arr[id].update, 160 p_data->arr[id].enable, p_data->arr[id].priority, 161 p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc); 162 } 163 } 164 165 static void 166 qed_dcbx_set_params(struct qed_dcbx_results *p_data, 167 struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 168 bool app_tlv, bool enable, u8 prio, u8 tc, 169 enum dcbx_protocol_type type, 170 enum qed_pci_personality personality) 171 { 172 /* PF update ramrod data */ 173 p_data->arr[type].enable = enable; 174 p_data->arr[type].priority = prio; 175 p_data->arr[type].tc = tc; 176 if (enable) 177 p_data->arr[type].update = UPDATE_DCB; 178 else 179 p_data->arr[type].update = DONT_UPDATE_DCB_DSCP; 180 181 if (test_bit(QED_MF_DONT_ADD_VLAN0_TAG, &p_hwfn->cdev->mf_bits)) 182 p_data->arr[type].dont_add_vlan0 = true; 183 184 /* QM reconf data */ 185 if (app_tlv && p_hwfn->hw_info.personality == personality) 186 qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); 187 188 /* Configure dcbx vlan priority in doorbell block for roce EDPM */ 189 if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) && 190 type == DCBX_PROTOCOL_ROCE) { 191 qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1); 192 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_PCP_BB_K2, prio << 1); 193 } 194 } 195 196 /* Update app protocol data and hw_info fields with the TLV info */ 197 static void 198 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, 199 struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 200 bool app_tlv, bool enable, u8 prio, u8 tc, 201 enum dcbx_protocol_type type) 202 { 203 enum qed_pci_personality personality; 204 enum dcbx_protocol_type id; 205 int i; 206 207 for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 208 id = qed_dcbx_app_update[i].id; 209 210 if (type != id) 211 continue; 212 213 personality = qed_dcbx_app_update[i].personality; 214 215 qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable, 216 prio, tc, type, personality); 217 } 218 } 219 220 static bool 221 qed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn, 222 u32 app_prio_bitmap, 223 u16 id, enum dcbx_protocol_type *type, bool ieee) 224 { 225 if (qed_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) { 226 *type = DCBX_PROTOCOL_FCOE; 227 } else if (qed_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) { 228 *type = DCBX_PROTOCOL_ROCE; 229 } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) { 230 *type = DCBX_PROTOCOL_ISCSI; 231 } else if (qed_dcbx_default_tlv(app_prio_bitmap, id, ieee)) { 232 *type = DCBX_PROTOCOL_ETH; 233 } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) { 234 *type = DCBX_PROTOCOL_ROCE_V2; 235 } else { 236 *type = DCBX_MAX_PROTOCOL_TYPE; 237 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 238 "No action required, App TLV entry = 0x%x\n", 239 app_prio_bitmap); 240 return false; 241 } 242 243 return true; 244 } 245 246 /* Parse app TLV's to update TC information in hw_info structure for 247 * reconfiguring QM. Get protocol specific data for PF update ramrod command. 248 */ 249 static int 250 qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 251 struct qed_dcbx_results *p_data, 252 struct dcbx_app_priority_entry *p_tbl, 253 u32 pri_tc_tbl, int count, u8 dcbx_version) 254 { 255 enum dcbx_protocol_type type; 256 bool enable, ieee, eth_tlv; 257 u8 tc, priority_map; 258 u16 protocol_id; 259 int priority; 260 int i; 261 262 DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Num APP entries = %d\n", count); 263 264 ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE); 265 eth_tlv = false; 266 /* Parse APP TLV */ 267 for (i = 0; i < count; i++) { 268 protocol_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 269 DCBX_APP_PROTOCOL_ID); 270 priority_map = QED_MFW_GET_FIELD(p_tbl[i].entry, 271 DCBX_APP_PRI_MAP); 272 priority = ffs(priority_map) - 1; 273 if (priority < 0) { 274 DP_ERR(p_hwfn, "Invalid priority\n"); 275 return -EINVAL; 276 } 277 278 tc = QED_DCBX_PRIO2TC(pri_tc_tbl, priority); 279 if (qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 280 protocol_id, &type, ieee)) { 281 /* ETH always have the enable bit reset, as it gets 282 * vlan information per packet. For other protocols, 283 * should be set according to the dcbx_enabled 284 * indication, but we only got here if there was an 285 * app tlv for the protocol, so dcbx must be enabled. 286 */ 287 if (type == DCBX_PROTOCOL_ETH) { 288 enable = false; 289 eth_tlv = true; 290 } else { 291 enable = true; 292 } 293 294 qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true, 295 enable, priority, tc, type); 296 } 297 } 298 299 /* If Eth TLV is not detected, use UFP TC as default TC */ 300 if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) && !eth_tlv) 301 p_data->arr[DCBX_PROTOCOL_ETH].tc = p_hwfn->ufp_info.tc; 302 303 /* Update ramrod protocol data and hw_info fields 304 * with default info when corresponding APP TLV's are not detected. 305 * The enabled field has a different logic for ethernet as only for 306 * ethernet dcb should disabled by default, as the information arrives 307 * from the OS (unless an explicit app tlv was present). 308 */ 309 tc = p_data->arr[DCBX_PROTOCOL_ETH].tc; 310 priority = p_data->arr[DCBX_PROTOCOL_ETH].priority; 311 for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) { 312 if (p_data->arr[type].update) 313 continue; 314 315 enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; 316 qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable, 317 priority, tc, type); 318 } 319 320 return 0; 321 } 322 323 /* Parse app TLV's to update TC information in hw_info structure for 324 * reconfiguring QM. Get protocol specific data for PF update ramrod command. 325 */ 326 static int 327 qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 328 { 329 struct dcbx_app_priority_feature *p_app; 330 struct dcbx_app_priority_entry *p_tbl; 331 struct qed_dcbx_results data = { 0 }; 332 struct dcbx_ets_feature *p_ets; 333 struct qed_hw_info *p_info; 334 u32 pri_tc_tbl, flags; 335 u8 dcbx_version; 336 int num_entries; 337 int rc = 0; 338 339 flags = p_hwfn->p_dcbx_info->operational.flags; 340 dcbx_version = QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION); 341 342 p_app = &p_hwfn->p_dcbx_info->operational.features.app; 343 p_tbl = p_app->app_pri_tbl; 344 345 p_ets = &p_hwfn->p_dcbx_info->operational.features.ets; 346 pri_tc_tbl = p_ets->pri_tc_tbl[0]; 347 348 p_info = &p_hwfn->hw_info; 349 num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES); 350 351 rc = qed_dcbx_process_tlv(p_hwfn, p_ptt, &data, p_tbl, pri_tc_tbl, 352 num_entries, dcbx_version); 353 if (rc) 354 return rc; 355 356 p_info->num_active_tc = QED_MFW_GET_FIELD(p_ets->flags, 357 DCBX_ETS_MAX_TCS); 358 p_hwfn->qm_info.ooo_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_OOO_TC); 359 data.pf_id = p_hwfn->rel_pf_id; 360 data.dcbx_enabled = !!dcbx_version; 361 362 qed_dcbx_dp_protocol(p_hwfn, &data); 363 364 memcpy(&p_hwfn->p_dcbx_info->results, &data, 365 sizeof(struct qed_dcbx_results)); 366 367 return 0; 368 } 369 370 static int 371 qed_dcbx_copy_mib(struct qed_hwfn *p_hwfn, 372 struct qed_ptt *p_ptt, 373 struct qed_dcbx_mib_meta_data *p_data, 374 enum qed_mib_read_type type) 375 { 376 u32 prefix_seq_num, suffix_seq_num; 377 int read_count = 0; 378 int rc = 0; 379 380 /* The data is considered to be valid only if both sequence numbers are 381 * the same. 382 */ 383 do { 384 if (type == QED_DCBX_REMOTE_LLDP_MIB) { 385 qed_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote, 386 p_data->addr, p_data->size); 387 prefix_seq_num = p_data->lldp_remote->prefix_seq_num; 388 suffix_seq_num = p_data->lldp_remote->suffix_seq_num; 389 } else { 390 qed_memcpy_from(p_hwfn, p_ptt, p_data->mib, 391 p_data->addr, p_data->size); 392 prefix_seq_num = p_data->mib->prefix_seq_num; 393 suffix_seq_num = p_data->mib->suffix_seq_num; 394 } 395 read_count++; 396 397 DP_VERBOSE(p_hwfn, 398 QED_MSG_DCB, 399 "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 400 type, read_count, prefix_seq_num, suffix_seq_num); 401 } while ((prefix_seq_num != suffix_seq_num) && 402 (read_count < QED_DCBX_MAX_MIB_READ_TRY)); 403 404 if (read_count >= QED_DCBX_MAX_MIB_READ_TRY) { 405 DP_ERR(p_hwfn, 406 "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 407 type, read_count, prefix_seq_num, suffix_seq_num); 408 rc = -EIO; 409 } 410 411 return rc; 412 } 413 414 static void 415 qed_dcbx_get_priority_info(struct qed_hwfn *p_hwfn, 416 struct qed_dcbx_app_prio *p_prio, 417 struct qed_dcbx_results *p_results) 418 { 419 u8 val; 420 421 p_prio->roce = QED_DCBX_INVALID_PRIORITY; 422 p_prio->roce_v2 = QED_DCBX_INVALID_PRIORITY; 423 p_prio->iscsi = QED_DCBX_INVALID_PRIORITY; 424 p_prio->fcoe = QED_DCBX_INVALID_PRIORITY; 425 426 if (p_results->arr[DCBX_PROTOCOL_ROCE].update && 427 p_results->arr[DCBX_PROTOCOL_ROCE].enable) 428 p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority; 429 430 if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update && 431 p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) { 432 val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority; 433 p_prio->roce_v2 = val; 434 } 435 436 if (p_results->arr[DCBX_PROTOCOL_ISCSI].update && 437 p_results->arr[DCBX_PROTOCOL_ISCSI].enable) 438 p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority; 439 440 if (p_results->arr[DCBX_PROTOCOL_FCOE].update && 441 p_results->arr[DCBX_PROTOCOL_FCOE].enable) 442 p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority; 443 444 if (p_results->arr[DCBX_PROTOCOL_ETH].update && 445 p_results->arr[DCBX_PROTOCOL_ETH].enable) 446 p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority; 447 448 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 449 "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n", 450 p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe, 451 p_prio->eth); 452 } 453 454 static void 455 qed_dcbx_get_app_data(struct qed_hwfn *p_hwfn, 456 struct dcbx_app_priority_feature *p_app, 457 struct dcbx_app_priority_entry *p_tbl, 458 struct qed_dcbx_params *p_params, bool ieee) 459 { 460 struct qed_app_entry *entry; 461 u8 pri_map; 462 int i; 463 464 p_params->app_willing = QED_MFW_GET_FIELD(p_app->flags, 465 DCBX_APP_WILLING); 466 p_params->app_valid = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ENABLED); 467 p_params->app_error = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR); 468 p_params->num_app_entries = QED_MFW_GET_FIELD(p_app->flags, 469 DCBX_APP_NUM_ENTRIES); 470 for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 471 entry = &p_params->app_entry[i]; 472 if (ieee) { 473 u8 sf_ieee; 474 u32 val; 475 476 sf_ieee = QED_MFW_GET_FIELD(p_tbl[i].entry, 477 DCBX_APP_SF_IEEE); 478 switch (sf_ieee) { 479 case DCBX_APP_SF_IEEE_RESERVED: 480 /* Old MFW */ 481 val = QED_MFW_GET_FIELD(p_tbl[i].entry, 482 DCBX_APP_SF); 483 entry->sf_ieee = val ? 484 QED_DCBX_SF_IEEE_TCP_UDP_PORT : 485 QED_DCBX_SF_IEEE_ETHTYPE; 486 break; 487 case DCBX_APP_SF_IEEE_ETHTYPE: 488 entry->sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE; 489 break; 490 case DCBX_APP_SF_IEEE_TCP_PORT: 491 entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT; 492 break; 493 case DCBX_APP_SF_IEEE_UDP_PORT: 494 entry->sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT; 495 break; 496 case DCBX_APP_SF_IEEE_TCP_UDP_PORT: 497 entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT; 498 break; 499 } 500 } else { 501 entry->ethtype = !(QED_MFW_GET_FIELD(p_tbl[i].entry, 502 DCBX_APP_SF)); 503 } 504 505 pri_map = QED_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP); 506 entry->prio = ffs(pri_map) - 1; 507 entry->proto_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 508 DCBX_APP_PROTOCOL_ID); 509 qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 510 entry->proto_id, 511 &entry->proto_type, ieee); 512 } 513 514 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 515 "APP params: willing %d, valid %d error = %d\n", 516 p_params->app_willing, p_params->app_valid, 517 p_params->app_error); 518 } 519 520 static void 521 qed_dcbx_get_pfc_data(struct qed_hwfn *p_hwfn, 522 u32 pfc, struct qed_dcbx_params *p_params) 523 { 524 u8 pfc_map; 525 526 p_params->pfc.willing = QED_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING); 527 p_params->pfc.max_tc = QED_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS); 528 p_params->pfc.enabled = QED_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED); 529 pfc_map = QED_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP); 530 p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0); 531 p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1); 532 p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2); 533 p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3); 534 p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4); 535 p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5); 536 p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6); 537 p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7); 538 539 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 540 "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n", 541 p_params->pfc.willing, pfc_map, p_params->pfc.max_tc, 542 p_params->pfc.enabled); 543 } 544 545 static void 546 qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn, 547 struct dcbx_ets_feature *p_ets, 548 struct qed_dcbx_params *p_params) 549 { 550 __be32 bw_map[2], tsa_map[2]; 551 u32 pri_map; 552 int i; 553 554 p_params->ets_willing = QED_MFW_GET_FIELD(p_ets->flags, 555 DCBX_ETS_WILLING); 556 p_params->ets_enabled = QED_MFW_GET_FIELD(p_ets->flags, 557 DCBX_ETS_ENABLED); 558 p_params->ets_cbs = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS); 559 p_params->max_ets_tc = QED_MFW_GET_FIELD(p_ets->flags, 560 DCBX_ETS_MAX_TCS); 561 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 562 "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n", 563 p_params->ets_willing, p_params->ets_enabled, 564 p_params->ets_cbs, p_ets->pri_tc_tbl[0], 565 p_params->max_ets_tc); 566 567 if (p_params->ets_enabled && !p_params->max_ets_tc) { 568 p_params->max_ets_tc = QED_MAX_PFC_PRIORITIES; 569 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 570 "ETS params: max_ets_tc is forced to %d\n", 571 p_params->max_ets_tc); 572 } 573 574 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are 575 * encoded in a type u32 array of size 2. 576 */ 577 cpu_to_be32_array(bw_map, p_ets->tc_bw_tbl, 2); 578 cpu_to_be32_array(tsa_map, p_ets->tc_tsa_tbl, 2); 579 pri_map = p_ets->pri_tc_tbl[0]; 580 581 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 582 p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i]; 583 p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i]; 584 p_params->ets_pri_tc_tbl[i] = QED_DCBX_PRIO2TC(pri_map, i); 585 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 586 "elem %d bw_tbl %x tsa_tbl %x\n", 587 i, p_params->ets_tc_bw_tbl[i], 588 p_params->ets_tc_tsa_tbl[i]); 589 } 590 } 591 592 static void 593 qed_dcbx_get_common_params(struct qed_hwfn *p_hwfn, 594 struct dcbx_app_priority_feature *p_app, 595 struct dcbx_app_priority_entry *p_tbl, 596 struct dcbx_ets_feature *p_ets, 597 u32 pfc, struct qed_dcbx_params *p_params, bool ieee) 598 { 599 qed_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee); 600 qed_dcbx_get_ets_data(p_hwfn, p_ets, p_params); 601 qed_dcbx_get_pfc_data(p_hwfn, pfc, p_params); 602 } 603 604 static void 605 qed_dcbx_get_local_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *params) 606 { 607 struct dcbx_features *p_feat; 608 609 p_feat = &p_hwfn->p_dcbx_info->local_admin.features; 610 qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 611 p_feat->app.app_pri_tbl, &p_feat->ets, 612 p_feat->pfc, ¶ms->local.params, false); 613 params->local.valid = true; 614 } 615 616 static void 617 qed_dcbx_get_remote_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *params) 618 { 619 struct dcbx_features *p_feat; 620 621 p_feat = &p_hwfn->p_dcbx_info->remote.features; 622 qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 623 p_feat->app.app_pri_tbl, &p_feat->ets, 624 p_feat->pfc, ¶ms->remote.params, false); 625 params->remote.valid = true; 626 } 627 628 static void 629 qed_dcbx_get_operational_params(struct qed_hwfn *p_hwfn, 630 struct qed_dcbx_get *params) 631 { 632 struct qed_dcbx_operational_params *p_operational; 633 struct qed_dcbx_results *p_results; 634 struct dcbx_features *p_feat; 635 bool enabled, err; 636 u32 flags; 637 bool val; 638 639 flags = p_hwfn->p_dcbx_info->operational.flags; 640 641 /* If DCBx version is non zero, then negotiation 642 * was successfuly performed 643 */ 644 p_operational = ¶ms->operational; 645 enabled = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) != 646 DCBX_CONFIG_VERSION_DISABLED); 647 if (!enabled) { 648 p_operational->enabled = enabled; 649 p_operational->valid = false; 650 DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Dcbx is disabled\n"); 651 return; 652 } 653 654 p_feat = &p_hwfn->p_dcbx_info->operational.features; 655 p_results = &p_hwfn->p_dcbx_info->results; 656 657 val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 658 DCBX_CONFIG_VERSION_IEEE); 659 p_operational->ieee = val; 660 val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 661 DCBX_CONFIG_VERSION_CEE); 662 p_operational->cee = val; 663 664 val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 665 DCBX_CONFIG_VERSION_STATIC); 666 p_operational->local = val; 667 668 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 669 "Version support: ieee %d, cee %d, static %d\n", 670 p_operational->ieee, p_operational->cee, 671 p_operational->local); 672 673 qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 674 p_feat->app.app_pri_tbl, &p_feat->ets, 675 p_feat->pfc, ¶ms->operational.params, 676 p_operational->ieee); 677 qed_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio, p_results); 678 err = QED_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR); 679 p_operational->err = err; 680 p_operational->enabled = enabled; 681 p_operational->valid = true; 682 } 683 684 static void 685 qed_dcbx_get_local_lldp_params(struct qed_hwfn *p_hwfn, 686 struct qed_dcbx_get *params) 687 { 688 struct lldp_config_params_s *p_local; 689 690 p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE]; 691 692 memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id, 693 sizeof(p_local->local_chassis_id)); 694 memcpy(params->lldp_local.local_port_id, p_local->local_port_id, 695 sizeof(p_local->local_port_id)); 696 } 697 698 static void 699 qed_dcbx_get_remote_lldp_params(struct qed_hwfn *p_hwfn, 700 struct qed_dcbx_get *params) 701 { 702 struct lldp_status_params_s *p_remote; 703 704 p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE]; 705 706 memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id, 707 sizeof(p_remote->peer_chassis_id)); 708 memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id, 709 sizeof(p_remote->peer_port_id)); 710 } 711 712 static int 713 qed_dcbx_get_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *p_params, 714 enum qed_mib_read_type type) 715 { 716 switch (type) { 717 case QED_DCBX_REMOTE_MIB: 718 qed_dcbx_get_remote_params(p_hwfn, p_params); 719 break; 720 case QED_DCBX_LOCAL_MIB: 721 qed_dcbx_get_local_params(p_hwfn, p_params); 722 break; 723 case QED_DCBX_OPERATIONAL_MIB: 724 qed_dcbx_get_operational_params(p_hwfn, p_params); 725 break; 726 case QED_DCBX_REMOTE_LLDP_MIB: 727 qed_dcbx_get_remote_lldp_params(p_hwfn, p_params); 728 break; 729 case QED_DCBX_LOCAL_LLDP_MIB: 730 qed_dcbx_get_local_lldp_params(p_hwfn, p_params); 731 break; 732 default: 733 DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 734 return -EINVAL; 735 } 736 737 return 0; 738 } 739 740 static int 741 qed_dcbx_read_local_lldp_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 742 { 743 struct qed_dcbx_mib_meta_data data; 744 int rc = 0; 745 746 memset(&data, 0, sizeof(data)); 747 data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 748 lldp_config_params); 749 data.lldp_local = p_hwfn->p_dcbx_info->lldp_local; 750 data.size = sizeof(struct lldp_config_params_s); 751 qed_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size); 752 753 return rc; 754 } 755 756 static int 757 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn *p_hwfn, 758 struct qed_ptt *p_ptt, 759 enum qed_mib_read_type type) 760 { 761 struct qed_dcbx_mib_meta_data data; 762 int rc = 0; 763 764 memset(&data, 0, sizeof(data)); 765 data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 766 lldp_status_params); 767 data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote; 768 data.size = sizeof(struct lldp_status_params_s); 769 rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 770 771 return rc; 772 } 773 774 static int 775 qed_dcbx_read_operational_mib(struct qed_hwfn *p_hwfn, 776 struct qed_ptt *p_ptt, 777 enum qed_mib_read_type type) 778 { 779 struct qed_dcbx_mib_meta_data data; 780 int rc = 0; 781 782 memset(&data, 0, sizeof(data)); 783 data.addr = p_hwfn->mcp_info->port_addr + 784 offsetof(struct public_port, operational_dcbx_mib); 785 data.mib = &p_hwfn->p_dcbx_info->operational; 786 data.size = sizeof(struct dcbx_mib); 787 rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 788 789 return rc; 790 } 791 792 static int 793 qed_dcbx_read_remote_mib(struct qed_hwfn *p_hwfn, 794 struct qed_ptt *p_ptt, enum qed_mib_read_type type) 795 { 796 struct qed_dcbx_mib_meta_data data; 797 int rc = 0; 798 799 memset(&data, 0, sizeof(data)); 800 data.addr = p_hwfn->mcp_info->port_addr + 801 offsetof(struct public_port, remote_dcbx_mib); 802 data.mib = &p_hwfn->p_dcbx_info->remote; 803 data.size = sizeof(struct dcbx_mib); 804 rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 805 806 return rc; 807 } 808 809 static int 810 qed_dcbx_read_local_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 811 { 812 struct qed_dcbx_mib_meta_data data; 813 int rc = 0; 814 815 memset(&data, 0, sizeof(data)); 816 data.addr = p_hwfn->mcp_info->port_addr + 817 offsetof(struct public_port, local_admin_dcbx_mib); 818 data.local_admin = &p_hwfn->p_dcbx_info->local_admin; 819 data.size = sizeof(struct dcbx_local_params); 820 qed_memcpy_from(p_hwfn, p_ptt, data.local_admin, data.addr, data.size); 821 822 return rc; 823 } 824 825 static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn, 826 struct qed_ptt *p_ptt, enum qed_mib_read_type type) 827 { 828 int rc = -EINVAL; 829 830 switch (type) { 831 case QED_DCBX_OPERATIONAL_MIB: 832 rc = qed_dcbx_read_operational_mib(p_hwfn, p_ptt, type); 833 break; 834 case QED_DCBX_REMOTE_MIB: 835 rc = qed_dcbx_read_remote_mib(p_hwfn, p_ptt, type); 836 break; 837 case QED_DCBX_LOCAL_MIB: 838 rc = qed_dcbx_read_local_mib(p_hwfn, p_ptt); 839 break; 840 case QED_DCBX_REMOTE_LLDP_MIB: 841 rc = qed_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type); 842 break; 843 case QED_DCBX_LOCAL_LLDP_MIB: 844 rc = qed_dcbx_read_local_lldp_mib(p_hwfn, p_ptt); 845 break; 846 default: 847 DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 848 } 849 850 return rc; 851 } 852 853 static void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type) 854 { 855 struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common; 856 void *cookie = hwfn->cdev->ops_cookie; 857 858 if (cookie && op->dcbx_aen) 859 op->dcbx_aen(cookie, &hwfn->p_dcbx_info->get, mib_type); 860 } 861 862 /* Read updated MIB. 863 * Reconfigure QM and invoke PF update ramrod command if operational MIB 864 * change is detected. 865 */ 866 int 867 qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn, 868 struct qed_ptt *p_ptt, enum qed_mib_read_type type) 869 { 870 int rc = 0; 871 872 rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 873 if (rc) 874 return rc; 875 876 if (type == QED_DCBX_OPERATIONAL_MIB) { 877 rc = qed_dcbx_process_mib_info(p_hwfn, p_ptt); 878 if (!rc) { 879 /* reconfigure tcs of QM queues according 880 * to negotiation results 881 */ 882 qed_qm_reconf(p_hwfn, p_ptt); 883 884 /* update storm FW with negotiation results */ 885 qed_sp_pf_update(p_hwfn); 886 887 /* for roce PFs, we may want to enable/disable DPM 888 * when DCBx change occurs 889 */ 890 if (p_hwfn->hw_info.personality == 891 QED_PCI_ETH_ROCE) 892 qed_roce_dpm_dcbx(p_hwfn, p_ptt); 893 } 894 } 895 896 qed_dcbx_get_params(p_hwfn, &p_hwfn->p_dcbx_info->get, type); 897 898 if (type == QED_DCBX_OPERATIONAL_MIB) { 899 struct qed_dcbx_results *p_data; 900 u16 val; 901 902 /* Configure in NIG which protocols support EDPM and should 903 * honor PFC. 904 */ 905 p_data = &p_hwfn->p_dcbx_info->results; 906 val = (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE].tc) | 907 (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE_V2].tc); 908 val <<= NIG_REG_TX_EDPM_CTRL_TX_EDPM_TC_EN_SHIFT; 909 val |= NIG_REG_TX_EDPM_CTRL_TX_EDPM_EN; 910 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_EDPM_CTRL, val); 911 } 912 913 qed_dcbx_aen(p_hwfn, type); 914 915 return rc; 916 } 917 918 int qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn) 919 { 920 p_hwfn->p_dcbx_info = kzalloc(sizeof(*p_hwfn->p_dcbx_info), GFP_KERNEL); 921 if (!p_hwfn->p_dcbx_info) 922 return -ENOMEM; 923 924 return 0; 925 } 926 927 void qed_dcbx_info_free(struct qed_hwfn *p_hwfn) 928 { 929 kfree(p_hwfn->p_dcbx_info); 930 p_hwfn->p_dcbx_info = NULL; 931 } 932 933 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data, 934 struct qed_dcbx_results *p_src, 935 enum dcbx_protocol_type type) 936 { 937 p_data->dcb_enable_flag = p_src->arr[type].enable; 938 p_data->dcb_priority = p_src->arr[type].priority; 939 p_data->dcb_tc = p_src->arr[type].tc; 940 p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0; 941 } 942 943 /* Set pf update ramrod command params */ 944 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src, 945 struct pf_update_ramrod_data *p_dest) 946 { 947 struct protocol_dcb_data *p_dcb_data; 948 u8 update_flag; 949 950 update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update; 951 p_dest->update_fcoe_dcb_data_mode = update_flag; 952 953 update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update; 954 p_dest->update_roce_dcb_data_mode = update_flag; 955 956 update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update; 957 p_dest->update_rroce_dcb_data_mode = update_flag; 958 959 update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update; 960 p_dest->update_iscsi_dcb_data_mode = update_flag; 961 update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update; 962 p_dest->update_eth_dcb_data_mode = update_flag; 963 964 p_dcb_data = &p_dest->fcoe_dcb_data; 965 qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE); 966 p_dcb_data = &p_dest->roce_dcb_data; 967 qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE); 968 p_dcb_data = &p_dest->rroce_dcb_data; 969 qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE_V2); 970 p_dcb_data = &p_dest->iscsi_dcb_data; 971 qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI); 972 p_dcb_data = &p_dest->eth_dcb_data; 973 qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH); 974 } 975 976 u8 qed_dcbx_get_priority_tc(struct qed_hwfn *p_hwfn, u8 pri) 977 { 978 struct qed_dcbx_get *dcbx_info = &p_hwfn->p_dcbx_info->get; 979 980 if (pri >= QED_MAX_PFC_PRIORITIES) { 981 DP_ERR(p_hwfn, "Invalid priority %d\n", pri); 982 return QED_DCBX_DEFAULT_TC; 983 } 984 985 if (!dcbx_info->operational.valid) { 986 DP_VERBOSE(p_hwfn, QED_MSG_DCB, 987 "Dcbx parameters not available\n"); 988 return QED_DCBX_DEFAULT_TC; 989 } 990 991 return dcbx_info->operational.params.ets_pri_tc_tbl[pri]; 992 } 993 994 #ifdef CONFIG_DCB 995 static int qed_dcbx_query_params(struct qed_hwfn *p_hwfn, 996 struct qed_dcbx_get *p_get, 997 enum qed_mib_read_type type) 998 { 999 struct qed_ptt *p_ptt; 1000 int rc; 1001 1002 if (IS_VF(p_hwfn->cdev)) 1003 return -EINVAL; 1004 1005 p_ptt = qed_ptt_acquire(p_hwfn); 1006 if (!p_ptt) 1007 return -EBUSY; 1008 1009 rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 1010 if (rc) 1011 goto out; 1012 1013 rc = qed_dcbx_get_params(p_hwfn, p_get, type); 1014 1015 out: 1016 qed_ptt_release(p_hwfn, p_ptt); 1017 return rc; 1018 } 1019 1020 static void 1021 qed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn, 1022 u32 *pfc, struct qed_dcbx_params *p_params) 1023 { 1024 u8 pfc_map = 0; 1025 int i; 1026 1027 *pfc &= ~DCBX_PFC_ERROR_MASK; 1028 1029 if (p_params->pfc.willing) 1030 *pfc |= DCBX_PFC_WILLING_MASK; 1031 else 1032 *pfc &= ~DCBX_PFC_WILLING_MASK; 1033 1034 if (p_params->pfc.enabled) 1035 *pfc |= DCBX_PFC_ENABLED_MASK; 1036 else 1037 *pfc &= ~DCBX_PFC_ENABLED_MASK; 1038 1039 *pfc &= ~DCBX_PFC_CAPS_MASK; 1040 *pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT; 1041 1042 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 1043 if (p_params->pfc.prio[i]) 1044 pfc_map |= BIT(i); 1045 1046 *pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK; 1047 *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT); 1048 1049 DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc); 1050 } 1051 1052 static void 1053 qed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn, 1054 struct dcbx_ets_feature *p_ets, 1055 struct qed_dcbx_params *p_params) 1056 { 1057 __be32 bw_map[2], tsa_map[2]; 1058 u32 val; 1059 int i; 1060 1061 if (p_params->ets_willing) 1062 p_ets->flags |= DCBX_ETS_WILLING_MASK; 1063 else 1064 p_ets->flags &= ~DCBX_ETS_WILLING_MASK; 1065 1066 if (p_params->ets_cbs) 1067 p_ets->flags |= DCBX_ETS_CBS_MASK; 1068 else 1069 p_ets->flags &= ~DCBX_ETS_CBS_MASK; 1070 1071 if (p_params->ets_enabled) 1072 p_ets->flags |= DCBX_ETS_ENABLED_MASK; 1073 else 1074 p_ets->flags &= ~DCBX_ETS_ENABLED_MASK; 1075 1076 p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK; 1077 p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT; 1078 1079 p_ets->pri_tc_tbl[0] = 0; 1080 1081 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 1082 ((u8 *)bw_map)[i] = p_params->ets_tc_bw_tbl[i]; 1083 ((u8 *)tsa_map)[i] = p_params->ets_tc_tsa_tbl[i]; 1084 1085 /* Copy the priority value to the corresponding 4 bits in the 1086 * traffic class table. 1087 */ 1088 val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4)); 1089 p_ets->pri_tc_tbl[0] |= val; 1090 } 1091 1092 be32_to_cpu_array(p_ets->tc_bw_tbl, bw_map, 2); 1093 be32_to_cpu_array(p_ets->tc_tsa_tbl, tsa_map, 2); 1094 } 1095 1096 static void 1097 qed_dcbx_set_app_data(struct qed_hwfn *p_hwfn, 1098 struct dcbx_app_priority_feature *p_app, 1099 struct qed_dcbx_params *p_params, bool ieee) 1100 { 1101 u32 *entry; 1102 int i; 1103 1104 if (p_params->app_willing) 1105 p_app->flags |= DCBX_APP_WILLING_MASK; 1106 else 1107 p_app->flags &= ~DCBX_APP_WILLING_MASK; 1108 1109 if (p_params->app_valid) 1110 p_app->flags |= DCBX_APP_ENABLED_MASK; 1111 else 1112 p_app->flags &= ~DCBX_APP_ENABLED_MASK; 1113 1114 p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK; 1115 p_app->flags |= (u32)p_params->num_app_entries << 1116 DCBX_APP_NUM_ENTRIES_SHIFT; 1117 1118 for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 1119 entry = &p_app->app_pri_tbl[i].entry; 1120 *entry = 0; 1121 if (ieee) { 1122 *entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK); 1123 switch (p_params->app_entry[i].sf_ieee) { 1124 case QED_DCBX_SF_IEEE_ETHTYPE: 1125 *entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE << 1126 DCBX_APP_SF_IEEE_SHIFT); 1127 *entry |= ((u32)DCBX_APP_SF_ETHTYPE << 1128 DCBX_APP_SF_SHIFT); 1129 break; 1130 case QED_DCBX_SF_IEEE_TCP_PORT: 1131 *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT << 1132 DCBX_APP_SF_IEEE_SHIFT); 1133 *entry |= ((u32)DCBX_APP_SF_PORT << 1134 DCBX_APP_SF_SHIFT); 1135 break; 1136 case QED_DCBX_SF_IEEE_UDP_PORT: 1137 *entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT << 1138 DCBX_APP_SF_IEEE_SHIFT); 1139 *entry |= ((u32)DCBX_APP_SF_PORT << 1140 DCBX_APP_SF_SHIFT); 1141 break; 1142 case QED_DCBX_SF_IEEE_TCP_UDP_PORT: 1143 *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT << 1144 DCBX_APP_SF_IEEE_SHIFT); 1145 *entry |= ((u32)DCBX_APP_SF_PORT << 1146 DCBX_APP_SF_SHIFT); 1147 break; 1148 } 1149 } else { 1150 *entry &= ~DCBX_APP_SF_MASK; 1151 if (p_params->app_entry[i].ethtype) 1152 *entry |= ((u32)DCBX_APP_SF_ETHTYPE << 1153 DCBX_APP_SF_SHIFT); 1154 else 1155 *entry |= ((u32)DCBX_APP_SF_PORT << 1156 DCBX_APP_SF_SHIFT); 1157 } 1158 1159 *entry &= ~DCBX_APP_PROTOCOL_ID_MASK; 1160 *entry |= ((u32)p_params->app_entry[i].proto_id << 1161 DCBX_APP_PROTOCOL_ID_SHIFT); 1162 *entry &= ~DCBX_APP_PRI_MAP_MASK; 1163 *entry |= ((u32)(p_params->app_entry[i].prio) << 1164 DCBX_APP_PRI_MAP_SHIFT); 1165 } 1166 } 1167 1168 static void 1169 qed_dcbx_set_local_params(struct qed_hwfn *p_hwfn, 1170 struct dcbx_local_params *local_admin, 1171 struct qed_dcbx_set *params) 1172 { 1173 bool ieee = false; 1174 1175 local_admin->flags = 0; 1176 memcpy(&local_admin->features, 1177 &p_hwfn->p_dcbx_info->operational.features, 1178 sizeof(local_admin->features)); 1179 1180 if (params->enabled) { 1181 local_admin->config = params->ver_num; 1182 ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE); 1183 } else { 1184 local_admin->config = DCBX_CONFIG_VERSION_DISABLED; 1185 } 1186 1187 DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Dcbx version = %d\n", 1188 local_admin->config); 1189 1190 if (params->override_flags & QED_DCBX_OVERRIDE_PFC_CFG) 1191 qed_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc, 1192 ¶ms->config.params); 1193 1194 if (params->override_flags & QED_DCBX_OVERRIDE_ETS_CFG) 1195 qed_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets, 1196 ¶ms->config.params); 1197 1198 if (params->override_flags & QED_DCBX_OVERRIDE_APP_CFG) 1199 qed_dcbx_set_app_data(p_hwfn, &local_admin->features.app, 1200 ¶ms->config.params, ieee); 1201 } 1202 1203 int qed_dcbx_config_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 1204 struct qed_dcbx_set *params, bool hw_commit) 1205 { 1206 struct dcbx_local_params local_admin; 1207 struct qed_dcbx_mib_meta_data data; 1208 u32 resp = 0, param = 0; 1209 int rc = 0; 1210 1211 if (!hw_commit) { 1212 memcpy(&p_hwfn->p_dcbx_info->set, params, 1213 sizeof(struct qed_dcbx_set)); 1214 return 0; 1215 } 1216 1217 /* clear set-parmas cache */ 1218 memset(&p_hwfn->p_dcbx_info->set, 0, sizeof(p_hwfn->p_dcbx_info->set)); 1219 1220 memset(&local_admin, 0, sizeof(local_admin)); 1221 qed_dcbx_set_local_params(p_hwfn, &local_admin, params); 1222 1223 data.addr = p_hwfn->mcp_info->port_addr + 1224 offsetof(struct public_port, local_admin_dcbx_mib); 1225 data.local_admin = &local_admin; 1226 data.size = sizeof(struct dcbx_local_params); 1227 qed_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size); 1228 1229 rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX, 1230 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, ¶m); 1231 if (rc) 1232 DP_NOTICE(p_hwfn, "Failed to send DCBX update request\n"); 1233 1234 return rc; 1235 } 1236 1237 int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, 1238 struct qed_dcbx_set *params) 1239 { 1240 struct qed_dcbx_get *dcbx_info; 1241 int rc; 1242 1243 if (p_hwfn->p_dcbx_info->set.config.valid) { 1244 memcpy(params, &p_hwfn->p_dcbx_info->set, 1245 sizeof(struct qed_dcbx_set)); 1246 return 0; 1247 } 1248 1249 dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL); 1250 if (!dcbx_info) 1251 return -ENOMEM; 1252 1253 rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB); 1254 if (rc) { 1255 kfree(dcbx_info); 1256 return rc; 1257 } 1258 1259 p_hwfn->p_dcbx_info->set.override_flags = 0; 1260 p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED; 1261 if (dcbx_info->operational.cee) 1262 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE; 1263 if (dcbx_info->operational.ieee) 1264 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 1265 if (dcbx_info->operational.local) 1266 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC; 1267 1268 p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; 1269 BUILD_BUG_ON(sizeof(dcbx_info->operational.params) != 1270 sizeof(p_hwfn->p_dcbx_info->set.config.params)); 1271 memcpy(&p_hwfn->p_dcbx_info->set.config.params, 1272 &dcbx_info->operational.params, 1273 sizeof(p_hwfn->p_dcbx_info->set.config.params)); 1274 p_hwfn->p_dcbx_info->set.config.valid = true; 1275 1276 memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); 1277 1278 kfree(dcbx_info); 1279 1280 return 0; 1281 } 1282 1283 static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, 1284 enum qed_mib_read_type type) 1285 { 1286 struct qed_dcbx_get *dcbx_info; 1287 1288 dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_ATOMIC); 1289 if (!dcbx_info) 1290 return NULL; 1291 1292 if (qed_dcbx_query_params(hwfn, dcbx_info, type)) { 1293 kfree(dcbx_info); 1294 return NULL; 1295 } 1296 1297 if ((type == QED_DCBX_OPERATIONAL_MIB) && 1298 !dcbx_info->operational.enabled) { 1299 DP_INFO(hwfn, "DCBX is not enabled/operational\n"); 1300 kfree(dcbx_info); 1301 return NULL; 1302 } 1303 1304 return dcbx_info; 1305 } 1306 1307 static u8 qed_dcbnl_getstate(struct qed_dev *cdev) 1308 { 1309 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1310 struct qed_dcbx_get *dcbx_info; 1311 bool enabled; 1312 1313 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1314 if (!dcbx_info) 1315 return 0; 1316 1317 enabled = dcbx_info->operational.enabled; 1318 DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", enabled); 1319 kfree(dcbx_info); 1320 1321 return enabled; 1322 } 1323 1324 static u8 qed_dcbnl_setstate(struct qed_dev *cdev, u8 state) 1325 { 1326 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1327 struct qed_dcbx_set dcbx_set; 1328 struct qed_ptt *ptt; 1329 int rc; 1330 1331 DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", state); 1332 1333 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1334 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1335 if (rc) 1336 return 1; 1337 1338 dcbx_set.enabled = !!state; 1339 1340 ptt = qed_ptt_acquire(hwfn); 1341 if (!ptt) 1342 return 1; 1343 1344 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1345 1346 qed_ptt_release(hwfn, ptt); 1347 1348 return rc ? 1 : 0; 1349 } 1350 1351 static void qed_dcbnl_getpgtccfgtx(struct qed_dev *cdev, int tc, u8 *prio_type, 1352 u8 *pgid, u8 *bw_pct, u8 *up_map) 1353 { 1354 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1355 struct qed_dcbx_get *dcbx_info; 1356 1357 DP_VERBOSE(hwfn, QED_MSG_DCB, "tc = %d\n", tc); 1358 *prio_type = *pgid = *bw_pct = *up_map = 0; 1359 if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 1360 DP_INFO(hwfn, "Invalid tc %d\n", tc); 1361 return; 1362 } 1363 1364 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1365 if (!dcbx_info) 1366 return; 1367 1368 *pgid = dcbx_info->operational.params.ets_pri_tc_tbl[tc]; 1369 kfree(dcbx_info); 1370 } 1371 1372 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 *bw_pct) 1373 { 1374 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1375 struct qed_dcbx_get *dcbx_info; 1376 1377 *bw_pct = 0; 1378 DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d\n", pgid); 1379 if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 1380 DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 1381 return; 1382 } 1383 1384 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1385 if (!dcbx_info) 1386 return; 1387 1388 *bw_pct = dcbx_info->operational.params.ets_tc_bw_tbl[pgid]; 1389 DP_VERBOSE(hwfn, QED_MSG_DCB, "bw_pct = %d\n", *bw_pct); 1390 kfree(dcbx_info); 1391 } 1392 1393 static void qed_dcbnl_getpgtccfgrx(struct qed_dev *cdev, int tc, u8 *prio, 1394 u8 *bwg_id, u8 *bw_pct, u8 *up_map) 1395 { 1396 DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1397 *prio = *bwg_id = *bw_pct = *up_map = 0; 1398 } 1399 1400 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev *cdev, 1401 int bwg_id, u8 *bw_pct) 1402 { 1403 DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1404 *bw_pct = 0; 1405 } 1406 1407 static void qed_dcbnl_getpfccfg(struct qed_dev *cdev, 1408 int priority, u8 *setting) 1409 { 1410 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1411 struct qed_dcbx_get *dcbx_info; 1412 1413 DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d\n", priority); 1414 if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 1415 DP_INFO(hwfn, "Invalid priority %d\n", priority); 1416 return; 1417 } 1418 1419 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1420 if (!dcbx_info) 1421 return; 1422 1423 *setting = dcbx_info->operational.params.pfc.prio[priority]; 1424 DP_VERBOSE(hwfn, QED_MSG_DCB, "setting = %d\n", *setting); 1425 kfree(dcbx_info); 1426 } 1427 1428 static void qed_dcbnl_setpfccfg(struct qed_dev *cdev, int priority, u8 setting) 1429 { 1430 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1431 struct qed_dcbx_set dcbx_set; 1432 struct qed_ptt *ptt; 1433 int rc; 1434 1435 DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d setting = %d\n", 1436 priority, setting); 1437 if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 1438 DP_INFO(hwfn, "Invalid priority %d\n", priority); 1439 return; 1440 } 1441 1442 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1443 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1444 if (rc) 1445 return; 1446 1447 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1448 dcbx_set.config.params.pfc.prio[priority] = !!setting; 1449 1450 ptt = qed_ptt_acquire(hwfn); 1451 if (!ptt) 1452 return; 1453 1454 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1455 1456 qed_ptt_release(hwfn, ptt); 1457 } 1458 1459 static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap) 1460 { 1461 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1462 struct qed_dcbx_get *dcbx_info; 1463 int rc = 0; 1464 1465 DP_VERBOSE(hwfn, QED_MSG_DCB, "capid = %d\n", capid); 1466 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1467 if (!dcbx_info) 1468 return 1; 1469 1470 switch (capid) { 1471 case DCB_CAP_ATTR_PG: 1472 case DCB_CAP_ATTR_PFC: 1473 case DCB_CAP_ATTR_UP2TC: 1474 case DCB_CAP_ATTR_GSP: 1475 *cap = true; 1476 break; 1477 case DCB_CAP_ATTR_PG_TCS: 1478 case DCB_CAP_ATTR_PFC_TCS: 1479 *cap = 0x80; 1480 break; 1481 case DCB_CAP_ATTR_DCBX: 1482 *cap = (DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_VER_IEEE | 1483 DCB_CAP_DCBX_STATIC); 1484 break; 1485 default: 1486 *cap = false; 1487 rc = 1; 1488 } 1489 1490 DP_VERBOSE(hwfn, QED_MSG_DCB, "id = %d caps = %d\n", capid, *cap); 1491 kfree(dcbx_info); 1492 1493 return rc; 1494 } 1495 1496 static int qed_dcbnl_getnumtcs(struct qed_dev *cdev, int tcid, u8 *num) 1497 { 1498 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1499 struct qed_dcbx_get *dcbx_info; 1500 int rc = 0; 1501 1502 DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d\n", tcid); 1503 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1504 if (!dcbx_info) 1505 return -EINVAL; 1506 1507 switch (tcid) { 1508 case DCB_NUMTCS_ATTR_PG: 1509 *num = dcbx_info->operational.params.max_ets_tc; 1510 break; 1511 case DCB_NUMTCS_ATTR_PFC: 1512 *num = dcbx_info->operational.params.pfc.max_tc; 1513 break; 1514 default: 1515 rc = -EINVAL; 1516 } 1517 1518 kfree(dcbx_info); 1519 DP_VERBOSE(hwfn, QED_MSG_DCB, "numtcs = %d\n", *num); 1520 1521 return rc; 1522 } 1523 1524 static u8 qed_dcbnl_getpfcstate(struct qed_dev *cdev) 1525 { 1526 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1527 struct qed_dcbx_get *dcbx_info; 1528 bool enabled; 1529 1530 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1531 if (!dcbx_info) 1532 return 0; 1533 1534 enabled = dcbx_info->operational.params.pfc.enabled; 1535 DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d\n", enabled); 1536 kfree(dcbx_info); 1537 1538 return enabled; 1539 } 1540 1541 static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev) 1542 { 1543 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1544 struct qed_dcbx_get *dcbx_info; 1545 u8 mode = 0; 1546 1547 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1548 if (!dcbx_info) 1549 return 0; 1550 1551 if (dcbx_info->operational.ieee) 1552 mode |= DCB_CAP_DCBX_VER_IEEE; 1553 if (dcbx_info->operational.cee) 1554 mode |= DCB_CAP_DCBX_VER_CEE; 1555 if (dcbx_info->operational.local) 1556 mode |= DCB_CAP_DCBX_STATIC; 1557 1558 DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode); 1559 kfree(dcbx_info); 1560 1561 return mode; 1562 } 1563 1564 static void qed_dcbnl_setpgtccfgtx(struct qed_dev *cdev, 1565 int tc, 1566 u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 1567 { 1568 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1569 struct qed_dcbx_set dcbx_set; 1570 struct qed_ptt *ptt; 1571 int rc; 1572 1573 DP_VERBOSE(hwfn, QED_MSG_DCB, 1574 "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n", 1575 tc, pri_type, pgid, bw_pct, up_map); 1576 1577 if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 1578 DP_INFO(hwfn, "Invalid tc %d\n", tc); 1579 return; 1580 } 1581 1582 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1583 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1584 if (rc) 1585 return; 1586 1587 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1588 dcbx_set.config.params.ets_pri_tc_tbl[tc] = pgid; 1589 1590 ptt = qed_ptt_acquire(hwfn); 1591 if (!ptt) 1592 return; 1593 1594 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1595 1596 qed_ptt_release(hwfn, ptt); 1597 } 1598 1599 static void qed_dcbnl_setpgtccfgrx(struct qed_dev *cdev, int prio, 1600 u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 1601 { 1602 DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1603 } 1604 1605 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 bw_pct) 1606 { 1607 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1608 struct qed_dcbx_set dcbx_set; 1609 struct qed_ptt *ptt; 1610 int rc; 1611 1612 DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d bw_pct = %d\n", pgid, bw_pct); 1613 if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 1614 DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 1615 return; 1616 } 1617 1618 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1619 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1620 if (rc) 1621 return; 1622 1623 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1624 dcbx_set.config.params.ets_tc_bw_tbl[pgid] = bw_pct; 1625 1626 ptt = qed_ptt_acquire(hwfn); 1627 if (!ptt) 1628 return; 1629 1630 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1631 1632 qed_ptt_release(hwfn, ptt); 1633 } 1634 1635 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev *cdev, int pgid, u8 bw_pct) 1636 { 1637 DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1638 } 1639 1640 static u8 qed_dcbnl_setall(struct qed_dev *cdev) 1641 { 1642 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1643 struct qed_dcbx_set dcbx_set; 1644 struct qed_ptt *ptt; 1645 int rc; 1646 1647 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1648 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1649 if (rc) 1650 return 1; 1651 1652 ptt = qed_ptt_acquire(hwfn); 1653 if (!ptt) 1654 return 1; 1655 1656 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 1); 1657 1658 qed_ptt_release(hwfn, ptt); 1659 1660 return rc; 1661 } 1662 1663 static int qed_dcbnl_setnumtcs(struct qed_dev *cdev, int tcid, u8 num) 1664 { 1665 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1666 struct qed_dcbx_set dcbx_set; 1667 struct qed_ptt *ptt; 1668 int rc; 1669 1670 DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d num = %d\n", tcid, num); 1671 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1672 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1673 if (rc) 1674 return 1; 1675 1676 switch (tcid) { 1677 case DCB_NUMTCS_ATTR_PG: 1678 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1679 dcbx_set.config.params.max_ets_tc = num; 1680 break; 1681 case DCB_NUMTCS_ATTR_PFC: 1682 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1683 dcbx_set.config.params.pfc.max_tc = num; 1684 break; 1685 default: 1686 DP_INFO(hwfn, "Invalid tcid %d\n", tcid); 1687 return -EINVAL; 1688 } 1689 1690 ptt = qed_ptt_acquire(hwfn); 1691 if (!ptt) 1692 return -EINVAL; 1693 1694 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1695 1696 qed_ptt_release(hwfn, ptt); 1697 1698 return 0; 1699 } 1700 1701 static void qed_dcbnl_setpfcstate(struct qed_dev *cdev, u8 state) 1702 { 1703 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1704 struct qed_dcbx_set dcbx_set; 1705 struct qed_ptt *ptt; 1706 int rc; 1707 1708 DP_VERBOSE(hwfn, QED_MSG_DCB, "new state = %d\n", state); 1709 1710 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1711 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1712 if (rc) 1713 return; 1714 1715 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1716 dcbx_set.config.params.pfc.enabled = !!state; 1717 1718 ptt = qed_ptt_acquire(hwfn); 1719 if (!ptt) 1720 return; 1721 1722 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1723 1724 qed_ptt_release(hwfn, ptt); 1725 } 1726 1727 static int qed_dcbnl_getapp(struct qed_dev *cdev, u8 idtype, u16 idval) 1728 { 1729 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1730 struct qed_dcbx_get *dcbx_info; 1731 struct qed_app_entry *entry; 1732 bool ethtype; 1733 u8 prio = 0; 1734 int i; 1735 1736 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1737 if (!dcbx_info) 1738 return -EINVAL; 1739 1740 ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 1741 for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 1742 entry = &dcbx_info->operational.params.app_entry[i]; 1743 if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) { 1744 prio = entry->prio; 1745 break; 1746 } 1747 } 1748 1749 if (i == QED_DCBX_MAX_APP_PROTOCOL) { 1750 DP_ERR(cdev, "App entry (%d, %d) not found\n", idtype, idval); 1751 kfree(dcbx_info); 1752 return -EINVAL; 1753 } 1754 1755 kfree(dcbx_info); 1756 1757 return prio; 1758 } 1759 1760 static int qed_dcbnl_setapp(struct qed_dev *cdev, 1761 u8 idtype, u16 idval, u8 pri_map) 1762 { 1763 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1764 struct qed_dcbx_set dcbx_set; 1765 struct qed_app_entry *entry; 1766 struct qed_ptt *ptt; 1767 bool ethtype; 1768 int rc, i; 1769 1770 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1771 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1772 if (rc) 1773 return -EINVAL; 1774 1775 ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 1776 for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 1777 entry = &dcbx_set.config.params.app_entry[i]; 1778 if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) 1779 break; 1780 /* First empty slot */ 1781 if (!entry->proto_id) { 1782 dcbx_set.config.params.num_app_entries++; 1783 break; 1784 } 1785 } 1786 1787 if (i == QED_DCBX_MAX_APP_PROTOCOL) { 1788 DP_ERR(cdev, "App table is full\n"); 1789 return -EBUSY; 1790 } 1791 1792 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 1793 dcbx_set.config.params.app_entry[i].ethtype = ethtype; 1794 dcbx_set.config.params.app_entry[i].proto_id = idval; 1795 dcbx_set.config.params.app_entry[i].prio = pri_map; 1796 1797 ptt = qed_ptt_acquire(hwfn); 1798 if (!ptt) 1799 return -EBUSY; 1800 1801 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1802 1803 qed_ptt_release(hwfn, ptt); 1804 1805 return rc; 1806 } 1807 1808 static u8 qed_dcbnl_setdcbx(struct qed_dev *cdev, u8 mode) 1809 { 1810 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1811 struct qed_dcbx_set dcbx_set; 1812 struct qed_ptt *ptt; 1813 int rc; 1814 1815 DP_VERBOSE(hwfn, QED_MSG_DCB, "new mode = %x\n", mode); 1816 1817 if (!(mode & DCB_CAP_DCBX_VER_IEEE) && 1818 !(mode & DCB_CAP_DCBX_VER_CEE) && !(mode & DCB_CAP_DCBX_STATIC)) { 1819 DP_INFO(hwfn, "Allowed modes are cee, ieee or static\n"); 1820 return 1; 1821 } 1822 1823 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1824 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1825 if (rc) 1826 return 1; 1827 1828 dcbx_set.ver_num = 0; 1829 if (mode & DCB_CAP_DCBX_VER_CEE) { 1830 dcbx_set.ver_num |= DCBX_CONFIG_VERSION_CEE; 1831 dcbx_set.enabled = true; 1832 } 1833 1834 if (mode & DCB_CAP_DCBX_VER_IEEE) { 1835 dcbx_set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 1836 dcbx_set.enabled = true; 1837 } 1838 1839 if (mode & DCB_CAP_DCBX_STATIC) { 1840 dcbx_set.ver_num |= DCBX_CONFIG_VERSION_STATIC; 1841 dcbx_set.enabled = true; 1842 } 1843 1844 ptt = qed_ptt_acquire(hwfn); 1845 if (!ptt) 1846 return 1; 1847 1848 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1849 1850 qed_ptt_release(hwfn, ptt); 1851 1852 return rc; 1853 } 1854 1855 static u8 qed_dcbnl_getfeatcfg(struct qed_dev *cdev, int featid, u8 *flags) 1856 { 1857 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1858 struct qed_dcbx_get *dcbx_info; 1859 1860 DP_VERBOSE(hwfn, QED_MSG_DCB, "Feature id = %d\n", featid); 1861 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1862 if (!dcbx_info) 1863 return 1; 1864 1865 *flags = 0; 1866 switch (featid) { 1867 case DCB_FEATCFG_ATTR_PG: 1868 if (dcbx_info->operational.params.ets_enabled) 1869 *flags = DCB_FEATCFG_ENABLE; 1870 else 1871 *flags = DCB_FEATCFG_ERROR; 1872 break; 1873 case DCB_FEATCFG_ATTR_PFC: 1874 if (dcbx_info->operational.params.pfc.enabled) 1875 *flags = DCB_FEATCFG_ENABLE; 1876 else 1877 *flags = DCB_FEATCFG_ERROR; 1878 break; 1879 case DCB_FEATCFG_ATTR_APP: 1880 if (dcbx_info->operational.params.app_valid) 1881 *flags = DCB_FEATCFG_ENABLE; 1882 else 1883 *flags = DCB_FEATCFG_ERROR; 1884 break; 1885 default: 1886 DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 1887 kfree(dcbx_info); 1888 return 1; 1889 } 1890 1891 DP_VERBOSE(hwfn, QED_MSG_DCB, "flags = %d\n", *flags); 1892 kfree(dcbx_info); 1893 1894 return 0; 1895 } 1896 1897 static u8 qed_dcbnl_setfeatcfg(struct qed_dev *cdev, int featid, u8 flags) 1898 { 1899 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1900 struct qed_dcbx_set dcbx_set; 1901 bool enabled, willing; 1902 struct qed_ptt *ptt; 1903 int rc; 1904 1905 DP_VERBOSE(hwfn, QED_MSG_DCB, "featid = %d flags = %d\n", 1906 featid, flags); 1907 memset(&dcbx_set, 0, sizeof(dcbx_set)); 1908 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1909 if (rc) 1910 return 1; 1911 1912 enabled = !!(flags & DCB_FEATCFG_ENABLE); 1913 willing = !!(flags & DCB_FEATCFG_WILLING); 1914 switch (featid) { 1915 case DCB_FEATCFG_ATTR_PG: 1916 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1917 dcbx_set.config.params.ets_enabled = enabled; 1918 dcbx_set.config.params.ets_willing = willing; 1919 break; 1920 case DCB_FEATCFG_ATTR_PFC: 1921 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1922 dcbx_set.config.params.pfc.enabled = enabled; 1923 dcbx_set.config.params.pfc.willing = willing; 1924 break; 1925 case DCB_FEATCFG_ATTR_APP: 1926 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 1927 dcbx_set.config.params.app_willing = willing; 1928 break; 1929 default: 1930 DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 1931 return 1; 1932 } 1933 1934 ptt = qed_ptt_acquire(hwfn); 1935 if (!ptt) 1936 return 1; 1937 1938 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1939 1940 qed_ptt_release(hwfn, ptt); 1941 1942 return 0; 1943 } 1944 1945 static int qed_dcbnl_peer_getappinfo(struct qed_dev *cdev, 1946 struct dcb_peer_app_info *info, 1947 u16 *app_count) 1948 { 1949 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1950 struct qed_dcbx_get *dcbx_info; 1951 1952 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1953 if (!dcbx_info) 1954 return -EINVAL; 1955 1956 info->willing = dcbx_info->remote.params.app_willing; 1957 info->error = dcbx_info->remote.params.app_error; 1958 *app_count = dcbx_info->remote.params.num_app_entries; 1959 kfree(dcbx_info); 1960 1961 return 0; 1962 } 1963 1964 static int qed_dcbnl_peer_getapptable(struct qed_dev *cdev, 1965 struct dcb_app *table) 1966 { 1967 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1968 struct qed_dcbx_get *dcbx_info; 1969 int i; 1970 1971 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1972 if (!dcbx_info) 1973 return -EINVAL; 1974 1975 for (i = 0; i < dcbx_info->remote.params.num_app_entries; i++) { 1976 if (dcbx_info->remote.params.app_entry[i].ethtype) 1977 table[i].selector = DCB_APP_IDTYPE_ETHTYPE; 1978 else 1979 table[i].selector = DCB_APP_IDTYPE_PORTNUM; 1980 table[i].priority = dcbx_info->remote.params.app_entry[i].prio; 1981 table[i].protocol = 1982 dcbx_info->remote.params.app_entry[i].proto_id; 1983 } 1984 1985 kfree(dcbx_info); 1986 1987 return 0; 1988 } 1989 1990 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev *cdev, struct cee_pfc *pfc) 1991 { 1992 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1993 struct qed_dcbx_get *dcbx_info; 1994 int i; 1995 1996 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1997 if (!dcbx_info) 1998 return -EINVAL; 1999 2000 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 2001 if (dcbx_info->remote.params.pfc.prio[i]) 2002 pfc->pfc_en |= BIT(i); 2003 2004 pfc->tcs_supported = dcbx_info->remote.params.pfc.max_tc; 2005 DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d tcs_supported = %d\n", 2006 pfc->pfc_en, pfc->tcs_supported); 2007 kfree(dcbx_info); 2008 2009 return 0; 2010 } 2011 2012 static int qed_dcbnl_cee_peer_getpg(struct qed_dev *cdev, struct cee_pg *pg) 2013 { 2014 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2015 struct qed_dcbx_get *dcbx_info; 2016 int i; 2017 2018 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 2019 if (!dcbx_info) 2020 return -EINVAL; 2021 2022 pg->willing = dcbx_info->remote.params.ets_willing; 2023 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 2024 pg->pg_bw[i] = dcbx_info->remote.params.ets_tc_bw_tbl[i]; 2025 pg->prio_pg[i] = dcbx_info->remote.params.ets_pri_tc_tbl[i]; 2026 } 2027 2028 DP_VERBOSE(hwfn, QED_MSG_DCB, "willing = %d", pg->willing); 2029 kfree(dcbx_info); 2030 2031 return 0; 2032 } 2033 2034 static int qed_dcbnl_get_ieee_pfc(struct qed_dev *cdev, 2035 struct ieee_pfc *pfc, bool remote) 2036 { 2037 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2038 struct qed_dcbx_params *params; 2039 struct qed_dcbx_get *dcbx_info; 2040 int rc, i; 2041 2042 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2043 if (!dcbx_info) 2044 return -EINVAL; 2045 2046 if (!dcbx_info->operational.ieee) { 2047 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2048 kfree(dcbx_info); 2049 return -EINVAL; 2050 } 2051 2052 if (remote) { 2053 memset(dcbx_info, 0, sizeof(*dcbx_info)); 2054 rc = qed_dcbx_query_params(hwfn, dcbx_info, 2055 QED_DCBX_REMOTE_MIB); 2056 if (rc) { 2057 kfree(dcbx_info); 2058 return -EINVAL; 2059 } 2060 2061 params = &dcbx_info->remote.params; 2062 } else { 2063 params = &dcbx_info->operational.params; 2064 } 2065 2066 pfc->pfc_cap = params->pfc.max_tc; 2067 pfc->pfc_en = 0; 2068 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 2069 if (params->pfc.prio[i]) 2070 pfc->pfc_en |= BIT(i); 2071 2072 kfree(dcbx_info); 2073 2074 return 0; 2075 } 2076 2077 static int qed_dcbnl_ieee_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2078 { 2079 return qed_dcbnl_get_ieee_pfc(cdev, pfc, false); 2080 } 2081 2082 static int qed_dcbnl_ieee_setpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2083 { 2084 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2085 struct qed_dcbx_get *dcbx_info; 2086 struct qed_dcbx_set dcbx_set; 2087 struct qed_ptt *ptt; 2088 int rc, i; 2089 2090 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2091 if (!dcbx_info) 2092 return -EINVAL; 2093 2094 if (!dcbx_info->operational.ieee) { 2095 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2096 kfree(dcbx_info); 2097 return -EINVAL; 2098 } 2099 2100 kfree(dcbx_info); 2101 2102 memset(&dcbx_set, 0, sizeof(dcbx_set)); 2103 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2104 if (rc) 2105 return -EINVAL; 2106 2107 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 2108 for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 2109 dcbx_set.config.params.pfc.prio[i] = !!(pfc->pfc_en & BIT(i)); 2110 2111 dcbx_set.config.params.pfc.max_tc = pfc->pfc_cap; 2112 2113 ptt = qed_ptt_acquire(hwfn); 2114 if (!ptt) 2115 return -EINVAL; 2116 2117 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2118 2119 qed_ptt_release(hwfn, ptt); 2120 2121 return rc; 2122 } 2123 2124 static int qed_dcbnl_get_ieee_ets(struct qed_dev *cdev, 2125 struct ieee_ets *ets, bool remote) 2126 { 2127 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2128 struct qed_dcbx_get *dcbx_info; 2129 struct qed_dcbx_params *params; 2130 int rc; 2131 2132 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2133 if (!dcbx_info) 2134 return -EINVAL; 2135 2136 if (!dcbx_info->operational.ieee) { 2137 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2138 kfree(dcbx_info); 2139 return -EINVAL; 2140 } 2141 2142 if (remote) { 2143 memset(dcbx_info, 0, sizeof(*dcbx_info)); 2144 rc = qed_dcbx_query_params(hwfn, dcbx_info, 2145 QED_DCBX_REMOTE_MIB); 2146 if (rc) { 2147 kfree(dcbx_info); 2148 return -EINVAL; 2149 } 2150 2151 params = &dcbx_info->remote.params; 2152 } else { 2153 params = &dcbx_info->operational.params; 2154 } 2155 2156 ets->ets_cap = params->max_ets_tc; 2157 ets->willing = params->ets_willing; 2158 ets->cbs = params->ets_cbs; 2159 memcpy(ets->tc_tx_bw, params->ets_tc_bw_tbl, sizeof(ets->tc_tx_bw)); 2160 memcpy(ets->tc_tsa, params->ets_tc_tsa_tbl, sizeof(ets->tc_tsa)); 2161 memcpy(ets->prio_tc, params->ets_pri_tc_tbl, sizeof(ets->prio_tc)); 2162 kfree(dcbx_info); 2163 2164 return 0; 2165 } 2166 2167 static int qed_dcbnl_ieee_getets(struct qed_dev *cdev, struct ieee_ets *ets) 2168 { 2169 return qed_dcbnl_get_ieee_ets(cdev, ets, false); 2170 } 2171 2172 static int qed_dcbnl_ieee_setets(struct qed_dev *cdev, struct ieee_ets *ets) 2173 { 2174 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2175 struct qed_dcbx_get *dcbx_info; 2176 struct qed_dcbx_set dcbx_set; 2177 struct qed_ptt *ptt; 2178 int rc; 2179 2180 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2181 if (!dcbx_info) 2182 return -EINVAL; 2183 2184 if (!dcbx_info->operational.ieee) { 2185 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2186 kfree(dcbx_info); 2187 return -EINVAL; 2188 } 2189 2190 kfree(dcbx_info); 2191 2192 memset(&dcbx_set, 0, sizeof(dcbx_set)); 2193 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2194 if (rc) 2195 return -EINVAL; 2196 2197 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 2198 dcbx_set.config.params.max_ets_tc = ets->ets_cap; 2199 dcbx_set.config.params.ets_willing = ets->willing; 2200 dcbx_set.config.params.ets_cbs = ets->cbs; 2201 memcpy(dcbx_set.config.params.ets_tc_bw_tbl, ets->tc_tx_bw, 2202 sizeof(ets->tc_tx_bw)); 2203 memcpy(dcbx_set.config.params.ets_tc_tsa_tbl, ets->tc_tsa, 2204 sizeof(ets->tc_tsa)); 2205 memcpy(dcbx_set.config.params.ets_pri_tc_tbl, ets->prio_tc, 2206 sizeof(ets->prio_tc)); 2207 2208 ptt = qed_ptt_acquire(hwfn); 2209 if (!ptt) 2210 return -EINVAL; 2211 2212 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2213 2214 qed_ptt_release(hwfn, ptt); 2215 2216 return rc; 2217 } 2218 2219 static int 2220 qed_dcbnl_ieee_peer_getets(struct qed_dev *cdev, struct ieee_ets *ets) 2221 { 2222 return qed_dcbnl_get_ieee_ets(cdev, ets, true); 2223 } 2224 2225 static int 2226 qed_dcbnl_ieee_peer_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2227 { 2228 return qed_dcbnl_get_ieee_pfc(cdev, pfc, true); 2229 } 2230 2231 static int qed_get_sf_ieee_value(u8 selector, u8 *sf_ieee) 2232 { 2233 switch (selector) { 2234 case IEEE_8021QAZ_APP_SEL_ETHERTYPE: 2235 *sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE; 2236 break; 2237 case IEEE_8021QAZ_APP_SEL_STREAM: 2238 *sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT; 2239 break; 2240 case IEEE_8021QAZ_APP_SEL_DGRAM: 2241 *sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT; 2242 break; 2243 case IEEE_8021QAZ_APP_SEL_ANY: 2244 *sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT; 2245 break; 2246 default: 2247 return -EINVAL; 2248 } 2249 2250 return 0; 2251 } 2252 2253 static int qed_dcbnl_ieee_getapp(struct qed_dev *cdev, struct dcb_app *app) 2254 { 2255 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2256 struct qed_dcbx_get *dcbx_info; 2257 struct qed_app_entry *entry; 2258 u8 prio = 0; 2259 u8 sf_ieee; 2260 int i; 2261 2262 DP_VERBOSE(hwfn, QED_MSG_DCB, "selector = %d protocol = %d\n", 2263 app->selector, app->protocol); 2264 2265 if (qed_get_sf_ieee_value(app->selector, &sf_ieee)) { 2266 DP_INFO(cdev, "Invalid selector field value %d\n", 2267 app->selector); 2268 return -EINVAL; 2269 } 2270 2271 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2272 if (!dcbx_info) 2273 return -EINVAL; 2274 2275 if (!dcbx_info->operational.ieee) { 2276 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2277 kfree(dcbx_info); 2278 return -EINVAL; 2279 } 2280 2281 for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 2282 entry = &dcbx_info->operational.params.app_entry[i]; 2283 if ((entry->sf_ieee == sf_ieee) && 2284 (entry->proto_id == app->protocol)) { 2285 prio = entry->prio; 2286 break; 2287 } 2288 } 2289 2290 if (i == QED_DCBX_MAX_APP_PROTOCOL) { 2291 DP_ERR(cdev, "App entry (%d, %d) not found\n", app->selector, 2292 app->protocol); 2293 kfree(dcbx_info); 2294 return -EINVAL; 2295 } 2296 2297 app->priority = ffs(prio) - 1; 2298 2299 kfree(dcbx_info); 2300 2301 return 0; 2302 } 2303 2304 static int qed_dcbnl_ieee_setapp(struct qed_dev *cdev, struct dcb_app *app) 2305 { 2306 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2307 struct qed_dcbx_get *dcbx_info; 2308 struct qed_dcbx_set dcbx_set; 2309 struct qed_app_entry *entry; 2310 struct qed_ptt *ptt; 2311 u8 sf_ieee; 2312 int rc, i; 2313 2314 DP_VERBOSE(hwfn, QED_MSG_DCB, "selector = %d protocol = %d pri = %d\n", 2315 app->selector, app->protocol, app->priority); 2316 if (app->priority >= QED_MAX_PFC_PRIORITIES) { 2317 DP_INFO(hwfn, "Invalid priority %d\n", app->priority); 2318 return -EINVAL; 2319 } 2320 2321 if (qed_get_sf_ieee_value(app->selector, &sf_ieee)) { 2322 DP_INFO(cdev, "Invalid selector field value %d\n", 2323 app->selector); 2324 return -EINVAL; 2325 } 2326 2327 dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2328 if (!dcbx_info) 2329 return -EINVAL; 2330 2331 if (!dcbx_info->operational.ieee) { 2332 DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2333 kfree(dcbx_info); 2334 return -EINVAL; 2335 } 2336 2337 kfree(dcbx_info); 2338 2339 memset(&dcbx_set, 0, sizeof(dcbx_set)); 2340 rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2341 if (rc) 2342 return -EINVAL; 2343 2344 for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 2345 entry = &dcbx_set.config.params.app_entry[i]; 2346 if ((entry->sf_ieee == sf_ieee) && 2347 (entry->proto_id == app->protocol)) 2348 break; 2349 /* First empty slot */ 2350 if (!entry->proto_id) { 2351 dcbx_set.config.params.num_app_entries++; 2352 break; 2353 } 2354 } 2355 2356 if (i == QED_DCBX_MAX_APP_PROTOCOL) { 2357 DP_ERR(cdev, "App table is full\n"); 2358 return -EBUSY; 2359 } 2360 2361 dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 2362 dcbx_set.config.params.app_entry[i].sf_ieee = sf_ieee; 2363 dcbx_set.config.params.app_entry[i].proto_id = app->protocol; 2364 dcbx_set.config.params.app_entry[i].prio = BIT(app->priority); 2365 2366 ptt = qed_ptt_acquire(hwfn); 2367 if (!ptt) 2368 return -EBUSY; 2369 2370 rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2371 2372 qed_ptt_release(hwfn, ptt); 2373 2374 return rc; 2375 } 2376 2377 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass = { 2378 .getstate = qed_dcbnl_getstate, 2379 .setstate = qed_dcbnl_setstate, 2380 .getpgtccfgtx = qed_dcbnl_getpgtccfgtx, 2381 .getpgbwgcfgtx = qed_dcbnl_getpgbwgcfgtx, 2382 .getpgtccfgrx = qed_dcbnl_getpgtccfgrx, 2383 .getpgbwgcfgrx = qed_dcbnl_getpgbwgcfgrx, 2384 .getpfccfg = qed_dcbnl_getpfccfg, 2385 .setpfccfg = qed_dcbnl_setpfccfg, 2386 .getcap = qed_dcbnl_getcap, 2387 .getnumtcs = qed_dcbnl_getnumtcs, 2388 .getpfcstate = qed_dcbnl_getpfcstate, 2389 .getdcbx = qed_dcbnl_getdcbx, 2390 .setpgtccfgtx = qed_dcbnl_setpgtccfgtx, 2391 .setpgtccfgrx = qed_dcbnl_setpgtccfgrx, 2392 .setpgbwgcfgtx = qed_dcbnl_setpgbwgcfgtx, 2393 .setpgbwgcfgrx = qed_dcbnl_setpgbwgcfgrx, 2394 .setall = qed_dcbnl_setall, 2395 .setnumtcs = qed_dcbnl_setnumtcs, 2396 .setpfcstate = qed_dcbnl_setpfcstate, 2397 .setapp = qed_dcbnl_setapp, 2398 .setdcbx = qed_dcbnl_setdcbx, 2399 .setfeatcfg = qed_dcbnl_setfeatcfg, 2400 .getfeatcfg = qed_dcbnl_getfeatcfg, 2401 .getapp = qed_dcbnl_getapp, 2402 .peer_getappinfo = qed_dcbnl_peer_getappinfo, 2403 .peer_getapptable = qed_dcbnl_peer_getapptable, 2404 .cee_peer_getpfc = qed_dcbnl_cee_peer_getpfc, 2405 .cee_peer_getpg = qed_dcbnl_cee_peer_getpg, 2406 .ieee_getpfc = qed_dcbnl_ieee_getpfc, 2407 .ieee_setpfc = qed_dcbnl_ieee_setpfc, 2408 .ieee_getets = qed_dcbnl_ieee_getets, 2409 .ieee_setets = qed_dcbnl_ieee_setets, 2410 .ieee_peer_getpfc = qed_dcbnl_ieee_peer_getpfc, 2411 .ieee_peer_getets = qed_dcbnl_ieee_peer_getets, 2412 .ieee_getapp = qed_dcbnl_ieee_getapp, 2413 .ieee_setapp = qed_dcbnl_ieee_setapp, 2414 }; 2415 2416 #endif 2417