src/dpdk/drivers/net/cxgbe/cxgbe_filter.c
static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
				 struct ch_filter_specification *fs,
				 struct filter_ctx *ctx)
{
	struct port_info *pi = ethdev2pinfo(dev);
	struct adapter *adapter = pi->adapter;
	struct tid_info *t = &adapter->tids;
	struct filter_entry *f;
	struct rte_mbuf *mbuf;
	struct sge_ctrl_txq *ctrlq;
	unsigned int iq;
	int atid, size;
	int ret = 0;

	ret = cxgbe_validate_filter(adapter, fs);
	if (ret)
		return ret;

	iq = get_filter_steerq(dev, fs);

	ctrlq = &adapter->sge.ctrlq[pi->port_id];

	f = t4_os_alloc(sizeof(*f));
	if (!f)
		return -ENOMEM;

	f->fs = *fs;
	f->ctx = ctx;
	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
	 * the filter.
	 */
	if (f->fs.newdmac || f->fs.newvlan == VLAN_INSERT ||
	    f->fs.newvlan == VLAN_REWRITE) {
		/* allocate L2T entry for new filter */
		f->l2t = cxgbe_l2t_alloc_switching(dev, f->fs.vlan,
						   f->fs.eport, f->fs.dmac);
		if (!f->l2t) {
			ret = -ENOMEM;
			goto out_err;
		}
	}

	/* 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 = -EAGAIN;
			goto out_err;
		}
	}

	atid = cxgbe_alloc_atid(t, f);
	if (atid < 0)
		goto out_err;

	if (f->fs.type == FILTER_TYPE_IPV6) {
		/* IPv6 hash filter */
		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
		if (!f->clipt)
			goto free_atid;

		size = sizeof(struct cpl_t6_act_open_req6);
		mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
		if (!mbuf) {
			ret = -ENOMEM;
			goto free_atid;
		}

		mbuf->data_len = size;
		mbuf->pkt_len = mbuf->data_len;

		mk_act_open_req6(f, mbuf,
				 ((adapter->sge.fw_evtq.abs_id << 14) | atid),
				 adapter);
	} else {
		/* IPv4 hash filter */
		size = sizeof(struct cpl_t6_act_open_req);
		mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
		if (!mbuf) {
			ret = -ENOMEM;
			goto free_atid;
		}

		mbuf->data_len = size;
		mbuf->pkt_len = mbuf->data_len;

		mk_act_open_req(f, mbuf,
				((adapter->sge.fw_evtq.abs_id << 14) | atid),
				adapter);
	}

	f->pending = 1;
	t4_mgmt_tx(ctrlq, mbuf);
	return 0;

free_atid:
	cxgbe_free_atid(t, atid);

out_err:
	clear_filter(f);
	t4_os_free(f);
	return ret;
}
/**
 * Set the specified hash filter.
 */
Set the specified hash filter.
Set the specified hash filter .
static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
				 struct ch_filter_specification *fs,
				 struct filter_ctx *ctx)
{
	struct port_info *pi = ethdev2pinfo(dev);
	struct adapter *adapter = pi->adapter;
	struct tid_info *t = &adapter->tids;
	struct filter_entry *f;
	struct rte_mbuf *mbuf;
	struct sge_ctrl_txq *ctrlq;
	unsigned int iq;
	int atid, size;
	int ret = 0;
	ret = cxgbe_validate_filter(adapter, fs);
	if (ret)
		return ret;
	iq = get_filter_steerq(dev, fs);
	ctrlq = &adapter->sge.ctrlq[pi->port_id];
	f = t4_os_alloc(sizeof(*f));
	if (!f)
		return -ENOMEM;
	f->fs = *fs;
	f->ctx = ctx;
	f->dev = dev;
	f->fs.iq = iq;
	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 (f->fs.newdmac || f->fs.newvlan == VLAN_INSERT ||
	    f->fs.newvlan == VLAN_REWRITE) {
		f->l2t = cxgbe_l2t_alloc_switching(dev, f->fs.vlan,
						   f->fs.eport, f->fs.dmac);
		if (!f->l2t) {
			ret = -ENOMEM;
			goto out_err;
		}
	}
	if (f->fs.newsmac) {
		f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac);
		if (!f->smt) {
			ret = -EAGAIN;
			goto out_err;
		}
	}
	atid = cxgbe_alloc_atid(t, f);
	if (atid < 0)
		goto out_err;
	if (f->fs.type == FILTER_TYPE_IPV6) {
		f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
		if (!f->clipt)
			goto free_atid;
		size = sizeof(struct cpl_t6_act_open_req6);
		mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
		if (!mbuf) {
			ret = -ENOMEM;
			goto free_atid;
		}
		mbuf->data_len = size;
		mbuf->pkt_len = mbuf->data_len;
		mk_act_open_req6(f, mbuf,
				 ((adapter->sge.fw_evtq.abs_id << 14) | atid),
				 adapter);
	} else {
		size = sizeof(struct cpl_t6_act_open_req);
		mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
		if (!mbuf) {
			ret = -ENOMEM;
			goto free_atid;
		}
		mbuf->data_len = size;
		mbuf->pkt_len = mbuf->data_len;
		mk_act_open_req(f, mbuf,
				((adapter->sge.fw_evtq.abs_id << 14) | atid),
				adapter);
	}
	f->pending = 1;
	t4_mgmt_tx(ctrlq, mbuf);
	return 0;
