Commit 735c9ee9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'wangxun-netdev-features-support'

Mengyuan Lou says:

====================
Wangxun netdev features support

Implement tx_csum and rx_csum to support hardware checksum offload.
Implement ndo_vlan_rx_add_vid and ndo_vlan_rx_kill_vid.
Implement ndo_set_features.
Enable macros in netdev features which wangxun can support.
====================

Link: https://lore.kernel.org/r/20230530022632.17938-1-mengyuanlou@net-swift.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6f4b9814 7df4af51
Loading
Loading
Loading
Loading
+271 −1
Original line number Diff line number Diff line
@@ -1182,12 +1182,28 @@ static void wx_enable_sec_rx_path(struct wx *wx)
	WX_WRITE_FLUSH(wx);
}

static void wx_vlan_strip_control(struct wx *wx, bool enable)
{
	int i, j;

	for (i = 0; i < wx->num_rx_queues; i++) {
		struct wx_ring *ring = wx->rx_ring[i];

		j = ring->reg_idx;
		wr32m(wx, WX_PX_RR_CFG(j), WX_PX_RR_CFG_VLAN,
		      enable ? WX_PX_RR_CFG_VLAN : 0);
	}
}

void wx_set_rx_mode(struct net_device *netdev)
{
	struct wx *wx = netdev_priv(netdev);
	netdev_features_t features;
	u32 fctrl, vmolr, vlnctrl;
	int count;

	features = netdev->features;

	/* Check for Promiscuous and All Multicast modes */
	fctrl = rd32(wx, WX_PSR_CTL);
	fctrl &= ~(WX_PSR_CTL_UPE | WX_PSR_CTL_MPE);
@@ -1254,6 +1270,13 @@ void wx_set_rx_mode(struct net_device *netdev)
	wr32(wx, WX_PSR_VLAN_CTL, vlnctrl);
	wr32(wx, WX_PSR_CTL, fctrl);
	wr32(wx, WX_PSR_VM_L2CTL(0), vmolr);

	if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
	    (features & NETIF_F_HW_VLAN_STAG_RX))
		wx_vlan_strip_control(wx, true);
	else
		wx_vlan_strip_control(wx, false);

}
EXPORT_SYMBOL(wx_set_rx_mode);

@@ -1462,6 +1485,16 @@ static void wx_configure_tx(struct wx *wx)
	      WX_MAC_TX_CFG_TE, WX_MAC_TX_CFG_TE);
}

static void wx_restore_vlan(struct wx *wx)
{
	u16 vid = 1;

	wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), 0);

	for_each_set_bit_from(vid, wx->active_vlans, VLAN_N_VID)
		wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), vid);
}

/**
 * wx_configure_rx - Configure Receive Unit after Reset
 * @wx: pointer to private structure
@@ -1527,7 +1560,7 @@ void wx_configure(struct wx *wx)
	wx_configure_port(wx);

	wx_set_rx_mode(wx->netdev);

	wx_restore_vlan(wx);
	wx_enable_sec_rx_path(wx);

	wx_configure_tx(wx);
@@ -1727,4 +1760,241 @@ int wx_sw_init(struct wx *wx)
}
EXPORT_SYMBOL(wx_sw_init);

/**
 *  wx_find_vlvf_slot - find the vlanid or the first empty slot
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *
 *  return the VLVF index where this VLAN id should be placed
 *
 **/
static int wx_find_vlvf_slot(struct wx *wx, u32 vlan)
{
	u32 bits = 0, first_empty_slot = 0;
	int regindex;

	/* short cut the special case */
	if (vlan == 0)
		return 0;

	/* Search for the vlan id in the VLVF entries. Save off the first empty
	 * slot found along the way
	 */
	for (regindex = 1; regindex < WX_PSR_VLAN_SWC_ENTRIES; regindex++) {
		wr32(wx, WX_PSR_VLAN_SWC_IDX, regindex);
		bits = rd32(wx, WX_PSR_VLAN_SWC);
		if (!bits && !(first_empty_slot))
			first_empty_slot = regindex;
		else if ((bits & 0x0FFF) == vlan)
			break;
	}

	if (regindex >= WX_PSR_VLAN_SWC_ENTRIES) {
		if (first_empty_slot)
			regindex = first_empty_slot;
		else
			regindex = -ENOMEM;
	}

	return regindex;
}

