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 /* I couldn't comeup with a better idea of not redefine 77 * another strcture and instead somehow reuse the earlier 78 * above structure and modify its members. 79 */ 80 mac_callbacks_t t4_m_ring_callbacks = { 81 .mc_callbacks = MC_GETCAPAB | MC_PROPERTIES, 82 .mc_getstat = t4_mc_getstat, 83 .mc_start = t4_mc_start, 84 .mc_stop = t4_mc_stop, 85 .mc_setpromisc =t4_mc_setpromisc, 86 .mc_multicst = t4_mc_multicst, 87 .mc_unicst = NULL, /* t4_addmac */ 88 .mc_tx = NULL, /* t4_eth_tx */ 89 .mc_getcapab = t4_mc_getcapab, 90 .mc_setprop = t4_mc_setprop, 91 .mc_getprop = t4_mc_getprop, 92 .mc_propinfo = t4_mc_propinfo, 93 }; 94 95 #define T4PROP_TMR_IDX "_holdoff_timer_idx" 96 #define T4PROP_PKTC_IDX "_holdoff_pktc_idx" 97 #define T4PROP_MTU "_mtu" 98 #define T4PROP_HW_CSUM "_hw_csum" 99 #define T4PROP_HW_LSO "_hw_lso" 100 #define T4PROP_TX_PAUSE "_tx_pause" 101 #define T4PROP_RX_PAUSE "_rx_pause" 102 103 char *t4_priv_props[] = { 104 T4PROP_TMR_IDX, 105 T4PROP_PKTC_IDX, 106 #if MAC_VERSION == 1 107 /* MAC_VERSION 1 doesn't seem to use MAC_PROP_MTU, hmmmm */ 108 T4PROP_MTU, 109 #endif 110 T4PROP_HW_CSUM, 111 T4PROP_HW_LSO, 112 T4PROP_TX_PAUSE, 113 T4PROP_RX_PAUSE, 114 NULL 115 }; 116 117 /* 118 * To determine the actual Ethernet mode that we're in we need to look at the 119 * port type. That will tell us whether we're using a BASE-T PHY, have an 120 * external SFP connection whose module type we also need to use to qualify 121 * this, and then the link speed itself. Combining that tuple we can then get 122 * the current media. 123 * 124 * Our tables below assume we have gotten it down so the last thing we need to 125 * consider is a single speed. If port types end up supporting the same class of 126 * transceiver at a given speed, then this will need to be changed to use 127 * additional information to disambiguate that (which will require additional 128 * logic from the firmware). 129 */ 130 typedef struct { 131 fw_port_cap32_t tmm_speed; 132 mac_ether_media_t tmm_ether; 133 } t4nex_media_map_t; 134 135 static const t4nex_media_map_t t4nex_map_baset[] = { 136 /* 137 * We're assuming that the 100 Mb/s mode is 100BASE-TX. It's hard to say 138 * for certain what the phy would have done, but given the rest of the 139 * market, that seems the most likely one. 140 */ 141 { FW_PORT_CAP32_SPEED_100M, ETHER_MEDIA_100BASE_TX }, 142 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_T }, 143 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_T } 144 }; 145 146 static const t4nex_media_map_t t4nex_map_kx[] = { 147 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX }, 148 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KX4 } 149 }; 150 151 static const t4nex_media_map_t t4nex_map_cx[] = { 152 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CX4 } 153 }; 154 155 static const t4nex_media_map_t t4nex_map_kr[] = { 156 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX }, 157 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KR }, 158 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_KR }, 159 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_KR4 }, 160 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_KR2 }, 161 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_KR4 }, 162 }; 163 164 static const t4nex_media_map_t t4nex_map_lr[] = { 165 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_LX }, 166 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LR }, 167 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_LR }, 168 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_LR4 }, 169 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_LR2 }, 170 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_LR4 }, 171 }; 172 173 static const t4nex_media_map_t t4nex_map_sr[] = { 174 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_SX }, 175 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_SR }, 176 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_SR }, 177 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_SR4 }, 178 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_SR2 }, 179 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_SR4 }, 180 }; 181 182 static const t4nex_media_map_t t4nex_map_er[] = { 183 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ER }, 184 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ER }, 185 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ER4 }, 186 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ER4 }, 187 }; 188 189 static const t4nex_media_map_t t4nex_map_cr[] = { 190 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX }, 191 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CR }, 192 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_CR }, 193 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_CR4 }, 194 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_CR2 }, 195 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_CR4 }, 196 }; 197 198 static const t4nex_media_map_t t4nex_map_acc[] = { 199 { FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX }, 200 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ACC }, 201 { FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ACC }, 202 { FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ACC4 }, 203 { FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_ACC2 }, 204 { FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ACC4 }, 205 }; 206 207 static const t4nex_media_map_t t4nex_map_lrm[] = { 208 { FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LRM }, 209 }; 210 211 static mac_ether_media_t 212 t4_port_to_media(struct port_info *pi) 213 { 214 fw_port_cap32_t speed; 215 struct link_config *lc = &pi->link_cfg; 216 const t4nex_media_map_t *map = NULL; 217 size_t count = 0; 218 219 if (lc->link_ok != 0) { 220 speed = t4_link_fwcap_to_fwspeed(lc->link_caps); 221 } else { 222 return (ETHER_MEDIA_UNKNOWN); 223 } 224 225 switch (pi->port_type) { 226 case FW_PORT_TYPE_FIBER_XFI: 227 case FW_PORT_TYPE_FIBER_XAUI: 228 case FW_PORT_TYPE_SFP: 229 case FW_PORT_TYPE_QSFP_10G: 230 case FW_PORT_TYPE_QSA: 231 case FW_PORT_TYPE_QSFP: 232 case FW_PORT_TYPE_CR4_QSFP: 233 case FW_PORT_TYPE_CR_QSFP: 234 case FW_PORT_TYPE_CR2_QSFP: 235 case FW_PORT_TYPE_SFP28: 236 switch (pi->mod_type) { 237 case FW_PORT_MOD_TYPE_LR: 238 map = t4nex_map_lr; 239 count = ARRAY_SIZE(t4nex_map_lr); 240 break; 241 case FW_PORT_MOD_TYPE_SR: 242 map = t4nex_map_sr; 243 count = ARRAY_SIZE(t4nex_map_sr); 244 break; 245 case FW_PORT_MOD_TYPE_ER: 246 map = t4nex_map_er; 247 count = ARRAY_SIZE(t4nex_map_er); 248 break; 249 case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: 250 map = t4nex_map_cr; 251 count = ARRAY_SIZE(t4nex_map_cr); 252 break; 253 case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: 254 map = t4nex_map_acc; 255 count = ARRAY_SIZE(t4nex_map_acc); 256 break; 257 case FW_PORT_MOD_TYPE_LRM: 258 map = t4nex_map_lrm; 259 count = ARRAY_SIZE(t4nex_map_lrm); 260 break; 261 case FW_PORT_MOD_TYPE_ERROR: 262 case FW_PORT_MOD_TYPE_UNKNOWN: 263 case FW_PORT_MOD_TYPE_NOTSUPPORTED: 264 case FW_PORT_MOD_TYPE_NONE: 265 case FW_PORT_MOD_TYPE_NA: 266 default: 267 break; 268 } 269 break; 270 case FW_PORT_TYPE_KX4: 271 case FW_PORT_TYPE_KX: 272 map = t4nex_map_kx; 273 count = ARRAY_SIZE(t4nex_map_kx); 274 break; 275 case FW_PORT_TYPE_CX4: 276 map = t4nex_map_cx; 277 count = ARRAY_SIZE(t4nex_map_cx); 278 break; 279 case FW_PORT_TYPE_KR: 280 case FW_PORT_TYPE_BP_AP: 281 case FW_PORT_TYPE_BP4_AP: 282 case FW_PORT_TYPE_BP40_BA: 283 case FW_PORT_TYPE_KR4_100G: 284 case FW_PORT_TYPE_KR_SFP28: 285 case FW_PORT_TYPE_KR_XLAUI: 286 map = t4nex_map_kr; 287 count = ARRAY_SIZE(t4nex_map_kr); 288 break; 289 case FW_PORT_TYPE_BT_SGMII: 290 case FW_PORT_TYPE_BT_XFI: 291 case FW_PORT_TYPE_BT_XAUI: 292 map = t4nex_map_baset; 293 count = ARRAY_SIZE(t4nex_map_baset); 294 break; 295 case FW_PORT_TYPE_NONE: 296 default: 297 break; 298 } 299 300 for (size_t i = 0; i < count; i++) { 301 if (map[i].tmm_speed == speed) { 302 return (map[i].tmm_ether); 303 } 304 } 305 306 /* 307 * At this point we return unknown as we already checked for a down link 308 * earlier. 309 */ 310 return (ETHER_MEDIA_UNKNOWN); 311 } 312 313 static int 314 t4_mc_getstat(void *arg, uint_t stat, uint64_t *val) 315 { 316 struct port_info *pi = arg; 317 struct adapter *sc = pi->adapter; 318 struct link_config *lc = &pi->link_cfg; 319 320 #define GET_STAT(name) \ 321 t4_read_reg64(sc, PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_##name##_L)) 322 323 switch (stat) { 324 case MAC_STAT_IFSPEED: 325 if (lc->link_ok != 0) { 326 *val = t4_link_fwcap_to_speed(lc->link_caps); 327 *val *= 1000000; 328 } else 329 *val = 0; 330 break; 331 332 case MAC_STAT_MULTIRCV: 333 *val = GET_STAT(RX_PORT_MCAST); 334 break; 335 336 case MAC_STAT_BRDCSTRCV: 337 *val = GET_STAT(RX_PORT_BCAST); 338 break; 339 340 case MAC_STAT_MULTIXMT: 341 *val = GET_STAT(TX_PORT_MCAST); 342 break; 343 344 case MAC_STAT_BRDCSTXMT: 345 *val = GET_STAT(TX_PORT_BCAST); 346 break; 347 348 case MAC_STAT_NORCVBUF: 349 *val = 0; /* TODO should come from rxq->nomem */ 350 break; 351 352 case MAC_STAT_IERRORS: 353 *val = GET_STAT(RX_PORT_MTU_ERROR) + 354 GET_STAT(RX_PORT_MTU_CRC_ERROR) + 355 GET_STAT(RX_PORT_CRC_ERROR) + 356 GET_STAT(RX_PORT_LEN_ERROR) + 357 GET_STAT(RX_PORT_SYM_ERROR) + 358 GET_STAT(RX_PORT_LESS_64B); 359 break; 360 361 case MAC_STAT_UNKNOWNS: 362 return (ENOTSUP); 363 364 case MAC_STAT_NOXMTBUF: 365 *val = GET_STAT(TX_PORT_DROP); 366 break; 367 368 case MAC_STAT_OERRORS: 369 *val = GET_STAT(TX_PORT_ERROR); 370 break; 371 372 case MAC_STAT_COLLISIONS: 373 return (ENOTSUP); 374 375 case MAC_STAT_RBYTES: 376 *val = GET_STAT(RX_PORT_BYTES); 377 break; 378 379 case MAC_STAT_IPACKETS: 380 *val = GET_STAT(RX_PORT_FRAMES); 381 break; 382 383 case MAC_STAT_OBYTES: 384 *val = GET_STAT(TX_PORT_BYTES); 385 break; 386 387 case MAC_STAT_OPACKETS: 388 *val = GET_STAT(TX_PORT_FRAMES); 389 break; 390 391 case ETHER_STAT_ALIGN_ERRORS: 392 return (ENOTSUP); 393 394 case ETHER_STAT_FCS_ERRORS: 395 *val = GET_STAT(RX_PORT_CRC_ERROR); 396 break; 397 398 case ETHER_STAT_FIRST_COLLISIONS: 399 case ETHER_STAT_MULTI_COLLISIONS: 400 case ETHER_STAT_SQE_ERRORS: 401 case ETHER_STAT_DEFER_XMTS: 402 case ETHER_STAT_TX_LATE_COLLISIONS: 403 case ETHER_STAT_EX_COLLISIONS: 404 return (ENOTSUP); 405 406 case ETHER_STAT_MACXMT_ERRORS: 407 *val = GET_STAT(TX_PORT_ERROR); 408 break; 409 410 case ETHER_STAT_CARRIER_ERRORS: 411 return (ENOTSUP); 412 413 case ETHER_STAT_TOOLONG_ERRORS: 414 *val = GET_STAT(RX_PORT_MTU_ERROR); 415 break; 416 417 case ETHER_STAT_MACRCV_ERRORS: 418 *val = GET_STAT(RX_PORT_MTU_ERROR) + 419 GET_STAT(RX_PORT_MTU_CRC_ERROR) + 420 GET_STAT(RX_PORT_CRC_ERROR) + 421 GET_STAT(RX_PORT_LEN_ERROR) + 422 GET_STAT(RX_PORT_SYM_ERROR) + 423 GET_STAT(RX_PORT_LESS_64B); 424 break; 425 426 case ETHER_STAT_XCVR_ADDR: 427 case ETHER_STAT_XCVR_ID: 428 return (ENOTSUP); 429 case ETHER_STAT_XCVR_INUSE: 430 *val = t4_port_to_media(pi); 431 break; 432 433 case ETHER_STAT_CAP_100GFDX: 434 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100G); 435 break; 436 437 case ETHER_STAT_CAP_50GFDX: 438 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_50G); 439 break; 440 441 case ETHER_STAT_CAP_40GFDX: 442 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_40G); 443 break; 444 445 case ETHER_STAT_CAP_25GFDX: 446 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_25G); 447 break; 448 449 case ETHER_STAT_CAP_10GFDX: 450 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_10G); 451 break; 452 453 case ETHER_STAT_CAP_1000FDX: 454 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_1G); 455 break; 456 457 case ETHER_STAT_CAP_100FDX: 458 *val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100M); 459 break; 460 461 case ETHER_STAT_CAP_1000HDX: 462 case ETHER_STAT_CAP_100HDX: 463 case ETHER_STAT_CAP_10FDX: 464 case ETHER_STAT_CAP_10HDX: 465 return (ENOTSUP); 466 467 case ETHER_STAT_CAP_ASMPAUSE: 468 *val = !!(lc->pcaps & FW_PORT_CAP32_FC_RX); 469 break; 470 471 case ETHER_STAT_CAP_PAUSE: 472 *val = !!(lc->pcaps & FW_PORT_CAP32_FC_TX); 473 break; 474 475 case ETHER_STAT_CAP_AUTONEG: 476 *val = !!(lc->pcaps & FW_PORT_CAP32_ANEG); 477 break; 478 479 /* 480 * We have set flow control configuration based on tx_pause and rx_pause 481 * values supported through ndd. Now, we need to translate the settings 482 * we have in link_config structure to adv_cap_asmpause and 483 * adv_cap_pause. 484 * 485 * There are 4 combinations possible and the translation is as below: 486 * tx_pause = 0 => We don't send pause frames during Rx congestion 487 * tx_pause = 1 => We send pause frames during Rx congestion 488 * rx_pause = 0 => We ignore received pause frames 489 * rx_pause = 1 => We pause transmission when we receive pause frames 490 * 491 * +----------------------------+----------------------------------+ 492 * | tx_pause | rx_pause | adv_cap_asmpause | adv_cap_pause | 493 * +-------------------------+-------------------------------------+ 494 * | 0 | 0 | 0 | 0 | 495 * | 0 | 1 | 1 | 0 | 496 * | 1 | 0 | 1 | 1 | 497 * | 1 | 1 | 0 | 1 | 498 * +----------------------------+----------------------------------+ 499 */ 500 501 /* Advertised asymmetric pause capability */ 502 case ETHER_STAT_ADV_CAP_ASMPAUSE: 503 if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR) 504 *val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_ASM_DIR); 505 else 506 *val = (!!(lc->admin_caps & FW_PORT_CAP32_FC_TX)) ^ 507 (!!(lc->admin_caps & FW_PORT_CAP32_FC_RX)); 508 break; 509 510 /* Advertised pause capability */ 511 case ETHER_STAT_ADV_CAP_PAUSE: 512 if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE) 513 *val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_PAUSE); 514 else 515 *val = !!(lc->admin_caps & FW_PORT_CAP32_FC_TX); 516 break; 517 518 case ETHER_STAT_ADV_CAP_100GFDX: 519 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100G); 520 break; 521 522 case ETHER_STAT_ADV_CAP_50GFDX: 523 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_50G); 524 break; 525 526 case ETHER_STAT_ADV_CAP_40GFDX: 527 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_40G); 528 break; 529 530 case ETHER_STAT_ADV_CAP_25GFDX: 531 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_25G); 532 break; 533 534 case ETHER_STAT_ADV_CAP_10GFDX: 535 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_10G); 536 break; 537 538 case ETHER_STAT_ADV_CAP_1000FDX: 539 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_1G); 540 break; 541 542 case ETHER_STAT_ADV_CAP_100FDX: 543 *val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100M); 544 break; 545 546 case ETHER_STAT_ADV_CAP_AUTONEG: 547 *val = !!(lc->admin_caps & FW_PORT_CAP32_ANEG); 548 break; 549 550 case ETHER_STAT_ADV_CAP_1000HDX: 551 case ETHER_STAT_ADV_CAP_100HDX: 552 case ETHER_STAT_ADV_CAP_10FDX: 553 case ETHER_STAT_ADV_CAP_10HDX: 554 return (ENOTSUP); /* TODO */ 555 556 case ETHER_STAT_LP_CAP_ASMPAUSE: 557 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 558 return (ENOTSUP); 559 560 if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR) 561 *val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_ASM_DIR); 562 else 563 *val = (!!(lc->lpacaps & FW_PORT_CAP32_FC_TX)) ^ 564 (!!(lc->lpacaps & FW_PORT_CAP32_FC_RX)); 565 break; 566 567 case ETHER_STAT_LP_CAP_PAUSE: 568 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 569 return (ENOTSUP); 570 571 if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE) 572 *val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_PAUSE); 573 else 574 *val = !!(lc->lpacaps & FW_PORT_CAP32_FC_TX); 575 break; 576 577 case ETHER_STAT_LP_CAP_100GFDX: 578 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 579 return (ENOTSUP); 580 581 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100G); 582 break; 583 584 case ETHER_STAT_LP_CAP_50GFDX: 585 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 586 return (ENOTSUP); 587 588 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_50G); 589 break; 590 591 case ETHER_STAT_LP_CAP_40GFDX: 592 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 593 return (ENOTSUP); 594 595 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_40G); 596 break; 597 598 case ETHER_STAT_LP_CAP_25GFDX: 599 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 600 return (ENOTSUP); 601 602 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_25G); 603 break; 604 605 case ETHER_STAT_LP_CAP_10GFDX: 606 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 607 return (ENOTSUP); 608 609 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_10G); 610 break; 611 612 case ETHER_STAT_LP_CAP_1000FDX: 613 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 614 return (ENOTSUP); 615 616 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_1G); 617 break; 618 619 case ETHER_STAT_LP_CAP_100FDX: 620 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 621 return (ENOTSUP); 622 623 *val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100M); 624 break; 625 626 case ETHER_STAT_LP_CAP_AUTONEG: 627 if (!(lc->acaps & FW_PORT_CAP32_ANEG)) 628 return (ENOTSUP); 629 630 *val = !!(lc->lpacaps & FW_PORT_CAP32_ANEG); 631 break; 632 633 case ETHER_STAT_LP_CAP_1000HDX: 634 case ETHER_STAT_LP_CAP_100HDX: 635 case ETHER_STAT_LP_CAP_10FDX: 636 case ETHER_STAT_LP_CAP_10HDX: 637 return (ENOTSUP); 638 639 case ETHER_STAT_LINK_ASMPAUSE: 640 *val = (!!(lc->link_caps & FW_PORT_CAP32_FC_TX)) ^ 641 (!!(lc->link_caps & FW_PORT_CAP32_FC_RX)); 642 break; 643 644 case ETHER_STAT_LINK_PAUSE: 645 *val = !!(lc->link_caps & FW_PORT_CAP32_FC_TX); 646 break; 647 648 case ETHER_STAT_LINK_AUTONEG: 649 *val = !!(lc->link_caps & FW_PORT_CAP32_ANEG); 650 break; 651 652 case ETHER_STAT_LINK_DUPLEX: 653 if (lc->link_ok != 0) 654 *val = LINK_DUPLEX_FULL; 655 else 656 *val = LINK_DUPLEX_UNKNOWN; 657 break; 658 659 default: 660 return (ENOTSUP); 661 } 662 #undef GET_STAT 663 664 return (0); 665 } 666 667 static int 668 t4_mc_start(void *arg) 669 { 670 struct port_info *pi = arg; 671 int rc; 672 673 rc = begin_synchronized_op(pi, 0, 1); 674 if (rc != 0) 675 return (rc); 676 rc = t4_init_synchronized(pi); 677 end_synchronized_op(pi, 0); 678 679 return (rc); 680 } 681 682 static void 683 t4_mc_stop(void *arg) 684 { 685 struct port_info *pi = arg; 686 687 while (begin_synchronized_op(pi, 0, 1) != 0) 688 continue; 689 (void) t4_uninit_synchronized(pi); 690 end_synchronized_op(pi, 0); 691 } 692 693 static int 694 t4_mc_setpromisc(void *arg, boolean_t on) 695 { 696 struct port_info *pi = arg; 697 struct adapter *sc = pi->adapter; 698 int rc; 699 700 rc = begin_synchronized_op(pi, 1, 1); 701 if (rc != 0) 702 return (rc); 703 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, -1, on ? 1 : 0, -1, -1, -1, 704 false); 705 end_synchronized_op(pi, 1); 706 707 return (rc); 708 } 709 710 /* 711 * TODO: Starts failing as soon as the 336 entry table fills up. Need to use 712 * hash in that case. 713 */ 714 static int 715 t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr) 716 { 717 struct port_info *pi = arg; 718 struct adapter *sc = pi->adapter; 719 struct fw_vi_mac_cmd c; 720 int len16, rc; 721 722 len16 = howmany(sizeof (c.op_to_viid) + sizeof (c.freemacs_to_len16) + 723 sizeof (c.u.exact[0]), 16); 724 c.op_to_viid = htonl(V_FW_CMD_OP(FW_VI_MAC_CMD) | F_FW_CMD_REQUEST | 725 F_FW_CMD_WRITE | V_FW_VI_MAC_CMD_VIID(pi->viid)); 726 c.freemacs_to_len16 = htonl(V_FW_CMD_LEN16(len16)); 727 c.u.exact[0].valid_to_idx = htons(F_FW_VI_MAC_CMD_VALID | 728 V_FW_VI_MAC_CMD_IDX(add ? FW_VI_MAC_ADD_MAC : 729 FW_VI_MAC_MAC_BASED_FREE)); 730 bcopy(mcaddr, &c.u.exact[0].macaddr, ETHERADDRL); 731 732 rc = begin_synchronized_op(pi, 1, 1); 733 if (rc != 0) 734 return (rc); 735 rc = -t4_wr_mbox_meat(sc, sc->mbox, &c, len16 * 16, &c, true); 736 end_synchronized_op(pi, 1); 737 if (rc != 0) 738 return (rc); 739 #ifdef DEBUG 740 /* 741 * TODO: Firmware doesn't seem to return the correct index on removal 742 * (it gives back 0x3fd FW_VI_MAC_MAC_BASED_FREE unchanged. Remove this 743 * code once it is fixed. 744 */ 745 else { 746 uint16_t idx; 747 748 idx = G_FW_VI_MAC_CMD_IDX(ntohs(c.u.exact[0].valid_to_idx)); 749 cxgb_printf(pi->dip, CE_NOTE, 750 "%02x:%02x:%02x:%02x:%02x:%02x %s %d", mcaddr[0], 751 mcaddr[1], mcaddr[2], mcaddr[3], mcaddr[4], mcaddr[5], 752 add ? "added at index" : "removed from index", idx); 753 } 754 #endif 755 756 return (0); 757 } 758 759 int 760 t4_mc_unicst(void *arg, const uint8_t *ucaddr) 761 { 762 struct port_info *pi = arg; 763 struct adapter *sc = pi->adapter; 764 int rc; 765 766 if (ucaddr == NULL) 767 return (EINVAL); 768 769 rc = begin_synchronized_op(pi, 1, 1); 770 if (rc != 0) 771 return (rc); 772 773 /* We will support adding only one mac address */ 774 if (pi->adapter->props.multi_rings && pi->macaddr_cnt) { 775 end_synchronized_op(pi, 1); 776 return (ENOSPC); 777 } 778 rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt, ucaddr, 779 true, &pi->smt_idx); 780 if (rc < 0) 781 rc = -rc; 782 else { 783 pi->macaddr_cnt++; 784 pi->xact_addr_filt = rc; 785 rc = 0; 786 } 787 end_synchronized_op(pi, 1); 788 789 return (rc); 790 } 791 792 int 793 t4_addmac(void *arg, const uint8_t *ucaddr) 794 { 795 return (t4_mc_unicst(arg, ucaddr)); 796 } 797 798 static int 799 t4_remmac(void *arg, const uint8_t *mac_addr) 800 { 801 struct port_info *pi = arg; 802 int rc; 803 804 rc = begin_synchronized_op(pi, 1, 1); 805 if (rc != 0) 806 return (rc); 807 808 pi->macaddr_cnt--; 809 end_synchronized_op(pi, 1); 810 811 return (0); 812 } 813 814 /* 815 * Callback funtion for MAC layer to register all groups. 816 */ 817 void 818 t4_fill_group(void *arg, mac_ring_type_t rtype, const int rg_index, 819 mac_group_info_t *infop, mac_group_handle_t gh) 820 { 821 struct port_info *pi = arg; 822 823 switch (rtype) { 824 case MAC_RING_TYPE_RX: { 825 infop->mgi_driver = (mac_group_driver_t)arg; 826 infop->mgi_start = NULL; 827 infop->mgi_stop = NULL; 828 infop->mgi_addmac = t4_addmac; 829 infop->mgi_remmac = t4_remmac; 830 infop->mgi_count = pi->nrxq; 831 break; 832 } 833 case MAC_RING_TYPE_TX: 834 default: 835 ASSERT(0); 836 break; 837 } 838 } 839 840 static int 841 t4_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num) 842 { 843 struct sge_rxq *rxq = (struct sge_rxq *)rh; 844 845 RXQ_LOCK(rxq); 846 rxq->ring_gen_num = mr_gen_num; 847 RXQ_UNLOCK(rxq); 848 return (0); 849 } 850 851 /* 852 * Enable interrupt on the specificed rx ring. 853 */ 854 int 855 t4_ring_intr_enable(mac_intr_handle_t intrh) 856 { 857 struct sge_rxq *rxq = (struct sge_rxq *)intrh; 858 struct adapter *sc = rxq->port->adapter; 859 struct sge_iq *iq; 860 861 iq = &rxq->iq; 862 RXQ_LOCK(rxq); 863 iq->polling = 0; 864 iq->state = IQS_IDLE; 865 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), 866 V_SEINTARM(iq->intr_params) | V_INGRESSQID(iq->cntxt_id)); 867 RXQ_UNLOCK(rxq); 868 return (0); 869 } 870 871 /* 872 * Disable interrupt on the specificed rx ring. 873 */ 874 int 875 t4_ring_intr_disable(mac_intr_handle_t intrh) 876 { 877 struct sge_rxq *rxq = (struct sge_rxq *)intrh; 878 struct sge_iq *iq; 879 880 /* Nothing to be done here wrt interrupt, as it 881 * will not fire, until we write back to 882 * A_SGE_PF_GTS.SEIntArm in t4_ring_intr_enable. 883 */ 884 885 iq = &rxq->iq; 886 RXQ_LOCK(rxq); 887 iq->polling = 1; 888 iq->state = IQS_BUSY; 889 RXQ_UNLOCK(rxq); 890 return (0); 891 } 892 893 mblk_t * 894 t4_poll_ring(void *arg, int n_bytes) 895 { 896 struct sge_rxq *rxq = (struct sge_rxq *)arg; 897 mblk_t *mp = NULL; 898 899 ASSERT(n_bytes >= 0); 900 if (n_bytes == 0) 901 return (NULL); 902 903 RXQ_LOCK(rxq); 904 mp = t4_ring_rx(rxq, n_bytes); 905 RXQ_UNLOCK(rxq); 906 907 return (mp); 908 } 909 910 /* 911 * Retrieve a value for one of the statistics for a particular rx ring 912 */ 913 int 914 t4_rx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 915 { 916 struct sge_rxq *rxq = (struct sge_rxq *)rh; 917 918 switch (stat) { 919 case MAC_STAT_RBYTES: 920 *val = rxq->rxbytes; 921 break; 922 923 case MAC_STAT_IPACKETS: 924 *val = rxq->rxpkts; 925 break; 926 927 default: 928 *val = 0; 929 return (ENOTSUP); 930 } 931 932 return (0); 933 } 934 935 /* 936 * Retrieve a value for one of the statistics for a particular tx ring 937 */ 938 int 939 t4_tx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 940 { 941 struct sge_txq *txq = (struct sge_txq *)rh; 942 943 switch (stat) { 944 case MAC_STAT_RBYTES: 945 *val = txq->txbytes; 946 break; 947 948 case MAC_STAT_IPACKETS: 949 *val = txq->txpkts; 950 break; 951 952 default: 953 *val = 0; 954 return (ENOTSUP); 955 } 956 957 return (0); 958 } 959 960 /* 961 * Callback funtion for MAC layer to register all rings 962 * for given ring_group, noted by group_index. 963 * Since we have only one group, ring index becomes 964 * absolute index. 965 */ 966 void 967 t4_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index, 968 const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 969 { 970 struct port_info *pi = arg; 971 mac_intr_t *mintr; 972 973 switch (rtype) { 974 case MAC_RING_TYPE_RX: { 975 struct sge_rxq *rxq; 976 977 rxq = &pi->adapter->sge.rxq[pi->first_rxq + ring_index]; 978 rxq->ring_handle = rh; 979 980 infop->mri_driver = (mac_ring_driver_t)rxq; 981 infop->mri_start = t4_ring_start; 982 infop->mri_stop = NULL; 983 infop->mri_poll = t4_poll_ring; 984 infop->mri_stat = t4_rx_stat; 985 986 mintr = &infop->mri_intr; 987 mintr->mi_handle = (mac_intr_handle_t)rxq; 988 mintr->mi_enable = t4_ring_intr_enable; 989 mintr->mi_disable = t4_ring_intr_disable; 990 991 break; 992 } 993 case MAC_RING_TYPE_TX: { 994 struct sge_txq *txq = &pi->adapter->sge.txq[pi->first_txq + ring_index]; 995 txq->ring_handle = rh; 996 infop->mri_driver = (mac_ring_driver_t)txq; 997 infop->mri_start = NULL; 998 infop->mri_stop = NULL; 999 infop->mri_tx = t4_eth_tx; 1000 infop->mri_stat = t4_tx_stat; 1001 break; 1002 } 1003 default: 1004 ASSERT(0); 1005 break; 1006 } 1007 } 1008 1009 mblk_t * 1010 t4_mc_tx(void *arg, mblk_t *m) 1011 { 1012 struct port_info *pi = arg; 1013 struct adapter *sc = pi->adapter; 1014 struct sge_txq *txq = &sc->sge.txq[pi->first_txq]; 1015 1016 return (t4_eth_tx(txq, m)); 1017 } 1018 1019 static int 1020 t4_mc_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) 1021 { 1022 struct port_info *pi = arg; 1023 1024 if (id != 0 || infop == NULL) 1025 return (EINVAL); 1026 1027 switch (pi->mod_type) { 1028 case FW_PORT_MOD_TYPE_NONE: 1029 mac_transceiver_info_set_present(infop, B_FALSE); 1030 break; 1031 case FW_PORT_MOD_TYPE_NOTSUPPORTED: 1032 mac_transceiver_info_set_present(infop, B_TRUE); 1033 mac_transceiver_info_set_usable(infop, B_FALSE); 1034 break; 1035 default: 1036 mac_transceiver_info_set_present(infop, B_TRUE); 1037 mac_transceiver_info_set_usable(infop, B_TRUE); 1038 break; 1039 } 1040 1041 return (0); 1042 } 1043 1044 static int 1045 t4_mc_transceiver_read(void *arg, uint_t id, uint_t page, void *bp, 1046 size_t nbytes, off_t offset, size_t *nread) 1047 { 1048 struct port_info *pi = arg; 1049 struct adapter *sc = pi->adapter; 1050 int rc; 1051 size_t i, maxread; 1052 /* LINTED: E_FUNC_VAR_UNUSED */ 1053 struct fw_ldst_cmd ldst __unused; 1054 1055 if (id != 0 || bp == NULL || nbytes == 0 || nread == NULL || 1056 (page != 0xa0 && page != 0xa2) || offset < 0) 1057 return (EINVAL); 1058 1059 if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) 1060 return (EINVAL); 1061 1062 rc = begin_synchronized_op(pi, 0, 1); 1063 if (rc != 0) 1064 return (rc); 1065 1066 /* 1067 * Firmware has a maximum size that we can read. Don't read more than it 1068 * allows. 1069 */ 1070 maxread = sizeof (ldst.u.i2c.data); 1071 for (i = 0; i < nbytes; i += maxread) { 1072 size_t toread = MIN(maxread, nbytes - i); 1073 rc = -t4_i2c_rd(sc, sc->mbox, pi->port_id, page, offset, toread, 1074 bp); 1075 if (rc != 0) 1076 break; 1077 offset += toread; 1078 bp = (void *)((uintptr_t)bp + toread); 1079 } 1080 end_synchronized_op(pi, 0); 1081 if (rc == 0) 1082 *nread = nbytes; 1083 return (rc); 1084 } 1085 1086 static int 1087 t4_port_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 1088 { 1089 struct port_info *pi = arg; 1090 struct adapter *sc = pi->adapter; 1091 int val, rc; 1092 1093 if (flags != 0) 1094 return (EINVAL); 1095 1096 switch (mode) { 1097 case MAC_LED_DEFAULT: 1098 val = 0; 1099 break; 1100 case MAC_LED_IDENT: 1101 val = 0xffff; 1102 break; 1103 1104 default: 1105 return (ENOTSUP); 1106 } 1107 1108 rc = begin_synchronized_op(pi, 1, 1); 1109 if (rc != 0) 1110 return (rc); 1111 rc = -t4_identify_port(sc, sc->mbox, pi->viid, val); 1112 end_synchronized_op(pi, 1); 1113 1114 return (rc); 1115 } 1116 1117 static boolean_t 1118 t4_mc_getcapab(void *arg, mac_capab_t cap, void *data) 1119 { 1120 struct port_info *pi = arg; 1121 boolean_t status = B_TRUE; 1122 mac_capab_transceiver_t *mct; 1123 mac_capab_led_t *mcl; 1124 1125 switch (cap) { 1126 case MAC_CAPAB_HCKSUM: 1127 if (pi->features & CXGBE_HW_CSUM) { 1128 uint32_t *d = data; 1129 *d = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM | 1130 HCKSUM_INET_FULL_V6; 1131 } else 1132 status = B_FALSE; 1133 break; 1134 1135 case MAC_CAPAB_LSO: 1136 /* Enabling LSO requires Checksum offloading */ 1137 if (pi->features & CXGBE_HW_LSO && 1138 pi->features & CXGBE_HW_CSUM) { 1139 mac_capab_lso_t *d = data; 1140 1141 d->lso_flags = LSO_TX_BASIC_TCP_IPV4 | 1142 LSO_TX_BASIC_TCP_IPV6; 1143 d->lso_basic_tcp_ipv4.lso_max = 65535; 1144 d->lso_basic_tcp_ipv6.lso_max = 65535; 1145 } else 1146 status = B_FALSE; 1147 break; 1148 1149 case MAC_CAPAB_RINGS: { 1150 mac_capab_rings_t *cap_rings = data; 1151 1152 if (!pi->adapter->props.multi_rings) { 1153 status = B_FALSE; 1154 break; 1155 } 1156 switch (cap_rings->mr_type) { 1157 case MAC_RING_TYPE_RX: 1158 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1159 cap_rings->mr_rnum = pi->nrxq; 1160 cap_rings->mr_gnum = 1; 1161 cap_rings->mr_rget = t4_fill_ring; 1162 cap_rings->mr_gget = t4_fill_group; 1163 cap_rings->mr_gaddring = NULL; 1164 cap_rings->mr_gremring = NULL; 1165 break; 1166 case MAC_RING_TYPE_TX: 1167 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 1168 cap_rings->mr_rnum = pi->ntxq; 1169 cap_rings->mr_gnum = 0; 1170 cap_rings->mr_rget = t4_fill_ring; 1171 cap_rings->mr_gget = NULL; 1172 break; 1173 } 1174 break; 1175 } 1176 1177 case MAC_CAPAB_TRANSCEIVER: 1178 mct = data; 1179 1180 mct->mct_flags = 0; 1181 mct->mct_ntransceivers = 1; 1182 mct->mct_info = t4_mc_transceiver_info; 1183 mct->mct_read = t4_mc_transceiver_read; 1184 break; 1185 case MAC_CAPAB_LED: 1186 mcl = data; 1187 mcl->mcl_flags = 0; 1188 mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_IDENT; 1189 mcl->mcl_set = t4_port_led_set; 1190 break; 1191 1192 default: 1193 status = B_FALSE; /* cap not supported */ 1194 } 1195 1196 return (status); 1197 } 1198 1199 static void t4_mac_link_caps_to_flowctrl(fw_port_cap32_t caps, 1200 link_flowctrl_t *fc) 1201 { 1202 u8 pause_tx = 0, pause_rx = 0; 1203 1204 if (caps & FW_PORT_CAP32_FC_TX) 1205 pause_tx = 1; 1206 1207 if (caps & FW_PORT_CAP32_FC_RX) 1208 pause_rx = 1; 1209 1210 if (pause_rx & pause_tx) 1211 *fc = LINK_FLOWCTRL_BI; 1212 else if (pause_tx) 1213 *fc = LINK_FLOWCTRL_TX; 1214 else if (pause_rx) 1215 *fc = LINK_FLOWCTRL_RX; 1216 else 1217 *fc = LINK_FLOWCTRL_NONE; 1218 } 1219 1220 static int t4_mac_flowctrl_to_link_caps(struct port_info *pi, 1221 link_flowctrl_t fc, 1222 fw_port_cap32_t *new_caps) 1223 { 1224 cc_pause_t pause = 0; 1225 1226 switch (fc) { 1227 case LINK_FLOWCTRL_BI: 1228 pause |= PAUSE_TX | PAUSE_RX; 1229 break; 1230 case LINK_FLOWCTRL_TX: 1231 pause |= PAUSE_TX; 1232 break; 1233 case LINK_FLOWCTRL_RX: 1234 pause |= PAUSE_RX; 1235 break; 1236 default: 1237 break; 1238 } 1239 1240 if (pi->link_cfg.admin_caps & FW_PORT_CAP32_ANEG) 1241 pause |= PAUSE_AUTONEG; 1242 1243 return t4_link_set_pause(pi, pause, new_caps); 1244 } 1245 1246 static link_fec_t t4_mac_port_caps_to_fec_cap(fw_port_cap32_t caps) 1247 { 1248 link_fec_t link_fec = 0; 1249 1250 if (caps & FW_PORT_CAP32_FEC_RS) 1251 link_fec |= LINK_FEC_RS; 1252 1253 if (caps & FW_PORT_CAP32_FEC_BASER_RS) 1254 link_fec |= LINK_FEC_BASE_R; 1255 1256 if (caps & FW_PORT_CAP32_FEC_NO_FEC) 1257 link_fec |= LINK_FEC_NONE; 1258 1259 if ((link_fec & (link_fec - 1)) && 1260 !(caps & FW_PORT_CAP32_FORCE_FEC)) 1261 return LINK_FEC_AUTO; 1262 1263 return link_fec; 1264 } 1265 1266 static void t4_mac_admin_caps_to_fec_cap(fw_port_cap32_t caps, 1267 link_fec_t *fec) 1268 { 1269 *fec = t4_mac_port_caps_to_fec_cap(caps); 1270 } 1271 1272 static void t4_mac_link_caps_to_fec_cap(fw_port_cap32_t caps, 1273 link_fec_t *fec) 1274 { 1275 link_fec_t link_fec; 1276 1277 caps &= ~FW_PORT_CAP32_FEC_NO_FEC; 1278 link_fec = t4_mac_port_caps_to_fec_cap(caps); 1279 *fec = link_fec ? link_fec : LINK_FEC_NONE; 1280 } 1281 1282 static int 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", 1427 __func__, rc); 1428 return (rc); 1429 } 1430 } 1431 1432 if (rx_mode != 0) { 1433 rc = begin_synchronized_op(pi, 1, 1); 1434 if (rc != 0) 1435 return (rc); 1436 rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v32, -1, 1437 -1, -1, -1, false); 1438 end_synchronized_op(pi, 1); 1439 if (rc != 0) { 1440 cxgb_printf(pi->dip, CE_WARN, 1441 "set_rxmode failed: %d", rc); 1442 return (rc); 1443 } 1444 } 1445 } 1446 1447 if (relink != 0) 1448 lc->admin_caps = new_caps; 1449 1450 return (0); 1451 } 1452 1453 static int 1454 t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t size, 1455 void *val) 1456 { 1457 struct port_info *pi = arg; 1458 struct link_config *lc = &pi->link_cfg; 1459 uint8_t *u = val; 1460 int rc = 0; 1461 1462 switch (id) { 1463 case MAC_PROP_DUPLEX: 1464 *(link_duplex_t *)val = lc->link_ok ? LINK_DUPLEX_FULL : 1465 LINK_DUPLEX_UNKNOWN; 1466 break; 1467 1468 case MAC_PROP_SPEED: 1469 if (lc->link_ok != 0) { 1470 *(uint64_t *)val = 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