<div dir="ltr">Hello,<br><br>I am trying to operate a Broadcom BCM57414 2x10G nic using dpdk bnxt pmd. I use DPDK 22.11.<br>However,
 doing so I stumbled over a number of different issues. Mainly, using 
the dpdk rte_eth library, I don't seem to be able to correctly poll the 
link status: I expect my nic has a problem using autoneg to set the link
 speed/duplex, because these parameters remain unknown while autoneg is 
on. However, after trying to set link up, instead of showing the link 
state as down, I see the link being up, which is in truth not the case, 
as
 no packets can transit on the line and the switch at the other end sees
 it down.<br><br>When searching around and trying to debug the code, I found the function bnxt_dev_info_get_op() sets my nic in interrupt mode:<br><br> > eth_dev->data->dev_conf.intr_conf.lsc = 1;<br><br>Which is a bit of a surprising thing to do for a function meant to get info. <br>Thus
 my card ends up working in a mode I didn't configure it to, which may 
be the cause of my issue: later when setting the link up in function 
bnxt_dev_set_link_up_op():<br><div><br></div><div>>  if (!bp->link_info->link_up)<br>             >     rc = bnxt_set_hwrm_link_config(bp, true);</div>      >  if (!rc)<br>       >     eth_dev->data->dev_link.link_status = 1;<br><br>So
 link_status in eth_dev gets set to 1 as long as the operation did not 
