NXP(Freescale) QorIQ T2080 SRIO FRA程序分析

作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

A problem of sending SRIO doorbell, message by T2080

FRA

doorbell收发,新建fra配置文件,rman_cfg为默认配置,trans_cfg的type字段为Doorbell,flowlvl表示flow level为5,dists_cfg定义rman处理的消息,RMAN_RX和RMAN_TX,sid定义源id,did 定义目的id

<fra_cfg>
<!--	xxxxxxxxxxxxxxxxxxxx RMan hardware configuration xxxxxxxxxxxxxxxxxxx -->
	<rman_cfg>
		<defcfg file="/usr/etc/rman_config.xml"/>
	</rman_cfg>

<!--	transaction field described all the type transaction settings -->

	<trans_cfg>
		<!-- dbell setting -->
		<transaction name="dbell-peer" type="Doorbell">
			<flowlvl value="5" mask="1"/>
		</transaction>
	</trans_cfg>

	<dists_cfg>
<!--	xxxxxxxxxxxxxxxxxxxxxx RMAN RX distribution xxxxxxxxxxxxxxxxxxxxxxxx -->
		<distribution name="dbell_from_peer" type="RMAN_RX">
			<rio_port number="0" mask="1"/>
			<sid value="0x11" mask="0xff"/>
			<queue base="0x4100" mode="direct" wq="0"/>
			<transactionref name="dbell-peer"/>
		</distribution>

<!--	xxxxxxxxxxxxxxxxxxxxxxx RMAN TX distribution xxxxxxxxxxxxxxxxxxxxxxx -->
		<distribution name="dbell_to_peer" type="RMAN_TX">
			<rio_port number="0"/>
			<did value="0x11"/>
			<queue base="0x4200" count="4" wq="0"/>
			<transactionref name="dbell-peer"/>
		</distribution>
	</dists_cfg>

<!--	xxxxxxxxxxxxxxxxxxxxxxxxxx Policy xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
	<policies_cfg>
		<policy name="peer-srio-peer" enable="yes">
			<dist_order>
				<distributionref name="dbell_to_peer"/>
				<distributionref name="dbell_from_peer"/>
			</dist_order>
		</policy>
	</policies_cfg>
</fra_cfg>

看一下rman_config.xml

<rman_cfg>
	<fqbits type="Data-streaming" value="2"/>
	<fqbits type="Mailbox" value="2"/>
	<md_create mode="yes"/>
	<!--
	OSID - Outbound Segmentation Interleaving Disable
	Segmentation interleaving allows the message manager to
	interleave segments from two or more transactions with the
	same destination device ID (regardless of type). This may
	increase performance for transmission but may also consume
	additional reassembly resources at the destination.

	A non-Freescale target device may not complete Type 9
	reassembly correctly when segmentation interleaving is
	performed on two PDUs with the same flow but different CoS.
	Workaround: disable segmentation interleaving by setting
	<osid value="yes">
	-->
	<osid value="no"/>
	<efq value="yes"/>
	<bpid type="Data-streaming" value="11"/>
	<bpid type="Doorbell" value="10"/>
	<bpid type="Mailbox" value="11"/>
	<sgbpid value="12"/>
</rman_cfg>

fq_bit是做什么的呢,

