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