/**
 *  wx_set_vlvf - Set VLAN Pool Filter
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
 *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
 *  @vfta_changed: pointer to boolean flag which indicates whether VFTA
 *                 should be changed
 *
 *  Turn on/off specified bit in VLVF table.
 **/
static int wx_set_vlvf(struct wx *wx, u32 vlan, u32 vind, bool vlan_on,
		       bool *vfta_changed)
{
	int vlvf_index;
	u32 vt, bits;

	/* If VT Mode is set
	 *   Either vlan_on
	 *     make sure the vlan is in VLVF
	 *     set the vind bit in the matching VLVFB
	 *   Or !vlan_on
	 *     clear the pool bit and possibly the vind
	 */
	vt = rd32(wx, WX_CFG_PORT_CTL);
	if (!(vt & WX_CFG_PORT_CTL_NUM_VT_MASK))
		return 0;

	vlvf_index = wx_find_vlvf_slot(wx, vlan);
	if (vlvf_index < 0)
		return vlvf_index;

	wr32(wx, WX_PSR_VLAN_SWC_IDX, vlvf_index);
	if (vlan_on) {
		/* set the pool bit */
		if (vind < 32) {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L);
			bits |= (1 << vind);
			wr32(wx, WX_PSR_VLAN_SWC_VM_L, bits);
		} else {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H);
			bits |= (1 << (vind - 32));
			wr32(wx, WX_PSR_VLAN_SWC_VM_H, bits);
		}
	} else {
		/* clear the pool bit */
		if (vind < 32) {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L);
			bits &= ~(1 << vind);
			wr32(wx, WX_PSR_VLAN_SWC_VM_L, bits);
			bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_H);
		} else {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H);
			bits &= ~(1 << (vind - 32));
			wr32(wx, WX_PSR_VLAN_SWC_VM_H, bits);
			bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_L);
		}
	}

	if (bits) {
		wr32(wx, WX_PSR_VLAN_SWC, (WX_PSR_VLAN_SWC_VIEN | vlan));
		if (!vlan_on && vfta_changed)
			*vfta_changed = false;
	} else {
		wr32(wx, WX_PSR_VLAN_SWC, 0);
	}

	return 0;
}

/**
 *  wx_set_vfta - Set VLAN filter table
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
 *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
 *
 *  Turn on/off specified VLAN in the VLAN filter table.
 **/
static int wx_set_vfta(struct wx *wx, u32 vlan, u32 vind, bool vlan_on)
{
	u32 bitindex, vfta, targetbit;
	bool vfta_changed = false;
	int regindex, ret;

	/* this is a 2 part operation - first the VFTA, then the
	 * VLVF and VLVFB if VT Mode is set
	 * We don't write the VFTA until we know the VLVF part succeeded.
	 */

	/* Part 1
	 * The VFTA is a bitstring made up of 128 32-bit registers
	 * that enable the particular VLAN id, much like the MTA:
	 *    bits[11-5]: which register
	 *    bits[4-0]:  which bit in the register
	 */
	regindex = (vlan >> 5) & 0x7F;
	bitindex = vlan & 0x1F;
	targetbit = (1 << bitindex);
	/* errata 5 */
	vfta = wx->mac.vft_shadow[regindex];
	if (vlan_on) {
		if (!(vfta & targetbit)) {
			vfta |= targetbit;
			vfta_changed = true;
		}
	} else {
		if ((vfta & targetbit)) {
			vfta &= ~targetbit;
			vfta_changed = true;
		}
	}
	/* Part 2
	 * Call wx_set_vlvf to set VLVFB and VLVF
	 */
	ret = wx_set_vlvf(wx, vlan, vind, vlan_on, &vfta_changed);
	if (ret != 0)
		return ret;

	if (vfta_changed)
		wr32(wx, WX_PSR_VLAN_TBL(regindex), vfta);
	wx->mac.vft_shadow[regindex] = vfta;

	return 0;
}

/**
 *  wx_clear_vfta - Clear VLAN filter table
 *  @wx: pointer to hardware structure
 *
 *  Clears the VLAN filer table, and the VMDq index associated with the filter
 **/
