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 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14 * Copyright 2019 Joyent, Inc.
15 * Copyright 2017 Tegile Systems, Inc. All rights reserved.
16 * Copyright 2020 RackTop Systems, Inc.
17 * Copyright 2020 Ryan Zezeski
18 */
19
20 /*
21 * i40e - Intel 10/40 Gb Ethernet driver
22 *
23 * The i40e driver is the main software device driver for the Intel 40 Gb family
24 * of devices. Note that these devices come in many flavors with both 40 GbE
25 * ports and 10 GbE ports. This device is the successor to the 82599 family of
26 * devices (ixgbe).
27 *
28 * Unlike previous generations of Intel 1 GbE and 10 GbE devices, the 40 GbE
29 * devices defined in the XL710 controller (previously known as Fortville) are a
30 * rather different beast and have a small switch embedded inside of them. In
31 * addition, the way that most of the programming is done has been overhauled.
32 * As opposed to just using PCIe memory mapped registers, it also has an
33 * administrative queue which is used to communicate with firmware running on
34 * the chip.
35 *
36 * Each physical function in the hardware shows up as a device that this driver
37 * will bind to. The hardware splits many resources evenly across all of the
573
574 /*
575 * Firmware abstracts all of the mac and phy information for us, so we
576 * can use i40e_get_link_status to determine the current state.
577 */
578 if (ls == B_TRUE) {
579 enum i40e_aq_link_speed speed;
580
581 speed = i40e_get_link_speed(hw);
582
583 /*
584 * Translate from an i40e value to a value in Mbits/s.
585 */
586 switch (speed) {
587 case I40E_LINK_SPEED_100MB:
588 i40e->i40e_link_speed = 100;
589 break;
590 case I40E_LINK_SPEED_1GB:
591 i40e->i40e_link_speed = 1000;
592 break;
593 case I40E_LINK_SPEED_10GB:
594 i40e->i40e_link_speed = 10000;
595 break;
596 case I40E_LINK_SPEED_20GB:
597 i40e->i40e_link_speed = 20000;
598 break;
599 case I40E_LINK_SPEED_40GB:
600 i40e->i40e_link_speed = 40000;
601 break;
602 case I40E_LINK_SPEED_25GB:
603 i40e->i40e_link_speed = 25000;
604 break;
605 default:
606 i40e->i40e_link_speed = 0;
607 break;
608 }
609
610 /*
611 * At this time, hardware does not support half-duplex
612 * operation, hence why we don't ask the hardware about our
1330 return (B_FALSE);
1331 }
1332
1333 i40e_hw_to_instance(i40e, hw);
1334
1335 rc = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
1336 hw->func_caps.num_rx_qp, 0, 0);
1337 if (rc != 0) {
1338 i40e_error(i40e, "failed to initialize hardware memory cache: "
1339 "%d", rc);
1340 return (B_FALSE);
1341 }
1342
1343 rc = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY);
1344 if (rc != 0) {
1345 i40e_error(i40e, "failed to configure hardware memory cache: "
1346 "%d", rc);
1347 return (B_FALSE);
1348 }
1349
1350 (void) i40e_aq_stop_lldp(hw, TRUE, NULL);
1351
1352 rc = i40e_get_mac_addr(hw, hw->mac.addr);
1353 if (rc != I40E_SUCCESS) {
1354 i40e_error(i40e, "failed to retrieve hardware mac address: %d",
1355 rc);
1356 return (B_FALSE);
1357 }
1358
1359 rc = i40e_validate_mac_addr(hw->mac.addr);
1360 if (rc != 0) {
1361 i40e_error(i40e, "failed to validate internal mac address: "
1362 "%d", rc);
1363 return (B_FALSE);
1364 }
1365 bcopy(hw->mac.addr, hw->mac.perm_addr, ETHERADDRL);
1366 if ((rc = i40e_get_port_mac_addr(hw, hw->mac.port_addr)) !=
1367 I40E_SUCCESS) {
1368 i40e_error(i40e, "failed to retrieve port mac address: %d",
1369 rc);
1370 return (B_FALSE);
3161 ASSERT(MUTEX_HELD(&i40e->i40e_general_lock));
3162
3163 if (!i40e_chip_start(i40e)) {
3164 i40e_fm_ereport(i40e, DDI_FM_DEVICE_INVAL_STATE);
3165 rc = B_FALSE;
3166 goto done;
3167 }
3168
3169 /*
3170 * Enable broadcast traffic; however, do not enable multicast traffic.
3171 * That's handle exclusively through MAC's mc_multicst routines.
3172 */
3173 err = i40e_aq_set_vsi_broadcast(hw, I40E_DEF_VSI_SEID(i40e), B_TRUE,
3174 NULL);
3175 if (err != I40E_SUCCESS) {
3176 i40e_error(i40e, "failed to set default VSI: %d", err);
3177 rc = B_FALSE;
3178 goto done;
3179 }
3180
3181 err = i40e_aq_set_mac_config(hw, i40e->i40e_frame_max, B_TRUE, 0, NULL);
3182 if (err != I40E_SUCCESS) {
3183 i40e_error(i40e, "failed to set MAC config: %d", err);
3184 rc = B_FALSE;
3185 goto done;
3186 }
3187
3188 /*
3189 * Finally, make sure that we're happy from an FM perspective.
3190 */
3191 if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
3192 DDI_FM_OK) {
3193 rc = B_FALSE;
3194 goto done;
3195 }
3196
3197 /* Clear state bits prior to final interrupt enabling. */
3198 atomic_and_32(&i40e->i40e_state,
3199 ~(I40E_ERROR | I40E_STALL | I40E_OVERTEMP));
3200
3201 i40e_intr_io_enable_all(i40e);
|
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 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14 * Copyright 2019 Joyent, Inc.
15 * Copyright 2017 Tegile Systems, Inc. All rights reserved.
16 * Copyright 2020 RackTop Systems, Inc.
17 * Copyright 2020 Ryan Zezeski
18 * Copyright 2021 Oxide Computer Company
19 */
20
21 /*
22 * i40e - Intel 10/40 Gb Ethernet driver
23 *
24 * The i40e driver is the main software device driver for the Intel 40 Gb family
25 * of devices. Note that these devices come in many flavors with both 40 GbE
26 * ports and 10 GbE ports. This device is the successor to the 82599 family of
27 * devices (ixgbe).
28 *
29 * Unlike previous generations of Intel 1 GbE and 10 GbE devices, the 40 GbE
30 * devices defined in the XL710 controller (previously known as Fortville) are a
31 * rather different beast and have a small switch embedded inside of them. In
32 * addition, the way that most of the programming is done has been overhauled.
33 * As opposed to just using PCIe memory mapped registers, it also has an
34 * administrative queue which is used to communicate with firmware running on
35 * the chip.
36 *
37 * Each physical function in the hardware shows up as a device that this driver
38 * will bind to. The hardware splits many resources evenly across all of the
574
575 /*
576 * Firmware abstracts all of the mac and phy information for us, so we
577 * can use i40e_get_link_status to determine the current state.
578 */
579 if (ls == B_TRUE) {
580 enum i40e_aq_link_speed speed;
581
582 speed = i40e_get_link_speed(hw);
583
584 /*
585 * Translate from an i40e value to a value in Mbits/s.
586 */
587 switch (speed) {
588 case I40E_LINK_SPEED_100MB:
589 i40e->i40e_link_speed = 100;
590 break;
591 case I40E_LINK_SPEED_1GB:
592 i40e->i40e_link_speed = 1000;
593 break;
594 case I40E_LINK_SPEED_2_5GB:
595 i40e->i40e_link_speed = 2500;
596 break;
597 case I40E_LINK_SPEED_5GB:
598 i40e->i40e_link_speed = 5000;
599 break;
600 case I40E_LINK_SPEED_10GB:
601 i40e->i40e_link_speed = 10000;
602 break;
603 case I40E_LINK_SPEED_20GB:
604 i40e->i40e_link_speed = 20000;
605 break;
606 case I40E_LINK_SPEED_40GB:
607 i40e->i40e_link_speed = 40000;
608 break;
609 case I40E_LINK_SPEED_25GB:
610 i40e->i40e_link_speed = 25000;
611 break;
612 default:
613 i40e->i40e_link_speed = 0;
614 break;
615 }
616
617 /*
618 * At this time, hardware does not support half-duplex
619 * operation, hence why we don't ask the hardware about our
1337 return (B_FALSE);
1338 }
1339
1340 i40e_hw_to_instance(i40e, hw);
1341
1342 rc = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
1343 hw->func_caps.num_rx_qp, 0, 0);
1344 if (rc != 0) {
1345 i40e_error(i40e, "failed to initialize hardware memory cache: "
1346 "%d", rc);
1347 return (B_FALSE);
1348 }
1349
1350 rc = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY);
1351 if (rc != 0) {
1352 i40e_error(i40e, "failed to configure hardware memory cache: "
1353 "%d", rc);
1354 return (B_FALSE);
1355 }
1356
1357 (void) i40e_aq_stop_lldp(hw, TRUE, FALSE, NULL);
1358
1359 rc = i40e_get_mac_addr(hw, hw->mac.addr);
1360 if (rc != I40E_SUCCESS) {
1361 i40e_error(i40e, "failed to retrieve hardware mac address: %d",
1362 rc);
1363 return (B_FALSE);
1364 }
1365
1366 rc = i40e_validate_mac_addr(hw->mac.addr);
1367 if (rc != 0) {
1368 i40e_error(i40e, "failed to validate internal mac address: "
1369 "%d", rc);
1370 return (B_FALSE);
1371 }
1372 bcopy(hw->mac.addr, hw->mac.perm_addr, ETHERADDRL);
1373 if ((rc = i40e_get_port_mac_addr(hw, hw->mac.port_addr)) !=
1374 I40E_SUCCESS) {
1375 i40e_error(i40e, "failed to retrieve port mac address: %d",
1376 rc);
1377 return (B_FALSE);
3168 ASSERT(MUTEX_HELD(&i40e->i40e_general_lock));
3169
3170 if (!i40e_chip_start(i40e)) {
3171 i40e_fm_ereport(i40e, DDI_FM_DEVICE_INVAL_STATE);
3172 rc = B_FALSE;
3173 goto done;
3174 }
3175
3176 /*
3177 * Enable broadcast traffic; however, do not enable multicast traffic.
3178 * That's handle exclusively through MAC's mc_multicst routines.
3179 */
3180 err = i40e_aq_set_vsi_broadcast(hw, I40E_DEF_VSI_SEID(i40e), B_TRUE,
3181 NULL);
3182 if (err != I40E_SUCCESS) {
3183 i40e_error(i40e, "failed to set default VSI: %d", err);
3184 rc = B_FALSE;
3185 goto done;
3186 }
3187
3188 err = i40e_aq_set_mac_config(hw, i40e->i40e_frame_max, B_TRUE, 0,
3189 B_FALSE, NULL);
3190 if (err != I40E_SUCCESS) {
3191 i40e_error(i40e, "failed to set MAC config: %d", err);
3192 rc = B_FALSE;
3193 goto done;
3194 }
3195
3196 /*
3197 * Finally, make sure that we're happy from an FM perspective.
3198 */
3199 if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
3200 DDI_FM_OK) {
3201 rc = B_FALSE;
3202 goto done;
3203 }
3204
3205 /* Clear state bits prior to final interrupt enabling. */
3206 atomic_and_32(&i40e->i40e_state,
3207 ~(I40E_ERROR | I40E_STALL | I40E_OVERTEMP));
3208
3209 i40e_intr_io_enable_all(i40e);
|