root/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cxgb4_dcb_state_synced
  2. cxgb4_dcb_state_init
  3. cxgb4_dcb_version_init
  4. cxgb4_dcb_cleanup_apps
  5. cxgb4_dcb_reset
  6. cxgb4_dcb_update_support
  7. cxgb4_dcb_state_fsm
  8. cxgb4_dcb_handle_fw_update
  9. cxgb4_getstate
  10. cxgb4_setstate
  11. cxgb4_getpgtccfg
  12. cxgb4_getpgtccfg_tx
  13. cxgb4_getpgtccfg_rx
  14. cxgb4_setpgtccfg_tx
  15. cxgb4_getpgbwgcfg
  16. cxgb4_getpgbwgcfg_tx
  17. cxgb4_getpgbwgcfg_rx
  18. cxgb4_setpgbwgcfg_tx
  19. cxgb4_getpfccfg
  20. cxgb4_setpfccfg
  21. cxgb4_setall
  22. cxgb4_getcap
  23. cxgb4_getnumtcs
  24. cxgb4_setnumtcs
  25. cxgb4_getpfcstate
  26. cxgb4_setpfcstate
  27. __cxgb4_getapp
  28. cxgb4_getapp
  29. __cxgb4_setapp
  30. cxgb4_setapp
  31. cxgb4_ieee_negotiation_complete
  32. cxgb4_ieee_read_ets
  33. cxgb4_ieee_get_ets
  34. cxgb4_ieee_get_pfc
  35. cxgb4_ieee_peer_ets
  36. cxgb4_ieee_getapp
  37. cxgb4_ieee_setapp
  38. cxgb4_getdcbx
  39. cxgb4_setdcbx
  40. cxgb4_getpeer_app
  41. cxgb4_getpeerapp_tbl
  42. cxgb4_cee_peer_getpg
  43. cxgb4_cee_peer_getpfc

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Copyright (C) 2013-2014 Chelsio Communications.  All rights reserved.
   4  *
   5  *  Written by Anish Bhatt (anish@chelsio.com)
   6  *             Casey Leedom (leedom@chelsio.com)
   7  */
   8 
   9 #include "cxgb4.h"
  10 
  11 /* DCBx version control
  12  */
  13 const char * const dcb_ver_array[] = {
  14         "Unknown",
  15         "DCBx-CIN",
  16         "DCBx-CEE 1.01",
  17         "DCBx-IEEE",
  18         "", "", "",
  19         "Auto Negotiated"
  20 };
  21 
  22 static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state)
  23 {
  24         if (state == CXGB4_DCB_STATE_FW_ALLSYNCED ||
  25             state == CXGB4_DCB_STATE_HOST)
  26                 return true;
  27         else
  28                 return false;
  29 }
  30 
  31 /* Initialize a port's Data Center Bridging state.
  32  */
  33 void cxgb4_dcb_state_init(struct net_device *dev)
  34 {
  35         struct port_info *pi = netdev2pinfo(dev);
  36         struct port_dcb_info *dcb = &pi->dcb;
  37         int version_temp = dcb->dcb_version;
  38 
  39         memset(dcb, 0, sizeof(struct port_dcb_info));
  40         dcb->state = CXGB4_DCB_STATE_START;
  41         if (version_temp)
  42                 dcb->dcb_version = version_temp;
  43 
  44         netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n",
  45                     __func__, pi->port_id);
  46 }
  47 
  48 void cxgb4_dcb_version_init(struct net_device *dev)
  49 {
  50         struct port_info *pi = netdev2pinfo(dev);
  51         struct port_dcb_info *dcb = &pi->dcb;
  52 
  53         /* Any writes here are only done on kernels that exlicitly need
  54          * a specific version, say < 2.6.38 which only support CEE
  55          */
  56         dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
  57 }
  58 
  59 static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
  60 {
  61         struct port_info *pi = netdev2pinfo(dev);
  62         struct adapter *adap = pi->adapter;
  63         struct port_dcb_info *dcb = &pi->dcb;
  64         struct dcb_app app;
  65         int i, err;
  66 
  67         /* zero priority implies remove */
  68         app.priority = 0;
  69 
  70         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  71                 /* Check if app list is exhausted */
  72                 if (!dcb->app_priority[i].protocolid)
  73                         break;
  74 
  75                 app.protocol = dcb->app_priority[i].protocolid;
  76 
  77                 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
  78                         app.priority = dcb->app_priority[i].user_prio_map;
  79                         app.selector = dcb->app_priority[i].sel_field + 1;
  80                         err = dcb_ieee_delapp(dev, &app);
  81                 } else {
  82                         app.selector = !!(dcb->app_priority[i].sel_field);
  83                         err = dcb_setapp(dev, &app);
  84                 }
  85 
  86                 if (err) {
  87                         dev_err(adap->pdev_dev,
  88                                 "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
  89                                 dcb_ver_array[dcb->dcb_version], app.selector,
  90                                 app.protocol, -err);
  91                         break;
  92                 }
  93         }
  94 }
  95 
  96 /* Reset a port's Data Center Bridging state.  Typically used after a
  97  * Link Down event.
  98  */
  99 void cxgb4_dcb_reset(struct net_device *dev)
 100 {
 101         cxgb4_dcb_cleanup_apps(dev);
 102         cxgb4_dcb_state_init(dev);
 103 }
 104 
 105 /* update the dcb port support, if version is IEEE then set it to
 106  * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then
 107  * clear that. and if it is set to CEE then set dcb supported to
 108  * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it
 109  */
 110 static inline void cxgb4_dcb_update_support(struct port_dcb_info *dcb)
 111 {
 112         if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
 113                 if (dcb->supported & DCB_CAP_DCBX_VER_CEE)
 114                         dcb->supported &= ~DCB_CAP_DCBX_VER_CEE;
 115                 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
 116         } else if (dcb->dcb_version == FW_PORT_DCB_VER_CEE1D01) {
 117                 if (dcb->supported & DCB_CAP_DCBX_VER_IEEE)
 118                         dcb->supported &= ~DCB_CAP_DCBX_VER_IEEE;
 119                 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
 120         }
 121 }
 122 
 123 /* Finite State machine for Data Center Bridging.
 124  */
 125 void cxgb4_dcb_state_fsm(struct net_device *dev,
 126                          enum cxgb4_dcb_state_input transition_to)
 127 {
 128         struct port_info *pi = netdev2pinfo(dev);
 129         struct port_dcb_info *dcb = &pi->dcb;
 130         struct adapter *adap = pi->adapter;
 131         enum cxgb4_dcb_state current_state = dcb->state;
 132 
 133         netdev_dbg(dev, "%s: State change from %d to %d for %s\n",
 134                     __func__, dcb->state, transition_to, dev->name);
 135 
 136         switch (current_state) {
 137         case CXGB4_DCB_STATE_START: {
 138                 switch (transition_to) {
 139                 case CXGB4_DCB_INPUT_FW_DISABLED: {
 140                         /* we're going to use Host DCB */
 141                         dcb->state = CXGB4_DCB_STATE_HOST;
 142                         dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
 143                         break;
 144                 }
 145 
 146                 case CXGB4_DCB_INPUT_FW_ENABLED: {
 147                         /* we're going to use Firmware DCB */
 148                         dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
 149                         dcb->supported = DCB_CAP_DCBX_LLD_MANAGED;
 150                         if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE)
 151                                 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
 152                         else
 153                                 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
 154                         break;
 155                 }
 156 
 157                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 158                         /* expected transition */
 159                         break;
 160                 }
 161 
 162                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 163                         dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
 164                         break;
 165                 }
 166 
 167                 default:
 168                         goto bad_state_input;
 169                 }
 170                 break;
 171         }
 172 
 173         case CXGB4_DCB_STATE_FW_INCOMPLETE: {
 174                 if (transition_to != CXGB4_DCB_INPUT_FW_DISABLED) {
 175                         /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state,
 176                          * check if the dcb version is changed (there can be
 177                          * mismatch in default config & the negotiated switch
 178                          * configuration at FW, so update the dcb support
 179                          * accordingly.
 180                          */
 181                         cxgb4_dcb_update_support(dcb);
 182                 }
 183                 switch (transition_to) {
 184                 case CXGB4_DCB_INPUT_FW_ENABLED: {
 185                         /* we're alreaady in firmware DCB mode */
 186                         break;
 187                 }
 188 
 189                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 190                         /* we're already incomplete */
 191                         break;
 192                 }
 193 
 194                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 195                         dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
 196                         dcb->enabled = 1;
 197                         linkwatch_fire_event(dev);
 198                         break;
 199                 }
 200 
 201                 default:
 202                         goto bad_state_input;
 203                 }
 204                 break;
 205         }
 206 
 207         case CXGB4_DCB_STATE_FW_ALLSYNCED: {
 208                 switch (transition_to) {
 209                 case CXGB4_DCB_INPUT_FW_ENABLED: {
 210                         /* we're alreaady in firmware DCB mode */
 211                         break;
 212                 }
 213 
 214                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 215                         /* We were successfully running with firmware DCB but
 216                          * now it's telling us that it's in an "incomplete
 217                          * state.  We need to reset back to a ground state
 218                          * of incomplete.
 219                          */
 220                         cxgb4_dcb_reset(dev);
 221                         dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
 222                         dcb->supported = CXGB4_DCBX_FW_SUPPORT;
 223                         linkwatch_fire_event(dev);
 224                         break;
 225                 }
 226 
 227                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 228                         /* we're already all sync'ed
 229                          * this is only applicable for IEEE or
 230                          * when another VI already completed negotiaton
 231                          */
 232                         dcb->enabled = 1;
 233                         linkwatch_fire_event(dev);
 234                         break;
 235                 }
 236 
 237                 default:
 238                         goto bad_state_input;
 239                 }
 240                 break;
 241         }
 242 
 243         case CXGB4_DCB_STATE_HOST: {
 244                 switch (transition_to) {
 245                 case CXGB4_DCB_INPUT_FW_DISABLED: {
 246                         /* we're alreaady in Host DCB mode */
 247                         break;
 248                 }
 249 
 250                 default:
 251                         goto bad_state_input;
 252                 }
 253                 break;
 254         }
 255 
 256         default:
 257                 goto bad_state_transition;
 258         }
 259         return;
 260 
 261 bad_state_input:
 262         dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
 263                 transition_to);
 264         return;
 265 
 266 bad_state_transition:
 267         dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
 268                 current_state, transition_to);
 269 }
 270 
 271 /* Handle a DCB/DCBX update message from the firmware.
 272  */
 273 void cxgb4_dcb_handle_fw_update(struct adapter *adap,
 274                                 const struct fw_port_cmd *pcmd)
 275 {
 276         const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
 277         int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
 278         struct net_device *dev = adap->port[adap->chan_map[port]];
 279         struct port_info *pi = netdev_priv(dev);
 280         struct port_dcb_info *dcb = &pi->dcb;
 281         int dcb_type = pcmd->u.dcb.pgid.type;
 282         int dcb_running_version;
 283 
 284         /* Handle Firmware DCB Control messages separately since they drive
 285          * our state machine.
 286          */
 287         if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
 288                 enum cxgb4_dcb_state_input input =
 289                         ((pcmd->u.dcb.control.all_syncd_pkd &
 290                           FW_PORT_CMD_ALL_SYNCD_F)
 291                          ? CXGB4_DCB_INPUT_FW_ALLSYNCED
 292                          : CXGB4_DCB_INPUT_FW_INCOMPLETE);
 293 
 294                 if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) {
 295                         dcb_running_version = FW_PORT_CMD_DCB_VERSION_G(
 296                                 be16_to_cpu(
 297                                 pcmd->u.dcb.control.dcb_version_to_app_state));
 298                         if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 ||
 299                             dcb_running_version == FW_PORT_DCB_VER_IEEE) {
 300                                 dcb->dcb_version = dcb_running_version;
 301                                 dev_warn(adap->pdev_dev, "Interface %s is running %s\n",
 302                                          dev->name,
 303                                          dcb_ver_array[dcb->dcb_version]);
 304                         } else {
 305                                 dev_warn(adap->pdev_dev,
 306                                          "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
 307                                          dcb_ver_array[dcb->dcb_version],
 308                                          dcb_ver_array[dcb_running_version]);
 309                                 dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN;
 310                         }
 311                 }
 312 
 313                 cxgb4_dcb_state_fsm(dev, input);
 314                 return;
 315         }
 316 
 317         /* It's weird, and almost certainly an error, to get Firmware DCB
 318          * messages when we either haven't been told whether we're going to be
 319          * doing Host or Firmware DCB; and even worse when we've been told
 320          * that we're doing Host DCB!
 321          */
 322         if (dcb->state == CXGB4_DCB_STATE_START ||
 323             dcb->state == CXGB4_DCB_STATE_HOST) {
 324                 dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
 325                         dcb->state);
 326                 return;
 327         }
 328 
 329         /* Now handle the general Firmware DCB update messages ...
 330          */
 331         switch (dcb_type) {
 332         case FW_PORT_DCB_TYPE_PGID:
 333                 dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
 334                 dcb->msgs |= CXGB4_DCB_FW_PGID;
 335                 break;
 336 
 337         case FW_PORT_DCB_TYPE_PGRATE:
 338                 dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
 339                 memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
 340                        sizeof(dcb->pgrate));
 341                 memcpy(dcb->tsa, &fwdcb->pgrate.tsa,
 342                        sizeof(dcb->tsa));
 343                 dcb->msgs |= CXGB4_DCB_FW_PGRATE;
 344                 if (dcb->msgs & CXGB4_DCB_FW_PGID)
 345                         IEEE_FAUX_SYNC(dev, dcb);
 346                 break;
 347 
 348         case FW_PORT_DCB_TYPE_PRIORATE:
 349                 memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
 350                        sizeof(dcb->priorate));
 351                 dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
 352                 break;
 353 
 354         case FW_PORT_DCB_TYPE_PFC:
 355                 dcb->pfcen = fwdcb->pfc.pfcen;
 356                 dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
 357                 dcb->msgs |= CXGB4_DCB_FW_PFC;
 358                 IEEE_FAUX_SYNC(dev, dcb);
 359                 break;
 360 
 361         case FW_PORT_DCB_TYPE_APP_ID: {
 362                 const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
 363                 int idx = fwap->idx;
 364                 struct app_priority *ap = &dcb->app_priority[idx];
 365 
 366                 struct dcb_app app = {
 367                         .protocol = be16_to_cpu(fwap->protocolid),
 368                 };
 369                 int err;
 370 
 371                 /* Convert from firmware format to relevant format
 372                  * when using app selector
 373                  */
 374                 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
 375                         app.selector = (fwap->sel_field + 1);
 376                         app.priority = ffs(fwap->user_prio_map) - 1;
 377                         err = dcb_ieee_setapp(dev, &app);
 378                         IEEE_FAUX_SYNC(dev, dcb);
 379                 } else {
 380                         /* Default is CEE */
 381                         app.selector = !!(fwap->sel_field);
 382                         app.priority = fwap->user_prio_map;
 383                         err = dcb_setapp(dev, &app);
 384                 }
 385 
 386                 if (err)
 387                         dev_err(adap->pdev_dev,
 388                                 "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
 389                                 app.selector, app.protocol, app.priority, -err);
 390 
 391                 ap->user_prio_map = fwap->user_prio_map;
 392                 ap->sel_field = fwap->sel_field;
 393                 ap->protocolid = be16_to_cpu(fwap->protocolid);
 394                 dcb->msgs |= CXGB4_DCB_FW_APP_ID;
 395                 break;
 396         }
 397 
 398         default:
 399                 dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
 400                         dcb_type);
 401                 break;
 402         }
 403 }
 404 
 405 /* Data Center Bridging netlink operations.
 406  */
 407 
 408 
 409 /* Get current DCB enabled/disabled state.
 410  */
 411 static u8 cxgb4_getstate(struct net_device *dev)
 412 {
 413         struct port_info *pi = netdev2pinfo(dev);
 414 
 415         return pi->dcb.enabled;
 416 }
 417 
 418 /* Set DCB enabled/disabled.
 419  */
 420 static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
 421 {
 422         struct port_info *pi = netdev2pinfo(dev);
 423 
 424         /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
 425         if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
 426                 pi->dcb.enabled = enabled;
 427                 return 0;
 428         }
 429 
 430         /* Firmware doesn't provide any mechanism to control the DCB state.
 431          */
 432         if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
 433                 return 1;
 434 
 435         return 0;
 436 }
 437 
 438 static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
 439                              u8 *prio_type, u8 *pgid, u8 *bw_per,
 440                              u8 *up_tc_map, int local)
 441 {
 442         struct fw_port_cmd pcmd;
 443         struct port_info *pi = netdev2pinfo(dev);
 444         struct adapter *adap = pi->adapter;
 445         int err;
 446 
 447         *prio_type = *pgid = *bw_per = *up_tc_map = 0;
 448 
 449         if (local)
 450                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 451         else
 452                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 453 
 454         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 455         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 456         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 457                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 458                 return;
 459         }
 460         *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
 461 
 462         if (local)
 463                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 464         else
 465                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 466         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 467         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 468         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 469                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 470                         -err);
 471                 return;
 472         }
 473 
 474         *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
 475         *up_tc_map = (1 << tc);
 476 
 477         /* prio_type is link strict */
 478         if (*pgid != 0xF)
 479                 *prio_type = 0x2;
 480 }
 481 
 482 static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
 483                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
 484                                 u8 *up_tc_map)
 485 {
 486         /* tc 0 is written at MSB position */
 487         return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
 488                                 up_tc_map, 1);
 489 }
 490 
 491 
 492 static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
 493                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
 494                                 u8 *up_tc_map)
 495 {
 496         /* tc 0 is written at MSB position */
 497         return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
 498                                 up_tc_map, 0);
 499 }
 500 
 501 static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
 502                                 u8 prio_type, u8 pgid, u8 bw_per,
 503                                 u8 up_tc_map)
 504 {
 505         struct fw_port_cmd pcmd;
 506         struct port_info *pi = netdev2pinfo(dev);
 507         struct adapter *adap = pi->adapter;
 508         int fw_tc = 7 - tc;
 509         u32 _pgid;
 510         int err;
 511 
 512         if (pgid == DCB_ATTR_VALUE_UNDEFINED)
 513                 return;
 514         if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
 515                 return;
 516 
 517         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 518         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 519 
 520         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 521         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 522                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 523                 return;
 524         }
 525 
 526         _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
 527         _pgid &= ~(0xF << (fw_tc * 4));
 528         _pgid |= pgid << (fw_tc * 4);
 529         pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
 530 
 531         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 532 
 533         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 534         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 535                 dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
 536                         -err);
 537                 return;
 538         }
 539 
 540         memset(&pcmd, 0, sizeof(struct fw_port_cmd));
 541 
 542         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 543         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 544 
 545         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 546         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 547                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 548                         -err);
 549                 return;
 550         }
 551 
 552         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
 553 
 554         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 555         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 556                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 557 
 558         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 559         if (err != FW_PORT_DCB_CFG_SUCCESS)
 560                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
 561                         -err);
 562 }
 563 
 564 static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
 565                               int local)
 566 {
 567         struct fw_port_cmd pcmd;
 568         struct port_info *pi = netdev2pinfo(dev);
 569         struct adapter *adap = pi->adapter;
 570         int err;
 571 
 572         if (local)
 573                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 574         else
 575                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 576 
 577         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 578         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 579         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 580                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 581                         -err);
 582                 return;
 583         }
 584 
 585         *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
 586 }
 587 
 588 static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
 589 {
 590         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
 591 }
 592 
 593 static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
 594 {
 595         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
 596 }
 597 
 598 static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
 599                                  u8 bw_per)
 600 {
 601         struct fw_port_cmd pcmd;
 602         struct port_info *pi = netdev2pinfo(dev);
 603         struct adapter *adap = pi->adapter;
 604         int err;
 605 
 606         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 607         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 608 
 609         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 610         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 611                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 612                         -err);
 613                 return;
 614         }
 615 
 616         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
 617 
 618         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 619         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 620                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 621 
 622         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 623 
 624         if (err != FW_PORT_DCB_CFG_SUCCESS)
 625                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
 626                         -err);
 627 }
 628 
 629 /* Return whether the specified Traffic Class Priority has Priority Pause
 630  * Frames enabled.
 631  */
 632 static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
 633 {
 634         struct port_info *pi = netdev2pinfo(dev);
 635         struct port_dcb_info *dcb = &pi->dcb;
 636 
 637         if (!cxgb4_dcb_state_synced(dcb->state) ||
 638             priority >= CXGB4_MAX_PRIORITY)
 639                 *pfccfg = 0;
 640         else
 641                 *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1;
 642 }
 643 
 644 /* Enable/disable Priority Pause Frames for the specified Traffic Class
 645  * Priority.
 646  */
 647 static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
 648 {
 649         struct fw_port_cmd pcmd;
 650         struct port_info *pi = netdev2pinfo(dev);
 651         struct adapter *adap = pi->adapter;
 652         int err;
 653 
 654         if (!cxgb4_dcb_state_synced(pi->dcb.state) ||
 655             priority >= CXGB4_MAX_PRIORITY)
 656                 return;
 657 
 658         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 659         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 660                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 661 
 662         pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
 663         pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
 664 
 665         if (pfccfg)
 666                 pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority));
 667         else
 668                 pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority)));
 669 
 670         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 671         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 672                 dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
 673                 return;
 674         }
 675 
 676         pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
 677 }
 678 
 679 static u8 cxgb4_setall(struct net_device *dev)
 680 {
 681         return 0;
 682 }
 683 
 684 /* Return DCB capabilities.
 685  */
 686 static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
 687 {
 688         struct port_info *pi = netdev2pinfo(dev);
 689 
 690         switch (cap_id) {
 691         case DCB_CAP_ATTR_PG:
 692         case DCB_CAP_ATTR_PFC:
 693                 *caps = true;
 694                 break;
 695 
 696         case DCB_CAP_ATTR_PG_TCS:
 697                 /* 8 priorities for PG represented by bitmap */
 698                 *caps = 0x80;
 699                 break;
 700 
 701         case DCB_CAP_ATTR_PFC_TCS:
 702                 /* 8 priorities for PFC represented by bitmap */
 703                 *caps = 0x80;
 704                 break;
 705 
 706         case DCB_CAP_ATTR_GSP:
 707                 *caps = true;
 708                 break;
 709 
 710         case DCB_CAP_ATTR_UP2TC:
 711         case DCB_CAP_ATTR_BCN:
 712                 *caps = false;
 713                 break;
 714 
 715         case DCB_CAP_ATTR_DCBX:
 716                 *caps = pi->dcb.supported;
 717                 break;
 718 
 719         default:
 720                 *caps = false;
 721         }
 722 
 723         return 0;
 724 }
 725 
 726 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
 727  */
 728 static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
 729 {
 730         struct port_info *pi = netdev2pinfo(dev);
 731 
 732         switch (tcs_id) {
 733         case DCB_NUMTCS_ATTR_PG:
 734                 if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
 735                         *num = pi->dcb.pg_num_tcs_supported;
 736                 else
 737                         *num = 0x8;
 738                 break;
 739 
 740         case DCB_NUMTCS_ATTR_PFC:
 741                 *num = 0x8;
 742                 break;
 743 
 744         default:
 745                 return -EINVAL;
 746         }
 747 
 748         return 0;
 749 }
 750 
 751 /* Set the number of Traffic Classes supported for the indicated Traffic Class
 752  * ID.
 753  */
 754 static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
 755 {
 756         /* Setting the number of Traffic Classes isn't supported.
 757          */
 758         return -ENOSYS;
 759 }
 760 
 761 /* Return whether Priority Flow Control is enabled.  */
 762 static u8 cxgb4_getpfcstate(struct net_device *dev)
 763 {
 764         struct port_info *pi = netdev2pinfo(dev);
 765 
 766         if (!cxgb4_dcb_state_synced(pi->dcb.state))
 767                 return false;
 768 
 769         return pi->dcb.pfcen != 0;
 770 }
 771 
 772 /* Enable/disable Priority Flow Control. */
 773 static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
 774 {
 775         /* We can't enable/disable Priority Flow Control but we also can't
 776          * return an error ...
 777          */
 778 }
 779 
 780 /* Return the Application User Priority Map associated with the specified
 781  * Application ID.
 782  */
 783 static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 784                           int peer)
 785 {
 786         struct port_info *pi = netdev2pinfo(dev);
 787         struct adapter *adap = pi->adapter;
 788         int i;
 789 
 790         if (!cxgb4_dcb_state_synced(pi->dcb.state))
 791                 return 0;
 792 
 793         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
 794                 struct fw_port_cmd pcmd;
 795                 int err;
 796 
 797                 if (peer)
 798                         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 799                 else
 800                         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 801 
 802                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 803                 pcmd.u.dcb.app_priority.idx = i;
 804 
 805                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 806                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
 807                         dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
 808                                 -err);
 809                         return err;
 810                 }
 811                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
 812                         if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
 813                                 return pcmd.u.dcb.app_priority.user_prio_map;
 814 
 815                 /* exhausted app list */
 816                 if (!pcmd.u.dcb.app_priority.protocolid)
 817                         break;
 818         }
 819 
 820         return -EEXIST;
 821 }
 822 
 823 /* Return the Application User Priority Map associated with the specified
 824  * Application ID.
 825  */
 826 static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
 827 {
 828         /* Convert app_idtype to firmware format before querying */
 829         return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
 830                               app_idtype : 3, app_id, 0);
 831 }
 832 
 833 /* Write a new Application User Priority Map for the specified Application ID
 834  */
 835 static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 836                           u8 app_prio)
 837 {
 838         struct fw_port_cmd pcmd;
 839         struct port_info *pi = netdev2pinfo(dev);
 840         struct adapter *adap = pi->adapter;
 841         int i, err;
 842 
 843 
 844         if (!cxgb4_dcb_state_synced(pi->dcb.state))
 845                 return -EINVAL;
 846 
 847         /* DCB info gets thrown away on link up */
 848         if (!netif_carrier_ok(dev))
 849                 return -ENOLINK;
 850 
 851         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
 852                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 853                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 854                 pcmd.u.dcb.app_priority.idx = i;
 855                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 856 
 857                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
 858                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
 859                                 -err);
 860                         return err;
 861                 }
 862                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
 863                         /* overwrite existing app table */
 864                         pcmd.u.dcb.app_priority.protocolid = 0;
 865                         break;
 866                 }
 867                 /* find first empty slot */
 868                 if (!pcmd.u.dcb.app_priority.protocolid)
 869                         break;
 870         }
 871 
 872         if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
 873                 /* no empty slots available */
 874                 dev_err(adap->pdev_dev, "DCB app table full\n");
 875                 return -EBUSY;
 876         }
 877 
 878         /* write out new app table entry */
 879         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 880         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 881                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 882 
 883         pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 884         pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
 885         pcmd.u.dcb.app_priority.sel_field = app_idtype;
 886         pcmd.u.dcb.app_priority.user_prio_map = app_prio;
 887         pcmd.u.dcb.app_priority.idx = i;
 888 
 889         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 890         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 891                 dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
 892                         -err);
 893                 return err;
 894         }
 895 
 896         return 0;
 897 }
 898 
 899 /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
 900 static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 901                         u8 app_prio)
 902 {
 903         int ret;
 904         struct dcb_app app = {
 905                 .selector = app_idtype,
 906                 .protocol = app_id,
 907                 .priority = app_prio,
 908         };
 909 
 910         if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
 911             app_idtype != DCB_APP_IDTYPE_PORTNUM)
 912                 return -EINVAL;
 913 
 914         /* Convert app_idtype to a format that firmware understands */
 915         ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
 916                               app_idtype : 3, app_id, app_prio);
 917         if (ret)
 918                 return ret;
 919 
 920         return dcb_setapp(dev, &app);
 921 }
 922 
 923 /* Return whether IEEE Data Center Bridging has been negotiated.
 924  */
 925 static inline int
 926 cxgb4_ieee_negotiation_complete(struct net_device *dev,
 927                                 enum cxgb4_dcb_fw_msgs dcb_subtype)
 928 {
 929         struct port_info *pi = netdev2pinfo(dev);
 930         struct port_dcb_info *dcb = &pi->dcb;
 931 
 932         if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED)
 933                 if (dcb_subtype && !(dcb->msgs & dcb_subtype))
 934                         return 0;
 935 
 936         return (cxgb4_dcb_state_synced(dcb->state) &&
 937                 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
 938 }
 939 
 940 static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
 941                                int local)
 942 {
 943         struct port_info *pi = netdev2pinfo(dev);
 944         struct port_dcb_info *dcb = &pi->dcb;
 945         struct adapter *adap = pi->adapter;
 946         uint32_t tc_info;
 947         struct fw_port_cmd pcmd;
 948         int i, bwg, err;
 949 
 950         if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
 951                 return 0;
 952 
 953         ets->ets_cap =  dcb->pg_num_tcs_supported;
 954 
 955         if (local) {
 956                 ets->willing = 1;
 957                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 958         } else {
 959                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 960         }
 961 
 962         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 963         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 964         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 965                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 966                 return err;
 967         }
 968 
 969         tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
 970 
 971         if (local)
 972                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 973         else
 974                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 975 
 976         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 977         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 978         if (err != FW_PORT_DCB_CFG_SUCCESS) {
 979                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 980                         -err);
 981                 return err;
 982         }
 983 
 984         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 985                 bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
 986                 ets->prio_tc[i] = bwg;
 987                 ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
 988                 ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
 989                 ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
 990         }
 991 
 992         return 0;
 993 }
 994 
 995 static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
 996 {
 997         return cxgb4_ieee_read_ets(dev, ets, 1);
 998 }
 999 
