Skip to content

Commit b501d26

Browse files
Jiawen WuPaolo Abeni
authored andcommitted
net: txgbe: add FDIR ATR support
Add flow director ATR filter. ATR mode is enabled by default to filter TCP packets. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 7e8fcb8 commit b501d26

File tree

10 files changed

+548
-8
lines changed

10 files changed

+548
-8
lines changed

drivers/net/ethernet/wangxun/libwx/wx_hw.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,15 @@ static void wx_enable_rx(struct wx *wx)
11471147
static void wx_set_rxpba(struct wx *wx)
11481148
{
11491149
u32 rxpktsize, txpktsize, txpbthresh;
1150+
u32 pbsize = wx->mac.rx_pb_size;
11501151

1151-
rxpktsize = wx->mac.rx_pb_size << WX_RDB_PB_SZ_SHIFT;
1152+
if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
1153+
if (test_bit(WX_FLAG_FDIR_HASH, wx->flags) ||
1154+
test_bit(WX_FLAG_FDIR_PERFECT, wx->flags))
1155+
pbsize -= 64; /* Default 64KB */
1156+
}
1157+
1158+
rxpktsize = pbsize << WX_RDB_PB_SZ_SHIFT;
11521159
wr32(wx, WX_RDB_PB_SZ(0), rxpktsize);
11531160

11541161
/* Only support an equally distributed Tx packet buffer strategy. */
@@ -1261,7 +1268,7 @@ static void wx_configure_port(struct wx *wx)
12611268
* Stops the receive data path and waits for the HW to internally empty
12621269
* the Rx security block
12631270
**/
1264-
static int wx_disable_sec_rx_path(struct wx *wx)
1271+
int wx_disable_sec_rx_path(struct wx *wx)
12651272
{
12661273
u32 secrx;
12671274

@@ -1271,18 +1278,20 @@ static int wx_disable_sec_rx_path(struct wx *wx)
12711278
return read_poll_timeout(rd32, secrx, secrx & WX_RSC_ST_RSEC_RDY,
12721279
1000, 40000, false, wx, WX_RSC_ST);
12731280
}
1281+
EXPORT_SYMBOL(wx_disable_sec_rx_path);
12741282

12751283
/**
12761284
* wx_enable_sec_rx_path - Enables the receive data path
12771285
* @wx: pointer to private structure
12781286
*
12791287
* Enables the receive data path.
12801288
**/
1281-
static void wx_enable_sec_rx_path(struct wx *wx)
1289+
void wx_enable_sec_rx_path(struct wx *wx)
12821290
{
12831291
wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_RX_DIS, 0);
12841292
WX_WRITE_FLUSH(wx);
12851293
}
1294+
EXPORT_SYMBOL(wx_enable_sec_rx_path);
12861295

12871296
static void wx_vlan_strip_control(struct wx *wx, bool enable)
12881297
{
@@ -1499,6 +1508,13 @@ static void wx_configure_tx_ring(struct wx *wx,
14991508
txdctl |= ring->count / 128 << WX_PX_TR_CFG_TR_SIZE_SHIFT;
15001509
txdctl |= 0x20 << WX_PX_TR_CFG_WTHRESH_SHIFT;
15011510

1511+
ring->atr_count = 0;
1512+
if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags) &&
1513+
test_bit(WX_FLAG_FDIR_HASH, wx->flags))
1514+
ring->atr_sample_rate = wx->atr_sample_rate;
1515+
else
1516+
ring->atr_sample_rate = 0;
1517+
15021518
/* reinitialize tx_buffer_info */
15031519
memset(ring->tx_buffer_info, 0,
15041520
sizeof(struct wx_tx_buffer) * ring->count);
@@ -1732,7 +1748,9 @@ void wx_configure(struct wx *wx)
17321748

17331749
wx_set_rx_mode(wx->netdev);
17341750
wx_restore_vlan(wx);
1735-
wx_enable_sec_rx_path(wx);
1751+
1752+
if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
1753+
wx->configure_fdir(wx);
17361754

17371755
wx_configure_tx(wx);
17381756
wx_configure_rx(wx);
@@ -1959,6 +1977,7 @@ int wx_sw_init(struct wx *wx)
19591977
}
19601978

19611979
bitmap_zero(wx->state, WX_STATE_NBITS);
1980+
bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS);
19621981

19631982
return 0;
19641983
}