static void wx_clear_vfta(struct wx *wx)
{
	u32 offset;

	for (offset = 0; offset < wx->mac.vft_size; offset++) {
		wr32(wx, WX_PSR_VLAN_TBL(offset), 0);
		wx->mac.vft_shadow[offset] = 0;
	}

	for (offset = 0; offset < WX_PSR_VLAN_SWC_ENTRIES; offset++) {
		wr32(wx, WX_PSR_VLAN_SWC_IDX, offset);
		wr32(wx, WX_PSR_VLAN_SWC, 0);
		wr32(wx, WX_PSR_VLAN_SWC_VM_L, 0);
		wr32(wx, WX_PSR_VLAN_SWC_VM_H, 0);
	}
}

int wx_vlan_rx_add_vid(struct net_device *netdev,
		       __be16 proto, u16 vid)
{
	struct wx *wx = netdev_priv(netdev);

	/* add VID to filter table */
	wx_set_vfta(wx, vid, VMDQ_P(0), true);
	set_bit(vid, wx->active_vlans);

	return 0;
}
EXPORT_SYMBOL(wx_vlan_rx_add_vid);

int wx_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
	struct wx *wx = netdev_priv(netdev);

	/* remove VID from filter table */
	if (vid)
		wx_set_vfta(wx, vid, VMDQ_P(0), false);
	clear_bit(vid, wx->active_vlans);

	return 0;
}
EXPORT_SYMBOL(wx_vlan_rx_kill_vid);

/**
 *  wx_start_hw - Prepare hardware for Tx/Rx
 *  @wx: pointer to hardware structure
 *
 *  Starts the hardware using the generic start_hw function
 *  and the generation start_hw function.
 *  Then performs revision-specific operations, if any.
 **/
void wx_start_hw(struct wx *wx)
{
	int i;

	/* Clear the VLAN filter table */
	wx_clear_vfta(wx);
	WX_WRITE_FLUSH(wx);
	/* Clear the rate limiters */
	for (i = 0; i < wx->mac.max_tx_queues; i++) {
		wr32(wx, WX_TDM_RP_IDX, i);
		wr32(wx, WX_TDM_RP_RATE, 0);
	}
}
EXPORT_SYMBOL(wx_start_hw);

MODULE_LICENSE("GPL");
+3 −0
Original line number Diff line number Diff line
@@ -26,10 +26,13 @@ void wx_set_rx_mode(struct net_device *netdev);
int wx_change_mtu(struct net_device *netdev, int new_mtu);
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring);
void wx_configure(struct wx *wx);
void wx_start_hw(struct wx *wx);
int wx_disable_pcie_master(struct wx *wx);
int wx_stop_adapter(struct wx *wx);
void wx_reset_misc(struct wx *wx);
int wx_get_pcie_msix_counts(struct wx *wx, u16 *msix_count, u16 max_msix_count);
int wx_sw_init(struct wx *wx);
int wx_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid);
int wx_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid);

#endif /* _WX_HW_H_ */
+727 −7

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -28,5 +28,6 @@ void wx_free_resources(struct wx *wx);
int wx_setup_resources(struct wx *wx);
void wx_get_stats64(struct net_device *netdev,
		    struct rtnl_link_stats64 *stats);
int wx_set_features(struct net_device *netdev, netdev_features_t features);

#endif /* _NGBE_LIB_H_ */
+209 −5
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@

#include <linux/bitfield.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <net/ip.h>

#define WX_NCSI_SUP                             0x8000
#define WX_NCSI_MASK                            0x8000
@@ -64,6 +66,8 @@
#define WX_CFG_PORT_CTL_QINQ         BIT(2)
#define WX_CFG_PORT_CTL_D_VLAN       BIT(0) /* double vlan*/
#define WX_CFG_TAG_TPID(_i)          (0x14430 + ((_i) * 4))
#define WX_CFG_PORT_CTL_NUM_VT_MASK  GENMASK(13, 12) /* number of TVs */


