Commit 4bdb4411 authored by Jiawen Wu's avatar Jiawen Wu Committed by Paolo Abeni

net: txgbe: support Flow Director perfect filters

Support the addition and deletion of Flow Director filters.

Supported fields: src-ip, dst-ip, src-port, dst-port
Supported flow-types: tcp4, udp4, sctp4, ipv4
Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent b501d261
......@@ -2705,6 +2705,7 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
{
netdev_features_t changed = netdev->features ^ features;
struct wx *wx = netdev_priv(netdev);
bool need_reset = false;
if (features & NETIF_F_RXHASH) {
wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN,
......@@ -2722,6 +2723,36 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER))
wx_set_rx_mode(netdev);
if (!(test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)))
return 0;
/* Check if Flow Director n-tuple support was enabled or disabled. If
* the state changed, we need to reset.
*/
switch (features & NETIF_F_NTUPLE) {
case NETIF_F_NTUPLE:
/* turn off ATR, enable perfect filters and reset */
if (!(test_and_set_bit(WX_FLAG_FDIR_PERFECT, wx->flags)))
need_reset = true;
clear_bit(WX_FLAG_FDIR_HASH, wx->flags);
break;
default:
/* turn off perfect filters, enable ATR and reset */
if (test_and_clear_bit(WX_FLAG_FDIR_PERFECT, wx->flags))
need_reset = true;
/* We cannot enable ATR if RSS is disabled */
if (wx->ring_feature[RING_F_RSS].limit <= 1)
break;
set_bit(WX_FLAG_FDIR_HASH, wx->flags);
break;
}
if (need_reset)
wx->do_reset(netdev);
return 0;
}
EXPORT_SYMBOL(wx_set_features);
......
......@@ -4,7 +4,17 @@
#ifndef _TXGBE_FDIR_H_
#define _TXGBE_FDIR_H_
void txgbe_atr_compute_perfect_hash(union txgbe_atr_input *input,
union txgbe_atr_input *input_mask);
void txgbe_atr(struct wx_ring *ring, struct wx_tx_buffer *first, u8 ptype);
int txgbe_fdir_set_input_mask(struct wx *wx, union txgbe_atr_input *input_mask);
int txgbe_fdir_write_perfect_filter(struct wx *wx,
union txgbe_atr_input *input,
u16 soft_id, u8 queue);
int txgbe_fdir_erase_perfect_filter(struct wx *wx,
union txgbe_atr_input *input,
u16 soft_id);
void txgbe_configure_fdir(struct wx *wx);
void txgbe_fdir_filter_exit(struct wx *wx);
#endif /* _TXGBE_FDIR_H_ */
......@@ -283,6 +283,12 @@ static int txgbe_sw_init(struct wx *wx)
return 0;
}
static void txgbe_init_fdir(struct txgbe *txgbe)
{
txgbe->fdir_filter_count = 0;
spin_lock_init(&txgbe->fdir_perfect_lock);
}
/**
* txgbe_open - Called when a network interface is made active
* @netdev: network interface device structure
......@@ -361,6 +367,7 @@ static int txgbe_close(struct net_device *netdev)
txgbe_down(wx);
wx_free_irq(wx);
wx_free_resources(wx);
txgbe_fdir_filter_exit(wx);
wx_control_hw(wx, false);
return 0;
......@@ -669,6 +676,8 @@ static int txgbe_probe(struct pci_dev *pdev,
txgbe->wx = wx;
wx->priv = txgbe;
txgbe_init_fdir(txgbe);
err = txgbe_setup_misc_irq(txgbe);
if (err)
goto err_release_hw;
......
......@@ -90,6 +90,7 @@
#define TXGBE_XPCS_IDA_DATA 0x13004
/********************************* Flow Director *****************************/
#define TXGBE_RDB_FDIR_DROP_QUEUE 127
#define TXGBE_RDB_FDIR_CTL 0x19500
#define TXGBE_RDB_FDIR_CTL_INIT_DONE BIT(3)
#define TXGBE_RDB_FDIR_CTL_PERFECT_MATCH BIT(4)
......@@ -97,6 +98,13 @@
#define TXGBE_RDB_FDIR_CTL_HASH_BITS(v) FIELD_PREP(GENMASK(23, 20), v)
#define TXGBE_RDB_FDIR_CTL_MAX_LENGTH(v) FIELD_PREP(GENMASK(27, 24), v)
#define TXGBE_RDB_FDIR_CTL_FULL_THRESH(v) FIELD_PREP(GENMASK(31, 28), v)
#define TXGBE_RDB_FDIR_IP6(_i) (0x1950C + ((_i) * 4)) /* 0-2 */
#define TXGBE_RDB_FDIR_SA 0x19518
#define TXGBE_RDB_FDIR_DA 0x1951C
#define TXGBE_RDB_FDIR_PORT 0x19520
#define TXGBE_RDB_FDIR_PORT_DESTINATION_SHIFT 16
#define TXGBE_RDB_FDIR_FLEX 0x19524
#define TXGBE_RDB_FDIR_FLEX_FLEX_SHIFT 16
#define TXGBE_RDB_FDIR_HASH 0x19528
#define TXGBE_RDB_FDIR_HASH_SIG_SW_INDEX(v) FIELD_PREP(GENMASK(31, 16), v)
#define TXGBE_RDB_FDIR_HASH_BUCKET_VALID BIT(15)
......@@ -114,8 +122,16 @@
#define TXGBE_RDB_FDIR_CMD_QUEUE_EN BIT(15)
#define TXGBE_RDB_FDIR_CMD_RX_QUEUE(v) FIELD_PREP(GENMASK(22, 16), v)
#define TXGBE_RDB_FDIR_CMD_VT_POOL(v) FIELD_PREP(GENMASK(29, 24), v)
#define TXGBE_RDB_FDIR_DA4_MSK 0x1953C
#define TXGBE_RDB_FDIR_SA4_MSK 0x19540
#define TXGBE_RDB_FDIR_TCP_MSK 0x19544
#define TXGBE_RDB_FDIR_UDP_MSK 0x19548
#define TXGBE_RDB_FDIR_SCTP_MSK 0x19560
#define TXGBE_RDB_FDIR_HKEY 0x19568
#define TXGBE_RDB_FDIR_SKEY 0x1956C
#define TXGBE_RDB_FDIR_OTHER_MSK 0x19570
#define TXGBE_RDB_FDIR_OTHER_MSK_POOL BIT(2)
#define TXGBE_RDB_FDIR_OTHER_MSK_L4P BIT(3)
#define TXGBE_RDB_FDIR_FLEX_CFG(_i) (0x19580 + ((_i) * 4))
#define TXGBE_RDB_FDIR_FLEX_CFG_FIELD0 GENMASK(7, 0)
#define TXGBE_RDB_FDIR_FLEX_CFG_BASE_MAC FIELD_PREP(GENMASK(1, 0), 0)
......@@ -230,6 +246,13 @@ enum txgbe_fdir_pballoc_type {
TXGBE_FDIR_PBALLOC_256K = 3,
};
struct txgbe_fdir_filter {
struct hlist_node fdir_node;
union txgbe_atr_input filter;
u16 sw_idx;
u16 action;
};
/* TX/RX descriptor defines */
#define TXGBE_DEFAULT_TXD 512
#define TXGBE_DEFAULT_TX_WORK 256
......@@ -316,7 +339,10 @@ struct txgbe {
unsigned int link_irq;
/* flow director */
struct hlist_head fdir_filter_list;
union txgbe_atr_input fdir_mask;
int fdir_filter_count;
spinlock_t fdir_perfect_lock; /* spinlock for FDIR */
};
#endif /* _TXGBE_TYPE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment