static int i40e_pf_host_process_cmd_config_promisc_mode( struct i40e_pf_vf *vf, uint8_t *msg, uint16_t msglen) { int ret = I40E_SUCCESS; struct i40e_virtchnl_promisc_info *promisc = (struct i40e_virtchnl_promisc_info *)msg; struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); bool unicast = FALSE, multicast = FALSE; if (msg == NULL || msglen != sizeof(*promisc)) { ret = I40E_ERR_PARAM; goto send_msg; } if (promisc->flags & I40E_FLAG_VF_UNICAST_PROMISC) unicast = TRUE; ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vf->vsi->seid, unicast, NULL); if (ret != I40E_SUCCESS) goto send_msg; if (promisc->flags & I40E_FLAG_VF_MULTICAST_PROMISC) multicast = TRUE; ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid, multicast, NULL); send_msg: i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, ret, NULL, 0); return ret; }
/* * Enable and disable promiscuous mode as requested. We have to toggle both * unicast and multicast. Note that multicast may already be enabled due to the * i40e_m_multicast may toggle it itself. See i40e_main.c for more information * on this. */ static int i40e_m_promisc(void *arg, boolean_t on) { i40e_t *i40e = arg; struct i40e_hw *hw = &i40e->i40e_hw_space; int ret = 0, err = 0; mutex_enter(&i40e->i40e_general_lock); if (i40e->i40e_state & I40E_SUSPENDED) { ret = ECANCELED; goto done; } ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id, on, NULL); if (ret != I40E_SUCCESS) { i40e_error(i40e, "failed to %s unicast promiscuity on " "the default VSI: %d", on == B_TRUE ? "enable" : "disable", ret); err = EIO; goto done; } /* * If we have a non-zero mcast_promisc_count, then it has already been * enabled or we need to leave it that way and not touch it. */ if (i40e->i40e_mcast_promisc_count > 0) { i40e->i40e_promisc_on = on; goto done; } ret = i40e_aq_set_vsi_multicast_promiscuous(hw, i40e->i40e_vsi_id, on, NULL); if (ret != I40E_SUCCESS) { i40e_error(i40e, "failed to %s multicast promiscuity on " "the default VSI: %d", on == B_TRUE ? "enable" : "disable", ret); /* * Try our best to put us back into a state that MAC expects us * to be in. */ ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id, !on, NULL); if (ret != I40E_SUCCESS) { i40e_error(i40e, "failed to %s unicast promiscuity on " "the default VSI after toggling multicast failed: " "%d", on == B_TRUE ? "disable" : "enable", ret); } err = EIO; goto done; } else { i40e->i40e_promisc_on = on; } done: mutex_exit(&i40e->i40e_general_lock); return (err); }