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

Commit 7a8fc77b authored by Francois Romieu's avatar Francois Romieu
Browse files

r8169: convert to new VLAN model.

parent 54405cde
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -2236,15 +2236,6 @@ config R8169
	  To compile this driver as a module, choose M here: the module
	  will be called r8169.  This is recommended.

config R8169_VLAN
	bool "VLAN support"
	depends on R8169 && VLAN_8021Q
	---help---
	  Say Y here for the r8169 driver to support the functions required
	  by the kernel 802.1Q code.

	  If in doubt, say Y.

config SB1250_MAC
	tristate "SB1250 Gigabit Ethernet support"
	depends on SIBYTE_SB1xxx_SOC
+49 −61
Original line number Diff line number Diff line
@@ -537,9 +537,6 @@ struct rtl8169_private {
	u16 napi_event;
	u16 intr_mask;
	int phy_1000_ctrl_reg;
#ifdef CONFIG_R8169_VLAN
	struct vlan_group *vlgrp;
#endif

	struct mdio_ops {
		void (*write)(void __iomem *, int, int);
@@ -1276,8 +1273,6 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
	return 0;
}

#ifdef CONFIG_R8169_VLAN

static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
				      struct sk_buff *skb)
{
@@ -1285,64 +1280,37 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
}

static void rtl8169_vlan_rx_register(struct net_device *dev,
				     struct vlan_group *grp)
#define NETIF_F_HW_VLAN_TX_RX	(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)

static void rtl8169_vlan_mode(struct net_device *dev)
{
	struct rtl8169_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->mmio_addr;
	unsigned long flags;

	spin_lock_irqsave(&tp->lock, flags);
	tp->vlgrp = grp;
	/*
	 * Do not disable RxVlan on 8110SCd.
	 */
	if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05))
	if (dev->features & NETIF_F_HW_VLAN_RX)
		tp->cp_cmd |= RxVlan;
	else
		tp->cp_cmd &= ~RxVlan;
	RTL_W16(CPlusCmd, tp->cp_cmd);
	/* PCI commit */
	RTL_R16(CPlusCmd);
	spin_unlock_irqrestore(&tp->lock, flags);

	dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX;
}

static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
			       struct sk_buff *skb, int polling)
static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
{
	u32 opts2 = le32_to_cpu(desc->opts2);
	struct vlan_group *vlgrp = tp->vlgrp;
	int ret;

	if (vlgrp && (opts2 & RxVlanTag)) {
		u16 vtag = swab16(opts2 & 0xffff);
	if (opts2 & RxVlanTag)
		__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));

		if (likely(polling))
			vlan_gro_receive(&tp->napi, vlgrp, vtag, skb);
		else
			__vlan_hwaccel_rx(skb, vlgrp, vtag, polling);
		ret = 0;
	} else
		ret = -1;
	desc->opts2 = 0;
	return ret;
}

#else /* !CONFIG_R8169_VLAN */

static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
				      struct sk_buff *skb)
{
	return 0;
}

static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
			       struct sk_buff *skb, int polling)
{
	return -1;
}

#endif

static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1513,6 +1481,28 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
	}
}

static int rtl8169_set_flags(struct net_device *dev, u32 data)
{
	struct rtl8169_private *tp = netdev_priv(dev);
	unsigned long old_feat = dev->features;
	int rc;

	if ((tp->mac_version == RTL_GIGA_MAC_VER_05) &&
	    !(data & ETH_FLAG_RXVLAN)) {
		netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n");
		return -EINVAL;
	}

	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN);
	if (rc)
		return rc;

	if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX)
		rtl8169_vlan_mode(dev);

	return 0;
}

static const struct ethtool_ops rtl8169_ethtool_ops = {
	.get_drvinfo		= rtl8169_get_drvinfo,
	.get_regs_len		= rtl8169_get_regs_len,
@@ -1532,6 +1522,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
	.get_strings		= rtl8169_get_strings,
	.get_sset_count		= rtl8169_get_sset_count,
	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
	.set_flags		= rtl8169_set_flags,
	.get_flags		= ethtool_op_get_flags,
};

static void rtl8169_get_mac_version(struct rtl8169_private *tp,
@@ -2849,9 +2841,6 @@ static const struct net_device_ops rtl8169_netdev_ops = {
	.ndo_set_mac_address	= rtl_set_mac_address,
	.ndo_do_ioctl		= rtl8169_ioctl,
	.ndo_set_multicast_list	= rtl_set_rx_mode,
#ifdef CONFIG_R8169_VLAN
	.ndo_vlan_rx_register	= rtl8169_vlan_rx_register,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= rtl8169_netpoll,
#endif
@@ -3145,6 +3134,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	/* Identify chip attached to board */
	rtl8169_get_mac_version(tp, ioaddr);

	/*
	 * Pretend we are using VLANs; This bypasses a nasty bug where
	 * Interrupts stop flowing on high load on 8110SCd controllers.
	 */
	if (tp->mac_version == RTL_GIGA_MAC_VER_05)
		tp->cp_cmd |= RxVlan;

	rtl_init_mdio_ops(tp);
	rtl_init_pll_power_ops(tp);

@@ -3213,10 +3209,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);

#ifdef CONFIG_R8169_VLAN
	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
	dev->features |= NETIF_F_GRO;
	dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO;

	tp->intr_mask = 0xffff;
	tp->hw_start = cfg->hw_start;
@@ -3334,12 +3327,7 @@ static int rtl8169_open(struct net_device *dev)

	rtl8169_init_phy(dev, tp);

	/*
	 * Pretend we are using VLANs; This bypasses a nasty bug where
	 * Interrupts stop flowing on high load on 8110SCd controllers.
	 */
	if (tp->mac_version == RTL_GIGA_MAC_VER_05)
		RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan);
	rtl8169_vlan_mode(dev);

	rtl_pll_power_up(tp);

@@ -4689,12 +4677,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
			skb_put(skb, pkt_size);
			skb->protocol = eth_type_trans(skb, dev);

			if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
			rtl8169_rx_vlan_tag(desc, skb);

			if (likely(polling))
				napi_gro_receive(&tp->napi, skb);
			else
				netif_rx(skb);
			}

			dev->stats.rx_bytes += pkt_size;
			dev->stats.rx_packets++;