//build_t2080rdb-64b\tmp\work\t2080rdb_64b-fsl-linux\usdpaa\git-r4\git\src\rman\rman_driver.c line181
int rman_dev_config(struct rman_dev *rmdev, const struct rman_cfg *cfg)
{
	uint32_t mmmr;

	if (!rmdev || !rmdev->global_regs || !cfg)
		return -EINVAL;

	mmmr = read_reg(&rmdev->global_regs->mmmr);
	/* Set inbound message descriptor write status */
	mmmr &= ~(1 << RMAN_MMMR_MDD_SHIFT);
	mmmr |= cfg->md_create << RMAN_MMMR_MDD_SHIFT;
	/* Set OSID */
	mmmr &= ~(1 << RMAN_MMMR_OSID_SHIFT);
	mmmr |= cfg->osid << RMAN_MMMR_OSID_SHIFT;
	/* Set EFQ */
	mmmr &= ~(1 << RMAN_MMMR_EFQ_SHIFT);
	mmmr |= cfg->efq << RMAN_MMMR_EFQ_SHIFT;
	write_reg(&rmdev->global_regs->mmmr, mmmr);

	/* Initialize the frame queue assembly register */
	/* Data streaming supports max 32 inbound frame queues */
	write_reg(&rmdev->global_regs->mmt9fqar,
		  cfg->fq_bits[RIO_TYPE9] << RMAN_FQAR_STID_SHIFT);
	/* Doorbell supports max 1 inbound frame queues */
	write_reg(&rmdev->global_regs->mmt10fqar, 0);
	/* Mailbox supports max 4 inbound frame queues */
	write_reg(&rmdev->global_regs->mmt11fqar,
		  cfg->fq_bits[RIO_TYPE11] << RMAN_FQAR_LTR_SHIFT);

	return 0;
}

FRA只支持SRIO TYPE 8~11四种类型,

//build_t2080rdb-64b\tmp\work\t2080rdb_64b-fsl-linux\usdpaa\git-r4\git\include\usdpaa\fsl_rman_ib.h line37
enum RIO_TYPE {
	RIO_TYPE0 = 0,
	RIO_TYPE1,
	RIO_TYPE2,
	RIO_TYPE3,
	RIO_TYPE4,
	RIO_TYPE5,
	RIO_TYPE6,
	RIO_TYPE7,
	RIO_TYPE8,
	RIO_TYPE9,
	RIO_TYPE10,
	RIO_TYPE11,
	RIO_TYPE_NUM,
	RIO_TYPE_PW = RIO_TYPE8,
	RIO_TYPE_DSTR = RIO_TYPE9,
	RIO_TYPE_DBELL = RIO_TYPE10,
	RIO_TYPE_MBOX = RIO_TYPE11
};
//build_t2080rdb-64b\tmp\work\t2080rdb_64b-fsl-linux\usdpaa-apps\git-r0\git\src\fra\lib\fra_cfg_parser\fra_cfg_parser.c line267
static int parse_tran(xmlNodePtr tran_node, struct list_head *list)
{
	char *name;
	char *type;
	xmlNodePtr tranp;
	struct rio_tran *tran;

	if (!tran_node)
		return -EINVAL;

	name = get_attributes(tran_node, BAD_CAST TRAN_NAME);
	search_member(tran, name, list);
	if (!tran) {
		tran = malloc(sizeof(*tran));
		if (!tran)
			return -ENOMEM;
		memset(tran, 0, sizeof(*tran));
		snprintf(tran->name, sizeof(tran->name), "%s",  name);
		type = get_attributes(tran_node, BAD_CAST TRAN_TYPE);
		tran->type = rio_type_str_to_idx(type);
		list_add_tail(&tran->node, list);
	}

	/* Update tran configuration */
	tranp = tran_node->xmlChildrenNode;
	switch (tran->type) {
	case RIO_TYPE_DBELL:
	case RIO_TYPE_PW:
		for_all_sibling_nodes(tranp) {
			if ((is_node(tranp, BAD_CAST TRAN_FLOWLVL_NODE))) {
				tran_parse_element(tranp, tran->flowlvl,
					tran->flowlvl_mask);
			}
		}
		break;
	case RIO_TYPE_MBOX:
		for_all_sibling_nodes(tranp) {
			if ((is_node(tranp, BAD_CAST TRAN_FLOWLVL_NODE)))
				tran_parse_element(tranp, tran->flowlvl,
						tran->flowlvl_mask);
			else if ((is_node(tranp, BAD_CAST TRAN_MBOX_NODE)))
				tran_parse_element(tranp, tran->mbox.mbox,
						tran->mbox.mbox_mask);
			else if ((is_node(tranp, BAD_CAST TRAN_LTR_NODE)))
				tran_parse_element(tranp, tran->mbox.ltr,
						tran->mbox.ltr_mask);
			else if ((is_node(tranp, BAD_CAST TRAN_MSGLEN_NODE)))
				tran_parse_element(tranp, tran->mbox.msglen,
						tran->mbox.msglen_mask);
		}
		break;
	case RIO_TYPE_DSTR:
		for_all_sibling_nodes(tranp) {
			if ((is_node(tranp, BAD_CAST TRAN_FLOWLVL_NODE)))
				tran_parse_element(tranp, tran->flowlvl,
					tran->flowlvl_mask);
			else if ((is_node(tranp, BAD_CAST TRAN_COS_NODE)))
				tran_parse_element(tranp, tran->dstr.cos,
					tran->dstr.cos_mask);
			else if ((is_node(tranp, BAD_CAST TRAN_STREAMID_NODE)))
				tran_parse_element(tranp,
					tran->dstr.streamid,
					tran->dstr.streamid_mask);
		}
		break;
	default:
		error(0, 0, "transaction %s has an invalid type %s",
		      tran->name, RIO_TYPE_TO_STR[tran->type]);
		return -ENXIO;
	}
	return 0;
}

