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