Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
static int __fm10k_mc_sync(struct net_device *dev,
			   const unsigned char *addr, bool sync)
{
	struct fm10k_intfc *interface = netdev_priv(dev);
	struct fm10k_hw *hw = &interface->hw;
	u16 vid, glort = interface->glort;

	/* 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_mc_addr(hw, glort, addr, vid, sync);
	}

	return 0;
}
Exemplo n.º 3
0
static int __fm10k_mc_sync(struct net_device *dev,
			   const unsigned char *addr, bool sync)
{
	struct fm10k_intfc *interface = netdev_priv(dev);
	struct fm10k_hw *hw = &interface->hw;
	u16 vid, glort = interface->glort;
	s32 err;

	if (!is_multicast_ether_addr(addr))
		return -EADDRNOTAVAIL;

	/* 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)) {
		err = hw->mac.ops.update_mc_addr(hw, glort, addr, vid, sync);
		if (err)
			return err;
	}

	return 0;
}
Exemplo n.º 4
0
static void fm10k_clear_unused_vlans(struct fm10k_intfc *interface)
{
	struct fm10k_hw *hw = &interface->hw;
	u32 vid, prev_vid;

	/* loop through and find any gaps in the table */
	for (vid = 0, prev_vid = 0;
	     prev_vid < VLAN_N_VID;
	     prev_vid = vid + 1, vid = fm10k_find_next_vlan(interface, vid)) {
		if (prev_vid == vid)
			continue;

		/* send request to clear multiple bits at a time */
		prev_vid += (vid - prev_vid - 1) << FM10K_VLAN_LENGTH_SHIFT;
		hw->mac.ops.update_vlan(hw, prev_vid, 0, false);
	}
}
Exemplo n.º 5
0
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);
}