Commit a05e7a67 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'ionic-code-maintenance'

Shannon Nelson says:

====================
ionic: code maintenance

These are a few fixes for a hardware bug, a couple of sw bugs,
and a little code cleanup.
====================

Link: https://lore.kernel.org/r/20230202215537.69756-1-shannon.nelson@amd.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 69ff53e4 b69585bf
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -708,9 +708,16 @@ void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,
		q->lif->index, q->name, q->hw_type, q->hw_index,
		q->head_idx, ring_doorbell);

	if (ring_doorbell)
	if (ring_doorbell) {
		ionic_dbell_ring(lif->kern_dbpage, q->hw_type,
				 q->dbval | q->head_idx);

		q->dbell_jiffies = jiffies;

		if (q_to_qcq(q)->napi_qcq)
			mod_timer(&q_to_qcq(q)->napi_qcq->napi_deadline,
				  jiffies + IONIC_NAPI_DEADLINE);
	}
}

static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos)
+12 −0
Original line number Diff line number Diff line
@@ -25,6 +25,12 @@
#define IONIC_DEV_INFO_REG_COUNT	32
#define IONIC_DEV_CMD_REG_COUNT		32

#define IONIC_NAPI_DEADLINE		(HZ / 200)	/* 5ms */
#define IONIC_ADMIN_DOORBELL_DEADLINE	(HZ / 2)	/* 500ms */
#define IONIC_TX_DOORBELL_DEADLINE	(HZ / 100)	/* 10ms */
#define IONIC_RX_MIN_DOORBELL_DEADLINE	(HZ / 100)	/* 10ms */
#define IONIC_RX_MAX_DOORBELL_DEADLINE	(HZ * 5)	/* 5s */

struct ionic_dev_bar {
	void __iomem *vaddr;
	phys_addr_t bus_addr;
@@ -216,6 +222,8 @@ struct ionic_queue {
	struct ionic_lif *lif;
	struct ionic_desc_info *info;
	u64 dbval;
	unsigned long dbell_deadline;
	unsigned long dbell_jiffies;
	u16 head_idx;
	u16 tail_idx;
	unsigned int index;
@@ -361,4 +369,8 @@ void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info,
int ionic_heartbeat_check(struct ionic *ionic);
bool ionic_is_fw_running(struct ionic_dev *idev);

bool ionic_adminq_poke_doorbell(struct ionic_queue *q);
bool ionic_txq_poke_doorbell(struct ionic_queue *q);
bool ionic_rxq_poke_doorbell(struct ionic_queue *q);

#endif /* _IONIC_DEV_H_ */
+59 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "ionic.h"
#include "ionic_bus.h"
#include "ionic_dev.h"
#include "ionic_lif.h"
#include "ionic_txrx.h"
#include "ionic_ethtool.h"
@@ -200,6 +201,13 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep)
	}
}

static void ionic_napi_deadline(struct timer_list *timer)
{
	struct ionic_qcq *qcq = container_of(timer, struct ionic_qcq, napi_deadline);

	napi_schedule(&qcq->napi);
}

static irqreturn_t ionic_isr(int irq, void *data)
{
	struct napi_struct *napi = data;
@@ -269,6 +277,7 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
			.oper = IONIC_Q_ENABLE,
		},
	};
	int ret;

	idev = &lif->ionic->idev;
	dev = lif->ionic->dev;
@@ -276,16 +285,24 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
	dev_dbg(dev, "q_enable.index %d q_enable.qtype %d\n",
		ctx.cmd.q_control.index, ctx.cmd.q_control.type);

	if (qcq->flags & IONIC_QCQ_F_INTR)
		ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);

	ret = ionic_adminq_post_wait(lif, &ctx);
	if (ret)
		return ret;

	if (qcq->napi.poll)
		napi_enable(&qcq->napi);

	if (qcq->flags & IONIC_QCQ_F_INTR) {
		irq_set_affinity_hint(qcq->intr.vector,
				      &qcq->intr.affinity_mask);
		napi_enable(&qcq->napi);
		ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);
		ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
				IONIC_INTR_MASK_CLEAR);
	}

	return ionic_adminq_post_wait(lif, &ctx);
	return 0;
}

