Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e49038d6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'qlcnic-next'



Rajesh Borundia says:

====================
qlcnic fixes

This series adds following fixes.

o While processing mailbox if driver gets a spurious mailbox
  interrupt it leads into premature completion of a next
  mailbox request. Added a guard against this by checking current
  state of mailbox and ignored spurious interrupt.
  Added a stats counter to record this condition.

v2:

o Added patch that removes usage of atomic_t as we are not implemeting
  atomicity by using atomic_t value.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b795a213 819bfe76
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -566,6 +566,7 @@ struct qlcnic_adapter_stats {
	u64  tx_dma_map_error;
	u64  spurious_intr;
	u64  mac_filter_limit_overrun;
	u64  mbx_spurious_intr;
};

/*
@@ -1099,7 +1100,7 @@ struct qlcnic_mailbox {
	unsigned long		status;
	spinlock_t		queue_lock;	/* Mailbox queue lock */
	spinlock_t		aen_lock;	/* Mailbox response/AEN lock */
	atomic_t		rsp_status;
	u32			rsp_status;
	u32			num_cmds;
};

+15 −9
Original line number Diff line number Diff line
@@ -491,7 +491,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)

static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
{
	atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
	mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
	complete(&mbx->completion);
}

@@ -510,7 +510,7 @@ static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
	if (event &  QLCNIC_MBX_ASYNC_EVENT) {
		__qlcnic_83xx_process_aen(adapter);
	} else {
		if (atomic_read(&mbx->rsp_status) != rsp_status)
		if (mbx->rsp_status != rsp_status)
			qlcnic_83xx_notify_mbx_response(mbx);
	}
out:
@@ -1023,7 +1023,7 @@ static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
		if (event &  QLCNIC_MBX_ASYNC_EVENT) {
			__qlcnic_83xx_process_aen(adapter);
		} else {
			if (atomic_read(&mbx->rsp_status) != rsp_status)
			if (mbx->rsp_status != rsp_status)
				qlcnic_83xx_notify_mbx_response(mbx);
		}
	}
@@ -2338,9 +2338,9 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,

static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
{
	u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
	struct qlcnic_adapter *adapter = data;
	struct qlcnic_mailbox *mbx;
	u32 mask, resp, event;
	unsigned long flags;

	mbx = adapter->ahw->mailbox;
@@ -2350,10 +2350,14 @@ static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
		goto out;

	event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
	if (event &  QLCNIC_MBX_ASYNC_EVENT)
	if (event &  QLCNIC_MBX_ASYNC_EVENT) {
		__qlcnic_83xx_process_aen(adapter);
	else
	} else {
		if (mbx->rsp_status != rsp_status)
			qlcnic_83xx_notify_mbx_response(mbx);
		else
			adapter->stats.mbx_spurious_intr++;
	}

out:
	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
@@ -4050,10 +4054,10 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
	struct qlcnic_adapter *adapter = mbx->adapter;
	const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
	struct device *dev = &adapter->pdev->dev;
	atomic_t *rsp_status = &mbx->rsp_status;
	struct list_head *head = &mbx->cmd_q;
	struct qlcnic_hardware_context *ahw;
	struct qlcnic_cmd_args *cmd = NULL;
	unsigned long flags;

	ahw = adapter->ahw;

@@ -4063,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
			return;
		}

		atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
		spin_lock_irqsave(&mbx->aen_lock, flags);
		mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
		spin_unlock_irqrestore(&mbx->aen_lock, flags);

		spin_lock(&mbx->queue_lock);

+2 −1
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
	 QLC_OFF(stats.mac_filter_limit_overrun)},
	{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
	 QLC_OFF(stats.spurious_intr)},

	{"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
	 QLC_OFF(stats.mbx_spurious_intr)},
};

static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {