19d26e4fcSRobert Mustacchi /* 29d26e4fcSRobert Mustacchi * This file and its contents are supplied under the terms of the 39d26e4fcSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 49d26e4fcSRobert Mustacchi * You may only use this file in accordance with the terms of version 59d26e4fcSRobert Mustacchi * 1.0 of the CDDL. 69d26e4fcSRobert Mustacchi * 79d26e4fcSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 89d26e4fcSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 99d26e4fcSRobert Mustacchi * http://www.illumos.org/license/CDDL. 109d26e4fcSRobert Mustacchi */ 119d26e4fcSRobert Mustacchi 129d26e4fcSRobert Mustacchi /* 139d26e4fcSRobert Mustacchi * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. 14286d309cSRobert Mustacchi * Copyright (c) 2018, Joyent, Inc. 15396505afSPaul Winder * Copyright 2017 Tegile Systems, Inc. All rights reserved. 1688628b1bSRyan Zezeski * Copyright 2020 Ryan Zezeski 17*aa2a44afSPaul Winder * Copyright 2020 RackTop Systems, Inc. 189d26e4fcSRobert Mustacchi */ 199d26e4fcSRobert Mustacchi 209d26e4fcSRobert Mustacchi /* 219d26e4fcSRobert Mustacchi * For more information, please see the big theory statement in i40e_main.c. 229d26e4fcSRobert Mustacchi */ 239d26e4fcSRobert Mustacchi 249d26e4fcSRobert Mustacchi #include "i40e_sw.h" 259d26e4fcSRobert Mustacchi 269d26e4fcSRobert Mustacchi #define I40E_PROP_RX_DMA_THRESH "_rx_dma_threshold" 279d26e4fcSRobert Mustacchi #define I40E_PROP_TX_DMA_THRESH "_tx_dma_threshold" 289d26e4fcSRobert Mustacchi #define I40E_PROP_RX_ITR "_rx_intr_throttle" 299d26e4fcSRobert Mustacchi #define I40E_PROP_TX_ITR "_tx_intr_throttle" 309d26e4fcSRobert Mustacchi #define I40E_PROP_OTHER_ITR "_other_intr_throttle" 319d26e4fcSRobert Mustacchi 329d26e4fcSRobert Mustacchi char *i40e_priv_props[] = { 339d26e4fcSRobert Mustacchi I40E_PROP_RX_DMA_THRESH, 349d26e4fcSRobert Mustacchi I40E_PROP_TX_DMA_THRESH, 359d26e4fcSRobert Mustacchi I40E_PROP_RX_ITR, 369d26e4fcSRobert Mustacchi I40E_PROP_TX_ITR, 379d26e4fcSRobert Mustacchi I40E_PROP_OTHER_ITR, 389d26e4fcSRobert Mustacchi NULL 399d26e4fcSRobert Mustacchi }; 409d26e4fcSRobert Mustacchi 419d26e4fcSRobert Mustacchi static int 429d26e4fcSRobert Mustacchi i40e_group_remove_mac(void *arg, const uint8_t *mac_addr) 439d26e4fcSRobert Mustacchi { 4409aee612SRyan Zezeski i40e_rx_group_t *rxg = arg; 4509aee612SRyan Zezeski i40e_t *i40e = rxg->irg_i40e; 469d26e4fcSRobert Mustacchi struct i40e_aqc_remove_macvlan_element_data filt; 479d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 489d26e4fcSRobert Mustacchi int ret, i, last; 499d26e4fcSRobert Mustacchi i40e_uaddr_t *iua; 509d26e4fcSRobert Mustacchi 519d26e4fcSRobert Mustacchi if (I40E_IS_MULTICAST(mac_addr)) 529d26e4fcSRobert Mustacchi return (EINVAL); 539d26e4fcSRobert Mustacchi 549d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 559d26e4fcSRobert Mustacchi 569d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 579d26e4fcSRobert Mustacchi ret = ECANCELED; 589d26e4fcSRobert Mustacchi goto done; 599d26e4fcSRobert Mustacchi } 609d26e4fcSRobert Mustacchi 619d26e4fcSRobert Mustacchi for (i = 0; i < i40e->i40e_resources.ifr_nmacfilt_used; i++) { 629d26e4fcSRobert Mustacchi if (bcmp(mac_addr, i40e->i40e_uaddrs[i].iua_mac, 639d26e4fcSRobert Mustacchi ETHERADDRL) == 0) 649d26e4fcSRobert Mustacchi break; 659d26e4fcSRobert Mustacchi } 669d26e4fcSRobert Mustacchi 679d26e4fcSRobert Mustacchi if (i == i40e->i40e_resources.ifr_nmacfilt_used) { 689d26e4fcSRobert Mustacchi ret = ENOENT; 699d26e4fcSRobert Mustacchi goto done; 709d26e4fcSRobert Mustacchi } 719d26e4fcSRobert Mustacchi 729d26e4fcSRobert Mustacchi iua = &i40e->i40e_uaddrs[i]; 739d26e4fcSRobert Mustacchi ASSERT(i40e->i40e_resources.ifr_nmacfilt_used > 0); 749d26e4fcSRobert Mustacchi 759d26e4fcSRobert Mustacchi bzero(&filt, sizeof (filt)); 769d26e4fcSRobert Mustacchi bcopy(mac_addr, filt.mac_addr, ETHERADDRL); 779d26e4fcSRobert Mustacchi filt.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | 789d26e4fcSRobert Mustacchi I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 799d26e4fcSRobert Mustacchi 809d26e4fcSRobert Mustacchi if (i40e_aq_remove_macvlan(hw, iua->iua_vsi, &filt, 1, NULL) != 819d26e4fcSRobert Mustacchi I40E_SUCCESS) { 829d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to remove mac address " 839d26e4fcSRobert Mustacchi "%2x:%2x:%2x:%2x:%2x:%2x from unicast filter: %d", 849d26e4fcSRobert Mustacchi mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 859d26e4fcSRobert Mustacchi mac_addr[4], mac_addr[5], filt.error_code); 869d26e4fcSRobert Mustacchi ret = EIO; 879d26e4fcSRobert Mustacchi goto done; 889d26e4fcSRobert Mustacchi } 899d26e4fcSRobert Mustacchi 909d26e4fcSRobert Mustacchi last = i40e->i40e_resources.ifr_nmacfilt_used - 1; 919d26e4fcSRobert Mustacchi if (i != last) { 929d26e4fcSRobert Mustacchi i40e_uaddr_t *src = &i40e->i40e_uaddrs[last]; 939d26e4fcSRobert Mustacchi bcopy(src, iua, sizeof (i40e_uaddr_t)); 949d26e4fcSRobert Mustacchi } 959d26e4fcSRobert Mustacchi 969d26e4fcSRobert Mustacchi /* 979d26e4fcSRobert Mustacchi * Set the multicast bit in the last one to indicate to ourselves that 989d26e4fcSRobert Mustacchi * it's invalid. 999d26e4fcSRobert Mustacchi */ 1009d26e4fcSRobert Mustacchi bzero(&i40e->i40e_uaddrs[last], sizeof (i40e_uaddr_t)); 1019d26e4fcSRobert Mustacchi i40e->i40e_uaddrs[last].iua_mac[0] = 0x01; 1029d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt_used--; 1039d26e4fcSRobert Mustacchi ret = 0; 1049d26e4fcSRobert Mustacchi done: 1059d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 1069d26e4fcSRobert Mustacchi 1079d26e4fcSRobert Mustacchi return (ret); 1089d26e4fcSRobert Mustacchi } 1099d26e4fcSRobert Mustacchi 1109d26e4fcSRobert Mustacchi static int 1119d26e4fcSRobert Mustacchi i40e_group_add_mac(void *arg, const uint8_t *mac_addr) 1129d26e4fcSRobert Mustacchi { 11309aee612SRyan Zezeski i40e_rx_group_t *rxg = arg; 11409aee612SRyan Zezeski i40e_t *i40e = rxg->irg_i40e; 11509aee612SRyan Zezeski struct i40e_hw *hw = &i40e->i40e_hw_space; 11609aee612SRyan Zezeski int i, ret; 11709aee612SRyan Zezeski i40e_uaddr_t *iua; 1189d26e4fcSRobert Mustacchi struct i40e_aqc_add_macvlan_element_data filt; 1199d26e4fcSRobert Mustacchi 1209d26e4fcSRobert Mustacchi if (I40E_IS_MULTICAST(mac_addr)) 1219d26e4fcSRobert Mustacchi return (EINVAL); 1229d26e4fcSRobert Mustacchi 1239d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 1249d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 1259d26e4fcSRobert Mustacchi ret = ECANCELED; 1269d26e4fcSRobert Mustacchi goto done; 1279d26e4fcSRobert Mustacchi } 1289d26e4fcSRobert Mustacchi 1299d26e4fcSRobert Mustacchi if (i40e->i40e_resources.ifr_nmacfilt == 1309d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt_used) { 1319d26e4fcSRobert Mustacchi ret = ENOSPC; 1329d26e4fcSRobert Mustacchi goto done; 1339d26e4fcSRobert Mustacchi } 1349d26e4fcSRobert Mustacchi 1359d26e4fcSRobert Mustacchi for (i = 0; i < i40e->i40e_resources.ifr_nmacfilt_used; i++) { 1369d26e4fcSRobert Mustacchi if (bcmp(mac_addr, i40e->i40e_uaddrs[i].iua_mac, 1379d26e4fcSRobert Mustacchi ETHERADDRL) == 0) { 1389d26e4fcSRobert Mustacchi ret = EEXIST; 1399d26e4fcSRobert Mustacchi goto done; 1409d26e4fcSRobert Mustacchi } 1419d26e4fcSRobert Mustacchi } 1429d26e4fcSRobert Mustacchi 1439d26e4fcSRobert Mustacchi bzero(&filt, sizeof (filt)); 1449d26e4fcSRobert Mustacchi bcopy(mac_addr, filt.mac_addr, ETHERADDRL); 1459d26e4fcSRobert Mustacchi filt.flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH | 1469d26e4fcSRobert Mustacchi I40E_AQC_MACVLAN_ADD_IGNORE_VLAN; 1479d26e4fcSRobert Mustacchi 14809aee612SRyan Zezeski if ((ret = i40e_aq_add_macvlan(hw, rxg->irg_vsi_seid, &filt, 1, 1499d26e4fcSRobert Mustacchi NULL)) != I40E_SUCCESS) { 1509d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to add mac address " 1519d26e4fcSRobert Mustacchi "%2x:%2x:%2x:%2x:%2x:%2x to unicast filter: %d", 1529d26e4fcSRobert Mustacchi mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 1539d26e4fcSRobert Mustacchi mac_addr[4], mac_addr[5], ret); 1549d26e4fcSRobert Mustacchi ret = EIO; 1559d26e4fcSRobert Mustacchi goto done; 1569d26e4fcSRobert Mustacchi } 1579d26e4fcSRobert Mustacchi 1589d26e4fcSRobert Mustacchi iua = &i40e->i40e_uaddrs[i40e->i40e_resources.ifr_nmacfilt_used]; 1599d26e4fcSRobert Mustacchi bcopy(mac_addr, iua->iua_mac, ETHERADDRL); 16009aee612SRyan Zezeski iua->iua_vsi = rxg->irg_vsi_seid; 1619d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt_used++; 1629d26e4fcSRobert Mustacchi ASSERT(i40e->i40e_resources.ifr_nmacfilt_used <= 1639d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt); 1649d26e4fcSRobert Mustacchi ret = 0; 1659d26e4fcSRobert Mustacchi done: 1669d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 1679d26e4fcSRobert Mustacchi return (ret); 1689d26e4fcSRobert Mustacchi } 1699d26e4fcSRobert Mustacchi 1709d26e4fcSRobert Mustacchi static int 1719d26e4fcSRobert Mustacchi i40e_m_start(void *arg) 1729d26e4fcSRobert Mustacchi { 1739d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 1749d26e4fcSRobert Mustacchi int rc = 0; 1759d26e4fcSRobert Mustacchi 1769d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 1779d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 1789d26e4fcSRobert Mustacchi rc = ECANCELED; 1799d26e4fcSRobert Mustacchi goto done; 1809d26e4fcSRobert Mustacchi } 1819d26e4fcSRobert Mustacchi 182*aa2a44afSPaul Winder if (!i40e_start(i40e)) { 1839d26e4fcSRobert Mustacchi rc = EIO; 1849d26e4fcSRobert Mustacchi goto done; 1859d26e4fcSRobert Mustacchi } 1869d26e4fcSRobert Mustacchi 1879d26e4fcSRobert Mustacchi atomic_or_32(&i40e->i40e_state, I40E_STARTED); 1889d26e4fcSRobert Mustacchi done: 1899d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 1909d26e4fcSRobert Mustacchi 1919d26e4fcSRobert Mustacchi return (rc); 1929d26e4fcSRobert Mustacchi } 1939d26e4fcSRobert Mustacchi 1949d26e4fcSRobert Mustacchi static void 1959d26e4fcSRobert Mustacchi i40e_m_stop(void *arg) 1969d26e4fcSRobert Mustacchi { 1979d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 1989d26e4fcSRobert Mustacchi 1999d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 2009d26e4fcSRobert Mustacchi 2019d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) 2029d26e4fcSRobert Mustacchi goto done; 2039d26e4fcSRobert Mustacchi 2049d26e4fcSRobert Mustacchi atomic_and_32(&i40e->i40e_state, ~I40E_STARTED); 205*aa2a44afSPaul Winder i40e_stop(i40e); 2069d26e4fcSRobert Mustacchi done: 2079d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 2089d26e4fcSRobert Mustacchi } 2099d26e4fcSRobert Mustacchi 2109d26e4fcSRobert Mustacchi /* 2119d26e4fcSRobert Mustacchi * Enable and disable promiscuous mode as requested. We have to toggle both 2129d26e4fcSRobert Mustacchi * unicast and multicast. Note that multicast may already be enabled due to the 2139d26e4fcSRobert Mustacchi * i40e_m_multicast may toggle it itself. See i40e_main.c for more information 2149d26e4fcSRobert Mustacchi * on this. 2159d26e4fcSRobert Mustacchi */ 2169d26e4fcSRobert Mustacchi static int 2179d26e4fcSRobert Mustacchi i40e_m_promisc(void *arg, boolean_t on) 2189d26e4fcSRobert Mustacchi { 2199d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 2209d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 2219d26e4fcSRobert Mustacchi int ret = 0, err = 0; 2229d26e4fcSRobert Mustacchi 2239d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 2249d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 2259d26e4fcSRobert Mustacchi ret = ECANCELED; 2269d26e4fcSRobert Mustacchi goto done; 2279d26e4fcSRobert Mustacchi } 2289d26e4fcSRobert Mustacchi 2299d26e4fcSRobert Mustacchi 23009aee612SRyan Zezeski ret = i40e_aq_set_vsi_unicast_promiscuous(hw, I40E_DEF_VSI_SEID(i40e), 2313d75a287SRobert Mustacchi on, NULL, B_FALSE); 2329d26e4fcSRobert Mustacchi if (ret != I40E_SUCCESS) { 2339d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to %s unicast promiscuity on " 2349d26e4fcSRobert Mustacchi "the default VSI: %d", on == B_TRUE ? "enable" : "disable", 2359d26e4fcSRobert Mustacchi ret); 2369d26e4fcSRobert Mustacchi err = EIO; 2379d26e4fcSRobert Mustacchi goto done; 2389d26e4fcSRobert Mustacchi } 2399d26e4fcSRobert Mustacchi 2409d26e4fcSRobert Mustacchi /* 2419d26e4fcSRobert Mustacchi * If we have a non-zero mcast_promisc_count, then it has already been 2429d26e4fcSRobert Mustacchi * enabled or we need to leave it that way and not touch it. 2439d26e4fcSRobert Mustacchi */ 2449d26e4fcSRobert Mustacchi if (i40e->i40e_mcast_promisc_count > 0) { 2459d26e4fcSRobert Mustacchi i40e->i40e_promisc_on = on; 2469d26e4fcSRobert Mustacchi goto done; 2479d26e4fcSRobert Mustacchi } 2489d26e4fcSRobert Mustacchi 24909aee612SRyan Zezeski ret = i40e_aq_set_vsi_multicast_promiscuous(hw, I40E_DEF_VSI_SEID(i40e), 2509d26e4fcSRobert Mustacchi on, NULL); 2519d26e4fcSRobert Mustacchi if (ret != I40E_SUCCESS) { 2529d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to %s multicast promiscuity on " 2539d26e4fcSRobert Mustacchi "the default VSI: %d", on == B_TRUE ? "enable" : "disable", 2549d26e4fcSRobert Mustacchi ret); 2559d26e4fcSRobert Mustacchi 2569d26e4fcSRobert Mustacchi /* 2579d26e4fcSRobert Mustacchi * Try our best to put us back into a state that MAC expects us 2589d26e4fcSRobert Mustacchi * to be in. 2599d26e4fcSRobert Mustacchi */ 26009aee612SRyan Zezeski ret = i40e_aq_set_vsi_unicast_promiscuous(hw, 26109aee612SRyan Zezeski I40E_DEF_VSI_SEID(i40e), !on, NULL, B_FALSE); 2629d26e4fcSRobert Mustacchi if (ret != I40E_SUCCESS) { 2639d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to %s unicast promiscuity on " 2649d26e4fcSRobert Mustacchi "the default VSI after toggling multicast failed: " 2659d26e4fcSRobert Mustacchi "%d", on == B_TRUE ? "disable" : "enable", ret); 2669d26e4fcSRobert Mustacchi } 2679d26e4fcSRobert Mustacchi 2689d26e4fcSRobert Mustacchi err = EIO; 2699d26e4fcSRobert Mustacchi goto done; 2709d26e4fcSRobert Mustacchi } else { 2719d26e4fcSRobert Mustacchi i40e->i40e_promisc_on = on; 2729d26e4fcSRobert Mustacchi } 2739d26e4fcSRobert Mustacchi 2749d26e4fcSRobert Mustacchi done: 2759d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 2769d26e4fcSRobert Mustacchi return (err); 2779d26e4fcSRobert Mustacchi } 2789d26e4fcSRobert Mustacchi 2799d26e4fcSRobert Mustacchi /* 2809d26e4fcSRobert Mustacchi * See the big theory statement in i40e_main.c for multicast address management. 2819d26e4fcSRobert Mustacchi */ 2829d26e4fcSRobert Mustacchi static int 2839d26e4fcSRobert Mustacchi i40e_multicast_add(i40e_t *i40e, const uint8_t *multicast_address) 2849d26e4fcSRobert Mustacchi { 2859d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 2869d26e4fcSRobert Mustacchi struct i40e_aqc_add_macvlan_element_data filt; 2879d26e4fcSRobert Mustacchi i40e_maddr_t *mc; 2889d26e4fcSRobert Mustacchi int ret; 2899d26e4fcSRobert Mustacchi 2909d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 2919d26e4fcSRobert Mustacchi 2929d26e4fcSRobert Mustacchi if (i40e->i40e_resources.ifr_nmcastfilt_used == 2939d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmcastfilt) { 2949d26e4fcSRobert Mustacchi if (i40e->i40e_mcast_promisc_count == 0 && 2959d26e4fcSRobert Mustacchi i40e->i40e_promisc_on == B_FALSE) { 2969d26e4fcSRobert Mustacchi ret = i40e_aq_set_vsi_multicast_promiscuous(hw, 29709aee612SRyan Zezeski I40E_DEF_VSI_SEID(i40e), B_TRUE, NULL); 2989d26e4fcSRobert Mustacchi if (ret != I40E_SUCCESS) { 2999d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to enable multicast " 3009d26e4fcSRobert Mustacchi "promiscuous mode on VSI %d: %d", 30109aee612SRyan Zezeski I40E_DEF_VSI_SEID(i40e), ret); 3029d26e4fcSRobert Mustacchi return (EIO); 3039d26e4fcSRobert Mustacchi } 3049d26e4fcSRobert Mustacchi } 3059d26e4fcSRobert Mustacchi i40e->i40e_mcast_promisc_count++; 3069d26e4fcSRobert Mustacchi return (0); 3079d26e4fcSRobert Mustacchi } 3089d26e4fcSRobert Mustacchi 3099d26e4fcSRobert Mustacchi mc = &i40e->i40e_maddrs[i40e->i40e_resources.ifr_nmcastfilt_used]; 3109d26e4fcSRobert Mustacchi bzero(&filt, sizeof (filt)); 3119d26e4fcSRobert Mustacchi bcopy(multicast_address, filt.mac_addr, ETHERADDRL); 3129d26e4fcSRobert Mustacchi filt.flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH | 3139d26e4fcSRobert Mustacchi I40E_AQC_MACVLAN_ADD_IGNORE_VLAN; 3149d26e4fcSRobert Mustacchi 31509aee612SRyan Zezeski if ((ret = i40e_aq_add_macvlan(hw, I40E_DEF_VSI_SEID(i40e), &filt, 1, 3169d26e4fcSRobert Mustacchi NULL)) != I40E_SUCCESS) { 3179d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to add mac address " 3189d26e4fcSRobert Mustacchi "%2x:%2x:%2x:%2x:%2x:%2x to multicast filter: %d", 3199d26e4fcSRobert Mustacchi multicast_address[0], multicast_address[1], 3209d26e4fcSRobert Mustacchi multicast_address[2], multicast_address[3], 3219d26e4fcSRobert Mustacchi multicast_address[4], multicast_address[5], 3229d26e4fcSRobert Mustacchi ret); 3239d26e4fcSRobert Mustacchi return (EIO); 3249d26e4fcSRobert Mustacchi } 3259d26e4fcSRobert Mustacchi 3269d26e4fcSRobert Mustacchi bcopy(multicast_address, mc->ima_mac, ETHERADDRL); 3279d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmcastfilt_used++; 3289d26e4fcSRobert Mustacchi return (0); 3299d26e4fcSRobert Mustacchi } 3309d26e4fcSRobert Mustacchi 3319d26e4fcSRobert Mustacchi /* 3329d26e4fcSRobert Mustacchi * See the big theory statement in i40e_main.c for multicast address management. 3339d26e4fcSRobert Mustacchi */ 3349d26e4fcSRobert Mustacchi static int 3359d26e4fcSRobert Mustacchi i40e_multicast_remove(i40e_t *i40e, const uint8_t *multicast_address) 3369d26e4fcSRobert Mustacchi { 3379d26e4fcSRobert Mustacchi int i, ret; 3389d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 3399d26e4fcSRobert Mustacchi 3409d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 3419d26e4fcSRobert Mustacchi 3429d26e4fcSRobert Mustacchi for (i = 0; i < i40e->i40e_resources.ifr_nmcastfilt_used; i++) { 3439d26e4fcSRobert Mustacchi struct i40e_aqc_remove_macvlan_element_data filt; 3449d26e4fcSRobert Mustacchi int last; 3459d26e4fcSRobert Mustacchi 3469d26e4fcSRobert Mustacchi if (bcmp(multicast_address, i40e->i40e_maddrs[i].ima_mac, 3479d26e4fcSRobert Mustacchi ETHERADDRL) != 0) { 3489d26e4fcSRobert Mustacchi continue; 3499d26e4fcSRobert Mustacchi } 3509d26e4fcSRobert Mustacchi 3519d26e4fcSRobert Mustacchi bzero(&filt, sizeof (filt)); 3529d26e4fcSRobert Mustacchi bcopy(multicast_address, filt.mac_addr, ETHERADDRL); 3539d26e4fcSRobert Mustacchi filt.flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH | 3549d26e4fcSRobert Mustacchi I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 3559d26e4fcSRobert Mustacchi 35609aee612SRyan Zezeski if (i40e_aq_remove_macvlan(hw, I40E_DEF_VSI_SEID(i40e), &filt, 35709aee612SRyan Zezeski 1, NULL) != I40E_SUCCESS) { 3589d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to remove mac address " 3599d26e4fcSRobert Mustacchi "%2x:%2x:%2x:%2x:%2x:%2x from multicast " 3609d26e4fcSRobert Mustacchi "filter: %d", 3619d26e4fcSRobert Mustacchi multicast_address[0], multicast_address[1], 3629d26e4fcSRobert Mustacchi multicast_address[2], multicast_address[3], 3639d26e4fcSRobert Mustacchi multicast_address[4], multicast_address[5], 3649d26e4fcSRobert Mustacchi filt.error_code); 3659d26e4fcSRobert Mustacchi return (EIO); 3669d26e4fcSRobert Mustacchi } 3679d26e4fcSRobert Mustacchi 3689d26e4fcSRobert Mustacchi last = i40e->i40e_resources.ifr_nmcastfilt_used - 1; 3699d26e4fcSRobert Mustacchi if (i != last) { 3709d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_maddrs[last], &i40e->i40e_maddrs[i], 3719d26e4fcSRobert Mustacchi sizeof (i40e_maddr_t)); 3729d26e4fcSRobert Mustacchi bzero(&i40e->i40e_maddrs[last], sizeof (i40e_maddr_t)); 3739d26e4fcSRobert Mustacchi } 3749d26e4fcSRobert Mustacchi 3759d26e4fcSRobert Mustacchi ASSERT(i40e->i40e_resources.ifr_nmcastfilt_used > 0); 3769d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmcastfilt_used--; 3779d26e4fcSRobert Mustacchi return (0); 3789d26e4fcSRobert Mustacchi } 3799d26e4fcSRobert Mustacchi 3809d26e4fcSRobert Mustacchi if (i40e->i40e_mcast_promisc_count > 0) { 3819d26e4fcSRobert Mustacchi if (i40e->i40e_mcast_promisc_count == 1 && 3829d26e4fcSRobert Mustacchi i40e->i40e_promisc_on == B_FALSE) { 3839d26e4fcSRobert Mustacchi ret = i40e_aq_set_vsi_multicast_promiscuous(hw, 38409aee612SRyan Zezeski I40E_DEF_VSI_SEID(i40e), B_FALSE, NULL); 3859d26e4fcSRobert Mustacchi if (ret != I40E_SUCCESS) { 3869d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to disable " 3879d26e4fcSRobert Mustacchi "multicast promiscuous mode on VSI %d: %d", 38809aee612SRyan Zezeski I40E_DEF_VSI_SEID(i40e), ret); 3899d26e4fcSRobert Mustacchi return (EIO); 3909d26e4fcSRobert Mustacchi } 3919d26e4fcSRobert Mustacchi } 3929d26e4fcSRobert Mustacchi i40e->i40e_mcast_promisc_count--; 3939d26e4fcSRobert Mustacchi 3949d26e4fcSRobert Mustacchi return (0); 3959d26e4fcSRobert Mustacchi } 3969d26e4fcSRobert Mustacchi 3979d26e4fcSRobert Mustacchi return (ENOENT); 3989d26e4fcSRobert Mustacchi } 3999d26e4fcSRobert Mustacchi 4009d26e4fcSRobert Mustacchi static int 4019d26e4fcSRobert Mustacchi i40e_m_multicast(void *arg, boolean_t add, const uint8_t *multicast_address) 4029d26e4fcSRobert Mustacchi { 4039d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 4049d26e4fcSRobert Mustacchi int rc; 4059d26e4fcSRobert Mustacchi 4069d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 4079d26e4fcSRobert Mustacchi 4089d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 4099d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 4109d26e4fcSRobert Mustacchi return (ECANCELED); 4119d26e4fcSRobert Mustacchi } 4129d26e4fcSRobert Mustacchi 4139d26e4fcSRobert Mustacchi if (add == B_TRUE) { 4149d26e4fcSRobert Mustacchi rc = i40e_multicast_add(i40e, multicast_address); 4159d26e4fcSRobert Mustacchi } else { 4169d26e4fcSRobert Mustacchi rc = i40e_multicast_remove(i40e, multicast_address); 4179d26e4fcSRobert Mustacchi } 4189d26e4fcSRobert Mustacchi 4199d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 4209d26e4fcSRobert Mustacchi return (rc); 4219d26e4fcSRobert Mustacchi } 4229d26e4fcSRobert Mustacchi 4239d26e4fcSRobert Mustacchi /* ARGSUSED */ 4249d26e4fcSRobert Mustacchi static void 4259d26e4fcSRobert Mustacchi i40e_m_ioctl(void *arg, queue_t *q, mblk_t *mp) 4269d26e4fcSRobert Mustacchi { 4279d26e4fcSRobert Mustacchi /* 4289d26e4fcSRobert Mustacchi * At this time, we don't support toggling i40e into loopback mode. It's 4299d26e4fcSRobert Mustacchi * questionable how much value this has when there's no clear way to 4309d26e4fcSRobert Mustacchi * toggle this behavior from a supported way in userland. 4319d26e4fcSRobert Mustacchi */ 4329d26e4fcSRobert Mustacchi miocnak(q, mp, 0, EINVAL); 4339d26e4fcSRobert Mustacchi } 4349d26e4fcSRobert Mustacchi 4359d26e4fcSRobert Mustacchi static int 4369d26e4fcSRobert Mustacchi i40e_ring_start(mac_ring_driver_t rh, uint64_t gen_num) 4379d26e4fcSRobert Mustacchi { 4389d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh; 439*aa2a44afSPaul Winder int rv; 440*aa2a44afSPaul Winder 441*aa2a44afSPaul Winder if ((rv = i40e_setup_ring(itrq)) != 0) 442*aa2a44afSPaul Winder return (rv); 4439d26e4fcSRobert Mustacchi 4449d26e4fcSRobert Mustacchi /* 4459d26e4fcSRobert Mustacchi * GLDv3 requires we keep track of a generation number, as it uses 4469d26e4fcSRobert Mustacchi * that number to keep track of whether or not a ring is active. 4479d26e4fcSRobert Mustacchi */ 4489d26e4fcSRobert Mustacchi mutex_enter(&itrq->itrq_rx_lock); 4499d26e4fcSRobert Mustacchi itrq->itrq_rxgen = gen_num; 4509d26e4fcSRobert Mustacchi mutex_exit(&itrq->itrq_rx_lock); 4519d26e4fcSRobert Mustacchi return (0); 4529d26e4fcSRobert Mustacchi } 4539d26e4fcSRobert Mustacchi 454*aa2a44afSPaul Winder static void 455*aa2a44afSPaul Winder i40e_ring_stop(mac_ring_driver_t rh) 456*aa2a44afSPaul Winder { 457*aa2a44afSPaul Winder i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh; 458*aa2a44afSPaul Winder 459*aa2a44afSPaul Winder if (!i40e_shutdown_ring(itrq)) { 460*aa2a44afSPaul Winder i40e_t *i40e = itrq->itrq_i40e; 461*aa2a44afSPaul Winder 462*aa2a44afSPaul Winder ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_LOST); 463*aa2a44afSPaul Winder i40e_error(i40e, "Failed to stop ring %u", itrq->itrq_index); 464*aa2a44afSPaul Winder } 465*aa2a44afSPaul Winder } 466*aa2a44afSPaul Winder 4679d26e4fcSRobert Mustacchi /* ARGSUSED */ 4689d26e4fcSRobert Mustacchi static int 4699d26e4fcSRobert Mustacchi i40e_rx_ring_intr_enable(mac_intr_handle_t intrh) 4709d26e4fcSRobert Mustacchi { 4719d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = (i40e_trqpair_t *)intrh; 4729d26e4fcSRobert Mustacchi 473396505afSPaul Winder mutex_enter(&itrq->itrq_rx_lock); 474396505afSPaul Winder ASSERT(itrq->itrq_intr_poll == B_TRUE); 475338749cbSRobert Mustacchi i40e_intr_rx_queue_enable(itrq); 476396505afSPaul Winder itrq->itrq_intr_poll = B_FALSE; 477396505afSPaul Winder mutex_exit(&itrq->itrq_rx_lock); 4789d26e4fcSRobert Mustacchi 4799d26e4fcSRobert Mustacchi return (0); 4809d26e4fcSRobert Mustacchi } 4819d26e4fcSRobert Mustacchi 4829d26e4fcSRobert Mustacchi /* ARGSUSED */ 4839d26e4fcSRobert Mustacchi static int 4849d26e4fcSRobert Mustacchi i40e_rx_ring_intr_disable(mac_intr_handle_t intrh) 4859d26e4fcSRobert Mustacchi { 4869d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = (i40e_trqpair_t *)intrh; 4879d26e4fcSRobert Mustacchi 488396505afSPaul Winder mutex_enter(&itrq->itrq_rx_lock); 489338749cbSRobert Mustacchi i40e_intr_rx_queue_disable(itrq); 490396505afSPaul Winder itrq->itrq_intr_poll = B_TRUE; 491396505afSPaul Winder mutex_exit(&itrq->itrq_rx_lock); 4929d26e4fcSRobert Mustacchi 4939d26e4fcSRobert Mustacchi return (0); 4949d26e4fcSRobert Mustacchi } 4959d26e4fcSRobert Mustacchi 4969d26e4fcSRobert Mustacchi /* ARGSUSED */ 4979d26e4fcSRobert Mustacchi static void 4989d26e4fcSRobert Mustacchi i40e_fill_tx_ring(void *arg, mac_ring_type_t rtype, const int group_index, 4999d26e4fcSRobert Mustacchi const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 5009d26e4fcSRobert Mustacchi { 5019d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 5029d26e4fcSRobert Mustacchi mac_intr_t *mintr = &infop->mri_intr; 5039d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = &(i40e->i40e_trqpairs[ring_index]); 5049d26e4fcSRobert Mustacchi 5059d26e4fcSRobert Mustacchi /* 5069d26e4fcSRobert Mustacchi * Note the group index here is expected to be -1 due to the fact that 5079d26e4fcSRobert Mustacchi * we're not actually grouping things tx-wise at this time. 5089d26e4fcSRobert Mustacchi */ 5099d26e4fcSRobert Mustacchi ASSERT(group_index == -1); 51009aee612SRyan Zezeski ASSERT(ring_index < i40e->i40e_num_trqpairs_per_vsi); 5119d26e4fcSRobert Mustacchi 5129d26e4fcSRobert Mustacchi itrq->itrq_mactxring = rh; 5139d26e4fcSRobert Mustacchi infop->mri_driver = (mac_ring_driver_t)itrq; 5149d26e4fcSRobert Mustacchi infop->mri_start = NULL; 5159d26e4fcSRobert Mustacchi infop->mri_stop = NULL; 5169d26e4fcSRobert Mustacchi infop->mri_tx = i40e_ring_tx; 5179d26e4fcSRobert Mustacchi infop->mri_stat = i40e_tx_ring_stat; 5189d26e4fcSRobert Mustacchi 5199d26e4fcSRobert Mustacchi /* 5209d26e4fcSRobert Mustacchi * We only provide the handle in cases where we have MSI-X interrupts, 5219d26e4fcSRobert Mustacchi * to indicate that we'd actually support retargetting. 5229d26e4fcSRobert Mustacchi */ 5239d26e4fcSRobert Mustacchi if (i40e->i40e_intr_type & DDI_INTR_TYPE_MSIX) { 5249d26e4fcSRobert Mustacchi mintr->mi_ddi_handle = 5259d26e4fcSRobert Mustacchi i40e->i40e_intr_handles[itrq->itrq_tx_intrvec]; 5269d26e4fcSRobert Mustacchi } 5279d26e4fcSRobert Mustacchi } 5289d26e4fcSRobert Mustacchi 5299d26e4fcSRobert Mustacchi /* ARGSUSED */ 5309d26e4fcSRobert Mustacchi static void 5319d26e4fcSRobert Mustacchi i40e_fill_rx_ring(void *arg, mac_ring_type_t rtype, const int group_index, 5329d26e4fcSRobert Mustacchi const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 5339d26e4fcSRobert Mustacchi { 5349d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 5359d26e4fcSRobert Mustacchi mac_intr_t *mintr = &infop->mri_intr; 53609aee612SRyan Zezeski uint_t trqpair_index; 53709aee612SRyan Zezeski i40e_trqpair_t *itrq; 5389d26e4fcSRobert Mustacchi 53909aee612SRyan Zezeski /* This assumes static groups. */ 54009aee612SRyan Zezeski ASSERT3S(group_index, >=, 0); 54109aee612SRyan Zezeski ASSERT3S(ring_index, >=, 0); 54209aee612SRyan Zezeski trqpair_index = (group_index * i40e->i40e_num_trqpairs_per_vsi) + 54309aee612SRyan Zezeski ring_index; 54409aee612SRyan Zezeski ASSERT3U(trqpair_index, <, i40e->i40e_num_trqpairs); 54509aee612SRyan Zezeski itrq = &i40e->i40e_trqpairs[trqpair_index]; 5469d26e4fcSRobert Mustacchi 5479d26e4fcSRobert Mustacchi itrq->itrq_macrxring = rh; 5489d26e4fcSRobert Mustacchi infop->mri_driver = (mac_ring_driver_t)itrq; 5499d26e4fcSRobert Mustacchi infop->mri_start = i40e_ring_start; 550*aa2a44afSPaul Winder infop->mri_stop = i40e_ring_stop; 5519d26e4fcSRobert Mustacchi infop->mri_poll = i40e_ring_rx_poll; 5529d26e4fcSRobert Mustacchi infop->mri_stat = i40e_rx_ring_stat; 5539d26e4fcSRobert Mustacchi mintr->mi_handle = (mac_intr_handle_t)itrq; 5549d26e4fcSRobert Mustacchi mintr->mi_enable = i40e_rx_ring_intr_enable; 5559d26e4fcSRobert Mustacchi mintr->mi_disable = i40e_rx_ring_intr_disable; 5569d26e4fcSRobert Mustacchi 5579d26e4fcSRobert Mustacchi /* 5589d26e4fcSRobert Mustacchi * We only provide the handle in cases where we have MSI-X interrupts, 5599d26e4fcSRobert Mustacchi * to indicate that we'd actually support retargetting. 5609d26e4fcSRobert Mustacchi */ 5619d26e4fcSRobert Mustacchi if (i40e->i40e_intr_type & DDI_INTR_TYPE_MSIX) { 5629d26e4fcSRobert Mustacchi mintr->mi_ddi_handle = 5639d26e4fcSRobert Mustacchi i40e->i40e_intr_handles[itrq->itrq_rx_intrvec]; 5649d26e4fcSRobert Mustacchi } 5659d26e4fcSRobert Mustacchi } 5669d26e4fcSRobert Mustacchi 5679d26e4fcSRobert Mustacchi /* ARGSUSED */ 5689d26e4fcSRobert Mustacchi static void 5699d26e4fcSRobert Mustacchi i40e_fill_rx_group(void *arg, mac_ring_type_t rtype, const int index, 5709d26e4fcSRobert Mustacchi mac_group_info_t *infop, mac_group_handle_t gh) 5719d26e4fcSRobert Mustacchi { 5729d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 57309aee612SRyan Zezeski i40e_rx_group_t *rxg; 5749d26e4fcSRobert Mustacchi 5759d26e4fcSRobert Mustacchi if (rtype != MAC_RING_TYPE_RX) 5769d26e4fcSRobert Mustacchi return; 5779d26e4fcSRobert Mustacchi 57809aee612SRyan Zezeski rxg = &i40e->i40e_rx_groups[index]; 57909aee612SRyan Zezeski rxg->irg_grp_hdl = gh; 58009aee612SRyan Zezeski 58109aee612SRyan Zezeski infop->mgi_driver = (mac_group_driver_t)rxg; 5829d26e4fcSRobert Mustacchi infop->mgi_start = NULL; 5839d26e4fcSRobert Mustacchi infop->mgi_stop = NULL; 5849d26e4fcSRobert Mustacchi infop->mgi_addmac = i40e_group_add_mac; 5859d26e4fcSRobert Mustacchi infop->mgi_remmac = i40e_group_remove_mac; 5869d26e4fcSRobert Mustacchi 58788628b1bSRyan Zezeski ASSERT3U(i40e->i40e_num_rx_groups, <=, I40E_MAX_NUM_RX_GROUPS); 58809aee612SRyan Zezeski infop->mgi_count = i40e->i40e_num_trqpairs_per_vsi; 5899d26e4fcSRobert Mustacchi } 5909d26e4fcSRobert Mustacchi 59145d3dd98SRobert Mustacchi static int 59245d3dd98SRobert Mustacchi i40e_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) 59345d3dd98SRobert Mustacchi { 59445d3dd98SRobert Mustacchi boolean_t present, usable; 59545d3dd98SRobert Mustacchi i40e_t *i40e = arg; 59645d3dd98SRobert Mustacchi 59745d3dd98SRobert Mustacchi if (id != 0 || infop == NULL) 59845d3dd98SRobert Mustacchi return (EINVAL); 59945d3dd98SRobert Mustacchi 60045d3dd98SRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 601286d309cSRobert Mustacchi switch (i40e->i40e_hw_space.phy.link_info.module_type[0]) { 602286d309cSRobert Mustacchi case I40E_MODULE_TYPE_SFP: 603286d309cSRobert Mustacchi case I40E_MODULE_TYPE_QSFP: 604286d309cSRobert Mustacchi break; 605286d309cSRobert Mustacchi default: 606286d309cSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 607286d309cSRobert Mustacchi return (ENOTSUP); 608286d309cSRobert Mustacchi } 609286d309cSRobert Mustacchi 61045d3dd98SRobert Mustacchi present = !!(i40e->i40e_hw_space.phy.link_info.link_info & 61145d3dd98SRobert Mustacchi I40E_AQ_MEDIA_AVAILABLE); 61245d3dd98SRobert Mustacchi if (present) { 61345d3dd98SRobert Mustacchi usable = !!(i40e->i40e_hw_space.phy.link_info.an_info & 61445d3dd98SRobert Mustacchi I40E_AQ_QUALIFIED_MODULE); 61545d3dd98SRobert Mustacchi } else { 61645d3dd98SRobert Mustacchi usable = B_FALSE; 61745d3dd98SRobert Mustacchi } 61845d3dd98SRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 61945d3dd98SRobert Mustacchi 62045d3dd98SRobert Mustacchi mac_transceiver_info_set_usable(infop, usable); 62145d3dd98SRobert Mustacchi mac_transceiver_info_set_present(infop, present); 62245d3dd98SRobert Mustacchi 62345d3dd98SRobert Mustacchi return (0); 62445d3dd98SRobert Mustacchi } 62545d3dd98SRobert Mustacchi 626286d309cSRobert Mustacchi static int 627286d309cSRobert Mustacchi i40e_transceiver_read(void *arg, uint_t id, uint_t page, void *buf, 628286d309cSRobert Mustacchi size_t nbytes, off_t offset, size_t *nread) 629286d309cSRobert Mustacchi { 630286d309cSRobert Mustacchi i40e_t *i40e = arg; 631286d309cSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 632286d309cSRobert Mustacchi uint8_t *buf8 = buf; 633286d309cSRobert Mustacchi size_t i; 634286d309cSRobert Mustacchi 635286d309cSRobert Mustacchi if (id != 0 || buf == NULL || nbytes == 0 || nread == NULL || 636286d309cSRobert Mustacchi (page != 0xa0 && page != 0xa2) || offset < 0) 637286d309cSRobert Mustacchi return (EINVAL); 638286d309cSRobert Mustacchi 639286d309cSRobert Mustacchi /* 640286d309cSRobert Mustacchi * Both supported pages have a length of 256 bytes, ensure nothing asks 641286d309cSRobert Mustacchi * us to go beyond that. 642286d309cSRobert Mustacchi */ 643286d309cSRobert Mustacchi if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) { 644286d309cSRobert Mustacchi return (EINVAL); 645286d309cSRobert Mustacchi } 646286d309cSRobert Mustacchi 647286d309cSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 648286d309cSRobert Mustacchi switch (i40e->i40e_hw_space.phy.link_info.module_type[0]) { 649286d309cSRobert Mustacchi case I40E_MODULE_TYPE_SFP: 650286d309cSRobert Mustacchi case I40E_MODULE_TYPE_QSFP: 651286d309cSRobert Mustacchi break; 652286d309cSRobert Mustacchi default: 653286d309cSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 654286d309cSRobert Mustacchi return (ENOTSUP); 655286d309cSRobert Mustacchi } 656286d309cSRobert Mustacchi 657286d309cSRobert Mustacchi /* 658286d309cSRobert Mustacchi * Make sure we have a sufficiently new firmware version to run this 659286d309cSRobert Mustacchi * command. This was introduced in firmware API 1.7. This is apparently 660286d309cSRobert Mustacchi * only supported on the XL710 MAC, not the XL722. 661286d309cSRobert Mustacchi */ 662286d309cSRobert Mustacchi if (hw->mac.type != I40E_MAC_XL710 || hw->aq.api_maj_ver != 1 || 663286d309cSRobert Mustacchi hw->aq.api_min_ver < 7) { 664286d309cSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 665286d309cSRobert Mustacchi return (ENOTSUP); 666286d309cSRobert Mustacchi } 667286d309cSRobert Mustacchi 668286d309cSRobert Mustacchi for (i = 0; i < nbytes; i++, offset++) { 669286d309cSRobert Mustacchi enum i40e_status_code status; 670286d309cSRobert Mustacchi uint32_t val; 671286d309cSRobert Mustacchi 672286d309cSRobert Mustacchi status = i40e_aq_get_phy_register(hw, 673286d309cSRobert Mustacchi I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, page, offset, 674286d309cSRobert Mustacchi &val, NULL); 675286d309cSRobert Mustacchi if (status != I40E_SUCCESS) { 676286d309cSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 677286d309cSRobert Mustacchi return (EIO); 678286d309cSRobert Mustacchi } 679286d309cSRobert Mustacchi 680286d309cSRobert Mustacchi buf8[i] = (uint8_t)val; 681286d309cSRobert Mustacchi } 682286d309cSRobert Mustacchi 683286d309cSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 684286d309cSRobert Mustacchi *nread = nbytes; 685286d309cSRobert Mustacchi 686286d309cSRobert Mustacchi return (0); 687286d309cSRobert Mustacchi } 688286d309cSRobert Mustacchi 689c1e9c696SRobert Mustacchi static int 690c1e9c696SRobert Mustacchi i40e_gld_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 691c1e9c696SRobert Mustacchi { 692c1e9c696SRobert Mustacchi i40e_t *i40e = arg; 693c1e9c696SRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 694c1e9c696SRobert Mustacchi 695c1e9c696SRobert Mustacchi if (flags != 0) 696c1e9c696SRobert Mustacchi return (EINVAL); 697c1e9c696SRobert Mustacchi 698c1e9c696SRobert Mustacchi if (mode != MAC_LED_DEFAULT && 699c1e9c696SRobert Mustacchi mode != MAC_LED_IDENT && 700c1e9c696SRobert Mustacchi mode != MAC_LED_OFF && 701c1e9c696SRobert Mustacchi mode != MAC_LED_ON) 702c1e9c696SRobert Mustacchi return (ENOTSUP); 703c1e9c696SRobert Mustacchi 704c1e9c696SRobert Mustacchi if (mode != MAC_LED_DEFAULT && !i40e->i40e_led_saved) { 705c1e9c696SRobert Mustacchi i40e->i40e_led_status = i40e_led_get(hw); 706c1e9c696SRobert Mustacchi i40e->i40e_led_saved = B_TRUE; 707c1e9c696SRobert Mustacchi } 708c1e9c696SRobert Mustacchi 709c1e9c696SRobert Mustacchi switch (mode) { 710c1e9c696SRobert Mustacchi case MAC_LED_DEFAULT: 711c1e9c696SRobert Mustacchi if (i40e->i40e_led_saved) { 712c1e9c696SRobert Mustacchi i40e_led_set(hw, i40e->i40e_led_status, B_FALSE); 713c1e9c696SRobert Mustacchi i40e->i40e_led_status = 0; 714c1e9c696SRobert Mustacchi i40e->i40e_led_saved = B_FALSE; 715c1e9c696SRobert Mustacchi } 716c1e9c696SRobert Mustacchi break; 717c1e9c696SRobert Mustacchi case MAC_LED_IDENT: 718c1e9c696SRobert Mustacchi i40e_led_set(hw, 0xf, B_TRUE); 719c1e9c696SRobert Mustacchi break; 720c1e9c696SRobert Mustacchi case MAC_LED_OFF: 721c1e9c696SRobert Mustacchi i40e_led_set(hw, 0x0, B_FALSE); 722c1e9c696SRobert Mustacchi break; 723c1e9c696SRobert Mustacchi case MAC_LED_ON: 724c1e9c696SRobert Mustacchi i40e_led_set(hw, 0xf, B_FALSE); 725c1e9c696SRobert Mustacchi break; 726c1e9c696SRobert Mustacchi default: 727c1e9c696SRobert Mustacchi return (ENOTSUP); 728c1e9c696SRobert Mustacchi } 729c1e9c696SRobert Mustacchi 730c1e9c696SRobert Mustacchi return (0); 731c1e9c696SRobert Mustacchi } 732c1e9c696SRobert Mustacchi 7339d26e4fcSRobert Mustacchi static boolean_t 7349d26e4fcSRobert Mustacchi i40e_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 7359d26e4fcSRobert Mustacchi { 7369d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 7379d26e4fcSRobert Mustacchi mac_capab_rings_t *cap_rings; 73845d3dd98SRobert Mustacchi mac_capab_transceiver_t *mct; 739c1e9c696SRobert Mustacchi mac_capab_led_t *mcl; 7409d26e4fcSRobert Mustacchi 7419d26e4fcSRobert Mustacchi switch (cap) { 7429d26e4fcSRobert Mustacchi case MAC_CAPAB_HCKSUM: { 7439d26e4fcSRobert Mustacchi uint32_t *txflags = cap_data; 7449d26e4fcSRobert Mustacchi 7459d26e4fcSRobert Mustacchi *txflags = 0; 7469d26e4fcSRobert Mustacchi if (i40e->i40e_tx_hcksum_enable == B_TRUE) 7479d26e4fcSRobert Mustacchi *txflags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 7489d26e4fcSRobert Mustacchi break; 7499d26e4fcSRobert Mustacchi } 7509d26e4fcSRobert Mustacchi 75109aee612SRyan Zezeski case MAC_CAPAB_LSO: { 75209aee612SRyan Zezeski mac_capab_lso_t *cap_lso = cap_data; 75309aee612SRyan Zezeski 75409aee612SRyan Zezeski if (i40e->i40e_tx_lso_enable == B_TRUE) { 75585f496faSRobert Mustacchi cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 | 75685f496faSRobert Mustacchi LSO_TX_BASIC_TCP_IPV6; 75709aee612SRyan Zezeski cap_lso->lso_basic_tcp_ipv4.lso_max = I40E_LSO_MAXLEN; 75885f496faSRobert Mustacchi cap_lso->lso_basic_tcp_ipv6.lso_max = I40E_LSO_MAXLEN; 75909aee612SRyan Zezeski } else { 76009aee612SRyan Zezeski return (B_FALSE); 76109aee612SRyan Zezeski } 76209aee612SRyan Zezeski break; 76309aee612SRyan Zezeski } 76409aee612SRyan Zezeski 7659d26e4fcSRobert Mustacchi case MAC_CAPAB_RINGS: 7669d26e4fcSRobert Mustacchi cap_rings = cap_data; 7679d26e4fcSRobert Mustacchi cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 7689d26e4fcSRobert Mustacchi switch (cap_rings->mr_type) { 7699d26e4fcSRobert Mustacchi case MAC_RING_TYPE_TX: 7709d26e4fcSRobert Mustacchi /* 77109aee612SRyan Zezeski * Note, saying we have no groups, but some 77209aee612SRyan Zezeski * number of rings indicates to MAC that it 77309aee612SRyan Zezeski * should create psuedo-groups with one for 77409aee612SRyan Zezeski * each TX ring. This may not be the long term 77509aee612SRyan Zezeski * behavior we want, but it'll work for now. 7769d26e4fcSRobert Mustacchi */ 7779d26e4fcSRobert Mustacchi cap_rings->mr_gnum = 0; 77809aee612SRyan Zezeski cap_rings->mr_rnum = i40e->i40e_num_trqpairs_per_vsi; 7799d26e4fcSRobert Mustacchi cap_rings->mr_rget = i40e_fill_tx_ring; 7809d26e4fcSRobert Mustacchi cap_rings->mr_gget = NULL; 7819d26e4fcSRobert Mustacchi cap_rings->mr_gaddring = NULL; 7829d26e4fcSRobert Mustacchi cap_rings->mr_gremring = NULL; 7839d26e4fcSRobert Mustacchi break; 7849d26e4fcSRobert Mustacchi case MAC_RING_TYPE_RX: 7859d26e4fcSRobert Mustacchi cap_rings->mr_rnum = i40e->i40e_num_trqpairs; 7869d26e4fcSRobert Mustacchi cap_rings->mr_rget = i40e_fill_rx_ring; 78709aee612SRyan Zezeski cap_rings->mr_gnum = i40e->i40e_num_rx_groups; 7889d26e4fcSRobert Mustacchi cap_rings->mr_gget = i40e_fill_rx_group; 7899d26e4fcSRobert Mustacchi cap_rings->mr_gaddring = NULL; 7909d26e4fcSRobert Mustacchi cap_rings->mr_gremring = NULL; 7919d26e4fcSRobert Mustacchi break; 7929d26e4fcSRobert Mustacchi default: 7939d26e4fcSRobert Mustacchi return (B_FALSE); 7949d26e4fcSRobert Mustacchi } 7959d26e4fcSRobert Mustacchi break; 79645d3dd98SRobert Mustacchi case MAC_CAPAB_TRANSCEIVER: 79745d3dd98SRobert Mustacchi mct = cap_data; 79845d3dd98SRobert Mustacchi 79945d3dd98SRobert Mustacchi /* 80045d3dd98SRobert Mustacchi * Firmware doesn't have a great way of telling us in advance 80145d3dd98SRobert Mustacchi * whether we'd expect a SFF transceiver. As such, we always 80245d3dd98SRobert Mustacchi * advertise the support for this capability. 80345d3dd98SRobert Mustacchi */ 80445d3dd98SRobert Mustacchi mct->mct_flags = 0; 80545d3dd98SRobert Mustacchi mct->mct_ntransceivers = 1; 80645d3dd98SRobert Mustacchi mct->mct_info = i40e_transceiver_info; 807286d309cSRobert Mustacchi mct->mct_read = i40e_transceiver_read; 80845d3dd98SRobert Mustacchi 80945d3dd98SRobert Mustacchi return (B_TRUE); 810c1e9c696SRobert Mustacchi case MAC_CAPAB_LED: 811c1e9c696SRobert Mustacchi mcl = cap_data; 812c1e9c696SRobert Mustacchi 813c1e9c696SRobert Mustacchi mcl->mcl_flags = 0; 814c1e9c696SRobert Mustacchi mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_IDENT | MAC_LED_OFF | 815c1e9c696SRobert Mustacchi MAC_LED_ON; 816c1e9c696SRobert Mustacchi mcl->mcl_set = i40e_gld_led_set; 817c1e9c696SRobert Mustacchi break; 818c1e9c696SRobert Mustacchi 8199d26e4fcSRobert Mustacchi default: 8209d26e4fcSRobert Mustacchi return (B_FALSE); 8219d26e4fcSRobert Mustacchi } 8229d26e4fcSRobert Mustacchi 8239d26e4fcSRobert Mustacchi return (B_TRUE); 8249d26e4fcSRobert Mustacchi } 8259d26e4fcSRobert Mustacchi 8269d26e4fcSRobert Mustacchi /* ARGSUSED */ 8279d26e4fcSRobert Mustacchi static int 8289d26e4fcSRobert Mustacchi i40e_m_setprop_private(i40e_t *i40e, const char *pr_name, uint_t pr_valsize, 8299d26e4fcSRobert Mustacchi const void *pr_val) 8309d26e4fcSRobert Mustacchi { 8319d26e4fcSRobert Mustacchi int ret; 8329d26e4fcSRobert Mustacchi long val; 8339d26e4fcSRobert Mustacchi char *eptr; 8349d26e4fcSRobert Mustacchi 8359d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 8369d26e4fcSRobert Mustacchi 8379d26e4fcSRobert Mustacchi if ((ret = ddi_strtol(pr_val, &eptr, 10, &val)) != 0 || 8389d26e4fcSRobert Mustacchi *eptr != '\0') { 8399d26e4fcSRobert Mustacchi return (ret); 8409d26e4fcSRobert Mustacchi } 8419d26e4fcSRobert Mustacchi 8429d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 8439d26e4fcSRobert Mustacchi if (val < I40E_MIN_RX_DMA_THRESH || 8449d26e4fcSRobert Mustacchi val > I40E_MAX_RX_DMA_THRESH) { 8459d26e4fcSRobert Mustacchi return (EINVAL); 8469d26e4fcSRobert Mustacchi } 8479d26e4fcSRobert Mustacchi i40e->i40e_rx_dma_min = (uint32_t)val; 8489d26e4fcSRobert Mustacchi return (0); 8499d26e4fcSRobert Mustacchi } 8509d26e4fcSRobert Mustacchi 8519d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 8529d26e4fcSRobert Mustacchi if (val < I40E_MIN_TX_DMA_THRESH || 8539d26e4fcSRobert Mustacchi val > I40E_MAX_TX_DMA_THRESH) { 8549d26e4fcSRobert Mustacchi return (EINVAL); 8559d26e4fcSRobert Mustacchi } 8569d26e4fcSRobert Mustacchi i40e->i40e_tx_dma_min = (uint32_t)val; 8579d26e4fcSRobert Mustacchi return (0); 8589d26e4fcSRobert Mustacchi } 8599d26e4fcSRobert Mustacchi 8609d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 8619d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 8629d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 8639d26e4fcSRobert Mustacchi return (EINVAL); 8649d26e4fcSRobert Mustacchi } 8659d26e4fcSRobert Mustacchi i40e->i40e_rx_itr = (uint32_t)val; 8669d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_RX, i40e->i40e_rx_itr); 8679d26e4fcSRobert Mustacchi return (0); 8689d26e4fcSRobert Mustacchi } 8699d26e4fcSRobert Mustacchi 8709d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 8719d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 8729d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 8739d26e4fcSRobert Mustacchi return (EINVAL); 8749d26e4fcSRobert Mustacchi } 8759d26e4fcSRobert Mustacchi i40e->i40e_tx_itr = (uint32_t)val; 8769d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_TX, i40e->i40e_tx_itr); 8779d26e4fcSRobert Mustacchi return (0); 8789d26e4fcSRobert Mustacchi } 8799d26e4fcSRobert Mustacchi 8809d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 8819d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 8829d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 8839d26e4fcSRobert Mustacchi return (EINVAL); 8849d26e4fcSRobert Mustacchi } 8859d26e4fcSRobert Mustacchi i40e->i40e_tx_itr = (uint32_t)val; 8869d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_OTHER, 8879d26e4fcSRobert Mustacchi i40e->i40e_other_itr); 8889d26e4fcSRobert Mustacchi return (0); 8899d26e4fcSRobert Mustacchi } 8909d26e4fcSRobert Mustacchi 8919d26e4fcSRobert Mustacchi return (ENOTSUP); 8929d26e4fcSRobert Mustacchi } 8939d26e4fcSRobert Mustacchi 8949d26e4fcSRobert Mustacchi static int 8959d26e4fcSRobert Mustacchi i40e_m_getprop_private(i40e_t *i40e, const char *pr_name, uint_t pr_valsize, 8969d26e4fcSRobert Mustacchi void *pr_val) 8979d26e4fcSRobert Mustacchi { 8989d26e4fcSRobert Mustacchi uint32_t val; 8999d26e4fcSRobert Mustacchi 9009d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 9019d26e4fcSRobert Mustacchi 9029d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 9039d26e4fcSRobert Mustacchi val = i40e->i40e_rx_dma_min; 9049d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 9059d26e4fcSRobert Mustacchi val = i40e->i40e_tx_dma_min; 9069d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 9079d26e4fcSRobert Mustacchi val = i40e->i40e_rx_itr; 9089d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 9099d26e4fcSRobert Mustacchi val = i40e->i40e_tx_itr; 9109d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 9119d26e4fcSRobert Mustacchi val = i40e->i40e_other_itr; 9129d26e4fcSRobert Mustacchi } else { 9139d26e4fcSRobert Mustacchi return (ENOTSUP); 9149d26e4fcSRobert Mustacchi } 9159d26e4fcSRobert Mustacchi 9169d26e4fcSRobert Mustacchi if (snprintf(pr_val, pr_valsize, "%d", val) >= pr_valsize) 9179d26e4fcSRobert Mustacchi return (ERANGE); 9189d26e4fcSRobert Mustacchi return (0); 9199d26e4fcSRobert Mustacchi } 9209d26e4fcSRobert Mustacchi 9219d26e4fcSRobert Mustacchi /* 9229d26e4fcSRobert Mustacchi * Annoyingly for private properties MAC seems to ignore default values that 9239d26e4fcSRobert Mustacchi * aren't strings. That means that we have to translate all of these into 9249d26e4fcSRobert Mustacchi * uint32_t's and instead we size the buffer to be large enough to hold a 9259d26e4fcSRobert Mustacchi * uint32_t. 9269d26e4fcSRobert Mustacchi */ 9279d26e4fcSRobert Mustacchi /* ARGSUSED */ 9289d26e4fcSRobert Mustacchi static void 9299d26e4fcSRobert Mustacchi i40e_m_propinfo_private(i40e_t *i40e, const char *pr_name, 9309d26e4fcSRobert Mustacchi mac_prop_info_handle_t prh) 9319d26e4fcSRobert Mustacchi { 9329d26e4fcSRobert Mustacchi char buf[64]; 9339d26e4fcSRobert Mustacchi uint32_t def; 9349d26e4fcSRobert Mustacchi 9359d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 9369d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 9379d26e4fcSRobert Mustacchi def = I40E_DEF_RX_DMA_THRESH; 9389d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, 9399d26e4fcSRobert Mustacchi I40E_MIN_RX_DMA_THRESH, 9409d26e4fcSRobert Mustacchi I40E_MAX_RX_DMA_THRESH); 9419d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 9429d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 9439d26e4fcSRobert Mustacchi def = I40E_DEF_TX_DMA_THRESH; 9449d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, 9459d26e4fcSRobert Mustacchi I40E_MIN_TX_DMA_THRESH, 9469d26e4fcSRobert Mustacchi I40E_MAX_TX_DMA_THRESH); 9479d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 9489d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 9499d26e4fcSRobert Mustacchi def = I40E_DEF_RX_ITR; 9509d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 9519d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 9529d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 9539d26e4fcSRobert Mustacchi def = I40E_DEF_TX_ITR; 9549d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 9559d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 9569d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 9579d26e4fcSRobert Mustacchi def = I40E_DEF_OTHER_ITR; 9589d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 9599d26e4fcSRobert Mustacchi } else { 9609d26e4fcSRobert Mustacchi return; 9619d26e4fcSRobert Mustacchi } 9629d26e4fcSRobert Mustacchi 9639d26e4fcSRobert Mustacchi (void) snprintf(buf, sizeof (buf), "%d", def); 9649d26e4fcSRobert Mustacchi mac_prop_info_set_default_str(prh, buf); 9659d26e4fcSRobert Mustacchi } 9669d26e4fcSRobert Mustacchi 9679d26e4fcSRobert Mustacchi static int 9689d26e4fcSRobert Mustacchi i40e_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 9699d26e4fcSRobert Mustacchi uint_t pr_valsize, const void *pr_val) 9709d26e4fcSRobert Mustacchi { 9719d26e4fcSRobert Mustacchi uint32_t new_mtu; 9729d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 9739d26e4fcSRobert Mustacchi int ret = 0; 9749d26e4fcSRobert Mustacchi 9759d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 9769d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 9779d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 9789d26e4fcSRobert Mustacchi return (ECANCELED); 9799d26e4fcSRobert Mustacchi } 9809d26e4fcSRobert Mustacchi 9819d26e4fcSRobert Mustacchi switch (pr_num) { 9829d26e4fcSRobert Mustacchi /* 9839d26e4fcSRobert Mustacchi * These properties are always read-only across every device. 9849d26e4fcSRobert Mustacchi */ 9859d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 9869d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 9879d26e4fcSRobert Mustacchi case MAC_PROP_STATUS: 9889d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 9899d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 9909d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 9913d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 9929d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 9939d26e4fcSRobert Mustacchi ret = ENOTSUP; 9949d26e4fcSRobert Mustacchi break; 9959d26e4fcSRobert Mustacchi /* 9969d26e4fcSRobert Mustacchi * These are read-only at this time as we don't support configuring 9979d26e4fcSRobert Mustacchi * auto-negotiation. See the theory statement in i40e_main.c. 9989d26e4fcSRobert Mustacchi */ 9999d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 10009d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 10019d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 10023d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 10039d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 10049d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 10059d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 10069d26e4fcSRobert Mustacchi ret = ENOTSUP; 10079d26e4fcSRobert Mustacchi break; 10089d26e4fcSRobert Mustacchi 10099d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 10109d26e4fcSRobert Mustacchi bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 10119d26e4fcSRobert Mustacchi if (new_mtu == i40e->i40e_sdu) 10129d26e4fcSRobert Mustacchi break; 10139d26e4fcSRobert Mustacchi 10149d26e4fcSRobert Mustacchi if (new_mtu < I40E_MIN_MTU || 10159d26e4fcSRobert Mustacchi new_mtu > I40E_MAX_MTU) { 10169d26e4fcSRobert Mustacchi ret = EINVAL; 10179d26e4fcSRobert Mustacchi break; 10189d26e4fcSRobert Mustacchi } 10199d26e4fcSRobert Mustacchi 10209d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_STARTED) { 10219d26e4fcSRobert Mustacchi ret = EBUSY; 10229d26e4fcSRobert Mustacchi break; 10239d26e4fcSRobert Mustacchi } 10249d26e4fcSRobert Mustacchi 10259d26e4fcSRobert Mustacchi ret = mac_maxsdu_update(i40e->i40e_mac_hdl, new_mtu); 10269d26e4fcSRobert Mustacchi if (ret == 0) { 10279d26e4fcSRobert Mustacchi i40e->i40e_sdu = new_mtu; 10289d26e4fcSRobert Mustacchi i40e_update_mtu(i40e); 10299d26e4fcSRobert Mustacchi } 10309d26e4fcSRobert Mustacchi break; 10319d26e4fcSRobert Mustacchi 10329d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 10339d26e4fcSRobert Mustacchi ret = i40e_m_setprop_private(i40e, pr_name, pr_valsize, pr_val); 10349d26e4fcSRobert Mustacchi break; 10359d26e4fcSRobert Mustacchi default: 10369d26e4fcSRobert Mustacchi ret = ENOTSUP; 10379d26e4fcSRobert Mustacchi break; 10389d26e4fcSRobert Mustacchi } 10399d26e4fcSRobert Mustacchi 10409d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 10419d26e4fcSRobert Mustacchi return (ret); 10429d26e4fcSRobert Mustacchi } 10439d26e4fcSRobert Mustacchi 10449d26e4fcSRobert Mustacchi static int 10459d26e4fcSRobert Mustacchi i40e_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 10469d26e4fcSRobert Mustacchi uint_t pr_valsize, void *pr_val) 10479d26e4fcSRobert Mustacchi { 10489d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 10499d26e4fcSRobert Mustacchi uint64_t speed; 10509d26e4fcSRobert Mustacchi int ret = 0; 10519d26e4fcSRobert Mustacchi uint8_t *u8; 10529d26e4fcSRobert Mustacchi link_flowctrl_t fctl; 10539d26e4fcSRobert Mustacchi 10549d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 10559d26e4fcSRobert Mustacchi 10569d26e4fcSRobert Mustacchi switch (pr_num) { 10579d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 10589d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_duplex_t)) { 10599d26e4fcSRobert Mustacchi ret = EOVERFLOW; 10609d26e4fcSRobert Mustacchi break; 10619d26e4fcSRobert Mustacchi } 10629d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_link_duplex, pr_val, sizeof (link_duplex_t)); 10639d26e4fcSRobert Mustacchi break; 10649d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 10659d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint64_t)) { 10669d26e4fcSRobert Mustacchi ret = EOVERFLOW; 10679d26e4fcSRobert Mustacchi break; 10689d26e4fcSRobert Mustacchi } 10699d26e4fcSRobert Mustacchi speed = i40e->i40e_link_speed * 1000000ULL; 10709d26e4fcSRobert Mustacchi bcopy(&speed, pr_val, sizeof (speed)); 10719d26e4fcSRobert Mustacchi break; 10729d26e4fcSRobert Mustacchi case MAC_PROP_STATUS: 10739d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_state_t)) { 10749d26e4fcSRobert Mustacchi ret = EOVERFLOW; 10759d26e4fcSRobert Mustacchi break; 10769d26e4fcSRobert Mustacchi } 10779d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_link_state, pr_val, sizeof (link_state_t)); 10789d26e4fcSRobert Mustacchi break; 10799d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 10809d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 10819d26e4fcSRobert Mustacchi ret = EOVERFLOW; 10829d26e4fcSRobert Mustacchi break; 10839d26e4fcSRobert Mustacchi } 10849d26e4fcSRobert Mustacchi u8 = pr_val; 10859d26e4fcSRobert Mustacchi *u8 = 1; 10869d26e4fcSRobert Mustacchi break; 10879d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 10889d26e4fcSRobert Mustacchi /* 10899d26e4fcSRobert Mustacchi * Because we don't currently support hardware flow control, we 10909d26e4fcSRobert Mustacchi * just hardcode this to be none. 10919d26e4fcSRobert Mustacchi */ 10929d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_flowctrl_t)) { 10939d26e4fcSRobert Mustacchi ret = EOVERFLOW; 10949d26e4fcSRobert Mustacchi break; 10959d26e4fcSRobert Mustacchi } 10969d26e4fcSRobert Mustacchi fctl = LINK_FLOWCTRL_NONE; 10979d26e4fcSRobert Mustacchi bcopy(&fctl, pr_val, sizeof (link_flowctrl_t)); 10989d26e4fcSRobert Mustacchi break; 10999d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 11009d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint32_t)) { 11019d26e4fcSRobert Mustacchi ret = EOVERFLOW; 11029d26e4fcSRobert Mustacchi break; 11039d26e4fcSRobert Mustacchi } 11049d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_sdu, pr_val, sizeof (uint32_t)); 11059d26e4fcSRobert Mustacchi break; 11069d26e4fcSRobert Mustacchi 11079d26e4fcSRobert Mustacchi /* 11089d26e4fcSRobert Mustacchi * Because we don't let users control the speeds we may auto-negotiate 11099d26e4fcSRobert Mustacchi * to, the values of the ADV_ and EN_ will always be the same. 11109d26e4fcSRobert Mustacchi */ 11119d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 11129d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 11139d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 11149d26e4fcSRobert Mustacchi ret = EOVERFLOW; 11159d26e4fcSRobert Mustacchi break; 11169d26e4fcSRobert Mustacchi } 11179d26e4fcSRobert Mustacchi u8 = pr_val; 11189d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0; 11199d26e4fcSRobert Mustacchi break; 11209d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 11219d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 11229d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 11239d26e4fcSRobert Mustacchi ret = EOVERFLOW; 11249d26e4fcSRobert Mustacchi break; 11259d26e4fcSRobert Mustacchi } 11269d26e4fcSRobert Mustacchi u8 = pr_val; 11279d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0; 11289d26e4fcSRobert Mustacchi break; 11299d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 11309d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 11319d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 11329d26e4fcSRobert Mustacchi ret = EOVERFLOW; 11339d26e4fcSRobert Mustacchi break; 11349d26e4fcSRobert Mustacchi } 11359d26e4fcSRobert Mustacchi u8 = pr_val; 11369d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0; 11379d26e4fcSRobert Mustacchi break; 11383d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 11393d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 11403d75a287SRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 11413d75a287SRobert Mustacchi ret = EOVERFLOW; 11423d75a287SRobert Mustacchi break; 11433d75a287SRobert Mustacchi } 11443d75a287SRobert Mustacchi u8 = pr_val; 11453d75a287SRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0; 11463d75a287SRobert Mustacchi break; 11479d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 11489d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 11499d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 11509d26e4fcSRobert Mustacchi ret = EOVERFLOW; 11519d26e4fcSRobert Mustacchi break; 11529d26e4fcSRobert Mustacchi } 11539d26e4fcSRobert Mustacchi u8 = pr_val; 11549d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0; 11559d26e4fcSRobert Mustacchi break; 11569d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 11579d26e4fcSRobert Mustacchi ret = i40e_m_getprop_private(i40e, pr_name, pr_valsize, pr_val); 11589d26e4fcSRobert Mustacchi break; 11599d26e4fcSRobert Mustacchi default: 11609d26e4fcSRobert Mustacchi ret = ENOTSUP; 11619d26e4fcSRobert Mustacchi break; 11629d26e4fcSRobert Mustacchi } 11639d26e4fcSRobert Mustacchi 11649d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 11659d26e4fcSRobert Mustacchi 11669d26e4fcSRobert Mustacchi return (ret); 11679d26e4fcSRobert Mustacchi } 11689d26e4fcSRobert Mustacchi 11699d26e4fcSRobert Mustacchi static void 11709d26e4fcSRobert Mustacchi i40e_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 11719d26e4fcSRobert Mustacchi mac_prop_info_handle_t prh) 11729d26e4fcSRobert Mustacchi { 11739d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 11749d26e4fcSRobert Mustacchi 11759d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 11769d26e4fcSRobert Mustacchi 11779d26e4fcSRobert Mustacchi switch (pr_num) { 11789d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 11799d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 11809d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 11819d26e4fcSRobert Mustacchi break; 11829d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 11839d26e4fcSRobert Mustacchi /* 11849d26e4fcSRobert Mustacchi * At the moment, the driver doesn't support flow control, hence 11859d26e4fcSRobert Mustacchi * why this is set to read-only and none. 11869d26e4fcSRobert Mustacchi */ 11879d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 11889d26e4fcSRobert Mustacchi mac_prop_info_set_default_link_flowctrl(prh, 11899d26e4fcSRobert Mustacchi LINK_FLOWCTRL_NONE); 11909d26e4fcSRobert Mustacchi break; 11919d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 11929d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_MTU, I40E_MAX_MTU); 11939d26e4fcSRobert Mustacchi break; 11949d26e4fcSRobert Mustacchi 11959d26e4fcSRobert Mustacchi /* 11969d26e4fcSRobert Mustacchi * We set the defaults for these based upon the phy's ability to 11979d26e4fcSRobert Mustacchi * support the speeds. Note, auto-negotiation is required for fiber, 11989d26e4fcSRobert Mustacchi * hence it is read-only and always enabled. When we have access to 11999d26e4fcSRobert Mustacchi * copper phys we can revisit this. 12009d26e4fcSRobert Mustacchi */ 12019d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 12029d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12039d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 1); 12049d26e4fcSRobert Mustacchi break; 12059d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 12069d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12079d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12089d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0); 12099d26e4fcSRobert Mustacchi break; 12109d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 12119d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12129d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12139d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0); 12149d26e4fcSRobert Mustacchi break; 12159d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 12169d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12179d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12189d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0); 12199d26e4fcSRobert Mustacchi break; 12209d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 12219d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12229d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12239d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0); 12249d26e4fcSRobert Mustacchi break; 12259d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 12269d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12279d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12289d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0); 12299d26e4fcSRobert Mustacchi break; 12309d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 12319d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12329d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12339d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0); 12349d26e4fcSRobert Mustacchi break; 12353d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 12363d75a287SRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12373d75a287SRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12383d75a287SRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0); 12393d75a287SRobert Mustacchi break; 12403d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 12413d75a287SRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12423d75a287SRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12433d75a287SRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0); 12443d75a287SRobert Mustacchi break; 12459d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 12469d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12479d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12489d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0); 12499d26e4fcSRobert Mustacchi break; 12509d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 12519d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 12529d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 12539d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0); 12549d26e4fcSRobert Mustacchi break; 12559d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 12569d26e4fcSRobert Mustacchi i40e_m_propinfo_private(i40e, pr_name, prh); 12579d26e4fcSRobert Mustacchi break; 12589d26e4fcSRobert Mustacchi default: 12599d26e4fcSRobert Mustacchi break; 12609d26e4fcSRobert Mustacchi } 12619d26e4fcSRobert Mustacchi 12629d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 12639d26e4fcSRobert Mustacchi } 12649d26e4fcSRobert Mustacchi 12659d26e4fcSRobert Mustacchi #define I40E_M_CALLBACK_FLAGS \ 12669d26e4fcSRobert Mustacchi (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO) 12679d26e4fcSRobert Mustacchi 12689d26e4fcSRobert Mustacchi static mac_callbacks_t i40e_m_callbacks = { 12699d26e4fcSRobert Mustacchi I40E_M_CALLBACK_FLAGS, 12709d26e4fcSRobert Mustacchi i40e_m_stat, 12719d26e4fcSRobert Mustacchi i40e_m_start, 12729d26e4fcSRobert Mustacchi i40e_m_stop, 12739d26e4fcSRobert Mustacchi i40e_m_promisc, 12749d26e4fcSRobert Mustacchi i40e_m_multicast, 12759d26e4fcSRobert Mustacchi NULL, 12769d26e4fcSRobert Mustacchi NULL, 12779d26e4fcSRobert Mustacchi NULL, 12789d26e4fcSRobert Mustacchi i40e_m_ioctl, 12799d26e4fcSRobert Mustacchi i40e_m_getcapab, 12809d26e4fcSRobert Mustacchi NULL, 12819d26e4fcSRobert Mustacchi NULL, 12829d26e4fcSRobert Mustacchi i40e_m_setprop, 12839d26e4fcSRobert Mustacchi i40e_m_getprop, 12849d26e4fcSRobert Mustacchi i40e_m_propinfo 12859d26e4fcSRobert Mustacchi }; 12869d26e4fcSRobert Mustacchi 12879d26e4fcSRobert Mustacchi boolean_t 12889d26e4fcSRobert Mustacchi i40e_register_mac(i40e_t *i40e) 12899d26e4fcSRobert Mustacchi { 12909d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 12919d26e4fcSRobert Mustacchi int status; 12929d26e4fcSRobert Mustacchi mac_register_t *mac = mac_alloc(MAC_VERSION); 12939d26e4fcSRobert Mustacchi 12949d26e4fcSRobert Mustacchi if (mac == NULL) 12959d26e4fcSRobert Mustacchi return (B_FALSE); 12969d26e4fcSRobert Mustacchi 12979d26e4fcSRobert Mustacchi mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 12989d26e4fcSRobert Mustacchi mac->m_driver = i40e; 12999d26e4fcSRobert Mustacchi mac->m_dip = i40e->i40e_dip; 13009d26e4fcSRobert Mustacchi mac->m_src_addr = hw->mac.addr; 13019d26e4fcSRobert Mustacchi mac->m_callbacks = &i40e_m_callbacks; 13029d26e4fcSRobert Mustacchi mac->m_min_sdu = 0; 13039d26e4fcSRobert Mustacchi mac->m_max_sdu = i40e->i40e_sdu; 13049d26e4fcSRobert Mustacchi mac->m_margin = VLAN_TAGSZ; 13059d26e4fcSRobert Mustacchi mac->m_priv_props = i40e_priv_props; 13069d26e4fcSRobert Mustacchi mac->m_v12n = MAC_VIRT_LEVEL1; 13079d26e4fcSRobert Mustacchi 13089d26e4fcSRobert Mustacchi status = mac_register(mac, &i40e->i40e_mac_hdl); 13099d26e4fcSRobert Mustacchi if (status != 0) 13109d26e4fcSRobert Mustacchi i40e_error(i40e, "mac_register() returned %d", status); 13119d26e4fcSRobert Mustacchi mac_free(mac); 13129d26e4fcSRobert Mustacchi 13139d26e4fcSRobert Mustacchi return (status == 0); 13149d26e4fcSRobert Mustacchi } 1315