/* GPIO Registers */
#define WX_GPIO_DR                   0x14800
@@ -87,6 +91,8 @@
/* TDM CTL BIT */
#define WX_TDM_CTL_TE                BIT(0) /* Transmit Enable */
#define WX_TDM_PB_THRE(_i)           (0x18020 + ((_i) * 4))
#define WX_TDM_RP_IDX                0x1820C
#define WX_TDM_RP_RATE               0x18404

/***************************** RDB registers *********************************/
/* receive packet buffer */
@@ -105,6 +111,8 @@
#define WX_RDB_PL_CFG_L2HDR          BIT(3)
#define WX_RDB_PL_CFG_TUN_TUNHDR     BIT(4)
#define WX_RDB_PL_CFG_TUN_OUTL2HDR   BIT(5)
#define WX_RDB_RA_CTL                0x194F4
#define WX_RDB_RA_CTL_RSS_EN         BIT(2) /* RSS Enable */

/******************************* PSR Registers *******************************/
/* psr control */
@@ -150,6 +158,9 @@
#define WX_PSR_LAN_FLEX_DW_H(_i)     (0x15C04 + ((_i) * 16))
#define WX_PSR_LAN_FLEX_MSK(_i)      (0x15C08 + ((_i) * 16))

/* vlan tbl */
#define WX_PSR_VLAN_TBL(_i)          (0x16000 + ((_i) * 4))

/* mac switcher */
#define WX_PSR_MAC_SWC_AD_L          0x16200
#define WX_PSR_MAC_SWC_AD_H          0x16204
@@ -161,6 +172,15 @@
#define WX_PSR_MAC_SWC_IDX           0x16210
#define WX_CLEAR_VMDQ_ALL            0xFFFFFFFFU

/* vlan switch */
#define WX_PSR_VLAN_SWC              0x16220
#define WX_PSR_VLAN_SWC_VM_L         0x16224
#define WX_PSR_VLAN_SWC_VM_H         0x16228
#define WX_PSR_VLAN_SWC_IDX          0x16230         /* 64 vlan entries */
/* VLAN pool filtering masks */
#define WX_PSR_VLAN_SWC_VIEN         BIT(31)  /* filter is valid */
#define WX_PSR_VLAN_SWC_ENTRIES      64

/********************************* RSEC **************************************/
/* general rsec */
#define WX_RSC_CTL                   0x17000
@@ -255,6 +275,7 @@
#define WX_PX_RR_RP(_i)              (0x0100C + ((_i) * 0x40))
#define WX_PX_RR_CFG(_i)             (0x01010 + ((_i) * 0x40))
/* PX_RR_CFG bit definitions */
#define WX_PX_RR_CFG_VLAN            BIT(31)
#define WX_PX_RR_CFG_SPLIT_MODE      BIT(26)
#define WX_PX_RR_CFG_RR_THER_SHIFT   16
#define WX_PX_RR_CFG_RR_HDR_SZ       GENMASK(15, 12)
@@ -296,6 +317,7 @@
#define WX_MAX_TXD                   8192

#define WX_MAX_JUMBO_FRAME_SIZE      9432 /* max payload 9414 */
#define VMDQ_P(p)                    p

/* Supported Rx Buffer Sizes */
#define WX_RXBUFFER_256      256    /* Used for skb receive header */
@@ -315,17 +337,64 @@
#define TXD_USE_COUNT(S)     DIV_ROUND_UP((S), WX_MAX_DATA_PER_TXD)
#define DESC_NEEDED          (MAX_SKB_FRAGS + 4)

/* Ether Types */
#define WX_ETH_P_CNM                 0x22E7

#define WX_CFG_PORT_ST               0x14404

/******************* Receive Descriptor bit definitions **********************/
#define WX_RXD_STAT_DD               BIT(0) /* Done */
#define WX_RXD_STAT_EOP              BIT(1) /* End of Packet */
#define WX_RXD_STAT_VP               BIT(5) /* IEEE VLAN Pkt */
#define WX_RXD_STAT_L4CS             BIT(7) /* L4 xsum calculated */
#define WX_RXD_STAT_IPCS             BIT(8) /* IP xsum calculated */
#define WX_RXD_STAT_OUTERIPCS        BIT(10) /* Cloud IP xsum calculated*/

