1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * This file is part of the Chelsio T4 support code. 14 * 15 * Copyright (C) 2010-2013 Chelsio Communications. All rights reserved. 16 * 17 * This program is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this 20 * release for licensing terms and conditions. 21 */ 22 23 /* 24 * Copyright 2020 RackTop Systems, Inc. 25 * Copyright 2023 Oxide Computer Company 26 */ 27 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/dlpi.h> 31 #include <sys/mac_provider.h> 32 #include <sys/mac_ether.h> 33 #include <sys/strsubr.h> 34 #include <sys/queue.h> 35 36 #include "common/common.h" 37 #include "common/t4_regs.h" 38 39 static int t4_mc_getstat(void *arg, uint_t stat, uint64_t *val); 40 static int t4_mc_start(void *arg); 41 static void t4_mc_stop(void *arg); 42 static int t4_mc_setpromisc(void *arg, boolean_t on); 43 static int t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr); 44 static int t4_mc_unicst(void *arg, const uint8_t *ucaddr); 45 static boolean_t t4_mc_getcapab(void *arg, mac_capab_t cap, void *data); 46 static int t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, 47 uint_t size, const void *val); 48 static int t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, 49 uint_t size, void *val); 50 static void t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id, 51 mac_prop_info_handle_t ph); 52 53 static int t4_init_synchronized(struct port_info *pi); 54 static int t4_uninit_synchronized(struct port_info *pi); 55 static void propinfo(struct port_info *pi, const char *name, 56 mac_prop_info_handle_t ph); 57 static int getprop(struct port_info *pi, const char *name, uint_t size, 58 void *val); 59 static int setprop(struct port_info *pi, const char *name, const void *val); 60 61 mac_callbacks_t t4_m_callbacks = { 62 .mc_callbacks = MC_GETCAPAB | MC_PROPERTIES, 63 .mc_getstat = t4_mc_getstat, 64 .mc_start = t4_mc_start, 65 .mc_stop = t4_mc_stop, 66 .mc_setpromisc = t4_mc_setpromisc, 67 .mc_multicst = t4_mc_multicst, 68 .mc_unicst = t4_mc_unicst, 69 .mc_tx = t4_mc_tx, 70 .mc_getcapab = t4_mc_getcapab, 71 .mc_setprop = t4_mc_setprop, 72 .mc_getprop = t4_mc_getprop, 73 .mc_propinfo = t4_mc_propinfo, 74 }; 75 76 mac_callbacks_t t4_m_ring_callbacks = { 77 .mc_callbacks = MC_GETCAPAB | MC_PROPERTIES, 78 .mc_getstat = t4_mc_getstat, 79 .mc_start = t4_mc_start, 80 .mc_stop = t4_mc_stop, 81 .mc_setpromisc = t4_mc_setpromisc, 82 .mc_multicst = t4_mc_multicst, 83 .mc_unicst = NULL, /* t4_addmac */ 84 .mc_tx = NULL, /* t4_eth_tx */ 85 .mc_getcapab = t4_mc_getcapab, 86 .mc_setprop = t4_mc_setprop, 87 .mc_getprop = t4_mc_getprop, 88 .mc_propinfo = t4_mc_propinfo, 89 }; 90 91 #define T4PROP_TMR_IDX "_holdoff_timer_idx" 92 #define T4PROP_PKTC_IDX "_holdoff_pktc_idx" 93 #define T4PROP_MTU "_mtu" 94 #define T4PROP_HW_CSUM "_hw_csum" 95 #define T4PROP_HW_LSO "_hw_lso" 96 #define T4PROP_TX_PAUSE "_tx_pause" 97 #define T4PROP_RX_PAUSE "_rx_pause" 98 99 char *t4_priv_props[] = { 100 T4PROP_TMR_IDX, 101 T4PROP_PKTC_IDX, 102 #if MAC_VERSION == 1 103 /* MAC_VERSION 1 doesn't seem to use MAC_PROP_MTU, hmmmm */ 104 T4PROP_MTU, 105 #endif 106 T4PROP_HW_CSUM, 107 T4PROP_HW_LSO, 108 T4PROP_TX_PAUSE, 109 T4PROP_RX_PAUSE, 110 NULL 111 }; 112 113 /* 114 * To determine the actual Ethernet mode that we're in we need to look at the 115 * port type. That will tell us whether we're using a BASE-T PHY, have an 116 * external SFP connection whose module type we also need to use to qualify 117 * this, and then the link speed itself. Combining that tuple we can then get 118 * the current media. 119 * 120 * Our tables below assume we have gotten it down so the last thing we need to 121 * consider is a single speed. If port types end up supporting the same class of 122 * transceiver at a given speed, then this will need to be changed to use 123 * additional information to disambiguate that (which will require additional 124 * logic from the firmware). 125 */ 126 typedef struct { 127 fw_port_cap32_t tmm_speed; 128 mac_ether_media_t tmm_ether; 129 } t4nex_media_map_t; 130 131 static const t4nex_media_map_t t4nex_map_baset[] = { 132 /* 133 * We're assuming that the 100 Mb/s mode is 100BASE-TX. It's hard to say 134 * for certain what the phy would have done, but given the rest of the 135 * market, that seems the most likely one. 136 */ 137 { FW_PORT_CAP32_SPEED_100M, ETHER_MEDIA_100BASE_TX }, 138 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_T }, 139 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_T } 140 }; 141 142 static const t4nex_media_map_t t4nex_map_kx[] = { 143 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX }, 144 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KX4 } 145 }; 146 147 static const t4nex_media_map_t t4nex_map_cx[] = { 148 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CX4 } 149 }; 150 151 static const t4nex_media_map_t t4nex_map_kr[] = { 152 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX }, 153 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KR }, 154 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_KR }, 155 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_KR4 }, 156 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_KR2 }, 157 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_KR4 }, 158 }; 159 160 static const t4nex_media_map_t t4nex_map_lr[] = { 161 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_LX }, 162 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LR }, 163 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_LR }, 164 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_LR4 }, 165 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_LR2 }, 166 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_LR4 }, 167 }; 168 169 static const t4nex_media_map_t t4nex_map_sr[] = { 170 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_SX }, 171 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_SR }, 172 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_SR }, 173 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_SR4 }, 174 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_SR2 }, 175 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_SR4 }, 176 }; 177 178 static const t4nex_media_map_t t4nex_map_er[] = { 179 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ER }, 180 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ER }, 181 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ER4 }, 182 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ER4 }, 183 }; 184 185 static const t4nex_media_map_t t4nex_map_cr[] = { 186 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX }, 187 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CR }, 188 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_CR }, 189 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_CR4 }, 190 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_CR2 }, 191 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_CR4 }, 192 }; 193 194 static const t4nex_media_map_t t4nex_map_acc[] = { 195 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX }, 196 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ACC }, 197 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ACC }, 198 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ACC4 }, 199 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_ACC2 }, 200 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ACC4 }, 201 }; 202 203 static const t4nex_media_map_t t4nex_map_lrm[] = { 204 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LRM }, 205 }; 206 207 static mac_ether_media_t 208 t4_port_to_media(struct port_info *pi) 209 { 210 fw_port_cap32_t speed; 211 struct link_config *lc = &pi->link_cfg; 212 const t4nex_media_map_t *map = NULL; 213 size_t count = 0; 214 215 if (lc->link_ok != 0) { 216 speed = t4_link_fwcap_to_fwspeed(lc->link_caps); 217 } else { 218 return (ETHER_MEDIA_UNKNOWN); 219 } 220 221 switch (pi->port_type) { 222 case FW_PORT_TYPE_FIBER_XFI: 223 case FW_PORT_TYPE_FIBER_XAUI: 224 case FW_PORT_TYPE_SFP: 225 case FW_PORT_TYPE_QSFP_10G: 226 case FW_PORT_TYPE_QSA: 227 case FW_PORT_TYPE_QSFP: 228 case FW_PORT_TYPE_CR4_QSFP: 229 case FW_PORT_TYPE_CR_QSFP: 230 case FW_PORT_TYPE_CR2_QSFP: 231 case FW_PORT_TYPE_SFP28: 232 switch (pi->mod_type) { 233 case FW_PORT_MOD_TYPE_LR: 234 map = t4nex_map_lr; 235 count = ARRAY_SIZE(t4nex_map_lr); 236 break; 237 case FW_PORT_MOD_TYPE_SR: 238 map = t4nex_map_sr; 239 count = ARRAY_SIZE(t4nex_map_sr); 240 break; 241 case FW_PORT_MOD_TYPE_ER: 242 map = t4nex_map_er; 243 count = ARRAY_SIZE(t4nex_map_er); 244 break; 245 case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: 246 map = t4nex_map_cr; 247 count = ARRAY_SIZE(t4nex_map_cr); 248 break; 249 case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: 250 map = t4nex_map_acc; 251 count = ARRAY_SIZE(t4nex_map_acc); 252 break; 253 case FW_PORT_MOD_TYPE_LRM: 254 map = t4nex_map_lrm; 255 count = ARRAY_SIZE(t4nex_map_lrm); 256 break; 257 case FW_PORT_MOD_TYPE_ERROR: 258 case FW_PORT_MOD_TYPE_UNKNOWN: 259 case FW_PORT_MOD_TYPE_NOTSUPPORTED: 260 case FW_PORT_MOD_TYPE_NONE: 261 case FW_PORT_MOD_TYPE_NA: 262 default: 263 break; 264 } 265 break; 266 case FW_PORT_TYPE_KX4: 267 case FW_PORT_TYPE_KX: 268 map = t4nex_map_kx; 269 count = ARRAY_SIZE(t4nex_map_kx); 270 break; 271 case FW_PORT_TYPE_CX4: 272 map = t4nex_map_cx; 273 count = ARRAY_SIZE(t4nex_map_cx); 274 break; 275 case FW_PORT_TYPE_KR: 276 case FW_PORT_TYPE_BP_AP: 277 case FW_PORT_TYPE_BP4_AP: 278 case FW_PORT_TYPE_BP40_BA: 279 case FW_PORT_TYPE_KR4_100G: 280 case FW_PORT_TYPE_KR_SFP28: 281 case FW_PORT_TYPE_KR_XLAUI: 282 map = t4nex_map_kr; 283 count = ARRAY_SIZE(t4nex_map_kr); 284 break; 285 case FW_PORT_TYPE_BT_SGMII: 286 case FW_PORT_TYPE_BT_XFI: 287 case FW_PORT_TYPE_BT_XAUI: 288 map = t4nex_map_baset; 289 count = ARRAY_SIZE(t4nex_map_baset); 290 break; 291 case FW_PORT_TYPE_NONE: 292 default: 293 break; 294 } 295 296 for (size_t i = 0; i < count; i++) { 297 if (map[i].tmm_speed == speed) { 298 return (map[i].tmm_ether); 299 } 300 } 301 302 /* 303 * At this point we return unknown as we already checked for a down link 304 * earlier. 305 */ 306 return (ETHER_MEDIA_UNKNOWN); 307 } 308 309 static int 310 t4_mc_getstat(void *arg, uint_t stat, uint64_t *val) 311 { 312 struct port_info *pi = arg; 313 struct adapter *sc = pi->adapter; 314 struct link_config *lc = &pi->link_cfg; 315 316 #define GET_STAT(name) \ 317 t4_read_reg64(sc, PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_##name##_L)) 318 319 switch (stat) { 320 case MAC_STAT_IFSPEED: 321 if (lc->link_ok != 0) { 322 *val = t4_link_fwcap_to_speed(lc->link_caps); 323 *val *= 1000000; 324 } else 325 *val = 0; 326 break; 327 328 case MAC_STAT_MULTIRCV: 329 *val = GET_STAT(RX_PORT_MCAST); 330 break; 331 332 case MAC_STAT_BRDCSTRCV: 333 *val = GET_STAT(RX_PORT_BCAST); 334 break; 335 336 case MAC_STAT_MULTIXMT: 337 *val = GET_STAT(TX_PORT_MCAST); 338 break; 339 340 case MAC_STAT_BRDCSTXMT: 341 *val = GET_STAT(TX_PORT_BCAST); 342 break; 343 344 case MAC_STAT_NORCVBUF: 345 *val = 0; /* TODO should come from rxq->nomem */ 346 break; 347 348 case MAC_STAT_IERRORS: 349 *val = GET_STAT(RX_PORT_MTU_ERROR) + 350 GET_STAT(RX_PORT_MTU_CRC_ERROR) + 351 GET_STAT(RX_PORT_CRC_ERROR) + 352 GET_STAT(RX_PORT_LEN_ERROR) + 353 GET_STAT(RX_PORT_SYM_ERROR) + 354 GET_STAT(RX_PORT_LESS_64B); 355 break; 356 357 case MAC_STAT_UNKNOWNS: 358 return (ENOTSUP); 359 360 case MAC_STAT_NOXMTBUF: 361 *val = GET_STAT(TX_PORT_DROP); 362 break; 363 364 case MAC_STAT_OERRORS: 365 *val = GET_STAT(TX_PORT_ERROR); 366 break; 367 368 case MAC_STAT_COLLISIONS: 369 return (ENOTSUP); 370 371 case MAC_STAT_RBYTES: 372 *val = GET_STAT(RX_PORT_BYTES); 373 break; 374 375 case MAC_STAT_IPACKETS: 376 *val = GET_STAT(RX_PORT_FRAMES); 377 break; 378 379 case MAC_STAT_OBYTES: 380 *val = GET_STAT(TX_PORT_BYTES); 381 break; 382 383 case MAC_STAT_OPACKETS: 384 *val = GET_STAT(TX_PORT_FRAMES); 385 break; 386 387 case ETHER_STAT_ALIGN_ERRORS: 388 return (ENOTSUP); 389 390 case ETHER_STAT_FCS_ERRORS: 391 *val = GET_STAT(RX_PORT_CRC_ERROR); 392 break; 393 394 case ETHER_STAT_FIRST_COLLISIONS: 395 case ETHER_STAT_MULTI_COLLISIONS: 396 case ETHER_STAT_SQE_ERRORS: 397 case ETHER_STAT_DEFER_XMTS: 398 case ETHER_STAT_TX_LATE_COLLISIONS: 399 case ETHER_STAT_EX_COLLISIONS: 400 return (ENOTSUP); 401 402 case ETHER_STAT_MACXMT_ERRORS: 403 *val = GET_STAT(TX_PORT_ERROR); 404 break; 405 406 case ETHER_STAT_CARRIER_ERRORS: 407 return (ENOTSUP); 408 409 case ETHER_STAT_TOOLONG_ERRORS: 410 *val = GET_STAT(RX_PORT_MTU_ERROR); 411 break; 412 413 case ETHER_STAT_MACRCV_ERRORS: 414 *val = GET_STAT(RX_PORT_MTU_ERROR) + 415 GET_STAT(RX_PORT_MTU_CRC_ERROR) + 416 GET_STAT(RX_PORT_CRC_ERROR) + 417 GET_STAT(RX_PORT_LEN_ERROR) + 418 GET_STAT(RX_PORT_SYM_ERROR) + 419 GET_STAT(RX_PORT_LESS_64B); 420 break; 421 422 case ETHER_STAT_XCVR_ADDR: 423 case ETHER_STAT_XCVR_ID: 424 return (ENOTSUP); 425 case ETHER_STAT_XCVR_INUSE: 426 *val = t4_port_to_media(pi); 427 break; 428 429 case ETHER_STAT_CAP_100GFDX: 430 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100G); 431 break; 432 433 case ETHER_STAT_CAP_50GFDX: 434 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_50G); 435 break; 436 437 case ETHER_STAT_CAP_40GFDX: 438 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_40G); 439 break; 440 441 case ETHER_STAT_CAP_25GFDX: 442 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_25G); 443 break; 444 445 case ETHER_STAT_CAP_10GFDX: 446 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_10G); 447 break; 448 449 case ETHER_STAT_CAP_1000FDX: 450 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_1G); 451 break; 452 453 case ETHER_STAT_CAP_100FDX: 454 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100M); 455 break; 456 457 case ETHER_STAT_CAP_1000HDX: 458 case ETHER_STAT_CAP_100HDX: 459 case ETHER_STAT_CAP_10FDX: 460 case ETHER_STAT_CAP_10HDX: 461 return (ENOTSUP); 462 463 case ETHER_STAT_CAP_ASMPAUSE: 464 *val = !!(lc->pcaps & FW_PORT_CAP32_FC_RX); 465 break; 466 467 case ETHER_STAT_CAP_PAUSE: 468 *val = !!(lc->pcaps & FW_PORT_CAP32_FC_TX); 469 break; 470 471 case ETHER_STAT_CAP_AUTONEG: 472 *val = !!(lc->pcaps & FW_PORT_CAP32_ANEG); 473 break; 474 475 /* 476 * We have set flow control configuration based on tx_pause and rx_pause 477 * values supported through ndd. Now, we need to translate the settings 478 * we have in link_config structure to adv_cap_asmpause and 479 * adv_cap_pause. 480 * 481 * There are 4 combinations possible and the translation is as below: 482 * tx_pause = 0 => We don't send pause frames during Rx congestion 483 * tx_pause = 1 => We send pause frames during Rx congestion 484 * rx_pause = 0 => We ignore received pause frames 485 * rx_pause = 1 => We pause transmission when we receive pause frames 486 * 487 * +----------------------------+----------------------------------+ 488 * | tx_pause | rx_pause | adv_cap_asmpause | adv_cap_pause | 489 * +-------------------------+-------------------------------------+ 490 * | 0 | 0 | 0 | 0 | 491 * | 0 | 1 | 1 | 0 | 492 * | 1 | 0 | 1 | 1 | 493 * | 1 | 1 | 0 | 1 | 494 * +----------------------------+----------------------------------+ 495 */ 496 497 /* Advertised asymmetric pause capability */ 498 case ETHER_STAT_ADV_CAP_ASMPAUSE: 499 if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR) 500 *val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_ASM_DIR); 501 else 502 *val = (!!(lc->admin_caps & FW_PORT_CAP32_FC_TX)) ^ 503 (!!(lc->admin_caps & FW_PORT_CAP32_FC_RX)); 504 break; 505 506 /* Advertised pause capability */ 507 case ETHER_STAT_ADV_CAP_PAUSE: 508 if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE) 509 *val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_PAUSE); 510 else 511 *val = !!(lc->admin_caps & FW_PORT_CAP32_FC_TX); 512 break; 513 514 case ETHER_STAT_ADV_CAP_100GFDX: 515 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100G); 516 break; 517 518 case ETHER_STAT_ADV_CAP_50GFDX: 519 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_50G); 520 break; 521 522 case ETHER_STAT_ADV_CAP_40GFDX: 523 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_40G); 524 break; 525 526 case ETHER_STAT_ADV_CAP_25GFDX: 527 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_25G); 528 break; 529 530 case ETHER_STAT_ADV_CAP_10GFDX: 531 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_10G); 532 break; 533 534 case ETHER_STAT_ADV_CAP_1000FDX: 535 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_1G); 536 break; 537 538 case ETHER_STAT_ADV_CAP_100FDX: 539 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100M); 540 break; 541 542 case ETHER_STAT_ADV_CAP_AUTONEG: 543 *val = !!(lc->admin_caps & FW_PORT_CAP32_ANEG); 544 break; 545 546 case ETHER_STAT_ADV_CAP_1000HDX: 547 case ETHER_STAT_ADV_CAP_100HDX: 548 case ETHER_STAT_ADV_CAP_10FDX: 549 case ETHER_STAT_ADV_CAP_10HDX: 550 return (ENOTSUP); /* TODO */ 551 552 case ETHER_STAT_LP_CAP_ASMPAUSE: 553 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 554 return (ENOTSUP); 555 556 if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR) 557 *val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_ASM_DIR); 558 else 559 *val = (!!(lc->lpacaps & FW_PORT_CAP32_FC_TX)) ^ 560 (!!(lc->lpacaps & FW_PORT_CAP32_FC_RX)); 561 break; 562 563 case ETHER_STAT_LP_CAP_PAUSE: 564 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 565 return (ENOTSUP); 566 567 if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE) 568 *val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_PAUSE); 569 else 570 *val = !!(lc->lpacaps & FW_PORT_CAP32_FC_TX); 571 break; 572 573 case ETHER_STAT_LP_CAP_100GFDX: 574 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 575 return (ENOTSUP); 576 577 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100G); 578 break; 579 580 case ETHER_STAT_LP_CAP_50GFDX: 581 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 582 return (ENOTSUP); 583 584 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_50G); 585 break; 586 587 case ETHER_STAT_LP_CAP_40GFDX: 588 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 589 return (ENOTSUP); 590 591 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_40G); 592 break; 593 594 case ETHER_STAT_LP_CAP_25GFDX: 595 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 596 return (ENOTSUP); 597 598 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_25G); 599 break; 600 601 case ETHER_STAT_LP_CAP_10GFDX: 602 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 603 return (ENOTSUP); 604 605 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_10G); 606 break; 607 608 case ETHER_STAT_LP_CAP_1000FDX: 609 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 610 return (ENOTSUP); 611 612 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_1G); 613 break; 614 615 case ETHER_STAT_LP_CAP_100FDX: 616 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 617 return (ENOTSUP); 618 619 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100M); 620 break; 621 622 case ETHER_STAT_LP_CAP_AUTONEG: 623 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 624 return (ENOTSUP); 625 626 *val = !!(lc->lpacaps & FW_PORT_CAP32_ANEG); 627 break; 628 629 case ETHER_STAT_LP_CAP_1000HDX: 630 case ETHER_STAT_LP_CAP_100HDX: 631 case ETHER_STAT_LP_CAP_10FDX: 632 case ETHER_STAT_LP_CAP_10HDX: 633 return (ENOTSUP); 634 635 case ETHER_STAT_LINK_ASMPAUSE: 636 *val = (!!(lc->link_caps & FW_PORT_CAP32_FC_TX)) ^ 637 (!!(lc->link_caps & FW_PORT_CAP32_FC_RX)); 638 break; 639 640 case ETHER_STAT_LINK_PAUSE: 641 *val = !!(lc->link_caps & FW_PORT_CAP32_FC_TX); 642 break; 643 644 case ETHER_STAT_LINK_AUTONEG: 645 *val = !!(lc->link_caps & FW_PORT_CAP32_ANEG); 646 break; 647 648 case ETHER_STAT_LINK_DUPLEX: 649 if (lc->link_ok != 0) 650 *val = LINK_DUPLEX_FULL; 651 else 652 *val = LINK_DUPLEX_UNKNOWN; 653 break; 654 655 default: 656 return (ENOTSUP); 657 } 658 #undef GET_STAT 659 660 return (0); 661 } 662 663 static int 664 t4_mc_start(void *arg) 665 { 666 struct port_info *pi = arg; 667 int rc; 668 669 rc = begin_synchronized_op(pi, 0, 1); 670 if (rc != 0) 671 return (rc); 672 rc = t4_init_synchronized(pi); 673 end_synchronized_op(pi, 0); 674 675 return (rc); 676 } 677 678 static void 679 t4_mc_stop(void *arg) 680 { 681 struct port_info *pi = arg; 682 683 while (begin_synchronized_op(pi, 0, 1) != 0) 684 continue; 685 (void) t4_uninit_synchronized(pi); 686 end_synchronized_op(pi, 0); 687 } 688 689 static int 690 t4_mc_setpromisc(void *arg, boolean_t on) 691 { 692 struct port_info *pi = arg; 693 struct adapter *sc = pi->adapter; 694 int rc; 695 696 rc = begin_synchronized_op(pi, 1, 1); 697 if (rc != 0) 698 return (rc); 699 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, -1, on ? 1 : 0, -1, -1, -1, 700 false); 701 end_synchronized_op(pi, 1); 702 703 return (rc); 704 } 705 706 /* 707 * TODO: Starts failing as soon as the 336 entry table fills up. Need to use 708 * hash in that case. 709 */ 710 static int 711 t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr) 712 { 713 struct port_info *pi = arg; 714 struct adapter *sc = pi->adapter; 715 struct fw_vi_mac_cmd c; 716 int len16, rc; 717 718 len16 = howmany(sizeof (c.op_to_viid) + sizeof (c.freemacs_to_len16) + 719 sizeof (c.u.exact[0]), 16); 720 c.op_to_viid = htonl(V_FW_CMD_OP(FW_VI_MAC_CMD) | F_FW_CMD_REQUEST | 721 F_FW_CMD_WRITE | V_FW_VI_MAC_CMD_VIID(pi->viid)); 722 c.freemacs_to_len16 = htonl(V_FW_CMD_LEN16(len16)); 723 c.u.exact[0].valid_to_idx = htons(F_FW_VI_MAC_CMD_VALID | 724 V_FW_VI_MAC_CMD_IDX(add ? FW_VI_MAC_ADD_MAC : 725 FW_VI_MAC_MAC_BASED_FREE)); 726 bcopy(mcaddr, &c.u.exact[0].macaddr, ETHERADDRL); 727 728 rc = begin_synchronized_op(pi, 1, 1); 729 if (rc != 0) 730 return (rc); 731 rc = -t4_wr_mbox_meat(sc, sc->mbox, &c, len16 * 16, &c, true); 732 end_synchronized_op(pi, 1); 733 if (rc != 0) 734 return (rc); 735 #ifdef DEBUG 736 /* 737 * TODO: Firmware doesn't seem to return the correct index on removal 738 * (it gives back 0x3fd FW_VI_MAC_MAC_BASED_FREE unchanged. Remove this 739 * code once it is fixed. 740 */ 741 else { 742 uint16_t idx; 743 744 idx = G_FW_VI_MAC_CMD_IDX(ntohs(c.u.exact[0].valid_to_idx)); 745 cxgb_printf(pi->dip, CE_NOTE, 746 "%02x:%02x:%02x:%02x:%02x:%02x %s %d", mcaddr[0], 747 mcaddr[1], mcaddr[2], mcaddr[3], mcaddr[4], mcaddr[5], 748 add ? "added at index" : "removed from index", idx); 749 } 750 #endif 751 752 return (0); 753 } 754 755 int 756 t4_mc_unicst(void *arg, const uint8_t *ucaddr) 757 { 758 struct port_info *pi = arg; 759 struct adapter *sc = pi->adapter; 760 int rc; 761 762 if (ucaddr == NULL) 763 return (EINVAL); 764 765 rc = begin_synchronized_op(pi, 1, 1); 766 if (rc != 0) 767 return (rc); 768 769 /* We will support adding only one mac address */ 770 if (pi->adapter->props.multi_rings && pi->macaddr_cnt) { 771 end_synchronized_op(pi, 1); 772 return (ENOSPC); 773 } 774 rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt, ucaddr, 775 true, &pi->smt_idx); 776 if (rc < 0) { 777 rc = -rc; 778 } else { 779 pi->macaddr_cnt++; 780 pi->xact_addr_filt = rc; 781 rc = 0; 782 } 783 end_synchronized_op(pi, 1); 784 785 return (rc); 786 } 787 788 int 789 t4_addmac(void *arg, const uint8_t *ucaddr) 790 { 791 return (t4_mc_unicst(arg, ucaddr)); 792 } 793 794 static int 795 t4_remmac(void *arg, const uint8_t *mac_addr) 796 { 797 struct port_info *pi = arg; 798 int rc; 799 800 rc = begin_synchronized_op(pi, 1, 1); 801 if (rc != 0) 802 return (rc); 803 804 pi->macaddr_cnt--; 805 end_synchronized_op(pi, 1); 806 807 return (0); 808 } 809 810 /* 811 * Callback funtion for MAC layer to register all groups. 812 */ 813 void 814 t4_fill_group(void *arg, mac_ring_type_t rtype, const int rg_index, 815 mac_group_info_t *infop, mac_group_handle_t gh) 816 { 817 struct port_info *pi = arg; 818 819 switch (rtype) { 820 case MAC_RING_TYPE_RX: { 821 infop->mgi_driver = (mac_group_driver_t)arg; 822 infop->mgi_start = NULL; 823 infop->mgi_stop = NULL; 824 infop->mgi_addmac = t4_addmac; 825 infop->mgi_remmac = t4_remmac; 826 infop->mgi_count = pi->nrxq; 827 break; 828 } 829 case MAC_RING_TYPE_TX: 830 default: 831 ASSERT(0); 832 break; 833 } 834 } 835 836 static int 837 t4_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num) 838 { 839 struct sge_rxq *rxq = (struct sge_rxq *)rh; 840 841 RXQ_LOCK(rxq); 842 rxq->ring_gen_num = mr_gen_num; 843 RXQ_UNLOCK(rxq); 844 return (0); 845 } 846 847 /* 848 * Enable interrupt on the specificed rx ring. 849 */ 850 int 851 t4_ring_intr_enable(mac_intr_handle_t intrh) 852 { 853 struct sge_rxq *rxq = (struct sge_rxq *)intrh; 854 struct adapter *sc = rxq->port->adapter; 855 struct sge_iq *iq; 856 857 iq = &rxq->iq; 858 RXQ_LOCK(rxq); 859 iq->polling = 0; 860 iq->state = IQS_IDLE; 861 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), 862 V_SEINTARM(iq->intr_params) | V_INGRESSQID(iq->cntxt_id)); 863 RXQ_UNLOCK(rxq); 864 return (0); 865 } 866 867 /* 868 * Disable interrupt on the specificed rx ring. 869 */ 870 int 871 t4_ring_intr_disable(mac_intr_handle_t intrh) 872 { 873 struct sge_rxq *rxq = (struct sge_rxq *)intrh; 874 struct sge_iq *iq; 875 876 /* 877 * Nothing to be done here wrt interrupt, as it will not fire, until we 878 * write back to A_SGE_PF_GTS.SEIntArm in t4_ring_intr_enable. 879 */ 880 881 iq = &rxq->iq; 882 RXQ_LOCK(rxq); 883 iq->polling = 1; 884 iq->state = IQS_BUSY; 885 RXQ_UNLOCK(rxq); 886 887 return (0); 888 } 889 890 mblk_t * 891 t4_poll_ring(void *arg, int n_bytes) 892 { 893 struct sge_rxq *rxq = (struct sge_rxq *)arg; 894 mblk_t *mp = NULL; 895 896 ASSERT(n_bytes >= 0); 897 if (n_bytes == 0) 898 return (NULL); 899 900 RXQ_LOCK(rxq); 901 mp = t4_ring_rx(rxq, n_bytes); 902 RXQ_UNLOCK(rxq); 903 904 return (mp); 905 } 906 907 /* 908 * Retrieve a value for one of the statistics for a particular rx ring 909 */ 910 int 911 t4_rx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 912 { 913 struct sge_rxq *rxq = (struct sge_rxq *)rh; 914 915 switch (stat) { 916 case MAC_STAT_RBYTES: 917 *val = rxq->rxbytes; 918 break; 919 920 case MAC_STAT_IPACKETS: 921 *val = rxq->rxpkts; 922 break; 923 924 default: 925 *val = 0; 926 return (ENOTSUP); 927 } 928 929 return (0); 930 } 931 932 /* 933 * Retrieve a value for one of the statistics for a particular tx ring 934 */ 935 int 936 t4_tx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 937 { 938 struct sge_txq *txq = (struct sge_txq *)rh; 939 940 switch (stat) { 941 case MAC_STAT_RBYTES: 942 *val = txq->txbytes; 943 break; 944 945 case MAC_STAT_IPACKETS: 946 *val = txq->txpkts; 947 break; 948 949 default: 950 *val = 0; 951 return (ENOTSUP); 952 } 953 954 return (0); 955 } 956 957 /* 958 * Callback funtion for MAC layer to register all rings 959 * for given ring_group, noted by group_index. 960 * Since we have only one group, ring index becomes 961 * absolute index. 962 */ 963 void 964 t4_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index, 965 const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 966 { 967 struct port_info *pi = arg; 968 mac_intr_t *mintr; 969 970 switch (rtype) { 971 case MAC_RING_TYPE_RX: { 972 struct sge_rxq *rxq; 973 974 rxq = &pi->adapter->sge.rxq[pi->first_rxq + ring_index]; 975 rxq->ring_handle = rh; 976 977 infop->mri_driver = (mac_ring_driver_t)rxq; 978 infop->mri_start = t4_ring_start; 979 infop->mri_stop = NULL; 980 infop->mri_poll = t4_poll_ring; 981 infop->mri_stat = t4_rx_stat; 982 983 mintr = &infop->mri_intr; 984 mintr->mi_handle = (mac_intr_handle_t)rxq; 985 mintr->mi_enable = t4_ring_intr_enable; 986 mintr->mi_disable = t4_ring_intr_disable; 987 988 break; 989 } 990 case MAC_RING_TYPE_TX: { 991 struct sge_txq *txq = 992 &pi->adapter->sge.txq[pi->first_txq + ring_index]; 993 txq->ring_handle = rh; 994 infop->mri_driver = (mac_ring_driver_t)txq; 995 infop->mri_start = NULL; 996 infop->mri_stop = NULL; 997 infop->mri_tx = t4_eth_tx; 998 infop->mri_stat = t4_tx_stat; 999 break; 1000 } 1001 default: 1002 ASSERT(0); 1003 break; 1004 } 1005 } 1006 1007 mblk_t * 1008 t4_mc_tx(void *arg, mblk_t *m) 1009 { 1010 struct port_info *pi = arg; 1011 struct adapter *sc = pi->adapter; 1012 struct sge_txq *txq = &sc->sge.txq[pi->first_txq]; 1013 1014 return (t4_eth_tx(txq, m)); 1015 } 1016 1017 static int 1018 t4_mc_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) 1019 { 1020 struct port_info *pi = arg; 1021 1022 if (id != 0 || infop == NULL) 1023 return (EINVAL); 1024 1025 switch (pi->mod_type) { 1026 case FW_PORT_MOD_TYPE_NONE: 1027 mac_transceiver_info_set_present(infop, B_FALSE); 1028 break; 1029 case FW_PORT_MOD_TYPE_NOTSUPPORTED: 1030 mac_transceiver_info_set_present(infop, B_TRUE); 1031 mac_transceiver_info_set_usable(infop, B_FALSE); 1032 break; 1033 default: 1034 mac_transceiver_info_set_present(infop, B_TRUE); 1035 mac_transceiver_info_set_usable(infop, B_TRUE); 1036 break; 1037 } 1038 1039 return (0); 1040 } 1041 1042 static int 1043 t4_mc_transceiver_read(void *arg, uint_t id, uint_t page, void *bp, 1044 size_t nbytes, off_t offset, size_t *nread) 1045 { 1046 struct port_info *pi = arg; 1047 struct adapter *sc = pi->adapter; 1048 int rc; 1049 size_t i, maxread; 1050 /* LINTED: E_FUNC_VAR_UNUSED */ 1051 struct fw_ldst_cmd ldst __unused; 1052 1053 if (id != 0 || bp == NULL || nbytes == 0 || nread == NULL || 1054 (page != 0xa0 && page != 0xa2) || offset < 0) 1055 return (EINVAL); 1056 1057 if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) 1058 return (EINVAL); 1059 1060 rc = begin_synchronized_op(pi, 0, 1); 1061 if (rc != 0) 1062 return (rc); 1063 1064 /* 1065 * Firmware has a maximum size that we can read. Don't read more than it 1066 * allows. 1067 */ 1068 maxread = sizeof (ldst.u.i2c.data); 1069 for (i = 0; i < nbytes; i += maxread) { 1070 size_t toread = MIN(maxread, nbytes - i); 1071 rc = -t4_i2c_rd(sc, sc->mbox, pi->port_id, page, offset, toread, 1072 bp); 1073 if (rc != 0) 1074 break; 1075 offset += toread; 1076 bp = (void *)((uintptr_t)bp + toread); 1077 } 1078 end_synchronized_op(pi, 0); 1079 if (rc == 0) 1080 *nread = nbytes; 1081 return (rc); 1082 } 1083 1084 static int 1085 t4_port_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 1086 { 1087 struct port_info *pi = arg; 1088 struct adapter *sc = pi->adapter; 1089 int val, rc; 1090 1091 if (flags != 0) 1092 return (EINVAL); 1093 1094 switch (mode) { 1095 case MAC_LED_DEFAULT: 1096 val = 0; 1097 break; 1098 case MAC_LED_IDENT: 1099 val = 0xffff; 1100 break; 1101 1102 default: 1103 return (ENOTSUP); 1104 } 1105 1106 rc = begin_synchronized_op(pi, 1, 1); 1107 if (rc != 0) 1108 return (rc); 1109 rc = -t4_identify_port(sc, sc->mbox, pi->viid, val); 1110 end_synchronized_op(pi, 1); 1111 1112 return (rc); 1113 } 1114 1115 static boolean_t 1116 t4_mc_getcapab(void *arg, mac_capab_t cap, void *data) 1117 { 1118 struct port_info *pi = arg; 1119 boolean_t status = B_TRUE; 1120 mac_capab_transceiver_t *mct; 1121 mac_capab_led_t *mcl; 1122 1123 switch (cap) { 1124 case MAC_CAPAB_HCKSUM: 1125 if (pi->features & CXGBE_HW_CSUM) { 1126 uint32_t *d = data; 1127 *d = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM | 1128 HCKSUM_INET_FULL_V6; 1129 } else 1130 status = B_FALSE; 1131 break; 1132 1133 case MAC_CAPAB_LSO: 1134 /* Enabling LSO requires Checksum offloading */ 1135 if (pi->features & CXGBE_HW_LSO && 1136 pi->features & CXGBE_HW_CSUM) { 1137 mac_capab_lso_t *d = data; 1138 1139 d->lso_flags = LSO_TX_BASIC_TCP_IPV4 | 1140 LSO_TX_BASIC_TCP_IPV6; 1141 d->lso_basic_tcp_ipv4.lso_max = 65535; 1142 d->lso_basic_tcp_ipv6.lso_max = 65535; 1143 } else 1144 status = B_FALSE; 1145 break; 1146 1147 case MAC_CAPAB_RINGS: { 1148 mac_capab_rings_t *cap_rings = data; 1149 1150 if (!pi->adapter->props.multi_rings) { 1151 status = B_FALSE; 1152 break; 1153 } 1154 switch (cap_rings->mr_type) { 1155 case MAC_RING_TYPE_RX: 1156 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1157 cap_rings->mr_rnum = pi->nrxq; 1158 cap_rings->mr_gnum = 1; 1159 cap_rings->mr_rget = t4_fill_ring; 1160 cap_rings->mr_gget = t4_fill_group; 1161 cap_rings->mr_gaddring = NULL; 1162 cap_rings->mr_gremring = NULL; 1163 break; 1164 case MAC_RING_TYPE_TX: 1165 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1166 cap_rings->mr_rnum = pi->ntxq; 1167 cap_rings->mr_gnum = 0; 1168 cap_rings->mr_rget = t4_fill_ring; 1169 cap_rings->mr_gget = NULL; 1170 break; 1171 } 1172 break; 1173 } 1174 1175 case MAC_CAPAB_TRANSCEIVER: 1176 mct = data; 1177 1178 mct->mct_flags = 0; 1179 mct->mct_ntransceivers = 1; 1180 mct->mct_info = t4_mc_transceiver_info; 1181 mct->mct_read = t4_mc_transceiver_read; 1182 break; 1183 case MAC_CAPAB_LED: 1184 mcl = data; 1185 mcl->mcl_flags = 0; 1186 mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_IDENT; 1187 mcl->mcl_set = t4_port_led_set; 1188 break; 1189 1190 default: 1191 status = B_FALSE; /* cap not supported */ 1192 } 1193 1194 return (status); 1195 } 1196 1197 static void 1198 t4_mac_link_caps_to_flowctrl(fw_port_cap32_t caps, link_flowctrl_t *fc) 1199 { 1200 u8 pause_tx = 0, pause_rx = 0; 1201 1202 if (caps & FW_PORT_CAP32_FC_TX) 1203 pause_tx = 1; 1204 1205 if (caps & FW_PORT_CAP32_FC_RX) 1206 pause_rx = 1; 1207 1208 if (pause_rx & pause_tx) 1209 *fc = LINK_FLOWCTRL_BI; 1210 else if (pause_tx) 1211 *fc = LINK_FLOWCTRL_TX; 1212 else if (pause_rx) 1213 *fc = LINK_FLOWCTRL_RX; 1214 else 1215 *fc = LINK_FLOWCTRL_NONE; 1216 } 1217 1218 static int 1219 t4_mac_flowctrl_to_link_caps(struct port_info *pi, link_flowctrl_t fc, 1220 fw_port_cap32_t *new_caps) 1221 { 1222 cc_pause_t pause = 0; 1223 1224 switch (fc) { 1225 case LINK_FLOWCTRL_BI: 1226 pause |= PAUSE_TX | PAUSE_RX; 1227 break; 1228 case LINK_FLOWCTRL_TX: 1229 pause |= PAUSE_TX; 1230 break; 1231 case LINK_FLOWCTRL_RX: 1232 pause |= PAUSE_RX; 1233 break; 1234 default: 1235 break; 1236 } 1237 1238 if (pi->link_cfg.admin_caps & FW_PORT_CAP32_ANEG) 1239 pause |= PAUSE_AUTONEG; 1240 1241 return (t4_link_set_pause(pi, pause, new_caps)); 1242 } 1243 1244 static link_fec_t 1245 t4_mac_port_caps_to_fec_cap(fw_port_cap32_t caps) 1246 { 1247 link_fec_t link_fec = 0; 1248 1249 if (caps & FW_PORT_CAP32_FEC_RS) 1250 link_fec |= LINK_FEC_RS; 1251 1252 if (caps & FW_PORT_CAP32_FEC_BASER_RS) 1253 link_fec |= LINK_FEC_BASE_R; 1254 1255 if (caps & FW_PORT_CAP32_FEC_NO_FEC) 1256 link_fec |= LINK_FEC_NONE; 1257 1258 if ((link_fec & (link_fec - 1)) && 1259 !(caps & FW_PORT_CAP32_FORCE_FEC)) 1260 return (LINK_FEC_AUTO); 1261 1262 return (link_fec); 1263 } 1264 1265 static void 1266 t4_mac_admin_caps_to_fec_cap(fw_port_cap32_t caps, link_fec_t *fec) 1267 { 1268 *fec = t4_mac_port_caps_to_fec_cap(caps); 1269 } 1270 1271 static void 1272 t4_mac_link_caps_to_fec_cap(fw_port_cap32_t caps, link_fec_t *fec) 1273 { 1274 link_fec_t link_fec; 1275 1276 caps &= ~FW_PORT_CAP32_FEC_NO_FEC; 1277 link_fec = t4_mac_port_caps_to_fec_cap(caps); 1278 *fec = link_fec ? link_fec : LINK_FEC_NONE; 1279 } 1280 1281 static int 1282 t4_mac_fec_cap_to_link_caps(struct port_info *pi, link_fec_t v, 1283 fw_port_cap32_t *new_caps) 1284 { 1285 cc_fec_t fec = 0; 1286 1287 if (v == LINK_FEC_AUTO) { 1288 fec = FEC_AUTO; 1289 goto out; 1290 } 1291 1292 if (v & LINK_FEC_NONE) { 1293 v &= ~LINK_FEC_NONE; 1294 fec |= FEC_NONE; 1295 } 1296 1297 if (v & LINK_FEC_RS) { 1298 v &= ~LINK_FEC_RS; 1299 fec |= FEC_RS; 1300 } 1301 1302 if (v & LINK_FEC_BASE_R) { 1303 v &= ~LINK_FEC_BASE_R; 1304 fec |= FEC_BASER_RS; 1305 } 1306 1307 if (v != 0) 1308 return (-1); 1309 1310 ASSERT3S(fec, !=, 0); 1311 1312 fec |= FEC_FORCE; 1313 1314 out: 1315 return (t4_link_set_fec(pi, fec, new_caps)); 1316 } 1317 1318 /* ARGSUSED */ 1319 static int 1320 t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size, 1321 const void *val) 1322 { 1323 struct port_info *pi = arg; 1324 struct adapter *sc = pi->adapter; 1325 struct link_config *lc = &pi->link_cfg; 1326 fw_port_cap32_t new_caps = lc->admin_caps; 1327 int relink = 0, rx_mode = 0, rc = 0; 1328 uint32_t v32 = *(uint32_t *)val; 1329 uint8_t v8 = *(uint8_t *)val; 1330 link_flowctrl_t fc; 1331 link_fec_t fec; 1332 1333 switch (id) { 1334 case MAC_PROP_AUTONEG: 1335 rc = t4_link_set_autoneg(pi, v8, &new_caps); 1336 relink = 1; 1337 break; 1338 1339 case MAC_PROP_MTU: 1340 if (v32 < 46 || v32 > MAX_MTU) { 1341 rc = EINVAL; 1342 } else if (v32 != pi->mtu) { 1343 pi->mtu = v32; 1344 (void) mac_maxsdu_update(pi->mh, v32); 1345 rx_mode = 1; 1346 } 1347 1348 break; 1349 1350 case MAC_PROP_FLOWCTRL: 1351 fc = *(link_flowctrl_t *)val; 1352 rc = t4_mac_flowctrl_to_link_caps(pi, fc, &new_caps); 1353 relink = 1; 1354 break; 1355 1356 case MAC_PROP_EN_FEC_CAP: 1357 fec = *(link_fec_t *)val; 1358 rc = t4_mac_fec_cap_to_link_caps(pi, fec, &new_caps); 1359 relink = 1; 1360 break; 1361 1362 case MAC_PROP_EN_100GFDX_CAP: 1363 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_100G, v8, 1364 &new_caps); 1365 relink = 1; 1366 break; 1367 1368 case MAC_PROP_EN_50GFDX_CAP: 1369 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_50G, v8, 1370 &new_caps); 1371 relink = 1; 1372 break; 1373 1374 case MAC_PROP_EN_40GFDX_CAP: 1375 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_40G, v8, 1376 &new_caps); 1377 relink = 1; 1378 break; 1379 1380 case MAC_PROP_EN_25GFDX_CAP: 1381 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_25G, v8, 1382 &new_caps); 1383 relink = 1; 1384 break; 1385 1386 case MAC_PROP_EN_10GFDX_CAP: 1387 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_10G, v8, 1388 &new_caps); 1389 relink = 1; 1390 break; 1391 1392 case MAC_PROP_EN_1000FDX_CAP: 1393 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_1G, v8, 1394 &new_caps); 1395 relink = 1; 1396 break; 1397 1398 case MAC_PROP_EN_100FDX_CAP: 1399 rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_100M, v8, 1400 &new_caps); 1401 relink = 1; 1402 break; 1403 1404 case MAC_PROP_PRIVATE: 1405 rc = setprop(pi, name, val); 1406 break; 1407 1408 default: 1409 rc = ENOTSUP; 1410 break; 1411 } 1412 1413 if (rc != 0) 1414 return (rc); 1415 1416 if (isset(&sc->open_device_map, pi->port_id) != 0) { 1417 if (relink != 0) { 1418 rc = begin_synchronized_op(pi, 1, 1); 1419 if (rc != 0) 1420 return (rc); 1421 rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc, 1422 new_caps); 1423 end_synchronized_op(pi, 1); 1424 if (rc != 0) { 1425 cxgb_printf(pi->dip, CE_WARN, 1426 "%s link config failed: %d", __func__, rc); 1427 return (rc); 1428 } 1429 } 1430 1431 if (rx_mode != 0) { 1432 rc = begin_synchronized_op(pi, 1, 1); 1433 if (rc != 0) 1434 return (rc); 1435 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v32, -1, 1436 -1, -1, -1, false); 1437 end_synchronized_op(pi, 1); 1438 if (rc != 0) { 1439 cxgb_printf(pi->dip, CE_WARN, 1440 "set_rxmode failed: %d", rc); 1441 return (rc); 1442 } 1443 } 1444 } 1445 1446 if (relink != 0) 1447 lc->admin_caps = new_caps; 1448 1449 return (0); 1450 } 1451 1452 static int 1453 t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t size, 1454 void *val) 1455 { 1456 struct port_info *pi = arg; 1457 struct link_config *lc = &pi->link_cfg; 1458 uint8_t *u = val; 1459 int rc = 0; 1460 1461 switch (id) { 1462 case MAC_PROP_DUPLEX: 1463 *(link_duplex_t *)val = lc->link_ok ? LINK_DUPLEX_FULL : 1464 LINK_DUPLEX_UNKNOWN; 1465 break; 1466 1467 case MAC_PROP_SPEED: 1468 if (lc->link_ok != 0) { 1469 *(uint64_t *)val = 1470 t4_link_fwcap_to_speed(lc->link_caps); 1471 *(uint64_t *)val *= 1000000; 1472 } else { 1473 *(uint64_t *)val = 0; 1474 } 1475 break; 1476 1477 case MAC_PROP_STATUS: 1478 *(link_state_t *)val = lc->link_ok ? LINK_STATE_UP : 1479 LINK_STATE_DOWN; 1480 break; 1481 1482 case MAC_PROP_MEDIA: 1483 *(mac_ether_media_t *)val = t4_port_to_media(pi); 1484 break; 1485 1486 case MAC_PROP_AUTONEG: 1487 *u = !!(lc->link_caps & FW_PORT_CAP32_ANEG); 1488 break; 1489 1490 case MAC_PROP_MTU: 1491 *(uint32_t *)val = pi->mtu; 1492 break; 1493 1494 case MAC_PROP_FLOWCTRL: 1495 t4_mac_link_caps_to_flowctrl(lc->link_caps, val); 1496 break; 1497 1498 case MAC_PROP_ADV_FEC_CAP: 1499 t4_mac_link_caps_to_fec_cap(lc->link_caps, val); 1500 break; 1501 1502 case MAC_PROP_EN_FEC_CAP: 1503 t4_mac_admin_caps_to_fec_cap(lc->admin_caps, val); 1504 break; 1505 1506 case MAC_PROP_ADV_100GFDX_CAP: 1507 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_100G); 1508 break; 1509 1510 case MAC_PROP_EN_100GFDX_CAP: 1511 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100G); 1512 break; 1513 1514 case MAC_PROP_ADV_50GFDX_CAP: 1515 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_50G); 1516 break; 1517 1518 case MAC_PROP_EN_50GFDX_CAP: 1519 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_50G); 1520 break; 1521 1522 case MAC_PROP_ADV_40GFDX_CAP: 1523 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_40G); 1524 break; 1525 1526 case MAC_PROP_EN_40GFDX_CAP: 1527 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_40G); 1528 break; 1529 1530 case MAC_PROP_ADV_25GFDX_CAP: 1531 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_25G); 1532 break; 1533 1534 case MAC_PROP_EN_25GFDX_CAP: 1535 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_25G); 1536 break; 1537 1538 case MAC_PROP_ADV_10GFDX_CAP: 1539 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_10G); 1540 break; 1541 1542 case MAC_PROP_EN_10GFDX_CAP: 1543 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_10G); 1544 break; 1545 1546 case MAC_PROP_ADV_1000FDX_CAP: 1547 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_1G); 1548 break; 1549 1550 case MAC_PROP_EN_1000FDX_CAP: 1551 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_1G); 1552 break; 1553 1554 case MAC_PROP_ADV_100FDX_CAP: 1555 *u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_100M); 1556 break; 1557 1558 case MAC_PROP_EN_100FDX_CAP: 1559 *u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100M); 1560 break; 1561 1562 case MAC_PROP_PRIVATE: 1563 return (getprop(pi, name, size, val)); 1564 1565 default: 1566 return (ENOTSUP); 1567 } 1568 1569 return (rc); 1570 } 1571 1572 static void 1573 t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id, 1574 mac_prop_info_handle_t ph) 1575 { 1576 struct port_info *pi = arg; 1577 struct link_config *lc = &pi->link_cfg; 1578 1579 switch (id) { 1580 case MAC_PROP_DUPLEX: 1581 case MAC_PROP_SPEED: 1582 case MAC_PROP_STATUS: 1583 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1584 break; 1585 1586 case MAC_PROP_AUTONEG: 1587 if (lc->pcaps & FW_PORT_CAP32_ANEG) 1588 mac_prop_info_set_default_uint8(ph, 1); 1589 else 1590 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1591 break; 1592 1593 case MAC_PROP_MTU: 1594 mac_prop_info_set_range_uint32(ph, 46, MAX_MTU); 1595 break; 1596 1597 case MAC_PROP_FLOWCTRL: 1598 mac_prop_info_set_default_link_flowctrl(ph, LINK_FLOWCTRL_BI); 1599 break; 1600 1601 case MAC_PROP_EN_FEC_CAP: 1602 mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO); 1603 break; 1604 1605 case MAC_PROP_ADV_FEC_CAP: 1606 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1607 mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO); 1608 break; 1609 1610 case MAC_PROP_EN_100GFDX_CAP: 1611 if (lc->pcaps & FW_PORT_CAP32_SPEED_100G) 1612 mac_prop_info_set_default_uint8(ph, 1); 1613 else 1614 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1615 break; 1616 1617 case MAC_PROP_EN_50GFDX_CAP: 1618 if (lc->pcaps & FW_PORT_CAP32_SPEED_50G) 1619 mac_prop_info_set_default_uint8(ph, 1); 1620 else 1621 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1622 break; 1623 1624 case MAC_PROP_EN_40GFDX_CAP: 1625 if (lc->pcaps & FW_PORT_CAP32_SPEED_40G) 1626 mac_prop_info_set_default_uint8(ph, 1); 1627 else 1628 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1629 break; 1630 1631 case MAC_PROP_EN_25GFDX_CAP: 1632 if (lc->pcaps & FW_PORT_CAP32_SPEED_25G) 1633 mac_prop_info_set_default_uint8(ph, 1); 1634 else 1635 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1636 break; 1637 1638 case MAC_PROP_EN_10GFDX_CAP: 1639 if (lc->pcaps & FW_PORT_CAP32_SPEED_10G) 1640 mac_prop_info_set_default_uint8(ph, 1); 1641 else 1642 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1643 break; 1644 1645 case MAC_PROP_EN_1000FDX_CAP: 1646 if (lc->pcaps & FW_PORT_CAP32_SPEED_1G) 1647 mac_prop_info_set_default_uint8(ph, 1); 1648 else 1649 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1650 break; 1651 1652 case MAC_PROP_EN_100FDX_CAP: 1653 if (lc->pcaps & FW_PORT_CAP32_SPEED_100M) 1654 mac_prop_info_set_default_uint8(ph, 1); 1655 else 1656 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1657 break; 1658 1659 case MAC_PROP_ADV_100GFDX_CAP: 1660 case MAC_PROP_ADV_50GFDX_CAP: 1661 case MAC_PROP_ADV_40GFDX_CAP: 1662 case MAC_PROP_ADV_25GFDX_CAP: 1663 case MAC_PROP_ADV_10GFDX_CAP: 1664 case MAC_PROP_ADV_1000FDX_CAP: 1665 case MAC_PROP_ADV_100FDX_CAP: 1666 mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ); 1667 break; 1668 1669 case MAC_PROP_PRIVATE: 1670 propinfo(pi, name, ph); 1671 break; 1672 1673 default: 1674 break; 1675 } 1676 } 1677 1678 int 1679 begin_synchronized_op(struct port_info *pi, int hold, int waitok) 1680 { 1681 struct adapter *sc = pi->adapter; 1682 int rc = 0; 1683 1684 ADAPTER_LOCK(sc); 1685 while (!IS_DOOMED(pi) && IS_BUSY(sc)) { 1686 if (!waitok) { 1687 rc = EBUSY; 1688 goto failed; 1689 } else if (cv_wait_sig(&sc->cv, &sc->lock) == 0) { 1690 rc = EINTR; 1691 goto failed; 1692 } 1693 } 1694 if (IS_DOOMED(pi) != 0) { /* shouldn't happen on Solaris */ 1695 rc = ENXIO; 1696 goto failed; 1697 } 1698 ASSERT(!IS_BUSY(sc)); 1699 /* LINTED: E_CONSTANT_CONDITION */ 1700 SET_BUSY(sc); 1701 1702 if (!hold) 1703 ADAPTER_UNLOCK(sc); 1704 1705 return (0); 1706 failed: 1707 ADAPTER_UNLOCK(sc); 1708 return (rc); 1709 } 1710 1711 void 1712 end_synchronized_op(struct port_info *pi, int held) 1713 { 1714 struct adapter *sc = pi->adapter; 1715 1716 if (!held) 1717 ADAPTER_LOCK(sc); 1718 1719 ADAPTER_LOCK_ASSERT_OWNED(sc); 1720 ASSERT(IS_BUSY(sc)); 1721 /* LINTED: E_CONSTANT_CONDITION */ 1722 CLR_BUSY(sc); 1723 cv_signal(&sc->cv); 1724 ADAPTER_UNLOCK(sc); 1725 } 1726 1727 static int 1728 t4_init_synchronized(struct port_info *pi) 1729 { 1730 struct adapter *sc = pi->adapter; 1731 int rc = 0; 1732 1733 ADAPTER_LOCK_ASSERT_NOTOWNED(sc); 1734 1735 if (isset(&sc->open_device_map, pi->port_id) != 0) 1736 return (0); /* already running */ 1737 1738 if (!(sc->flags & FULL_INIT_DONE) && 1739 ((rc = adapter_full_init(sc)) != 0)) 1740 return (rc); /* error message displayed already */ 1741 1742 if (!(pi->flags & PORT_INIT_DONE)) { 1743 rc = port_full_init(pi); 1744 if (rc != 0) 1745 return (rc); /* error message displayed already */ 1746 } else 1747 enable_port_queues(pi); 1748 1749 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, pi->mtu, 0, 0, 1, 0, false); 1750 if (rc != 0) { 1751 cxgb_printf(pi->dip, CE_WARN, "set_rxmode failed: %d", rc); 1752 goto done; 1753 } 1754 rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt, 1755 pi->hw_addr, true, &pi->smt_idx); 1756 if (rc < 0) { 1757 cxgb_printf(pi->dip, CE_WARN, "change_mac failed: %d", rc); 1758 rc = -rc; 1759 goto done; 1760 } else 1761 /* LINTED: E_ASSIGN_NARROW_CONV */ 1762 pi->xact_addr_filt = rc; 1763 1764 rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, &pi->link_cfg, 1765 pi->link_cfg.admin_caps); 1766 if (rc != 0) { 1767 cxgb_printf(pi->dip, CE_WARN, "start_link failed: %d", rc); 1768 goto done; 1769 } 1770 1771 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, true, true); 1772 if (rc != 0) { 1773 cxgb_printf(pi->dip, CE_WARN, "enable_vi failed: %d", rc); 1774 goto done; 1775 } 1776 1777 /* all ok */ 1778 setbit(&sc->open_device_map, pi->port_id); 1779 done: 1780 if (rc != 0) 1781 (void) t4_uninit_synchronized(pi); 1782 1783 return (rc); 1784 } 1785 1786 /* 1787 * Idempotent. 1788 */ 1789 static int 1790 t4_uninit_synchronized(struct port_info *pi) 1791 { 1792 struct adapter *sc = pi->adapter; 1793 int rc; 1794 1795 ADAPTER_LOCK_ASSERT_NOTOWNED(sc); 1796 1797 /* 1798 * Disable the VI so that all its data in either direction is discarded 1799 * by the MPS. Leave everything else (the queues, interrupts, and 1Hz 1800 * tick) intact as the TP can deliver negative advice or data that it's 1801 * holding in its RAM (for an offloaded connection) even after the VI is 1802 * disabled. 1803 */ 1804 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, false, false); 1805 if (rc != 0) { 1806 cxgb_printf(pi->dip, CE_WARN, "disable_vi failed: %d", rc); 1807 return (rc); 1808 } 1809 1810 disable_port_queues(pi); 1811 1812 clrbit(&sc->open_device_map, pi->port_id); 1813 1814 pi->link_cfg.link_ok = 0; 1815 mac_link_update(pi->mh, LINK_STATE_UNKNOWN); 1816 1817 return (0); 1818 } 1819 1820 static void 1821 propinfo(struct port_info *pi, const char *name, mac_prop_info_handle_t ph) 1822 { 1823 struct adapter *sc = pi->adapter; 1824 struct driver_properties *p = &sc->props; 1825 struct link_config *lc = &pi->link_cfg; 1826 int v; 1827 char str[16]; 1828 1829 if (strcmp(name, T4PROP_TMR_IDX) == 0) 1830 v = is_10G_port(pi) ? p->tmr_idx_10g : p->tmr_idx_1g; 1831 else if (strcmp(name, T4PROP_PKTC_IDX) == 0) 1832 v = is_10G_port(pi) ? p->pktc_idx_10g : p->pktc_idx_1g; 1833 else if (strcmp(name, T4PROP_HW_CSUM) == 0) 1834 v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0; 1835 else if (strcmp(name, T4PROP_HW_LSO) == 0) 1836 v = (pi->features & CXGBE_HW_LSO) ? 1 : 0; 1837 else if (strcmp(name, T4PROP_TX_PAUSE) == 0) 1838 v = (lc->pcaps & FW_PORT_CAP32_FC_TX) ? 1 : 0; 1839 else if (strcmp(name, T4PROP_RX_PAUSE) == 0) 1840 v = (lc->pcaps & FW_PORT_CAP32_FC_RX) ? 1 : 0; 1841 #if MAC_VERSION == 1 1842 else if (strcmp(name, T4PROP_MTU) == 0) 1843 v = ETHERMTU; 1844 #endif 1845 else 1846 return; 1847 1848 (void) snprintf(str, sizeof (str), "%d", v); 1849 mac_prop_info_set_default_str(ph, str); 1850 } 1851 1852 static int 1853 getprop(struct port_info *pi, const char *name, uint_t size, void *val) 1854 { 1855 struct link_config *lc = &pi->link_cfg; 1856 int v; 1857 1858 if (strcmp(name, T4PROP_TMR_IDX) == 0) 1859 v = pi->tmr_idx; 1860 else if (strcmp(name, T4PROP_PKTC_IDX) == 0) 1861 v = pi->pktc_idx; 1862 else if (strcmp(name, T4PROP_HW_CSUM) == 0) 1863 v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0; 1864 else if (strcmp(name, T4PROP_HW_LSO) == 0) 1865 v = (pi->features & CXGBE_HW_LSO) ? 1 : 0; 1866 else if (strcmp(name, T4PROP_TX_PAUSE) == 0) 1867 v = (lc->link_caps & FW_PORT_CAP32_FC_TX) ? 1 : 0; 1868 else if (strcmp(name, T4PROP_RX_PAUSE) == 0) 1869 v = (lc->link_caps & FW_PORT_CAP32_FC_RX) ? 1 : 0; 1870 #if MAC_VERSION == 1 1871 else if (strcmp(name, T4PROP_MTU) == 0) 1872 v = pi->mtu; 1873 #endif 1874 else 1875 return (ENOTSUP); 1876 1877 (void) snprintf(val, size, "%d", v); 1878 return (0); 1879 } 1880 1881 static int 1882 setprop(struct port_info *pi, const char *name, const void *val) 1883 { 1884 struct link_config *lc = &pi->link_cfg; 1885 fw_port_cap32_t new_caps = lc->admin_caps; 1886 int i, rc = 0, relink = 0, rx_mode = 0; 1887 struct adapter *sc = pi->adapter; 1888 struct sge_rxq *rxq; 1889 cc_pause_t fc = 0; 1890 long v; 1891 1892 (void) ddi_strtol(val, NULL, 0, &v); 1893 1894 if (strcmp(name, T4PROP_TMR_IDX) == 0) { 1895 if (v < 0 || v >= SGE_NTIMERS) 1896 return (EINVAL); 1897 if (v == pi->tmr_idx) 1898 return (0); 1899 1900 /* LINTED: E_ASSIGN_NARROW_CONV */ 1901 pi->tmr_idx = v; 1902 for_each_rxq(pi, i, rxq) { 1903 rxq->iq.intr_params = V_QINTR_TIMER_IDX(v) | 1904 V_QINTR_CNT_EN(pi->pktc_idx >= 0); 1905 } 1906 1907 } else if (strcmp(name, T4PROP_PKTC_IDX) == 0) { 1908 if (v >= SGE_NCOUNTERS) 1909 return (EINVAL); 1910 if (v == pi->pktc_idx || (v < 0 && pi->pktc_idx == -1)) 1911 return (0); 1912 1913 /* LINTED: E_ASSIGN_NARROW_CONV */ 1914 pi->pktc_idx = v < 0 ? -1 : v; 1915 for_each_rxq(pi, i, rxq) { 1916 rxq->iq.intr_params = V_QINTR_TIMER_IDX(pi->tmr_idx) | 1917 /* takes effect right away */ 1918 V_QINTR_CNT_EN(v >= 0); 1919 /* LINTED: E_ASSIGN_NARROW_CONV */ 1920 rxq->iq.intr_pktc_idx = v; /* this needs fresh plumb */ 1921 } 1922 } else if (strcmp(name, T4PROP_HW_CSUM) == 0) { 1923 if (v != 0 && v != 1) 1924 return (EINVAL); 1925 if (v == 1) 1926 pi->features |= CXGBE_HW_CSUM; 1927 else 1928 pi->features &= ~CXGBE_HW_CSUM; 1929 } else if (strcmp(name, T4PROP_HW_LSO) == 0) { 1930 if (v != 0 && v != 1) 1931 return (EINVAL); 1932 if (v == 1) 1933 pi->features |= CXGBE_HW_LSO; 1934 else 1935 pi->features &= ~CXGBE_HW_LSO; 1936 } else if (strcmp(name, T4PROP_TX_PAUSE) == 0) { 1937 if (v != 0 && v != 1) 1938 return (EINVAL); 1939 1940 if ((new_caps & FW_PORT_CAP32_FC_TX) && (v == 1)) 1941 fc |= PAUSE_TX; 1942 if (new_caps & FW_PORT_CAP32_FC_RX) 1943 fc |= PAUSE_RX; 1944 if (lc->admin_caps & FW_PORT_CAP32_ANEG) 1945 fc |= PAUSE_AUTONEG; 1946 1947 t4_link_set_pause(pi, fc, &new_caps); 1948 relink = 1; 1949 1950 } else if (strcmp(name, T4PROP_RX_PAUSE) == 0) { 1951 if (v != 0 && v != 1) 1952 return (EINVAL); 1953 1954 if (new_caps & FW_PORT_CAP32_FC_TX) 1955 fc |= PAUSE_TX; 1956 if ((new_caps & FW_PORT_CAP32_FC_RX) && (v == 1)) 1957 fc |= PAUSE_RX; 1958 if (lc->admin_caps & FW_PORT_CAP32_ANEG) 1959 fc |= PAUSE_AUTONEG; 1960 1961 t4_link_set_pause(pi, fc, &new_caps); 1962 relink = 1; 1963 } 1964 #if MAC_VERSION == 1 1965 else if (strcmp(name, T4PROP_MTU) == 0) { 1966 if (v < 46 || v > MAX_MTU) 1967 return (EINVAL); 1968 if (v == pi->mtu) 1969 return (0); 1970 1971 pi->mtu = (int)v; 1972 (void) mac_maxsdu_update(pi->mh, v); 1973 rx_mode = 1; 1974 } 1975 #endif 1976 else 1977 return (ENOTSUP); 1978 1979 if (!(relink || rx_mode)) 1980 return (0); 1981 1982 /* If we are here, either relink or rx_mode is 1 */ 1983 if (isset(&sc->open_device_map, pi->port_id) != 0) { 1984 if (relink != 0) { 1985 rc = begin_synchronized_op(pi, 1, 1); 1986 if (rc != 0) 1987 return (rc); 1988 rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc, 1989 new_caps); 1990 end_synchronized_op(pi, 1); 1991 if (rc != 0) { 1992 cxgb_printf(pi->dip, CE_WARN, 1993 "%s link config failed: %d", 1994 __func__, rc); 1995 return (rc); 1996 } 1997 } else if (rx_mode != 0) { 1998 rc = begin_synchronized_op(pi, 1, 1); 1999 if (rc != 0) 2000 return (rc); 2001 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v, -1, -1, 2002 -1, -1, false); 2003 end_synchronized_op(pi, 1); 2004 if (rc != 0) { 2005 cxgb_printf(pi->dip, CE_WARN, 2006 "set_rxmode failed: %d", rc); 2007 return (rc); 2008 } 2009 } 2010 } 2011 2012 if (relink != 0) 2013 lc->admin_caps = new_caps; 2014 2015 return (0); 2016 } 2017 2018 void 2019 t4_mc_init(struct port_info *pi) 2020 { 2021 pi->props = t4_priv_props; 2022 } 2023 2024 void 2025 t4_mc_cb_init(struct port_info *pi) 2026 { 2027 if (pi->adapter->props.multi_rings) 2028 pi->mc = &t4_m_ring_callbacks; 2029 else 2030 pi->mc = &t4_m_callbacks; 2031 } 2032 2033 void 2034 t4_os_link_changed(struct adapter *sc, int idx, int link_stat) 2035 { 2036 struct port_info *pi = sc->port[idx]; 2037 2038 mac_link_update(pi->mh, link_stat ? LINK_STATE_UP : LINK_STATE_DOWN); 2039 } 2040 2041 /* ARGSUSED */ 2042 void 2043 t4_mac_rx(struct port_info *pi, struct sge_rxq *rxq, mblk_t *m) 2044 { 2045 mac_rx(pi->mh, NULL, m); 2046 } 2047 2048 void 2049 t4_mac_tx_update(struct port_info *pi, struct sge_txq *txq) 2050 { 2051 if (pi->adapter->props.multi_rings) 2052 mac_tx_ring_update(pi->mh, txq->ring_handle); 2053 else 2054 mac_tx_update(pi->mh); 2055 } 2056