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