/* When the hardware/firmware supports additional capabilities, * additional header is filled-in by Octeon after length field in * Rx packets. this header contains additional packet information.
*/ if (oct->fw_info.rx_ol_flags)
oq->max_single_buffer_size -= OCTEP_VF_OQ_RESP_HW_EXT_SIZE;
/** * octep_vf_setup_oqs() - setup resources for all Rx queues. * * @oct: Octeon device private data structure.
*/ int octep_vf_setup_oqs(struct octep_vf_device *oct)
{ int i, retval = 0;
oct->num_oqs = 0; for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) {
retval = octep_vf_setup_oq(oct, i); if (retval) {
dev_err(&oct->pdev->dev, "Failed to setup OQ(RxQ)-%d.\n", i); goto oq_setup_err;
}
dev_dbg(&oct->pdev->dev, "Successfully setup OQ(RxQ)-%d.\n", i);
}
return 0;
oq_setup_err: while (i) {
i--;
octep_vf_free_oq(oct->oq[i]);
} return retval;
}
/** * octep_vf_oq_dbell_init() - Initialize Rx queue doorbell. * * @oct: Octeon device private data structure. * * Write number of descriptors to Rx queue doorbell register.
*/ void octep_vf_oq_dbell_init(struct octep_vf_device *oct)
{ int i;
for (i = 0; i < oct->num_oqs; i++)
writel(oct->oq[i]->max_count, oct->oq[i]->pkts_credit_reg);
}
/** * octep_vf_free_oqs() - Free resources of all Rx queues. * * @oct: Octeon device private data structure.
*/ void octep_vf_free_oqs(struct octep_vf_device *oct)
{ int i;
for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) { if (!oct->oq[i]) continue;
octep_vf_free_oq(oct->oq[i]);
dev_dbg(&oct->pdev->dev, "Successfully freed OQ(RxQ)-%d.\n", i);
}
}
/** * octep_vf_oq_check_hw_for_pkts() - Check for new Rx packets. * * @oct: Octeon device private data structure. * @oq: Octeon Rx queue data structure. * * Return: packets received after previous check.
*/ staticint octep_vf_oq_check_hw_for_pkts(struct octep_vf_device *oct, struct octep_vf_oq *oq)
{
u32 pkt_count, new_pkts;
/* Clear the hardware packets counter register if the rx queue is * being processed continuously with-in a single interrupt and * reached half its max value. * this counter is not cleared every time read, to save write cycles.
*/ if (unlikely(pkt_count > 0xF0000000U)) {
writel(pkt_count, oq->pkts_sent_reg);
pkt_count = readl(oq->pkts_sent_reg);
new_pkts += pkt_count;
}
oq->last_pkt_count = pkt_count;
oq->pkts_pending += new_pkts; return new_pkts;
}
/** * __octep_vf_oq_process_rx() - Process hardware Rx queue and push to stack. * * @oct: Octeon device private data structure. * @oq: Octeon Rx queue data structure. * @pkts_to_process: number of packets to be processed. * * Process the new packets in Rx queue. * Packets larger than single Rx buffer arrive in consecutive descriptors. * But, count returned by the API only accounts full packets, not fragments. * * Return: number of packets processed and pushed to stack.
*/ staticint __octep_vf_oq_process_rx(struct octep_vf_device *oct, struct octep_vf_oq *oq, u16 pkts_to_process)
{ struct octep_vf_oq_resp_hw_ext *resp_hw_ext = NULL;
netdev_features_t feat = oq->netdev->features; struct octep_vf_rx_buffer *buff_info; struct octep_vf_oq_resp_hw *resp_hw;
u32 pkt, rx_bytes, desc_used;
u16 data_offset, rx_ol_flags; struct sk_buff *skb;
u32 read_idx;
/** * octep_vf_oq_process_rx() - Process Rx queue. * * @oq: Octeon Rx queue data structure. * @budget: max number of packets can be processed in one invocation. * * Check for newly received packets and process them. * Keeps checking for new packets until budget is used or no new packets seen. * * Return: number of packets processed.
*/ int octep_vf_oq_process_rx(struct octep_vf_oq *oq, int budget)
{
u32 pkts_available, pkts_processed, total_pkts_processed; struct octep_vf_device *oct = oq->octep_vf_dev;
pkts_available = 0;
pkts_processed = 0;
total_pkts_processed = 0; while (total_pkts_processed < budget) { /* update pending count only when current one exhausted */ if (oq->pkts_pending == 0)
octep_vf_oq_check_hw_for_pkts(oct, oq);
pkts_available = min(budget - total_pkts_processed,
oq->pkts_pending); if (!pkts_available) break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.