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. 14*338749cbSRobert Mustacchi * Copyright (c) 2017, Joyent, Inc. 15396505afSPaul Winder * Copyright 2017 Tegile Systems, Inc. All rights reserved. 169d26e4fcSRobert Mustacchi */ 179d26e4fcSRobert Mustacchi 189d26e4fcSRobert Mustacchi /* 199d26e4fcSRobert Mustacchi * For more information, please see the big theory statement in i40e_main.c. 209d26e4fcSRobert Mustacchi */ 219d26e4fcSRobert Mustacchi 229d26e4fcSRobert Mustacchi #include "i40e_sw.h" 239d26e4fcSRobert Mustacchi 249d26e4fcSRobert Mustacchi #define I40E_PROP_RX_DMA_THRESH "_rx_dma_threshold" 259d26e4fcSRobert Mustacchi #define I40E_PROP_TX_DMA_THRESH "_tx_dma_threshold" 269d26e4fcSRobert Mustacchi #define I40E_PROP_RX_ITR "_rx_intr_throttle" 279d26e4fcSRobert Mustacchi #define I40E_PROP_TX_ITR "_tx_intr_throttle" 289d26e4fcSRobert Mustacchi #define I40E_PROP_OTHER_ITR "_other_intr_throttle" 299d26e4fcSRobert Mustacchi 309d26e4fcSRobert Mustacchi char *i40e_priv_props[] = { 319d26e4fcSRobert Mustacchi I40E_PROP_RX_DMA_THRESH, 329d26e4fcSRobert Mustacchi I40E_PROP_TX_DMA_THRESH, 339d26e4fcSRobert Mustacchi I40E_PROP_RX_ITR, 349d26e4fcSRobert Mustacchi I40E_PROP_TX_ITR, 359d26e4fcSRobert Mustacchi I40E_PROP_OTHER_ITR, 369d26e4fcSRobert Mustacchi NULL 379d26e4fcSRobert Mustacchi }; 389d26e4fcSRobert Mustacchi 399d26e4fcSRobert Mustacchi static int 409d26e4fcSRobert Mustacchi i40e_group_remove_mac(void *arg, const uint8_t *mac_addr) 419d26e4fcSRobert Mustacchi { 429d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 439d26e4fcSRobert Mustacchi struct i40e_aqc_remove_macvlan_element_data filt; 449d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 459d26e4fcSRobert Mustacchi int ret, i, last; 469d26e4fcSRobert Mustacchi i40e_uaddr_t *iua; 479d26e4fcSRobert Mustacchi 489d26e4fcSRobert Mustacchi if (I40E_IS_MULTICAST(mac_addr)) 499d26e4fcSRobert Mustacchi return (EINVAL); 509d26e4fcSRobert Mustacchi 519d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 529d26e4fcSRobert Mustacchi 539d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 549d26e4fcSRobert Mustacchi ret = ECANCELED; 559d26e4fcSRobert Mustacchi goto done; 569d26e4fcSRobert Mustacchi } 579d26e4fcSRobert Mustacchi 589d26e4fcSRobert Mustacchi for (i = 0; i < i40e->i40e_resources.ifr_nmacfilt_used; i++) { 599d26e4fcSRobert Mustacchi if (bcmp(mac_addr, i40e->i40e_uaddrs[i].iua_mac, 609d26e4fcSRobert Mustacchi ETHERADDRL) == 0) 619d26e4fcSRobert Mustacchi break; 629d26e4fcSRobert Mustacchi } 639d26e4fcSRobert Mustacchi 649d26e4fcSRobert Mustacchi if (i == i40e->i40e_resources.ifr_nmacfilt_used) { 659d26e4fcSRobert Mustacchi ret = ENOENT; 669d26e4fcSRobert Mustacchi goto done; 679d26e4fcSRobert Mustacchi } 689d26e4fcSRobert Mustacchi 699d26e4fcSRobert Mustacchi iua = &i40e->i40e_uaddrs[i]; 709d26e4fcSRobert Mustacchi ASSERT(i40e->i40e_resources.ifr_nmacfilt_used > 0); 719d26e4fcSRobert Mustacchi 729d26e4fcSRobert Mustacchi bzero(&filt, sizeof (filt)); 739d26e4fcSRobert Mustacchi bcopy(mac_addr, filt.mac_addr, ETHERADDRL); 749d26e4fcSRobert Mustacchi filt.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | 759d26e4fcSRobert Mustacchi I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 769d26e4fcSRobert Mustacchi 779d26e4fcSRobert Mustacchi if (i40e_aq_remove_macvlan(hw, iua->iua_vsi, &filt, 1, NULL) != 789d26e4fcSRobert Mustacchi I40E_SUCCESS) { 799d26e4fcSRobert Mustacchi i40e_error(i40e, "failed to remove mac address " 809d26e4fcSRobert Mustacchi "%2x:%2x:%2x:%2x:%2x:%2x from unicast filter: %d", 819d26e4fcSRobert Mustacchi mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 829d26e4fcSRobert Mustacchi mac_addr[4], mac_addr[5], filt.error_code); 839d26e4fcSRobert Mustacchi ret = EIO; 849d26e4fcSRobert Mustacchi goto done; 859d26e4fcSRobert Mustacchi } 869d26e4fcSRobert Mustacchi 879d26e4fcSRobert Mustacchi last = i40e->i40e_resources.ifr_nmacfilt_used - 1; 889d26e4fcSRobert Mustacchi if (i != last) { 899d26e4fcSRobert Mustacchi i40e_uaddr_t *src = &i40e->i40e_uaddrs[last]; 909d26e4fcSRobert Mustacchi bcopy(src, iua, sizeof (i40e_uaddr_t)); 919d26e4fcSRobert Mustacchi } 929d26e4fcSRobert Mustacchi 939d26e4fcSRobert Mustacchi /* 949d26e4fcSRobert Mustacchi * Set the multicast bit in the last one to indicate to ourselves that 959d26e4fcSRobert Mustacchi * it's invalid. 969d26e4fcSRobert Mustacchi */ 979d26e4fcSRobert Mustacchi bzero(&i40e->i40e_uaddrs[last], sizeof (i40e_uaddr_t)); 989d26e4fcSRobert Mustacchi i40e->i40e_uaddrs[last].iua_mac[0] = 0x01; 999d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt_used--; 1009d26e4fcSRobert Mustacchi ret = 0; 1019d26e4fcSRobert Mustacchi done: 1029d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 1039d26e4fcSRobert Mustacchi 1049d26e4fcSRobert Mustacchi return (ret); 1059d26e4fcSRobert Mustacchi } 1069d26e4fcSRobert Mustacchi 1079d26e4fcSRobert Mustacchi static int 1089d26e4fcSRobert Mustacchi i40e_group_add_mac(void *arg, const uint8_t *mac_addr) 1099d26e4fcSRobert Mustacchi { 1109d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 1119d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 1129d26e4fcSRobert Mustacchi int i, ret; 1139d26e4fcSRobert Mustacchi i40e_uaddr_t *iua; 1149d26e4fcSRobert Mustacchi struct i40e_aqc_add_macvlan_element_data filt; 1159d26e4fcSRobert Mustacchi 1169d26e4fcSRobert Mustacchi if (I40E_IS_MULTICAST(mac_addr)) 1179d26e4fcSRobert Mustacchi return (EINVAL); 1189d26e4fcSRobert Mustacchi 1199d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 1209d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 1219d26e4fcSRobert Mustacchi ret = ECANCELED; 1229d26e4fcSRobert Mustacchi goto done; 1239d26e4fcSRobert Mustacchi } 1249d26e4fcSRobert Mustacchi 1259d26e4fcSRobert Mustacchi if (i40e->i40e_resources.ifr_nmacfilt == 1269d26e4fcSRobert Mustacchi i40e->i40e_resources.ifr_nmacfilt_used) { 1279d26e4fcSRobert Mustacchi ret = ENOSPC; 1289d26e4fcSRobert Mustacchi goto done; 1299d26e4fcSRobert Mustacchi } 1309d26e4fcSRobert Mustacchi 1319d26e4fcSRobert Mustacchi for (i = 0; i < i40e->i40e_resources.ifr_nmacfilt_used; i++) { 1329d26e4fcSRobert Mustacchi if (bcmp(mac_addr, i40e->i40e_uaddrs[i].iua_mac, 1339d26e4fcSRobert Mustacchi ETHERADDRL) == 0) { 1349d26e4fcSRobert Mustacchi ret = EEXIST; 1359d26e4fcSRobert Mustacchi goto done; 1369d26e4fcSRobert Mustacchi } 1379d26e4fcSRobert Mustacchi } 1389d26e4fcSRobert Mustacchi 1399d26e4fcSRobert Mustacchi /* 1409d26e4fcSRobert Mustacchi * Note, the general use of the i40e_vsi_id will have to be refactored 1419d26e4fcSRobert Mustacchi * when we have proper group support. 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 1489d26e4fcSRobert Mustacchi if ((ret = i40e_aq_add_macvlan(hw, i40e->i40e_vsi_id, &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); 1609d26e4fcSRobert Mustacchi iua->iua_vsi = i40e->i40e_vsi_id; 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 1829d26e4fcSRobert Mustacchi if (!i40e_start(i40e, B_TRUE)) { 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); 2059d26e4fcSRobert Mustacchi i40e_stop(i40e, B_TRUE); 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 2309d26e4fcSRobert Mustacchi ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id, 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 2499d26e4fcSRobert Mustacchi ret = i40e_aq_set_vsi_multicast_promiscuous(hw, i40e->i40e_vsi_id, 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 */ 2609d26e4fcSRobert Mustacchi ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id, 2613d75a287SRobert Mustacchi !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, 2979d26e4fcSRobert Mustacchi i40e->i40e_vsi_id, 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", 3019d26e4fcSRobert Mustacchi i40e->i40e_vsi_id, 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 3159d26e4fcSRobert Mustacchi if ((ret = i40e_aq_add_macvlan(hw, i40e->i40e_vsi_id, &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 3569d26e4fcSRobert Mustacchi if (i40e_aq_remove_macvlan(hw, i40e->i40e_vsi_id, 3579d26e4fcSRobert Mustacchi &filt, 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, 3849d26e4fcSRobert Mustacchi i40e->i40e_vsi_id, 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", 3889d26e4fcSRobert Mustacchi i40e->i40e_vsi_id, 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; 4399d26e4fcSRobert Mustacchi 4409d26e4fcSRobert Mustacchi /* 4419d26e4fcSRobert Mustacchi * GLDv3 requires we keep track of a generation number, as it uses 4429d26e4fcSRobert Mustacchi * that number to keep track of whether or not a ring is active. 4439d26e4fcSRobert Mustacchi */ 4449d26e4fcSRobert Mustacchi mutex_enter(&itrq->itrq_rx_lock); 4459d26e4fcSRobert Mustacchi itrq->itrq_rxgen = gen_num; 4469d26e4fcSRobert Mustacchi mutex_exit(&itrq->itrq_rx_lock); 4479d26e4fcSRobert Mustacchi return (0); 4489d26e4fcSRobert Mustacchi } 4499d26e4fcSRobert Mustacchi 4509d26e4fcSRobert Mustacchi /* ARGSUSED */ 4519d26e4fcSRobert Mustacchi static int 4529d26e4fcSRobert Mustacchi i40e_rx_ring_intr_enable(mac_intr_handle_t intrh) 4539d26e4fcSRobert Mustacchi { 4549d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = (i40e_trqpair_t *)intrh; 4559d26e4fcSRobert Mustacchi 456396505afSPaul Winder mutex_enter(&itrq->itrq_rx_lock); 457396505afSPaul Winder ASSERT(itrq->itrq_intr_poll == B_TRUE); 458*338749cbSRobert Mustacchi i40e_intr_rx_queue_enable(itrq); 459396505afSPaul Winder itrq->itrq_intr_poll = B_FALSE; 460396505afSPaul Winder mutex_exit(&itrq->itrq_rx_lock); 4619d26e4fcSRobert Mustacchi 4629d26e4fcSRobert Mustacchi return (0); 4639d26e4fcSRobert Mustacchi } 4649d26e4fcSRobert Mustacchi 4659d26e4fcSRobert Mustacchi /* ARGSUSED */ 4669d26e4fcSRobert Mustacchi static int 4679d26e4fcSRobert Mustacchi i40e_rx_ring_intr_disable(mac_intr_handle_t intrh) 4689d26e4fcSRobert Mustacchi { 4699d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = (i40e_trqpair_t *)intrh; 4709d26e4fcSRobert Mustacchi 471396505afSPaul Winder mutex_enter(&itrq->itrq_rx_lock); 472*338749cbSRobert Mustacchi i40e_intr_rx_queue_disable(itrq); 473396505afSPaul Winder itrq->itrq_intr_poll = B_TRUE; 474396505afSPaul Winder mutex_exit(&itrq->itrq_rx_lock); 4759d26e4fcSRobert Mustacchi 4769d26e4fcSRobert Mustacchi return (0); 4779d26e4fcSRobert Mustacchi } 4789d26e4fcSRobert Mustacchi 4799d26e4fcSRobert Mustacchi /* ARGSUSED */ 4809d26e4fcSRobert Mustacchi static void 4819d26e4fcSRobert Mustacchi i40e_fill_tx_ring(void *arg, mac_ring_type_t rtype, const int group_index, 4829d26e4fcSRobert Mustacchi const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 4839d26e4fcSRobert Mustacchi { 4849d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 4859d26e4fcSRobert Mustacchi mac_intr_t *mintr = &infop->mri_intr; 4869d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = &(i40e->i40e_trqpairs[ring_index]); 4879d26e4fcSRobert Mustacchi 4889d26e4fcSRobert Mustacchi /* 4899d26e4fcSRobert Mustacchi * Note the group index here is expected to be -1 due to the fact that 4909d26e4fcSRobert Mustacchi * we're not actually grouping things tx-wise at this time. 4919d26e4fcSRobert Mustacchi */ 4929d26e4fcSRobert Mustacchi ASSERT(group_index == -1); 4939d26e4fcSRobert Mustacchi ASSERT(ring_index < i40e->i40e_num_trqpairs); 4949d26e4fcSRobert Mustacchi 4959d26e4fcSRobert Mustacchi itrq->itrq_mactxring = rh; 4969d26e4fcSRobert Mustacchi infop->mri_driver = (mac_ring_driver_t)itrq; 4979d26e4fcSRobert Mustacchi infop->mri_start = NULL; 4989d26e4fcSRobert Mustacchi infop->mri_stop = NULL; 4999d26e4fcSRobert Mustacchi infop->mri_tx = i40e_ring_tx; 5009d26e4fcSRobert Mustacchi infop->mri_stat = i40e_tx_ring_stat; 5019d26e4fcSRobert Mustacchi 5029d26e4fcSRobert Mustacchi /* 5039d26e4fcSRobert Mustacchi * We only provide the handle in cases where we have MSI-X interrupts, 5049d26e4fcSRobert Mustacchi * to indicate that we'd actually support retargetting. 5059d26e4fcSRobert Mustacchi */ 5069d26e4fcSRobert Mustacchi if (i40e->i40e_intr_type & DDI_INTR_TYPE_MSIX) { 5079d26e4fcSRobert Mustacchi mintr->mi_ddi_handle = 5089d26e4fcSRobert Mustacchi i40e->i40e_intr_handles[itrq->itrq_tx_intrvec]; 5099d26e4fcSRobert Mustacchi } 5109d26e4fcSRobert Mustacchi } 5119d26e4fcSRobert Mustacchi 5129d26e4fcSRobert Mustacchi /* ARGSUSED */ 5139d26e4fcSRobert Mustacchi static void 5149d26e4fcSRobert Mustacchi i40e_fill_rx_ring(void *arg, mac_ring_type_t rtype, const int group_index, 5159d26e4fcSRobert Mustacchi const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 5169d26e4fcSRobert Mustacchi { 5179d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 5189d26e4fcSRobert Mustacchi mac_intr_t *mintr = &infop->mri_intr; 5199d26e4fcSRobert Mustacchi i40e_trqpair_t *itrq = &i40e->i40e_trqpairs[ring_index]; 5209d26e4fcSRobert Mustacchi 5219d26e4fcSRobert Mustacchi /* 5229d26e4fcSRobert Mustacchi * We assert the group number and ring index to help sanity check 5239d26e4fcSRobert Mustacchi * ourselves and mark that we'll need to rework this when we have 5249d26e4fcSRobert Mustacchi * multiple groups. 5259d26e4fcSRobert Mustacchi */ 5269d26e4fcSRobert Mustacchi ASSERT3S(group_index, ==, 0); 5279d26e4fcSRobert Mustacchi ASSERT3S(ring_index, <, i40e->i40e_num_trqpairs); 5289d26e4fcSRobert Mustacchi 5299d26e4fcSRobert Mustacchi itrq->itrq_macrxring = rh; 5309d26e4fcSRobert Mustacchi infop->mri_driver = (mac_ring_driver_t)itrq; 5319d26e4fcSRobert Mustacchi infop->mri_start = i40e_ring_start; 5329d26e4fcSRobert Mustacchi infop->mri_stop = NULL; 5339d26e4fcSRobert Mustacchi infop->mri_poll = i40e_ring_rx_poll; 5349d26e4fcSRobert Mustacchi infop->mri_stat = i40e_rx_ring_stat; 5359d26e4fcSRobert Mustacchi mintr->mi_handle = (mac_intr_handle_t)itrq; 5369d26e4fcSRobert Mustacchi mintr->mi_enable = i40e_rx_ring_intr_enable; 5379d26e4fcSRobert Mustacchi mintr->mi_disable = i40e_rx_ring_intr_disable; 5389d26e4fcSRobert Mustacchi 5399d26e4fcSRobert Mustacchi /* 5409d26e4fcSRobert Mustacchi * We only provide the handle in cases where we have MSI-X interrupts, 5419d26e4fcSRobert Mustacchi * to indicate that we'd actually support retargetting. 5429d26e4fcSRobert Mustacchi */ 5439d26e4fcSRobert Mustacchi if (i40e->i40e_intr_type & DDI_INTR_TYPE_MSIX) { 5449d26e4fcSRobert Mustacchi mintr->mi_ddi_handle = 5459d26e4fcSRobert Mustacchi i40e->i40e_intr_handles[itrq->itrq_rx_intrvec]; 5469d26e4fcSRobert Mustacchi } 5479d26e4fcSRobert Mustacchi } 5489d26e4fcSRobert Mustacchi 5499d26e4fcSRobert Mustacchi /* ARGSUSED */ 5509d26e4fcSRobert Mustacchi static void 5519d26e4fcSRobert Mustacchi i40e_fill_rx_group(void *arg, mac_ring_type_t rtype, const int index, 5529d26e4fcSRobert Mustacchi mac_group_info_t *infop, mac_group_handle_t gh) 5539d26e4fcSRobert Mustacchi { 5549d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 5559d26e4fcSRobert Mustacchi 5569d26e4fcSRobert Mustacchi if (rtype != MAC_RING_TYPE_RX) 5579d26e4fcSRobert Mustacchi return; 5589d26e4fcSRobert Mustacchi 5599d26e4fcSRobert Mustacchi /* 5609d26e4fcSRobert Mustacchi * Note, this is a simplified view of a group, given that we only have a 5619d26e4fcSRobert Mustacchi * single group and a single ring at the moment. We'll want to expand 5629d26e4fcSRobert Mustacchi * upon this as we leverage more hardware functionality. 5639d26e4fcSRobert Mustacchi */ 5649d26e4fcSRobert Mustacchi i40e->i40e_rx_group_handle = gh; 5659d26e4fcSRobert Mustacchi infop->mgi_driver = (mac_group_driver_t)i40e; 5669d26e4fcSRobert Mustacchi infop->mgi_start = NULL; 5679d26e4fcSRobert Mustacchi infop->mgi_stop = NULL; 5689d26e4fcSRobert Mustacchi infop->mgi_addmac = i40e_group_add_mac; 5699d26e4fcSRobert Mustacchi infop->mgi_remmac = i40e_group_remove_mac; 5709d26e4fcSRobert Mustacchi 5719d26e4fcSRobert Mustacchi ASSERT(i40e->i40e_num_rx_groups == I40E_GROUP_MAX); 5729d26e4fcSRobert Mustacchi infop->mgi_count = i40e->i40e_num_trqpairs; 5739d26e4fcSRobert Mustacchi } 5749d26e4fcSRobert Mustacchi 5759d26e4fcSRobert Mustacchi static boolean_t 5769d26e4fcSRobert Mustacchi i40e_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 5779d26e4fcSRobert Mustacchi { 5789d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 5799d26e4fcSRobert Mustacchi mac_capab_rings_t *cap_rings; 5809d26e4fcSRobert Mustacchi 5819d26e4fcSRobert Mustacchi switch (cap) { 5829d26e4fcSRobert Mustacchi case MAC_CAPAB_HCKSUM: { 5839d26e4fcSRobert Mustacchi uint32_t *txflags = cap_data; 5849d26e4fcSRobert Mustacchi 5859d26e4fcSRobert Mustacchi *txflags = 0; 5869d26e4fcSRobert Mustacchi if (i40e->i40e_tx_hcksum_enable == B_TRUE) 5879d26e4fcSRobert Mustacchi *txflags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 5889d26e4fcSRobert Mustacchi break; 5899d26e4fcSRobert Mustacchi } 5909d26e4fcSRobert Mustacchi 5919d26e4fcSRobert Mustacchi case MAC_CAPAB_RINGS: 5929d26e4fcSRobert Mustacchi cap_rings = cap_data; 5939d26e4fcSRobert Mustacchi cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 5949d26e4fcSRobert Mustacchi switch (cap_rings->mr_type) { 5959d26e4fcSRobert Mustacchi case MAC_RING_TYPE_TX: 5969d26e4fcSRobert Mustacchi /* 5979d26e4fcSRobert Mustacchi * Note, saying we have no rings, but some number of 5989d26e4fcSRobert Mustacchi * groups indicates to MAC that it should create 5999d26e4fcSRobert Mustacchi * psuedo-groups with one for each TX ring. This may not 6009d26e4fcSRobert Mustacchi * be the long term behavior we want, but it'll work for 6019d26e4fcSRobert Mustacchi * now. 6029d26e4fcSRobert Mustacchi */ 6039d26e4fcSRobert Mustacchi cap_rings->mr_gnum = 0; 6049d26e4fcSRobert Mustacchi cap_rings->mr_rnum = i40e->i40e_num_trqpairs; 6059d26e4fcSRobert Mustacchi cap_rings->mr_rget = i40e_fill_tx_ring; 6069d26e4fcSRobert Mustacchi cap_rings->mr_gget = NULL; 6079d26e4fcSRobert Mustacchi cap_rings->mr_gaddring = NULL; 6089d26e4fcSRobert Mustacchi cap_rings->mr_gremring = NULL; 6099d26e4fcSRobert Mustacchi break; 6109d26e4fcSRobert Mustacchi case MAC_RING_TYPE_RX: 6119d26e4fcSRobert Mustacchi cap_rings->mr_rnum = i40e->i40e_num_trqpairs; 6129d26e4fcSRobert Mustacchi cap_rings->mr_rget = i40e_fill_rx_ring; 6139d26e4fcSRobert Mustacchi cap_rings->mr_gnum = I40E_GROUP_MAX; 6149d26e4fcSRobert Mustacchi cap_rings->mr_gget = i40e_fill_rx_group; 6159d26e4fcSRobert Mustacchi cap_rings->mr_gaddring = NULL; 6169d26e4fcSRobert Mustacchi cap_rings->mr_gremring = NULL; 6179d26e4fcSRobert Mustacchi break; 6189d26e4fcSRobert Mustacchi default: 6199d26e4fcSRobert Mustacchi return (B_FALSE); 6209d26e4fcSRobert Mustacchi } 6219d26e4fcSRobert Mustacchi break; 6229d26e4fcSRobert Mustacchi default: 6239d26e4fcSRobert Mustacchi return (B_FALSE); 6249d26e4fcSRobert Mustacchi } 6259d26e4fcSRobert Mustacchi 6269d26e4fcSRobert Mustacchi return (B_TRUE); 6279d26e4fcSRobert Mustacchi } 6289d26e4fcSRobert Mustacchi 6299d26e4fcSRobert Mustacchi /* ARGSUSED */ 6309d26e4fcSRobert Mustacchi static int 6319d26e4fcSRobert Mustacchi i40e_m_setprop_private(i40e_t *i40e, const char *pr_name, uint_t pr_valsize, 6329d26e4fcSRobert Mustacchi const void *pr_val) 6339d26e4fcSRobert Mustacchi { 6349d26e4fcSRobert Mustacchi int ret; 6359d26e4fcSRobert Mustacchi long val; 6369d26e4fcSRobert Mustacchi char *eptr; 6379d26e4fcSRobert Mustacchi 6389d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 6399d26e4fcSRobert Mustacchi 6409d26e4fcSRobert Mustacchi if ((ret = ddi_strtol(pr_val, &eptr, 10, &val)) != 0 || 6419d26e4fcSRobert Mustacchi *eptr != '\0') { 6429d26e4fcSRobert Mustacchi return (ret); 6439d26e4fcSRobert Mustacchi } 6449d26e4fcSRobert Mustacchi 6459d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 6469d26e4fcSRobert Mustacchi if (val < I40E_MIN_RX_DMA_THRESH || 6479d26e4fcSRobert Mustacchi val > I40E_MAX_RX_DMA_THRESH) { 6489d26e4fcSRobert Mustacchi return (EINVAL); 6499d26e4fcSRobert Mustacchi } 6509d26e4fcSRobert Mustacchi i40e->i40e_rx_dma_min = (uint32_t)val; 6519d26e4fcSRobert Mustacchi return (0); 6529d26e4fcSRobert Mustacchi } 6539d26e4fcSRobert Mustacchi 6549d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 6559d26e4fcSRobert Mustacchi if (val < I40E_MIN_TX_DMA_THRESH || 6569d26e4fcSRobert Mustacchi val > I40E_MAX_TX_DMA_THRESH) { 6579d26e4fcSRobert Mustacchi return (EINVAL); 6589d26e4fcSRobert Mustacchi } 6599d26e4fcSRobert Mustacchi i40e->i40e_tx_dma_min = (uint32_t)val; 6609d26e4fcSRobert Mustacchi return (0); 6619d26e4fcSRobert Mustacchi } 6629d26e4fcSRobert Mustacchi 6639d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 6649d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 6659d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 6669d26e4fcSRobert Mustacchi return (EINVAL); 6679d26e4fcSRobert Mustacchi } 6689d26e4fcSRobert Mustacchi i40e->i40e_rx_itr = (uint32_t)val; 6699d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_RX, i40e->i40e_rx_itr); 6709d26e4fcSRobert Mustacchi return (0); 6719d26e4fcSRobert Mustacchi } 6729d26e4fcSRobert Mustacchi 6739d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 6749d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 6759d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 6769d26e4fcSRobert Mustacchi return (EINVAL); 6779d26e4fcSRobert Mustacchi } 6789d26e4fcSRobert Mustacchi i40e->i40e_tx_itr = (uint32_t)val; 6799d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_TX, i40e->i40e_tx_itr); 6809d26e4fcSRobert Mustacchi return (0); 6819d26e4fcSRobert Mustacchi } 6829d26e4fcSRobert Mustacchi 6839d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 6849d26e4fcSRobert Mustacchi if (val < I40E_MIN_ITR || 6859d26e4fcSRobert Mustacchi val > I40E_MAX_ITR) { 6869d26e4fcSRobert Mustacchi return (EINVAL); 6879d26e4fcSRobert Mustacchi } 6889d26e4fcSRobert Mustacchi i40e->i40e_tx_itr = (uint32_t)val; 6899d26e4fcSRobert Mustacchi i40e_intr_set_itr(i40e, I40E_ITR_INDEX_OTHER, 6909d26e4fcSRobert Mustacchi i40e->i40e_other_itr); 6919d26e4fcSRobert Mustacchi return (0); 6929d26e4fcSRobert Mustacchi } 6939d26e4fcSRobert Mustacchi 6949d26e4fcSRobert Mustacchi return (ENOTSUP); 6959d26e4fcSRobert Mustacchi } 6969d26e4fcSRobert Mustacchi 6979d26e4fcSRobert Mustacchi static int 6989d26e4fcSRobert Mustacchi i40e_m_getprop_private(i40e_t *i40e, const char *pr_name, uint_t pr_valsize, 6999d26e4fcSRobert Mustacchi void *pr_val) 7009d26e4fcSRobert Mustacchi { 7019d26e4fcSRobert Mustacchi uint32_t val; 7029d26e4fcSRobert Mustacchi 7039d26e4fcSRobert Mustacchi ASSERT(MUTEX_HELD(&i40e->i40e_general_lock)); 7049d26e4fcSRobert Mustacchi 7059d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 7069d26e4fcSRobert Mustacchi val = i40e->i40e_rx_dma_min; 7079d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 7089d26e4fcSRobert Mustacchi val = i40e->i40e_tx_dma_min; 7099d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 7109d26e4fcSRobert Mustacchi val = i40e->i40e_rx_itr; 7119d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 7129d26e4fcSRobert Mustacchi val = i40e->i40e_tx_itr; 7139d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 7149d26e4fcSRobert Mustacchi val = i40e->i40e_other_itr; 7159d26e4fcSRobert Mustacchi } else { 7169d26e4fcSRobert Mustacchi return (ENOTSUP); 7179d26e4fcSRobert Mustacchi } 7189d26e4fcSRobert Mustacchi 7199d26e4fcSRobert Mustacchi if (snprintf(pr_val, pr_valsize, "%d", val) >= pr_valsize) 7209d26e4fcSRobert Mustacchi return (ERANGE); 7219d26e4fcSRobert Mustacchi return (0); 7229d26e4fcSRobert Mustacchi } 7239d26e4fcSRobert Mustacchi 7249d26e4fcSRobert Mustacchi /* 7259d26e4fcSRobert Mustacchi * Annoyingly for private properties MAC seems to ignore default values that 7269d26e4fcSRobert Mustacchi * aren't strings. That means that we have to translate all of these into 7279d26e4fcSRobert Mustacchi * uint32_t's and instead we size the buffer to be large enough to hold a 7289d26e4fcSRobert Mustacchi * uint32_t. 7299d26e4fcSRobert Mustacchi */ 7309d26e4fcSRobert Mustacchi /* ARGSUSED */ 7319d26e4fcSRobert Mustacchi static void 7329d26e4fcSRobert Mustacchi i40e_m_propinfo_private(i40e_t *i40e, const char *pr_name, 7339d26e4fcSRobert Mustacchi mac_prop_info_handle_t prh) 7349d26e4fcSRobert Mustacchi { 7359d26e4fcSRobert Mustacchi char buf[64]; 7369d26e4fcSRobert Mustacchi uint32_t def; 7379d26e4fcSRobert Mustacchi 7389d26e4fcSRobert Mustacchi if (strcmp(pr_name, I40E_PROP_RX_DMA_THRESH) == 0) { 7399d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 7409d26e4fcSRobert Mustacchi def = I40E_DEF_RX_DMA_THRESH; 7419d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, 7429d26e4fcSRobert Mustacchi I40E_MIN_RX_DMA_THRESH, 7439d26e4fcSRobert Mustacchi I40E_MAX_RX_DMA_THRESH); 7449d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_DMA_THRESH) == 0) { 7459d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 7469d26e4fcSRobert Mustacchi def = I40E_DEF_TX_DMA_THRESH; 7479d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, 7489d26e4fcSRobert Mustacchi I40E_MIN_TX_DMA_THRESH, 7499d26e4fcSRobert Mustacchi I40E_MAX_TX_DMA_THRESH); 7509d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_RX_ITR) == 0) { 7519d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 7529d26e4fcSRobert Mustacchi def = I40E_DEF_RX_ITR; 7539d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 7549d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_TX_ITR) == 0) { 7559d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 7569d26e4fcSRobert Mustacchi def = I40E_DEF_TX_ITR; 7579d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 7589d26e4fcSRobert Mustacchi } else if (strcmp(pr_name, I40E_PROP_OTHER_ITR) == 0) { 7599d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 7609d26e4fcSRobert Mustacchi def = I40E_DEF_OTHER_ITR; 7619d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_ITR, I40E_MAX_ITR); 7629d26e4fcSRobert Mustacchi } else { 7639d26e4fcSRobert Mustacchi return; 7649d26e4fcSRobert Mustacchi } 7659d26e4fcSRobert Mustacchi 7669d26e4fcSRobert Mustacchi (void) snprintf(buf, sizeof (buf), "%d", def); 7679d26e4fcSRobert Mustacchi mac_prop_info_set_default_str(prh, buf); 7689d26e4fcSRobert Mustacchi } 7699d26e4fcSRobert Mustacchi 7709d26e4fcSRobert Mustacchi static int 7719d26e4fcSRobert Mustacchi i40e_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 7729d26e4fcSRobert Mustacchi uint_t pr_valsize, const void *pr_val) 7739d26e4fcSRobert Mustacchi { 7749d26e4fcSRobert Mustacchi uint32_t new_mtu; 7759d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 7769d26e4fcSRobert Mustacchi int ret = 0; 7779d26e4fcSRobert Mustacchi 7789d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 7799d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_SUSPENDED) { 7809d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 7819d26e4fcSRobert Mustacchi return (ECANCELED); 7829d26e4fcSRobert Mustacchi } 7839d26e4fcSRobert Mustacchi 7849d26e4fcSRobert Mustacchi switch (pr_num) { 7859d26e4fcSRobert Mustacchi /* 7869d26e4fcSRobert Mustacchi * These properties are always read-only across every device. 7879d26e4fcSRobert Mustacchi */ 7889d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 7899d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 7909d26e4fcSRobert Mustacchi case MAC_PROP_STATUS: 7919d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 7929d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 7939d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 7943d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 7959d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 7969d26e4fcSRobert Mustacchi ret = ENOTSUP; 7979d26e4fcSRobert Mustacchi break; 7989d26e4fcSRobert Mustacchi /* 7999d26e4fcSRobert Mustacchi * These are read-only at this time as we don't support configuring 8009d26e4fcSRobert Mustacchi * auto-negotiation. See the theory statement in i40e_main.c. 8019d26e4fcSRobert Mustacchi */ 8029d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 8039d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 8049d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 8053d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 8069d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 8079d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 8089d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 8099d26e4fcSRobert Mustacchi ret = ENOTSUP; 8109d26e4fcSRobert Mustacchi break; 8119d26e4fcSRobert Mustacchi 8129d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 8139d26e4fcSRobert Mustacchi bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 8149d26e4fcSRobert Mustacchi if (new_mtu == i40e->i40e_sdu) 8159d26e4fcSRobert Mustacchi break; 8169d26e4fcSRobert Mustacchi 8179d26e4fcSRobert Mustacchi if (new_mtu < I40E_MIN_MTU || 8189d26e4fcSRobert Mustacchi new_mtu > I40E_MAX_MTU) { 8199d26e4fcSRobert Mustacchi ret = EINVAL; 8209d26e4fcSRobert Mustacchi break; 8219d26e4fcSRobert Mustacchi } 8229d26e4fcSRobert Mustacchi 8239d26e4fcSRobert Mustacchi if (i40e->i40e_state & I40E_STARTED) { 8249d26e4fcSRobert Mustacchi ret = EBUSY; 8259d26e4fcSRobert Mustacchi break; 8269d26e4fcSRobert Mustacchi } 8279d26e4fcSRobert Mustacchi 8289d26e4fcSRobert Mustacchi ret = mac_maxsdu_update(i40e->i40e_mac_hdl, new_mtu); 8299d26e4fcSRobert Mustacchi if (ret == 0) { 8309d26e4fcSRobert Mustacchi i40e->i40e_sdu = new_mtu; 8319d26e4fcSRobert Mustacchi i40e_update_mtu(i40e); 8329d26e4fcSRobert Mustacchi } 8339d26e4fcSRobert Mustacchi break; 8349d26e4fcSRobert Mustacchi 8359d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 8369d26e4fcSRobert Mustacchi ret = i40e_m_setprop_private(i40e, pr_name, pr_valsize, pr_val); 8379d26e4fcSRobert Mustacchi break; 8389d26e4fcSRobert Mustacchi default: 8399d26e4fcSRobert Mustacchi ret = ENOTSUP; 8409d26e4fcSRobert Mustacchi break; 8419d26e4fcSRobert Mustacchi } 8429d26e4fcSRobert Mustacchi 8439d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 8449d26e4fcSRobert Mustacchi return (ret); 8459d26e4fcSRobert Mustacchi } 8469d26e4fcSRobert Mustacchi 8479d26e4fcSRobert Mustacchi static int 8489d26e4fcSRobert Mustacchi i40e_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 8499d26e4fcSRobert Mustacchi uint_t pr_valsize, void *pr_val) 8509d26e4fcSRobert Mustacchi { 8519d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 8529d26e4fcSRobert Mustacchi uint64_t speed; 8539d26e4fcSRobert Mustacchi int ret = 0; 8549d26e4fcSRobert Mustacchi uint8_t *u8; 8559d26e4fcSRobert Mustacchi link_flowctrl_t fctl; 8569d26e4fcSRobert Mustacchi 8579d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 8589d26e4fcSRobert Mustacchi 8599d26e4fcSRobert Mustacchi switch (pr_num) { 8609d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 8619d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_duplex_t)) { 8629d26e4fcSRobert Mustacchi ret = EOVERFLOW; 8639d26e4fcSRobert Mustacchi break; 8649d26e4fcSRobert Mustacchi } 8659d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_link_duplex, pr_val, sizeof (link_duplex_t)); 8669d26e4fcSRobert Mustacchi break; 8679d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 8689d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint64_t)) { 8699d26e4fcSRobert Mustacchi ret = EOVERFLOW; 8709d26e4fcSRobert Mustacchi break; 8719d26e4fcSRobert Mustacchi } 8729d26e4fcSRobert Mustacchi speed = i40e->i40e_link_speed * 1000000ULL; 8739d26e4fcSRobert Mustacchi bcopy(&speed, pr_val, sizeof (speed)); 8749d26e4fcSRobert Mustacchi break; 8759d26e4fcSRobert Mustacchi case MAC_PROP_STATUS: 8769d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_state_t)) { 8779d26e4fcSRobert Mustacchi ret = EOVERFLOW; 8789d26e4fcSRobert Mustacchi break; 8799d26e4fcSRobert Mustacchi } 8809d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_link_state, pr_val, sizeof (link_state_t)); 8819d26e4fcSRobert Mustacchi break; 8829d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 8839d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 8849d26e4fcSRobert Mustacchi ret = EOVERFLOW; 8859d26e4fcSRobert Mustacchi break; 8869d26e4fcSRobert Mustacchi } 8879d26e4fcSRobert Mustacchi u8 = pr_val; 8889d26e4fcSRobert Mustacchi *u8 = 1; 8899d26e4fcSRobert Mustacchi break; 8909d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 8919d26e4fcSRobert Mustacchi /* 8929d26e4fcSRobert Mustacchi * Because we don't currently support hardware flow control, we 8939d26e4fcSRobert Mustacchi * just hardcode this to be none. 8949d26e4fcSRobert Mustacchi */ 8959d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (link_flowctrl_t)) { 8969d26e4fcSRobert Mustacchi ret = EOVERFLOW; 8979d26e4fcSRobert Mustacchi break; 8989d26e4fcSRobert Mustacchi } 8999d26e4fcSRobert Mustacchi fctl = LINK_FLOWCTRL_NONE; 9009d26e4fcSRobert Mustacchi bcopy(&fctl, pr_val, sizeof (link_flowctrl_t)); 9019d26e4fcSRobert Mustacchi break; 9029d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 9039d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint32_t)) { 9049d26e4fcSRobert Mustacchi ret = EOVERFLOW; 9059d26e4fcSRobert Mustacchi break; 9069d26e4fcSRobert Mustacchi } 9079d26e4fcSRobert Mustacchi bcopy(&i40e->i40e_sdu, pr_val, sizeof (uint32_t)); 9089d26e4fcSRobert Mustacchi break; 9099d26e4fcSRobert Mustacchi 9109d26e4fcSRobert Mustacchi /* 9119d26e4fcSRobert Mustacchi * Because we don't let users control the speeds we may auto-negotiate 9129d26e4fcSRobert Mustacchi * to, the values of the ADV_ and EN_ will always be the same. 9139d26e4fcSRobert Mustacchi */ 9149d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 9159d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 9169d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 9179d26e4fcSRobert Mustacchi ret = EOVERFLOW; 9189d26e4fcSRobert Mustacchi break; 9199d26e4fcSRobert Mustacchi } 9209d26e4fcSRobert Mustacchi u8 = pr_val; 9219d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0; 9229d26e4fcSRobert Mustacchi break; 9239d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 9249d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 9259d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 9269d26e4fcSRobert Mustacchi ret = EOVERFLOW; 9279d26e4fcSRobert Mustacchi break; 9289d26e4fcSRobert Mustacchi } 9299d26e4fcSRobert Mustacchi u8 = pr_val; 9309d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0; 9319d26e4fcSRobert Mustacchi break; 9329d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 9339d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 9349d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 9359d26e4fcSRobert Mustacchi ret = EOVERFLOW; 9369d26e4fcSRobert Mustacchi break; 9379d26e4fcSRobert Mustacchi } 9389d26e4fcSRobert Mustacchi u8 = pr_val; 9399d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0; 9409d26e4fcSRobert Mustacchi break; 9413d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 9423d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 9433d75a287SRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 9443d75a287SRobert Mustacchi ret = EOVERFLOW; 9453d75a287SRobert Mustacchi break; 9463d75a287SRobert Mustacchi } 9473d75a287SRobert Mustacchi u8 = pr_val; 9483d75a287SRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0; 9493d75a287SRobert Mustacchi break; 9509d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 9519d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 9529d26e4fcSRobert Mustacchi if (pr_valsize < sizeof (uint8_t)) { 9539d26e4fcSRobert Mustacchi ret = EOVERFLOW; 9549d26e4fcSRobert Mustacchi break; 9559d26e4fcSRobert Mustacchi } 9569d26e4fcSRobert Mustacchi u8 = pr_val; 9579d26e4fcSRobert Mustacchi *u8 = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0; 9589d26e4fcSRobert Mustacchi break; 9599d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 9609d26e4fcSRobert Mustacchi ret = i40e_m_getprop_private(i40e, pr_name, pr_valsize, pr_val); 9619d26e4fcSRobert Mustacchi break; 9629d26e4fcSRobert Mustacchi default: 9639d26e4fcSRobert Mustacchi ret = ENOTSUP; 9649d26e4fcSRobert Mustacchi break; 9659d26e4fcSRobert Mustacchi } 9669d26e4fcSRobert Mustacchi 9679d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 9689d26e4fcSRobert Mustacchi 9699d26e4fcSRobert Mustacchi return (ret); 9709d26e4fcSRobert Mustacchi } 9719d26e4fcSRobert Mustacchi 9729d26e4fcSRobert Mustacchi static void 9739d26e4fcSRobert Mustacchi i40e_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 9749d26e4fcSRobert Mustacchi mac_prop_info_handle_t prh) 9759d26e4fcSRobert Mustacchi { 9769d26e4fcSRobert Mustacchi i40e_t *i40e = arg; 9779d26e4fcSRobert Mustacchi 9789d26e4fcSRobert Mustacchi mutex_enter(&i40e->i40e_general_lock); 9799d26e4fcSRobert Mustacchi 9809d26e4fcSRobert Mustacchi switch (pr_num) { 9819d26e4fcSRobert Mustacchi case MAC_PROP_DUPLEX: 9829d26e4fcSRobert Mustacchi case MAC_PROP_SPEED: 9839d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 9849d26e4fcSRobert Mustacchi break; 9859d26e4fcSRobert Mustacchi case MAC_PROP_FLOWCTRL: 9869d26e4fcSRobert Mustacchi /* 9879d26e4fcSRobert Mustacchi * At the moment, the driver doesn't support flow control, hence 9889d26e4fcSRobert Mustacchi * why this is set to read-only and none. 9899d26e4fcSRobert Mustacchi */ 9909d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 9919d26e4fcSRobert Mustacchi mac_prop_info_set_default_link_flowctrl(prh, 9929d26e4fcSRobert Mustacchi LINK_FLOWCTRL_NONE); 9939d26e4fcSRobert Mustacchi break; 9949d26e4fcSRobert Mustacchi case MAC_PROP_MTU: 9959d26e4fcSRobert Mustacchi mac_prop_info_set_range_uint32(prh, I40E_MIN_MTU, I40E_MAX_MTU); 9969d26e4fcSRobert Mustacchi break; 9979d26e4fcSRobert Mustacchi 9989d26e4fcSRobert Mustacchi /* 9999d26e4fcSRobert Mustacchi * We set the defaults for these based upon the phy's ability to 10009d26e4fcSRobert Mustacchi * support the speeds. Note, auto-negotiation is required for fiber, 10019d26e4fcSRobert Mustacchi * hence it is read-only and always enabled. When we have access to 10029d26e4fcSRobert Mustacchi * copper phys we can revisit this. 10039d26e4fcSRobert Mustacchi */ 10049d26e4fcSRobert Mustacchi case MAC_PROP_AUTONEG: 10059d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10069d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 1); 10079d26e4fcSRobert Mustacchi break; 10089d26e4fcSRobert Mustacchi case MAC_PROP_ADV_100FDX_CAP: 10099d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10109d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10119d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0); 10129d26e4fcSRobert Mustacchi break; 10139d26e4fcSRobert Mustacchi case MAC_PROP_EN_100FDX_CAP: 10149d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10159d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10169d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0); 10179d26e4fcSRobert Mustacchi break; 10189d26e4fcSRobert Mustacchi case MAC_PROP_ADV_1000FDX_CAP: 10199d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10209d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10219d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0); 10229d26e4fcSRobert Mustacchi break; 10239d26e4fcSRobert Mustacchi case MAC_PROP_EN_1000FDX_CAP: 10249d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10259d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10269d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0); 10279d26e4fcSRobert Mustacchi break; 10289d26e4fcSRobert Mustacchi case MAC_PROP_ADV_10GFDX_CAP: 10299d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10309d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10319d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0); 10329d26e4fcSRobert Mustacchi break; 10339d26e4fcSRobert Mustacchi case MAC_PROP_EN_10GFDX_CAP: 10349d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10359d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10369d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0); 10379d26e4fcSRobert Mustacchi break; 10383d75a287SRobert Mustacchi case MAC_PROP_ADV_25GFDX_CAP: 10393d75a287SRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10403d75a287SRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10413d75a287SRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0); 10423d75a287SRobert Mustacchi break; 10433d75a287SRobert Mustacchi case MAC_PROP_EN_25GFDX_CAP: 10443d75a287SRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10453d75a287SRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10463d75a287SRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0); 10473d75a287SRobert Mustacchi break; 10489d26e4fcSRobert Mustacchi case MAC_PROP_ADV_40GFDX_CAP: 10499d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10509d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10519d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0); 10529d26e4fcSRobert Mustacchi break; 10539d26e4fcSRobert Mustacchi case MAC_PROP_EN_40GFDX_CAP: 10549d26e4fcSRobert Mustacchi mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 10559d26e4fcSRobert Mustacchi mac_prop_info_set_default_uint8(prh, 10569d26e4fcSRobert Mustacchi (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0); 10579d26e4fcSRobert Mustacchi break; 10589d26e4fcSRobert Mustacchi case MAC_PROP_PRIVATE: 10599d26e4fcSRobert Mustacchi i40e_m_propinfo_private(i40e, pr_name, prh); 10609d26e4fcSRobert Mustacchi break; 10619d26e4fcSRobert Mustacchi default: 10629d26e4fcSRobert Mustacchi break; 10639d26e4fcSRobert Mustacchi } 10649d26e4fcSRobert Mustacchi 10659d26e4fcSRobert Mustacchi mutex_exit(&i40e->i40e_general_lock); 10669d26e4fcSRobert Mustacchi } 10679d26e4fcSRobert Mustacchi 10689d26e4fcSRobert Mustacchi #define I40E_M_CALLBACK_FLAGS \ 10699d26e4fcSRobert Mustacchi (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO) 10709d26e4fcSRobert Mustacchi 10719d26e4fcSRobert Mustacchi static mac_callbacks_t i40e_m_callbacks = { 10729d26e4fcSRobert Mustacchi I40E_M_CALLBACK_FLAGS, 10739d26e4fcSRobert Mustacchi i40e_m_stat, 10749d26e4fcSRobert Mustacchi i40e_m_start, 10759d26e4fcSRobert Mustacchi i40e_m_stop, 10769d26e4fcSRobert Mustacchi i40e_m_promisc, 10779d26e4fcSRobert Mustacchi i40e_m_multicast, 10789d26e4fcSRobert Mustacchi NULL, 10799d26e4fcSRobert Mustacchi NULL, 10809d26e4fcSRobert Mustacchi NULL, 10819d26e4fcSRobert Mustacchi i40e_m_ioctl, 10829d26e4fcSRobert Mustacchi i40e_m_getcapab, 10839d26e4fcSRobert Mustacchi NULL, 10849d26e4fcSRobert Mustacchi NULL, 10859d26e4fcSRobert Mustacchi i40e_m_setprop, 10869d26e4fcSRobert Mustacchi i40e_m_getprop, 10879d26e4fcSRobert Mustacchi i40e_m_propinfo 10889d26e4fcSRobert Mustacchi }; 10899d26e4fcSRobert Mustacchi 10909d26e4fcSRobert Mustacchi boolean_t 10919d26e4fcSRobert Mustacchi i40e_register_mac(i40e_t *i40e) 10929d26e4fcSRobert Mustacchi { 10939d26e4fcSRobert Mustacchi struct i40e_hw *hw = &i40e->i40e_hw_space; 10949d26e4fcSRobert Mustacchi int status; 10959d26e4fcSRobert Mustacchi mac_register_t *mac = mac_alloc(MAC_VERSION); 10969d26e4fcSRobert Mustacchi 10979d26e4fcSRobert Mustacchi if (mac == NULL) 10989d26e4fcSRobert Mustacchi return (B_FALSE); 10999d26e4fcSRobert Mustacchi 11009d26e4fcSRobert Mustacchi mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 11019d26e4fcSRobert Mustacchi mac->m_driver = i40e; 11029d26e4fcSRobert Mustacchi mac->m_dip = i40e->i40e_dip; 11039d26e4fcSRobert Mustacchi mac->m_src_addr = hw->mac.addr; 11049d26e4fcSRobert Mustacchi mac->m_callbacks = &i40e_m_callbacks; 11059d26e4fcSRobert Mustacchi mac->m_min_sdu = 0; 11069d26e4fcSRobert Mustacchi mac->m_max_sdu = i40e->i40e_sdu; 11079d26e4fcSRobert Mustacchi mac->m_margin = VLAN_TAGSZ; 11089d26e4fcSRobert Mustacchi mac->m_priv_props = i40e_priv_props; 11099d26e4fcSRobert Mustacchi mac->m_v12n = MAC_VIRT_LEVEL1; 11109d26e4fcSRobert Mustacchi 11119d26e4fcSRobert Mustacchi status = mac_register(mac, &i40e->i40e_mac_hdl); 11129d26e4fcSRobert Mustacchi if (status != 0) 11139d26e4fcSRobert Mustacchi i40e_error(i40e, "mac_register() returned %d", status); 11149d26e4fcSRobert Mustacchi mac_free(mac); 11159d26e4fcSRobert Mustacchi 11169d26e4fcSRobert Mustacchi return (status == 0); 11179d26e4fcSRobert Mustacchi } 1118