1000 /* We reuse this for peer PFC as well, as we can't have it enabled one way */
1001 static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
1002 {
1003         struct port_info *pi = netdev2pinfo(dev);
1004         struct port_dcb_info *dcb = &pi->dcb;
1005 
1006         memset(pfc, 0, sizeof(struct ieee_pfc));
1007 
1008         if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
1009                 return 0;
1010 
1011         pfc->pfc_cap = dcb->pfc_num_tcs_supported;
1012         pfc->pfc_en = bitswap_1(dcb->pfcen);
1013 
1014         return 0;
1015 }
1016 
1017 static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
1018 {
1019         return cxgb4_ieee_read_ets(dev, ets, 0);
1020 }
1021 
1022 /* Fill in the Application User Priority Map associated with the
1023  * specified Application.
1024  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1025  */
1026 static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
1027 {
1028         int prio;
1029 
1030         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1031                 return -EINVAL;
1032         if (!(app->selector && app->protocol))
1033                 return -EINVAL;
1034 
1035         /* Try querying firmware first, use firmware format */
1036         prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
1037 
1038         if (prio < 0)
1039                 prio = dcb_ieee_getapp_mask(dev, app);
1040 
1041         app->priority = ffs(prio) - 1;
1042         return 0;
1043 }
1044 
1045 /* Write a new Application User Priority Map for the specified Application ID.
1046  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1047  */
1048 static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
1049 {
1050         int ret;
1051 
1052         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1053                 return -EINVAL;
1054         if (!(app->selector && app->protocol))
1055                 return -EINVAL;
1056 
1057         if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE  &&
1058               app->selector < IEEE_8021QAZ_APP_SEL_ANY))
1059                 return -EINVAL;
1060 
1061         /* change selector to a format that firmware understands */
1062         ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
1063                              (1 << app->priority));
1064         if (ret)
1065                 return ret;
1066 
1067         return dcb_ieee_setapp(dev, app);
1068 }
1069 
1070 /* Return our DCBX parameters.
1071  */
1072 static u8 cxgb4_getdcbx(struct net_device *dev)
1073 {
1074         struct port_info *pi = netdev2pinfo(dev);
1075 
1076         /* This is already set by cxgb4_set_dcb_caps, so just return it */
1077         return pi->dcb.supported;
1078 }
1079 
1080 /* Set our DCBX parameters.
1081  */
1082 static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
1083 {
1084         struct port_info *pi = netdev2pinfo(dev);
1085 
1086         /* Filter out requests which exceed our capabilities.
1087          */
1088         if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
1089             != dcb_request)
1090                 return 1;
1091 
1092         /* Can't enable DCB if we haven't successfully negotiated it.
1093          */
1094         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1095                 return 1;
1096 
1097         /* There's currently no mechanism to allow for the firmware DCBX
1098          * negotiation to be changed from the Host Driver.  If the caller
1099          * requests exactly the same parameters that we already have then
1100          * we'll allow them to be successfully "set" ...
1101          */
1102         if (dcb_request != pi->dcb.supported)
1103                 return 1;
1104 
1105         pi->dcb.supported = dcb_request;
1106         return 0;
1107 }
1108 
1109 static int cxgb4_getpeer_app(struct net_device *dev,
1110                              struct dcb_peer_app_info *info, u16 *app_count)
1111 {
1112         struct fw_port_cmd pcmd;
1113         struct port_info *pi = netdev2pinfo(dev);
1114         struct adapter *adap = pi->adapter;
1115         int i, err = 0;
1116 
1117         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1118                 return 1;
1119 
1120         info->willing = 0;
1121         info->error = 0;
1122 
1123         *app_count = 0;
1124         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1125                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1126                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1127                 pcmd.u.dcb.app_priority.idx = *app_count;
1128                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1129 
1130                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1131                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1132                                 -err);
1133                         return err;
1134                 }
1135 
1136                 /* find first empty slot */
1137                 if (!pcmd.u.dcb.app_priority.protocolid)
1138                         break;
1139         }
1140         *app_count = i;
1141         return err;
1142 }
1143 
1144 static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
1145 {
1146         struct fw_port_cmd pcmd;
1147         struct port_info *pi = netdev2pinfo(dev);
1148         struct adapter *adap = pi->adapter;
1149         int i, err = 0;
1150 
1151         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1152                 return 1;
1153 
1154         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1155                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1156                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1157                 pcmd.u.dcb.app_priority.idx = i;
1158                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1159 
1160                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1161                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1162                                 -err);
1163                         return err;
1164                 }
1165 
1166                 /* find first empty slot */
1167                 if (!pcmd.u.dcb.app_priority.protocolid)
1168                         break;
1169 
1170                 table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1);
1171                 table[i].protocol =
1172                         be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
1173                 table[i].priority =
1174                         ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
1175         }
1176         return err;
1177 }
1178 
1179 /* Return Priority Group information.
1180  */
1181 static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
1182 {
1183         struct fw_port_cmd pcmd;
1184         struct port_info *pi = netdev2pinfo(dev);
1185         struct adapter *adap = pi->adapter;
1186         u32 pgid;
1187         int i, err;
1188 
1189         /* We're always "willing" -- the Switch Fabric always dictates the
1190          * DCBX parameters to us.
1191          */
1192         pg->willing = true;
1193 
1194         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1195         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
1196         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1197         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1198                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
1199                 return err;
1200         }
1201         pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
1202 
1203         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1204                 pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
1205 
1206         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1207         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
1208         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1209         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1210                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
1211                         -err);
1212                 return err;
1213         }
1214 
1215         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1216                 pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1217 
1218         pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported;
1219 
1220         return 0;
1221 }
1222 
1223 /* Return Priority Flow Control information.
1224  */
1225 static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1226 {
1227         struct port_info *pi = netdev2pinfo(dev);
1228 
1229         cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1230 
1231         /* Firmware sends this to us in a formwat that is a bit flipped version
1232          * of spec, correct it before we send it to host. This is taken care of
1233          * by bit shifting in other uses of pfcen
1234          */
1235         pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
1236 
1237         pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported;
1238 
1239         return 0;
1240 }
1241 
1242 const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1243         .ieee_getets            = cxgb4_ieee_get_ets,
1244         .ieee_getpfc            = cxgb4_ieee_get_pfc,
1245         .ieee_getapp            = cxgb4_ieee_getapp,
1246         .ieee_setapp            = cxgb4_ieee_setapp,
1247         .ieee_peer_getets       = cxgb4_ieee_peer_ets,
1248         .ieee_peer_getpfc       = cxgb4_ieee_get_pfc,
1249 
1250         /* CEE std */
1251         .getstate               = cxgb4_getstate,
1252         .setstate               = cxgb4_setstate,
1253         .getpgtccfgtx           = cxgb4_getpgtccfg_tx,
1254         .getpgbwgcfgtx          = cxgb4_getpgbwgcfg_tx,
1255         .getpgtccfgrx           = cxgb4_getpgtccfg_rx,
1256         .getpgbwgcfgrx          = cxgb4_getpgbwgcfg_rx,
1257         .setpgtccfgtx           = cxgb4_setpgtccfg_tx,
1258         .setpgbwgcfgtx          = cxgb4_setpgbwgcfg_tx,
1259         .setpfccfg              = cxgb4_setpfccfg,
1260         .getpfccfg              = cxgb4_getpfccfg,
1261         .setall                 = cxgb4_setall,
1262         .getcap                 = cxgb4_getcap,
1263         .getnumtcs              = cxgb4_getnumtcs,
1264         .setnumtcs              = cxgb4_setnumtcs,
1265         .getpfcstate            = cxgb4_getpfcstate,
1266         .setpfcstate            = cxgb4_setpfcstate,
1267         .getapp                 = cxgb4_getapp,
1268         .setapp                 = cxgb4_setapp,
1269 
1270         /* DCBX configuration */
1271         .getdcbx                = cxgb4_getdcbx,
1272         .setdcbx                = cxgb4_setdcbx,
1273 
1274         /* peer apps */
1275         .peer_getappinfo        = cxgb4_getpeer_app,
1276         .peer_getapptable       = cxgb4_getpeerapp_tbl,
1277 
1278         /* CEE peer */
1279         .cee_peer_getpg         = cxgb4_cee_peer_getpg,
1280         .cee_peer_getpfc        = cxgb4_cee_peer_getpfc,
1281 };

/* [<][>][^][v][top][bottom][index][help] */