|
@@ -1597,56 +1597,49 @@ next_cqe: /* don't consume bd rx buffer */
|
|
|
|
|
|
static int qede_poll(struct napi_struct *napi, int budget)
|
|
static int qede_poll(struct napi_struct *napi, int budget)
|
|
{
|
|
{
|
|
- int work_done = 0;
|
|
|
|
struct qede_fastpath *fp = container_of(napi, struct qede_fastpath,
|
|
struct qede_fastpath *fp = container_of(napi, struct qede_fastpath,
|
|
- napi);
|
|
|
|
|
|
+ napi);
|
|
struct qede_dev *edev = fp->edev;
|
|
struct qede_dev *edev = fp->edev;
|
|
|
|
+ int rx_work_done = 0;
|
|
|
|
+ u8 tc;
|
|
|
|
|
|
- while (1) {
|
|
|
|
- u8 tc;
|
|
|
|
-
|
|
|
|
- for (tc = 0; tc < edev->num_tc; tc++)
|
|
|
|
- if (qede_txq_has_work(&fp->txqs[tc]))
|
|
|
|
- qede_tx_int(edev, &fp->txqs[tc]);
|
|
|
|
-
|
|
|
|
- if (qede_has_rx_work(fp->rxq)) {
|
|
|
|
- work_done += qede_rx_int(fp, budget - work_done);
|
|
|
|
-
|
|
|
|
- /* must not complete if we consumed full budget */
|
|
|
|
- if (work_done >= budget)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ for (tc = 0; tc < edev->num_tc; tc++)
|
|
|
|
+ if (qede_txq_has_work(&fp->txqs[tc]))
|
|
|
|
+ qede_tx_int(edev, &fp->txqs[tc]);
|
|
|
|
+
|
|
|
|
+ rx_work_done = qede_has_rx_work(fp->rxq) ?
|
|
|
|
+ qede_rx_int(fp, budget) : 0;
|
|
|
|
+ if (rx_work_done < budget) {
|
|
|
|
+ qed_sb_update_sb_idx(fp->sb_info);
|
|
|
|
+ /* *_has_*_work() reads the status block,
|
|
|
|
+ * thus we need to ensure that status block indices
|
|
|
|
+ * have been actually read (qed_sb_update_sb_idx)
|
|
|
|
+ * prior to this check (*_has_*_work) so that
|
|
|
|
+ * we won't write the "newer" value of the status block
|
|
|
|
+ * to HW (if there was a DMA right after
|
|
|
|
+ * qede_has_rx_work and if there is no rmb, the memory
|
|
|
|
+ * reading (qed_sb_update_sb_idx) may be postponed
|
|
|
|
+ * to right before *_ack_sb). In this case there
|
|
|
|
+ * will never be another interrupt until there is
|
|
|
|
+ * another update of the status block, while there
|
|
|
|
+ * is still unhandled work.
|
|
|
|
+ */
|
|
|
|
+ rmb();
|
|
|
|
|
|
/* Fall out from the NAPI loop if needed */
|
|
/* Fall out from the NAPI loop if needed */
|
|
- if (!(qede_has_rx_work(fp->rxq) || qede_has_tx_work(fp))) {
|
|
|
|
- qed_sb_update_sb_idx(fp->sb_info);
|
|
|
|
- /* *_has_*_work() reads the status block,
|
|
|
|
- * thus we need to ensure that status block indices
|
|
|
|
- * have been actually read (qed_sb_update_sb_idx)
|
|
|
|
- * prior to this check (*_has_*_work) so that
|
|
|
|
- * we won't write the "newer" value of the status block
|
|
|
|
- * to HW (if there was a DMA right after
|
|
|
|
- * qede_has_rx_work and if there is no rmb, the memory
|
|
|
|
- * reading (qed_sb_update_sb_idx) may be postponed
|
|
|
|
- * to right before *_ack_sb). In this case there
|
|
|
|
- * will never be another interrupt until there is
|
|
|
|
- * another update of the status block, while there
|
|
|
|
- * is still unhandled work.
|
|
|
|
- */
|
|
|
|
- rmb();
|
|
|
|
-
|
|
|
|
- if (!(qede_has_rx_work(fp->rxq) ||
|
|
|
|
- qede_has_tx_work(fp))) {
|
|
|
|
- napi_complete(napi);
|
|
|
|
- /* Update and reenable interrupts */
|
|
|
|
- qed_sb_ack(fp->sb_info, IGU_INT_ENABLE,
|
|
|
|
- 1 /*update*/);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!(qede_has_rx_work(fp->rxq) ||
|
|
|
|
+ qede_has_tx_work(fp))) {
|
|
|
|
+ napi_complete(napi);
|
|
|
|
+
|
|
|
|
+ /* Update and reenable interrupts */
|
|
|
|
+ qed_sb_ack(fp->sb_info, IGU_INT_ENABLE,
|
|
|
|
+ 1 /*update*/);
|
|
|
|
+ } else {
|
|
|
|
+ rx_work_done = budget;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return work_done;
|
|
|
|
|
|
+ return rx_work_done;
|
|
}
|
|
}
|
|
|
|
|
|
static irqreturn_t qede_msix_fp_int(int irq, void *fp_cookie)
|
|
static irqreturn_t qede_msix_fp_int(int irq, void *fp_cookie)
|