作者
QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118
参考
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)寄存器,
函数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>