Commit d1a1105e authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller
Browse files

qlcnic: Fix loopback test for SR-IOV PF.



o Do not disable mailbox interrupts while running
  loopback test through SR-IOV PF.

Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 91b7282b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1868,6 +1868,7 @@ static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring)
		writel(0xfbff, adapter->tgt_mask_reg);
}

extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_failed_ops;

+42 −14
Original line number Diff line number Diff line
@@ -402,7 +402,8 @@ static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)

	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:
	qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
	spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
@@ -758,7 +759,7 @@ poll:
		/* Get the FW response data */
		fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
		if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
			qlcnic_83xx_process_aen(adapter);
			__qlcnic_83xx_process_aen(adapter);
			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
			if (mbx_val)
				goto poll;
@@ -862,7 +863,7 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
	return;
}

void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
{
	u32 event[QLC_83XX_MBX_AEN_CNT];
	int i;
@@ -907,6 +908,24 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
	QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
}

static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	u32 resp, event;
	unsigned long flags;

	spin_lock_irqsave(&ahw->mbx_lock, flags);

	resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
	if (resp & QLCNIC_SET_OWNER) {
		event = readl(QLCNIC_MBX_FW(ahw, 0));
		if (event &  QLCNIC_MBX_ASYNC_EVENT)
			__qlcnic_83xx_process_aen(adapter);
	}

	spin_unlock_irqrestore(&ahw->mbx_lock, flags);
}

static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
{
	int index, i, err, sds_mbx_size;
@@ -1274,6 +1293,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)

	if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
		/* disable and free mailbox interrupt */
		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
			qlcnic_83xx_free_mbx_intr(adapter);
		adapter->ahw->loopback_state = 0;
		adapter->ahw->hw_ops->setup_link_event(adapter, 1);
@@ -1302,6 +1322,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
	qlcnic_detach(adapter);

	if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
		if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
			err = qlcnic_83xx_setup_mbx_intr(adapter);
			if (err) {
				dev_err(&adapter->pdev->dev,
@@ -1310,6 +1331,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
				goto out;
			}
		}
	}
	adapter->ahw->diag_test = 0;
	adapter->max_sds_rings = max_sds_rings;

@@ -1556,7 +1578,9 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
	/* Poll for link up event before running traffic */
	do {
		msleep(500);
		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
			qlcnic_83xx_process_aen(adapter);

		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
			dev_info(&adapter->pdev->dev,
				 "Firmware didn't sent link up event to loopback request\n");
@@ -1610,7 +1634,9 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
	/* Wait for Link and IDC Completion AEN */
	do {
		msleep(300);
		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
			qlcnic_83xx_process_aen(adapter);

		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
			dev_err(&adapter->pdev->dev,
				"FW did not generate IDC completion AEN\n");
@@ -1650,7 +1676,9 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
	/* Wait for Link and IDC Completion AEN */
	do {
		msleep(300);
		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
			qlcnic_83xx_process_aen(adapter);

		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
			dev_err(&adapter->pdev->dev,
				"Firmware didn't sent IDC completion AEN\n");
@@ -1924,7 +1952,7 @@ irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)

	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);
+1 −1
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@ void qlcnic_83xx_disable_intr(struct qlcnic_adapter *,
			     struct qlcnic_host_sds_ring *);
void qlcnic_83xx_check_vf(struct qlcnic_adapter *,
			  const struct pci_device_id *);
void qlcnic_83xx_process_aen(struct qlcnic_adapter *);
void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
int qlcnic_enable_eswitch(struct qlcnic_adapter *, u8, u8);
+29 −5
Original line number Diff line number Diff line
@@ -862,6 +862,8 @@ clear_diag_irq:
#define QLCNIC_ILB_PKT_SIZE		64
#define QLCNIC_NUM_ILB_PKT		16
#define QLCNIC_ILB_MAX_RCV_LOOP		10
#define QLCNIC_LB_PKT_POLL_DELAY_MSEC	1
#define QLCNIC_LB_PKT_POLL_COUNT	20

static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
{
@@ -898,9 +900,9 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
		loop = 0;

		do {
			msleep(1);
			msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
			qlcnic_process_rcv_ring_diag(sds_ring);
			if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
			if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
				break;
		} while (!adapter->ahw->diag_cnt);

@@ -1539,3 +1541,25 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
	.get_dump_data = qlcnic_get_dump_data,
	.set_dump = qlcnic_set_dump,
};

const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
	.get_settings		= qlcnic_get_settings,
	.get_drvinfo		= qlcnic_get_drvinfo,
	.get_regs_len		= qlcnic_get_regs_len,
	.get_regs		= qlcnic_get_regs,
	.get_link		= ethtool_op_get_link,
	.get_eeprom_len		= qlcnic_get_eeprom_len,
	.get_eeprom		= qlcnic_get_eeprom,
	.get_ringparam		= qlcnic_get_ringparam,
	.set_ringparam		= qlcnic_set_ringparam,
	.get_channels		= qlcnic_get_channels,
	.get_pauseparam		= qlcnic_get_pauseparam,
	.get_wol		= qlcnic_get_wol,
	.get_strings		= qlcnic_get_strings,
	.get_ethtool_stats	= qlcnic_get_ethtool_stats,
	.get_sset_count		= qlcnic_get_sset_count,
	.get_coalesce		= qlcnic_get_intr_coalesce,
	.set_coalesce		= qlcnic_set_intr_coalesce,
	.set_msglevel		= qlcnic_set_msglevel,
	.get_msglevel		= qlcnic_get_msglevel,
};
+4 −1
Original line number Diff line number Diff line
@@ -1743,6 +1743,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,

	qlcnic_change_mtu(netdev, netdev->mtu);

	if (qlcnic_sriov_vf_check(adapter))
		SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops);
	else
		SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);

	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
Loading