[...]
> +static inline unsigned char * > +i40e_find_available_buffer(struct rte_eth_dev *dev) > +{ > + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); > + struct i40e_fdir_info *fdir_info = &pf->fdir; > + struct i40e_tx_queue *txq = pf->fdir.txq; > + volatile struct i40e_tx_desc *txdp = &txq->tx_ring[txq->tx_tail + 1]; > + uint32_t i; > + > + /* no available buffer > + * search for more available buffers from the current > + * descriptor, until an unavailable one > + */ > + if (fdir_info->txq_available_buf_count <= 0) { > + uint16_t tmp_tail; > + volatile struct i40e_tx_desc *tmp_txdp; > + > + tmp_tail = txq->tx_tail; > + tmp_txdp = &txq->tx_ring[tmp_tail + 1]; > + > + do { > + if ((tmp_txdp->cmd_type_offset_bsz & > + > rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) == > + > rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) > + fdir_info->txq_available_buf_count++; > + else > + break; > + > + tmp_tail += 2; > + if (tmp_tail >= txq->nb_tx_desc) > + tmp_tail = 0; > + } while (tmp_tail != txq->tx_tail); > + } > + > + /* > + * if txq_available_buf_count > 0, just use the next one is ok, > + * else wait for the next DD until it's set to make sure the data > + * had been fetched by hardware > + */ > + if (fdir_info->txq_available_buf_count > 0) { > + fdir_info->txq_available_buf_count--; > + } else { > + /* wait until the tx descriptor is ready */ > + for (i = 0; i < I40E_FDIR_MAX_WAIT_US; i++) { > + if ((txdp->cmd_type_offset_bsz & > + > rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) == > + > rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) > + break; > + rte_delay_us(1); > + } > + if (i >= I40E_FDIR_MAX_WAIT_US) { > + PMD_DRV_LOG(ERR, > + "Failed to program FDIR filter: time out to get DD > on tx > queue."); > + return NULL; > + } > + } Why wait for I40E_FDIR_MAX_WAIT_US but not return NULL immediately? [...] > i40e_flow_fdir_filter_programming(struct i40e_pf *pf, > enum i40e_filter_pctype pctype, > const struct i40e_fdir_filter_conf *filter, > - bool add) > + bool add, bool wait_status) > { > struct i40e_tx_queue *txq = pf->fdir.txq; > struct i40e_rx_queue *rxq = pf->fdir.rxq; > @@ -2011,8 +2092,10 @@ i40e_flow_fdir_filter_programming(struct i40e_pf *pf, > volatile struct i40e_tx_desc *txdp; > volatile struct i40e_filter_program_desc *fdirdp; > uint32_t td_cmd; > - uint16_t vsi_id, i; > + uint16_t vsi_id; > uint8_t dest; > + uint32_t i; > + uint8_t retry_count = 0; > > PMD_DRV_LOG(INFO, "filling filter programming descriptor."); > fdirdp = (volatile struct i40e_filter_program_desc *) > @@ -2087,7 +2170,8 @@ i40e_flow_fdir_filter_programming(struct i40e_pf *pf, > > PMD_DRV_LOG(INFO, "filling transmit descriptor."); > txdp = &txq->tx_ring[txq->tx_tail + 1]; > - txdp->buffer_addr = rte_cpu_to_le_64(pf->fdir.dma_addr); > + txdp->buffer_addr = rte_cpu_to_le_64(pf->fdir.dma_addr[txq->tx_tail / > 2]); > + [txq->tx_tail / 2] is not readable, how about use the avail pkt you get directly? Or another index to identify it? > td_cmd = I40E_TX_DESC_CMD_EOP | > I40E_TX_DESC_CMD_RS | > I40E_TX_DESC_CMD_DUMMY; > @@ -2100,25 +2184,34 @@ i40e_flow_fdir_filter_programming(struct i40e_pf *pf, > txq->tx_tail = 0; > /* Update the tx tail register */ > rte_wmb(); > + > + /* capture the previous error report(if any) from rx ring */ > + while ((i40e_check_fdir_programming_status(rxq) < 0) && > + (++retry_count < 100)) > + PMD_DRV_LOG(INFO, "previous error report captured."); > + Why check FDIR ring for 100 times? And "&&" is used here, the log is only print if the 100th check fails? > > -- > 2.17.1