#define WX_RXD_ERR_OUTERIPER         BIT(26) /* CRC IP Header error */
#define WX_RXD_ERR_RXE               BIT(29) /* Any MAC Error */

#define WX_RXD_ERR_TCPE              BIT(30) /* TCP/UDP Checksum Error */
#define WX_RXD_ERR_IPE               BIT(31) /* IP Checksum Error */

/* RSS Hash results */
#define WX_RXD_RSSTYPE_MASK          GENMASK(3, 0)
#define WX_RXD_RSSTYPE_IPV4_TCP      0x00000001U
#define WX_RXD_RSSTYPE_IPV6_TCP      0x00000003U
#define WX_RXD_RSSTYPE_IPV4_SCTP     0x00000004U
#define WX_RXD_RSSTYPE_IPV6_SCTP     0x00000006U
#define WX_RXD_RSSTYPE_IPV4_UDP      0x00000007U
#define WX_RXD_RSSTYPE_IPV6_UDP      0x00000008U

#define WX_RSS_L4_TYPES_MASK \
	((1ul << WX_RXD_RSSTYPE_IPV4_TCP) | \
	 (1ul << WX_RXD_RSSTYPE_IPV4_UDP) | \
	 (1ul << WX_RXD_RSSTYPE_IPV4_SCTP) | \
	 (1ul << WX_RXD_RSSTYPE_IPV6_TCP) | \
	 (1ul << WX_RXD_RSSTYPE_IPV6_UDP) | \
	 (1ul << WX_RXD_RSSTYPE_IPV6_SCTP))
/* TUN */
#define WX_PTYPE_TUN_IPV4            0x80
#define WX_PTYPE_TUN_IPV6            0xC0

/* PKT for TUN */
#define WX_PTYPE_PKT_IPIP            0x00 /* IP+IP */
#define WX_PTYPE_PKT_IG              0x10 /* IP+GRE */
#define WX_PTYPE_PKT_IGM             0x20 /* IP+GRE+MAC */
#define WX_PTYPE_PKT_IGMV            0x30 /* IP+GRE+MAC+VLAN */
/* PKT for !TUN */
#define WX_PTYPE_PKT_MAC             0x10
#define WX_PTYPE_PKT_IP              0x20

/* TYP for PKT=mac */
#define WX_PTYPE_TYP_MAC             0x01
/* TYP for PKT=ip */
#define WX_PTYPE_PKT_IPV6            0x08
#define WX_PTYPE_TYP_IPFRAG          0x01
#define WX_PTYPE_TYP_IP              0x02
#define WX_PTYPE_TYP_UDP             0x03
#define WX_PTYPE_TYP_TCP             0x04
#define WX_PTYPE_TYP_SCTP            0x05

#define WX_RXD_PKTTYPE(_rxd) \
	((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 9) & 0xFF)
#define WX_RXD_IPV6EX(_rxd) \
	((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 6) & 0x1)
/*********************** Transmit Descriptor Config Masks ****************/
#define WX_TXD_STAT_DD               BIT(0)  /* Descriptor Done */
#define WX_TXD_DTYP_DATA             0       /* Adv Data Descriptor */
@@ -334,6 +403,113 @@
#define WX_TXD_IFCS                  BIT(25) /* Insert FCS */
#define WX_TXD_RS                    BIT(27) /* Report Status */

/*********************** Adv Transmit Descriptor Config Masks ****************/
#define WX_TXD_MAC_TSTAMP            BIT(19) /* IEEE1588 time stamp */
#define WX_TXD_DTYP_CTXT             BIT(20) /* Adv Context Desc */
#define WX_TXD_LINKSEC               BIT(26) /* enable linksec */
#define WX_TXD_VLE                   BIT(30) /* VLAN pkt enable */
#define WX_TXD_TSE                   BIT(31) /* TCP Seg enable */
#define WX_TXD_CC                    BIT(7) /* Check Context */
#define WX_TXD_IPSEC                 BIT(8) /* enable ipsec esp */
#define WX_TXD_L4CS                  BIT(9)
#define WX_TXD_IIPCS                 BIT(10)
#define WX_TXD_EIPCS                 BIT(11)
#define WX_TXD_PAYLEN_SHIFT          13 /* Adv desc PAYLEN shift */
#define WX_TXD_MACLEN_SHIFT          9  /* Adv ctxt desc mac len shift */
#define WX_TXD_TAG_TPID_SEL_SHIFT    11

