1 /*
   2 * CDDL HEADER START
   3 *
   4 * The contents of this file are subject to the terms of the
   5 * Common Development and Distribution License, v.1,  (the "License").
   6 * You may not use this file except in compliance with the License.
   7 *
   8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 * or http://opensource.org/licenses/CDDL-1.0.
  10 * See the License for the specific language governing permissions
  11 * and limitations under the License.
  12 *
  13 * When distributing Covered Code, include this CDDL HEADER in each
  14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 * If applicable, add the following below this CDDL HEADER, with the
  16 * fields enclosed by brackets "[]" replaced with your own identifying
  17 * information: Portions Copyright [yyyy] [name of copyright owner]
  18 *
  19 * CDDL HEADER END
  20 */
  21 
  22 /*
  23 * Copyright 2014-2017 Cavium, Inc. 
  24 * The contents of this file are subject to the terms of the Common Development 
  25 * and Distribution License, v.1,  (the "License").
  26 
  27 * You may not use this file except in compliance with the License.
  28 
  29 * You can obtain a copy of the License at available 
  30 * at http://opensource.org/licenses/CDDL-1.0
  31 
  32 * See the License for the specific language governing permissions and 
  33 * limitations under the License.
  34 */
  35 
  36 /*
  37  * Copyright 2018 Joyent, Inc.
  38  */
  39 
  40 #include "bcm_osal.h"
  41 #include "ecore.h"
  42 #include "ecore_sp_commands.h"
  43 #include "ecore_dcbx.h"
  44 #include "ecore_cxt.h"
  45 #include "ecore_gtt_reg_addr.h"
  46 #include "ecore_iro.h"
  47 #ifdef CONFIG_ECORE_ROCE
  48 #include "ecore_roce.h"
  49 #endif
  50 #include "ecore_iov_api.h"
  51 
  52 #define ECORE_DCBX_MAX_MIB_READ_TRY     (100)
  53 #define ECORE_ETH_TYPE_DEFAULT          (0)
  54 #define ECORE_ETH_TYPE_ROCE             (0x8915)
  55 #define ECORE_UDP_PORT_TYPE_ROCE_V2     (0x12B7)
  56 #define ECORE_ETH_TYPE_FCOE             (0x8906)
  57 #define ECORE_TCP_PORT_ISCSI            (0xCBC)
  58 
  59 #define ECORE_DCBX_INVALID_PRIORITY     0xFF
  60 
  61 /* Get Traffic Class from priority traffic class table, 4 bits represent
  62  * the traffic class corresponding to the priority.
  63  */
  64 #define ECORE_DCBX_PRIO2TC(prio_tc_tbl, prio) \
  65                 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
  66 
  67 static bool ecore_dcbx_app_ethtype(u32 app_info_bitmap)
  68 {
  69         return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
  70                   DCBX_APP_SF_ETHTYPE);
  71 }
  72 
  73 static bool ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap)
  74 {
  75         u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
  76 
  77         /* Old MFW */
  78         if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
  79                 return ecore_dcbx_app_ethtype(app_info_bitmap);
  80 
  81         return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE);
  82 }
  83 
  84 static bool ecore_dcbx_app_port(u32 app_info_bitmap)
  85 {
  86         return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
  87                   DCBX_APP_SF_PORT);
  88 }
  89 
  90 static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
  91 {
  92         u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
  93 
  94         /* Old MFW */
  95         if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
  96                 return ecore_dcbx_app_port(app_info_bitmap);
  97 
  98         return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT);
  99 }
 100 
 101 static bool ecore_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 102 {
 103         bool ethtype;
 104 
 105         if (ieee)
 106                 ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
 107         else
 108                 ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
 109 
 110         return !!(ethtype && (proto_id == ECORE_ETH_TYPE_DEFAULT));
 111 }
 112 
 113 static bool ecore_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 114 {
 115         bool port;
 116 
 117         if (ieee)
 118                 port = ecore_dcbx_ieee_app_port(app_info_bitmap,
 119                                                 DCBX_APP_SF_IEEE_TCP_PORT);
 120         else
 121                 port = ecore_dcbx_app_port(app_info_bitmap);
 122 
 123         return !!(port && (proto_id == ECORE_TCP_PORT_ISCSI));
 124 }
 125 
 126 static bool ecore_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 127 {
 128         bool ethtype;
 129 
 130         if (ieee)
 131                 ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
 132         else
 133                 ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
 134 
 135         return !!(ethtype && (proto_id == ECORE_ETH_TYPE_FCOE));
 136 }
 137 
 138 static bool ecore_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 139 {
 140         bool ethtype;
 141 
 142         if (ieee)
 143                 ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
 144         else
 145                 ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
 146 
 147         return !!(ethtype && (proto_id == ECORE_ETH_TYPE_ROCE));
 148 }
 149 
 150 static bool ecore_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
 151 {
 152         bool port;
 153 
 154         if (ieee)
 155                 port = ecore_dcbx_ieee_app_port(app_info_bitmap,
 156                                                 DCBX_APP_SF_IEEE_UDP_PORT);
 157         else
 158                 port = ecore_dcbx_app_port(app_info_bitmap);
 159 
 160         return !!(port && (proto_id == ECORE_UDP_PORT_TYPE_ROCE_V2));
 161 }
 162 
 163 static bool ecore_dcbx_iwarp_tlv(struct ecore_hwfn *p_hwfn, u32 app_info_bitmap,
 164                                  u16 proto_id, bool ieee)
 165 {
 166         bool port;
 167 
 168         if (!p_hwfn->p_dcbx_info->iwarp_port)
 169                 return false;
 170 
 171         if (ieee)
 172                 port = ecore_dcbx_ieee_app_port(app_info_bitmap,
 173                                                 DCBX_APP_SF_IEEE_TCP_PORT);
 174         else
 175                 port = ecore_dcbx_app_port(app_info_bitmap);
 176 
 177         return !!(port && (proto_id == p_hwfn->p_dcbx_info->iwarp_port));
 178 }
 179 
 180 static void
 181 ecore_dcbx_dp_protocol(struct ecore_hwfn *p_hwfn,
 182                        struct ecore_dcbx_results *p_data)
 183 {
 184         enum dcbx_protocol_type id;
 185         int i;
 186 
 187         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "DCBX negotiated: %d\n",
 188                    p_data->dcbx_enabled);
 189 
 190         for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
 191                 id = ecore_dcbx_app_update[i].id;
 192 
 193                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 194                            "%s info: update %d, enable %d, prio %d, tc %d, num_active_tc %d dscp_enable = %d dscp_val = %d\n",
 195                            ecore_dcbx_app_update[i].name, p_data->arr[id].update,
 196                            p_data->arr[id].enable, p_data->arr[id].priority,
 197                            p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc,
 198                            p_data->arr[id].dscp_enable,
 199                            p_data->arr[id].dscp_val);
 200         }
 201 }
 202 
 203 static void
 204 ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
 205                       struct ecore_hwfn *p_hwfn,
 206                       bool enable, u8 prio, u8 tc,
 207                       enum dcbx_protocol_type type,
 208                       enum ecore_pci_personality personality)
 209 {
 210         struct ecore_dcbx_dscp_params *dscp = &p_hwfn->p_dcbx_info->get.dscp;
 211 
 212         /* PF update ramrod data */
 213         p_data->arr[type].enable = enable;
 214         p_data->arr[type].priority = prio;
 215         p_data->arr[type].tc = tc;
 216         p_data->arr[type].dscp_enable = dscp->enabled;
 217         if (p_data->arr[type].dscp_enable) {
 218                 u8 i;
 219 
 220                 for (i = 0; i < ECORE_DCBX_DSCP_SIZE; i++)
 221                         if (prio == dscp->dscp_pri_map[i]) {
 222                                 p_data->arr[type].dscp_val = i;
 223                                 break;
 224                         }
 225         }
 226 
 227         if (enable && p_data->arr[type].dscp_enable)
 228                 p_data->arr[type].update = UPDATE_DCB_DSCP;
 229         else if (enable)
 230                 p_data->arr[type].update = UPDATE_DCB;
 231         else
 232                 p_data->arr[type].update = DONT_UPDATE_DCB_DSCP;
 233 
 234         /* QM reconf data */
 235         if (p_hwfn->hw_info.personality == personality)
 236                 p_hwfn->hw_info.offload_tc = tc;
 237 }
 238 
 239 /* Update app protocol data and hw_info fields with the TLV info */
 240 static void
 241 ecore_dcbx_update_app_info(struct ecore_dcbx_results *p_data,
 242                            struct ecore_hwfn *p_hwfn,
 243                            bool enable, u8 prio, u8 tc,
 244                            enum dcbx_protocol_type type)
 245 {
 246         enum ecore_pci_personality personality;
 247         enum dcbx_protocol_type id;
 248         int i;
 249 
 250         for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
 251                 id = ecore_dcbx_app_update[i].id;
 252 
 253                 if (type != id)
 254                         continue;
 255 
 256                 personality = ecore_dcbx_app_update[i].personality;
 257 
 258                 ecore_dcbx_set_params(p_data, p_hwfn, enable,
 259                                       prio, tc, type, personality);
 260         }
 261 }
 262 
 263 static enum _ecore_status_t
 264 ecore_dcbx_get_app_priority(u8 pri_bitmap, u8 *priority)
 265 {
 266         u32 pri_mask, pri = ECORE_MAX_PFC_PRIORITIES;
 267         u32 index = ECORE_MAX_PFC_PRIORITIES - 1;
 268         enum _ecore_status_t rc = ECORE_SUCCESS;
 269 
 270         /* Bitmap 1 corresponds to priority 0, return priority 0 */
 271         if (pri_bitmap == 1) {
 272                 *priority = 0;
 273                 return rc;
 274         }
 275 
 276         /* Choose the highest priority */
 277         while ((ECORE_MAX_PFC_PRIORITIES == pri) && index) {
 278                 pri_mask = 1 << index;
 279                 if (pri_bitmap & pri_mask)
 280                         pri = index;
 281                 index--;
 282         }
 283 
 284         if (pri < ECORE_MAX_PFC_PRIORITIES)
 285                 *priority = (u8)pri;
 286         else
 287                 rc = ECORE_INVAL;
 288 
 289         return rc;
 290 }
 291 
 292 static bool
 293 ecore_dcbx_get_app_protocol_type(struct ecore_hwfn *p_hwfn,
 294                                  u32 app_prio_bitmap, u16 id,
 295                                  enum dcbx_protocol_type *type, bool ieee)
 296 {
 297         if (ecore_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) {
 298                 *type = DCBX_PROTOCOL_FCOE;
 299         } else if (ecore_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) {
 300                 *type = DCBX_PROTOCOL_ROCE;
 301         } else if (ecore_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) {
 302                 *type = DCBX_PROTOCOL_ISCSI;
 303         } else if (ecore_dcbx_default_tlv(app_prio_bitmap, id, ieee)) {
 304                 *type = DCBX_PROTOCOL_ETH;
 305         } else if (ecore_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) {
 306                 *type = DCBX_PROTOCOL_ROCE_V2;
 307         } else if (ecore_dcbx_iwarp_tlv(p_hwfn, app_prio_bitmap, id, ieee)) {
 308                 *type = DCBX_PROTOCOL_IWARP;
 309         } else {
 310                 *type = DCBX_MAX_PROTOCOL_TYPE;
 311                 DP_ERR(p_hwfn,
 312                        "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
 313                        id, app_prio_bitmap);
 314                 return false;
 315         }
 316 
 317         return true;
 318 }
 319 
 320 /*  Parse app TLV's to update TC information in hw_info structure for
 321  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
 322  */
 323 static enum _ecore_status_t
 324 ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn,
 325                        struct ecore_dcbx_results *p_data,
 326                        struct dcbx_app_priority_entry *p_tbl, u32 pri_tc_tbl,
 327                        int count, u8 dcbx_version)
 328 {
 329         enum dcbx_protocol_type type;
 330         u8 tc, priority_map;
 331         bool enable, ieee;
 332         u16 protocol_id;
 333         u8 priority;
 334         enum _ecore_status_t rc = ECORE_SUCCESS;
 335         int i;
 336 
 337         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 338                    "Num APP entries = %d pri_tc_tbl = 0x%x dcbx_version = %u\n",
 339                    count, pri_tc_tbl, dcbx_version);
 340 
 341         ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE);
 342         /* Parse APP TLV */
 343         for (i = 0; i < count; i++) {
 344                 protocol_id = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 345                                                   DCBX_APP_PROTOCOL_ID);
 346                 priority_map = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 347                                                    DCBX_APP_PRI_MAP);
 348                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Id = 0x%x pri_map = %u\n",
 349                            protocol_id, priority_map);
 350                 rc = ecore_dcbx_get_app_priority(priority_map, &priority);
 351                 if (rc == ECORE_INVAL) {
 352                         DP_ERR(p_hwfn, "Invalid priority\n");
 353                         return ECORE_INVAL;
 354                 }
 355 
 356                 tc = ECORE_DCBX_PRIO2TC(pri_tc_tbl, priority);
 357                 if (ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
 358                                                      protocol_id, &type,
 359                                                      ieee)) {
 360                         /* ETH always have the enable bit reset, as it gets
 361                          * vlan information per packet. For other protocols,
 362                          * should be set according to the dcbx_enabled
 363                          * indication, but we only got here if there was an
 364                          * app tlv for the protocol, so dcbx must be enabled.
 365                          */
 366                         enable = !(type == DCBX_PROTOCOL_ETH);
 367 
 368                         ecore_dcbx_update_app_info(p_data, p_hwfn, enable,
 369                                                    priority, tc, type);
 370                 }
 371         }
 372 
 373         /* Update ramrod protocol data and hw_info fields
 374          * with default info when corresponding APP TLV's are not detected.
 375          * The enabled field has a different logic for ethernet as only for
 376          * ethernet dcb should disabled by default, as the information arrives
 377          * from the OS (unless an explicit app tlv was present).
 378          */
 379         tc = p_data->arr[DCBX_PROTOCOL_ETH].tc;
 380         priority = p_data->arr[DCBX_PROTOCOL_ETH].priority;
 381         for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) {
 382                 if (p_data->arr[type].update)
 383                         continue;
 384 
 385                 enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
 386                 ecore_dcbx_update_app_info(p_data, p_hwfn, enable,
 387                                            priority, tc, type);
 388         }
 389 
 390         return ECORE_SUCCESS;
 391 }
 392 
 393 /* Parse app TLV's to update TC information in hw_info structure for
 394  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
 395  */
 396 static enum _ecore_status_t
 397 ecore_dcbx_process_mib_info(struct ecore_hwfn *p_hwfn)
 398 {
 399         struct dcbx_app_priority_feature *p_app;
 400         enum _ecore_status_t rc = ECORE_SUCCESS;
 401         struct ecore_dcbx_results data = { 0 };
 402         struct dcbx_app_priority_entry *p_tbl;
 403         struct dcbx_ets_feature *p_ets;
 404         struct ecore_hw_info *p_info;
 405         u32 pri_tc_tbl, flags;
 406         u8 dcbx_version;
 407         int num_entries;
 408 
 409         flags = p_hwfn->p_dcbx_info->operational.flags;
 410         dcbx_version = ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION);
 411 
 412         p_app = &p_hwfn->p_dcbx_info->operational.features.app;
 413         p_tbl = p_app->app_pri_tbl;
 414 
 415         p_ets = &p_hwfn->p_dcbx_info->operational.features.ets;
 416         pri_tc_tbl = p_ets->pri_tc_tbl[0];
 417 
 418         p_info = &p_hwfn->hw_info;
 419         num_entries = ECORE_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
 420 
 421         rc = ecore_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl,
 422                                     num_entries, dcbx_version);
 423         if (rc != ECORE_SUCCESS)
 424                 return rc;
 425 
 426         p_info->num_active_tc = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
 427         p_hwfn->qm_info.ooo_tc = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_OOO_TC);
 428         data.pf_id = p_hwfn->rel_pf_id;
 429         data.dcbx_enabled = !!dcbx_version;
 430 
 431         ecore_dcbx_dp_protocol(p_hwfn, &data);
 432 
 433         OSAL_MEMCPY(&p_hwfn->p_dcbx_info->results, &data,
 434                     sizeof(struct ecore_dcbx_results));
 435 
 436         return ECORE_SUCCESS;
 437 }
 438 
 439 static enum _ecore_status_t
 440 ecore_dcbx_copy_mib(struct ecore_hwfn *p_hwfn,
 441                     struct ecore_ptt *p_ptt,
 442                     struct ecore_dcbx_mib_meta_data *p_data,
 443                     enum ecore_mib_read_type type)
 444 {
 445         enum _ecore_status_t rc = ECORE_SUCCESS;
 446         u32 prefix_seq_num, suffix_seq_num;
 447         int read_count = 0;
 448 
 449         /* The data is considered to be valid only if both sequence numbers are
 450          * the same.
 451          */
 452         do {
 453                 if (type == ECORE_DCBX_REMOTE_LLDP_MIB) {
 454                         ecore_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote,
 455                                           p_data->addr, p_data->size);
 456                         prefix_seq_num = p_data->lldp_remote->prefix_seq_num;
 457                         suffix_seq_num = p_data->lldp_remote->suffix_seq_num;
 458                 } else {
 459                         ecore_memcpy_from(p_hwfn, p_ptt, p_data->mib,
 460                                           p_data->addr, p_data->size);
 461                         prefix_seq_num = p_data->mib->prefix_seq_num;
 462                         suffix_seq_num = p_data->mib->suffix_seq_num;
 463                 }
 464                 read_count++;
 465 
 466                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 467                            "mib type = %d, try count = %d prefix seq num  = %d suffix seq num = %d\n",
 468                            type, read_count, prefix_seq_num, suffix_seq_num);
 469         } while ((prefix_seq_num != suffix_seq_num) &&
 470                  (read_count < ECORE_DCBX_MAX_MIB_READ_TRY));
 471 
 472         if (read_count >= ECORE_DCBX_MAX_MIB_READ_TRY) {
 473                 DP_ERR(p_hwfn,
 474                        "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
 475                        type, read_count, prefix_seq_num, suffix_seq_num);
 476                 rc = ECORE_IO;
 477         }
 478 
 479         return rc;
 480 }
 481 
 482 static void
 483 ecore_dcbx_get_priority_info(struct ecore_hwfn *p_hwfn,
 484                              struct ecore_dcbx_app_prio *p_prio,
 485                              struct ecore_dcbx_results *p_results)
 486 {
 487         u8 val;
 488 
 489         p_prio->roce = ECORE_DCBX_INVALID_PRIORITY;
 490         p_prio->roce_v2 = ECORE_DCBX_INVALID_PRIORITY;
 491         p_prio->iscsi = ECORE_DCBX_INVALID_PRIORITY;
 492         p_prio->fcoe = ECORE_DCBX_INVALID_PRIORITY;
 493 
 494         if (p_results->arr[DCBX_PROTOCOL_ROCE].update &&
 495             p_results->arr[DCBX_PROTOCOL_ROCE].enable)
 496                 p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority;
 497 
 498         if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update &&
 499             p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) {
 500                 val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority;
 501                 p_prio->roce_v2 = val;
 502         }
 503 
 504         if (p_results->arr[DCBX_PROTOCOL_ISCSI].update &&
 505             p_results->arr[DCBX_PROTOCOL_ISCSI].enable)
 506                 p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority;
 507 
 508         if (p_results->arr[DCBX_PROTOCOL_FCOE].update &&
 509             p_results->arr[DCBX_PROTOCOL_FCOE].enable)
 510                 p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority;
 511 
 512         if (p_results->arr[DCBX_PROTOCOL_ETH].update &&
 513             p_results->arr[DCBX_PROTOCOL_ETH].enable)
 514                 p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority;
 515 
 516         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 517                    "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
 518                    p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe,
 519                    p_prio->eth);
 520 }
 521 
 522 static void
 523 ecore_dcbx_get_app_data(struct ecore_hwfn *p_hwfn,
 524                         struct dcbx_app_priority_feature *p_app,
 525                         struct dcbx_app_priority_entry *p_tbl,
 526                         struct ecore_dcbx_params *p_params, bool ieee)
 527 {
 528         struct ecore_app_entry *entry;
 529         u8 pri_map;
 530         int i;
 531 
 532         p_params->app_willing = ECORE_MFW_GET_FIELD(p_app->flags,
 533                                                     DCBX_APP_WILLING);
 534         p_params->app_valid = ECORE_MFW_GET_FIELD(p_app->flags,
 535                                                   DCBX_APP_ENABLED);
 536         p_params->app_error = ECORE_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR);
 537         p_params->num_app_entries = ECORE_MFW_GET_FIELD(p_app->flags,
 538                                                         DCBX_APP_NUM_ENTRIES);
 539         for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
 540                 entry = &p_params->app_entry[i];
 541                 if (ieee) {
 542                         u8 sf_ieee;
 543                         u32 val;
 544 
 545                         sf_ieee = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 546                                                       DCBX_APP_SF_IEEE);
 547                         switch (sf_ieee) {
 548                         case DCBX_APP_SF_IEEE_RESERVED:
 549                                 /* Old MFW */
 550                                 val = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 551                                                             DCBX_APP_SF);
 552                                 entry->sf_ieee = val ?
 553                                         ECORE_DCBX_SF_IEEE_TCP_UDP_PORT :
 554                                         ECORE_DCBX_SF_IEEE_ETHTYPE;
 555                                 break;
 556                         case DCBX_APP_SF_IEEE_ETHTYPE:
 557                                 entry->sf_ieee = ECORE_DCBX_SF_IEEE_ETHTYPE;
 558                                 break;
 559                         case DCBX_APP_SF_IEEE_TCP_PORT:
 560                                 entry->sf_ieee = ECORE_DCBX_SF_IEEE_TCP_PORT;
 561                                 break;
 562                         case DCBX_APP_SF_IEEE_UDP_PORT:
 563                                 entry->sf_ieee = ECORE_DCBX_SF_IEEE_UDP_PORT;
 564                                 break;
 565                         case DCBX_APP_SF_IEEE_TCP_UDP_PORT:
 566                                 entry->sf_ieee = ECORE_DCBX_SF_IEEE_TCP_UDP_PORT;
 567                                 break;
 568                         }
 569                 } else {
 570                         entry->ethtype = !(ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 571                                                                DCBX_APP_SF));
 572                 }
 573 
 574                 pri_map = ECORE_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP);
 575                 ecore_dcbx_get_app_priority(pri_map, &entry->prio);
 576                 entry->proto_id = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
 577                                                       DCBX_APP_PROTOCOL_ID);
 578                 ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
 579                                                  entry->proto_id,
 580                                                  &entry->proto_type, ieee);
 581         }
 582 
 583         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 584                    "APP params: willing %d, valid %d error = %d\n",
 585                    p_params->app_willing, p_params->app_valid,
 586                    p_params->app_error);
 587 }
 588 
 589 static void
 590 ecore_dcbx_get_pfc_data(struct ecore_hwfn *p_hwfn,
 591                         u32 pfc, struct ecore_dcbx_params *p_params)
 592 {
 593         u8 pfc_map;
 594 
 595         p_params->pfc.willing = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING);
 596         p_params->pfc.max_tc = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS);
 597         p_params->pfc.enabled = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED);
 598         pfc_map = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP);
 599         p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0);
 600         p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1);
 601         p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2);
 602         p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3);
 603         p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4);
 604         p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5);
 605         p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6);
 606         p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7);
 607 
 608         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 609                    "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n",
 610                    p_params->pfc.willing, pfc_map, p_params->pfc.max_tc,
 611                    p_params->pfc.enabled);
 612 }
 613 
 614 static void
 615 ecore_dcbx_get_ets_data(struct ecore_hwfn *p_hwfn,
 616                         struct dcbx_ets_feature *p_ets,
 617                         struct ecore_dcbx_params *p_params)
 618 {
 619         u32 bw_map[2], tsa_map[2], pri_map;
 620         int i;
 621 
 622         p_params->ets_willing = ECORE_MFW_GET_FIELD(p_ets->flags,
 623                                                     DCBX_ETS_WILLING);
 624         p_params->ets_enabled = ECORE_MFW_GET_FIELD(p_ets->flags,
 625                                                     DCBX_ETS_ENABLED);
 626         p_params->ets_cbs = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS);
 627         p_params->max_ets_tc = ECORE_MFW_GET_FIELD(p_ets->flags,
 628                                                    DCBX_ETS_MAX_TCS);
 629         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 630                    "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
 631                    p_params->ets_willing, p_params->ets_enabled,
 632                    p_params->ets_cbs, p_ets->pri_tc_tbl[0],
 633                    p_params->max_ets_tc);
 634         if (p_params->ets_enabled && !p_params->max_ets_tc)
 635         {
 636                 p_params->max_ets_tc = ECORE_MAX_PFC_PRIORITIES;
 637                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 638                            "ETS params: max_ets_tc is forced to %d\n",
 639                    p_params->max_ets_tc);
 640         }
 641         /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
 642          * encoded in a type u32 array of size 2.
 643          */
 644         bw_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[0]);
 645         bw_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[1]);
 646         tsa_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[0]);
 647         tsa_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[1]);
 648         pri_map = p_ets->pri_tc_tbl[0];
 649         for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
 650                 p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
 651                 p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
 652                 p_params->ets_pri_tc_tbl[i] = ECORE_DCBX_PRIO2TC(pri_map, i);
 653                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 654                            "elem %d  bw_tbl %x tsa_tbl %x\n",
 655                            i, p_params->ets_tc_bw_tbl[i],
 656                            p_params->ets_tc_tsa_tbl[i]);
 657         }
 658 }
 659 
 660 static void
 661 ecore_dcbx_get_common_params(struct ecore_hwfn *p_hwfn,
 662                              struct dcbx_app_priority_feature *p_app,
 663                              struct dcbx_app_priority_entry *p_tbl,
 664                              struct dcbx_ets_feature *p_ets,
 665                              u32 pfc, struct ecore_dcbx_params *p_params,
 666                              bool ieee)
 667 {
 668         ecore_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee);
 669         ecore_dcbx_get_ets_data(p_hwfn, p_ets, p_params);
 670         ecore_dcbx_get_pfc_data(p_hwfn, pfc, p_params);
 671 }
 672 
 673 static void
 674 ecore_dcbx_get_local_params(struct ecore_hwfn *p_hwfn,
 675                             struct ecore_ptt *p_ptt,
 676                             struct ecore_dcbx_get *params)
 677 {
 678         struct dcbx_features *p_feat;
 679 
 680         p_feat = &p_hwfn->p_dcbx_info->local_admin.features;
 681         ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
 682                                      p_feat->app.app_pri_tbl, &p_feat->ets,
 683                                      p_feat->pfc, &params->local.params, false);
 684         params->local.valid = true;
 685 }
 686 
 687 static void
 688 ecore_dcbx_get_remote_params(struct ecore_hwfn *p_hwfn,
 689                              struct ecore_ptt *p_ptt,
 690                              struct ecore_dcbx_get *params)
 691 {
 692         struct dcbx_features *p_feat;
 693 
 694         p_feat = &p_hwfn->p_dcbx_info->remote.features;
 695         ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
 696                                      p_feat->app.app_pri_tbl, &p_feat->ets,
 697                                      p_feat->pfc, &params->remote.params,
 698                                      false);
 699         params->remote.valid = true;
 700 }
 701 
 702 static enum _ecore_status_t
 703 ecore_dcbx_get_operational_params(struct ecore_hwfn *p_hwfn,
 704                                   struct ecore_ptt *p_ptt,
 705                                   struct ecore_dcbx_get *params)
 706 {
 707         struct ecore_dcbx_operational_params *p_operational;
 708         struct ecore_dcbx_results *p_results;
 709         struct dcbx_features *p_feat;
 710         bool enabled, err;
 711         u32 flags;
 712         bool val;
 713 
 714         flags = p_hwfn->p_dcbx_info->operational.flags;
 715 
 716         /* If DCBx version is non zero, then negotiation
 717          * was successfuly performed
 718          */
 719         p_operational = &params->operational;
 720         enabled = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) !=
 721                      DCBX_CONFIG_VERSION_DISABLED);
 722         if (!enabled) {
 723                 p_operational->enabled = enabled;
 724                 p_operational->valid = false;
 725                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Dcbx is disabled\n");
 726                 return ECORE_INVAL;
 727         }
 728 
 729         p_feat = &p_hwfn->p_dcbx_info->operational.features;
 730         p_results = &p_hwfn->p_dcbx_info->results;
 731 
 732         val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
 733                  DCBX_CONFIG_VERSION_IEEE);
 734         p_operational->ieee = val;
 735 
 736         val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
 737                  DCBX_CONFIG_VERSION_CEE);
 738         p_operational->cee = val;
 739 
 740         val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
 741                  DCBX_CONFIG_VERSION_STATIC);
 742         p_operational->local = val;
 743 
 744         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
 745                    "Version support: ieee %d, cee %d, static %d\n",
 746                    p_operational->ieee, p_operational->cee,
 747                    p_operational->local);
 748 
 749         ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
 750                                      p_feat->app.app_pri_tbl, &p_feat->ets,
 751                                      p_feat->pfc, &params->operational.params,
 752                                      p_operational->ieee);
 753         ecore_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio,
 754                                      p_results);
 755         err = ECORE_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR);
 756         p_operational->err = err;
 757         p_operational->enabled = enabled;
 758         p_operational->valid = true;
 759 
 760         return ECORE_SUCCESS;
 761 }
 762 
 763 static void
 764 ecore_dcbx_get_dscp_params(struct ecore_hwfn *p_hwfn,
 765                            struct ecore_ptt *p_ptt,
 766                            struct ecore_dcbx_get *params)
 767 {
 768         struct ecore_dcbx_dscp_params *p_dscp;
 769         struct dcb_dscp_map *p_dscp_map;
 770         int i, j, entry;
 771         u32 pri_map;
 772 
 773         p_dscp = &params->dscp;
 774         p_dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
 775         p_dscp->enabled = ECORE_MFW_GET_FIELD(p_dscp_map->flags,
 776                                               DCB_DSCP_ENABLE);
 777         /* MFW encodes 64 dscp entries into 8 element array of u32 entries,
 778          * where each entry holds the 4bit priority map for 8 dscp entries.
 779          */
 780         for (i = 0, entry = 0; i < ECORE_DCBX_DSCP_SIZE / 8; i++) {
 781                 pri_map = OSAL_BE32_TO_CPU(p_dscp_map->dscp_pri_map[i]);
 782                 DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "elem %d pri_map 0x%x\n",
 783                            entry, pri_map);
 784                 for (j = 0; j < ECORE_DCBX_DSCP_SIZE / 8; j++, entry++)
 785                         p_dscp->dscp_pri_map[entry] = (u32)(pri_map >>
 786                                                            (j * 4)) & 0xf;
 787         }
 788 }
 789 
 790 static void
 791 ecore_dcbx_get_local_lldp_params(struct ecore_hwfn *p_hwfn,
 792                                  struct ecore_ptt *p_ptt,
 793                                  struct ecore_dcbx_get *params)
 794 {
 795         struct lldp_config_params_s *p_local;
 796 
 797         p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
 798 
 799         OSAL_MEMCPY(params->lldp_local.local_chassis_id,
 800                     p_local->local_chassis_id,
 801                     OSAL_ARRAY_SIZE(p_local->local_chassis_id));
 802         OSAL_MEMCPY(params->lldp_local.local_port_id, p_local->local_port_id,
 803                     OSAL_ARRAY_SIZE(p_local->local_port_id));
 804 }
 805 
 806 static void
 807 ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn *p_hwfn,
 808                                   struct ecore_ptt *p_ptt,
 809                                   struct ecore_dcbx_get *params)
 810 {
 811         struct lldp_status_params_s *p_remote;
 812 
 813         p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
 814 
 815         OSAL_MEMCPY(params->lldp_remote.peer_chassis_id,
 816                     p_remote->peer_chassis_id,
 817                     OSAL_ARRAY_SIZE(p_remote->peer_chassis_id));
 818         OSAL_MEMCPY(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
 819                     OSAL_ARRAY_SIZE(p_remote->peer_port_id));
 820 }
 821 
 822 static enum _ecore_status_t
 823 ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 824                       struct ecore_dcbx_get *p_params,
 825                       enum ecore_mib_read_type type)
 826 {
 827         enum _ecore_status_t rc = ECORE_SUCCESS;
 828 
 829         switch (type) {
 830         case ECORE_DCBX_REMOTE_MIB:
 831                 ecore_dcbx_get_remote_params(p_hwfn, p_ptt, p_params);
 832                 break;
 833         case ECORE_DCBX_LOCAL_MIB:
 834                 ecore_dcbx_get_local_params(p_hwfn, p_ptt, p_params);
 835                 break;
 836         case ECORE_DCBX_OPERATIONAL_MIB:
 837                 ecore_dcbx_get_operational_params(p_hwfn, p_ptt, p_params);
 838                 break;
 839         case ECORE_DCBX_REMOTE_LLDP_MIB:
 840                 ecore_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params);
 841                 break;
 842         case ECORE_DCBX_LOCAL_LLDP_MIB:
 843                 ecore_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params);
 844                 break;
 845         default:
 846                 DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
 847                 return ECORE_INVAL;
 848         }
 849 
 850         return rc;
 851 }
 852 
 853 static enum _ecore_status_t
 854 ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn *p_hwfn,
 855                                struct ecore_ptt *p_ptt)
 856 {
 857         struct ecore_dcbx_mib_meta_data data;
 858         enum _ecore_status_t rc = ECORE_SUCCESS;
 859 
 860         OSAL_MEM_ZERO(&data, sizeof(data));
 861         data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
 862                                                            lldp_config_params);
 863         data.lldp_local = p_hwfn->p_dcbx_info->lldp_local;
 864         data.size = sizeof(struct lldp_config_params_s);
 865         ecore_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size);
 866 
 867         return rc;
 868 }
 869 
 870 static enum _ecore_status_t
 871 ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn *p_hwfn,
 872                                 struct ecore_ptt *p_ptt,
 873                                 enum ecore_mib_read_type type)
 874 {
 875         struct ecore_dcbx_mib_meta_data data;
 876         enum _ecore_status_t rc = ECORE_SUCCESS;
 877 
 878         OSAL_MEM_ZERO(&data, sizeof(data));
 879         data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
 880                                                            lldp_status_params);
 881         data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote;
 882         data.size = sizeof(struct lldp_status_params_s);
 883         rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
 884 
 885         return rc;
 886 }
 887 
 888 static enum _ecore_status_t
 889 ecore_dcbx_read_operational_mib(struct ecore_hwfn *p_hwfn,
 890                                 struct ecore_ptt *p_ptt,
 891                                 enum ecore_mib_read_type type)
 892 {
 893         struct ecore_dcbx_mib_meta_data data;
 894         enum _ecore_status_t rc = ECORE_SUCCESS;
 895 
 896         OSAL_MEM_ZERO(&data, sizeof(data));
 897         data.addr = p_hwfn->mcp_info->port_addr +
 898                     offsetof(struct public_port, operational_dcbx_mib);
 899         data.mib = &p_hwfn->p_dcbx_info->operational;
 900         data.size = sizeof(struct dcbx_mib);
 901         rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
 902 
 903         return rc;
 904 }
 905 
 906 static enum _ecore_status_t
 907 ecore_dcbx_read_remote_mib(struct ecore_hwfn *p_hwfn,
 908                            struct ecore_ptt *p_ptt,
 909                            enum ecore_mib_read_type type)
 910 {
 911         struct ecore_dcbx_mib_meta_data data;
 912         enum _ecore_status_t rc = ECORE_SUCCESS;
 913 
 914         OSAL_MEM_ZERO(&data, sizeof(data));
 915         data.addr = p_hwfn->mcp_info->port_addr +
 916                     offsetof(struct public_port, remote_dcbx_mib);
 917         data.mib = &p_hwfn->p_dcbx_info->remote;
 918         data.size = sizeof(struct dcbx_mib);
 919         rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
 920 
 921         return rc;
 922 }
 923 
 924 static enum _ecore_status_t
 925 ecore_dcbx_read_local_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
 926 {
 927         struct ecore_dcbx_mib_meta_data data;
 928         enum _ecore_status_t rc = ECORE_SUCCESS;
 929 
 930         OSAL_MEM_ZERO(&data, sizeof(data));
 931         data.addr = p_hwfn->mcp_info->port_addr +
 932                         offsetof(struct public_port, local_admin_dcbx_mib);
 933         data.local_admin = &p_hwfn->p_dcbx_info->local_admin;
 934         data.size = sizeof(struct dcbx_local_params);
 935         ecore_memcpy_from(p_hwfn, p_ptt, data.local_admin,
 936                           data.addr, data.size);
 937 
 938         return rc;
 939 }
 940 
 941 static void
 942 ecore_dcbx_read_dscp_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
 943 {
 944         struct ecore_dcbx_mib_meta_data data;
 945 
 946         data.addr = p_hwfn->mcp_info->port_addr +
 947                         offsetof(struct public_port, dcb_dscp_map);
 948         data.dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
 949         data.size = sizeof(struct dcb_dscp_map);
 950         ecore_memcpy_from(p_hwfn, p_ptt, data.dscp_map, data.addr, data.size);
 951 }
 952 
 953 static enum _ecore_status_t ecore_dcbx_read_mib(struct ecore_hwfn *p_hwfn,
 954                                                 struct ecore_ptt *p_ptt,
 955                                                 enum ecore_mib_read_type type)
 956 {
 957         enum _ecore_status_t rc = ECORE_INVAL;
 958 
 959         switch (type) {
 960         case ECORE_DCBX_OPERATIONAL_MIB:
 961                 ecore_dcbx_read_dscp_mib(p_hwfn, p_ptt);
 962                 rc = ecore_dcbx_read_operational_mib(p_hwfn, p_ptt, type);
 963                 break;
 964         case ECORE_DCBX_REMOTE_MIB:
 965                 rc = ecore_dcbx_read_remote_mib(p_hwfn, p_ptt, type);
 966                 break;
 967         case ECORE_DCBX_LOCAL_MIB:
 968                 rc = ecore_dcbx_read_local_mib(p_hwfn, p_ptt);
 969                 break;
 970         case ECORE_DCBX_REMOTE_LLDP_MIB:
 971                 rc = ecore_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type);
 972                 break;
 973         case ECORE_DCBX_LOCAL_LLDP_MIB:
 974                 rc = ecore_dcbx_read_local_lldp_mib(p_hwfn, p_ptt);
 975                 break;
 976         default:
 977                 DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
 978         }
 979 
 980         return rc;
 981 }
 982 
 983 /*
 984  * Read updated MIB.
 985  * Reconfigure QM and invoke PF update ramrod command if operational MIB
 986  * change is detected.
 987  */
 988 enum _ecore_status_t
 989 ecore_dcbx_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 990                             enum ecore_mib_read_type type)
 991 {
 992         enum _ecore_status_t rc = ECORE_SUCCESS;
 993 
 994         rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
 995         if (rc)
 996                 return rc;
 997 
 998         if (type == ECORE_DCBX_OPERATIONAL_MIB) {
 999                 ecore_dcbx_get_dscp_params(p_hwfn, p_ptt,
1000                                            &p_hwfn->p_dcbx_info->get);
1001 
1002                 rc = ecore_dcbx_process_mib_info(p_hwfn);
1003                 if (!rc) {
1004                         bool enabled __unused;
1005 
1006                         /* reconfigure tcs of QM queues according
1007                          * to negotiation results
1008                          */
1009                         ecore_qm_reconf(p_hwfn, p_ptt);
1010 
1011                         /* update storm FW with negotiation results */
1012                         ecore_sp_pf_update_dcbx(p_hwfn);
1013 
1014                         /* set eagle enigne 1 flow control workaround
1015                          * according to negotiation results
1016                          */
1017                         enabled = p_hwfn->p_dcbx_info->results.dcbx_enabled;
1018 
1019 #ifdef CONFIG_ECORE_ROCE
1020                         /* for roce PFs, we may want to enable/disable DPM
1021                          * when DCBx change occurs
1022                          */
1023                         if (ECORE_IS_ROCE_PERSONALITY(p_hwfn))
1024                                 ecore_roce_dpm_dcbx(p_hwfn, p_ptt);
1025 #endif
1026                 }
1027         }
1028 
1029         ecore_dcbx_get_params(p_hwfn, p_ptt, &p_hwfn->p_dcbx_info->get, type);
1030 
1031         if (type == ECORE_DCBX_OPERATIONAL_MIB) {
1032                 struct ecore_dcbx_results *p_data;
1033                 u16 val;
1034 
1035                 /* Update the DSCP to TC mapping bit if required */
1036                 if (p_hwfn->p_dcbx_info->dscp_nig_update) {
1037                         ecore_wr(p_hwfn, p_ptt, NIG_REG_DSCP_TO_TC_MAP_ENABLE,
1038                                  0x1);
1039                         p_hwfn->p_dcbx_info->dscp_nig_update = false;
1040                 }
1041 
1042                 /* Configure in NIG which protocols support EDPM and should
1043                  * honor PFC.
1044                  */
1045                 p_data = &p_hwfn->p_dcbx_info->results;
1046                 val = (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE].tc) |
1047                         (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE_V2].tc);
1048                 val <<= NIG_REG_TX_EDPM_CTRL_TX_EDPM_TC_EN_SHIFT;
1049                 val |= NIG_REG_TX_EDPM_CTRL_TX_EDPM_EN;
1050                 ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_EDPM_CTRL, val);
1051         }
1052 
1053         OSAL_DCBX_AEN(p_hwfn, type);
1054 
1055         return rc;
1056 }
1057 
1058 enum _ecore_status_t ecore_dcbx_info_alloc(struct ecore_hwfn *p_hwfn)
1059 {
1060 #ifndef __EXTRACT__LINUX__
1061         OSAL_BUILD_BUG_ON(ECORE_LLDP_CHASSIS_ID_STAT_LEN !=
1062                           LLDP_CHASSIS_ID_STAT_LEN);
1063         OSAL_BUILD_BUG_ON(ECORE_LLDP_PORT_ID_STAT_LEN !=
1064                           LLDP_PORT_ID_STAT_LEN);
1065         OSAL_BUILD_BUG_ON(ECORE_DCBX_MAX_APP_PROTOCOL !=
1066                           DCBX_MAX_APP_PROTOCOL);
1067 #endif
1068 
1069         p_hwfn->p_dcbx_info = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
1070                                           sizeof(*p_hwfn->p_dcbx_info));
1071         if (!p_hwfn->p_dcbx_info) {
1072                 DP_NOTICE(p_hwfn, true,
1073                           "Failed to allocate `struct ecore_dcbx_info'");
1074                 return ECORE_NOMEM;
1075         }
1076 
1077         p_hwfn->p_dcbx_info->iwarp_port =
1078                 p_hwfn->pf_params.rdma_pf_params.iwarp_port;
1079 
1080         return ECORE_SUCCESS;
1081 }
1082 
1083 void ecore_dcbx_info_free(struct ecore_hwfn *p_hwfn)
1084 {
1085         OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_dcbx_info);
1086         p_hwfn->p_dcbx_info = OSAL_NULL;
1087 }
1088 
1089 static void ecore_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
1090                                             struct ecore_dcbx_results *p_src,
1091                                             enum dcbx_protocol_type type)
1092 {
1093         p_data->dcb_enable_flag = p_src->arr[type].enable;
1094         p_data->dcb_priority = p_src->arr[type].priority;
1095         p_data->dcb_tc = p_src->arr[type].tc;
1096         p_data->dscp_enable_flag = p_src->arr[type].dscp_enable;
1097         p_data->dscp_val = p_src->arr[type].dscp_val;
1098 }
1099 
1100 /* Set pf update ramrod command params */
1101 void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results *p_src,
1102                                      struct pf_update_ramrod_data *p_dest)
1103 {
1104         struct protocol_dcb_data *p_dcb_data;
1105         u8 update_flag;
1106 
1107         p_dest->pf_id = p_src->pf_id;
1108 
1109         update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update;
1110         p_dest->update_fcoe_dcb_data_mode = update_flag;
1111 
1112         update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update;
1113         p_dest->update_roce_dcb_data_mode = update_flag;
1114 
1115         update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update;
1116         p_dest->update_rroce_dcb_data_mode = update_flag;
1117 
1118         update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update;
1119         p_dest->update_iscsi_dcb_data_mode = update_flag;
1120         update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update;
1121         p_dest->update_eth_dcb_data_mode = update_flag;
1122         update_flag = p_src->arr[DCBX_PROTOCOL_IWARP].update;
1123         p_dest->update_iwarp_dcb_data_mode = update_flag;
1124 
1125         p_dcb_data = &p_dest->fcoe_dcb_data;
1126         ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE);
1127         p_dcb_data = &p_dest->roce_dcb_data;
1128         ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE);
1129         p_dcb_data = &p_dest->rroce_dcb_data;
1130         ecore_dcbx_update_protocol_data(p_dcb_data, p_src,
1131                                         DCBX_PROTOCOL_ROCE_V2);
1132         p_dcb_data = &p_dest->iscsi_dcb_data;
1133         ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI);
1134         p_dcb_data = &p_dest->eth_dcb_data;
1135         ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
1136         p_dcb_data = &p_dest->iwarp_dcb_data;
1137         ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_IWARP);
1138 }
1139 
1140 enum _ecore_status_t ecore_dcbx_query_params(struct ecore_hwfn *p_hwfn,
1141                                              struct ecore_dcbx_get *p_get,
1142                                              enum ecore_mib_read_type type)
1143 {
1144         struct ecore_ptt *p_ptt;
1145         enum _ecore_status_t rc;
1146 
1147         if (IS_VF(p_hwfn->p_dev))
1148                 return ECORE_INVAL;
1149 
1150         p_ptt = ecore_ptt_acquire(p_hwfn);
1151         if (!p_ptt) {
1152                 rc = ECORE_TIMEOUT;
1153                 DP_ERR(p_hwfn, "rc = %d\n", rc);
1154                 return rc;
1155         }
1156 
1157         rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
1158         if (rc != ECORE_SUCCESS)
1159                 goto out;
1160 
1161         rc = ecore_dcbx_get_params(p_hwfn, p_ptt, p_get, type);
1162 
1163 out:
1164         ecore_ptt_release(p_hwfn, p_ptt);
1165         return rc;
1166 }
1167 
1168 static void
1169 ecore_dcbx_set_pfc_data(struct ecore_hwfn *p_hwfn,
1170                         u32 *pfc, struct ecore_dcbx_params *p_params)
1171 {
1172         u8 pfc_map = 0;
1173         int i;
1174 
1175         *pfc &= ~DCBX_PFC_ERROR_MASK;
1176 
1177         if (p_params->pfc.willing)
1178                 *pfc |= DCBX_PFC_WILLING_MASK;
1179         else
1180                 *pfc &= ~DCBX_PFC_WILLING_MASK;
1181 
1182         if (p_params->pfc.enabled)
1183                 *pfc |= DCBX_PFC_ENABLED_MASK;
1184         else
1185                 *pfc &= ~DCBX_PFC_ENABLED_MASK;
1186 
1187         *pfc &= ~DCBX_PFC_CAPS_MASK;
1188         *pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT;
1189 
1190         for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++)
1191                 if (p_params->pfc.prio[i])
1192                         pfc_map |= (1 << i);
1193         *pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK;
1194         *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT);
1195 
1196         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "pfc = 0x%x\n", *pfc);
1197 }
1198 
1199 static void
1200 ecore_dcbx_set_ets_data(struct ecore_hwfn *p_hwfn,
1201                         struct dcbx_ets_feature *p_ets,
1202                         struct ecore_dcbx_params *p_params)
1203 {
1204         u8 *bw_map, *tsa_map;
1205         u32 val;
1206         int i;
1207 
1208         if (p_params->ets_willing)
1209                 p_ets->flags |= DCBX_ETS_WILLING_MASK;
1210         else
1211                 p_ets->flags &= ~DCBX_ETS_WILLING_MASK;
1212 
1213         if (p_params->ets_cbs)
1214                 p_ets->flags |= DCBX_ETS_CBS_MASK;
1215         else
1216                 p_ets->flags &= ~DCBX_ETS_CBS_MASK;
1217 
1218         if (p_params->ets_enabled)
1219                 p_ets->flags |= DCBX_ETS_ENABLED_MASK;
1220         else
1221                 p_ets->flags &= ~DCBX_ETS_ENABLED_MASK;
1222 
1223         p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK;
1224         p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT;
1225 
1226         bw_map = (u8 *)&p_ets->tc_bw_tbl[0];
1227         tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0];
1228         p_ets->pri_tc_tbl[0] = 0;
1229         for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
1230                 bw_map[i] = p_params->ets_tc_bw_tbl[i];
1231                 tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
1232                 /* Copy the priority value to the corresponding 4 bits in the
1233                  * traffic class table.
1234                  */
1235                 val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
1236                 p_ets->pri_tc_tbl[0] |= val;
1237         }
1238         for (i = 0; i < 2; i++) {
1239                 p_ets->tc_bw_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_bw_tbl[i]);
1240                 p_ets->tc_tsa_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_tsa_tbl[i]);
1241         }
1242 
1243         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
1244                    "flags = 0x%x pri_tc = 0x%x tc_bwl[] = {0x%x, 0x%x} tc_tsa = {0x%x, 0x%x}\n",
1245                    p_ets->flags, p_ets->pri_tc_tbl[0], p_ets->tc_bw_tbl[0],
1246                    p_ets->tc_bw_tbl[1], p_ets->tc_tsa_tbl[0],
1247                    p_ets->tc_tsa_tbl[1]);
1248 }
1249 
1250 static void
1251 ecore_dcbx_set_app_data(struct ecore_hwfn *p_hwfn,
1252                         struct dcbx_app_priority_feature *p_app,
1253                         struct ecore_dcbx_params *p_params, bool ieee)
1254 {
1255         u32 *entry;
1256         int i;
1257 
1258         if (p_params->app_willing)
1259                 p_app->flags |= DCBX_APP_WILLING_MASK;
1260         else
1261                 p_app->flags &= ~DCBX_APP_WILLING_MASK;
1262 
1263         if (p_params->app_valid)
1264                 p_app->flags |= DCBX_APP_ENABLED_MASK;
1265         else
1266                 p_app->flags &= ~DCBX_APP_ENABLED_MASK;
1267 
1268         p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK;
1269         p_app->flags |= (u32)p_params->num_app_entries <<
1270                                         DCBX_APP_NUM_ENTRIES_SHIFT;
1271 
1272         for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
1273                 entry = &p_app->app_pri_tbl[i].entry;
1274                 *entry = 0;
1275                 if (ieee) {
1276                         *entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK);
1277                         switch (p_params->app_entry[i].sf_ieee) {
1278                         case ECORE_DCBX_SF_IEEE_ETHTYPE:
1279                                 *entry  |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE <<
1280                                             DCBX_APP_SF_IEEE_SHIFT);
1281                                 *entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
1282                                             DCBX_APP_SF_SHIFT);
1283                                 break;
1284                         case ECORE_DCBX_SF_IEEE_TCP_PORT:
1285                                 *entry  |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT <<
1286                                             DCBX_APP_SF_IEEE_SHIFT);
1287                                 *entry  |= ((u32)DCBX_APP_SF_PORT <<
1288                                             DCBX_APP_SF_SHIFT);
1289                                 break;
1290                         case ECORE_DCBX_SF_IEEE_UDP_PORT:
1291                                 *entry  |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT <<
1292                                             DCBX_APP_SF_IEEE_SHIFT);
1293                                 *entry  |= ((u32)DCBX_APP_SF_PORT <<
1294                                             DCBX_APP_SF_SHIFT);
1295                                 break;
1296                         case ECORE_DCBX_SF_IEEE_TCP_UDP_PORT:
1297                                 *entry  |= (u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT <<
1298                                             DCBX_APP_SF_IEEE_SHIFT;
1299                                 *entry  |= ((u32)DCBX_APP_SF_PORT <<
1300                                             DCBX_APP_SF_SHIFT);
1301                                 break;
1302                         }
1303                 } else {
1304                         *entry &= ~DCBX_APP_SF_MASK;
1305                         if (p_params->app_entry[i].ethtype)
1306                                 *entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
1307                                             DCBX_APP_SF_SHIFT);
1308                         else
1309                                 *entry  |= ((u32)DCBX_APP_SF_PORT <<
1310                                             DCBX_APP_SF_SHIFT);
1311                 }
1312                 *entry &= ~DCBX_APP_PROTOCOL_ID_MASK;
1313                 *entry |= ((u32)p_params->app_entry[i].proto_id <<
1314                                 DCBX_APP_PROTOCOL_ID_SHIFT);
1315                 *entry &= ~DCBX_APP_PRI_MAP_MASK;
1316                 *entry |= ((u32)(p_params->app_entry[i].prio) <<
1317                                 DCBX_APP_PRI_MAP_SHIFT);
1318         }
1319 
1320         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_app->flags);
1321 }
1322 
1323 static enum _ecore_status_t
1324 ecore_dcbx_set_local_params(struct ecore_hwfn *p_hwfn,
1325                             struct dcbx_local_params *local_admin,
1326                             struct ecore_dcbx_set *params)
1327 {
1328         bool ieee = false;
1329 
1330         local_admin->flags = 0;
1331         OSAL_MEMCPY(&local_admin->features,
1332                     &p_hwfn->p_dcbx_info->operational.features,
1333                     sizeof(local_admin->features));
1334 
1335         if (params->enabled) {
1336                 local_admin->config = params->ver_num;
1337                 ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE);
1338         } else
1339                 local_admin->config = DCBX_CONFIG_VERSION_DISABLED;
1340 
1341         if (params->override_flags & ECORE_DCBX_OVERRIDE_PFC_CFG)
1342                 ecore_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc,
1343                                         &params->config.params);
1344 
1345         if (params->override_flags & ECORE_DCBX_OVERRIDE_ETS_CFG)
1346                 ecore_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets,
1347                                         &params->config.params);
1348 
1349         if (params->override_flags & ECORE_DCBX_OVERRIDE_APP_CFG)
1350                 ecore_dcbx_set_app_data(p_hwfn, &local_admin->features.app,
1351                                         &params->config.params, ieee);
1352 
1353         return ECORE_SUCCESS;
1354 }
1355 
1356 static enum _ecore_status_t
1357 ecore_dcbx_set_dscp_params(struct ecore_hwfn *p_hwfn,
1358                            struct dcb_dscp_map *p_dscp_map,
1359                            struct ecore_dcbx_set *p_params)
1360 {
1361         int entry, i, j;
1362         u32 val;
1363 
1364         OSAL_MEMCPY(p_dscp_map, &p_hwfn->p_dcbx_info->dscp_map,
1365                     sizeof(*p_dscp_map));
1366 
1367         p_dscp_map->flags &= ~DCB_DSCP_ENABLE_MASK;
1368         if (p_params->dscp.enabled)
1369                 p_dscp_map->flags |= DCB_DSCP_ENABLE_MASK;
1370 
1371         for (i = 0, entry = 0; i < 8; i++) {
1372                 val = 0;
1373                 for (j = 0; j < 8; j++, entry++)
1374                         val |= (((u32)p_params->dscp.dscp_pri_map[entry]) <<
1375                                 (j * 4));
1376 
1377                 p_dscp_map->dscp_pri_map[i] = OSAL_CPU_TO_BE32(val);
1378         }
1379 
1380         p_hwfn->p_dcbx_info->dscp_nig_update = true;
1381 
1382         DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_dscp_map->flags);
1383 
1384         return ECORE_SUCCESS;
1385 }
1386 
1387 enum _ecore_status_t ecore_dcbx_config_params(struct ecore_hwfn *p_hwfn,
1388                                               struct ecore_ptt *p_ptt,
1389                                               struct ecore_dcbx_set *params,
1390                                               bool hw_commit)
1391 {
1392         struct dcbx_local_params local_admin;
1393         struct ecore_dcbx_mib_meta_data data;
1394         struct dcb_dscp_map dscp_map;
1395         u32 resp = 0, param = 0;
1396         enum _ecore_status_t rc = ECORE_SUCCESS;
1397 
1398         if (!hw_commit) {
1399                 OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set, params,
1400                             sizeof(p_hwfn->p_dcbx_info->set));
1401                 return ECORE_SUCCESS;
1402         }
1403 
1404         /* clear set-parmas cache */
1405         OSAL_MEMSET(&p_hwfn->p_dcbx_info->set, 0,
1406                     sizeof(struct ecore_dcbx_set));
1407 
1408         OSAL_MEMSET(&local_admin, 0, sizeof(local_admin));
1409         ecore_dcbx_set_local_params(p_hwfn, &local_admin, params);
1410 
1411         data.addr = p_hwfn->mcp_info->port_addr +
1412                         offsetof(struct public_port, local_admin_dcbx_mib);
1413         data.local_admin = &local_admin;
1414         data.size = sizeof(struct dcbx_local_params);
1415         ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size);
1416 
1417         if (params->override_flags & ECORE_DCBX_OVERRIDE_DSCP_CFG) {
1418                 OSAL_MEMSET(&dscp_map, 0, sizeof(dscp_map));
1419                 ecore_dcbx_set_dscp_params(p_hwfn, &dscp_map, params);
1420 
1421                 data.addr = p_hwfn->mcp_info->port_addr +
1422                                 offsetof(struct public_port, dcb_dscp_map);
1423                 data.dscp_map = &dscp_map;
1424                 data.size = sizeof(struct dcb_dscp_map);
1425                 ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.dscp_map,
1426                                 data.size);
1427         }
1428 
1429         rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX,
1430                            1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, &param);
1431         if (rc != ECORE_SUCCESS) {
1432                 DP_NOTICE(p_hwfn, false,
1433                           "Failed to send DCBX update request\n");
1434                 return rc;
1435         }
1436 
1437         return rc;
1438 }
1439 
1440 enum _ecore_status_t ecore_dcbx_get_config_params(struct ecore_hwfn *p_hwfn,
1441                                                   struct ecore_dcbx_set *params)
1442 {
1443         struct ecore_dcbx_get *dcbx_info;
1444         int rc;
1445 
1446         if (p_hwfn->p_dcbx_info->set.config.valid) {
1447                 OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
1448                             sizeof(struct ecore_dcbx_set));
1449                 return ECORE_SUCCESS;
1450         }
1451 
1452         dcbx_info = OSAL_ALLOC(p_hwfn->p_dev, GFP_KERNEL,
1453                                sizeof(*dcbx_info));
1454         if (!dcbx_info) {
1455                 DP_ERR(p_hwfn, "Failed to allocate struct ecore_dcbx_info\n");
1456                 return ECORE_NOMEM;
1457         }
1458 
1459         OSAL_MEMSET(dcbx_info, 0, sizeof(*dcbx_info));
1460         rc = ecore_dcbx_query_params(p_hwfn, dcbx_info,
1461                                      ECORE_DCBX_OPERATIONAL_MIB);
1462         if (rc) {
1463                 OSAL_FREE(p_hwfn->p_dev, dcbx_info);
1464                 return rc;
1465         }
1466         p_hwfn->p_dcbx_info->set.override_flags = 0;
1467 
1468         p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED;
1469         if (dcbx_info->operational.cee)
1470                 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE;
1471         if (dcbx_info->operational.ieee)
1472                 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE;
1473         if (dcbx_info->operational.local)
1474                 p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC;
1475 
1476         p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled;
1477         OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set.config.params,
1478                     &dcbx_info->operational.params,
1479                     sizeof(struct ecore_dcbx_admin_params));
1480         p_hwfn->p_dcbx_info->set.config.valid = true;
1481 
1482         OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
1483                     sizeof(struct ecore_dcbx_set));
1484 
1485         OSAL_FREE(p_hwfn->p_dev, dcbx_info);
1486 
1487         return ECORE_SUCCESS;
1488 }