return any error code. This is the case when setting my card's link up 
(rc=0), although the link clearly can't get up, for whatever other bug 
is present. Now this shouldn't be much of an issue given we will update 
the link status at some point, mainly in rte_eth_link_get_nowait():<br><br> >  if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)<br>   >     rte_eth_linkstatus_get(dev, eth_link);<br>    >  else {<br> >     if (*dev->dev_ops->link_update == NULL)<br>     >         return -ENOTSUP;<br>  >     (*dev->dev_ops->link_update)(dev, 0);<br>       >      *eth_link = dev->data->dev_link;<br><br>Here
 we can see in the else statement that the link status gets updated. 
However because the pmd auto-configured the nic in interrupt mode when 
calling the get_info function, we are not going through that else 
statement. So when reading the value of the link_status, we read 1 
instead of 0. I suppose with interrupt mode enabled, the nic should be 
able to update this variable on its own, but it is clearly not the case 
in my setup: link status is never updated and incorrectly indicates the 
link is UP.<br><br>I can suggest a testpmd reproduction setup using the 
--no-lsc-interrupt option. With this option, dev_conf.intr_conf.lsc 
should be 0. In addition, I added a log to the rte_eth library in 
rte_eth_dev_start() to display dev_conf.intr_conf.lsc state when 
starting the port:<br><br>  > + RTE_ETHDEV_LOG(ERR, "><><><><!!<devstart>: dev->data->dev_conf.intr_conf=%d\n", dev->data->dev_conf.intr_conf.lsc);<br>        >   diag = (*dev->dev_ops->dev_start)(dev);<br><br>Running testpmd, we can see the following outpout when starting port:<br><br>dpdk-testpmd --log-level=pmd.net.bnxt.driver:8 -a 0000:02:00.0 -a 0000:02:00.1 -- -i --rxq=2 --txq=2 --coremask=0x0c --total-num-mbufs=250000 --no-lsc-interrupt<br>[...]<br>Configuring Port 0 (socket 0)<br>bnxt_rx_queue_setup_op(): App supplied RXQ drop_en status : 1<br>bnxt_rx_queue_setup_op(): RX Buf MTU 1500<br>bnxt_rx_queue_setup_op(): RX Buf size is 9728<br>bnxt_rx_queue_setup_op(): App supplied RXQ drop_en status : 1<br>bnxt_rx_queue_setup_op(): RX Buf MTU 1500<br>bnxt_rx_queue_setup_op(): RX Buf size is 9728<br>><><><><!!<devstart>: dev->data->dev_conf.intr_conf=1<br>bnxt_mq_rx_configure(): pools = 1 nb_q_per_grp = 2<br>bnxt_mq_rx_configure(): rxq[0] = 0x105fb7ac0 vnic[0] = 0x100227080<br>bnxt_mq_rx_configure(): rxq[1] = 0x105fb0e40 vnic[0] = 0x100227080<br>bnxt_setup_one_vnic(): vnic[0] = 0x100227080 vnic->fw_grp_ids = 0x105fa7e00<br>bnxt_hwrm_vnic_alloc(): Alloc VNIC. Start 0, End 2<br>bnxt_hwrm_vnic_alloc(): VNIC ID 2<br>bnxt_setup_one_vnic(): rxq[0]->vnic=0x100227080 vnic->fw_grp_ids=0x105fa7e00<br>bnxt_setup_one_vnic(): rxq[1]->vnic=0x100227080 vnic->fw_grp_ids=0x105fa7e00<br>bnxt_setup_one_vnic(): vnic->rx_queue_cnt = 2<br>bnxt_hwrm_port_phy_qcfg(): Link Speed:0,Auto:4:64:140,Support:140,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Signal:0,PAM::Auto:0,Support:0,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Speed:0,Auto:4:64:140,Support:140,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Signal:0,PAM::Auto:0,Support:0,Force:0<br>bnxt_ulp_port_init(): Skip ulp init for port: 0, TF is not enabled<br>bnxt_receive_function(): Using SSE vector mode receive for port 0<br>bnxt_transmit_function(): Using SSE vector mode transmit for port 0<br>Port 0: 00:0A:F7:B6:E3:D0<br>Configuring Port 1 (socket 0)<br>bnxt_rx_queue_setup_op(): App supplied RXQ drop_en status : 1<br>bnxt_rx_queue_setup_op(): RX Buf MTU 1500<br>bnxt_rx_queue_setup_op(): RX Buf size is 9728<br>bnxt_rx_queue_setup_op(): App supplied RXQ drop_en status : 1<br>bnxt_rx_queue_setup_op(): RX Buf MTU 1500<br>bnxt_rx_queue_setup_op(): RX Buf size is 9728<br>><><><><!!<devstart>: dev->data->dev_conf.intr_conf=1<br>bnxt_mq_rx_configure(): pools = 1 nb_q_per_grp = 2<br>bnxt_mq_rx_configure(): rxq[0] = 0x106200280 vnic[0] = 0x100200080<br>bnxt_mq_rx_configure(): rxq[1] = 0x105f10e40 vnic[0] = 0x100200080<br>bnxt_setup_one_vnic(): vnic[0] = 0x100200080 vnic->fw_grp_ids = 0x105f07e00<br>bnxt_hwrm_vnic_alloc(): Alloc VNIC. Start 0, End 2<br>bnxt_hwrm_vnic_alloc(): VNIC ID 3<br>bnxt_setup_one_vnic(): rxq[0]->vnic=0x100200080 vnic->fw_grp_ids=0x105f07e00<br>bnxt_setup_one_vnic(): rxq[1]->vnic=0x100200080 vnic->fw_grp_ids=0x105f07e00<br>bnxt_setup_one_vnic(): vnic->rx_queue_cnt = 2<br>bnxt_hwrm_port_phy_qcfg(): Link Speed:0,Auto:4:64:140,Support:140,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Signal:0,PAM::Auto:0,Support:0,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Speed:0,Auto:4:64:140,Support:140,Force:0<br>bnxt_hwrm_port_phy_qcfg(): Link Signal:0,PAM::Auto:0,Support:0,Force:0<br>bnxt_ulp_port_init(): Skip ulp init for port: 1, TF is not enabled<br>bnxt_receive_function(): Using SSE vector mode receive for port 1<br>bnxt_transmit_function(): Using SSE vector mode transmit for port 1<br>Port 1: 00:0A:F7:B6:E3:D1<br><br>Here,
 we can see that lsc interrupts are enabled even though we specified not
 to enable them. Then given autoneg does not work on my nic, I can try 
setting the link up and showing port info:<br><br>testpmd> set link-up port 0<br>bnxt_print_link_info(): Port 0 Link Up - speed 0 Mbps - half-duplex<br><br>testpmd> show port info 0<br><br>********************* Infos for port 0  *********************<br>MAC address: 00:0A:F7:B6:E3:D0<br>Device name: 0000:02:00.0<br>Driver name: net_bnxt<br>Firmware-version: 223.0.161.0<br>Devargs: <br>Connect to socket: 0<br>memory allocation on the socket: 0<br>Link status: up<br>Link speed: None<br>Link duplex: half-duplex<br>Autoneg status: Off<br>MTU: 1500<br>Promiscuous mode: enabled<br>Allmulticast mode: disabled<br>Maximum number of MAC addresses: 128<br>Maximum number of MAC addresses of hash filtering: 0<br>VLAN offload: <br>  strip off, filter off, extend off, qinq strip off<br>Hash key size in bytes: 40<br>Redirection table size: 128<br>Supported RSS offload flow types:<br>  ipv4  ipv4-tcp  ipv4-udp  ipv6  ipv6-tcp  ipv6-udp<br>  user-defined-50  user-defined-51<br>Minimum size of RX buffer: 1<br>Maximum configurable length of RX packet: 9600<br>Maximum configurable size of LRO aggregated packet: 0<br>Maximum number of VMDq pools: 64<br>Current number of RX queues: 2<br>Max possible RX queues: 117<br>Max possible number of RXDs per queue: 8192<br>Min possible number of RXDs per queue: 16<br>RXDs number alignment: 1<br>Current number of TX queues: 2<br>Max possible TX queues: 117<br>Max possible number of TXDs per queue: 4096<br>Min possible number of TXDs per queue: 16<br>TXDs number alignment: 1<br>Max segment number per packet: 65535<br>Max segment number per MTU/TSO: 65535<br>Device capabilities: 0x3( RUNTIME_RX_QUEUE_SETUP RUNTIME_TX_QUEUE_SETUP )<br>Switch name: 0000:02:00.0<br>Switch domain Id: 0<br>Switch Port Id: 32768<br>Device error handling mode: proactive<br><br>This shows link status is seen as up, even although link speed is None.<br><br>I
 was wondering if patching the code to move this line which sets lsc 
interrupt on somewhere else might be reasonable, or if this could cause further trouble. Maybe having a parameter to trigger it ON/OFF might be a
 good addition.<br>May I have your opinion on this matter?<br><br>Sincerely,<br>Edwin Brossette</div>