void fm10k_restore_rx_state(struct fm10k_intfc *interface) { struct net_device *netdev = interface->netdev; struct fm10k_hw *hw = &interface->hw; int xcast_mode; u16 vid, glort; /* record glort for this interface */ glort = interface->glort; /* convert interface flags to xcast mode */ if (netdev->flags & IFF_PROMISC) xcast_mode = FM10K_XCAST_MODE_PROMISC; else if (netdev->flags & IFF_ALLMULTI) xcast_mode = FM10K_XCAST_MODE_ALLMULTI; else if (netdev->flags & (IFF_BROADCAST | IFF_MULTICAST)) xcast_mode = FM10K_XCAST_MODE_MULTI; else xcast_mode = FM10K_XCAST_MODE_NONE; fm10k_mbx_lock(interface); /* Enable logical port */ hw->mac.ops.update_lport_state(hw, glort, interface->glort_count, true); /* update VLAN table */ hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, xcast_mode == FM10K_XCAST_MODE_PROMISC); /* Add filter for VLAN 0 */ hw->mac.ops.update_vlan(hw, 0, 0, true); /* update table with current entries */ for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; vid < VLAN_N_VID; vid = fm10k_find_next_vlan(interface, vid)) { hw->mac.ops.update_vlan(hw, vid, 0, true); hw->mac.ops.update_uc_addr(hw, glort, hw->mac.addr, vid, true, 0); } /* update xcast mode before synchronizing addresses */ hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode); /* synchronize all of the addresses */ __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync); __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync); fm10k_mbx_unlock(interface); /* record updated xcast mode state */ interface->xcast_mode = xcast_mode; /* Restore tunnel configuration */ fm10k_restore_udp_port_info(interface); }
static void fm10k_set_rx_mode(struct net_device *dev) { struct fm10k_intfc *interface = netdev_priv(dev); struct fm10k_hw *hw = &interface->hw; int xcast_mode; /* no need to update the harwdare if we are not running */ if (!(dev->flags & IFF_UP)) return; /* determine new mode based on flags */ xcast_mode = (dev->flags & IFF_PROMISC) ? FM10K_XCAST_MODE_PROMISC : (dev->flags & IFF_ALLMULTI) ? FM10K_XCAST_MODE_ALLMULTI : (dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) ? FM10K_XCAST_MODE_MULTI : FM10K_XCAST_MODE_NONE; fm10k_mbx_lock(interface); /* syncronize all of the addresses */ if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { __dev_uc_sync(dev, fm10k_uc_sync, fm10k_uc_unsync); if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) __dev_mc_sync(dev, fm10k_mc_sync, fm10k_mc_unsync); } /* if we aren't changing modes there is nothing to do */ if (interface->xcast_mode != xcast_mode) { /* update VLAN table */ if (xcast_mode == FM10K_XCAST_MODE_PROMISC) hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, true); if (interface->xcast_mode == FM10K_XCAST_MODE_PROMISC) fm10k_clear_unused_vlans(interface); /* update xcast mode */ hw->mac.ops.update_xcast_mode(hw, interface->glort, xcast_mode); /* record updated xcast mode state */ interface->xcast_mode = xcast_mode; } fm10k_mbx_unlock(interface); }
void fm10k_restore_rx_state(struct fm10k_intfc *interface) { struct net_device *netdev = interface->netdev; struct fm10k_hw *hw = &interface->hw; int xcast_mode; u16 vid, glort; /* restore our address if perm_addr is set */ if (hw->mac.type == fm10k_mac_vf) { if (is_valid_ether_addr(hw->mac.perm_addr)) { ether_addr_copy(hw->mac.addr, hw->mac.perm_addr); ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr); ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr); netdev->addr_assign_type &= ~NET_ADDR_RANDOM; } if (hw->mac.vlan_override) netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; else netdev->features |= NETIF_F_HW_VLAN_CTAG_RX; } /* record glort for this interface */ glort = interface->glort; /* convert interface flags to xcast mode */ if (netdev->flags & IFF_PROMISC) xcast_mode = FM10K_XCAST_MODE_PROMISC; else if (netdev->flags & IFF_ALLMULTI) xcast_mode = FM10K_XCAST_MODE_ALLMULTI; else if (netdev->flags & (IFF_BROADCAST | IFF_MULTICAST)) xcast_mode = FM10K_XCAST_MODE_MULTI; else xcast_mode = FM10K_XCAST_MODE_NONE; fm10k_mbx_lock(interface); /* Enable logical port */ hw->mac.ops.update_lport_state(hw, glort, interface->glort_count, true); /* update VLAN table */ hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, xcast_mode == FM10K_XCAST_MODE_PROMISC); /* Add filter for VLAN 0 */ hw->mac.ops.update_vlan(hw, 0, 0, true); /* update table with current entries */ for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0; vid < VLAN_N_VID; vid = fm10k_find_next_vlan(interface, vid)) { hw->mac.ops.update_vlan(hw, vid, 0, true); hw->mac.ops.update_uc_addr(hw, glort, hw->mac.addr, vid, true, 0); } /* syncronize all of the addresses */ if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync); if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync); } /* update xcast mode */ hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode); fm10k_mbx_unlock(interface); /* record updated xcast mode state */ interface->xcast_mode = xcast_mode; /* Restore tunnel configuration */ fm10k_restore_vxlan_port(interface); }