FRA配置文件里有两个Mask<flowlvl value="5" mask="1"/><sid value="0x11" mask="0xff"/>,这需要查看ibcu(Inbound Block Classification Unit)寄存器,
131
函数rman_config_ibcu使用了上面的两个Mask,参考T2080DPAARM,可以看到这两个Mask都是对接收的包进行过滤分类用的,

int rman_config_ibcu(struct rman_inbound_block *ib,
			  const struct ibcu_cfg *cfg)
{
	int cu_index = cfg->ibcu;

	if (ib->cu[cu_index].status != IBCU_STATUS_READY) {
		error(0, EINVAL, "RMan: please firstly request an ibcu");
		return -EINVAL;
	}

	write_reg(&ib->cu[cu_index].cu_regs->fqr, cfg->fqid);
	write_reg(&ib->cu[cu_index].cu_regs->rvr[0],
		  cfg->sid << 16 | cfg->did);
	write_reg(&ib->cu[cu_index].cu_regs->rmr[0],
		  cfg->sid_mask << 16 | cfg->did_mask);
	switch (cfg->tran->type) {
	case RIO_TYPE_DBELL:
	case RIO_TYPE_PW:
		write_reg(&ib->cu[cu_index].cu_regs->rvr[1],
			  cfg->tran->flowlvl << 28 |
			  cfg->port << 24);
		write_reg(&ib->cu[cu_index].cu_regs->rmr[1],
			  cfg->tran->flowlvl_mask << 28 |
			  cfg->port_mask << 24);
		write_reg(&ib->cu[cu_index].cu_regs->dbpr,
			  (cfg->msgsize << 16) | cfg->bpid);
		write_reg(&ib->cu[cu_index].cu_regs->dor,
			  cfg->data_offset);
		break;
	case RIO_TYPE_MBOX:
		write_reg(&ib->cu[cu_index].cu_regs->rvr[1],
			  cfg->tran->flowlvl << 28 |
			  cfg->port << 24 |
			  cfg->tran->mbox.msglen << 8 |
			  cfg->tran->mbox.ltr << 6 |
			  cfg->tran->mbox.mbox);
		write_reg(&ib->cu[cu_index].cu_regs->rmr[1],
			  cfg->tran->flowlvl_mask << 28 |
			  cfg->port_mask << 24 |
			  cfg->tran->mbox.msglen_mask << 8 |
			  cfg->tran->mbox.ltr_mask << 6 |
			  cfg->tran->mbox.mbox_mask);
		write_reg(&ib->cu[cu_index].cu_regs->dbpr,
			  (cfg->msgsize << 16) | cfg->bpid);
		write_reg(&ib->cu[cu_index].cu_regs->dor,
			  cfg->data_offset);
		break;
	case RIO_TYPE_DSTR:
		write_reg(&ib->cu[cu_index].cu_regs->rvr[1],
			  cfg->tran->flowlvl << 28 |
			  cfg->port << 24 |
			  cfg->tran->dstr.cos << 16 |
			  cfg->tran->dstr.streamid);
		write_reg(&ib->cu[cu_index].cu_regs->rmr[1],
			  cfg->tran->flowlvl_mask << 28 |
			  cfg->port_mask << 24 |
			  cfg->tran->dstr.cos_mask << 16 |
			  cfg->tran->dstr.streamid_mask);
		write_reg(&ib->cu[cu_index].cu_regs->t9fcdr,
			  cfg->fcdr << 16 |
			  cfg->fcdr);
		write_reg(&ib->cu[cu_index].cu_regs->dbpr,
			  (cfg->msgsize << 16) | cfg->bpid);
		write_reg(&ib->cu[cu_index].cu_regs->t9sgbpr,
			  (cfg->sgsize << 16) | cfg->sgbpid);
		write_reg(&ib->cu[cu_index].cu_regs->dor,
			  cfg->data_offset);
		break;
	default:
		return -EINVAL;
	}
	write_reg(&ib->cu[cu_index].cu_regs->mr,
		  cfg->fq_mode << 28 |
		  cfg->tran->type << 24 |
		  cfg->ext << 23 |
		  cfg->cgn);

	return 0;
}

