qlcnic: helper routine to handle async events
Create a helper routine to handle async events, as it is being called from multiple places Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								3d73b5fda4
							
						
					
				
			
			
				commit
				
					
						483202d590
					
				
			
		
					 4 changed files with 45 additions and 64 deletions
				
			
		| 
						 | 
					@ -12,13 +12,6 @@
 | 
				
			||||||
#include <linux/interrupt.h>
 | 
					#include <linux/interrupt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QLCNIC_MAX_TX_QUEUES		1
 | 
					#define QLCNIC_MAX_TX_QUEUES		1
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define QLCNIC_MBX_RSP(reg)		LSW(reg)
 | 
					 | 
				
			||||||
#define QLCNIC_MBX_NUM_REGS(reg)	(MSW(reg) & 0x1FF)
 | 
					 | 
				
			||||||
#define QLCNIC_MBX_STATUS(reg)		(((reg) >> 25) & 0x7F)
 | 
					 | 
				
			||||||
#define QLCNIC_MBX_HOST(ahw, i)	((ahw)->pci_base0 + ((i) * 4))
 | 
					 | 
				
			||||||
#define QLCNIC_MBX_FW(ahw, i)		((ahw)->pci_base0 + 0x800 + ((i) * 4))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RSS_HASHTYPE_IP_TCP		0x3
 | 
					#define RSS_HASHTYPE_IP_TCP		0x3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* status descriptor mailbox data
 | 
					/* status descriptor mailbox data
 | 
				
			||||||
| 
						 | 
					@ -696,7 +689,7 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	u16 opcode;
 | 
						u16 opcode;
 | 
				
			||||||
	u8 mbx_err_code, mac_cmd_rcode;
 | 
						u8 mbx_err_code, mac_cmd_rcode;
 | 
				
			||||||
	u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, temp, fw[8];
 | 
						u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
 | 
				
			||||||
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opcode = LSW(cmd->req.arg[0]);
 | 
						opcode = LSW(cmd->req.arg[0]);
 | 
				
			||||||
| 
						 | 
					@ -738,42 +731,8 @@ poll:
 | 
				
			||||||
	opcode = QLCNIC_MBX_RSP(fw_data);
 | 
						opcode = QLCNIC_MBX_RSP(fw_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rsp != QLCNIC_RCODE_TIMEOUT) {
 | 
						if (rsp != QLCNIC_RCODE_TIMEOUT) {
 | 
				
			||||||
		if (opcode == QLCNIC_MBX_LINK_EVENT) {
 | 
							if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
 | 
				
			||||||
			for (i = 0; i < rsp_num; i++) {
 | 
								qlcnic_83xx_process_aen(adapter);
 | 
				
			||||||
				temp = readl(QLCNIC_MBX_FW(ahw, i));
 | 
					 | 
				
			||||||
				fw[i] = temp;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			qlcnic_83xx_handle_link_aen(adapter, fw);
 | 
					 | 
				
			||||||
			/* clear fw mbx control register */
 | 
					 | 
				
			||||||
			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
 | 
					 | 
				
			||||||
			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 | 
					 | 
				
			||||||
			if (mbx_val)
 | 
					 | 
				
			||||||
				goto poll;
 | 
					 | 
				
			||||||
		} else if (opcode == QLCNIC_MBX_COMP_EVENT) {
 | 
					 | 
				
			||||||
			for (i = 0; i < rsp_num; i++) {
 | 
					 | 
				
			||||||
				temp = readl(QLCNIC_MBX_FW(ahw, i));
 | 
					 | 
				
			||||||
				fw[i] = temp;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			qlcnic_83xx_handle_idc_comp_aen(adapter, fw);
 | 
					 | 
				
			||||||
			/* clear fw mbx control register */
 | 
					 | 
				
			||||||
			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
 | 
					 | 
				
			||||||
			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 | 
					 | 
				
			||||||
			if (mbx_val)
 | 
					 | 
				
			||||||
				goto poll;
 | 
					 | 
				
			||||||
		} else if (opcode == QLCNIC_MBX_REQUEST_EVENT) {
 | 
					 | 
				
			||||||
			/* IDC Request Notification */
 | 
					 | 
				
			||||||
			for (i = 0; i < rsp_num; i++) {
 | 
					 | 
				
			||||||
				temp = readl(QLCNIC_MBX_FW(ahw, i));
 | 
					 | 
				
			||||||
				fw[i] = temp;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) {
 | 
					 | 
				
			||||||
				temp = QLCNIC_MBX_RSP(fw[i]);
 | 
					 | 
				
			||||||
				adapter->ahw->mbox_aen[i] = temp;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			queue_delayed_work(adapter->qlcnic_wq,
 | 
					 | 
				
			||||||
					   &adapter->idc_aen_work, 0);
 | 
					 | 
				
			||||||
			/* clear fw mbx control register */
 | 
					 | 
				
			||||||
			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
 | 
					 | 
				
			||||||
			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 | 
								mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 | 
				
			||||||
			if (mbx_val)
 | 
								if (mbx_val)
 | 
				
			||||||
				goto poll;
 | 
									goto poll;
 | 
				
			||||||
| 
						 | 
					@ -875,20 +834,10 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 | 
					void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 mask, resp, event[QLC_83XX_MBX_AEN_CNT];
 | 
						u32 event[QLC_83XX_MBX_AEN_CNT];
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
						struct qlcnic_hardware_context *ahw = adapter->ahw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!spin_trylock(&ahw->mbx_lock)) {
 | 
					 | 
				
			||||||
		mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 | 
					 | 
				
			||||||
		writel(0, adapter->ahw->pci_base0 + mask);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!(resp & QLCNIC_SET_OWNER))
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
 | 
						for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
 | 
				
			||||||
		event[i] = readl(QLCNIC_MBX_FW(ahw, i));
 | 
							event[i] = readl(QLCNIC_MBX_FW(ahw, i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -923,10 +872,6 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
 | 
						QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 | 
					 | 
				
			||||||
	writel(0, adapter->ahw->pci_base0 + mask);
 | 
					 | 
				
			||||||
	spin_unlock(&ahw->mbx_lock);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
 | 
					static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -1620,7 +1565,21 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
 | 
				
			||||||
irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
 | 
					irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct qlcnic_adapter *adapter = data;
 | 
						struct qlcnic_adapter *adapter = data;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
						u32 mask, resp, event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
 | 
				
			||||||
 | 
						resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
 | 
				
			||||||
 | 
						if (!(resp & QLCNIC_SET_OWNER))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
 | 
				
			||||||
 | 
						if (event &  QLCNIC_MBX_ASYNC_EVENT)
 | 
				
			||||||
		qlcnic_83xx_process_aen(adapter);
 | 
							qlcnic_83xx_process_aen(adapter);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 | 
				
			||||||
 | 
						writel(0, adapter->ahw->pci_base0 + mask);
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return IRQ_HANDLED;
 | 
						return IRQ_HANDLED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,9 +137,6 @@ struct qlc_83xx_reset {
 | 
				
			||||||
#define QLC_83XX_IDC_MINOR_VERSION			0
 | 
					#define QLC_83XX_IDC_MINOR_VERSION			0
 | 
				
			||||||
#define QLC_83XX_IDC_FLASH_PARAM_ADDR			0x3e8020
 | 
					#define QLC_83XX_IDC_FLASH_PARAM_ADDR			0x3e8020
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mailbox process AEN count */
 | 
					 | 
				
			||||||
#define QLC_83XX_MBX_AEN_CNT 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct qlcnic_adapter;
 | 
					struct qlcnic_adapter;
 | 
				
			||||||
struct qlc_83xx_idc {
 | 
					struct qlc_83xx_idc {
 | 
				
			||||||
	int (*state_entry) (struct qlcnic_adapter *);
 | 
						int (*state_entry) (struct qlcnic_adapter *);
 | 
				
			||||||
| 
						 | 
					@ -156,6 +153,12 @@ struct qlc_83xx_idc {
 | 
				
			||||||
	char		**name;
 | 
						char		**name;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_RSP(reg)		LSW(reg)
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_NUM_REGS(reg)	(MSW(reg) & 0x1FF)
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_STATUS(reg)		(((reg) >> 25) & 0x7F)
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_HOST(ahw, i)	((ahw)->pci_base0 + ((i) * 4))
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_FW(ahw, i)		((ahw)->pci_base0 + 0x800 + ((i) * 4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mailbox process AEN count */
 | 
					/* Mailbox process AEN count */
 | 
				
			||||||
#define QLC_83XX_IDC_COMP_AEN			3
 | 
					#define QLC_83XX_IDC_COMP_AEN			3
 | 
				
			||||||
#define QLC_83XX_MBX_AEN_CNT			5
 | 
					#define QLC_83XX_MBX_AEN_CNT			5
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,7 @@ struct qlcnic_mailbox_metadata {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QLCNIC_MBX_RSP_OK	1
 | 
					#define QLCNIC_MBX_RSP_OK	1
 | 
				
			||||||
#define QLCNIC_MBX_PORT_RSP_OK	0x1a
 | 
					#define QLCNIC_MBX_PORT_RSP_OK	0x1a
 | 
				
			||||||
 | 
					#define QLCNIC_MBX_ASYNC_EVENT	BIT_15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct qlcnic_pci_info;
 | 
					struct qlcnic_pci_info;
 | 
				
			||||||
struct qlcnic_info;
 | 
					struct qlcnic_info;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1553,6 +1553,24 @@ skip:
 | 
				
			||||||
	return count;
 | 
						return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
						u32 mask, resp, event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
 | 
				
			||||||
 | 
						resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
 | 
				
			||||||
 | 
						if (!(resp & QLCNIC_SET_OWNER))
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
 | 
				
			||||||
 | 
						if (event &  QLCNIC_MBX_ASYNC_EVENT)
 | 
				
			||||||
 | 
							qlcnic_83xx_process_aen(adapter);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 | 
				
			||||||
 | 
						writel(0, adapter->ahw->pci_base0 + mask);
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
 | 
					static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int tx_complete;
 | 
						int tx_complete;
 | 
				
			||||||
| 
						 | 
					@ -1567,7 +1585,7 @@ static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
 | 
				
			||||||
	tx_ring = adapter->tx_ring;
 | 
						tx_ring = adapter->tx_ring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 | 
						if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 | 
				
			||||||
		qlcnic_83xx_process_aen(adapter);
 | 
							qlcnic_83xx_poll_process_aen(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
 | 
						tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
 | 
				
			||||||
	work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
 | 
						work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue