Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 447b816f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch '8021ad'



Patrick McHardy says:

====================
The following patches add support for 802.1ad (provider tagging) to the
VLAN driver. The patchset consists of the following parts:

- renaming of the NET_F_HW_VLAN feature flags to indicate that they only
  operate on CTAGs

- preparation for 802.1ad VLAN filtering offload by adding a proto argument
  to the rx_{add,kill}_vid net_device_ops callbacks

- preparation of the VLAN code to support multiple protocols by making the
  protocol used for tagging a property of the VLAN device and converting
  the device lookup functions accordingly

- second step of preparation of the VLAN code by making the packet tagging
  functions take a protocol argument

- introducation of 802.1ad support in the VLAN code, consisting mainly of
  checking for ETH_P_8021AD in a couple of places and testing the netdevice
  offload feature checks to take the protocol into account

- announcement of STAG offloading capabilities in a couple of drivers for
  virtual network devices

The patchset is based on net-next.git and has been tested with single and
double tagging with and without HW acceleration (for CTAGs).
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c2962897 28d2b136
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2948,7 +2948,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
					nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
							nesvnic->netdev->name, vlan_tag);

					__vlan_hwaccel_put_tag(rx_skb, vlan_tag);
					__vlan_hwaccel_put_tag(rx_skb, htons(ETH_P_8021Q), vlan_tag);
				}
				if (nes_use_lro)
					lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
+7 −7
Original line number Diff line number Diff line
@@ -1599,7 +1599,7 @@ static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev,

	/* Enable/Disable VLAN Stripping */
	u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
	if (features & NETIF_F_HW_VLAN_RX)
	if (features & NETIF_F_HW_VLAN_CTAG_RX)
		u32temp &= 0xfdffffff;
	else
		u32temp	|= 0x02000000;
@@ -1614,10 +1614,10 @@ static netdev_features_t nes_fix_features(struct net_device *netdev, netdev_feat
	 * Since there is no support for separate rx/tx vlan accel
	 * enable/disable make sure tx flag is always in same state as rx.
	 */
	if (features & NETIF_F_HW_VLAN_RX)
		features |= NETIF_F_HW_VLAN_TX;
	if (features & NETIF_F_HW_VLAN_CTAG_RX)
		features |= NETIF_F_HW_VLAN_CTAG_TX;
	else
		features &= ~NETIF_F_HW_VLAN_TX;
		features &= ~NETIF_F_HW_VLAN_CTAG_TX;

	return features;
}
@@ -1628,7 +1628,7 @@ static int nes_set_features(struct net_device *netdev, netdev_features_t feature
	struct nes_device *nesdev = nesvnic->nesdev;
	u32 changed = netdev->features ^ features;

	if (changed & NETIF_F_HW_VLAN_RX)
	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
		nes_vlan_mode(netdev, nesdev, features);

	return 0;
@@ -1706,11 +1706,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
	netdev->dev_addr[4] = (u8)(u64temp>>8);
	netdev->dev_addr[5] = (u8)u64temp;

	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX;
	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX;
	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
		netdev->hw_features |= NETIF_F_TSO;

	netdev->features = netdev->hw_features | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_TX;
	netdev->features = netdev->hw_features | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX;
	netdev->hw_features |= NETIF_F_LRO;

	nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
+2 −2
Original line number Diff line number Diff line
@@ -514,7 +514,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
		skb->dev = client_info->slave->dev;

		if (client_info->tag) {
			skb = vlan_put_tag(skb, client_info->vlan_id);
			skb = vlan_put_tag(skb, htons(ETH_P_8021Q), client_info->vlan_id);
			if (!skb) {
				pr_err("%s: Error: failed to insert VLAN tag\n",
				       client_info->slave->bond->dev->name);
@@ -1014,7 +1014,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
				continue;
			}

			skb = vlan_put_tag(skb, vlan->vlan_id);
			skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan->vlan_id);
			if (!skb) {
				pr_err("%s: Error: failed to insert VLAN tag\n",
				       bond->dev->name);
+18 −13
Original line number Diff line number Diff line
@@ -428,14 +428,15 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 * @bond_dev: bonding net device that got called
 * @vid: vlan id being added
 */
static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
				__be16 proto, u16 vid)
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct slave *slave, *stop_at;
	int i, res;

	bond_for_each_slave(bond, slave, i) {
		res = vlan_vid_add(slave->dev, vid);
		res = vlan_vid_add(slave->dev, proto, vid);
		if (res)
			goto unwind;
	}
@@ -453,7 +454,7 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
	/* unwind from head to the slave that failed */
	stop_at = slave;
	bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at)
		vlan_vid_del(slave->dev, vid);
		vlan_vid_del(slave->dev, proto, vid);

	return res;
}
@@ -463,14 +464,15 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
 * @bond_dev: bonding net device that got called
 * @vid: vlan id being removed
 */