static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int fw_err)
@@ -316,6 +333,7 @@ static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int f
		synchronize_irq(qcq->intr.vector);
		irq_set_affinity_hint(qcq->intr.vector, NULL);
		napi_disable(&qcq->napi);
		del_timer_sync(&qcq->napi_deadline);
	}

	/* If there was a previous fw communcation error, don't bother with
@@ -451,6 +469,7 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,

	n_qcq->intr.vector = src_qcq->intr.vector;
	n_qcq->intr.index = src_qcq->intr.index;
	n_qcq->napi_qcq = src_qcq->napi_qcq;
}

static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qcq)
@@ -564,13 +583,15 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
	}

	if (flags & IONIC_QCQ_F_NOTIFYQ) {
		int q_size, cq_size;
		int q_size;

		/* q & cq need to be contiguous in case of notifyq */
		/* q & cq need to be contiguous in NotifyQ, so alloc it all in q
		 * and don't alloc qc.  We leave new->qc_size and new->qc_base
		 * as 0 to be sure we don't try to free it later.
		 */
		q_size = ALIGN(num_descs * desc_size, PAGE_SIZE);
		cq_size = ALIGN(num_descs * cq_desc_size, PAGE_SIZE);

		new->q_size = PAGE_SIZE + q_size + cq_size;
		new->q_size = PAGE_SIZE + q_size +
			      ALIGN(num_descs * cq_desc_size, PAGE_SIZE);
		new->q_base = dma_alloc_coherent(dev, new->q_size,
						 &new->q_base_pa, GFP_KERNEL);
		if (!new->q_base) {
@@ -773,8 +794,14 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
	dev_dbg(dev, "txq->hw_type %d\n", q->hw_type);
	dev_dbg(dev, "txq->hw_index %d\n", q->hw_index);

	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
	q->dbell_deadline = IONIC_TX_DOORBELL_DEADLINE;
	q->dbell_jiffies = jiffies;

	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
		netif_napi_add(lif->netdev, &qcq->napi, ionic_tx_napi);
		qcq->napi_qcq = qcq;
		timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);
	}

	qcq->flags |= IONIC_QCQ_F_INITED;

@@ -828,11 +855,17 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
	dev_dbg(dev, "rxq->hw_type %d\n", q->hw_type);
	dev_dbg(dev, "rxq->hw_index %d\n", q->hw_index);

	q->dbell_deadline = IONIC_RX_MIN_DOORBELL_DEADLINE;
	q->dbell_jiffies = jiffies;

	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
		netif_napi_add(lif->netdev, &qcq->napi, ionic_rx_napi);
	else
		netif_napi_add(lif->netdev, &qcq->napi, ionic_txrx_napi);

	qcq->napi_qcq = qcq;
	timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);

	qcq->flags |= IONIC_QCQ_F_INITED;

	return 0;
@@ -1150,6 +1183,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
	struct ionic_dev *idev = &lif->ionic->idev;
	unsigned long irqflags;
	unsigned int flags = 0;
	bool resched = false;
	int rx_work = 0;
	int tx_work = 0;
	int n_work = 0;
@@ -1187,6 +1221,16 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
		ionic_intr_credits(idev->intr_ctrl, intr->index, credits, flags);
	}

	if (!a_work && ionic_adminq_poke_doorbell(&lif->adminqcq->q))
		resched = true;
	if (lif->hwstamp_rxq && !rx_work && ionic_rxq_poke_doorbell(&lif->hwstamp_rxq->q))
		resched = true;
	if (lif->hwstamp_txq && !tx_work && ionic_txq_poke_doorbell(&lif->hwstamp_txq->q))
		resched = true;
	if (resched)
		mod_timer(&lif->adminqcq->napi_deadline,
			  jiffies + IONIC_NAPI_DEADLINE);

	return work_done;
}

@@ -3245,8 +3289,14 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
	dev_dbg(dev, "adminq->hw_type %d\n", q->hw_type);
	dev_dbg(dev, "adminq->hw_index %d\n", q->hw_index);

	q->dbell_deadline = IONIC_ADMIN_DOORBELL_DEADLINE;
	q->dbell_jiffies = jiffies;

	netif_napi_add(lif->netdev, &qcq->napi, ionic_adminq_napi);

	qcq->napi_qcq = qcq;
	timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);

	napi_enable(&qcq->napi);

	if (qcq->flags & IONIC_QCQ_F_INTR)
+2 −0
Original line number Diff line number Diff line
@@ -74,8 +74,10 @@ struct ionic_qcq {
	struct ionic_queue q;
	struct ionic_cq cq;
	struct ionic_intr_info intr;
	struct timer_list napi_deadline;
	struct napi_struct napi;
	unsigned int flags;
	struct ionic_qcq *napi_qcq;
	struct dentry *dentry;
};

+29 −0
Original line number Diff line number Diff line
@@ -289,6 +289,35 @@ static void ionic_adminq_cb(struct ionic_queue *q,
	complete_all(&ctx->work);
}

bool ionic_adminq_poke_doorbell(struct ionic_queue *q)
{
	struct ionic_lif *lif = q->lif;
	unsigned long now, then, dif;
	unsigned long irqflags;

	spin_lock_irqsave(&lif->adminq_lock, irqflags);

	if (q->tail_idx == q->head_idx) {
		spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
		return false;
	}

	now = READ_ONCE(jiffies);
	then = q->dbell_jiffies;
	dif = now - then;

	if (dif > q->dbell_deadline) {
		ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
				 q->dbval | q->head_idx);

		q->dbell_jiffies = now;
	}

	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);

	return true;
}

int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
	struct ionic_desc_info *desc_info;
Loading