Commit 4bfbe53f authored by David S. Miller's avatar David S. Miller

Merge branch 'cxgb4-add-hash-filter-support-to-tc-flower-offload'

Rahul Lakkireddy says:

====================
cxgb4: add hash-filter support to tc-flower offload

This series of patches add support to create hash-filters; a.k.a
exact-match filters, to tc-flower offload.  T6 supports creating
~500K hash-filters in hw and can theoretically be expanded up to
~1 million.

Patch 1 fetches and saves the configured hw filter tuple field shifts
and filter mask.

Patch 2 initializes the driver to use hash-filter configuration.

Patch 3 adds support to create hash filters in hw.

Patch 4 adds support to delete hash filters in hw.

Patch 5 adds support to retrieve filter stats for hash filters.

Patch 6 converts the flower table to use rhashtable instead of
static hlist.

Patch 7 finally adds support to create hash filters via tc-flower
offload.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1f2c897c 3eb8b62d
...@@ -287,10 +287,18 @@ struct tp_params { ...@@ -287,10 +287,18 @@ struct tp_params {
* places we store their offsets here, or a -1 if the field isn't * places we store their offsets here, or a -1 if the field isn't
* present. * present.
*/ */
int vlan_shift; int fcoe_shift;
int vnic_shift;
int port_shift; int port_shift;
int vnic_shift;
int vlan_shift;
int tos_shift;
int protocol_shift; int protocol_shift;
int ethertype_shift;
int macmatch_shift;
int matchtype_shift;
int frag_shift;
u64 hash_filter_mask;
}; };
struct vpd_params { struct vpd_params {
...@@ -358,6 +366,7 @@ struct adapter_params { ...@@ -358,6 +366,7 @@ struct adapter_params {
unsigned char crypto; /* HW capability for crypto */ unsigned char crypto; /* HW capability for crypto */
unsigned char bypass; unsigned char bypass;
unsigned char hash_filter;
unsigned int ofldq_wr_cred; unsigned int ofldq_wr_cred;
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */ bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
...@@ -909,8 +918,10 @@ struct adapter { ...@@ -909,8 +918,10 @@ struct adapter {
struct chcr_stats_debug chcr_stats; struct chcr_stats_debug chcr_stats;
/* TC flower offload */ /* TC flower offload */
DECLARE_HASHTABLE(flower_anymatch_tbl, 9); struct rhashtable flower_tbl;
struct rhashtable_params flower_ht_params;
struct timer_list flower_stats_timer; struct timer_list flower_stats_timer;
struct work_struct flower_stats_work;
/* Ethtool Dump */ /* Ethtool Dump */
struct ethtool_dump eth_dump; struct ethtool_dump eth_dump;
...@@ -1041,6 +1052,7 @@ struct ch_filter_specification { ...@@ -1041,6 +1052,7 @@ struct ch_filter_specification {
* matching that doesn't exist as a (value, mask) tuple. * matching that doesn't exist as a (value, mask) tuple.
*/ */
uint32_t type:1; /* 0 => IPv4, 1 => IPv6 */ uint32_t type:1; /* 0 => IPv4, 1 => IPv6 */
u32 hash:1; /* 0 => wild-card, 1 => exact-match */
/* Packet dispatch information. Ingress packets which match the /* Packet dispatch information. Ingress packets which match the
* filter rules will be dropped, passed to the host or switched back * filter rules will be dropped, passed to the host or switched back
...@@ -1098,7 +1110,14 @@ enum { ...@@ -1098,7 +1110,14 @@ enum {
}; };
enum { enum {
NAT_MODE_ALL = 7, /* NAT on entire 4-tuple */ NAT_MODE_NONE = 0, /* No NAT performed */
NAT_MODE_DIP, /* NAT on Dst IP */
NAT_MODE_DIP_DP, /* NAT on Dst IP, Dst Port */
NAT_MODE_DIP_DP_SIP, /* NAT on Dst IP, Dst Port and Src IP */
NAT_MODE_DIP_DP_SP, /* NAT on Dst IP, Dst Port and Src Port */
NAT_MODE_SIP_SP, /* NAT on Src IP and Src Port */
NAT_MODE_DIP_SIP_SP, /* NAT on Dst IP, Src IP and Src Port */
NAT_MODE_ALL /* NAT on entire 4-tuple */
}; };
/* Host shadow copy of ingress filter entry. This is in host native format /* Host shadow copy of ingress filter entry. This is in host native format
...@@ -1132,6 +1151,11 @@ static inline int is_offload(const struct adapter *adap) ...@@ -1132,6 +1151,11 @@ static inline int is_offload(const struct adapter *adap)
return adap->params.offload; return adap->params.offload;
} }
static inline int is_hashfilter(const struct adapter *adap)
{
return adap->params.hash_filter;
}
static inline int is_pci_uld(const struct adapter *adap) static inline int is_pci_uld(const struct adapter *adap)
{ {
return adap->params.crypto; return adap->params.crypto;
......
...@@ -37,7 +37,12 @@ ...@@ -37,7 +37,12 @@
#include "t4_msg.h" #include "t4_msg.h"
#define WORD_MASK 0xffffffff
void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl); void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl);
void hash_del_filter_rpl(struct adapter *adap,
const struct cpl_abort_rpl_rss *rpl);
void clear_filter(struct adapter *adap, struct filter_entry *f); void clear_filter(struct adapter *adap, struct filter_entry *f);
int set_filter_wr(struct adapter *adapter, int fidx); int set_filter_wr(struct adapter *adapter, int fidx);
...@@ -45,4 +50,7 @@ int delete_filter(struct adapter *adapter, unsigned int fidx); ...@@ -45,4 +50,7 @@ int delete_filter(struct adapter *adapter, unsigned int fidx);
int writable_filter(struct filter_entry *f); int writable_filter(struct filter_entry *f);
void clear_all_filters(struct adapter *adapter); void clear_all_filters(struct adapter *adapter);
int init_hash_filter(struct adapter *adap);
bool is_filter_exact_match(struct adapter *adap,
struct ch_filter_specification *fs);
#endif /* __CXGB4_FILTER_H */ #endif /* __CXGB4_FILTER_H */
...@@ -572,6 +572,14 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, ...@@ -572,6 +572,14 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
const struct cpl_set_tcb_rpl *p = (void *)rsp; const struct cpl_set_tcb_rpl *p = (void *)rsp;
filter_rpl(q->adap, p); filter_rpl(q->adap, p);
} else if (opcode == CPL_ACT_OPEN_RPL) {
const struct cpl_act_open_rpl *p = (void *)rsp;
hash_filter_rpl(q->adap, p);
} else if (opcode == CPL_ABORT_RPL_RSS) {
const struct cpl_abort_rpl_rss *p = (void *)rsp;
hash_del_filter_rpl(q->adap, p);
} else } else
dev_err(q->adap->pdev_dev, dev_err(q->adap->pdev_dev,
"unexpected CPL %#x on FW event queue\n", opcode); "unexpected CPL %#x on FW event queue\n", opcode);
...@@ -3963,7 +3971,8 @@ static int adap_init0(struct adapter *adap) ...@@ -3963,7 +3971,8 @@ static int adap_init0(struct adapter *adap)
if (ret < 0) if (ret < 0)
goto bye; goto bye;
if (caps_cmd.ofldcaps) { if (caps_cmd.ofldcaps ||
(caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_HASHFILTER))) {
/* query offload-related parameters */ /* query offload-related parameters */
params[0] = FW_PARAM_DEV(NTID); params[0] = FW_PARAM_DEV(NTID);
params[1] = FW_PARAM_PFVF(SERVER_START); params[1] = FW_PARAM_PFVF(SERVER_START);
...@@ -4000,8 +4009,13 @@ static int adap_init0(struct adapter *adap) ...@@ -4000,8 +4009,13 @@ static int adap_init0(struct adapter *adap)
adap->vres.ddp.size = val[4] - val[3] + 1; adap->vres.ddp.size = val[4] - val[3] + 1;
adap->params.ofldq_wr_cred = val[5]; adap->params.ofldq_wr_cred = val[5];
adap->params.offload = 1; if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_HASHFILTER)) {
adap->num_ofld_uld += 1; if (init_hash_filter(adap) < 0)
goto bye;
} else {
adap->params.offload = 1;
adap->num_ofld_uld += 1;
}
} }
if (caps_cmd.rdmacaps) { if (caps_cmd.rdmacaps) {
params[0] = FW_PARAM_PFVF(STAG_START); params[0] = FW_PARAM_PFVF(STAG_START);
...@@ -5168,10 +5182,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -5168,10 +5182,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"could not offload tc u32, continuing\n"); "could not offload tc u32, continuing\n");
cxgb4_init_tc_flower(adapter); if (cxgb4_init_tc_flower(adapter))
dev_warn(&pdev->dev,
"could not offload tc flower, continuing\n");
} }
if (is_offload(adapter)) { if (is_offload(adapter) || is_hashfilter(adapter)) {
if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) { if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
u32 hash_base, hash_reg; u32 hash_base, hash_reg;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <net/tc_act/tc_vlan.h> #include <net/tc_act/tc_vlan.h>
#include "cxgb4.h" #include "cxgb4.h"
#include "cxgb4_filter.h"
#include "cxgb4_tc_flower.h" #include "cxgb4_tc_flower.h"
#define STATS_CHECK_PERIOD (HZ / 2) #define STATS_CHECK_PERIOD (HZ / 2)
...@@ -74,13 +75,8 @@ static struct ch_tc_flower_entry *allocate_flower_entry(void) ...@@ -74,13 +75,8 @@ static struct ch_tc_flower_entry *allocate_flower_entry(void)
static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap, static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,
unsigned long flower_cookie) unsigned long flower_cookie)
{ {
struct ch_tc_flower_entry *flower_entry; return rhashtable_lookup_fast(&adap->flower_tbl, &flower_cookie,
adap->flower_ht_params);
hash_for_each_possible_rcu(adap->flower_anymatch_tbl, flower_entry,
link, flower_cookie)
if (flower_entry->tc_flower_cookie == flower_cookie)
return flower_entry;
return NULL;
} }
static void cxgb4_process_flow_match(struct net_device *dev, static void cxgb4_process_flow_match(struct net_device *dev,
...@@ -677,11 +673,16 @@ int cxgb4_tc_flower_replace(struct net_device *dev, ...@@ -677,11 +673,16 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
cxgb4_process_flow_match(dev, cls, fs); cxgb4_process_flow_match(dev, cls, fs);
cxgb4_process_flow_actions(dev, cls, fs); cxgb4_process_flow_actions(dev, cls, fs);
fidx = cxgb4_get_free_ftid(dev, fs->type ? PF_INET6 : PF_INET); fs->hash = is_filter_exact_match(adap, fs);
if (fidx < 0) { if (fs->hash) {
netdev_err(dev, "%s: No fidx for offload.\n", __func__); fidx = 0;
ret = -ENOMEM; } else {
goto free_entry; fidx = cxgb4_get_free_ftid(dev, fs->type ? PF_INET6 : PF_INET);
if (fidx < 0) {
netdev_err(dev, "%s: No fidx for offload.\n", __func__);
ret = -ENOMEM;
goto free_entry;
}
} }
init_completion(&ctx.completion); init_completion(&ctx.completion);
...@@ -707,12 +708,17 @@ int cxgb4_tc_flower_replace(struct net_device *dev, ...@@ -707,12 +708,17 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
goto free_entry; goto free_entry;
} }
INIT_HLIST_NODE(&ch_flower->link);
ch_flower->tc_flower_cookie = cls->cookie; ch_flower->tc_flower_cookie = cls->cookie;
ch_flower->filter_id = ctx.tid; ch_flower->filter_id = ctx.tid;
hash_add_rcu(adap->flower_anymatch_tbl, &ch_flower->link, cls->cookie); ret = rhashtable_insert_fast(&adap->flower_tbl, &ch_flower->node,
adap->flower_ht_params);
if (ret)
goto del_filter;
return ret; return 0;
del_filter:
cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
free_entry: free_entry:
kfree(ch_flower); kfree(ch_flower);
...@@ -730,47 +736,70 @@ int cxgb4_tc_flower_destroy(struct net_device *dev, ...@@ -730,47 +736,70 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
if (!ch_flower) if (!ch_flower)
return -ENOENT; return -ENOENT;
ret = cxgb4_del_filter(dev, ch_flower->filter_id); ret = cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
if (ret) if (ret)
goto err; goto err;
hash_del_rcu(&ch_flower->link); ret = rhashtable_remove_fast(&adap->flower_tbl, &ch_flower->node,
adap->flower_ht_params);
if (ret) {
netdev_err(dev, "Flow remove from rhashtable failed");
goto err;
}
kfree_rcu(ch_flower, rcu); kfree_rcu(ch_flower, rcu);
err: err:
return ret; return ret;
} }
static void ch_flower_stats_cb(struct timer_list *t) static void ch_flower_stats_handler(struct work_struct *work)
{ {
struct adapter *adap = from_timer(adap, t, flower_stats_timer); struct adapter *adap = container_of(work, struct adapter,
flower_stats_work);
struct ch_tc_flower_entry *flower_entry; struct ch_tc_flower_entry *flower_entry;
struct ch_tc_flower_stats *ofld_stats; struct ch_tc_flower_stats *ofld_stats;
unsigned int i; struct rhashtable_iter iter;
u64 packets; u64 packets;
u64 bytes; u64 bytes;
int ret; int ret;
rcu_read_lock(); rhashtable_walk_enter(&adap->flower_tbl, &iter);
hash_for_each_rcu(adap->flower_anymatch_tbl, i, flower_entry, link) { do {
ret = cxgb4_get_filter_counters(adap->port[0], flower_entry = ERR_PTR(rhashtable_walk_start(&iter));
flower_entry->filter_id, if (IS_ERR(flower_entry))
&packets, &bytes); goto walk_stop;
if (!ret) {
spin_lock(&flower_entry->lock); while ((flower_entry = rhashtable_walk_next(&iter)) &&
ofld_stats = &flower_entry->stats; !IS_ERR(flower_entry)) {
ret = cxgb4_get_filter_counters(adap->port[0],
if (ofld_stats->prev_packet_count != packets) { flower_entry->filter_id,
ofld_stats->prev_packet_count = packets; &packets, &bytes,
ofld_stats->last_used = jiffies; flower_entry->fs.hash);
if (!ret) {
spin_lock(&flower_entry->lock);
ofld_stats = &flower_entry->stats;
if (ofld_stats->prev_packet_count != packets) {
ofld_stats->prev_packet_count = packets;
ofld_stats->last_used = jiffies;
}
spin_unlock(&flower_entry->lock);
} }
spin_unlock(&flower_entry->lock);
} }
} walk_stop:
rcu_read_unlock(); rhashtable_walk_stop(&iter);
} while (flower_entry == ERR_PTR(-EAGAIN));
rhashtable_walk_exit(&iter);
mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD); mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);
} }
static void ch_flower_stats_cb(struct timer_list *t)
{
struct adapter *adap = from_timer(adap, t, flower_stats_timer);
schedule_work(&adap->flower_stats_work);
}
int cxgb4_tc_flower_stats(struct net_device *dev, int cxgb4_tc_flower_stats(struct net_device *dev,
struct tc_cls_flower_offload *cls) struct tc_cls_flower_offload *cls)
{ {
...@@ -788,7 +817,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev, ...@@ -788,7 +817,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
} }
ret = cxgb4_get_filter_counters(dev, ch_flower->filter_id, ret = cxgb4_get_filter_counters(dev, ch_flower->filter_id,
&packets, &bytes); &packets, &bytes,
ch_flower->fs.hash);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -812,15 +842,35 @@ int cxgb4_tc_flower_stats(struct net_device *dev, ...@@ -812,15 +842,35 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
return ret; return ret;
} }
void cxgb4_init_tc_flower(struct adapter *adap) static const struct rhashtable_params cxgb4_tc_flower_ht_params = {
.nelem_hint = 384,
.head_offset = offsetof(struct ch_tc_flower_entry, node),
.key_offset = offsetof(struct ch_tc_flower_entry, tc_flower_cookie),
.key_len = sizeof(((struct ch_tc_flower_entry *)0)->tc_flower_cookie),
.max_size = 524288,
.min_size = 512,
.automatic_shrinking = true
};
int cxgb4_init_tc_flower(struct adapter *adap)
{ {
hash_init(adap->flower_anymatch_tbl); int ret;
adap->flower_ht_params = cxgb4_tc_flower_ht_params;
ret = rhashtable_init(&adap->flower_tbl, &adap->flower_ht_params);
if (ret)
return ret;
INIT_WORK(&adap->flower_stats_work, ch_flower_stats_handler);
timer_setup(&adap->flower_stats_timer, ch_flower_stats_cb, 0); timer_setup(&adap->flower_stats_timer, ch_flower_stats_cb, 0);
mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD); mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);
return 0;
} }
void cxgb4_cleanup_tc_flower(struct adapter *adap) void cxgb4_cleanup_tc_flower(struct adapter *adap)
{ {
if (adap->flower_stats_timer.function) if (adap->flower_stats_timer.function)
del_timer_sync(&adap->flower_stats_timer); del_timer_sync(&adap->flower_stats_timer);
cancel_work_sync(&adap->flower_stats_work);
rhashtable_destroy(&adap->flower_tbl);
} }
...@@ -48,7 +48,7 @@ struct ch_tc_flower_entry { ...@@ -48,7 +48,7 @@ struct ch_tc_flower_entry {
struct ch_filter_specification fs; struct ch_filter_specification fs;
struct ch_tc_flower_stats stats; struct ch_tc_flower_stats stats;
unsigned long tc_flower_cookie; unsigned long tc_flower_cookie;
struct hlist_node link; struct rhash_head node;
struct rcu_head rcu; struct rcu_head rcu;
spinlock_t lock; /* lock for stats */ spinlock_t lock; /* lock for stats */
u32 filter_id; u32 filter_id;
...@@ -115,6 +115,6 @@ int cxgb4_tc_flower_destroy(struct net_device *dev, ...@@ -115,6 +115,6 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
int cxgb4_tc_flower_stats(struct net_device *dev, int cxgb4_tc_flower_stats(struct net_device *dev,
struct tc_cls_flower_offload *cls); struct tc_cls_flower_offload *cls);
void cxgb4_init_tc_flower(struct adapter *adap); int cxgb4_init_tc_flower(struct adapter *adap);
void cxgb4_cleanup_tc_flower(struct adapter *adap); void cxgb4_cleanup_tc_flower(struct adapter *adap);
#endif /* __CXGB4_TC_FLOWER_H */ #endif /* __CXGB4_TC_FLOWER_H */
...@@ -380,7 +380,7 @@ int cxgb4_delete_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) ...@@ -380,7 +380,7 @@ int cxgb4_delete_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
return -EINVAL; return -EINVAL;
} }
ret = cxgb4_del_filter(dev, filter_id); ret = cxgb4_del_filter(dev, filter_id, NULL);
if (ret) if (ret)
goto out; goto out;
...@@ -399,7 +399,7 @@ int cxgb4_delete_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) ...@@ -399,7 +399,7 @@ int cxgb4_delete_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
if (!test_bit(j, link->tid_map)) if (!test_bit(j, link->tid_map))
continue; continue;
ret = __cxgb4_del_filter(dev, j, NULL); ret = __cxgb4_del_filter(dev, j, NULL, NULL);
if (ret) if (ret)
goto out; goto out;
......
...@@ -217,12 +217,14 @@ int __cxgb4_set_filter(struct net_device *dev, int filter_id, ...@@ -217,12 +217,14 @@ int __cxgb4_set_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs, struct ch_filter_specification *fs,
struct filter_ctx *ctx); struct filter_ctx *ctx);
int __cxgb4_del_filter(struct net_device *dev, int filter_id, int __cxgb4_del_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs,
struct filter_ctx *ctx); struct filter_ctx *ctx);
int cxgb4_set_filter(struct net_device *dev, int filter_id, int cxgb4_set_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs); struct ch_filter_specification *fs);
int cxgb4_del_filter(struct net_device *dev, int filter_id); int cxgb4_del_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs);
int cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx, int cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx,
u64 *hitcnt, u64 *bytecnt); u64 *hitcnt, u64 *bytecnt, bool hash);
static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
{ {
......
...@@ -8816,11 +8816,21 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok) ...@@ -8816,11 +8816,21 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
* shift positions of several elements of the Compressed Filter Tuple * shift positions of several elements of the Compressed Filter Tuple
* for this adapter which we need frequently ... * for this adapter which we need frequently ...
*/ */
adap->params.tp.vlan_shift = t4_filter_field_shift(adap, VLAN_F); adap->params.tp.fcoe_shift = t4_filter_field_shift(adap, FCOE_F);
adap->params.tp.vnic_shift = t4_filter_field_shift(adap, VNIC_ID_F);
adap->params.tp.port_shift = t4_filter_field_shift(adap, PORT_F); adap->params.tp.port_shift = t4_filter_field_shift(adap, PORT_F);
adap->params.tp.vnic_shift = t4_filter_field_shift(adap, VNIC_ID_F);
adap->params.tp.vlan_shift = t4_filter_field_shift(adap, VLAN_F);
adap->params.tp.tos_shift = t4_filter_field_shift(adap, TOS_F);
adap->params.tp.protocol_shift = t4_filter_field_shift(adap, adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
PROTOCOL_F); PROTOCOL_F);
adap->params.tp.ethertype_shift = t4_filter_field_shift(adap,
ETHERTYPE_F);
adap->params.tp.macmatch_shift = t4_filter_field_shift(adap,
MACMATCH_F);
adap->params.tp.matchtype_shift = t4_filter_field_shift(adap,
MPSHITTYPE_F);
adap->params.tp.frag_shift = t4_filter_field_shift(adap,
FRAGMENTATION_F);
/* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID /* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
* represents the presence of an Outer VLAN instead of a VNIC ID. * represents the presence of an Outer VLAN instead of a VNIC ID.
...@@ -8828,6 +8838,10 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok) ...@@ -8828,6 +8838,10 @@ int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
if ((adap->params.tp.ingress_config & VNIC_F) == 0) if ((adap->params.tp.ingress_config & VNIC_F) == 0)
adap->params.tp.vnic_shift = -1; adap->params.tp.vnic_shift = -1;
v = t4_read_reg(adap, LE_3_DB_HASH_MASK_GEN_IPV4_T6_A);
adap->params.tp.hash_filter_mask = v;
v = t4_read_reg(adap, LE_4_DB_HASH_MASK_GEN_IPV4_T6_A);
adap->params.tp.hash_filter_mask |= ((u64)v << 32);
return 0; return 0;
} }
......
...@@ -286,6 +286,7 @@ struct work_request_hdr { ...@@ -286,6 +286,7 @@ struct work_request_hdr {
#define RX_CHANNEL_S 26 #define RX_CHANNEL_S 26
#define RX_CHANNEL_V(x) ((x) << RX_CHANNEL_S) #define RX_CHANNEL_V(x) ((x) << RX_CHANNEL_S)
#define RX_CHANNEL_F RX_CHANNEL_V(1U)
#define WND_SCALE_EN_S 28 #define WND_SCALE_EN_S 28
#define WND_SCALE_EN_V(x) ((x) << WND_SCALE_EN_S) #define WND_SCALE_EN_V(x) ((x) << WND_SCALE_EN_S)
...@@ -315,6 +316,10 @@ struct cpl_pass_open_req { ...@@ -315,6 +316,10 @@ struct cpl_pass_open_req {
#define DELACK_V(x) ((x) << DELACK_S) #define DELACK_V(x) ((x) << DELACK_S)
#define DELACK_F DELACK_V(1U) #define DELACK_F DELACK_V(1U)
#define NON_OFFLOAD_S 7
#define NON_OFFLOAD_V(x) ((x) << NON_OFFLOAD_S)
#define NON_OFFLOAD_F NON_OFFLOAD_V(1U)
#define DSCP_S 22 #define DSCP_S 22
#define DSCP_M 0x3F #define DSCP_M 0x3F
#define DSCP_V(x) ((x) << DSCP_S) #define DSCP_V(x) ((x) << DSCP_S)
......
...@@ -2933,6 +2933,23 @@ ...@@ -2933,6 +2933,23 @@
#define SSRAMINTPERR_V(x) ((x) << SSRAMINTPERR_S) #define SSRAMINTPERR_V(x) ((x) << SSRAMINTPERR_S)
#define SSRAMINTPERR_F SSRAMINTPERR_V(1U) #define SSRAMINTPERR_F SSRAMINTPERR_V(1U)
#define LE_DB_RSP_CODE_0_A 0x19c74
#define TCAM_ACTV_HIT_S 0
#define TCAM_ACTV_HIT_M 0x1fU
#define TCAM_ACTV_HIT_V(x) ((x) << TCAM_ACTV_HIT_S)
#define TCAM_ACTV_HIT_G(x) (((x) >> TCAM_ACTV_HIT_S) & TCAM_ACTV_HIT_M)
#define LE_DB_RSP_CODE_1_A 0x19c78
#define HASH_ACTV_HIT_S 25
#define HASH_ACTV_HIT_M 0x1fU
#define HASH_ACTV_HIT_V(x) ((x) << HASH_ACTV_HIT_S)
#define HASH_ACTV_HIT_G(x) (((x) >> HASH_ACTV_HIT_S) & HASH_ACTV_HIT_M)
#define LE_3_DB_HASH_MASK_GEN_IPV4_T6_A 0x19eac
#define LE_4_DB_HASH_MASK_GEN_IPV4_T6_A 0x19eb0
#define NCSI_INT_CAUSE_A 0x1a0d8 #define NCSI_INT_CAUSE_A 0x1a0d8
#define CIM_DM_PRTY_ERR_S 8 #define CIM_DM_PRTY_ERR_S 8
......
...@@ -42,6 +42,28 @@ ...@@ -42,6 +42,28 @@
#define TCB_T_FLAGS_W 1 #define TCB_T_FLAGS_W 1
#define TF_CCTRL_ECE_S 60
#define TF_CCTRL_CWR_S 61 #define TF_CCTRL_CWR_S 61
#define TF_CCTRL_RFR_S 62
#define TCB_RSS_INFO_W 3
#define TCB_RSS_INFO_S 0
#define TCB_RSS_INFO_M 0x3ffULL
#define TCB_RSS_INFO_V(x) ((x) << TCB_RSS_INFO_S)
#define TCB_TIMESTAMP_W 5
#define TCB_TIMESTAMP_S 0
#define TCB_TIMESTAMP_M 0xffffffffULL
#define TCB_TIMESTAMP_V(x) ((x) << TCB_TIMESTAMP_S)
#define TCB_RTT_TS_RECENT_AGE_W 6
#define TCB_RTT_TS_RECENT_AGE_S 0
#define TCB_RTT_TS_RECENT_AGE_M 0xffffffffULL
#define TCB_RTT_TS_RECENT_AGE_V(x) ((x) << TCB_RTT_TS_RECENT_AGE_S)
#define TCB_SND_UNA_RAW_W 10
#define TCB_RX_FRAG2_PTR_RAW_W 27
#define TCB_RX_FRAG3_LEN_RAW_W 29
#define TCB_RX_FRAG3_START_IDX_OFFSET_RAW_W 30
#define TCB_PDU_HDR_LEN_W 31
#endif /* __T4_TCB_H */ #endif /* __T4_TCB_H */
...@@ -1092,6 +1092,7 @@ enum fw_caps_config_switch { ...@@ -1092,6 +1092,7 @@ enum fw_caps_config_switch {
enum fw_caps_config_nic { enum fw_caps_config_nic {
FW_CAPS_CONFIG_NIC = 0x00000001, FW_CAPS_CONFIG_NIC = 0x00000001,
FW_CAPS_CONFIG_NIC_VM = 0x00000002, FW_CAPS_CONFIG_NIC_VM = 0x00000002,
FW_CAPS_CONFIG_NIC_HASHFILTER = 0x00000020,
}; };
enum fw_caps_config_ofld { enum fw_caps_config_ofld {
......
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