Ejemplo n.º 1
0
static void _rhea_hasher_channel_register_set(struct rhea_channel *channel,
					      unsigned hash_bits)
{
	u64 reg = 0x0ULL;
	struct rhea_pport *pport;
	struct rhea_pport_bpfc *bpfc;

	if (NULL == channel)
		return;

	/* always get pport from channel */
	pport = _rhea_pport_get(channel->pport_nr);
	if (NULL == pport) {
		rhea_error("Invalid pport number");
		return;
	}

	if (NULL == channel->qpn) {
		rhea_error("Only the main channel ID can set the hasher");
		return;
	}

	bpfc = &pport->pport_regs->bpfc;

	/* reset number of used hash bits for all channels */
	switch (channel->type) {
	case HEA_UC_PORT:

		reg = in_be64(&bpfc->p_rcu);
		reg = hea_set_u64_bits(reg, hash_bits, 9, 11);
		out_be64(&bpfc->p_rcu, reg);
		break;

	case HEA_MC_PORT:

		reg = in_be64(&bpfc->p_rcm);
		reg = hea_set_u64_bits(reg, hash_bits, 9, 11);
		out_be64(&bpfc->p_rcm, reg);
		break;

	case HEA_BC_PORT:

		reg = in_be64(&bpfc->p_rcb);
		reg = hea_set_u64_bits(reg, hash_bits, 9, 11);
		out_be64(&bpfc->p_rcb, reg);
		break;

	default:

		if (0 <= channel->type - HEA_LPORT_0) {
			int lport_index = hea_lport_index_get(channel->type);

			reg = in_be64(&bpfc->pl_rc[lport_index]);
			reg = hea_set_u64_bits(reg, hash_bits, 9, 11);
			out_be64(&bpfc->pl_rc[lport_index], reg);
		}
		break;
	}
}
Ejemplo n.º 2
0
static int _rhea_tcam_register_set(struct rhea_channel *channel,
				   unsigned tcam_base,
				   unsigned tcam_offset,
				   unsigned qpn_offset,
				   unsigned pattern, unsigned mask)
{

	int rc = 0;
	unsigned tcam_index;
	unsigned qpn_index;
	u64 reg_pattern;
	u64 reg_mask;
	struct rhea_pport *pport;

	if (NULL == channel)
		return -EINVAL;

	if (NULL == channel->tcam || NULL == channel->qpn) {
		rhea_error("TCAM or QPN is not allocated");
		return -EINVAL;
	}

	pport = _rhea_pport_get(channel->pport_nr);
	if (NULL == pport) {
		rhea_error("Invalid pport number");
		return -EINVAL;
	}

	/* get the real index in the TCAM array */
	rc = _rhea_channel_resource_index_get(channel->tcam,
					      tcam_base, tcam_offset,
					      &tcam_index);
	if (rc) {
		rhea_error("Was not able to find index in TCAM map");
		return -EINVAL;
	}

	/* check if the offset is valid for this channel */
	rc = _rhea_channel_resource_index_get(channel->qpn,
					      channel->qpn_base, qpn_offset,
					      &qpn_index);
	if (rc) {
		rhea_error("Was not able to find index in QPN map");
		return -EINVAL;
	}

	reg_pattern = in_be64(&pport->pport_regs->bpfc.pg_tcampr[tcam_index]);
	reg_mask = in_be64(&pport->pport_regs->bpfc.pg_tcamm[tcam_index]);

	/* set pattern and mask */
	reg_pattern = hea_set_u64_bits(reg_pattern, pattern, 0, 31);
	reg_mask = hea_set_u64_bits(reg_mask, mask, 0, 31);

	/* configure LPORT or PPORT */
	switch (channel->type) {
	case HEA_BC_PORT:
	case HEA_MC_PORT:
	case HEA_UC_PORT:
		/* case UC_MC_HEA_BC_PORT: */

		/* is physical port */
		reg_pattern = hea_set_u64_bits(reg_pattern, 0, 48, 48);
		reg_mask = hea_set_u64_bits(reg_mask, 1, 48, 48);
		break;

	default:

		/* is logical port */
		reg_pattern = hea_set_u64_bits(reg_pattern, 1, 48, 48);
		reg_mask = hea_set_u64_bits(reg_mask, 1, 48, 48);
		break;
	}

	/* configure which channel type is using this TCAM */
	switch (channel->type) {
	case HEA_BC_PORT:
		reg_pattern = hea_set_u64_bits(reg_pattern, 1, 54, 55);
		reg_mask = hea_set_u64_bits(reg_mask, 3, 54, 55);
		break;

	case HEA_MC_PORT:
		reg_pattern = hea_set_u64_bits(reg_pattern, 2, 54, 55);
		reg_mask = hea_set_u64_bits(reg_mask, 3, 54, 55);
		break;

	case HEA_UC_PORT:
		reg_pattern = hea_set_u64_bits(reg_pattern, 3, 54, 55);
		reg_mask = hea_set_u64_bits(reg_mask, 3, 54, 55);
		break;

	default:
	    {
		int lport_index = hea_lport_index_get(channel->type);

		/* only allow one logical port at a time
		 * --> not all combinations are possible */
		reg_pattern =
			hea_set_u64_bits(reg_pattern, lport_index, 54, 55);
		reg_mask = hea_set_u64_bits(reg_mask, 3, 54, 55);
	    }
		break;
	}

	/* This is the offset from the QPN base to be used
	 * if the packet data matches the pattern */
	reg_pattern = hea_set_u64_bits(reg_pattern, qpn_offset, 59, 63);

	/* write back registers */
	out_be64(&pport->pport_regs->bpfc.pg_tcampr[tcam_index], reg_pattern);
	out_be64(&pport->pport_regs->bpfc.pg_tcamm[tcam_index], reg_mask);

	return rc;
}