free_atid:
	cxgbe_free_atid(t, atid);
out_err:
	clear_filter(f);
	t4_os_free(f);
	return ret;
}
static int cxgbe_set_hash_filter ( struct rte_eth_dev * dev , struct ch_filter_specification * fs , struct filter_ctx * ctx ) { struct port_info * pi = ethdev2pinfo ( dev ) ; struct adapter * adapter = pi -> adapter ; struct tid_info * t = & adapter -> tids ; struct filter_entry * f ; struct rte_mbuf * mbuf ; struct sge_ctrl_txq * ctrlq ; unsigned int iq ; int atid , size ; int ret = 0 ; ret = cxgbe_validate_filter ( adapter , fs ) ; if ( ret ) return ret ; iq = get_filter_steerq ( dev , fs ) ; ctrlq = & adapter -> sge . ctrlq [ pi -> port_id ] ; f = t4_os_alloc ( sizeof ( * f ) ) ; if ( ! f ) return - ENOMEM ; f -> fs = * fs ; f -> ctx = ctx ; f -> dev = dev ; f -> fs . iq = iq ; 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 ( f -> fs . newdmac || f -> fs . newvlan == VLAN_INSERT || f -> fs . newvlan == VLAN_REWRITE ) { f -> l2t = cxgbe_l2t_alloc_switching ( dev , f -> fs . vlan , f -> fs . eport , f -> fs . dmac ) ; if ( ! f -> l2t ) { ret = - ENOMEM ; goto out_err ; } } if ( f -> fs . newsmac ) { f -> smt = cxgbe_smt_alloc_switching ( f -> dev , f -> fs . smac ) ; if ( ! f -> smt ) { ret = - EAGAIN ; goto out_err ; } } atid = cxgbe_alloc_atid ( t , f ) ; if ( atid < 0 ) goto out_err ; if ( f -> fs . type == FILTER_TYPE_IPV6 ) { f -> clipt = cxgbe_clip_alloc ( f -> dev , ( u32 * ) & f -> fs . val . lip ) ; if ( ! f -> clipt ) goto free_atid ; size = sizeof ( struct cpl_t6_act_open_req6 ) ; mbuf = rte_pktmbuf_alloc ( ctrlq -> mb_pool ) ; if ( ! mbuf ) { ret = - ENOMEM ; goto free_atid ; } mbuf -> data_len = size ; mbuf -> pkt_len = mbuf -> data_len ; mk_act_open_req6 ( f , mbuf , ( ( adapter -> sge . fw_evtq . abs_id << 14 ) | atid ) , adapter ) ; } else { size = sizeof ( struct cpl_t6_act_open_req ) ; mbuf = rte_pktmbuf_alloc ( ctrlq -> mb_pool ) ; if ( ! mbuf ) { ret = - ENOMEM ; goto free_atid ; } mbuf -> data_len = size ; mbuf -> pkt_len = mbuf -> data_len ; mk_act_open_req ( f , mbuf , ( ( adapter -> sge . fw_evtq . abs_id << 14 ) | atid ) , adapter ) ; } f -> pending = 1 ; t4_mgmt_tx ( ctrlq , mbuf ) ; return 0 ; free_atid : cxgbe_free_atid ( t , atid ) ; out_err : clear_filter ( f ) ; t4_os_free ( f ) ; return ret ; }
Set the specified hash filter.
Set the specified hash filter .
/* Allocate MPS TCAM entry to match Destination MAC. */ /*
	 * 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.
	 */ /* allocate L2T entry for new filter */ /* If the new filter requires Source MAC rewriting then we need to
	 * allocate a SMT entry for the filter
	 */ /* IPv6 hash filter */ /* IPv4 hash filter */