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