brintos

brintos / linux-shallow public Read only

0
0
Text · 56.7 KiB · f9dd501 Raw
2230 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * QLogic qlcnic NIC Driver4 * Copyright (c) 2009-2013 QLogic Corporation5 */6 7#include <linux/types.h>8 9#include "qlcnic_sriov.h"10#include "qlcnic.h"11#include "qlcnic_83xx_hw.h"12 13#define QLC_BC_COMMAND	014#define QLC_BC_RESPONSE	115 16#define QLC_MBOX_RESP_TIMEOUT		(10 * HZ)17#define QLC_MBOX_CH_FREE_TIMEOUT	(10 * HZ)18 19#define QLC_BC_MSG		020#define QLC_BC_CFREE		121#define QLC_BC_FLR		222#define QLC_BC_HDR_SZ		1623#define QLC_BC_PAYLOAD_SZ	(1024 - QLC_BC_HDR_SZ)24 25#define QLC_DEFAULT_RCV_DESCRIPTORS_SRIOV_VF		204826#define QLC_DEFAULT_JUMBO_RCV_DESCRIPTORS_SRIOV_VF	51227 28#define QLC_83XX_VF_RESET_FAIL_THRESH	829#define QLC_BC_CMD_MAX_RETRY_CNT	530 31static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work);32static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *);33static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *, u32);34static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *);35static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *);36static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *);37static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *,38				  struct qlcnic_cmd_args *);39static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8);40static void qlcnic_sriov_process_bc_cmd(struct work_struct *);41static int qlcnic_sriov_vf_shutdown(struct pci_dev *);42static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *);43static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *,44					struct qlcnic_cmd_args *);45 46static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {47	.read_crb			= qlcnic_83xx_read_crb,48	.write_crb			= qlcnic_83xx_write_crb,49	.read_reg			= qlcnic_83xx_rd_reg_indirect,50	.write_reg			= qlcnic_83xx_wrt_reg_indirect,51	.get_mac_address		= qlcnic_83xx_get_mac_address,52	.setup_intr			= qlcnic_83xx_setup_intr,53	.alloc_mbx_args			= qlcnic_83xx_alloc_mbx_args,54	.mbx_cmd			= qlcnic_sriov_issue_cmd,55	.get_func_no			= qlcnic_83xx_get_func_no,56	.api_lock			= qlcnic_83xx_cam_lock,57	.api_unlock			= qlcnic_83xx_cam_unlock,58	.process_lb_rcv_ring_diag	= qlcnic_83xx_process_rcv_ring_diag,59	.create_rx_ctx			= qlcnic_83xx_create_rx_ctx,60	.create_tx_ctx			= qlcnic_83xx_create_tx_ctx,61	.del_rx_ctx			= qlcnic_83xx_del_rx_ctx,62	.del_tx_ctx			= qlcnic_83xx_del_tx_ctx,63	.setup_link_event		= qlcnic_83xx_setup_link_event,64	.get_nic_info			= qlcnic_83xx_get_nic_info,65	.get_pci_info			= qlcnic_83xx_get_pci_info,66	.set_nic_info			= qlcnic_83xx_set_nic_info,67	.change_macvlan			= qlcnic_83xx_sre_macaddr_change,68	.napi_enable			= qlcnic_83xx_napi_enable,69	.napi_disable			= qlcnic_83xx_napi_disable,70	.config_intr_coal		= qlcnic_83xx_config_intr_coal,71	.config_rss			= qlcnic_83xx_config_rss,72	.config_hw_lro			= qlcnic_83xx_config_hw_lro,73	.config_promisc_mode		= qlcnic_83xx_nic_set_promisc,74	.change_l2_filter		= qlcnic_83xx_change_l2_filter,75	.get_board_info			= qlcnic_83xx_get_port_info,76	.free_mac_list			= qlcnic_sriov_vf_free_mac_list,77	.enable_sds_intr		= qlcnic_83xx_enable_sds_intr,78	.disable_sds_intr		= qlcnic_83xx_disable_sds_intr,79	.encap_rx_offload               = qlcnic_83xx_encap_rx_offload,80	.encap_tx_offload               = qlcnic_83xx_encap_tx_offload,81};82 83static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {84	.config_bridged_mode	= qlcnic_config_bridged_mode,85	.config_led		= qlcnic_config_led,86	.cancel_idc_work        = qlcnic_sriov_vf_cancel_fw_work,87	.napi_add		= qlcnic_83xx_napi_add,88	.napi_del		= qlcnic_83xx_napi_del,89	.shutdown		= qlcnic_sriov_vf_shutdown,90	.resume			= qlcnic_sriov_vf_resume,91	.config_ipaddr		= qlcnic_83xx_config_ipaddr,92	.clear_legacy_intr	= qlcnic_83xx_clear_legacy_intr,93};94 95static const struct qlcnic_mailbox_metadata qlcnic_sriov_bc_mbx_tbl[] = {96	{QLCNIC_BC_CMD_CHANNEL_INIT, 2, 2},97	{QLCNIC_BC_CMD_CHANNEL_TERM, 2, 2},98	{QLCNIC_BC_CMD_GET_ACL, 3, 14},99	{QLCNIC_BC_CMD_CFG_GUEST_VLAN, 2, 2},100};101 102static inline bool qlcnic_sriov_bc_msg_check(u32 val)103{104	return (val & (1 << QLC_BC_MSG)) ? true : false;105}106 107static inline bool qlcnic_sriov_channel_free_check(u32 val)108{109	return (val & (1 << QLC_BC_CFREE)) ? true : false;110}111 112static inline bool qlcnic_sriov_flr_check(u32 val)113{114	return (val & (1 << QLC_BC_FLR)) ? true : false;115}116 117static inline u8 qlcnic_sriov_target_func_id(u32 val)118{119	return (val >> 4) & 0xff;120}121 122static int qlcnic_sriov_virtid_fn(struct qlcnic_adapter *adapter, int vf_id)123{124	struct pci_dev *dev = adapter->pdev;125	int pos;126	u16 stride, offset;127 128	if (qlcnic_sriov_vf_check(adapter))129		return 0;130 131	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);132	if (!pos)133		return 0;134	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);135	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);136 137	return (dev->devfn + offset + stride * vf_id) & 0xff;138}139 140int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)141{142	struct qlcnic_sriov *sriov;143	struct qlcnic_back_channel *bc;144	struct workqueue_struct *wq;145	struct qlcnic_vport *vp;146	struct qlcnic_vf_info *vf;147	int err, i;148 149	if (!qlcnic_sriov_enable_check(adapter))150		return -EIO;151 152	sriov  = kzalloc(sizeof(struct qlcnic_sriov), GFP_KERNEL);153	if (!sriov)154		return -ENOMEM;155 156	adapter->ahw->sriov = sriov;157	sriov->num_vfs = num_vfs;158	bc = &sriov->bc;159	sriov->vf_info = kcalloc(num_vfs, sizeof(struct qlcnic_vf_info),160				 GFP_KERNEL);161	if (!sriov->vf_info) {162		err = -ENOMEM;163		goto qlcnic_free_sriov;164	}165 166	wq = create_singlethread_workqueue("bc-trans");167	if (wq == NULL) {168		err = -ENOMEM;169		dev_err(&adapter->pdev->dev,170			"Cannot create bc-trans workqueue\n");171		goto qlcnic_free_vf_info;172	}173 174	bc->bc_trans_wq = wq;175 176	wq = create_singlethread_workqueue("async");177	if (wq == NULL) {178		err = -ENOMEM;179		dev_err(&adapter->pdev->dev, "Cannot create async workqueue\n");180		goto qlcnic_destroy_trans_wq;181	}182 183	bc->bc_async_wq =  wq;184	INIT_LIST_HEAD(&bc->async_cmd_list);185	INIT_WORK(&bc->vf_async_work, qlcnic_sriov_handle_async_issue_cmd);186	spin_lock_init(&bc->queue_lock);187	bc->adapter = adapter;188 189	for (i = 0; i < num_vfs; i++) {190		vf = &sriov->vf_info[i];191		vf->adapter = adapter;192		vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i);193		mutex_init(&vf->send_cmd_lock);194		spin_lock_init(&vf->vlan_list_lock);195		INIT_LIST_HEAD(&vf->rcv_act.wait_list);196		INIT_LIST_HEAD(&vf->rcv_pend.wait_list);197		spin_lock_init(&vf->rcv_act.lock);198		spin_lock_init(&vf->rcv_pend.lock);199		init_completion(&vf->ch_free_cmpl);200 201		INIT_WORK(&vf->trans_work, qlcnic_sriov_process_bc_cmd);202 203		if (qlcnic_sriov_pf_check(adapter)) {204			vp = kzalloc(sizeof(struct qlcnic_vport), GFP_KERNEL);205			if (!vp) {206				err = -ENOMEM;207				goto qlcnic_destroy_async_wq;208			}209			sriov->vf_info[i].vp = vp;210			vp->vlan_mode = QLC_GUEST_VLAN_MODE;211			vp->max_tx_bw = MAX_BW;212			vp->min_tx_bw = MIN_BW;213			vp->spoofchk = false;214			eth_random_addr(vp->mac);215			dev_info(&adapter->pdev->dev,216				 "MAC Address %pM is configured for VF %d\n",217				 vp->mac, i);218		}219	}220 221	return 0;222 223qlcnic_destroy_async_wq:224	while (i--)225		kfree(sriov->vf_info[i].vp);226	destroy_workqueue(bc->bc_async_wq);227 228qlcnic_destroy_trans_wq:229	destroy_workqueue(bc->bc_trans_wq);230 231qlcnic_free_vf_info:232	kfree(sriov->vf_info);233 234qlcnic_free_sriov:235	kfree(adapter->ahw->sriov);236	return err;237}238 239void qlcnic_sriov_cleanup_list(struct qlcnic_trans_list *t_list)240{241	struct qlcnic_bc_trans *trans;242	struct qlcnic_cmd_args cmd;243	unsigned long flags;244 245	spin_lock_irqsave(&t_list->lock, flags);246 247	while (!list_empty(&t_list->wait_list)) {248		trans = list_first_entry(&t_list->wait_list,249					 struct qlcnic_bc_trans, list);250		list_del(&trans->list);251		t_list->count--;252		cmd.req.arg = (u32 *)trans->req_pay;253		cmd.rsp.arg = (u32 *)trans->rsp_pay;254		qlcnic_free_mbx_args(&cmd);255		qlcnic_sriov_cleanup_transaction(trans);256	}257 258	spin_unlock_irqrestore(&t_list->lock, flags);259}260 261void __qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)262{263	struct qlcnic_sriov *sriov = adapter->ahw->sriov;264	struct qlcnic_back_channel *bc = &sriov->bc;265	struct qlcnic_vf_info *vf;266	int i;267 268	if (!qlcnic_sriov_enable_check(adapter))269		return;270 271	qlcnic_sriov_cleanup_async_list(bc);272	destroy_workqueue(bc->bc_async_wq);273 274	for (i = 0; i < sriov->num_vfs; i++) {275		vf = &sriov->vf_info[i];276		qlcnic_sriov_cleanup_list(&vf->rcv_pend);277		cancel_work_sync(&vf->trans_work);278		qlcnic_sriov_cleanup_list(&vf->rcv_act);279	}280 281	destroy_workqueue(bc->bc_trans_wq);282 283	for (i = 0; i < sriov->num_vfs; i++)284		kfree(sriov->vf_info[i].vp);285 286	kfree(sriov->vf_info);287	kfree(adapter->ahw->sriov);288}289 290static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter)291{292	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);293	qlcnic_sriov_cfg_bc_intr(adapter, 0);294	__qlcnic_sriov_cleanup(adapter);295}296 297void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)298{299	if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state))300		return;301 302	qlcnic_sriov_free_vlans(adapter);303 304	if (qlcnic_sriov_pf_check(adapter))305		qlcnic_sriov_pf_cleanup(adapter);306 307	if (qlcnic_sriov_vf_check(adapter))308		qlcnic_sriov_vf_cleanup(adapter);309}310 311static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,312				    u32 *pay, u8 pci_func, u8 size)313{314	struct qlcnic_hardware_context *ahw = adapter->ahw;315	struct qlcnic_mailbox *mbx = ahw->mailbox;316	struct qlcnic_cmd_args cmd;317	unsigned long timeout;318	int err;319 320	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));321	cmd.hdr = hdr;322	cmd.pay = pay;323	cmd.pay_size = size;324	cmd.func_num = pci_func;325	cmd.op_type = QLC_83XX_MBX_POST_BC_OP;326	cmd.cmd_op = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;327 328	err = mbx->ops->enqueue_cmd(adapter, &cmd, &timeout);329	if (err) {330		dev_err(&adapter->pdev->dev,331			"%s: Mailbox not available, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",332			__func__, cmd.cmd_op, cmd.type, ahw->pci_func,333			ahw->op_mode);334		return err;335	}336 337	if (!wait_for_completion_timeout(&cmd.completion, timeout)) {338		dev_err(&adapter->pdev->dev,339			"%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",340			__func__, cmd.cmd_op, cmd.type, ahw->pci_func,341			ahw->op_mode);342		flush_workqueue(mbx->work_q);343	}344 345	return cmd.rsp_opcode;346}347 348static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter)349{350	adapter->num_rxd = QLC_DEFAULT_RCV_DESCRIPTORS_SRIOV_VF;351	adapter->max_rxd = MAX_RCV_DESCRIPTORS_10G;352	adapter->num_jumbo_rxd = QLC_DEFAULT_JUMBO_RCV_DESCRIPTORS_SRIOV_VF;353	adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;354	adapter->num_txd = MAX_CMD_DESCRIPTORS;355	adapter->max_rds_rings = MAX_RDS_RINGS;356}357 358int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *adapter,359				   struct qlcnic_info *npar_info, u16 vport_id)360{361	struct device *dev = &adapter->pdev->dev;362	struct qlcnic_cmd_args cmd;363	int err;364	u32 status;365 366	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);367	if (err)368		return err;369 370	cmd.req.arg[1] = vport_id << 16 | 0x1;371	err = qlcnic_issue_cmd(adapter, &cmd);372	if (err) {373		dev_err(&adapter->pdev->dev,374			"Failed to get vport info, err=%d\n", err);375		qlcnic_free_mbx_args(&cmd);376		return err;377	}378 379	status = cmd.rsp.arg[2] & 0xffff;380	if (status & BIT_0)381		npar_info->min_tx_bw = MSW(cmd.rsp.arg[2]);382	if (status & BIT_1)383		npar_info->max_tx_bw = LSW(cmd.rsp.arg[3]);384	if (status & BIT_2)385		npar_info->max_tx_ques = MSW(cmd.rsp.arg[3]);386	if (status & BIT_3)387		npar_info->max_tx_mac_filters = LSW(cmd.rsp.arg[4]);388	if (status & BIT_4)389		npar_info->max_rx_mcast_mac_filters = MSW(cmd.rsp.arg[4]);390	if (status & BIT_5)391		npar_info->max_rx_ucast_mac_filters = LSW(cmd.rsp.arg[5]);392	if (status & BIT_6)393		npar_info->max_rx_ip_addr = MSW(cmd.rsp.arg[5]);394	if (status & BIT_7)395		npar_info->max_rx_lro_flow = LSW(cmd.rsp.arg[6]);396	if (status & BIT_8)397		npar_info->max_rx_status_rings = MSW(cmd.rsp.arg[6]);398	if (status & BIT_9)399		npar_info->max_rx_buf_rings = LSW(cmd.rsp.arg[7]);400 401	npar_info->max_rx_ques = MSW(cmd.rsp.arg[7]);402	npar_info->max_tx_vlan_keys = LSW(cmd.rsp.arg[8]);403	npar_info->max_local_ipv6_addrs = MSW(cmd.rsp.arg[8]);404	npar_info->max_remote_ipv6_addrs = LSW(cmd.rsp.arg[9]);405 406	dev_info(dev, "\n\tmin_tx_bw: %d, max_tx_bw: %d max_tx_ques: %d,\n"407		 "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n"408		 "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n"409		 "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n"410		 "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n"411		 "\tlocal_ipv6_addr: %d, remote_ipv6_addr: %d\n",412		 npar_info->min_tx_bw, npar_info->max_tx_bw,413		 npar_info->max_tx_ques, npar_info->max_tx_mac_filters,414		 npar_info->max_rx_mcast_mac_filters,415		 npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr,416		 npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings,417		 npar_info->max_rx_buf_rings, npar_info->max_rx_ques,418		 npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs,419		 npar_info->max_remote_ipv6_addrs);420 421	qlcnic_free_mbx_args(&cmd);422	return err;423}424 425static int qlcnic_sriov_set_pvid_mode(struct qlcnic_adapter *adapter,426				      struct qlcnic_cmd_args *cmd)427{428	adapter->rx_pvid = MSW(cmd->rsp.arg[1]) & 0xffff;429	adapter->flags &= ~QLCNIC_TAGGING_ENABLED;430	return 0;431}432 433static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,434					    struct qlcnic_cmd_args *cmd)435{436	struct qlcnic_sriov *sriov = adapter->ahw->sriov;437	int i, num_vlans, ret;438	u16 *vlans;439 440	if (sriov->allowed_vlans)441		return 0;442 443	sriov->any_vlan = cmd->rsp.arg[2] & 0xf;444	sriov->num_allowed_vlans = cmd->rsp.arg[2] >> 16;445	dev_info(&adapter->pdev->dev, "Number of allowed Guest VLANs = %d\n",446		 sriov->num_allowed_vlans);447 448	ret = qlcnic_sriov_alloc_vlans(adapter);449	if (ret)450		return ret;451 452	if (!sriov->any_vlan)453		return 0;454 455	num_vlans = sriov->num_allowed_vlans;456	sriov->allowed_vlans = kcalloc(num_vlans, sizeof(u16), GFP_KERNEL);457	if (!sriov->allowed_vlans)458		return -ENOMEM;459 460	vlans = (u16 *)&cmd->rsp.arg[3];461	for (i = 0; i < num_vlans; i++)462		sriov->allowed_vlans[i] = vlans[i];463 464	return 0;465}466 467static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter)468{469	struct qlcnic_sriov *sriov = adapter->ahw->sriov;470	struct qlcnic_cmd_args cmd;471	int ret = 0;472 473	memset(&cmd, 0, sizeof(cmd));474	ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd, QLCNIC_BC_CMD_GET_ACL);475	if (ret)476		return ret;477 478	ret = qlcnic_issue_cmd(adapter, &cmd);479	if (ret) {480		dev_err(&adapter->pdev->dev, "Failed to get ACL, err=%d\n",481			ret);482	} else {483		sriov->vlan_mode = cmd.rsp.arg[1] & 0x3;484		switch (sriov->vlan_mode) {485		case QLC_GUEST_VLAN_MODE:486			ret = qlcnic_sriov_set_guest_vlan_mode(adapter, &cmd);487			break;488		case QLC_PVID_MODE:489			ret = qlcnic_sriov_set_pvid_mode(adapter, &cmd);490			break;491		}492	}493 494	qlcnic_free_mbx_args(&cmd);495	return ret;496}497 498static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)499{500	struct qlcnic_hardware_context *ahw = adapter->ahw;501	struct qlcnic_info nic_info;502	int err;503 504	err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0);505	if (err)506		return err;507 508	ahw->max_mc_count = nic_info.max_rx_mcast_mac_filters;509 510	err = qlcnic_get_nic_info(adapter, &nic_info, ahw->pci_func);511	if (err)512		return -EIO;513 514	if (qlcnic_83xx_get_port_info(adapter))515		return -EIO;516 517	qlcnic_sriov_vf_cfg_buff_desc(adapter);518	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;519	dev_info(&adapter->pdev->dev, "HAL Version: %d\n",520		 adapter->ahw->fw_hal_version);521 522	ahw->physical_port = (u8) nic_info.phys_port;523	ahw->switch_mode = nic_info.switch_mode;524	ahw->max_mtu = nic_info.max_mtu;525	ahw->op_mode = nic_info.op_mode;526	ahw->capabilities = nic_info.capabilities;527	return 0;528}529 530static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter)531{532	int err;533 534	adapter->flags |= QLCNIC_VLAN_FILTERING;535	adapter->ahw->total_nic_func = 1;536	INIT_LIST_HEAD(&adapter->vf_mc_list);537	if (!qlcnic_use_msi_x && !!qlcnic_use_msi)538		dev_warn(&adapter->pdev->dev,539			 "Device does not support MSI interrupts\n");540 541	/* compute and set default and max tx/sds rings */542	qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING);543	qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING);544 545	err = qlcnic_setup_intr(adapter);546	if (err) {547		dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");548		goto err_out_disable_msi;549	}550 551	err = qlcnic_83xx_setup_mbx_intr(adapter);552	if (err)553		goto err_out_disable_msi;554 555	err = qlcnic_sriov_init(adapter, 1);556	if (err)557		goto err_out_disable_mbx_intr;558 559	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);560	if (err)561		goto err_out_cleanup_sriov;562 563	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);564	if (err)565		goto err_out_disable_bc_intr;566 567	err = qlcnic_sriov_vf_init_driver(adapter);568	if (err)569		goto err_out_send_channel_term;570 571	err = qlcnic_sriov_get_vf_acl(adapter);572	if (err)573		goto err_out_send_channel_term;574 575	err = qlcnic_setup_netdev(adapter, adapter->netdev);576	if (err)577		goto err_out_send_channel_term;578 579	pci_set_drvdata(adapter->pdev, adapter);580	dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",581		 adapter->netdev->name);582 583	qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,584			     adapter->ahw->idc.delay);585	return 0;586 587err_out_send_channel_term:588	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);589 590err_out_disable_bc_intr:591	qlcnic_sriov_cfg_bc_intr(adapter, 0);592 593err_out_cleanup_sriov:594	__qlcnic_sriov_cleanup(adapter);595 596err_out_disable_mbx_intr:597	qlcnic_83xx_free_mbx_intr(adapter);598 599err_out_disable_msi:600	qlcnic_teardown_intr(adapter);601	return err;602}603 604static int qlcnic_sriov_check_dev_ready(struct qlcnic_adapter *adapter)605{606	u32 state;607 608	do {609		msleep(20);610		if (++adapter->fw_fail_cnt > QLC_BC_CMD_MAX_RETRY_CNT)611			return -EIO;612		state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);613	} while (state != QLC_83XX_IDC_DEV_READY);614 615	return 0;616}617 618int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter)619{620	struct qlcnic_hardware_context *ahw = adapter->ahw;621	int err;622 623	set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status);624	ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;625	ahw->reset_context = 0;626	adapter->fw_fail_cnt = 0;627	ahw->msix_supported = 1;628	adapter->need_fw_reset = 0;629	adapter->flags |= QLCNIC_TX_INTR_SHARED;630 631	err = qlcnic_sriov_check_dev_ready(adapter);632	if (err)633		return err;634 635	err = qlcnic_sriov_setup_vf(adapter);636	if (err)637		return err;638 639	if (qlcnic_read_mac_addr(adapter))640		dev_warn(&adapter->pdev->dev, "failed to read mac addr\n");641 642	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);643 644	clear_bit(__QLCNIC_RESETTING, &adapter->state);645	return 0;646}647 648void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *adapter)649{650	struct qlcnic_hardware_context *ahw = adapter->ahw;651 652	ahw->op_mode = QLCNIC_SRIOV_VF_FUNC;653	dev_info(&adapter->pdev->dev,654		 "HAL Version: %d Non Privileged SRIOV function\n",655		 ahw->fw_hal_version);656	adapter->nic_ops = &qlcnic_sriov_vf_ops;657	set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);658	return;659}660 661void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *ahw)662{663	ahw->hw_ops		= &qlcnic_sriov_vf_hw_ops;664	ahw->reg_tbl		= (u32 *)qlcnic_83xx_reg_tbl;665	ahw->ext_reg_tbl	= (u32 *)qlcnic_83xx_ext_reg_tbl;666}667 668static u32 qlcnic_sriov_get_bc_paysize(u32 real_pay_size, u8 curr_frag)669{670	u32 pay_size;671 672	pay_size = real_pay_size / ((curr_frag + 1) * QLC_BC_PAYLOAD_SZ);673 674	if (pay_size)675		pay_size = QLC_BC_PAYLOAD_SZ;676	else677		pay_size = real_pay_size % QLC_BC_PAYLOAD_SZ;678 679	return pay_size;680}681 682int qlcnic_sriov_func_to_index(struct qlcnic_adapter *adapter, u8 pci_func)683{684	struct qlcnic_vf_info *vf_info = adapter->ahw->sriov->vf_info;685	u8 i;686 687	if (qlcnic_sriov_vf_check(adapter))688		return 0;689 690	for (i = 0; i < adapter->ahw->sriov->num_vfs; i++) {691		if (vf_info[i].pci_func == pci_func)692			return i;693	}694 695	return -EINVAL;696}697 698static inline int qlcnic_sriov_alloc_bc_trans(struct qlcnic_bc_trans **trans)699{700	*trans = kzalloc(sizeof(struct qlcnic_bc_trans), GFP_ATOMIC);701	if (!*trans)702		return -ENOMEM;703 704	init_completion(&(*trans)->resp_cmpl);705	return 0;706}707 708static inline int qlcnic_sriov_alloc_bc_msg(struct qlcnic_bc_hdr **hdr,709					    u32 size)710{711	*hdr = kcalloc(size, sizeof(struct qlcnic_bc_hdr), GFP_ATOMIC);712	if (!*hdr)713		return -ENOMEM;714 715	return 0;716}717 718static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *mbx, u32 type)719{720	const struct qlcnic_mailbox_metadata *mbx_tbl;721	int i, size;722 723	mbx_tbl = qlcnic_sriov_bc_mbx_tbl;724	size = ARRAY_SIZE(qlcnic_sriov_bc_mbx_tbl);725 726	for (i = 0; i < size; i++) {727		if (type == mbx_tbl[i].cmd) {728			mbx->op_type = QLC_BC_CMD;729			mbx->req.num = mbx_tbl[i].in_args;730			mbx->rsp.num = mbx_tbl[i].out_args;731			mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),732					       GFP_ATOMIC);733			if (!mbx->req.arg)734				return -ENOMEM;735			mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),736					       GFP_ATOMIC);737			if (!mbx->rsp.arg) {738				kfree(mbx->req.arg);739				mbx->req.arg = NULL;740				return -ENOMEM;741			}742			mbx->req.arg[0] = (type | (mbx->req.num << 16) |743					   (3 << 29));744			mbx->rsp.arg[0] = (type & 0xffff) | mbx->rsp.num << 16;745			return 0;746		}747	}748	return -EINVAL;749}750 751static int qlcnic_sriov_prepare_bc_hdr(struct qlcnic_bc_trans *trans,752				       struct qlcnic_cmd_args *cmd,753				       u16 seq, u8 msg_type)754{755	struct qlcnic_bc_hdr *hdr;756	int i;757	u32 num_regs, bc_pay_sz;758	u16 remainder;759	u8 cmd_op, num_frags, t_num_frags;760 761	bc_pay_sz = QLC_BC_PAYLOAD_SZ;762	if (msg_type == QLC_BC_COMMAND) {763		trans->req_pay = (struct qlcnic_bc_payload *)cmd->req.arg;764		trans->rsp_pay = (struct qlcnic_bc_payload *)cmd->rsp.arg;765		num_regs = cmd->req.num;766		trans->req_pay_size = (num_regs * 4);767		num_regs = cmd->rsp.num;768		trans->rsp_pay_size = (num_regs * 4);769		cmd_op = cmd->req.arg[0] & 0xff;770		remainder = (trans->req_pay_size) % (bc_pay_sz);771		num_frags = (trans->req_pay_size) / (bc_pay_sz);772		if (remainder)773			num_frags++;774		t_num_frags = num_frags;775		if (qlcnic_sriov_alloc_bc_msg(&trans->req_hdr, num_frags))776			return -ENOMEM;777		remainder = (trans->rsp_pay_size) % (bc_pay_sz);778		num_frags = (trans->rsp_pay_size) / (bc_pay_sz);779		if (remainder)780			num_frags++;781		if (qlcnic_sriov_alloc_bc_msg(&trans->rsp_hdr, num_frags))782			return -ENOMEM;783		num_frags  = t_num_frags;784		hdr = trans->req_hdr;785	}  else {786		cmd->req.arg = (u32 *)trans->req_pay;787		cmd->rsp.arg = (u32 *)trans->rsp_pay;788		cmd_op = cmd->req.arg[0] & 0xff;789		cmd->cmd_op = cmd_op;790		remainder = (trans->rsp_pay_size) % (bc_pay_sz);791		num_frags = (trans->rsp_pay_size) / (bc_pay_sz);792		if (remainder)793			num_frags++;794		cmd->req.num = trans->req_pay_size / 4;795		cmd->rsp.num = trans->rsp_pay_size / 4;796		hdr = trans->rsp_hdr;797		cmd->op_type = trans->req_hdr->op_type;798	}799 800	trans->trans_id = seq;801	trans->cmd_id = cmd_op;802	for (i = 0; i < num_frags; i++) {803		hdr[i].version = 2;804		hdr[i].msg_type = msg_type;805		hdr[i].op_type = cmd->op_type;806		hdr[i].num_cmds = 1;807		hdr[i].num_frags = num_frags;808		hdr[i].frag_num = i + 1;809		hdr[i].cmd_op = cmd_op;810		hdr[i].seq_id = seq;811	}812	return 0;813}814 815static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *trans)816{817	if (!trans)818		return;819	kfree(trans->req_hdr);820	kfree(trans->rsp_hdr);821	kfree(trans);822}823 824static int qlcnic_sriov_clear_trans(struct qlcnic_vf_info *vf,825				    struct qlcnic_bc_trans *trans, u8 type)826{827	struct qlcnic_trans_list *t_list;828	unsigned long flags;829	int ret = 0;830 831	if (type == QLC_BC_RESPONSE) {832		t_list = &vf->rcv_act;833		spin_lock_irqsave(&t_list->lock, flags);834		t_list->count--;835		list_del(&trans->list);836		if (t_list->count > 0)837			ret = 1;838		spin_unlock_irqrestore(&t_list->lock, flags);839	}840	if (type == QLC_BC_COMMAND) {841		while (test_and_set_bit(QLC_BC_VF_SEND, &vf->state))842			msleep(100);843		vf->send_cmd = NULL;844		clear_bit(QLC_BC_VF_SEND, &vf->state);845	}846	return ret;847}848 849static void qlcnic_sriov_schedule_bc_cmd(struct qlcnic_sriov *sriov,850					 struct qlcnic_vf_info *vf,851					 work_func_t func)852{853	if (test_bit(QLC_BC_VF_FLR, &vf->state) ||854	    vf->adapter->need_fw_reset)855		return;856 857	queue_work(sriov->bc.bc_trans_wq, &vf->trans_work);858}859 860static inline void qlcnic_sriov_wait_for_resp(struct qlcnic_bc_trans *trans)861{862	struct completion *cmpl = &trans->resp_cmpl;863 864	if (wait_for_completion_timeout(cmpl, QLC_MBOX_RESP_TIMEOUT))865		trans->trans_state = QLC_END;866	else867		trans->trans_state = QLC_ABORT;868 869	return;870}871 872static void qlcnic_sriov_handle_multi_frags(struct qlcnic_bc_trans *trans,873					    u8 type)874{875	if (type == QLC_BC_RESPONSE) {876		trans->curr_rsp_frag++;877		if (trans->curr_rsp_frag < trans->rsp_hdr->num_frags)878			trans->trans_state = QLC_INIT;879		else880			trans->trans_state = QLC_END;881	} else {882		trans->curr_req_frag++;883		if (trans->curr_req_frag < trans->req_hdr->num_frags)884			trans->trans_state = QLC_INIT;885		else886			trans->trans_state = QLC_WAIT_FOR_RESP;887	}888}889 890static void qlcnic_sriov_wait_for_channel_free(struct qlcnic_bc_trans *trans,891					       u8 type)892{893	struct qlcnic_vf_info *vf = trans->vf;894	struct completion *cmpl = &vf->ch_free_cmpl;895 896	if (!wait_for_completion_timeout(cmpl, QLC_MBOX_CH_FREE_TIMEOUT)) {897		trans->trans_state = QLC_ABORT;898		return;899	}900 901	clear_bit(QLC_BC_VF_CHANNEL, &vf->state);902	qlcnic_sriov_handle_multi_frags(trans, type);903}904 905static void qlcnic_sriov_pull_bc_msg(struct qlcnic_adapter *adapter,906				     u32 *hdr, u32 *pay, u32 size)907{908	struct qlcnic_hardware_context *ahw = adapter->ahw;909	u8 i, max = 2, hdr_size, j;910 911	hdr_size = (sizeof(struct qlcnic_bc_hdr) / sizeof(u32));912	max = (size / sizeof(u32)) + hdr_size;913 914	for (i = 2, j = 0; j < hdr_size; i++, j++)915		*(hdr++) = readl(QLCNIC_MBX_FW(ahw, i));916	for (; j < max; i++, j++)917		*(pay++) = readl(QLCNIC_MBX_FW(ahw, i));918}919 920static int __qlcnic_sriov_issue_bc_post(struct qlcnic_vf_info *vf)921{922	int ret = -EBUSY;923	u32 timeout = 10000;924 925	do {926		if (!test_and_set_bit(QLC_BC_VF_CHANNEL, &vf->state)) {927			ret = 0;928			break;929		}930		mdelay(1);931	} while (--timeout);932 933	return ret;934}935 936static int qlcnic_sriov_issue_bc_post(struct qlcnic_bc_trans *trans, u8 type)937{938	struct qlcnic_vf_info *vf = trans->vf;939	u32 pay_size;940	u32 *hdr, *pay;941	int ret;942	u8 pci_func = trans->func_id;943 944	if (__qlcnic_sriov_issue_bc_post(vf))945		return -EBUSY;946 947	if (type == QLC_BC_COMMAND) {948		hdr = (u32 *)(trans->req_hdr + trans->curr_req_frag);949		pay = (u32 *)(trans->req_pay + trans->curr_req_frag);950		pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,951						       trans->curr_req_frag);952		pay_size = (pay_size / sizeof(u32));953	} else {954		hdr = (u32 *)(trans->rsp_hdr + trans->curr_rsp_frag);955		pay = (u32 *)(trans->rsp_pay + trans->curr_rsp_frag);956		pay_size = qlcnic_sriov_get_bc_paysize(trans->rsp_pay_size,957						       trans->curr_rsp_frag);958		pay_size = (pay_size / sizeof(u32));959	}960 961	ret = qlcnic_sriov_post_bc_msg(vf->adapter, hdr, pay,962				       pci_func, pay_size);963	return ret;964}965 966static int __qlcnic_sriov_send_bc_msg(struct qlcnic_bc_trans *trans,967				      struct qlcnic_vf_info *vf, u8 type)968{969	bool flag = true;970	int err = -EIO;971 972	while (flag) {973		if (test_bit(QLC_BC_VF_FLR, &vf->state) ||974		    vf->adapter->need_fw_reset)975			trans->trans_state = QLC_ABORT;976 977		switch (trans->trans_state) {978		case QLC_INIT:979			trans->trans_state = QLC_WAIT_FOR_CHANNEL_FREE;980			if (qlcnic_sriov_issue_bc_post(trans, type))981				trans->trans_state = QLC_ABORT;982			break;983		case QLC_WAIT_FOR_CHANNEL_FREE:984			qlcnic_sriov_wait_for_channel_free(trans, type);985			break;986		case QLC_WAIT_FOR_RESP:987			qlcnic_sriov_wait_for_resp(trans);988			break;989		case QLC_END:990			err = 0;991			flag = false;992			break;993		case QLC_ABORT:994			err = -EIO;995			flag = false;996			clear_bit(QLC_BC_VF_CHANNEL, &vf->state);997			break;998		default:999			err = -EIO;1000			flag = false;1001		}1002	}1003	return err;1004}1005 1006static int qlcnic_sriov_send_bc_cmd(struct qlcnic_adapter *adapter,1007				    struct qlcnic_bc_trans *trans, int pci_func)1008{1009	struct qlcnic_vf_info *vf;1010	int err, index = qlcnic_sriov_func_to_index(adapter, pci_func);1011 1012	if (index < 0)1013		return -EIO;1014 1015	vf = &adapter->ahw->sriov->vf_info[index];1016	trans->vf = vf;1017	trans->func_id = pci_func;1018 1019	if (!test_bit(QLC_BC_VF_STATE, &vf->state)) {1020		if (qlcnic_sriov_pf_check(adapter))1021			return -EIO;1022		if (qlcnic_sriov_vf_check(adapter) &&1023		    trans->cmd_id != QLCNIC_BC_CMD_CHANNEL_INIT)1024			return -EIO;1025	}1026 1027	mutex_lock(&vf->send_cmd_lock);1028	vf->send_cmd = trans;1029	err = __qlcnic_sriov_send_bc_msg(trans, vf, QLC_BC_COMMAND);1030	qlcnic_sriov_clear_trans(vf, trans, QLC_BC_COMMAND);1031	mutex_unlock(&vf->send_cmd_lock);1032	return err;1033}1034 1035static void __qlcnic_sriov_process_bc_cmd(struct qlcnic_adapter *adapter,1036					  struct qlcnic_bc_trans *trans,1037					  struct qlcnic_cmd_args *cmd)1038{1039#ifdef CONFIG_QLCNIC_SRIOV1040	if (qlcnic_sriov_pf_check(adapter)) {1041		qlcnic_sriov_pf_process_bc_cmd(adapter, trans, cmd);1042		return;1043	}1044#endif1045	cmd->rsp.arg[0] |= (0x9 << 25);1046	return;1047}1048 1049static void qlcnic_sriov_process_bc_cmd(struct work_struct *work)1050{1051	struct qlcnic_vf_info *vf = container_of(work, struct qlcnic_vf_info,1052						 trans_work);1053	struct qlcnic_bc_trans *trans = NULL;1054	struct qlcnic_adapter *adapter  = vf->adapter;1055	struct qlcnic_cmd_args cmd;1056	u8 req;1057 1058	if (adapter->need_fw_reset)1059		return;1060 1061	if (test_bit(QLC_BC_VF_FLR, &vf->state))1062		return;1063 1064	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));1065	trans = list_first_entry(&vf->rcv_act.wait_list,1066				 struct qlcnic_bc_trans, list);1067	adapter = vf->adapter;1068 1069	if (qlcnic_sriov_prepare_bc_hdr(trans, &cmd, trans->req_hdr->seq_id,1070					QLC_BC_RESPONSE))1071		goto cleanup_trans;1072 1073	__qlcnic_sriov_process_bc_cmd(adapter, trans, &cmd);1074	trans->trans_state = QLC_INIT;1075	__qlcnic_sriov_send_bc_msg(trans, vf, QLC_BC_RESPONSE);1076 1077cleanup_trans:1078	qlcnic_free_mbx_args(&cmd);1079	req = qlcnic_sriov_clear_trans(vf, trans, QLC_BC_RESPONSE);1080	qlcnic_sriov_cleanup_transaction(trans);1081	if (req)1082		qlcnic_sriov_schedule_bc_cmd(adapter->ahw->sriov, vf,1083					     qlcnic_sriov_process_bc_cmd);1084}1085 1086static void qlcnic_sriov_handle_bc_resp(struct qlcnic_bc_hdr *hdr,1087					struct qlcnic_vf_info *vf)1088{1089	struct qlcnic_bc_trans *trans;1090	u32 pay_size;1091 1092	if (test_and_set_bit(QLC_BC_VF_SEND, &vf->state))1093		return;1094 1095	trans = vf->send_cmd;1096 1097	if (trans == NULL)1098		goto clear_send;1099 1100	if (trans->trans_id != hdr->seq_id)1101		goto clear_send;1102 1103	pay_size = qlcnic_sriov_get_bc_paysize(trans->rsp_pay_size,1104					       trans->curr_rsp_frag);1105	qlcnic_sriov_pull_bc_msg(vf->adapter,1106				 (u32 *)(trans->rsp_hdr + trans->curr_rsp_frag),1107				 (u32 *)(trans->rsp_pay + trans->curr_rsp_frag),1108				 pay_size);1109	if (++trans->curr_rsp_frag < trans->rsp_hdr->num_frags)1110		goto clear_send;1111 1112	complete(&trans->resp_cmpl);1113 1114clear_send:1115	clear_bit(QLC_BC_VF_SEND, &vf->state);1116}1117 1118int __qlcnic_sriov_add_act_list(struct qlcnic_sriov *sriov,1119				struct qlcnic_vf_info *vf,1120				struct qlcnic_bc_trans *trans)1121{1122	struct qlcnic_trans_list *t_list = &vf->rcv_act;1123 1124	t_list->count++;1125	list_add_tail(&trans->list, &t_list->wait_list);1126	if (t_list->count == 1)1127		qlcnic_sriov_schedule_bc_cmd(sriov, vf,1128					     qlcnic_sriov_process_bc_cmd);1129	return 0;1130}1131 1132static int qlcnic_sriov_add_act_list(struct qlcnic_sriov *sriov,1133				     struct qlcnic_vf_info *vf,1134				     struct qlcnic_bc_trans *trans)1135{1136	struct qlcnic_trans_list *t_list = &vf->rcv_act;1137 1138	spin_lock(&t_list->lock);1139 1140	__qlcnic_sriov_add_act_list(sriov, vf, trans);1141 1142	spin_unlock(&t_list->lock);1143	return 0;1144}1145 1146static void qlcnic_sriov_handle_pending_trans(struct qlcnic_sriov *sriov,1147					      struct qlcnic_vf_info *vf,1148					      struct qlcnic_bc_hdr *hdr)1149{1150	struct qlcnic_bc_trans *trans = NULL;1151	struct list_head *node;1152	u32 pay_size, curr_frag;1153	u8 found = 0, active = 0;1154 1155	spin_lock(&vf->rcv_pend.lock);1156	if (vf->rcv_pend.count > 0) {1157		list_for_each(node, &vf->rcv_pend.wait_list) {1158			trans = list_entry(node, struct qlcnic_bc_trans, list);1159			if (trans->trans_id == hdr->seq_id) {1160				found = 1;1161				break;1162			}1163		}1164	}1165 1166	if (found) {1167		curr_frag = trans->curr_req_frag;1168		pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,1169						       curr_frag);1170		qlcnic_sriov_pull_bc_msg(vf->adapter,1171					 (u32 *)(trans->req_hdr + curr_frag),1172					 (u32 *)(trans->req_pay + curr_frag),1173					 pay_size);1174		trans->curr_req_frag++;1175		if (trans->curr_req_frag >= hdr->num_frags) {1176			vf->rcv_pend.count--;1177			list_del(&trans->list);1178			active = 1;1179		}1180	}1181	spin_unlock(&vf->rcv_pend.lock);1182 1183	if (active)1184		if (qlcnic_sriov_add_act_list(sriov, vf, trans))1185			qlcnic_sriov_cleanup_transaction(trans);1186 1187	return;1188}1189 1190static void qlcnic_sriov_handle_bc_cmd(struct qlcnic_sriov *sriov,1191				       struct qlcnic_bc_hdr *hdr,1192				       struct qlcnic_vf_info *vf)1193{1194	struct qlcnic_bc_trans *trans;1195	struct qlcnic_adapter *adapter = vf->adapter;1196	struct qlcnic_cmd_args cmd;1197	u32 pay_size;1198	int err;1199	u8 cmd_op;1200 1201	if (adapter->need_fw_reset)1202		return;1203 1204	if (!test_bit(QLC_BC_VF_STATE, &vf->state) &&1205	    hdr->op_type != QLC_BC_CMD &&1206	    hdr->cmd_op != QLCNIC_BC_CMD_CHANNEL_INIT)1207		return;1208 1209	if (hdr->frag_num > 1) {1210		qlcnic_sriov_handle_pending_trans(sriov, vf, hdr);1211		return;1212	}1213 1214	memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));1215	cmd_op = hdr->cmd_op;1216	if (qlcnic_sriov_alloc_bc_trans(&trans))1217		return;1218 1219	if (hdr->op_type == QLC_BC_CMD)1220		err = qlcnic_sriov_alloc_bc_mbx_args(&cmd, cmd_op);1221	else1222		err = qlcnic_alloc_mbx_args(&cmd, adapter, cmd_op);1223 1224	if (err) {1225		qlcnic_sriov_cleanup_transaction(trans);1226		return;1227	}1228 1229	cmd.op_type = hdr->op_type;1230	if (qlcnic_sriov_prepare_bc_hdr(trans, &cmd, hdr->seq_id,1231					QLC_BC_COMMAND)) {1232		qlcnic_free_mbx_args(&cmd);1233		qlcnic_sriov_cleanup_transaction(trans);1234		return;1235	}1236 1237	pay_size = qlcnic_sriov_get_bc_paysize(trans->req_pay_size,1238					 trans->curr_req_frag);1239	qlcnic_sriov_pull_bc_msg(vf->adapter,1240				 (u32 *)(trans->req_hdr + trans->curr_req_frag),1241				 (u32 *)(trans->req_pay + trans->curr_req_frag),1242				 pay_size);1243	trans->func_id = vf->pci_func;1244	trans->vf = vf;1245	trans->trans_id = hdr->seq_id;1246	trans->curr_req_frag++;1247 1248	if (qlcnic_sriov_soft_flr_check(adapter, trans, vf))1249		return;1250 1251	if (trans->curr_req_frag == trans->req_hdr->num_frags) {1252		if (qlcnic_sriov_add_act_list(sriov, vf, trans)) {1253			qlcnic_free_mbx_args(&cmd);1254			qlcnic_sriov_cleanup_transaction(trans);1255		}1256	} else {1257		spin_lock(&vf->rcv_pend.lock);1258		list_add_tail(&trans->list, &vf->rcv_pend.wait_list);1259		vf->rcv_pend.count++;1260		spin_unlock(&vf->rcv_pend.lock);1261	}1262}1263 1264static void qlcnic_sriov_handle_msg_event(struct qlcnic_sriov *sriov,1265					  struct qlcnic_vf_info *vf)1266{1267	struct qlcnic_bc_hdr hdr;1268	u32 *ptr = (u32 *)&hdr;1269	u8 msg_type, i;1270 1271	for (i = 2; i < 6; i++)1272		ptr[i - 2] = readl(QLCNIC_MBX_FW(vf->adapter->ahw, i));1273	msg_type = hdr.msg_type;1274 1275	switch (msg_type) {1276	case QLC_BC_COMMAND:1277		qlcnic_sriov_handle_bc_cmd(sriov, &hdr, vf);1278		break;1279	case QLC_BC_RESPONSE:1280		qlcnic_sriov_handle_bc_resp(&hdr, vf);1281		break;1282	}1283}1284 1285static void qlcnic_sriov_handle_flr_event(struct qlcnic_sriov *sriov,1286					  struct qlcnic_vf_info *vf)1287{1288	struct qlcnic_adapter *adapter = vf->adapter;1289 1290	if (qlcnic_sriov_pf_check(adapter))1291		qlcnic_sriov_pf_handle_flr(sriov, vf);1292	else1293		dev_err(&adapter->pdev->dev,1294			"Invalid event to VF. VF should not get FLR event\n");1295}1296 1297void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *adapter, u32 event)1298{1299	struct qlcnic_vf_info *vf;1300	struct qlcnic_sriov *sriov;1301	int index;1302	u8 pci_func;1303 1304	sriov = adapter->ahw->sriov;1305	pci_func = qlcnic_sriov_target_func_id(event);1306	index = qlcnic_sriov_func_to_index(adapter, pci_func);1307 1308	if (index < 0)1309		return;1310 1311	vf = &sriov->vf_info[index];1312	vf->pci_func = pci_func;1313 1314	if (qlcnic_sriov_channel_free_check(event))1315		complete(&vf->ch_free_cmpl);1316 1317	if (qlcnic_sriov_flr_check(event)) {1318		qlcnic_sriov_handle_flr_event(sriov, vf);1319		return;1320	}1321 1322	if (qlcnic_sriov_bc_msg_check(event))1323		qlcnic_sriov_handle_msg_event(sriov, vf);1324}1325 1326int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *adapter, u8 enable)1327{1328	struct qlcnic_cmd_args cmd;1329	int err;1330 1331	if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state))1332		return 0;1333 1334	if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_BC_EVENT_SETUP))1335		return -ENOMEM;1336 1337	if (enable)1338		cmd.req.arg[1] = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7);1339 1340	err = qlcnic_83xx_issue_cmd(adapter, &cmd);1341 1342	if (err != QLCNIC_RCODE_SUCCESS) {1343		dev_err(&adapter->pdev->dev,1344			"Failed to %s bc events, err=%d\n",1345			(enable ? "enable" : "disable"), err);1346	}1347 1348	qlcnic_free_mbx_args(&cmd);1349	return err;1350}1351 1352static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter,1353				     struct qlcnic_bc_trans *trans)1354{1355	u8 max = QLC_BC_CMD_MAX_RETRY_CNT;1356	u32 state;1357 1358	state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);1359	if (state == QLC_83XX_IDC_DEV_READY) {1360		msleep(20);1361		clear_bit(QLC_BC_VF_CHANNEL, &trans->vf->state);1362		trans->trans_state = QLC_INIT;1363		if (++adapter->fw_fail_cnt > max)1364			return -EIO;1365		else1366			return 0;1367	}1368 1369	return -EIO;1370}1371 1372static int __qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,1373				  struct qlcnic_cmd_args *cmd)1374{1375	struct qlcnic_hardware_context *ahw = adapter->ahw;1376	struct qlcnic_mailbox *mbx = ahw->mailbox;1377	struct device *dev = &adapter->pdev->dev;1378	struct qlcnic_bc_trans *trans;1379	int err;1380	u32 rsp_data, opcode, mbx_err_code, rsp;1381	u16 seq = ++adapter->ahw->sriov->bc.trans_counter;1382	u8 func = ahw->pci_func;1383 1384	rsp = qlcnic_sriov_alloc_bc_trans(&trans);1385	if (rsp)1386		goto free_cmd;1387 1388	rsp = qlcnic_sriov_prepare_bc_hdr(trans, cmd, seq, QLC_BC_COMMAND);1389	if (rsp)1390		goto cleanup_transaction;1391 1392retry:1393	if (!test_bit(QLC_83XX_MBX_READY, &mbx->status)) {1394		rsp = -EIO;1395		QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n",1396		      QLCNIC_MBX_RSP(cmd->req.arg[0]), func);1397		goto err_out;1398	}1399 1400	err = qlcnic_sriov_send_bc_cmd(adapter, trans, func);1401	if (err) {1402		dev_err(dev, "MBX command 0x%x timed out for VF %d\n",1403			(cmd->req.arg[0] & 0xffff), func);1404		rsp = QLCNIC_RCODE_TIMEOUT;1405 1406		/* After adapter reset PF driver may take some time to1407		 * respond to VF's request. Retry request till maximum retries.1408		 */1409		if ((trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) &&1410		    !qlcnic_sriov_retry_bc_cmd(adapter, trans))1411			goto retry;1412 1413		goto err_out;1414	}1415 1416	rsp_data = cmd->rsp.arg[0];1417	mbx_err_code = QLCNIC_MBX_STATUS(rsp_data);1418	opcode = QLCNIC_MBX_RSP(cmd->req.arg[0]);1419 1420	if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||1421	    (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {1422		rsp = QLCNIC_RCODE_SUCCESS;1423	} else {1424		if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {1425			rsp = QLCNIC_RCODE_SUCCESS;1426		} else {1427			rsp = mbx_err_code;1428			if (!rsp)1429				rsp = 1;1430 1431			dev_err(dev,1432				"MBX command 0x%x failed with err:0x%x for VF %d\n",1433				opcode, mbx_err_code, func);1434		}1435	}1436 1437err_out:1438	if (rsp == QLCNIC_RCODE_TIMEOUT) {1439		ahw->reset_context = 1;1440		adapter->need_fw_reset = 1;1441		clear_bit(QLC_83XX_MBX_READY, &mbx->status);1442	}1443 1444cleanup_transaction:1445	qlcnic_sriov_cleanup_transaction(trans);1446 1447free_cmd:1448	if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {1449		qlcnic_free_mbx_args(cmd);1450		kfree(cmd);1451	}1452 1453	return rsp;1454}1455 1456 1457static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,1458				  struct qlcnic_cmd_args *cmd)1459{1460	if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT)1461		return qlcnic_sriov_async_issue_cmd(adapter, cmd);1462	else1463		return __qlcnic_sriov_issue_cmd(adapter, cmd);1464}1465 1466static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op)1467{1468	struct qlcnic_cmd_args cmd;1469	struct qlcnic_vf_info *vf = &adapter->ahw->sriov->vf_info[0];1470	int ret;1471 1472	memset(&cmd, 0, sizeof(cmd));1473	if (qlcnic_sriov_alloc_bc_mbx_args(&cmd, cmd_op))1474		return -ENOMEM;1475 1476	ret = qlcnic_issue_cmd(adapter, &cmd);1477	if (ret) {1478		dev_err(&adapter->pdev->dev,1479			"Failed bc channel %s %d\n", cmd_op ? "term" : "init",1480			ret);1481		goto out;1482	}1483 1484	cmd_op = (cmd.rsp.arg[0] & 0xff);1485	if (cmd.rsp.arg[0] >> 25 == 2)1486		return 2;1487	if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)1488		set_bit(QLC_BC_VF_STATE, &vf->state);1489	else1490		clear_bit(QLC_BC_VF_STATE, &vf->state);1491 1492out:1493	qlcnic_free_mbx_args(&cmd);1494	return ret;1495}1496 1497static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac,1498				  enum qlcnic_mac_type mac_type)1499{1500	struct qlcnic_adapter *adapter = netdev_priv(netdev);1501	struct qlcnic_sriov *sriov = adapter->ahw->sriov;1502	struct qlcnic_vf_info *vf;1503	u16 vlan_id;1504	int i;1505 1506	vf = &adapter->ahw->sriov->vf_info[0];1507 1508	if (!qlcnic_sriov_check_any_vlan(vf)) {1509		qlcnic_nic_add_mac(adapter, mac, 0, mac_type);1510	} else {1511		spin_lock(&vf->vlan_list_lock);1512		for (i = 0; i < sriov->num_allowed_vlans; i++) {1513			vlan_id = vf->sriov_vlans[i];1514			if (vlan_id)1515				qlcnic_nic_add_mac(adapter, mac, vlan_id,1516						   mac_type);1517		}1518		spin_unlock(&vf->vlan_list_lock);1519		if (qlcnic_84xx_check(adapter))1520			qlcnic_nic_add_mac(adapter, mac, 0, mac_type);1521	}1522}1523 1524void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc)1525{1526	struct list_head *head = &bc->async_cmd_list;1527	struct qlcnic_async_cmd *entry;1528 1529	flush_workqueue(bc->bc_async_wq);1530	cancel_work_sync(&bc->vf_async_work);1531 1532	spin_lock(&bc->queue_lock);1533	while (!list_empty(head)) {1534		entry = list_entry(head->next, struct qlcnic_async_cmd,1535				   list);1536		list_del(&entry->list);1537		kfree(entry->cmd);1538		kfree(entry);1539	}1540	spin_unlock(&bc->queue_lock);1541}1542 1543void qlcnic_sriov_vf_set_multi(struct net_device *netdev)1544{1545	struct qlcnic_adapter *adapter = netdev_priv(netdev);1546	struct qlcnic_hardware_context *ahw = adapter->ahw;1547	static const u8 bcast_addr[ETH_ALEN] = {1548		0xff, 0xff, 0xff, 0xff, 0xff, 0xff1549	};1550	struct netdev_hw_addr *ha;1551	u32 mode = VPORT_MISS_MODE_DROP;1552 1553	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))1554		return;1555 1556	if (netdev->flags & IFF_PROMISC) {1557		if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))1558			mode = VPORT_MISS_MODE_ACCEPT_ALL;1559	} else if ((netdev->flags & IFF_ALLMULTI) ||1560		   (netdev_mc_count(netdev) > ahw->max_mc_count)) {1561		mode = VPORT_MISS_MODE_ACCEPT_MULTI;1562	} else {1563		qlcnic_vf_add_mc_list(netdev, bcast_addr, QLCNIC_BROADCAST_MAC);1564		if (!netdev_mc_empty(netdev)) {1565			qlcnic_flush_mcast_mac(adapter);1566			netdev_for_each_mc_addr(ha, netdev)1567				qlcnic_vf_add_mc_list(netdev, ha->addr,1568						      QLCNIC_MULTICAST_MAC);1569		}1570	}1571 1572	/* configure unicast MAC address, if there is not sufficient space1573	 * to store all the unicast addresses then enable promiscuous mode1574	 */1575	if (netdev_uc_count(netdev) > ahw->max_uc_count) {1576		mode = VPORT_MISS_MODE_ACCEPT_ALL;1577	} else if (!netdev_uc_empty(netdev)) {1578		netdev_for_each_uc_addr(ha, netdev)1579			qlcnic_vf_add_mc_list(netdev, ha->addr,1580					      QLCNIC_UNICAST_MAC);1581	}1582 1583	if (adapter->pdev->is_virtfn) {1584		if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&1585		    !adapter->fdb_mac_learn) {1586			qlcnic_alloc_lb_filters_mem(adapter);1587			adapter->drv_mac_learn = true;1588			adapter->rx_mac_learn = true;1589		} else {1590			adapter->drv_mac_learn = false;1591			adapter->rx_mac_learn = false;1592		}1593	}1594 1595	qlcnic_nic_set_promisc(adapter, mode);1596}1597 1598static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work)1599{1600	struct qlcnic_async_cmd *entry, *tmp;1601	struct qlcnic_back_channel *bc;1602	struct qlcnic_cmd_args *cmd;1603	struct list_head *head;1604	LIST_HEAD(del_list);1605 1606	bc = container_of(work, struct qlcnic_back_channel, vf_async_work);1607	head = &bc->async_cmd_list;1608 1609	spin_lock(&bc->queue_lock);1610	list_splice_init(head, &del_list);1611	spin_unlock(&bc->queue_lock);1612 1613	list_for_each_entry_safe(entry, tmp, &del_list, list) {1614		list_del(&entry->list);1615		cmd = entry->cmd;1616		__qlcnic_sriov_issue_cmd(bc->adapter, cmd);1617		kfree(entry);1618	}1619 1620	if (!list_empty(head))1621		queue_work(bc->bc_async_wq, &bc->vf_async_work);1622 1623	return;1624}1625 1626static struct qlcnic_async_cmd *1627qlcnic_sriov_alloc_async_cmd(struct qlcnic_back_channel *bc,1628			     struct qlcnic_cmd_args *cmd)1629{1630	struct qlcnic_async_cmd *entry = NULL;1631 1632	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);1633	if (!entry)1634		return NULL;1635 1636	entry->cmd = cmd;1637 1638	spin_lock(&bc->queue_lock);1639	list_add_tail(&entry->list, &bc->async_cmd_list);1640	spin_unlock(&bc->queue_lock);1641 1642	return entry;1643}1644 1645static void qlcnic_sriov_schedule_async_cmd(struct qlcnic_back_channel *bc,1646					    struct qlcnic_cmd_args *cmd)1647{1648	struct qlcnic_async_cmd *entry = NULL;1649 1650	entry = qlcnic_sriov_alloc_async_cmd(bc, cmd);1651	if (!entry) {1652		qlcnic_free_mbx_args(cmd);1653		kfree(cmd);1654		return;1655	}1656 1657	queue_work(bc->bc_async_wq, &bc->vf_async_work);1658}1659 1660static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *adapter,1661					struct qlcnic_cmd_args *cmd)1662{1663 1664	struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc;1665 1666	if (adapter->need_fw_reset)1667		return -EIO;1668 1669	qlcnic_sriov_schedule_async_cmd(bc, cmd);1670 1671	return 0;1672}1673 1674static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)1675{1676	int err;1677 1678	adapter->need_fw_reset = 0;1679	qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox);1680	qlcnic_83xx_enable_mbx_interrupt(adapter);1681 1682	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);1683	if (err)1684		return err;1685 1686	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);1687	if (err)1688		goto err_out_cleanup_bc_intr;1689 1690	err = qlcnic_sriov_vf_init_driver(adapter);1691	if (err)1692		goto err_out_term_channel;1693 1694	return 0;1695 1696err_out_term_channel:1697	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);1698 1699err_out_cleanup_bc_intr:1700	qlcnic_sriov_cfg_bc_intr(adapter, 0);1701	return err;1702}1703 1704static void qlcnic_sriov_vf_attach(struct qlcnic_adapter *adapter)1705{1706	struct net_device *netdev = adapter->netdev;1707 1708	if (netif_running(netdev)) {1709		if (!qlcnic_up(adapter, netdev))1710			qlcnic_restore_indev_addr(netdev, NETDEV_UP);1711	}1712 1713	netif_device_attach(netdev);1714}1715 1716static void qlcnic_sriov_vf_detach(struct qlcnic_adapter *adapter)1717{1718	struct qlcnic_hardware_context *ahw = adapter->ahw;1719	struct qlcnic_intrpt_config *intr_tbl = ahw->intr_tbl;1720	struct net_device *netdev = adapter->netdev;1721	u8 i, max_ints = ahw->num_msix - 1;1722 1723	netif_device_detach(netdev);1724	qlcnic_83xx_detach_mailbox_work(adapter);1725	qlcnic_83xx_disable_mbx_intr(adapter);1726 1727	if (netif_running(netdev))1728		qlcnic_down(adapter, netdev);1729 1730	for (i = 0; i < max_ints; i++) {1731		intr_tbl[i].id = i;1732		intr_tbl[i].enabled = 0;1733		intr_tbl[i].src = 0;1734	}1735	ahw->reset_context = 0;1736}1737 1738static int qlcnic_sriov_vf_handle_dev_ready(struct qlcnic_adapter *adapter)1739{1740	struct qlcnic_hardware_context *ahw = adapter->ahw;1741	struct device *dev = &adapter->pdev->dev;1742	struct qlc_83xx_idc *idc = &ahw->idc;1743	u8 func = ahw->pci_func;1744	u32 state;1745 1746	if ((idc->prev_state == QLC_83XX_IDC_DEV_NEED_RESET) ||1747	    (idc->prev_state == QLC_83XX_IDC_DEV_INIT)) {1748		if (!qlcnic_sriov_vf_reinit_driver(adapter)) {1749			qlcnic_sriov_vf_attach(adapter);1750			adapter->fw_fail_cnt = 0;1751			dev_info(dev,1752				 "%s: Reinitialization of VF 0x%x done after FW reset\n",1753				 __func__, func);1754		} else {1755			dev_err(dev,1756				"%s: Reinitialization of VF 0x%x failed after FW reset\n",1757				__func__, func);1758			state = QLCRDX(ahw, QLC_83XX_IDC_DEV_STATE);1759			dev_info(dev, "Current state 0x%x after FW reset\n",1760				 state);1761		}1762	}1763 1764	return 0;1765}1766 1767static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)1768{1769	struct qlcnic_hardware_context *ahw = adapter->ahw;1770	struct qlcnic_mailbox *mbx = ahw->mailbox;1771	struct device *dev = &adapter->pdev->dev;1772	struct qlc_83xx_idc *idc = &ahw->idc;1773	u8 func = ahw->pci_func;1774	u32 state;1775 1776	adapter->reset_ctx_cnt++;1777 1778	/* Skip the context reset and check if FW is hung */1779	if (adapter->reset_ctx_cnt < 3) {1780		adapter->need_fw_reset = 1;1781		clear_bit(QLC_83XX_MBX_READY, &mbx->status);1782		dev_info(dev,1783			 "Resetting context, wait here to check if FW is in failed state\n");1784		return 0;1785	}1786 1787	/* Check if number of resets exceed the threshold.1788	 * If it exceeds the threshold just fail the VF.1789	 */1790	if (adapter->reset_ctx_cnt > QLC_83XX_VF_RESET_FAIL_THRESH) {1791		clear_bit(QLC_83XX_MODULE_LOADED, &idc->status);1792		adapter->tx_timeo_cnt = 0;1793		adapter->fw_fail_cnt = 0;1794		adapter->reset_ctx_cnt = 0;1795		qlcnic_sriov_vf_detach(adapter);1796		dev_err(dev,1797			"Device context resets have exceeded the threshold, device interface will be shutdown\n");1798		return -EIO;1799	}1800 1801	dev_info(dev, "Resetting context of VF 0x%x\n", func);1802	dev_info(dev, "%s: Context reset count %d for VF 0x%x\n",1803		 __func__, adapter->reset_ctx_cnt, func);1804	set_bit(__QLCNIC_RESETTING, &adapter->state);1805	adapter->need_fw_reset = 1;1806	clear_bit(QLC_83XX_MBX_READY, &mbx->status);1807	qlcnic_sriov_vf_detach(adapter);1808	adapter->need_fw_reset = 0;1809 1810	if (!qlcnic_sriov_vf_reinit_driver(adapter)) {1811		qlcnic_sriov_vf_attach(adapter);1812		adapter->tx_timeo_cnt = 0;1813		adapter->reset_ctx_cnt = 0;1814		adapter->fw_fail_cnt = 0;1815		dev_info(dev, "Done resetting context for VF 0x%x\n", func);1816	} else {1817		dev_err(dev, "%s: Reinitialization of VF 0x%x failed\n",1818			__func__, func);1819		state = QLCRDX(ahw, QLC_83XX_IDC_DEV_STATE);1820		dev_info(dev, "%s: Current state 0x%x\n", __func__, state);1821	}1822 1823	return 0;1824}1825 1826static int qlcnic_sriov_vf_idc_ready_state(struct qlcnic_adapter *adapter)1827{1828	struct qlcnic_hardware_context *ahw = adapter->ahw;1829	int ret = 0;1830 1831	if (ahw->idc.prev_state != QLC_83XX_IDC_DEV_READY)1832		ret = qlcnic_sriov_vf_handle_dev_ready(adapter);1833	else if (ahw->reset_context)1834		ret = qlcnic_sriov_vf_handle_context_reset(adapter);1835 1836	clear_bit(__QLCNIC_RESETTING, &adapter->state);1837	return ret;1838}1839 1840static int qlcnic_sriov_vf_idc_failed_state(struct qlcnic_adapter *adapter)1841{1842	struct qlc_83xx_idc *idc = &adapter->ahw->idc;1843 1844	dev_err(&adapter->pdev->dev, "Device is in failed state\n");1845	if (idc->prev_state == QLC_83XX_IDC_DEV_READY)1846		qlcnic_sriov_vf_detach(adapter);1847 1848	clear_bit(QLC_83XX_MODULE_LOADED, &idc->status);1849	clear_bit(__QLCNIC_RESETTING, &adapter->state);1850	return -EIO;1851}1852 1853static int1854qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)1855{1856	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;1857	struct qlc_83xx_idc *idc = &adapter->ahw->idc;1858 1859	dev_info(&adapter->pdev->dev, "Device is in quiescent state\n");1860	if (idc->prev_state == QLC_83XX_IDC_DEV_READY) {1861		set_bit(__QLCNIC_RESETTING, &adapter->state);1862		adapter->tx_timeo_cnt = 0;1863		adapter->reset_ctx_cnt = 0;1864		clear_bit(QLC_83XX_MBX_READY, &mbx->status);1865		qlcnic_sriov_vf_detach(adapter);1866	}1867 1868	return 0;1869}1870 1871static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)1872{1873	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;1874	struct qlc_83xx_idc *idc = &adapter->ahw->idc;1875	u8 func = adapter->ahw->pci_func;1876 1877	if (idc->prev_state == QLC_83XX_IDC_DEV_READY) {1878		dev_err(&adapter->pdev->dev,1879			"Firmware hang detected by VF 0x%x\n", func);1880		set_bit(__QLCNIC_RESETTING, &adapter->state);1881		adapter->tx_timeo_cnt = 0;1882		adapter->reset_ctx_cnt = 0;1883		clear_bit(QLC_83XX_MBX_READY, &mbx->status);1884		qlcnic_sriov_vf_detach(adapter);1885	}1886	return 0;1887}1888 1889static int qlcnic_sriov_vf_idc_unknown_state(struct qlcnic_adapter *adapter)1890{1891	dev_err(&adapter->pdev->dev, "%s: Device in unknown state\n", __func__);1892	return 0;1893}1894 1895static void qlcnic_sriov_vf_periodic_tasks(struct qlcnic_adapter *adapter)1896{1897	if (adapter->fhash.fnum)1898		qlcnic_prune_lb_filters(adapter);1899}1900 1901static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work)1902{1903	struct qlcnic_adapter *adapter;1904	struct qlc_83xx_idc *idc;1905	int ret = 0;1906 1907	adapter = container_of(work, struct qlcnic_adapter, fw_work.work);1908	idc = &adapter->ahw->idc;1909	idc->curr_state = QLCRDX(adapter->ahw, QLC_83XX_IDC_DEV_STATE);1910 1911	switch (idc->curr_state) {1912	case QLC_83XX_IDC_DEV_READY:1913		ret = qlcnic_sriov_vf_idc_ready_state(adapter);1914		break;1915	case QLC_83XX_IDC_DEV_NEED_RESET:1916	case QLC_83XX_IDC_DEV_INIT:1917		ret = qlcnic_sriov_vf_idc_init_reset_state(adapter);1918		break;1919	case QLC_83XX_IDC_DEV_NEED_QUISCENT:1920		ret = qlcnic_sriov_vf_idc_need_quiescent_state(adapter);1921		break;1922	case QLC_83XX_IDC_DEV_FAILED:1923		ret = qlcnic_sriov_vf_idc_failed_state(adapter);1924		break;1925	case QLC_83XX_IDC_DEV_QUISCENT:1926		break;1927	default:1928		ret = qlcnic_sriov_vf_idc_unknown_state(adapter);1929	}1930 1931	idc->prev_state = idc->curr_state;1932	qlcnic_sriov_vf_periodic_tasks(adapter);1933 1934	if (!ret && test_bit(QLC_83XX_MODULE_LOADED, &idc->status))1935		qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,1936				     idc->delay);1937}1938 1939static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *adapter)1940{1941	while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))1942		msleep(20);1943 1944	clear_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);1945	clear_bit(__QLCNIC_RESETTING, &adapter->state);1946	cancel_delayed_work_sync(&adapter->fw_work);1947}1948 1949static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov,1950				      struct qlcnic_vf_info *vf, u16 vlan_id)1951{1952	int i, err = -EINVAL;1953 1954	if (!vf->sriov_vlans)1955		return err;1956 1957	spin_lock_bh(&vf->vlan_list_lock);1958 1959	for (i = 0; i < sriov->num_allowed_vlans; i++) {1960		if (vf->sriov_vlans[i] == vlan_id) {1961			err = 0;1962			break;1963		}1964	}1965 1966	spin_unlock_bh(&vf->vlan_list_lock);1967	return err;1968}1969 1970static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov,1971					   struct qlcnic_vf_info *vf)1972{1973	int err = 0;1974 1975	spin_lock_bh(&vf->vlan_list_lock);1976 1977	if (vf->num_vlan >= sriov->num_allowed_vlans)1978		err = -EINVAL;1979 1980	spin_unlock_bh(&vf->vlan_list_lock);1981	return err;1982}1983 1984static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_adapter *adapter,1985					  u16 vid, u8 enable)1986{1987	struct qlcnic_sriov *sriov = adapter->ahw->sriov;1988	struct qlcnic_vf_info *vf;1989	bool vlan_exist;1990	u8 allowed = 0;1991	int i;1992 1993	vf = &adapter->ahw->sriov->vf_info[0];1994	vlan_exist = qlcnic_sriov_check_any_vlan(vf);1995	if (sriov->vlan_mode != QLC_GUEST_VLAN_MODE)1996		return -EINVAL;1997 1998	if (enable) {1999		if (qlcnic_83xx_vf_check(adapter) && vlan_exist)2000			return -EINVAL;2001 2002		if (qlcnic_sriov_validate_num_vlans(sriov, vf))2003			return -EINVAL;2004 2005		if (sriov->any_vlan) {2006			for (i = 0; i < sriov->num_allowed_vlans; i++) {2007				if (sriov->allowed_vlans[i] == vid)2008					allowed = 1;2009			}2010 2011			if (!allowed)2012				return -EINVAL;2013		}2014	} else {2015		if (!vlan_exist || qlcnic_sriov_check_vlan_id(sriov, vf, vid))2016			return -EINVAL;2017	}2018 2019	return 0;2020}2021 2022static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id,2023					enum qlcnic_vlan_operations opcode)2024{2025	struct qlcnic_adapter *adapter = vf->adapter;2026	struct qlcnic_sriov *sriov;2027 2028	sriov = adapter->ahw->sriov;2029 2030	if (!vf->sriov_vlans)2031		return;2032 2033	spin_lock_bh(&vf->vlan_list_lock);2034 2035	switch (opcode) {2036	case QLC_VLAN_ADD:2037		qlcnic_sriov_add_vlan_id(sriov, vf, vlan_id);2038		break;2039	case QLC_VLAN_DELETE:2040		qlcnic_sriov_del_vlan_id(sriov, vf, vlan_id);2041		break;2042	default:2043		netdev_err(adapter->netdev, "Invalid VLAN operation\n");2044	}2045 2046	spin_unlock_bh(&vf->vlan_list_lock);2047	return;2048}2049 2050int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter,2051				   u16 vid, u8 enable)2052{2053	struct qlcnic_sriov *sriov = adapter->ahw->sriov;2054	struct net_device *netdev = adapter->netdev;2055	struct qlcnic_vf_info *vf;2056	struct qlcnic_cmd_args cmd;2057	int ret;2058 2059	memset(&cmd, 0, sizeof(cmd));2060	if (vid == 0)2061		return 0;2062 2063	vf = &adapter->ahw->sriov->vf_info[0];2064	ret = qlcnic_sriov_validate_vlan_cfg(adapter, vid, enable);2065	if (ret)2066		return ret;2067 2068	ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd,2069					     QLCNIC_BC_CMD_CFG_GUEST_VLAN);2070	if (ret)2071		return ret;2072 2073	cmd.req.arg[1] = (enable & 1) | vid << 16;2074 2075	qlcnic_sriov_cleanup_async_list(&sriov->bc);2076	ret = qlcnic_issue_cmd(adapter, &cmd);2077	if (ret) {2078		dev_err(&adapter->pdev->dev,2079			"Failed to configure guest VLAN, err=%d\n", ret);2080	} else {2081		netif_addr_lock_bh(netdev);2082		qlcnic_free_mac_list(adapter);2083		netif_addr_unlock_bh(netdev);2084 2085		if (enable)2086			qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD);2087		else2088			qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE);2089 2090		netif_addr_lock_bh(netdev);2091		qlcnic_set_multi(netdev);2092		netif_addr_unlock_bh(netdev);2093	}2094 2095	qlcnic_free_mbx_args(&cmd);2096	return ret;2097}2098 2099static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter)2100{2101	struct list_head *head = &adapter->mac_list;2102	struct qlcnic_mac_vlan_list *cur;2103 2104	while (!list_empty(head)) {2105		cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list);2106		qlcnic_sre_macaddr_change(adapter, cur->mac_addr, cur->vlan_id,2107					  QLCNIC_MAC_DEL);2108		list_del(&cur->list);2109		kfree(cur);2110	}2111}2112 2113 2114static int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev)2115{2116	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);2117	struct net_device *netdev = adapter->netdev;2118 2119	netif_device_detach(netdev);2120	qlcnic_cancel_idc_work(adapter);2121 2122	if (netif_running(netdev))2123		qlcnic_down(adapter, netdev);2124 2125	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);2126	qlcnic_sriov_cfg_bc_intr(adapter, 0);2127	qlcnic_83xx_disable_mbx_intr(adapter);2128	cancel_delayed_work_sync(&adapter->idc_aen_work);2129 2130	return pci_save_state(pdev);2131}2132 2133static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)2134{2135	struct qlc_83xx_idc *idc = &adapter->ahw->idc;2136	struct net_device *netdev = adapter->netdev;2137	int err;2138 2139	set_bit(QLC_83XX_MODULE_LOADED, &idc->status);2140	qlcnic_83xx_enable_mbx_interrupt(adapter);2141	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);2142	if (err)2143		return err;2144 2145	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);2146	if (!err) {2147		if (netif_running(netdev)) {2148			err = qlcnic_up(adapter, netdev);2149			if (!err)2150				qlcnic_restore_indev_addr(netdev, NETDEV_UP);2151		}2152	}2153 2154	netif_device_attach(netdev);2155	qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,2156			     idc->delay);2157	return err;2158}2159 2160int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)2161{2162	struct qlcnic_sriov *sriov = adapter->ahw->sriov;2163	struct qlcnic_vf_info *vf;2164	int i;2165 2166	for (i = 0; i < sriov->num_vfs; i++) {2167		vf = &sriov->vf_info[i];2168		vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans,2169					  sizeof(*vf->sriov_vlans), GFP_KERNEL);2170		if (!vf->sriov_vlans)2171			return -ENOMEM;2172	}2173 2174	return 0;2175}2176 2177void qlcnic_sriov_free_vlans(struct qlcnic_adapter *adapter)2178{2179	struct qlcnic_sriov *sriov = adapter->ahw->sriov;2180	struct qlcnic_vf_info *vf;2181	int i;2182 2183	for (i = 0; i < sriov->num_vfs; i++) {2184		vf = &sriov->vf_info[i];2185		kfree(vf->sriov_vlans);2186		vf->sriov_vlans = NULL;2187	}2188}2189 2190void qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *sriov,2191			      struct qlcnic_vf_info *vf, u16 vlan_id)2192{2193	int i;2194 2195	for (i = 0; i < sriov->num_allowed_vlans; i++) {2196		if (!vf->sriov_vlans[i]) {2197			vf->sriov_vlans[i] = vlan_id;2198			vf->num_vlan++;2199			return;2200		}2201	}2202}2203 2204void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *sriov,2205			      struct qlcnic_vf_info *vf, u16 vlan_id)2206{2207	int i;2208 2209	for (i = 0; i < sriov->num_allowed_vlans; i++) {2210		if (vf->sriov_vlans[i] == vlan_id) {2211			vf->sriov_vlans[i] = 0;2212			vf->num_vlan--;2213			return;2214		}2215	}2216}2217 2218bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf)2219{2220	bool err = false;2221 2222	spin_lock_bh(&vf->vlan_list_lock);2223 2224	if (vf->num_vlan)2225		err = true;2226 2227	spin_unlock_bh(&vf->vlan_list_lock);2228	return err;2229}2230