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