net/cxgbe: query firmware for filter resources

Fetch available filter resources from firmware and allocate table for
book-keeping and managing filters in hardware. Also define the hardware
filter specification (ch_filter_specification) used to describe each
filter rule.

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
This commit is contained in:
Shagun Agrawal 2018-06-08 23:28:11 +05:30 committed by Ferruh Yigit
parent 8c7cd2fa4e
commit 6f2a064bef
5 changed files with 240 additions and 0 deletions

View File

@ -11,9 +11,11 @@
#include <rte_bus_pci.h>
#include <rte_mbuf.h>
#include <rte_io.h>
#include <rte_ethdev.h>
#include "cxgbe_compat.h"
#include "t4_regs_values.h"
#include "cxgbe_ofld.h"
enum {
MAX_ETH_QSETS = 64, /* # of Ethernet Tx/Rx queue sets */
@ -306,6 +308,8 @@ struct adapter {
unsigned int vpd_flag;
int use_unpacked_mode; /* unpacked rx mode state */
struct tid_info tids; /* Info used to access TID related tables */
};
/**

View File

@ -489,6 +489,10 @@ enum fw_params_mnem {
enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_CCLK = 0x00, /* chip core clock in khz */
FW_PARAMS_PARAM_DEV_PORTVEC = 0x01, /* the port vector */
FW_PARAMS_PARAM_DEV_NTID = 0x02, /* reads the number of TIDs
* allocated by the device's
* Lookup Engine
*/
FW_PARAMS_PARAM_DEV_FWREV = 0x0B, /* fw version */
FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
@ -498,6 +502,8 @@ enum fw_params_param_dev {
* physical and virtual function parameters
*/
enum fw_params_param_pfvf {
FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,
FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,
FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A
};

View File

@ -0,0 +1,97 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Chelsio Communications.
* All rights reserved.
*/
#ifndef _CXGBE_FILTER_H_
#define _CXGBE_FILTER_H_
#include "t4_msg.h"
/*
* Defined bit width of user definable filter tuples
*/
#define ETHTYPE_BITWIDTH 16
#define FRAG_BITWIDTH 1
#define MACIDX_BITWIDTH 9
#define FCOE_BITWIDTH 1
#define IPORT_BITWIDTH 3
#define MATCHTYPE_BITWIDTH 3
#define PROTO_BITWIDTH 8
#define TOS_BITWIDTH 8
#define PF_BITWIDTH 8
#define VF_BITWIDTH 8
#define IVLAN_BITWIDTH 16
#define OVLAN_BITWIDTH 16
/*
* Filter matching rules. These consist of a set of ingress packet field
* (value, mask) tuples. The associated ingress packet field matches the
* tuple when ((field & mask) == value). (Thus a wildcard "don't care" field
* rule can be constructed by specifying a tuple of (0, 0).) A filter rule
* matches an ingress packet when all of the individual individual field
* matching rules are true.
*
* Partial field masks are always valid, however, while it may be easy to
* understand their meanings for some fields (e.g. IP address to match a
* subnet), for others making sensible partial masks is less intuitive (e.g.
* MPS match type) ...
*/
struct ch_filter_tuple {
/*
* Compressed header matching field rules. The TP_VLAN_PRI_MAP
* register selects which of these fields will participate in the
* filter match rules -- up to a maximum of 36 bits. Because
* TP_VLAN_PRI_MAP is a global register, all filters must use the same
* set of fields.
*/
uint32_t ethtype:ETHTYPE_BITWIDTH; /* Ethernet type */
uint32_t frag:FRAG_BITWIDTH; /* IP fragmentation header */
uint32_t ivlan_vld:1; /* inner VLAN valid */
uint32_t ovlan_vld:1; /* outer VLAN valid */
uint32_t pfvf_vld:1; /* PF/VF valid */
uint32_t macidx:MACIDX_BITWIDTH; /* exact match MAC index */
uint32_t fcoe:FCOE_BITWIDTH; /* FCoE packet */
uint32_t iport:IPORT_BITWIDTH; /* ingress port */
uint32_t matchtype:MATCHTYPE_BITWIDTH; /* MPS match type */
uint32_t proto:PROTO_BITWIDTH; /* protocol type */
uint32_t tos:TOS_BITWIDTH; /* TOS/Traffic Type */
uint32_t pf:PF_BITWIDTH; /* PCI-E PF ID */
uint32_t vf:VF_BITWIDTH; /* PCI-E VF ID */
uint32_t ivlan:IVLAN_BITWIDTH; /* inner VLAN */
uint32_t ovlan:OVLAN_BITWIDTH; /* outer VLAN */
/*
* Uncompressed header matching field rules. These are always
* available for field rules.
*/
uint8_t lip[16]; /* local IP address (IPv4 in [3:0]) */
uint8_t fip[16]; /* foreign IP address (IPv4 in [3:0]) */
uint16_t lport; /* local port */
uint16_t fport; /* foreign port */
/* reservations for future additions */
uint8_t rsvd[12];
};
/*
* Filter specification
*/
struct ch_filter_specification {
/* Filter rule value/mask pairs. */
struct ch_filter_tuple val;
struct ch_filter_tuple mask;
};
/*
* Host shadow copy of ingress filter entry. This is in host native format
* and doesn't match the ordering or bit order, etc. of the hardware or the
* firmware command.
*/
struct filter_entry {
/*
* The filter itself.
*/
struct ch_filter_specification fs;
};
#endif /* _CXGBE_FILTER_H_ */

View File

@ -38,6 +38,22 @@
#include "t4_msg.h"
#include "cxgbe.h"
/**
* Allocate a chunk of memory. The allocated memory is cleared.
*/
void *t4_alloc_mem(size_t size)
{
return rte_zmalloc(NULL, size, 0);
}
/**
* Free memory allocated through t4_alloc_mem().
*/
void t4_free_mem(void *addr)
{
rte_free(addr);
}
/*
* Response queue handler for the FW event queue.
*/
@ -169,6 +185,59 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us,
return 0;
}
/**
* Free TID tables.
*/
static void tid_free(struct tid_info *t)
{
if (t->tid_tab) {
if (t->ftid_bmap)
rte_bitmap_free(t->ftid_bmap);
if (t->ftid_bmap_array)
t4_os_free(t->ftid_bmap_array);
t4_os_free(t->tid_tab);
}
memset(t, 0, sizeof(struct tid_info));
}
/**
* Allocate and initialize the TID tables. Returns 0 on success.
*/
static int tid_init(struct tid_info *t)
{
size_t size;
unsigned int ftid_bmap_size;
unsigned int max_ftids = t->nftids;
ftid_bmap_size = rte_bitmap_get_memory_footprint(t->nftids);
size = t->ntids * sizeof(*t->tid_tab) +
max_ftids * sizeof(*t->ftid_tab);
t->tid_tab = t4_os_alloc(size);
if (!t->tid_tab)
return -ENOMEM;
t->ftid_tab = (struct filter_entry *)&t->tid_tab[t->ntids];
t->ftid_bmap_array = t4_os_alloc(ftid_bmap_size);
if (!t->ftid_bmap_array) {
tid_free(t);
return -ENOMEM;
}
t4_os_lock_init(&t->ftid_lock);
t->ftid_bmap = rte_bitmap_init(t->nftids, t->ftid_bmap_array,
ftid_bmap_size);
if (!t->ftid_bmap) {
tid_free(t);
return -ENOMEM;
}
return 0;
}
static inline bool is_x_1g_port(const struct link_config *lc)
{
return (lc->pcaps & FW_PORT_CAP32_SPEED_1G) != 0;
@ -706,6 +775,7 @@ bye:
static int adap_init0(struct adapter *adap)
{
struct fw_caps_config_cmd caps_cmd;
int ret = 0;
u32 v, port_vec;
enum dev_state state;
@ -822,6 +892,35 @@ static int adap_init0(struct adapter *adap)
V_FW_PARAMS_PARAM_Y(0) | \
V_FW_PARAMS_PARAM_Z(0))
params[0] = FW_PARAM_PFVF(FILTER_START);
params[1] = FW_PARAM_PFVF(FILTER_END);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2, params, val);
if (ret < 0)
goto bye;
adap->tids.ftid_base = val[0];
adap->tids.nftids = val[1] - val[0] + 1;
/*
* Get device capabilities so we can determine what resources we need
* to manage.
*/
memset(&caps_cmd, 0, sizeof(caps_cmd));
caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
F_FW_CMD_REQUEST | F_FW_CMD_READ);
caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
&caps_cmd);
if (ret < 0)
goto bye;
/* query tid-related parameters */
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
params, val);
if (ret < 0)
goto bye;
adap->tids.ntids = val[0];
/* If we're running on newer firmware, let it know that we're
* prepared to deal with encapsulated CPL messages. Older
* firmware won't understand this and we'll just get
@ -1307,6 +1406,7 @@ void cxgbe_close(struct adapter *adapter)
if (adapter->flags & FULL_INIT_DONE) {
if (is_pf4(adapter))
t4_intr_disable(adapter);
tid_free(&adapter->tids);
t4_sge_tx_monitor_stop(adapter);
t4_free_sge_resources(adapter);
for_each_port(adapter, i) {
@ -1469,6 +1569,12 @@ allocate_mac:
print_adapter_info(adapter);
print_port_info(adapter);
if (tid_init(&adapter->tids) < 0) {
/* Disable filtering support */
dev_warn(adapter, "could not allocate TID table, "
"filter support disabled. Continuing\n");
}
err = init_rss(adapter);
if (err)
goto out_free;

View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Chelsio Communications.
* All rights reserved.
*/
#ifndef _CXGBE_OFLD_H_
#define _CXGBE_OFLD_H_
#include <rte_bitmap.h>
#include "cxgbe_filter.h"
/*
* Holds the size, base address, free list start, etc of filter TID.
* The tables themselves are allocated dynamically.
*/
struct tid_info {
void **tid_tab;
unsigned int ntids;
struct filter_entry *ftid_tab; /* Normal filters */
struct rte_bitmap *ftid_bmap;
uint8_t *ftid_bmap_array;
unsigned int nftids;
unsigned int ftid_base;
rte_spinlock_t ftid_lock;
};
#endif /* _CXGBE_OFLD_H_ */