drivers/net/ethernet/wangxun/libwx/wx_hw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ void wx_mac_set_default_filter(struct wx *wx, u8 *addr);
2828
void wx_flush_sw_mac_table(struct wx *wx);
2929
int wx_set_mac(struct net_device *netdev, void *p);
3030
void wx_disable_rx(struct wx *wx);
31+
int wx_disable_sec_rx_path(struct wx *wx);
32+
void wx_enable_sec_rx_path(struct wx *wx);
3133
void wx_set_rx_mode(struct net_device *netdev);
3234
int wx_change_mtu(struct net_device *netdev, int new_mtu);
3335
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring);

drivers/net/ethernet/wangxun/libwx/wx_lib.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,11 @@ static struct wx_dec_ptype wx_ptype_lookup[256] = {
148148
[0xFD] = WX_PTT(IP, IPV6, IGMV, IPV6, SCTP, PAY4),
149149
};
150150

151-
static struct wx_dec_ptype wx_decode_ptype(const u8 ptype)
151+
struct wx_dec_ptype wx_decode_ptype(const u8 ptype)
152152
{
153153
return wx_ptype_lookup[ptype];
154154
}
155+
EXPORT_SYMBOL(wx_decode_ptype);
155156

156157
/* wx_test_staterr - tests bits in Rx descriptor status and error fields */
157158
static __le32 wx_test_staterr(union wx_rx_desc *rx_desc,
@@ -1453,6 +1454,7 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
14531454
static netdev_tx_t wx_xmit_frame_ring(struct sk_buff *skb,
14541455
struct wx_ring *tx_ring)
14551456
{
1457+
struct wx *wx = netdev_priv(tx_ring->netdev);
14561458
u16 count = TXD_USE_COUNT(skb_headlen(skb));
14571459
struct wx_tx_buffer *first;
14581460
u8 hdr_len = 0, ptype;
@@ -1498,6 +1500,10 @@ static netdev_tx_t wx_xmit_frame_ring(struct sk_buff *skb,
14981500
goto out_drop;
14991501
else if (!tso)
15001502
wx_tx_csum(tx_ring, first, ptype);
1503+
1504+
if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags) && tx_ring->atr_sample_rate)
1505+
wx->atr(tx_ring, first, ptype);
1506+
15011507
wx_tx_map(tx_ring, first, hdr_len);
15021508

15031509
return NETDEV_TX_OK;
@@ -1574,8 +1580,27 @@ static void wx_set_rss_queues(struct wx *wx)
15741580
f = &wx->ring_feature[RING_F_RSS];
15751581
f->indices = f->limit;
15761582

1577-
wx->num_rx_queues = f->limit;
1578-
wx->num_tx_queues = f->limit;
1583+
if (!(test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)))
1584+
goto out;
1585+
1586+
clear_bit(WX_FLAG_FDIR_HASH, wx->flags);
1587+
1588+
/* Use Flow Director in addition to RSS to ensure the best
1589+
* distribution of flows across cores, even when an FDIR flow
1590+
* isn't matched.
1591+
*/
1592+
if (f->indices > 1) {
1593+
f = &wx->ring_feature[RING_F_FDIR];
1594+
1595+
f->indices = f->limit;
1596+
1597+
if (!(test_bit(WX_FLAG_FDIR_PERFECT, wx->flags)))
1598+
set_bit(WX_FLAG_FDIR_HASH, wx->flags);
1599+
}
1600+
1601+
out:
1602+
wx->num_rx_queues = f->indices;
1603+
wx->num_tx_queues = f->indices;
15791604
}
15801605

15811606
static void wx_set_num_queues(struct wx *wx)

drivers/net/ethernet/wangxun/libwx/wx_lib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef _WX_LIB_H_
88
#define _WX_LIB_H_
99

