X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fcxgbe_filter.c;h=5a7efe7a733e880a12533af647eaa2d3369f87d3;hb=8c9f976f05bb73e2353741137ff4def526b47cb2;hp=45602d468d4900030ec0eb6a9aed34ea0bbc54d0;hpb=844b21299f1a10ac350528365dc761e2934512ee;p=dpdk.git diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c index 45602d468d..5a7efe7a73 100644 --- a/drivers/net/cxgbe/cxgbe_filter.c +++ b/drivers/net/cxgbe/cxgbe_filter.c @@ -8,36 +8,41 @@ #include "base/t4_tcb.h" #include "base/t4_regs.h" #include "cxgbe_filter.h" +#include "mps_tcam.h" #include "clip_tbl.h" #include "l2t.h" #include "smt.h" +#include "cxgbe_pfvf.h" /** * Initialize Hash Filters */ int cxgbe_init_hash_filter(struct adapter *adap) { - unsigned int n_user_filters; - unsigned int user_filter_perc; + unsigned int user_filter_perc, n_user_filters; + u32 param, val; int ret; - u32 params[7], val[7]; -#define FW_PARAM_DEV(param) \ - (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ - V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) + if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) { + val = t4_read_reg(adap, A_LE_DB_RSP_CODE_0); + if (G_TCAM_ACTV_HIT(val) != 4) { + adap->params.hash_filter = 0; + return 0; + } -#define FW_PARAM_PFVF(param) \ - (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ - V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) | \ - V_FW_PARAMS_PARAM_Y(0) | \ - V_FW_PARAMS_PARAM_Z(0)) + val = t4_read_reg(adap, A_LE_DB_RSP_CODE_1); + if (G_HASH_ACTV_HIT(val) != 4) { + adap->params.hash_filter = 0; + return 0; + } + } - params[0] = FW_PARAM_DEV(NTID); + param = CXGBE_FW_PARAM_DEV(NTID); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, - params, val); + ¶m, &val); if (ret < 0) return ret; - adap->tids.ntids = val[0]; + adap->tids.ntids = val; adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); user_filter_perc = 100; @@ -140,7 +145,7 @@ static unsigned int get_filter_steerq(struct rte_eth_dev *dev, * then assume it is an absolute qid. */ if (fs->iq < pi->n_rx_qsets) - iq = adapter->sge.ethrxq[pi->first_qset + + iq = adapter->sge.ethrxq[pi->first_rxqset + fs->iq].rspq.abs_id; else iq = fs->iq; @@ -290,9 +295,20 @@ int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries) */ static void clear_filter(struct filter_entry *f) { + struct port_info *pi = ethdev2pinfo(f->dev); + if (f->clipt) cxgbe_clip_release(f->dev, f->clipt); + if (f->l2t) + cxgbe_l2t_release(f->l2t); + + if (f->fs.mask.macidx) + cxgbe_mpstcam_remove(pi, f->fs.val.macidx); + + if (f->smt) + cxgbe_smt_release(f->smt); + /* The zeroing of the filter rule below clears the filter valid, * pending, locked flags etc. so it's all we need for * this operation. @@ -606,6 +622,19 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev, f->dev = dev; f->fs.iq = iq; + /* Allocate MPS TCAM entry to match Destination MAC. */ + if (f->fs.mask.macidx) { + int idx; + + idx = cxgbe_mpstcam_alloc(pi, f->fs.val.dmac, f->fs.mask.dmac); + if (idx <= 0) { + ret = -ENOMEM; + goto out_err; + } + + f->fs.val.macidx = idx; + } + /* * If the new filter requires loopback Destination MAC and/or VLAN * rewriting then we need to allocate a Layer 2 Table (L2T) entry for @@ -755,34 +784,6 @@ static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx) unsigned int port_id = ethdev2pinfo(dev)->port_id; int ret; - /* - * If the new filter requires loopback Destination MAC and/or VLAN - * rewriting then we need to allocate a Layer 2 Table (L2T) entry for - * the filter. - */ - if (f->fs.newvlan || f->fs.newdmac) { - /* allocate L2T entry for new filter */ - f->l2t = cxgbe_l2t_alloc_switching(f->dev, f->fs.vlan, - f->fs.eport, f->fs.dmac); - - if (!f->l2t) - return -ENOMEM; - } - - /* If the new filter requires Source MAC rewriting then we need to - * allocate a SMT entry for the filter - */ - if (f->fs.newsmac) { - f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac); - if (!f->smt) { - if (f->l2t) { - cxgbe_l2t_release(f->l2t); - f->l2t = NULL; - } - return -ENOMEM; - } - } - ctrlq = &adapter->sge.ctrlq[port_id]; mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool); if (!mbuf) { @@ -1078,6 +1079,19 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id, f->fs.iq = iq; f->dev = dev; + /* Allocate MPS TCAM entry to match Destination MAC. */ + if (f->fs.mask.macidx) { + int idx; + + idx = cxgbe_mpstcam_alloc(pi, f->fs.val.dmac, f->fs.mask.dmac); + if (idx <= 0) { + ret = -ENOMEM; + goto free_tid; + } + + f->fs.val.macidx = idx; + } + /* Allocate a clip table entry only if we have non-zero IPv6 address. */ if (chip_ver > CHELSIO_T5 && f->fs.type && memcmp(f->fs.val.lip, bitoff, sizeof(bitoff))) { @@ -1088,6 +1102,30 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id, } } + /* If the new filter requires loopback Destination MAC and/or VLAN + * rewriting then we need to allocate a Layer 2 Table (L2T) entry for + * the filter. + */ + if (f->fs.newvlan || f->fs.newdmac) { + f->l2t = cxgbe_l2t_alloc_switching(f->dev, f->fs.vlan, + f->fs.eport, f->fs.dmac); + if (!f->l2t) { + ret = -ENOMEM; + goto free_tid; + } + } + + /* If the new filter requires Source MAC rewriting then we need to + * allocate a SMT entry for the filter + */ + if (f->fs.newsmac) { + f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac); + if (!f->smt) { + ret = -ENOMEM; + goto free_tid; + } + } + iconf = adapter->params.tp.ingress_config; /* Either PFVF or OVLAN can be active, but not both