#define WX_TXD_L4LEN_SHIFT           8  /* Adv ctxt L4LEN shift */
#define WX_TXD_MSS_SHIFT             16  /* Adv ctxt MSS shift */

#define WX_TXD_OUTER_IPLEN_SHIFT     12 /* Adv ctxt OUTERIPLEN shift */
#define WX_TXD_TUNNEL_LEN_SHIFT      21 /* Adv ctxt TUNNELLEN shift */
#define WX_TXD_TUNNEL_TYPE_SHIFT     11 /* Adv Tx Desc Tunnel Type shift */
#define WX_TXD_TUNNEL_UDP            FIELD_PREP(BIT(WX_TXD_TUNNEL_TYPE_SHIFT), 0)
#define WX_TXD_TUNNEL_GRE            FIELD_PREP(BIT(WX_TXD_TUNNEL_TYPE_SHIFT), 1)

enum wx_tx_flags {
	/* cmd_type flags */
	WX_TX_FLAGS_HW_VLAN	= 0x01,
	WX_TX_FLAGS_TSO		= 0x02,
	WX_TX_FLAGS_TSTAMP	= 0x04,

	/* olinfo flags */
	WX_TX_FLAGS_CC		= 0x08,
	WX_TX_FLAGS_IPV4	= 0x10,
	WX_TX_FLAGS_CSUM	= 0x20,
	WX_TX_FLAGS_OUTER_IPV4	= 0x100,
	WX_TX_FLAGS_LINKSEC	= 0x200,
	WX_TX_FLAGS_IPSEC	= 0x400,
};

/* VLAN info */
#define WX_TX_FLAGS_VLAN_MASK			GENMASK(31, 16)
#define WX_TX_FLAGS_VLAN_SHIFT			16

/* wx_dec_ptype.mac: outer mac */
enum wx_dec_ptype_mac {
	WX_DEC_PTYPE_MAC_IP	= 0,
	WX_DEC_PTYPE_MAC_L2	= 2,
	WX_DEC_PTYPE_MAC_FCOE	= 3,
};

/* wx_dec_ptype.[e]ip: outer&encaped ip */
#define WX_DEC_PTYPE_IP_FRAG	0x4
enum wx_dec_ptype_ip {
	WX_DEC_PTYPE_IP_NONE = 0,
	WX_DEC_PTYPE_IP_IPV4 = 1,
	WX_DEC_PTYPE_IP_IPV6 = 2,
	WX_DEC_PTYPE_IP_FGV4 = WX_DEC_PTYPE_IP_FRAG | WX_DEC_PTYPE_IP_IPV4,
	WX_DEC_PTYPE_IP_FGV6 = WX_DEC_PTYPE_IP_FRAG | WX_DEC_PTYPE_IP_IPV6,
};

/* wx_dec_ptype.etype: encaped type */
enum wx_dec_ptype_etype {
	WX_DEC_PTYPE_ETYPE_NONE	= 0,
	WX_DEC_PTYPE_ETYPE_IPIP	= 1,	/* IP+IP */
	WX_DEC_PTYPE_ETYPE_IG	= 2,	/* IP+GRE */
	WX_DEC_PTYPE_ETYPE_IGM	= 3,	/* IP+GRE+MAC */
	WX_DEC_PTYPE_ETYPE_IGMV	= 4,	/* IP+GRE+MAC+VLAN */
};

/* wx_dec_ptype.proto: payload proto */
enum wx_dec_ptype_prot {
	WX_DEC_PTYPE_PROT_NONE	= 0,
	WX_DEC_PTYPE_PROT_UDP	= 1,
	WX_DEC_PTYPE_PROT_TCP	= 2,
	WX_DEC_PTYPE_PROT_SCTP	= 3,
	WX_DEC_PTYPE_PROT_ICMP	= 4,
	WX_DEC_PTYPE_PROT_TS	= 5,	/* time sync */
};