测试

root@t2080rdb:~# fra
Found /fsl,dpaa/ethernet@0, Tx Channel = 802, FMAN = 0, Port ID = 1
Found /fsl,dpaa/ethernet@1, Tx Channel = 803, FMAN = 0, Port ID = 2
Found /fsl,dpaa/ethernet@2, Tx Channel = 804, FMAN = 0, Port ID = 3
Found /fsl,dpaa/ethernet@3, Tx Channel = 805, FMAN = 0, Port ID = 4
Found /fsl,dpaa/ethernet@8, Tx Channel = 800, FMAN = 0, Port ID = 9
Found /fsl,dpaa/ethernet@9, Tx Channel = 801, FMAN = 0, Port ID = a
QMan: Allocated lookup table at 0x3fff9409f010, entry count 32769
Configuring for 2 network interfaces
BPOOL: Release 8192 bufs to BPID 9
BPOOL: Release 256 bufs to BPID 10
BPOOL: Release 8192 bufs to BPID 11
BPOOL: Release 8192 bufs to BPID 12
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Thread uid:0 alive (on cpu 1)
fra> q
Thread uid:0 killed (cpu 1)

修改设备树使用部分网口为usdpaa,或者请使用rman only模式,

<cfgdata>
        <config>
                <engine name="fm0">
                        <port type="MAC" number="1" policy="fm_policy_1"/>
                        <port type="MAC" number="2" policy="fm_policy_2"/>
                </engine>
        </config>
</cfgdata>

测试fra,

root@t2080rdb:~# fra -c config_srio.xml -p policy_ipv4.xml -f fra_config_mbox_processing1.xml 
Found /fsl,dpaa/ethernet@0, Tx Channel = 802, FMAN = 0, Port ID = 1
Found /fsl,dpaa/ethernet@1, Tx Channel = 803, FMAN = 0, Port ID = 2
QMan: Allocated lookup table at 0x3fffb244f010, entry count 32769
Configuring for 2 network interfaces
warn: drained 8192 bufs from BPID 9
BPOOL: Release 8192 bufs to BPID 9
warn: drained 256 bufs from BPID 10
BPOOL: Release 256 bufs to BPID 10
warn: drained 8192 bufs from BPID 11
BPOOL: Release 8192 bufs to BPID 11
warn: drained 8192 bufs from BPID 12
BPOOL: Release 8192 bufs to BPID 12
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Port 1 is not ready.
Try to restart connection...
fra: fsl_srio_connection(): Input/output error
fra: SRIO port0 is not connected
Thread uid:0 alive (on cpu 1)
fra> 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值