static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
				 __be16 proto, u16 vid)
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct slave *slave;
	int i, res;

	bond_for_each_slave(bond, slave, i)
		vlan_vid_del(slave->dev, vid);
		vlan_vid_del(slave->dev, proto, vid);

	res = bond_del_vlan(bond, vid);
	if (res) {
@@ -488,7 +490,8 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
	int res;

	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
		res = vlan_vid_add(slave_dev, vlan->vlan_id);
		res = vlan_vid_add(slave_dev, htons(ETH_P_8021Q),
				   vlan->vlan_id);
		if (res)
			pr_warning("%s: Failed to add vlan id %d to device %s\n",
				   bond->dev->name, vlan->vlan_id,
@@ -504,7 +507,7 @@ static void bond_del_vlans_from_slave(struct bonding *bond,
	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
		if (!vlan->vlan_id)
			continue;
		vlan_vid_del(slave_dev, vlan->vlan_id);
		vlan_vid_del(slave_dev, htons(ETH_P_8021Q), vlan->vlan_id);
	}
}

@@ -779,7 +782,7 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)

	/* rejoin all groups on vlan devices */
	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
		vlan_dev = __vlan_find_dev_deep(bond_dev,
		vlan_dev = __vlan_find_dev_deep(bond_dev, htons(ETH_P_8021Q),
						vlan->vlan_id);
		if (vlan_dev)
			__bond_resend_igmp_join_requests(vlan_dev);
@@ -2509,7 +2512,8 @@ static int bond_has_this_ip(struct bonding *bond, __be32 ip)

	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
		rcu_read_lock();
		vlan_dev = __vlan_find_dev_deep(bond->dev, vlan->vlan_id);
		vlan_dev = __vlan_find_dev_deep(bond->dev, htons(ETH_P_8021Q),
						vlan->vlan_id);
		rcu_read_unlock();
		if (vlan_dev && ip == bond_confirm_addr(vlan_dev, 0, ip))
			return 1;
@@ -2538,7 +2542,7 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
		return;
	}
	if (vlan_id) {
		skb = vlan_put_tag(skb, vlan_id);
		skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_id);
		if (!skb) {
			pr_err("failed to insert VLAN tag\n");
			return;
@@ -2600,6 +2604,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
		list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
			rcu_read_lock();
			vlan_dev = __vlan_find_dev_deep(bond->dev,
							htons(ETH_P_8021Q),
							vlan->vlan_id);
			rcu_read_unlock();
			if (vlan_dev == rt->dst.dev) {
@@ -4322,9 +4327,9 @@ static void bond_setup(struct net_device *bond_dev)
	 */

	bond_dev->hw_features = BOND_VLAN_FEATURES |
				NETIF_F_HW_VLAN_TX |
				NETIF_F_HW_VLAN_RX |
				NETIF_F_HW_VLAN_FILTER;
				NETIF_F_HW_VLAN_CTAG_TX |
				NETIF_F_HW_VLAN_CTAG_RX |
				NETIF_F_HW_VLAN_CTAG_FILTER;

	bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
	bond_dev->features |= bond_dev->hw_features;
+3 −3
Original line number Diff line number Diff line
@@ -1690,7 +1690,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
			skb_checksum_none_assert(new_skb);

		if (rx->rxStatus & TYPHOON_RX_VLAN)
			__vlan_hwaccel_put_tag(new_skb,
			__vlan_hwaccel_put_tag(new_skb, htons(ETH_P_8021Q),
					       ntohl(rx->vlanTag) & 0xffff);
		netif_receive_skb(new_skb);

@@ -2445,9 +2445,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	 * settings -- so we only allow the user to toggle the TX processing.
	 */
	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
		NETIF_F_HW_VLAN_TX;
		NETIF_F_HW_VLAN_CTAG_TX;
	dev->features = dev->hw_features |
		NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM;
		NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM;

	if(register_netdev(dev) < 0) {
		err_msg = "unable to register netdev";
Loading