/* wx_dec_ptype.layer: payload layer */
enum wx_dec_ptype_layer {
	WX_DEC_PTYPE_LAYER_NONE = 0,
	WX_DEC_PTYPE_LAYER_PAY2 = 1,
	WX_DEC_PTYPE_LAYER_PAY3 = 2,
	WX_DEC_PTYPE_LAYER_PAY4 = 3,
};

struct wx_dec_ptype {
	u32 known:1;
	u32 mac:2;	/* outer mac */
	u32 ip:3;	/* outer ip*/
	u32 etype:3;	/* encaped type */
	u32 eip:3;	/* encaped ip */
	u32 prot:4;	/* payload proto */
	u32 layer:3;	/* payload layer */
};

/* macro to make the table lines short */
#define WX_PTT(mac, ip, etype, eip, proto, layer)\
	      {1, \
	       WX_DEC_PTYPE_MAC_##mac,		/* mac */\
	       WX_DEC_PTYPE_IP_##ip,		/* ip */ \
	       WX_DEC_PTYPE_ETYPE_##etype,	/* etype */\
	       WX_DEC_PTYPE_IP_##eip,		/* eip */\
	       WX_DEC_PTYPE_PROT_##proto,	/* proto */\
	       WX_DEC_PTYPE_LAYER_##layer	/* layer */}

/* Host Interface Command Structures */
struct wx_hic_hdr {
	u8 cmd;
@@ -412,6 +588,8 @@ struct wx_mac_info {
	u32 mta_shadow[128];
	s32 mc_filter_type;
	u32 mcft_size;
	u32 vft_shadow[128];
	u32 vft_size;
	u32 num_rar_entries;
	u32 rx_pb_size;
	u32 tx_pb_size;
@@ -508,10 +686,25 @@ union wx_rx_desc {
	} wb;  /* writeback */
};

struct wx_tx_context_desc {
	__le32 vlan_macip_lens;
	__le32 seqnum_seed;
	__le32 type_tucmd_mlhl;
	__le32 mss_l4len_idx;
};

/* if _flag is in _input, return _result */
#define WX_SET_FLAG(_input, _flag, _result) \
	(((_flag) <= (_result)) ? \
	 ((u32)((_input) & (_flag)) * ((_result) / (_flag))) : \
	 ((u32)((_input) & (_flag)) / ((_flag) / (_result))))

#define WX_RX_DESC(R, i)     \
	(&(((union wx_rx_desc *)((R)->desc))[i]))
#define WX_TX_DESC(R, i)     \
	(&(((union wx_tx_desc *)((R)->desc))[i]))
#define WX_TX_CTXTDESC(R, i) \
	(&(((struct wx_tx_context_desc *)((R)->desc))[i]))

/* wrapper around a pointer to a socket buffer,
 * so a DMA handle can be stored along with the buffer
@@ -523,6 +716,8 @@ struct wx_tx_buffer {
	unsigned short gso_segs;
	DEFINE_DMA_UNMAP_ADDR(dma);
	DEFINE_DMA_UNMAP_LEN(len);
	__be16 protocol;
	u32 tx_flags;
};

struct wx_rx_buffer {
@@ -539,6 +734,11 @@ struct wx_queue_stats {
	u64 bytes;
};

struct wx_rx_queue_stats {
	u64 csum_good_cnt;
	u64 csum_err;
};

/* iterator for handling rings in ring container */
#define wx_for_each_ring(posm, headm) \
	for (posm = (headm).ring; posm; posm = posm->next)
@@ -550,7 +750,6 @@ struct wx_ring_container {
	u8 count;                       /* total number of rings in vector */
	u8 itr;                         /* current ITR setting for ring */
};

struct wx_ring {
	struct wx_ring *next;           /* pointer to next ring in q_vector */
	struct wx_q_vector *q_vector;   /* backpointer to host q_vector */
@@ -580,6 +779,9 @@ struct wx_ring {

	struct wx_queue_stats stats;
	struct u64_stats_sync syncp;
	union {
		struct wx_rx_queue_stats rx_stats;
	};
} ____cacheline_internodealigned_in_smp;

struct wx_q_vector {
@@ -610,6 +812,8 @@ enum wx_isb_idx {
};

struct wx {
	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];

	u8 __iomem *hw_addr;
	struct pci_dev *pdev;
	struct net_device *netdev;
Loading