10+
struct wx_dec_ptype wx_decode_ptype(const u8 ptype);
1011
void wx_alloc_rx_buffers(struct wx_ring *rx_ring, u16 cleaned_count);
1112
u16 wx_desc_unused(struct wx_ring *ring);
1213
netdev_tx_t wx_xmit_frame(struct sk_buff *skb,

drivers/net/ethernet/wangxun/libwx/wx_type.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,34 @@ enum WX_MSCA_CMD_value {
503503
#define WX_PTYPE_TYP_TCP 0x04
504504
#define WX_PTYPE_TYP_SCTP 0x05
505505

506+
/* Packet type non-ip values */
507+
enum wx_l2_ptypes {
508+
WX_PTYPE_L2_ABORTED = (WX_PTYPE_PKT_MAC),
509+
WX_PTYPE_L2_MAC = (WX_PTYPE_PKT_MAC | WX_PTYPE_TYP_MAC),
510+
511+
WX_PTYPE_L2_IPV4_FRAG = (WX_PTYPE_PKT_IP | WX_PTYPE_TYP_IPFRAG),
512+
WX_PTYPE_L2_IPV4 = (WX_PTYPE_PKT_IP | WX_PTYPE_TYP_IP),
513+
WX_PTYPE_L2_IPV4_UDP = (WX_PTYPE_PKT_IP | WX_PTYPE_TYP_UDP),
514+
WX_PTYPE_L2_IPV4_TCP = (WX_PTYPE_PKT_IP | WX_PTYPE_TYP_TCP),
515+
WX_PTYPE_L2_IPV4_SCTP = (WX_PTYPE_PKT_IP | WX_PTYPE_TYP_SCTP),
516+
WX_PTYPE_L2_IPV6_FRAG = (WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6 |
517+
WX_PTYPE_TYP_IPFRAG),
518+
WX_PTYPE_L2_IPV6 = (WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6 |
519+
WX_PTYPE_TYP_IP),
520+
WX_PTYPE_L2_IPV6_UDP = (WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6 |
521+
WX_PTYPE_TYP_UDP),
522+
WX_PTYPE_L2_IPV6_TCP = (WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6 |
523+
WX_PTYPE_TYP_TCP),
524+
WX_PTYPE_L2_IPV6_SCTP = (WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6 |
525+
WX_PTYPE_TYP_SCTP),
526+
527+
WX_PTYPE_L2_TUN4_MAC = (WX_PTYPE_TUN_IPV4 | WX_PTYPE_PKT_IGM),
528+
WX_PTYPE_L2_TUN6_MAC = (WX_PTYPE_TUN_IPV6 | WX_PTYPE_PKT_IGM),
529+
};
530+
531+
#define WX_PTYPE_PKT(_pt) ((_pt) & 0x30)
532+
#define WX_PTYPE_TYPL4(_pt) ((_pt) & 0x07)
533+
506534
#define WX_RXD_PKTTYPE(_rxd) \
507535
((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 9) & 0xFF)
508536
#define WX_RXD_IPV6EX(_rxd) \
@@ -552,6 +580,9 @@ enum wx_tx_flags {
552580
WX_TX_FLAGS_OUTER_IPV4 = 0x100,
553581
WX_TX_FLAGS_LINKSEC = 0x200,
554582
WX_TX_FLAGS_IPSEC = 0x400,
583+
584+
/* software defined flags */
585+
WX_TX_FLAGS_SW_VLAN = 0x40,
555586
};
556587

557588
/* VLAN info */
@@ -900,7 +931,13 @@ struct wx_ring {
900931
*/
901932
u16 next_to_use;
902933
u16 next_to_clean;
903-
u16 next_to_alloc;
934+
union {
935+
u16 next_to_alloc;
936+
struct {
937+
u8 atr_sample_rate;
938+
u8 atr_count;
939+
};
940+
};
904941

905942
struct wx_queue_stats stats;
906943
struct u64_stats_sync syncp;
@@ -939,6 +976,7 @@ struct wx_ring_feature {
939976
enum wx_ring_f_enum {
940977
RING_F_NONE = 0,
941978
RING_F_RSS,
979+
RING_F_FDIR,
942980
RING_F_ARRAY_SIZE /* must be last in enum set */
943981
};
944982

@@ -986,9 +1024,18 @@ enum wx_state {
9861024
WX_STATE_RESETTING,
9871025
WX_STATE_NBITS, /* must be last */
9881026
};
1027+
1028+
enum wx_pf_flags {
1029+
WX_FLAG_FDIR_CAPABLE,
1030+
WX_FLAG_FDIR_HASH,
1031+
WX_FLAG_FDIR_PERFECT,
1032+
WX_PF_FLAGS_NBITS /* must be last */
1033+
};
1034+
9891035
struct wx {
9901036
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
9911037
DECLARE_BITMAP(state, WX_STATE_NBITS);
1038+
DECLARE_BITMAP(flags, WX_PF_FLAGS_NBITS);
9921039

9931040
void *priv;
9941041
u8 __iomem *hw_addr;
@@ -1077,6 +1124,9 @@ struct wx {
10771124
u64 hw_csum_rx_error;
10781125
u64 alloc_rx_buff_failed;
10791126

1127+
u32 atr_sample_rate;
1128+
void (*atr)(struct wx_ring *ring, struct wx_tx_buffer *first, u8 ptype);
1129+
void (*configure_fdir)(struct wx *wx);
10801130
void (*do_reset)(struct net_device *netdev);
10811131
};
10821132

drivers/net/ethernet/wangxun/txgbe/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ txgbe-objs := txgbe_main.o \
1010
txgbe_hw.o \
1111
txgbe_phy.o \
1212
txgbe_irq.o \
13+
txgbe_fdir.o \
1314
txgbe_ethtool.o

0 commit comments

Comments
 (0)