19aebddd1SJeff Kirsher /*
2d19261b8SVasundhara Volam  * Copyright (C) 2005 - 2015 Emulex
39aebddd1SJeff Kirsher  * All rights reserved.
49aebddd1SJeff Kirsher  *
59aebddd1SJeff Kirsher  * This program is free software; you can redistribute it and/or
69aebddd1SJeff Kirsher  * modify it under the terms of the GNU General Public License version 2
79aebddd1SJeff Kirsher  * as published by the Free Software Foundation.  The full GNU General
89aebddd1SJeff Kirsher  * Public License is included in this distribution in the file called COPYING.
99aebddd1SJeff Kirsher  *
109aebddd1SJeff Kirsher  * Contact Information:
119aebddd1SJeff Kirsher  * linux-drivers@emulex.com
129aebddd1SJeff Kirsher  *
139aebddd1SJeff Kirsher  * Emulex
149aebddd1SJeff Kirsher  * 3333 Susan Street
159aebddd1SJeff Kirsher  * Costa Mesa, CA 92626
169aebddd1SJeff Kirsher  */
179aebddd1SJeff Kirsher 
186a4ab669SParav Pandit #include <linux/module.h>
199aebddd1SJeff Kirsher #include "be.h"
209aebddd1SJeff Kirsher #include "be_cmds.h"
219aebddd1SJeff Kirsher 
2221252377SVasundhara Volam static char *be_port_misconfig_evt_desc[] = {
2321252377SVasundhara Volam 	"A valid SFP module detected",
2421252377SVasundhara Volam 	"Optics faulted/ incorrectly installed/ not installed.",
2521252377SVasundhara Volam 	"Optics of two types installed.",
2621252377SVasundhara Volam 	"Incompatible optics.",
2721252377SVasundhara Volam 	"Unknown port SFP status"
2821252377SVasundhara Volam };
2921252377SVasundhara Volam 
3021252377SVasundhara Volam static char *be_port_misconfig_remedy_desc[] = {
3121252377SVasundhara Volam 	"",
3221252377SVasundhara Volam 	"Reseat optics. If issue not resolved, replace",
3321252377SVasundhara Volam 	"Remove one optic or install matching pair of optics",
3421252377SVasundhara Volam 	"Replace with compatible optics for card to function",
3521252377SVasundhara Volam 	""
3621252377SVasundhara Volam };
3721252377SVasundhara Volam 
38f25b119cSPadmanabh Ratnakar static struct be_cmd_priv_map cmd_priv_map[] = {
39f25b119cSPadmanabh Ratnakar 	{
40f25b119cSPadmanabh Ratnakar 		OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
41f25b119cSPadmanabh Ratnakar 		CMD_SUBSYSTEM_ETH,
42f25b119cSPadmanabh Ratnakar 		BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
43f25b119cSPadmanabh Ratnakar 		BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
44f25b119cSPadmanabh Ratnakar 	},
45f25b119cSPadmanabh Ratnakar 	{
46f25b119cSPadmanabh Ratnakar 		OPCODE_COMMON_GET_FLOW_CONTROL,
47f25b119cSPadmanabh Ratnakar 		CMD_SUBSYSTEM_COMMON,
48f25b119cSPadmanabh Ratnakar 		BE_PRIV_LNKQUERY | BE_PRIV_VHADM |
49f25b119cSPadmanabh Ratnakar 		BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
50f25b119cSPadmanabh Ratnakar 	},
51f25b119cSPadmanabh Ratnakar 	{
52f25b119cSPadmanabh Ratnakar 		OPCODE_COMMON_SET_FLOW_CONTROL,
53f25b119cSPadmanabh Ratnakar 		CMD_SUBSYSTEM_COMMON,
54f25b119cSPadmanabh Ratnakar 		BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
55f25b119cSPadmanabh Ratnakar 		BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
56f25b119cSPadmanabh Ratnakar 	},
57f25b119cSPadmanabh Ratnakar 	{
58f25b119cSPadmanabh Ratnakar 		OPCODE_ETH_GET_PPORT_STATS,
59f25b119cSPadmanabh Ratnakar 		CMD_SUBSYSTEM_ETH,
60f25b119cSPadmanabh Ratnakar 		BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
61f25b119cSPadmanabh Ratnakar 		BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
62f25b119cSPadmanabh Ratnakar 	},
63f25b119cSPadmanabh Ratnakar 	{
64f25b119cSPadmanabh Ratnakar 		OPCODE_COMMON_GET_PHY_DETAILS,
65f25b119cSPadmanabh Ratnakar 		CMD_SUBSYSTEM_COMMON,
66f25b119cSPadmanabh Ratnakar 		BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
67f25b119cSPadmanabh Ratnakar 		BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
68f25b119cSPadmanabh Ratnakar 	}
69f25b119cSPadmanabh Ratnakar };
70f25b119cSPadmanabh Ratnakar 
71a2cc4e0bSSathya Perla static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
72f25b119cSPadmanabh Ratnakar {
73f25b119cSPadmanabh Ratnakar 	int i;
74f25b119cSPadmanabh Ratnakar 	int num_entries = sizeof(cmd_priv_map)/sizeof(struct be_cmd_priv_map);
75f25b119cSPadmanabh Ratnakar 	u32 cmd_privileges = adapter->cmd_privileges;
76f25b119cSPadmanabh Ratnakar 
77f25b119cSPadmanabh Ratnakar 	for (i = 0; i < num_entries; i++)
78f25b119cSPadmanabh Ratnakar 		if (opcode == cmd_priv_map[i].opcode &&
79f25b119cSPadmanabh Ratnakar 		    subsystem == cmd_priv_map[i].subsystem)
80f25b119cSPadmanabh Ratnakar 			if (!(cmd_privileges & cmd_priv_map[i].priv_mask))
81f25b119cSPadmanabh Ratnakar 				return false;
82f25b119cSPadmanabh Ratnakar 
83f25b119cSPadmanabh Ratnakar 	return true;
84f25b119cSPadmanabh Ratnakar }
85f25b119cSPadmanabh Ratnakar 
863de09455SSomnath Kotur static inline void *embedded_payload(struct be_mcc_wrb *wrb)
873de09455SSomnath Kotur {
883de09455SSomnath Kotur 	return wrb->payload.embedded_payload;
893de09455SSomnath Kotur }
909aebddd1SJeff Kirsher 
919aebddd1SJeff Kirsher static void be_mcc_notify(struct be_adapter *adapter)
929aebddd1SJeff Kirsher {
939aebddd1SJeff Kirsher 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
949aebddd1SJeff Kirsher 	u32 val = 0;
959aebddd1SJeff Kirsher 
96954f6825SVenkata Duvvuru 	if (be_check_error(adapter, BE_ERROR_ANY))
979aebddd1SJeff Kirsher 		return;
989aebddd1SJeff Kirsher 
999aebddd1SJeff Kirsher 	val |= mccq->id & DB_MCCQ_RING_ID_MASK;
1009aebddd1SJeff Kirsher 	val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
1019aebddd1SJeff Kirsher 
1029aebddd1SJeff Kirsher 	wmb();
1039aebddd1SJeff Kirsher 	iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
1049aebddd1SJeff Kirsher }
1059aebddd1SJeff Kirsher 
1069aebddd1SJeff Kirsher /* To check if valid bit is set, check the entire word as we don't know
1079aebddd1SJeff Kirsher  * the endianness of the data (old entry is host endian while a new entry is
1089aebddd1SJeff Kirsher  * little endian) */
1099aebddd1SJeff Kirsher static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
1109aebddd1SJeff Kirsher {
1119e9ff4b7SSathya Perla 	u32 flags;
1129e9ff4b7SSathya Perla 
1139aebddd1SJeff Kirsher 	if (compl->flags != 0) {
1149e9ff4b7SSathya Perla 		flags = le32_to_cpu(compl->flags);
1159e9ff4b7SSathya Perla 		if (flags & CQE_FLAGS_VALID_MASK) {
1169e9ff4b7SSathya Perla 			compl->flags = flags;
1179aebddd1SJeff Kirsher 			return true;
1189aebddd1SJeff Kirsher 		}
1199aebddd1SJeff Kirsher 	}
1209e9ff4b7SSathya Perla 	return false;
1219e9ff4b7SSathya Perla }
1229aebddd1SJeff Kirsher 
1239aebddd1SJeff Kirsher /* Need to reset the entire word that houses the valid bit */
1249aebddd1SJeff Kirsher static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
1259aebddd1SJeff Kirsher {
1269aebddd1SJeff Kirsher 	compl->flags = 0;
1279aebddd1SJeff Kirsher }
1289aebddd1SJeff Kirsher 
129652bf646SPadmanabh Ratnakar static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
130652bf646SPadmanabh Ratnakar {
131652bf646SPadmanabh Ratnakar 	unsigned long addr;
132652bf646SPadmanabh Ratnakar 
133652bf646SPadmanabh Ratnakar 	addr = tag1;
134652bf646SPadmanabh Ratnakar 	addr = ((addr << 16) << 16) | tag0;
135652bf646SPadmanabh Ratnakar 	return (void *)addr;
136652bf646SPadmanabh Ratnakar }
137652bf646SPadmanabh Ratnakar 
1384c60005fSKalesh AP static bool be_skip_err_log(u8 opcode, u16 base_status, u16 addl_status)
1394c60005fSKalesh AP {
1404c60005fSKalesh AP 	if (base_status == MCC_STATUS_NOT_SUPPORTED ||
1414c60005fSKalesh AP 	    base_status == MCC_STATUS_ILLEGAL_REQUEST ||
1424c60005fSKalesh AP 	    addl_status == MCC_ADDL_STATUS_TOO_MANY_INTERFACES ||
14377be8c1cSKalesh AP 	    addl_status == MCC_ADDL_STATUS_INSUFFICIENT_VLANS ||
1444c60005fSKalesh AP 	    (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
1454c60005fSKalesh AP 	    (base_status == MCC_STATUS_ILLEGAL_FIELD ||
1464c60005fSKalesh AP 	     addl_status == MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH)))
1474c60005fSKalesh AP 		return true;
1484c60005fSKalesh AP 	else
1494c60005fSKalesh AP 		return false;
1504c60005fSKalesh AP }
1514c60005fSKalesh AP 
152559b633fSSathya Perla /* Place holder for all the async MCC cmds wherein the caller is not in a busy
153559b633fSSathya Perla  * loop (has not issued be_mcc_notify_wait())
154559b633fSSathya Perla  */
155559b633fSSathya Perla static void be_async_cmd_process(struct be_adapter *adapter,
156559b633fSSathya Perla 				 struct be_mcc_compl *compl,
157559b633fSSathya Perla 				 struct be_cmd_resp_hdr *resp_hdr)
158559b633fSSathya Perla {
159559b633fSSathya Perla 	enum mcc_base_status base_status = base_status(compl->status);
160559b633fSSathya Perla 	u8 opcode = 0, subsystem = 0;
161559b633fSSathya Perla 
162559b633fSSathya Perla 	if (resp_hdr) {
163559b633fSSathya Perla 		opcode = resp_hdr->opcode;
164559b633fSSathya Perla 		subsystem = resp_hdr->subsystem;
165559b633fSSathya Perla 	}
166559b633fSSathya Perla 
167559b633fSSathya Perla 	if (opcode == OPCODE_LOWLEVEL_LOOPBACK_TEST &&
168559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
169559b633fSSathya Perla 		complete(&adapter->et_cmd_compl);
170559b633fSSathya Perla 		return;
171559b633fSSathya Perla 	}
172559b633fSSathya Perla 
173559b633fSSathya Perla 	if ((opcode == OPCODE_COMMON_WRITE_FLASHROM ||
174559b633fSSathya Perla 	     opcode == OPCODE_COMMON_WRITE_OBJECT) &&
175559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_COMMON) {
176559b633fSSathya Perla 		adapter->flash_status = compl->status;
177559b633fSSathya Perla 		complete(&adapter->et_cmd_compl);
178559b633fSSathya Perla 		return;
179559b633fSSathya Perla 	}
180559b633fSSathya Perla 
181559b633fSSathya Perla 	if ((opcode == OPCODE_ETH_GET_STATISTICS ||
182559b633fSSathya Perla 	     opcode == OPCODE_ETH_GET_PPORT_STATS) &&
183559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_ETH &&
184559b633fSSathya Perla 	    base_status == MCC_STATUS_SUCCESS) {
185559b633fSSathya Perla 		be_parse_stats(adapter);
186559b633fSSathya Perla 		adapter->stats_cmd_sent = false;
187559b633fSSathya Perla 		return;
188559b633fSSathya Perla 	}
189559b633fSSathya Perla 
190559b633fSSathya Perla 	if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
191559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_COMMON) {
192559b633fSSathya Perla 		if (base_status == MCC_STATUS_SUCCESS) {
193559b633fSSathya Perla 			struct be_cmd_resp_get_cntl_addnl_attribs *resp =
194559b633fSSathya Perla 							(void *)resp_hdr;
19529e9122bSVenkata Duvvuru 			adapter->hwmon_info.be_on_die_temp =
196559b633fSSathya Perla 						resp->on_die_temperature;
197559b633fSSathya Perla 		} else {
198559b633fSSathya Perla 			adapter->be_get_temp_freq = 0;
19929e9122bSVenkata Duvvuru 			adapter->hwmon_info.be_on_die_temp =
20029e9122bSVenkata Duvvuru 						BE_INVALID_DIE_TEMP;
201559b633fSSathya Perla 		}
202559b633fSSathya Perla 		return;
203559b633fSSathya Perla 	}
204559b633fSSathya Perla }
205559b633fSSathya Perla 
2069aebddd1SJeff Kirsher static int be_mcc_compl_process(struct be_adapter *adapter,
2079aebddd1SJeff Kirsher 				struct be_mcc_compl *compl)
2089aebddd1SJeff Kirsher {
2094c60005fSKalesh AP 	enum mcc_base_status base_status;
2104c60005fSKalesh AP 	enum mcc_addl_status addl_status;
211652bf646SPadmanabh Ratnakar 	struct be_cmd_resp_hdr *resp_hdr;
212652bf646SPadmanabh Ratnakar 	u8 opcode = 0, subsystem = 0;
2139aebddd1SJeff Kirsher 
2149aebddd1SJeff Kirsher 	/* Just swap the status to host endian; mcc tag is opaquely copied
2159aebddd1SJeff Kirsher 	 * from mcc_wrb */
2169aebddd1SJeff Kirsher 	be_dws_le_to_cpu(compl, 4);
2179aebddd1SJeff Kirsher 
2184c60005fSKalesh AP 	base_status = base_status(compl->status);
2194c60005fSKalesh AP 	addl_status = addl_status(compl->status);
22096c9b2e4SVasundhara Volam 
221652bf646SPadmanabh Ratnakar 	resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
222652bf646SPadmanabh Ratnakar 	if (resp_hdr) {
223652bf646SPadmanabh Ratnakar 		opcode = resp_hdr->opcode;
224652bf646SPadmanabh Ratnakar 		subsystem = resp_hdr->subsystem;
225652bf646SPadmanabh Ratnakar 	}
226652bf646SPadmanabh Ratnakar 
227559b633fSSathya Perla 	be_async_cmd_process(adapter, compl, resp_hdr);
2285eeff635SSuresh Reddy 
229559b633fSSathya Perla 	if (base_status != MCC_STATUS_SUCCESS &&
230559b633fSSathya Perla 	    !be_skip_err_log(opcode, base_status, addl_status)) {
2314c60005fSKalesh AP 		if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
23297f1d8cdSVasundhara Volam 			dev_warn(&adapter->pdev->dev,
233522609f2SVasundhara Volam 				 "VF is not privileged to issue opcode %d-%d\n",
23497f1d8cdSVasundhara Volam 				 opcode, subsystem);
2359aebddd1SJeff Kirsher 		} else {
23697f1d8cdSVasundhara Volam 			dev_err(&adapter->pdev->dev,
23797f1d8cdSVasundhara Volam 				"opcode %d-%d failed:status %d-%d\n",
2384c60005fSKalesh AP 				opcode, subsystem, base_status, addl_status);
2399aebddd1SJeff Kirsher 		}
2409aebddd1SJeff Kirsher 	}
2414c60005fSKalesh AP 	return compl->status;
2429aebddd1SJeff Kirsher }
2439aebddd1SJeff Kirsher 
2449aebddd1SJeff Kirsher /* Link state evt is a string of bytes; no need for endian swapping */
2459aebddd1SJeff Kirsher static void be_async_link_state_process(struct be_adapter *adapter,
2463acf19d9SSathya Perla 					struct be_mcc_compl *compl)
2479aebddd1SJeff Kirsher {
2483acf19d9SSathya Perla 	struct be_async_event_link_state *evt =
2493acf19d9SSathya Perla 			(struct be_async_event_link_state *)compl;
2503acf19d9SSathya Perla 
251b236916aSAjit Khaparde 	/* When link status changes, link speed must be re-queried from FW */
25242f11cf2SAjit Khaparde 	adapter->phy.link_speed = -1;
253b236916aSAjit Khaparde 
254bdce2ad7SSuresh Reddy 	/* On BEx the FW does not send a separate link status
255bdce2ad7SSuresh Reddy 	 * notification for physical and logical link.
256bdce2ad7SSuresh Reddy 	 * On other chips just process the logical link
257bdce2ad7SSuresh Reddy 	 * status notification
258bdce2ad7SSuresh Reddy 	 */
259bdce2ad7SSuresh Reddy 	if (!BEx_chip(adapter) &&
2602e177a5cSPadmanabh Ratnakar 	    !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK))
2612e177a5cSPadmanabh Ratnakar 		return;
2622e177a5cSPadmanabh Ratnakar 
263b236916aSAjit Khaparde 	/* For the initial link status do not rely on the ASYNC event as
264b236916aSAjit Khaparde 	 * it may not be received in some cases.
265b236916aSAjit Khaparde 	 */
266b236916aSAjit Khaparde 	if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
267bdce2ad7SSuresh Reddy 		be_link_status_update(adapter,
268bdce2ad7SSuresh Reddy 				      evt->port_link_status & LINK_STATUS_MASK);
2699aebddd1SJeff Kirsher }
2709aebddd1SJeff Kirsher 
27121252377SVasundhara Volam static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
27221252377SVasundhara Volam 						  struct be_mcc_compl *compl)
27321252377SVasundhara Volam {
27421252377SVasundhara Volam 	struct be_async_event_misconfig_port *evt =
27521252377SVasundhara Volam 			(struct be_async_event_misconfig_port *)compl;
27621252377SVasundhara Volam 	u32 sfp_mismatch_evt = le32_to_cpu(evt->event_data_word1);
27721252377SVasundhara Volam 	struct device *dev = &adapter->pdev->dev;
27821252377SVasundhara Volam 	u8 port_misconfig_evt;
27921252377SVasundhara Volam 
28021252377SVasundhara Volam 	port_misconfig_evt =
28121252377SVasundhara Volam 		((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
28221252377SVasundhara Volam 
28321252377SVasundhara Volam 	/* Log an error message that would allow a user to determine
28421252377SVasundhara Volam 	 * whether the SFPs have an issue
28521252377SVasundhara Volam 	 */
28621252377SVasundhara Volam 	dev_info(dev, "Port %c: %s %s", adapter->port_name,
28721252377SVasundhara Volam 		 be_port_misconfig_evt_desc[port_misconfig_evt],
28821252377SVasundhara Volam 		 be_port_misconfig_remedy_desc[port_misconfig_evt]);
28921252377SVasundhara Volam 
29021252377SVasundhara Volam 	if (port_misconfig_evt == INCOMPATIBLE_SFP)
29121252377SVasundhara Volam 		adapter->flags |= BE_FLAGS_EVT_INCOMPATIBLE_SFP;
29221252377SVasundhara Volam }
29321252377SVasundhara Volam 
2949aebddd1SJeff Kirsher /* Grp5 CoS Priority evt */
2959aebddd1SJeff Kirsher static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
2963acf19d9SSathya Perla 					       struct be_mcc_compl *compl)
2979aebddd1SJeff Kirsher {
2983acf19d9SSathya Perla 	struct be_async_event_grp5_cos_priority *evt =
2993acf19d9SSathya Perla 			(struct be_async_event_grp5_cos_priority *)compl;
3003acf19d9SSathya Perla 
3019aebddd1SJeff Kirsher 	if (evt->valid) {
3029aebddd1SJeff Kirsher 		adapter->vlan_prio_bmap = evt->available_priority_bmap;
3039aebddd1SJeff Kirsher 		adapter->recommended_prio &= ~VLAN_PRIO_MASK;
3049aebddd1SJeff Kirsher 		adapter->recommended_prio =
3059aebddd1SJeff Kirsher 			evt->reco_default_priority << VLAN_PRIO_SHIFT;
3069aebddd1SJeff Kirsher 	}
3079aebddd1SJeff Kirsher }
3089aebddd1SJeff Kirsher 
309323ff71eSSathya Perla /* Grp5 QOS Speed evt: qos_link_speed is in units of 10 Mbps */
3109aebddd1SJeff Kirsher static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
3113acf19d9SSathya Perla 					    struct be_mcc_compl *compl)
3129aebddd1SJeff Kirsher {
3133acf19d9SSathya Perla 	struct be_async_event_grp5_qos_link_speed *evt =
3143acf19d9SSathya Perla 			(struct be_async_event_grp5_qos_link_speed *)compl;
3153acf19d9SSathya Perla 
316323ff71eSSathya Perla 	if (adapter->phy.link_speed >= 0 &&
317323ff71eSSathya Perla 	    evt->physical_port == adapter->port_num)
318323ff71eSSathya Perla 		adapter->phy.link_speed = le16_to_cpu(evt->qos_link_speed) * 10;
3199aebddd1SJeff Kirsher }
3209aebddd1SJeff Kirsher 
3219aebddd1SJeff Kirsher /*Grp5 PVID evt*/
3229aebddd1SJeff Kirsher static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
3233acf19d9SSathya Perla 					     struct be_mcc_compl *compl)
3249aebddd1SJeff Kirsher {
3253acf19d9SSathya Perla 	struct be_async_event_grp5_pvid_state *evt =
3263acf19d9SSathya Perla 			(struct be_async_event_grp5_pvid_state *)compl;
3273acf19d9SSathya Perla 
328bdac85b5SRavikumar Nelavelli 	if (evt->enabled) {
329939cf306SSomnath Kotur 		adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK;
330bdac85b5SRavikumar Nelavelli 		dev_info(&adapter->pdev->dev, "LPVID: %d\n", adapter->pvid);
331bdac85b5SRavikumar Nelavelli 	} else {
3329aebddd1SJeff Kirsher 		adapter->pvid = 0;
3339aebddd1SJeff Kirsher 	}
334bdac85b5SRavikumar Nelavelli }
3359aebddd1SJeff Kirsher 
336760c295eSVenkata Duvvuru #define MGMT_ENABLE_MASK	0x4
337760c295eSVenkata Duvvuru static void be_async_grp5_fw_control_process(struct be_adapter *adapter,
338760c295eSVenkata Duvvuru 					     struct be_mcc_compl *compl)
339760c295eSVenkata Duvvuru {
340760c295eSVenkata Duvvuru 	struct be_async_fw_control *evt = (struct be_async_fw_control *)compl;
341760c295eSVenkata Duvvuru 	u32 evt_dw1 = le32_to_cpu(evt->event_data_word1);
342760c295eSVenkata Duvvuru 
343760c295eSVenkata Duvvuru 	if (evt_dw1 & MGMT_ENABLE_MASK) {
344760c295eSVenkata Duvvuru 		adapter->flags |= BE_FLAGS_OS2BMC;
345760c295eSVenkata Duvvuru 		adapter->bmc_filt_mask = le32_to_cpu(evt->event_data_word2);
346760c295eSVenkata Duvvuru 	} else {
347760c295eSVenkata Duvvuru 		adapter->flags &= ~BE_FLAGS_OS2BMC;
348760c295eSVenkata Duvvuru 	}
349760c295eSVenkata Duvvuru }
350760c295eSVenkata Duvvuru 
3519aebddd1SJeff Kirsher static void be_async_grp5_evt_process(struct be_adapter *adapter,
3523acf19d9SSathya Perla 				      struct be_mcc_compl *compl)
3539aebddd1SJeff Kirsher {
3543acf19d9SSathya Perla 	u8 event_type = (compl->flags >> ASYNC_EVENT_TYPE_SHIFT) &
3553acf19d9SSathya Perla 				ASYNC_EVENT_TYPE_MASK;
3569aebddd1SJeff Kirsher 
3579aebddd1SJeff Kirsher 	switch (event_type) {
3589aebddd1SJeff Kirsher 	case ASYNC_EVENT_COS_PRIORITY:
3593acf19d9SSathya Perla 		be_async_grp5_cos_priority_process(adapter, compl);
3609aebddd1SJeff Kirsher 		break;
3619aebddd1SJeff Kirsher 	case ASYNC_EVENT_QOS_SPEED:
3623acf19d9SSathya Perla 		be_async_grp5_qos_speed_process(adapter, compl);
3639aebddd1SJeff Kirsher 		break;
3649aebddd1SJeff Kirsher 	case ASYNC_EVENT_PVID_STATE:
3653acf19d9SSathya Perla 		be_async_grp5_pvid_state_process(adapter, compl);
3669aebddd1SJeff Kirsher 		break;
367760c295eSVenkata Duvvuru 	/* Async event to disable/enable os2bmc and/or mac-learning */
368760c295eSVenkata Duvvuru 	case ASYNC_EVENT_FW_CONTROL:
369760c295eSVenkata Duvvuru 		be_async_grp5_fw_control_process(adapter, compl);
370760c295eSVenkata Duvvuru 		break;
3719aebddd1SJeff Kirsher 	default:
3729aebddd1SJeff Kirsher 		break;
3739aebddd1SJeff Kirsher 	}
3749aebddd1SJeff Kirsher }
3759aebddd1SJeff Kirsher 
376bc0c3405SAjit Khaparde static void be_async_dbg_evt_process(struct be_adapter *adapter,
3773acf19d9SSathya Perla 				     struct be_mcc_compl *cmp)
378bc0c3405SAjit Khaparde {
379bc0c3405SAjit Khaparde 	u8 event_type = 0;
380bc0c3405SAjit Khaparde 	struct be_async_event_qnq *evt = (struct be_async_event_qnq *)cmp;
381bc0c3405SAjit Khaparde 
3823acf19d9SSathya Perla 	event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
3833acf19d9SSathya Perla 			ASYNC_EVENT_TYPE_MASK;
384bc0c3405SAjit Khaparde 
385bc0c3405SAjit Khaparde 	switch (event_type) {
386bc0c3405SAjit Khaparde 	case ASYNC_DEBUG_EVENT_TYPE_QNQ:
387bc0c3405SAjit Khaparde 		if (evt->valid)
388bc0c3405SAjit Khaparde 			adapter->qnq_vid = le16_to_cpu(evt->vlan_tag);
389bc0c3405SAjit Khaparde 		adapter->flags |= BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
390bc0c3405SAjit Khaparde 	break;
391bc0c3405SAjit Khaparde 	default:
39205ccaa2bSVasundhara Volam 		dev_warn(&adapter->pdev->dev, "Unknown debug event 0x%x!\n",
39305ccaa2bSVasundhara Volam 			 event_type);
394bc0c3405SAjit Khaparde 	break;
395bc0c3405SAjit Khaparde 	}
396bc0c3405SAjit Khaparde }
397bc0c3405SAjit Khaparde 
39821252377SVasundhara Volam static void be_async_sliport_evt_process(struct be_adapter *adapter,
39921252377SVasundhara Volam 					 struct be_mcc_compl *cmp)
40021252377SVasundhara Volam {
40121252377SVasundhara Volam 	u8 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
40221252377SVasundhara Volam 			ASYNC_EVENT_TYPE_MASK;
40321252377SVasundhara Volam 
40421252377SVasundhara Volam 	if (event_type == ASYNC_EVENT_PORT_MISCONFIG)
40521252377SVasundhara Volam 		be_async_port_misconfig_event_process(adapter, cmp);
40621252377SVasundhara Volam }
40721252377SVasundhara Volam 
4083acf19d9SSathya Perla static inline bool is_link_state_evt(u32 flags)
4099aebddd1SJeff Kirsher {
4103acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4119aebddd1SJeff Kirsher 			ASYNC_EVENT_CODE_LINK_STATE;
4129aebddd1SJeff Kirsher }
4139aebddd1SJeff Kirsher 
4143acf19d9SSathya Perla static inline bool is_grp5_evt(u32 flags)
4159aebddd1SJeff Kirsher {
4163acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4173acf19d9SSathya Perla 			ASYNC_EVENT_CODE_GRP_5;
4189aebddd1SJeff Kirsher }
4199aebddd1SJeff Kirsher 
4203acf19d9SSathya Perla static inline bool is_dbg_evt(u32 flags)
421bc0c3405SAjit Khaparde {
4223acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4233acf19d9SSathya Perla 			ASYNC_EVENT_CODE_QNQ;
4243acf19d9SSathya Perla }
4253acf19d9SSathya Perla 
42621252377SVasundhara Volam static inline bool is_sliport_evt(u32 flags)
42721252377SVasundhara Volam {
42821252377SVasundhara Volam 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
42921252377SVasundhara Volam 		ASYNC_EVENT_CODE_SLIPORT;
43021252377SVasundhara Volam }
43121252377SVasundhara Volam 
4323acf19d9SSathya Perla static void be_mcc_event_process(struct be_adapter *adapter,
4333acf19d9SSathya Perla 				 struct be_mcc_compl *compl)
4343acf19d9SSathya Perla {
4353acf19d9SSathya Perla 	if (is_link_state_evt(compl->flags))
4363acf19d9SSathya Perla 		be_async_link_state_process(adapter, compl);
4373acf19d9SSathya Perla 	else if (is_grp5_evt(compl->flags))
4383acf19d9SSathya Perla 		be_async_grp5_evt_process(adapter, compl);
4393acf19d9SSathya Perla 	else if (is_dbg_evt(compl->flags))
4403acf19d9SSathya Perla 		be_async_dbg_evt_process(adapter, compl);
44121252377SVasundhara Volam 	else if (is_sliport_evt(compl->flags))
44221252377SVasundhara Volam 		be_async_sliport_evt_process(adapter, compl);
443bc0c3405SAjit Khaparde }
444bc0c3405SAjit Khaparde 
4459aebddd1SJeff Kirsher static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
4469aebddd1SJeff Kirsher {
4479aebddd1SJeff Kirsher 	struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
4489aebddd1SJeff Kirsher 	struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
4499aebddd1SJeff Kirsher 
4509aebddd1SJeff Kirsher 	if (be_mcc_compl_is_new(compl)) {
4519aebddd1SJeff Kirsher 		queue_tail_inc(mcc_cq);
4529aebddd1SJeff Kirsher 		return compl;
4539aebddd1SJeff Kirsher 	}
4549aebddd1SJeff Kirsher 	return NULL;
4559aebddd1SJeff Kirsher }
4569aebddd1SJeff Kirsher 
4579aebddd1SJeff Kirsher void be_async_mcc_enable(struct be_adapter *adapter)
4589aebddd1SJeff Kirsher {
4599aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_cq_lock);
4609aebddd1SJeff Kirsher 
4619aebddd1SJeff Kirsher 	be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
4629aebddd1SJeff Kirsher 	adapter->mcc_obj.rearm_cq = true;
4639aebddd1SJeff Kirsher 
4649aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_cq_lock);
4659aebddd1SJeff Kirsher }
4669aebddd1SJeff Kirsher 
4679aebddd1SJeff Kirsher void be_async_mcc_disable(struct be_adapter *adapter)
4689aebddd1SJeff Kirsher {
469a323d9bfSSathya Perla 	spin_lock_bh(&adapter->mcc_cq_lock);
470a323d9bfSSathya Perla 
4719aebddd1SJeff Kirsher 	adapter->mcc_obj.rearm_cq = false;
472a323d9bfSSathya Perla 	be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
473a323d9bfSSathya Perla 
474a323d9bfSSathya Perla 	spin_unlock_bh(&adapter->mcc_cq_lock);
4759aebddd1SJeff Kirsher }
4769aebddd1SJeff Kirsher 
47710ef9ab4SSathya Perla int be_process_mcc(struct be_adapter *adapter)
4789aebddd1SJeff Kirsher {
4799aebddd1SJeff Kirsher 	struct be_mcc_compl *compl;
48010ef9ab4SSathya Perla 	int num = 0, status = 0;
4819aebddd1SJeff Kirsher 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
4829aebddd1SJeff Kirsher 
483072a9c48SAmerigo Wang 	spin_lock(&adapter->mcc_cq_lock);
4843acf19d9SSathya Perla 
4859aebddd1SJeff Kirsher 	while ((compl = be_mcc_compl_get(adapter))) {
4869aebddd1SJeff Kirsher 		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
4873acf19d9SSathya Perla 			be_mcc_event_process(adapter, compl);
4889aebddd1SJeff Kirsher 		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
48910ef9ab4SSathya Perla 			status = be_mcc_compl_process(adapter, compl);
4909aebddd1SJeff Kirsher 			atomic_dec(&mcc_obj->q.used);
4919aebddd1SJeff Kirsher 		}
4929aebddd1SJeff Kirsher 		be_mcc_compl_use(compl);
4939aebddd1SJeff Kirsher 		num++;
4949aebddd1SJeff Kirsher 	}
4959aebddd1SJeff Kirsher 
49610ef9ab4SSathya Perla 	if (num)
49710ef9ab4SSathya Perla 		be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
49810ef9ab4SSathya Perla 
499072a9c48SAmerigo Wang 	spin_unlock(&adapter->mcc_cq_lock);
50010ef9ab4SSathya Perla 	return status;
5019aebddd1SJeff Kirsher }
5029aebddd1SJeff Kirsher 
5039aebddd1SJeff Kirsher /* Wait till no more pending mcc requests are present */
5049aebddd1SJeff Kirsher static int be_mcc_wait_compl(struct be_adapter *adapter)
5059aebddd1SJeff Kirsher {
5069aebddd1SJeff Kirsher #define mcc_timeout		120000 /* 12s timeout */
50710ef9ab4SSathya Perla 	int i, status = 0;
5089aebddd1SJeff Kirsher 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
5099aebddd1SJeff Kirsher 
5106589ade0SSathya Perla 	for (i = 0; i < mcc_timeout; i++) {
511954f6825SVenkata Duvvuru 		if (be_check_error(adapter, BE_ERROR_ANY))
5129aebddd1SJeff Kirsher 			return -EIO;
5139aebddd1SJeff Kirsher 
514072a9c48SAmerigo Wang 		local_bh_disable();
51510ef9ab4SSathya Perla 		status = be_process_mcc(adapter);
516072a9c48SAmerigo Wang 		local_bh_enable();
5179aebddd1SJeff Kirsher 
5189aebddd1SJeff Kirsher 		if (atomic_read(&mcc_obj->q.used) == 0)
5199aebddd1SJeff Kirsher 			break;
5209aebddd1SJeff Kirsher 		udelay(100);
5219aebddd1SJeff Kirsher 	}
5229aebddd1SJeff Kirsher 	if (i == mcc_timeout) {
5236589ade0SSathya Perla 		dev_err(&adapter->pdev->dev, "FW not responding\n");
524954f6825SVenkata Duvvuru 		be_set_error(adapter, BE_ERROR_FW);
525652bf646SPadmanabh Ratnakar 		return -EIO;
5269aebddd1SJeff Kirsher 	}
5279aebddd1SJeff Kirsher 	return status;
5289aebddd1SJeff Kirsher }
5299aebddd1SJeff Kirsher 
5309aebddd1SJeff Kirsher /* Notify MCC requests and wait for completion */
5319aebddd1SJeff Kirsher static int be_mcc_notify_wait(struct be_adapter *adapter)
5329aebddd1SJeff Kirsher {
533652bf646SPadmanabh Ratnakar 	int status;
534652bf646SPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
535652bf646SPadmanabh Ratnakar 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
536652bf646SPadmanabh Ratnakar 	u16 index = mcc_obj->q.head;
537652bf646SPadmanabh Ratnakar 	struct be_cmd_resp_hdr *resp;
538652bf646SPadmanabh Ratnakar 
539652bf646SPadmanabh Ratnakar 	index_dec(&index, mcc_obj->q.len);
540652bf646SPadmanabh Ratnakar 	wrb = queue_index_node(&mcc_obj->q, index);
541652bf646SPadmanabh Ratnakar 
542652bf646SPadmanabh Ratnakar 	resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
543652bf646SPadmanabh Ratnakar 
5449aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
545652bf646SPadmanabh Ratnakar 
546652bf646SPadmanabh Ratnakar 	status = be_mcc_wait_compl(adapter);
547652bf646SPadmanabh Ratnakar 	if (status == -EIO)
548652bf646SPadmanabh Ratnakar 		goto out;
549652bf646SPadmanabh Ratnakar 
5504c60005fSKalesh AP 	status = (resp->base_status |
5514c60005fSKalesh AP 		  ((resp->addl_status & CQE_ADDL_STATUS_MASK) <<
5524c60005fSKalesh AP 		   CQE_ADDL_STATUS_SHIFT));
553652bf646SPadmanabh Ratnakar out:
554652bf646SPadmanabh Ratnakar 	return status;
5559aebddd1SJeff Kirsher }
5569aebddd1SJeff Kirsher 
5579aebddd1SJeff Kirsher static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
5589aebddd1SJeff Kirsher {
5599aebddd1SJeff Kirsher 	int msecs = 0;
5609aebddd1SJeff Kirsher 	u32 ready;
5619aebddd1SJeff Kirsher 
5626589ade0SSathya Perla 	do {
563954f6825SVenkata Duvvuru 		if (be_check_error(adapter, BE_ERROR_ANY))
5649aebddd1SJeff Kirsher 			return -EIO;
5659aebddd1SJeff Kirsher 
5669aebddd1SJeff Kirsher 		ready = ioread32(db);
567434b3648SSathya Perla 		if (ready == 0xffffffff)
5689aebddd1SJeff Kirsher 			return -1;
5699aebddd1SJeff Kirsher 
5709aebddd1SJeff Kirsher 		ready &= MPU_MAILBOX_DB_RDY_MASK;
5719aebddd1SJeff Kirsher 		if (ready)
5729aebddd1SJeff Kirsher 			break;
5739aebddd1SJeff Kirsher 
5749aebddd1SJeff Kirsher 		if (msecs > 4000) {
5756589ade0SSathya Perla 			dev_err(&adapter->pdev->dev, "FW not responding\n");
576954f6825SVenkata Duvvuru 			be_set_error(adapter, BE_ERROR_FW);
577f67ef7baSPadmanabh Ratnakar 			be_detect_error(adapter);
5789aebddd1SJeff Kirsher 			return -1;
5799aebddd1SJeff Kirsher 		}
5809aebddd1SJeff Kirsher 
5819aebddd1SJeff Kirsher 		msleep(1);
5829aebddd1SJeff Kirsher 		msecs++;
5839aebddd1SJeff Kirsher 	} while (true);
5849aebddd1SJeff Kirsher 
5859aebddd1SJeff Kirsher 	return 0;
5869aebddd1SJeff Kirsher }
5879aebddd1SJeff Kirsher 
5889aebddd1SJeff Kirsher /*
5899aebddd1SJeff Kirsher  * Insert the mailbox address into the doorbell in two steps
5909aebddd1SJeff Kirsher  * Polls on the mbox doorbell till a command completion (or a timeout) occurs
5919aebddd1SJeff Kirsher  */
5929aebddd1SJeff Kirsher static int be_mbox_notify_wait(struct be_adapter *adapter)
5939aebddd1SJeff Kirsher {
5949aebddd1SJeff Kirsher 	int status;
5959aebddd1SJeff Kirsher 	u32 val = 0;
5969aebddd1SJeff Kirsher 	void __iomem *db = adapter->db + MPU_MAILBOX_DB_OFFSET;
5979aebddd1SJeff Kirsher 	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
5989aebddd1SJeff Kirsher 	struct be_mcc_mailbox *mbox = mbox_mem->va;
5999aebddd1SJeff Kirsher 	struct be_mcc_compl *compl = &mbox->compl;
6009aebddd1SJeff Kirsher 
6019aebddd1SJeff Kirsher 	/* wait for ready to be set */
6029aebddd1SJeff Kirsher 	status = be_mbox_db_ready_wait(adapter, db);
6039aebddd1SJeff Kirsher 	if (status != 0)
6049aebddd1SJeff Kirsher 		return status;
6059aebddd1SJeff Kirsher 
6069aebddd1SJeff Kirsher 	val |= MPU_MAILBOX_DB_HI_MASK;
6079aebddd1SJeff Kirsher 	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
6089aebddd1SJeff Kirsher 	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
6099aebddd1SJeff Kirsher 	iowrite32(val, db);
6109aebddd1SJeff Kirsher 
6119aebddd1SJeff Kirsher 	/* wait for ready to be set */
6129aebddd1SJeff Kirsher 	status = be_mbox_db_ready_wait(adapter, db);
6139aebddd1SJeff Kirsher 	if (status != 0)
6149aebddd1SJeff Kirsher 		return status;
6159aebddd1SJeff Kirsher 
6169aebddd1SJeff Kirsher 	val = 0;
6179aebddd1SJeff Kirsher 	/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
6189aebddd1SJeff Kirsher 	val |= (u32)(mbox_mem->dma >> 4) << 2;
6199aebddd1SJeff Kirsher 	iowrite32(val, db);
6209aebddd1SJeff Kirsher 
6219aebddd1SJeff Kirsher 	status = be_mbox_db_ready_wait(adapter, db);
6229aebddd1SJeff Kirsher 	if (status != 0)
6239aebddd1SJeff Kirsher 		return status;
6249aebddd1SJeff Kirsher 
6259aebddd1SJeff Kirsher 	/* A cq entry has been made now */
6269aebddd1SJeff Kirsher 	if (be_mcc_compl_is_new(compl)) {
6279aebddd1SJeff Kirsher 		status = be_mcc_compl_process(adapter, &mbox->compl);
6289aebddd1SJeff Kirsher 		be_mcc_compl_use(compl);
6299aebddd1SJeff Kirsher 		if (status)
6309aebddd1SJeff Kirsher 			return status;
6319aebddd1SJeff Kirsher 	} else {
6329aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev, "invalid mailbox completion\n");
6339aebddd1SJeff Kirsher 		return -1;
6349aebddd1SJeff Kirsher 	}
6359aebddd1SJeff Kirsher 	return 0;
6369aebddd1SJeff Kirsher }
6379aebddd1SJeff Kirsher 
638c5b3ad4cSSathya Perla static u16 be_POST_stage_get(struct be_adapter *adapter)
6399aebddd1SJeff Kirsher {
6409aebddd1SJeff Kirsher 	u32 sem;
6419aebddd1SJeff Kirsher 
642c5b3ad4cSSathya Perla 	if (BEx_chip(adapter))
643c5b3ad4cSSathya Perla 		sem  = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
6449aebddd1SJeff Kirsher 	else
645c5b3ad4cSSathya Perla 		pci_read_config_dword(adapter->pdev,
646c5b3ad4cSSathya Perla 				      SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
647c5b3ad4cSSathya Perla 
648c5b3ad4cSSathya Perla 	return sem & POST_STAGE_MASK;
6499aebddd1SJeff Kirsher }
6509aebddd1SJeff Kirsher 
65187f20c26SGavin Shan static int lancer_wait_ready(struct be_adapter *adapter)
652bf99e50dSPadmanabh Ratnakar {
653bf99e50dSPadmanabh Ratnakar #define SLIPORT_READY_TIMEOUT 30
654bf99e50dSPadmanabh Ratnakar 	u32 sliport_status;
655e673244aSKalesh AP 	int i;
656bf99e50dSPadmanabh Ratnakar 
657bf99e50dSPadmanabh Ratnakar 	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
658bf99e50dSPadmanabh Ratnakar 		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
659bf99e50dSPadmanabh Ratnakar 		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
6609fa465c0SSathya Perla 			return 0;
6619fa465c0SSathya Perla 
6629fa465c0SSathya Perla 		if (sliport_status & SLIPORT_STATUS_ERR_MASK &&
6639fa465c0SSathya Perla 		    !(sliport_status & SLIPORT_STATUS_RN_MASK))
6649fa465c0SSathya Perla 			return -EIO;
665bf99e50dSPadmanabh Ratnakar 
666bf99e50dSPadmanabh Ratnakar 		msleep(1000);
667bf99e50dSPadmanabh Ratnakar 	}
668bf99e50dSPadmanabh Ratnakar 
669e673244aSKalesh AP 	return sliport_status ? : -1;
670bf99e50dSPadmanabh Ratnakar }
671bf99e50dSPadmanabh Ratnakar 
672bf99e50dSPadmanabh Ratnakar int be_fw_wait_ready(struct be_adapter *adapter)
6739aebddd1SJeff Kirsher {
6749aebddd1SJeff Kirsher 	u16 stage;
6759aebddd1SJeff Kirsher 	int status, timeout = 0;
6769aebddd1SJeff Kirsher 	struct device *dev = &adapter->pdev->dev;
6779aebddd1SJeff Kirsher 
678bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter)) {
679bf99e50dSPadmanabh Ratnakar 		status = lancer_wait_ready(adapter);
680e673244aSKalesh AP 		if (status) {
681e673244aSKalesh AP 			stage = status;
682e673244aSKalesh AP 			goto err;
683e673244aSKalesh AP 		}
684e673244aSKalesh AP 		return 0;
685bf99e50dSPadmanabh Ratnakar 	}
686bf99e50dSPadmanabh Ratnakar 
6879aebddd1SJeff Kirsher 	do {
688ca3de6b2SSathya Perla 		/* There's no means to poll POST state on BE2/3 VFs */
689ca3de6b2SSathya Perla 		if (BEx_chip(adapter) && be_virtfn(adapter))
690ca3de6b2SSathya Perla 			return 0;
691ca3de6b2SSathya Perla 
692c5b3ad4cSSathya Perla 		stage = be_POST_stage_get(adapter);
69366d29cbcSGavin Shan 		if (stage == POST_STAGE_ARMFW_RDY)
69466d29cbcSGavin Shan 			return 0;
69566d29cbcSGavin Shan 
696a2cc4e0bSSathya Perla 		dev_info(dev, "Waiting for POST, %ds elapsed\n", timeout);
6979aebddd1SJeff Kirsher 		if (msleep_interruptible(2000)) {
6989aebddd1SJeff Kirsher 			dev_err(dev, "Waiting for POST aborted\n");
6999aebddd1SJeff Kirsher 			return -EINTR;
7009aebddd1SJeff Kirsher 		}
7019aebddd1SJeff Kirsher 		timeout += 2;
7023ab81b5fSSomnath Kotur 	} while (timeout < 60);
7039aebddd1SJeff Kirsher 
704e673244aSKalesh AP err:
705e673244aSKalesh AP 	dev_err(dev, "POST timeout; stage=%#x\n", stage);
7069fa465c0SSathya Perla 	return -ETIMEDOUT;
7079aebddd1SJeff Kirsher }
7089aebddd1SJeff Kirsher 
7099aebddd1SJeff Kirsher static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
7109aebddd1SJeff Kirsher {
7119aebddd1SJeff Kirsher 	return &wrb->payload.sgl[0];
7129aebddd1SJeff Kirsher }
7139aebddd1SJeff Kirsher 
714a2cc4e0bSSathya Perla static inline void fill_wrb_tags(struct be_mcc_wrb *wrb, unsigned long addr)
715bea50988SSathya Perla {
716bea50988SSathya Perla 	wrb->tag0 = addr & 0xFFFFFFFF;
717bea50988SSathya Perla 	wrb->tag1 = upper_32_bits(addr);
718bea50988SSathya Perla }
7199aebddd1SJeff Kirsher 
7209aebddd1SJeff Kirsher /* Don't touch the hdr after it's prepared */
721106df1e3SSomnath Kotur /* mem will be NULL for embedded commands */
722106df1e3SSomnath Kotur static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
723106df1e3SSomnath Kotur 				   u8 subsystem, u8 opcode, int cmd_len,
724a2cc4e0bSSathya Perla 				   struct be_mcc_wrb *wrb,
725a2cc4e0bSSathya Perla 				   struct be_dma_mem *mem)
7269aebddd1SJeff Kirsher {
727106df1e3SSomnath Kotur 	struct be_sge *sge;
728106df1e3SSomnath Kotur 
7299aebddd1SJeff Kirsher 	req_hdr->opcode = opcode;
7309aebddd1SJeff Kirsher 	req_hdr->subsystem = subsystem;
7319aebddd1SJeff Kirsher 	req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
7329aebddd1SJeff Kirsher 	req_hdr->version = 0;
733bea50988SSathya Perla 	fill_wrb_tags(wrb, (ulong) req_hdr);
734106df1e3SSomnath Kotur 	wrb->payload_length = cmd_len;
735106df1e3SSomnath Kotur 	if (mem) {
736106df1e3SSomnath Kotur 		wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
737106df1e3SSomnath Kotur 			MCC_WRB_SGE_CNT_SHIFT;
738106df1e3SSomnath Kotur 		sge = nonembedded_sgl(wrb);
739106df1e3SSomnath Kotur 		sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
740106df1e3SSomnath Kotur 		sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
741106df1e3SSomnath Kotur 		sge->len = cpu_to_le32(mem->size);
742106df1e3SSomnath Kotur 	} else
743106df1e3SSomnath Kotur 		wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
744106df1e3SSomnath Kotur 	be_dws_cpu_to_le(wrb, 8);
7459aebddd1SJeff Kirsher }
7469aebddd1SJeff Kirsher 
7479aebddd1SJeff Kirsher static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
7489aebddd1SJeff Kirsher 				      struct be_dma_mem *mem)
7499aebddd1SJeff Kirsher {
7509aebddd1SJeff Kirsher 	int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
7519aebddd1SJeff Kirsher 	u64 dma = (u64)mem->dma;
7529aebddd1SJeff Kirsher 
7539aebddd1SJeff Kirsher 	for (i = 0; i < buf_pages; i++) {
7549aebddd1SJeff Kirsher 		pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
7559aebddd1SJeff Kirsher 		pages[i].hi = cpu_to_le32(upper_32_bits(dma));
7569aebddd1SJeff Kirsher 		dma += PAGE_SIZE_4K;
7579aebddd1SJeff Kirsher 	}
7589aebddd1SJeff Kirsher }
7599aebddd1SJeff Kirsher 
7609aebddd1SJeff Kirsher static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
7619aebddd1SJeff Kirsher {
7629aebddd1SJeff Kirsher 	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
7639aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb
7649aebddd1SJeff Kirsher 		= &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
7659aebddd1SJeff Kirsher 	memset(wrb, 0, sizeof(*wrb));
7669aebddd1SJeff Kirsher 	return wrb;
7679aebddd1SJeff Kirsher }
7689aebddd1SJeff Kirsher 
7699aebddd1SJeff Kirsher static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
7709aebddd1SJeff Kirsher {
7719aebddd1SJeff Kirsher 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
7729aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
7739aebddd1SJeff Kirsher 
774aa790db9SPadmanabh Ratnakar 	if (!mccq->created)
775aa790db9SPadmanabh Ratnakar 		return NULL;
776aa790db9SPadmanabh Ratnakar 
7774d277125SVasundhara Volam 	if (atomic_read(&mccq->used) >= mccq->len)
7789aebddd1SJeff Kirsher 		return NULL;
7799aebddd1SJeff Kirsher 
7809aebddd1SJeff Kirsher 	wrb = queue_head_node(mccq);
7819aebddd1SJeff Kirsher 	queue_head_inc(mccq);
7829aebddd1SJeff Kirsher 	atomic_inc(&mccq->used);
7839aebddd1SJeff Kirsher 	memset(wrb, 0, sizeof(*wrb));
7849aebddd1SJeff Kirsher 	return wrb;
7859aebddd1SJeff Kirsher }
7869aebddd1SJeff Kirsher 
787bea50988SSathya Perla static bool use_mcc(struct be_adapter *adapter)
788bea50988SSathya Perla {
789bea50988SSathya Perla 	return adapter->mcc_obj.q.created;
790bea50988SSathya Perla }
791bea50988SSathya Perla 
792bea50988SSathya Perla /* Must be used only in process context */
793bea50988SSathya Perla static int be_cmd_lock(struct be_adapter *adapter)
794bea50988SSathya Perla {
795bea50988SSathya Perla 	if (use_mcc(adapter)) {
796bea50988SSathya Perla 		spin_lock_bh(&adapter->mcc_lock);
797bea50988SSathya Perla 		return 0;
798bea50988SSathya Perla 	} else {
799bea50988SSathya Perla 		return mutex_lock_interruptible(&adapter->mbox_lock);
800bea50988SSathya Perla 	}
801bea50988SSathya Perla }
802bea50988SSathya Perla 
803bea50988SSathya Perla /* Must be used only in process context */
804bea50988SSathya Perla static void be_cmd_unlock(struct be_adapter *adapter)
805bea50988SSathya Perla {
806bea50988SSathya Perla 	if (use_mcc(adapter))
807bea50988SSathya Perla 		spin_unlock_bh(&adapter->mcc_lock);
808bea50988SSathya Perla 	else
809bea50988SSathya Perla 		return mutex_unlock(&adapter->mbox_lock);
810bea50988SSathya Perla }
811bea50988SSathya Perla 
812bea50988SSathya Perla static struct be_mcc_wrb *be_cmd_copy(struct be_adapter *adapter,
813bea50988SSathya Perla 				      struct be_mcc_wrb *wrb)
814bea50988SSathya Perla {
815bea50988SSathya Perla 	struct be_mcc_wrb *dest_wrb;
816bea50988SSathya Perla 
817bea50988SSathya Perla 	if (use_mcc(adapter)) {
818bea50988SSathya Perla 		dest_wrb = wrb_from_mccq(adapter);
819bea50988SSathya Perla 		if (!dest_wrb)
820bea50988SSathya Perla 			return NULL;
821bea50988SSathya Perla 	} else {
822bea50988SSathya Perla 		dest_wrb = wrb_from_mbox(adapter);
823bea50988SSathya Perla 	}
824bea50988SSathya Perla 
825bea50988SSathya Perla 	memcpy(dest_wrb, wrb, sizeof(*wrb));
826bea50988SSathya Perla 	if (wrb->embedded & cpu_to_le32(MCC_WRB_EMBEDDED_MASK))
827bea50988SSathya Perla 		fill_wrb_tags(dest_wrb, (ulong) embedded_payload(wrb));
828bea50988SSathya Perla 
829bea50988SSathya Perla 	return dest_wrb;
830bea50988SSathya Perla }
831bea50988SSathya Perla 
832bea50988SSathya Perla /* Must be used only in process context */
833bea50988SSathya Perla static int be_cmd_notify_wait(struct be_adapter *adapter,
834bea50988SSathya Perla 			      struct be_mcc_wrb *wrb)
835bea50988SSathya Perla {
836bea50988SSathya Perla 	struct be_mcc_wrb *dest_wrb;
837bea50988SSathya Perla 	int status;
838bea50988SSathya Perla 
839bea50988SSathya Perla 	status = be_cmd_lock(adapter);
840bea50988SSathya Perla 	if (status)
841bea50988SSathya Perla 		return status;
842bea50988SSathya Perla 
843bea50988SSathya Perla 	dest_wrb = be_cmd_copy(adapter, wrb);
844bea50988SSathya Perla 	if (!dest_wrb)
845bea50988SSathya Perla 		return -EBUSY;
846bea50988SSathya Perla 
847bea50988SSathya Perla 	if (use_mcc(adapter))
848bea50988SSathya Perla 		status = be_mcc_notify_wait(adapter);
849bea50988SSathya Perla 	else
850bea50988SSathya Perla 		status = be_mbox_notify_wait(adapter);
851bea50988SSathya Perla 
852bea50988SSathya Perla 	if (!status)
853bea50988SSathya Perla 		memcpy(wrb, dest_wrb, sizeof(*wrb));
854bea50988SSathya Perla 
855bea50988SSathya Perla 	be_cmd_unlock(adapter);
856bea50988SSathya Perla 	return status;
857bea50988SSathya Perla }
858bea50988SSathya Perla 
8599aebddd1SJeff Kirsher /* Tell fw we're about to start firing cmds by writing a
8609aebddd1SJeff Kirsher  * special pattern across the wrb hdr; uses mbox
8619aebddd1SJeff Kirsher  */
8629aebddd1SJeff Kirsher int be_cmd_fw_init(struct be_adapter *adapter)
8639aebddd1SJeff Kirsher {
8649aebddd1SJeff Kirsher 	u8 *wrb;
8659aebddd1SJeff Kirsher 	int status;
8669aebddd1SJeff Kirsher 
867bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter))
868bf99e50dSPadmanabh Ratnakar 		return 0;
869bf99e50dSPadmanabh Ratnakar 
8709aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
8719aebddd1SJeff Kirsher 		return -1;
8729aebddd1SJeff Kirsher 
8739aebddd1SJeff Kirsher 	wrb = (u8 *)wrb_from_mbox(adapter);
8749aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8759aebddd1SJeff Kirsher 	*wrb++ = 0x12;
8769aebddd1SJeff Kirsher 	*wrb++ = 0x34;
8779aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8789aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8799aebddd1SJeff Kirsher 	*wrb++ = 0x56;
8809aebddd1SJeff Kirsher 	*wrb++ = 0x78;
8819aebddd1SJeff Kirsher 	*wrb = 0xFF;
8829aebddd1SJeff Kirsher 
8839aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
8849aebddd1SJeff Kirsher 
8859aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
8869aebddd1SJeff Kirsher 	return status;
8879aebddd1SJeff Kirsher }
8889aebddd1SJeff Kirsher 
8899aebddd1SJeff Kirsher /* Tell fw we're done with firing cmds by writing a
8909aebddd1SJeff Kirsher  * special pattern across the wrb hdr; uses mbox
8919aebddd1SJeff Kirsher  */
8929aebddd1SJeff Kirsher int be_cmd_fw_clean(struct be_adapter *adapter)
8939aebddd1SJeff Kirsher {
8949aebddd1SJeff Kirsher 	u8 *wrb;
8959aebddd1SJeff Kirsher 	int status;
8969aebddd1SJeff Kirsher 
897bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter))
898bf99e50dSPadmanabh Ratnakar 		return 0;
899bf99e50dSPadmanabh Ratnakar 
9009aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
9019aebddd1SJeff Kirsher 		return -1;
9029aebddd1SJeff Kirsher 
9039aebddd1SJeff Kirsher 	wrb = (u8 *)wrb_from_mbox(adapter);
9049aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9059aebddd1SJeff Kirsher 	*wrb++ = 0xAA;
9069aebddd1SJeff Kirsher 	*wrb++ = 0xBB;
9079aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9089aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9099aebddd1SJeff Kirsher 	*wrb++ = 0xCC;
9109aebddd1SJeff Kirsher 	*wrb++ = 0xDD;
9119aebddd1SJeff Kirsher 	*wrb = 0xFF;
9129aebddd1SJeff Kirsher 
9139aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
9149aebddd1SJeff Kirsher 
9159aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
9169aebddd1SJeff Kirsher 	return status;
9179aebddd1SJeff Kirsher }
918bf99e50dSPadmanabh Ratnakar 
919f2f781a7SSathya Perla int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo)
9209aebddd1SJeff Kirsher {
9219aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
9229aebddd1SJeff Kirsher 	struct be_cmd_req_eq_create *req;
923f2f781a7SSathya Perla 	struct be_dma_mem *q_mem = &eqo->q.dma_mem;
924f2f781a7SSathya Perla 	int status, ver = 0;
9259aebddd1SJeff Kirsher 
9269aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
9279aebddd1SJeff Kirsher 		return -1;
9289aebddd1SJeff Kirsher 
9299aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
9309aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
9319aebddd1SJeff Kirsher 
932106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
933a2cc4e0bSSathya Perla 			       OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb,
934a2cc4e0bSSathya Perla 			       NULL);
9359aebddd1SJeff Kirsher 
936f2f781a7SSathya Perla 	/* Support for EQ_CREATEv2 available only SH-R onwards */
937f2f781a7SSathya Perla 	if (!(BEx_chip(adapter) || lancer_chip(adapter)))
938f2f781a7SSathya Perla 		ver = 2;
939f2f781a7SSathya Perla 
940f2f781a7SSathya Perla 	req->hdr.version = ver;
9419aebddd1SJeff Kirsher 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
9429aebddd1SJeff Kirsher 
9439aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
9449aebddd1SJeff Kirsher 	/* 4byte eqe*/
9459aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
9469aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, count, req->context,
947f2f781a7SSathya Perla 		      __ilog2_u32(eqo->q.len / 256));
9489aebddd1SJeff Kirsher 	be_dws_cpu_to_le(req->context, sizeof(req->context));
9499aebddd1SJeff Kirsher 
9509aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
9519aebddd1SJeff Kirsher 
9529aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
9539aebddd1SJeff Kirsher 	if (!status) {
9549aebddd1SJeff Kirsher 		struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
95503d28ffeSKalesh AP 
956f2f781a7SSathya Perla 		eqo->q.id = le16_to_cpu(resp->eq_id);
957f2f781a7SSathya Perla 		eqo->msix_idx =
958f2f781a7SSathya Perla 			(ver == 2) ? le16_to_cpu(resp->msix_idx) : eqo->idx;
959f2f781a7SSathya Perla 		eqo->q.created = true;
9609aebddd1SJeff Kirsher 	}
9619aebddd1SJeff Kirsher 
9629aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
9639aebddd1SJeff Kirsher 	return status;
9649aebddd1SJeff Kirsher }
9659aebddd1SJeff Kirsher 
966f9449ab7SSathya Perla /* Use MCC */
9679aebddd1SJeff Kirsher int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
9685ee4979bSSathya Perla 			  bool permanent, u32 if_handle, u32 pmac_id)
9699aebddd1SJeff Kirsher {
9709aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
9719aebddd1SJeff Kirsher 	struct be_cmd_req_mac_query *req;
9729aebddd1SJeff Kirsher 	int status;
9739aebddd1SJeff Kirsher 
974f9449ab7SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
9759aebddd1SJeff Kirsher 
976f9449ab7SSathya Perla 	wrb = wrb_from_mccq(adapter);
977f9449ab7SSathya Perla 	if (!wrb) {
978f9449ab7SSathya Perla 		status = -EBUSY;
979f9449ab7SSathya Perla 		goto err;
980f9449ab7SSathya Perla 	}
9819aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
9829aebddd1SJeff Kirsher 
983106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
984a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req), wrb,
985a2cc4e0bSSathya Perla 			       NULL);
9865ee4979bSSathya Perla 	req->type = MAC_ADDRESS_TYPE_NETWORK;
9879aebddd1SJeff Kirsher 	if (permanent) {
9889aebddd1SJeff Kirsher 		req->permanent = 1;
9899aebddd1SJeff Kirsher 	} else {
9909aebddd1SJeff Kirsher 		req->if_id = cpu_to_le16((u16)if_handle);
991590c391dSPadmanabh Ratnakar 		req->pmac_id = cpu_to_le32(pmac_id);
9929aebddd1SJeff Kirsher 		req->permanent = 0;
9939aebddd1SJeff Kirsher 	}
9949aebddd1SJeff Kirsher 
995f9449ab7SSathya Perla 	status = be_mcc_notify_wait(adapter);
9969aebddd1SJeff Kirsher 	if (!status) {
9979aebddd1SJeff Kirsher 		struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
99803d28ffeSKalesh AP 
9999aebddd1SJeff Kirsher 		memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
10009aebddd1SJeff Kirsher 	}
10019aebddd1SJeff Kirsher 
1002f9449ab7SSathya Perla err:
1003f9449ab7SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
10049aebddd1SJeff Kirsher 	return status;
10059aebddd1SJeff Kirsher }
10069aebddd1SJeff Kirsher 
10079aebddd1SJeff Kirsher /* Uses synchronous MCCQ */
10089aebddd1SJeff Kirsher int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
10099aebddd1SJeff Kirsher 		    u32 if_id, u32 *pmac_id, u32 domain)
10109aebddd1SJeff Kirsher {
10119aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
10129aebddd1SJeff Kirsher 	struct be_cmd_req_pmac_add *req;
10139aebddd1SJeff Kirsher 	int status;
10149aebddd1SJeff Kirsher 
10159aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
10169aebddd1SJeff Kirsher 
10179aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
10189aebddd1SJeff Kirsher 	if (!wrb) {
10199aebddd1SJeff Kirsher 		status = -EBUSY;
10209aebddd1SJeff Kirsher 		goto err;
10219aebddd1SJeff Kirsher 	}
10229aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
10239aebddd1SJeff Kirsher 
1024106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1025a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req), wrb,
1026a2cc4e0bSSathya Perla 			       NULL);
10279aebddd1SJeff Kirsher 
10289aebddd1SJeff Kirsher 	req->hdr.domain = domain;
10299aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(if_id);
10309aebddd1SJeff Kirsher 	memcpy(req->mac_address, mac_addr, ETH_ALEN);
10319aebddd1SJeff Kirsher 
10329aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
10339aebddd1SJeff Kirsher 	if (!status) {
10349aebddd1SJeff Kirsher 		struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
103503d28ffeSKalesh AP 
10369aebddd1SJeff Kirsher 		*pmac_id = le32_to_cpu(resp->pmac_id);
10379aebddd1SJeff Kirsher 	}
10389aebddd1SJeff Kirsher 
10399aebddd1SJeff Kirsher err:
10409aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
1041e3a7ae2cSSomnath Kotur 
1042e3a7ae2cSSomnath Kotur 	 if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
1043e3a7ae2cSSomnath Kotur 		status = -EPERM;
1044e3a7ae2cSSomnath Kotur 
10459aebddd1SJeff Kirsher 	return status;
10469aebddd1SJeff Kirsher }
10479aebddd1SJeff Kirsher 
10489aebddd1SJeff Kirsher /* Uses synchronous MCCQ */
104930128031SSathya Perla int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
10509aebddd1SJeff Kirsher {
10519aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
10529aebddd1SJeff Kirsher 	struct be_cmd_req_pmac_del *req;
10539aebddd1SJeff Kirsher 	int status;
10549aebddd1SJeff Kirsher 
105530128031SSathya Perla 	if (pmac_id == -1)
105630128031SSathya Perla 		return 0;
105730128031SSathya Perla 
10589aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
10599aebddd1SJeff Kirsher 
10609aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
10619aebddd1SJeff Kirsher 	if (!wrb) {
10629aebddd1SJeff Kirsher 		status = -EBUSY;
10639aebddd1SJeff Kirsher 		goto err;
10649aebddd1SJeff Kirsher 	}
10659aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
10669aebddd1SJeff Kirsher 
1067106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1068cd3307aaSKalesh AP 			       OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req),
1069cd3307aaSKalesh AP 			       wrb, NULL);
10709aebddd1SJeff Kirsher 
10719aebddd1SJeff Kirsher 	req->hdr.domain = dom;
10729aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(if_id);
10739aebddd1SJeff Kirsher 	req->pmac_id = cpu_to_le32(pmac_id);
10749aebddd1SJeff Kirsher 
10759aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
10769aebddd1SJeff Kirsher 
10779aebddd1SJeff Kirsher err:
10789aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
10799aebddd1SJeff Kirsher 	return status;
10809aebddd1SJeff Kirsher }
10819aebddd1SJeff Kirsher 
10829aebddd1SJeff Kirsher /* Uses Mbox */
108310ef9ab4SSathya Perla int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
108410ef9ab4SSathya Perla 		     struct be_queue_info *eq, bool no_delay, int coalesce_wm)
10859aebddd1SJeff Kirsher {
10869aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
10879aebddd1SJeff Kirsher 	struct be_cmd_req_cq_create *req;
10889aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &cq->dma_mem;
10899aebddd1SJeff Kirsher 	void *ctxt;
10909aebddd1SJeff Kirsher 	int status;
10919aebddd1SJeff Kirsher 
10929aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
10939aebddd1SJeff Kirsher 		return -1;
10949aebddd1SJeff Kirsher 
10959aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
10969aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
10979aebddd1SJeff Kirsher 	ctxt = &req->context;
10989aebddd1SJeff Kirsher 
1099106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1100a2cc4e0bSSathya Perla 			       OPCODE_COMMON_CQ_CREATE, sizeof(*req), wrb,
1101a2cc4e0bSSathya Perla 			       NULL);
11029aebddd1SJeff Kirsher 
11039aebddd1SJeff Kirsher 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1104bbdc42f8SAjit Khaparde 
1105bbdc42f8SAjit Khaparde 	if (BEx_chip(adapter)) {
11069aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
11079aebddd1SJeff Kirsher 			      coalesce_wm);
11089aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
11099aebddd1SJeff Kirsher 			      ctxt, no_delay);
11109aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
11119aebddd1SJeff Kirsher 			      __ilog2_u32(cq->len / 256));
11129aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
11139aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
11149aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
1115bbdc42f8SAjit Khaparde 	} else {
1116bbdc42f8SAjit Khaparde 		req->hdr.version = 2;
1117bbdc42f8SAjit Khaparde 		req->page_size = 1; /* 1 for 4K */
111809e83a9dSAjit Khaparde 
111909e83a9dSAjit Khaparde 		/* coalesce-wm field in this cmd is not relevant to Lancer.
112009e83a9dSAjit Khaparde 		 * Lancer uses COMMON_MODIFY_CQ to set this field
112109e83a9dSAjit Khaparde 		 */
112209e83a9dSAjit Khaparde 		if (!lancer_chip(adapter))
112309e83a9dSAjit Khaparde 			AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
112409e83a9dSAjit Khaparde 				      ctxt, coalesce_wm);
1125bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
1126bbdc42f8SAjit Khaparde 			      no_delay);
1127bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
1128bbdc42f8SAjit Khaparde 			      __ilog2_u32(cq->len / 256));
1129bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
1130a2cc4e0bSSathya Perla 		AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
1131a2cc4e0bSSathya Perla 		AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
11329aebddd1SJeff Kirsher 	}
11339aebddd1SJeff Kirsher 
11349aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
11359aebddd1SJeff Kirsher 
11369aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
11379aebddd1SJeff Kirsher 
11389aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
11399aebddd1SJeff Kirsher 	if (!status) {
11409aebddd1SJeff Kirsher 		struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
114103d28ffeSKalesh AP 
11429aebddd1SJeff Kirsher 		cq->id = le16_to_cpu(resp->cq_id);
11439aebddd1SJeff Kirsher 		cq->created = true;
11449aebddd1SJeff Kirsher 	}
11459aebddd1SJeff Kirsher 
11469aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
11479aebddd1SJeff Kirsher 
11489aebddd1SJeff Kirsher 	return status;
11499aebddd1SJeff Kirsher }
11509aebddd1SJeff Kirsher 
11519aebddd1SJeff Kirsher static u32 be_encoded_q_len(int q_len)
11529aebddd1SJeff Kirsher {
11539aebddd1SJeff Kirsher 	u32 len_encoded = fls(q_len); /* log2(len) + 1 */
115403d28ffeSKalesh AP 
11559aebddd1SJeff Kirsher 	if (len_encoded == 16)
11569aebddd1SJeff Kirsher 		len_encoded = 0;
11579aebddd1SJeff Kirsher 	return len_encoded;
11589aebddd1SJeff Kirsher }
11599aebddd1SJeff Kirsher 
11604188e7dfSJingoo Han static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
11619aebddd1SJeff Kirsher 				  struct be_queue_info *mccq,
11629aebddd1SJeff Kirsher 				  struct be_queue_info *cq)
11639aebddd1SJeff Kirsher {
11649aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
11659aebddd1SJeff Kirsher 	struct be_cmd_req_mcc_ext_create *req;
11669aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &mccq->dma_mem;
11679aebddd1SJeff Kirsher 	void *ctxt;
11689aebddd1SJeff Kirsher 	int status;
11699aebddd1SJeff Kirsher 
11709aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
11719aebddd1SJeff Kirsher 		return -1;
11729aebddd1SJeff Kirsher 
11739aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
11749aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
11759aebddd1SJeff Kirsher 	ctxt = &req->context;
11769aebddd1SJeff Kirsher 
1177106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1178a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req), wrb,
1179a2cc4e0bSSathya Perla 			       NULL);
11809aebddd1SJeff Kirsher 
11819aebddd1SJeff Kirsher 	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1182666d39c7SVasundhara Volam 	if (BEx_chip(adapter)) {
11839aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
11849aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
11859aebddd1SJeff Kirsher 			      be_encoded_q_len(mccq->len));
11869aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
1187666d39c7SVasundhara Volam 	} else {
1188666d39c7SVasundhara Volam 		req->hdr.version = 1;
1189666d39c7SVasundhara Volam 		req->cq_id = cpu_to_le16(cq->id);
1190666d39c7SVasundhara Volam 
1191666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, ring_size, ctxt,
1192666d39c7SVasundhara Volam 			      be_encoded_q_len(mccq->len));
1193666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, valid, ctxt, 1);
1194666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_id,
1195666d39c7SVasundhara Volam 			      ctxt, cq->id);
1196666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_valid,
1197666d39c7SVasundhara Volam 			      ctxt, 1);
11989aebddd1SJeff Kirsher 	}
11999aebddd1SJeff Kirsher 
120021252377SVasundhara Volam 	/* Subscribe to Link State, Sliport Event and Group 5 Events
120121252377SVasundhara Volam 	 * (bits 1, 5 and 17 set)
120221252377SVasundhara Volam 	 */
120321252377SVasundhara Volam 	req->async_event_bitmap[0] =
120421252377SVasundhara Volam 			cpu_to_le32(BIT(ASYNC_EVENT_CODE_LINK_STATE) |
120521252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_GRP_5) |
120621252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_QNQ) |
120721252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_SLIPORT));
120821252377SVasundhara Volam 
12099aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
12109aebddd1SJeff Kirsher 
12119aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
12129aebddd1SJeff Kirsher 
12139aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
12149aebddd1SJeff Kirsher 	if (!status) {
12159aebddd1SJeff Kirsher 		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
121603d28ffeSKalesh AP 
12179aebddd1SJeff Kirsher 		mccq->id = le16_to_cpu(resp->id);
12189aebddd1SJeff Kirsher 		mccq->created = true;
12199aebddd1SJeff Kirsher 	}
12209aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
12219aebddd1SJeff Kirsher 
12229aebddd1SJeff Kirsher 	return status;
12239aebddd1SJeff Kirsher }
12249aebddd1SJeff Kirsher 
12254188e7dfSJingoo Han static int be_cmd_mccq_org_create(struct be_adapter *adapter,
12269aebddd1SJeff Kirsher 				  struct be_queue_info *mccq,
12279aebddd1SJeff Kirsher 				  struct be_queue_info *cq)
12289aebddd1SJeff Kirsher {
12299aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
12309aebddd1SJeff Kirsher 	struct be_cmd_req_mcc_create *req;
12319aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &mccq->dma_mem;
12329aebddd1SJeff Kirsher 	void *ctxt;
12339aebddd1SJeff Kirsher 	int status;
12349aebddd1SJeff Kirsher 
12359aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
12369aebddd1SJeff Kirsher 		return -1;
12379aebddd1SJeff Kirsher 
12389aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
12399aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
12409aebddd1SJeff Kirsher 	ctxt = &req->context;
12419aebddd1SJeff Kirsher 
1242106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1243a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MCC_CREATE, sizeof(*req), wrb,
1244a2cc4e0bSSathya Perla 			       NULL);
12459aebddd1SJeff Kirsher 
12469aebddd1SJeff Kirsher 	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
12479aebddd1SJeff Kirsher 
12489aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
12499aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
12509aebddd1SJeff Kirsher 		      be_encoded_q_len(mccq->len));
12519aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
12529aebddd1SJeff Kirsher 
12539aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
12549aebddd1SJeff Kirsher 
12559aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
12569aebddd1SJeff Kirsher 
12579aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
12589aebddd1SJeff Kirsher 	if (!status) {
12599aebddd1SJeff Kirsher 		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
126003d28ffeSKalesh AP 
12619aebddd1SJeff Kirsher 		mccq->id = le16_to_cpu(resp->id);
12629aebddd1SJeff Kirsher 		mccq->created = true;
12639aebddd1SJeff Kirsher 	}
12649aebddd1SJeff Kirsher 
12659aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
12669aebddd1SJeff Kirsher 	return status;
12679aebddd1SJeff Kirsher }
12689aebddd1SJeff Kirsher 
12699aebddd1SJeff Kirsher int be_cmd_mccq_create(struct be_adapter *adapter,
1270a2cc4e0bSSathya Perla 		       struct be_queue_info *mccq, struct be_queue_info *cq)
12719aebddd1SJeff Kirsher {
12729aebddd1SJeff Kirsher 	int status;
12739aebddd1SJeff Kirsher 
12749aebddd1SJeff Kirsher 	status = be_cmd_mccq_ext_create(adapter, mccq, cq);
1275666d39c7SVasundhara Volam 	if (status && BEx_chip(adapter)) {
12769aebddd1SJeff Kirsher 		dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
12779aebddd1SJeff Kirsher 			"or newer to avoid conflicting priorities between NIC "
12789aebddd1SJeff Kirsher 			"and FCoE traffic");
12799aebddd1SJeff Kirsher 		status = be_cmd_mccq_org_create(adapter, mccq, cq);
12809aebddd1SJeff Kirsher 	}
12819aebddd1SJeff Kirsher 	return status;
12829aebddd1SJeff Kirsher }
12839aebddd1SJeff Kirsher 
128494d73aaaSVasundhara Volam int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo)
12859aebddd1SJeff Kirsher {
12867707133cSSathya Perla 	struct be_mcc_wrb wrb = {0};
12879aebddd1SJeff Kirsher 	struct be_cmd_req_eth_tx_create *req;
128894d73aaaSVasundhara Volam 	struct be_queue_info *txq = &txo->q;
128994d73aaaSVasundhara Volam 	struct be_queue_info *cq = &txo->cq;
12909aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &txq->dma_mem;
129194d73aaaSVasundhara Volam 	int status, ver = 0;
12929aebddd1SJeff Kirsher 
12937707133cSSathya Perla 	req = embedded_payload(&wrb);
1294106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
12957707133cSSathya Perla 			       OPCODE_ETH_TX_CREATE, sizeof(*req), &wrb, NULL);
12969aebddd1SJeff Kirsher 
12979aebddd1SJeff Kirsher 	if (lancer_chip(adapter)) {
12989aebddd1SJeff Kirsher 		req->hdr.version = 1;
129994d73aaaSVasundhara Volam 	} else if (BEx_chip(adapter)) {
130094d73aaaSVasundhara Volam 		if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC)
130194d73aaaSVasundhara Volam 			req->hdr.version = 2;
130294d73aaaSVasundhara Volam 	} else { /* For SH */
130394d73aaaSVasundhara Volam 		req->hdr.version = 2;
13049aebddd1SJeff Kirsher 	}
13059aebddd1SJeff Kirsher 
130681b02655SVasundhara Volam 	if (req->hdr.version > 0)
130781b02655SVasundhara Volam 		req->if_id = cpu_to_le16(adapter->if_handle);
13089aebddd1SJeff Kirsher 	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
13099aebddd1SJeff Kirsher 	req->ulp_num = BE_ULP1_NUM;
13109aebddd1SJeff Kirsher 	req->type = BE_ETH_TX_RING_TYPE_STANDARD;
131194d73aaaSVasundhara Volam 	req->cq_id = cpu_to_le16(cq->id);
131294d73aaaSVasundhara Volam 	req->queue_size = be_encoded_q_len(txq->len);
13139aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
131494d73aaaSVasundhara Volam 	ver = req->hdr.version;
131594d73aaaSVasundhara Volam 
13167707133cSSathya Perla 	status = be_cmd_notify_wait(adapter, &wrb);
13179aebddd1SJeff Kirsher 	if (!status) {
13187707133cSSathya Perla 		struct be_cmd_resp_eth_tx_create *resp = embedded_payload(&wrb);
131903d28ffeSKalesh AP 
13209aebddd1SJeff Kirsher 		txq->id = le16_to_cpu(resp->cid);
132194d73aaaSVasundhara Volam 		if (ver == 2)
132294d73aaaSVasundhara Volam 			txo->db_offset = le32_to_cpu(resp->db_offset);
132394d73aaaSVasundhara Volam 		else
132494d73aaaSVasundhara Volam 			txo->db_offset = DB_TXULP1_OFFSET;
13259aebddd1SJeff Kirsher 		txq->created = true;
13269aebddd1SJeff Kirsher 	}
13279aebddd1SJeff Kirsher 
13289aebddd1SJeff Kirsher 	return status;
13299aebddd1SJeff Kirsher }
13309aebddd1SJeff Kirsher 
13319aebddd1SJeff Kirsher /* Uses MCC */
13329aebddd1SJeff Kirsher int be_cmd_rxq_create(struct be_adapter *adapter,
13339aebddd1SJeff Kirsher 		      struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
133410ef9ab4SSathya Perla 		      u32 if_id, u32 rss, u8 *rss_id)
13359aebddd1SJeff Kirsher {
13369aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
13379aebddd1SJeff Kirsher 	struct be_cmd_req_eth_rx_create *req;
13389aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &rxq->dma_mem;
13399aebddd1SJeff Kirsher 	int status;
13409aebddd1SJeff Kirsher 
13419aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
13429aebddd1SJeff Kirsher 
13439aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
13449aebddd1SJeff Kirsher 	if (!wrb) {
13459aebddd1SJeff Kirsher 		status = -EBUSY;
13469aebddd1SJeff Kirsher 		goto err;
13479aebddd1SJeff Kirsher 	}
13489aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
13499aebddd1SJeff Kirsher 
1350106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1351106df1e3SSomnath Kotur 			       OPCODE_ETH_RX_CREATE, sizeof(*req), wrb, NULL);
13529aebddd1SJeff Kirsher 
13539aebddd1SJeff Kirsher 	req->cq_id = cpu_to_le16(cq_id);
13549aebddd1SJeff Kirsher 	req->frag_size = fls(frag_size) - 1;
13559aebddd1SJeff Kirsher 	req->num_pages = 2;
13569aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
13579aebddd1SJeff Kirsher 	req->interface_id = cpu_to_le32(if_id);
135810ef9ab4SSathya Perla 	req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
13599aebddd1SJeff Kirsher 	req->rss_queue = cpu_to_le32(rss);
13609aebddd1SJeff Kirsher 
13619aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
13629aebddd1SJeff Kirsher 	if (!status) {
13639aebddd1SJeff Kirsher 		struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
136403d28ffeSKalesh AP 
13659aebddd1SJeff Kirsher 		rxq->id = le16_to_cpu(resp->id);
13669aebddd1SJeff Kirsher 		rxq->created = true;
13679aebddd1SJeff Kirsher 		*rss_id = resp->rss_id;
13689aebddd1SJeff Kirsher 	}
13699aebddd1SJeff Kirsher 
13709aebddd1SJeff Kirsher err:
13719aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
13729aebddd1SJeff Kirsher 	return status;
13739aebddd1SJeff Kirsher }
13749aebddd1SJeff Kirsher 
13759aebddd1SJeff Kirsher /* Generic destroyer function for all types of queues
13769aebddd1SJeff Kirsher  * Uses Mbox
13779aebddd1SJeff Kirsher  */
13789aebddd1SJeff Kirsher int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
13799aebddd1SJeff Kirsher 		     int queue_type)
13809aebddd1SJeff Kirsher {
13819aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
13829aebddd1SJeff Kirsher 	struct be_cmd_req_q_destroy *req;
13839aebddd1SJeff Kirsher 	u8 subsys = 0, opcode = 0;
13849aebddd1SJeff Kirsher 	int status;
13859aebddd1SJeff Kirsher 
13869aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
13879aebddd1SJeff Kirsher 		return -1;
13889aebddd1SJeff Kirsher 
13899aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
13909aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
13919aebddd1SJeff Kirsher 
13929aebddd1SJeff Kirsher 	switch (queue_type) {
13939aebddd1SJeff Kirsher 	case QTYPE_EQ:
13949aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
13959aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_EQ_DESTROY;
13969aebddd1SJeff Kirsher 		break;
13979aebddd1SJeff Kirsher 	case QTYPE_CQ:
13989aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
13999aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_CQ_DESTROY;
14009aebddd1SJeff Kirsher 		break;
14019aebddd1SJeff Kirsher 	case QTYPE_TXQ:
14029aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_ETH;
14039aebddd1SJeff Kirsher 		opcode = OPCODE_ETH_TX_DESTROY;
14049aebddd1SJeff Kirsher 		break;
14059aebddd1SJeff Kirsher 	case QTYPE_RXQ:
14069aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_ETH;
14079aebddd1SJeff Kirsher 		opcode = OPCODE_ETH_RX_DESTROY;
14089aebddd1SJeff Kirsher 		break;
14099aebddd1SJeff Kirsher 	case QTYPE_MCCQ:
14109aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
14119aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_MCC_DESTROY;
14129aebddd1SJeff Kirsher 		break;
14139aebddd1SJeff Kirsher 	default:
14149aebddd1SJeff Kirsher 		BUG();
14159aebddd1SJeff Kirsher 	}
14169aebddd1SJeff Kirsher 
1417106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req), wrb,
1418106df1e3SSomnath Kotur 			       NULL);
14199aebddd1SJeff Kirsher 	req->id = cpu_to_le16(q->id);
14209aebddd1SJeff Kirsher 
14219aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
14229aebddd1SJeff Kirsher 	q->created = false;
14239aebddd1SJeff Kirsher 
14249aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
14259aebddd1SJeff Kirsher 	return status;
14269aebddd1SJeff Kirsher }
14279aebddd1SJeff Kirsher 
14289aebddd1SJeff Kirsher /* Uses MCC */
14299aebddd1SJeff Kirsher int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
14309aebddd1SJeff Kirsher {
14319aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
14329aebddd1SJeff Kirsher 	struct be_cmd_req_q_destroy *req;
14339aebddd1SJeff Kirsher 	int status;
14349aebddd1SJeff Kirsher 
14359aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
14369aebddd1SJeff Kirsher 
14379aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
14389aebddd1SJeff Kirsher 	if (!wrb) {
14399aebddd1SJeff Kirsher 		status = -EBUSY;
14409aebddd1SJeff Kirsher 		goto err;
14419aebddd1SJeff Kirsher 	}
14429aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
14439aebddd1SJeff Kirsher 
1444106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1445106df1e3SSomnath Kotur 			       OPCODE_ETH_RX_DESTROY, sizeof(*req), wrb, NULL);
14469aebddd1SJeff Kirsher 	req->id = cpu_to_le16(q->id);
14479aebddd1SJeff Kirsher 
14489aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
14499aebddd1SJeff Kirsher 	q->created = false;
14509aebddd1SJeff Kirsher 
14519aebddd1SJeff Kirsher err:
14529aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
14539aebddd1SJeff Kirsher 	return status;
14549aebddd1SJeff Kirsher }
14559aebddd1SJeff Kirsher 
14569aebddd1SJeff Kirsher /* Create an rx filtering policy configuration on an i/f
1457bea50988SSathya Perla  * Will use MBOX only if MCCQ has not been created.
14589aebddd1SJeff Kirsher  */
14599aebddd1SJeff Kirsher int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
14601578e777SPadmanabh Ratnakar 		     u32 *if_handle, u32 domain)
14619aebddd1SJeff Kirsher {
1462bea50988SSathya Perla 	struct be_mcc_wrb wrb = {0};
14639aebddd1SJeff Kirsher 	struct be_cmd_req_if_create *req;
14649aebddd1SJeff Kirsher 	int status;
14659aebddd1SJeff Kirsher 
1466bea50988SSathya Perla 	req = embedded_payload(&wrb);
1467106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1468a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_INTERFACE_CREATE,
1469a2cc4e0bSSathya Perla 			       sizeof(*req), &wrb, NULL);
14709aebddd1SJeff Kirsher 	req->hdr.domain = domain;
14719aebddd1SJeff Kirsher 	req->capability_flags = cpu_to_le32(cap_flags);
14729aebddd1SJeff Kirsher 	req->enable_flags = cpu_to_le32(en_flags);
1473f9449ab7SSathya Perla 	req->pmac_invalid = true;
14749aebddd1SJeff Kirsher 
1475bea50988SSathya Perla 	status = be_cmd_notify_wait(adapter, &wrb);
14769aebddd1SJeff Kirsher 	if (!status) {
1477bea50988SSathya Perla 		struct be_cmd_resp_if_create *resp = embedded_payload(&wrb);
147803d28ffeSKalesh AP 
14799aebddd1SJeff Kirsher 		*if_handle = le32_to_cpu(resp->interface_id);
1480b5bb9776SSathya Perla 
1481b5bb9776SSathya Perla 		/* Hack to retrieve VF's pmac-id on BE3 */
148218c57c74SKalesh AP 		if (BE3_chip(adapter) && be_virtfn(adapter))
1483b5bb9776SSathya Perla 			adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id);
14849aebddd1SJeff Kirsher 	}
14859aebddd1SJeff Kirsher 	return status;
14869aebddd1SJeff Kirsher }
14879aebddd1SJeff Kirsher 
1488f9449ab7SSathya Perla /* Uses MCCQ */
148930128031SSathya Perla int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
14909aebddd1SJeff Kirsher {
14919aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
14929aebddd1SJeff Kirsher 	struct be_cmd_req_if_destroy *req;
14939aebddd1SJeff Kirsher 	int status;
14949aebddd1SJeff Kirsher 
149530128031SSathya Perla 	if (interface_id == -1)
1496f9449ab7SSathya Perla 		return 0;
14979aebddd1SJeff Kirsher 
1498f9449ab7SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
1499f9449ab7SSathya Perla 
1500f9449ab7SSathya Perla 	wrb = wrb_from_mccq(adapter);
1501f9449ab7SSathya Perla 	if (!wrb) {
1502f9449ab7SSathya Perla 		status = -EBUSY;
1503f9449ab7SSathya Perla 		goto err;
1504f9449ab7SSathya Perla 	}
15059aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
15069aebddd1SJeff Kirsher 
1507106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1508a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_INTERFACE_DESTROY,
1509a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
15109aebddd1SJeff Kirsher 	req->hdr.domain = domain;
15119aebddd1SJeff Kirsher 	req->interface_id = cpu_to_le32(interface_id);
15129aebddd1SJeff Kirsher 
1513f9449ab7SSathya Perla 	status = be_mcc_notify_wait(adapter);
1514f9449ab7SSathya Perla err:
1515f9449ab7SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
15169aebddd1SJeff Kirsher 	return status;
15179aebddd1SJeff Kirsher }
15189aebddd1SJeff Kirsher 
15199aebddd1SJeff Kirsher /* Get stats is a non embedded command: the request is not embedded inside
15209aebddd1SJeff Kirsher  * WRB but is a separate dma memory block
15219aebddd1SJeff Kirsher  * Uses asynchronous MCC
15229aebddd1SJeff Kirsher  */
15239aebddd1SJeff Kirsher int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
15249aebddd1SJeff Kirsher {
15259aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
15269aebddd1SJeff Kirsher 	struct be_cmd_req_hdr *hdr;
15279aebddd1SJeff Kirsher 	int status = 0;
15289aebddd1SJeff Kirsher 
15299aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
15309aebddd1SJeff Kirsher 
15319aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
15329aebddd1SJeff Kirsher 	if (!wrb) {
15339aebddd1SJeff Kirsher 		status = -EBUSY;
15349aebddd1SJeff Kirsher 		goto err;
15359aebddd1SJeff Kirsher 	}
15369aebddd1SJeff Kirsher 	hdr = nonemb_cmd->va;
15379aebddd1SJeff Kirsher 
1538106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
1539a2cc4e0bSSathya Perla 			       OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb,
1540a2cc4e0bSSathya Perla 			       nonemb_cmd);
15419aebddd1SJeff Kirsher 
1542ca34fe38SSathya Perla 	/* version 1 of the cmd is not supported only by BE2 */
154361000861SAjit Khaparde 	if (BE2_chip(adapter))
154461000861SAjit Khaparde 		hdr->version = 0;
154561000861SAjit Khaparde 	if (BE3_chip(adapter) || lancer_chip(adapter))
15469aebddd1SJeff Kirsher 		hdr->version = 1;
154761000861SAjit Khaparde 	else
154861000861SAjit Khaparde 		hdr->version = 2;
15499aebddd1SJeff Kirsher 
15509aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
15519aebddd1SJeff Kirsher 	adapter->stats_cmd_sent = true;
15529aebddd1SJeff Kirsher 
15539aebddd1SJeff Kirsher err:
15549aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
15559aebddd1SJeff Kirsher 	return status;
15569aebddd1SJeff Kirsher }
15579aebddd1SJeff Kirsher 
15589aebddd1SJeff Kirsher /* Lancer Stats */
15599aebddd1SJeff Kirsher int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
15609aebddd1SJeff Kirsher 			       struct be_dma_mem *nonemb_cmd)
15619aebddd1SJeff Kirsher {
15629aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
15639aebddd1SJeff Kirsher 	struct lancer_cmd_req_pport_stats *req;
15649aebddd1SJeff Kirsher 	int status = 0;
15659aebddd1SJeff Kirsher 
1566f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
1567f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_ETH))
1568f25b119cSPadmanabh Ratnakar 		return -EPERM;
1569f25b119cSPadmanabh Ratnakar 
15709aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
15719aebddd1SJeff Kirsher 
15729aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
15739aebddd1SJeff Kirsher 	if (!wrb) {
15749aebddd1SJeff Kirsher 		status = -EBUSY;
15759aebddd1SJeff Kirsher 		goto err;
15769aebddd1SJeff Kirsher 	}
15779aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
15789aebddd1SJeff Kirsher 
1579106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1580a2cc4e0bSSathya Perla 			       OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size,
1581a2cc4e0bSSathya Perla 			       wrb, nonemb_cmd);
15829aebddd1SJeff Kirsher 
1583d51ebd33SPadmanabh Ratnakar 	req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
15849aebddd1SJeff Kirsher 	req->cmd_params.params.reset_stats = 0;
15859aebddd1SJeff Kirsher 
15869aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
15879aebddd1SJeff Kirsher 	adapter->stats_cmd_sent = true;
15889aebddd1SJeff Kirsher 
15899aebddd1SJeff Kirsher err:
15909aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
15919aebddd1SJeff Kirsher 	return status;
15929aebddd1SJeff Kirsher }
15939aebddd1SJeff Kirsher 
1594323ff71eSSathya Perla static int be_mac_to_link_speed(int mac_speed)
1595323ff71eSSathya Perla {
1596323ff71eSSathya Perla 	switch (mac_speed) {
1597323ff71eSSathya Perla 	case PHY_LINK_SPEED_ZERO:
1598323ff71eSSathya Perla 		return 0;
1599323ff71eSSathya Perla 	case PHY_LINK_SPEED_10MBPS:
1600323ff71eSSathya Perla 		return 10;
1601323ff71eSSathya Perla 	case PHY_LINK_SPEED_100MBPS:
1602323ff71eSSathya Perla 		return 100;
1603323ff71eSSathya Perla 	case PHY_LINK_SPEED_1GBPS:
1604323ff71eSSathya Perla 		return 1000;
1605323ff71eSSathya Perla 	case PHY_LINK_SPEED_10GBPS:
1606323ff71eSSathya Perla 		return 10000;
1607b971f847SVasundhara Volam 	case PHY_LINK_SPEED_20GBPS:
1608b971f847SVasundhara Volam 		return 20000;
1609b971f847SVasundhara Volam 	case PHY_LINK_SPEED_25GBPS:
1610b971f847SVasundhara Volam 		return 25000;
1611b971f847SVasundhara Volam 	case PHY_LINK_SPEED_40GBPS:
1612b971f847SVasundhara Volam 		return 40000;
1613323ff71eSSathya Perla 	}
1614323ff71eSSathya Perla 	return 0;
1615323ff71eSSathya Perla }
1616323ff71eSSathya Perla 
1617323ff71eSSathya Perla /* Uses synchronous mcc
1618323ff71eSSathya Perla  * Returns link_speed in Mbps
1619323ff71eSSathya Perla  */
1620323ff71eSSathya Perla int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
1621323ff71eSSathya Perla 			     u8 *link_status, u32 dom)
16229aebddd1SJeff Kirsher {
16239aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
16249aebddd1SJeff Kirsher 	struct be_cmd_req_link_status *req;
16259aebddd1SJeff Kirsher 	int status;
16269aebddd1SJeff Kirsher 
16279aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
16289aebddd1SJeff Kirsher 
1629b236916aSAjit Khaparde 	if (link_status)
1630b236916aSAjit Khaparde 		*link_status = LINK_DOWN;
1631b236916aSAjit Khaparde 
16329aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
16339aebddd1SJeff Kirsher 	if (!wrb) {
16349aebddd1SJeff Kirsher 		status = -EBUSY;
16359aebddd1SJeff Kirsher 		goto err;
16369aebddd1SJeff Kirsher 	}
16379aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
16389aebddd1SJeff Kirsher 
163957cd80d4SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1640a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1641a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
164257cd80d4SPadmanabh Ratnakar 
1643ca34fe38SSathya Perla 	/* version 1 of the cmd is not supported only by BE2 */
1644ca34fe38SSathya Perla 	if (!BE2_chip(adapter))
1645daad6167SPadmanabh Ratnakar 		req->hdr.version = 1;
1646daad6167SPadmanabh Ratnakar 
164757cd80d4SPadmanabh Ratnakar 	req->hdr.domain = dom;
16489aebddd1SJeff Kirsher 
16499aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
16509aebddd1SJeff Kirsher 	if (!status) {
16519aebddd1SJeff Kirsher 		struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
165203d28ffeSKalesh AP 
1653323ff71eSSathya Perla 		if (link_speed) {
1654323ff71eSSathya Perla 			*link_speed = resp->link_speed ?
1655323ff71eSSathya Perla 				      le16_to_cpu(resp->link_speed) * 10 :
1656323ff71eSSathya Perla 				      be_mac_to_link_speed(resp->mac_speed);
1657323ff71eSSathya Perla 
1658323ff71eSSathya Perla 			if (!resp->logical_link_status)
1659323ff71eSSathya Perla 				*link_speed = 0;
16609aebddd1SJeff Kirsher 		}
1661b236916aSAjit Khaparde 		if (link_status)
1662b236916aSAjit Khaparde 			*link_status = resp->logical_link_status;
16639aebddd1SJeff Kirsher 	}
16649aebddd1SJeff Kirsher 
16659aebddd1SJeff Kirsher err:
16669aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
16679aebddd1SJeff Kirsher 	return status;
16689aebddd1SJeff Kirsher }
16699aebddd1SJeff Kirsher 
16709aebddd1SJeff Kirsher /* Uses synchronous mcc */
16719aebddd1SJeff Kirsher int be_cmd_get_die_temperature(struct be_adapter *adapter)
16729aebddd1SJeff Kirsher {
16739aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
16749aebddd1SJeff Kirsher 	struct be_cmd_req_get_cntl_addnl_attribs *req;
1675117affe3SVasundhara Volam 	int status = 0;
16769aebddd1SJeff Kirsher 
16779aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
16789aebddd1SJeff Kirsher 
16799aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
16809aebddd1SJeff Kirsher 	if (!wrb) {
16819aebddd1SJeff Kirsher 		status = -EBUSY;
16829aebddd1SJeff Kirsher 		goto err;
16839aebddd1SJeff Kirsher 	}
16849aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
16859aebddd1SJeff Kirsher 
1686106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1687a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES,
1688a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
16899aebddd1SJeff Kirsher 
16903de09455SSomnath Kotur 	be_mcc_notify(adapter);
16919aebddd1SJeff Kirsher 
16929aebddd1SJeff Kirsher err:
16939aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
16949aebddd1SJeff Kirsher 	return status;
16959aebddd1SJeff Kirsher }
16969aebddd1SJeff Kirsher 
16979aebddd1SJeff Kirsher /* Uses synchronous mcc */
16989aebddd1SJeff Kirsher int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
16999aebddd1SJeff Kirsher {
17009aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
17019aebddd1SJeff Kirsher 	struct be_cmd_req_get_fat *req;
17029aebddd1SJeff Kirsher 	int status;
17039aebddd1SJeff Kirsher 
17049aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
17059aebddd1SJeff Kirsher 
17069aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
17079aebddd1SJeff Kirsher 	if (!wrb) {
17089aebddd1SJeff Kirsher 		status = -EBUSY;
17099aebddd1SJeff Kirsher 		goto err;
17109aebddd1SJeff Kirsher 	}
17119aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
17129aebddd1SJeff Kirsher 
1713106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1714a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MANAGE_FAT, sizeof(*req), wrb,
1715a2cc4e0bSSathya Perla 			       NULL);
17169aebddd1SJeff Kirsher 	req->fat_operation = cpu_to_le32(QUERY_FAT);
17179aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
17189aebddd1SJeff Kirsher 	if (!status) {
17199aebddd1SJeff Kirsher 		struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
172003d28ffeSKalesh AP 
17219aebddd1SJeff Kirsher 		if (log_size && resp->log_size)
17229aebddd1SJeff Kirsher 			*log_size = le32_to_cpu(resp->log_size) -
17239aebddd1SJeff Kirsher 					sizeof(u32);
17249aebddd1SJeff Kirsher 	}
17259aebddd1SJeff Kirsher err:
17269aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
17279aebddd1SJeff Kirsher 	return status;
17289aebddd1SJeff Kirsher }
17299aebddd1SJeff Kirsher 
1730c5f156deSVasundhara Volam int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
17319aebddd1SJeff Kirsher {
17329aebddd1SJeff Kirsher 	struct be_dma_mem get_fat_cmd;
17339aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
17349aebddd1SJeff Kirsher 	struct be_cmd_req_get_fat *req;
17359aebddd1SJeff Kirsher 	u32 offset = 0, total_size, buf_size,
17369aebddd1SJeff Kirsher 				log_offset = sizeof(u32), payload_len;
1737c5f156deSVasundhara Volam 	int status = 0;
17389aebddd1SJeff Kirsher 
17399aebddd1SJeff Kirsher 	if (buf_len == 0)
1740c5f156deSVasundhara Volam 		return -EIO;
17419aebddd1SJeff Kirsher 
17429aebddd1SJeff Kirsher 	total_size = buf_len;
17439aebddd1SJeff Kirsher 
17449aebddd1SJeff Kirsher 	get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
17459aebddd1SJeff Kirsher 	get_fat_cmd.va = pci_alloc_consistent(adapter->pdev,
17469aebddd1SJeff Kirsher 					      get_fat_cmd.size,
17479aebddd1SJeff Kirsher 					      &get_fat_cmd.dma);
17489aebddd1SJeff Kirsher 	if (!get_fat_cmd.va) {
17499aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev,
1750cd3307aaSKalesh AP 			"Memory allocation failure while reading FAT data\n");
1751c5f156deSVasundhara Volam 		return -ENOMEM;
17529aebddd1SJeff Kirsher 	}
17539aebddd1SJeff Kirsher 
17549aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
17559aebddd1SJeff Kirsher 
17569aebddd1SJeff Kirsher 	while (total_size) {
17579aebddd1SJeff Kirsher 		buf_size = min(total_size, (u32)60*1024);
17589aebddd1SJeff Kirsher 		total_size -= buf_size;
17599aebddd1SJeff Kirsher 
17609aebddd1SJeff Kirsher 		wrb = wrb_from_mccq(adapter);
17619aebddd1SJeff Kirsher 		if (!wrb) {
17629aebddd1SJeff Kirsher 			status = -EBUSY;
17639aebddd1SJeff Kirsher 			goto err;
17649aebddd1SJeff Kirsher 		}
17659aebddd1SJeff Kirsher 		req = get_fat_cmd.va;
17669aebddd1SJeff Kirsher 
17679aebddd1SJeff Kirsher 		payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
1768106df1e3SSomnath Kotur 		be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1769a2cc4e0bSSathya Perla 				       OPCODE_COMMON_MANAGE_FAT, payload_len,
1770a2cc4e0bSSathya Perla 				       wrb, &get_fat_cmd);
17719aebddd1SJeff Kirsher 
17729aebddd1SJeff Kirsher 		req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
17739aebddd1SJeff Kirsher 		req->read_log_offset = cpu_to_le32(log_offset);
17749aebddd1SJeff Kirsher 		req->read_log_length = cpu_to_le32(buf_size);
17759aebddd1SJeff Kirsher 		req->data_buffer_size = cpu_to_le32(buf_size);
17769aebddd1SJeff Kirsher 
17779aebddd1SJeff Kirsher 		status = be_mcc_notify_wait(adapter);
17789aebddd1SJeff Kirsher 		if (!status) {
17799aebddd1SJeff Kirsher 			struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
178003d28ffeSKalesh AP 
17819aebddd1SJeff Kirsher 			memcpy(buf + offset,
17829aebddd1SJeff Kirsher 			       resp->data_buffer,
178392aa9214SSomnath Kotur 			       le32_to_cpu(resp->read_log_length));
17849aebddd1SJeff Kirsher 		} else {
17859aebddd1SJeff Kirsher 			dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
17869aebddd1SJeff Kirsher 			goto err;
17879aebddd1SJeff Kirsher 		}
17889aebddd1SJeff Kirsher 		offset += buf_size;
17899aebddd1SJeff Kirsher 		log_offset += buf_size;
17909aebddd1SJeff Kirsher 	}
17919aebddd1SJeff Kirsher err:
17929aebddd1SJeff Kirsher 	pci_free_consistent(adapter->pdev, get_fat_cmd.size,
1793a2cc4e0bSSathya Perla 			    get_fat_cmd.va, get_fat_cmd.dma);
17949aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
1795c5f156deSVasundhara Volam 	return status;
17969aebddd1SJeff Kirsher }
17979aebddd1SJeff Kirsher 
179804b71175SSathya Perla /* Uses synchronous mcc */
1799e97e3cdaSKalesh AP int be_cmd_get_fw_ver(struct be_adapter *adapter)
18009aebddd1SJeff Kirsher {
18019aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
18029aebddd1SJeff Kirsher 	struct be_cmd_req_get_fw_version *req;
18039aebddd1SJeff Kirsher 	int status;
18049aebddd1SJeff Kirsher 
180504b71175SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
18069aebddd1SJeff Kirsher 
180704b71175SSathya Perla 	wrb = wrb_from_mccq(adapter);
180804b71175SSathya Perla 	if (!wrb) {
180904b71175SSathya Perla 		status = -EBUSY;
181004b71175SSathya Perla 		goto err;
181104b71175SSathya Perla 	}
181204b71175SSathya Perla 
18139aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
18149aebddd1SJeff Kirsher 
1815106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1816a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_FW_VERSION, sizeof(*req), wrb,
1817a2cc4e0bSSathya Perla 			       NULL);
181804b71175SSathya Perla 	status = be_mcc_notify_wait(adapter);
18199aebddd1SJeff Kirsher 	if (!status) {
18209aebddd1SJeff Kirsher 		struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
1821acbafeb1SSathya Perla 
1822242eb470SVasundhara Volam 		strlcpy(adapter->fw_ver, resp->firmware_version_string,
1823242eb470SVasundhara Volam 			sizeof(adapter->fw_ver));
1824242eb470SVasundhara Volam 		strlcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string,
1825242eb470SVasundhara Volam 			sizeof(adapter->fw_on_flash));
18269aebddd1SJeff Kirsher 	}
182704b71175SSathya Perla err:
182804b71175SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
18299aebddd1SJeff Kirsher 	return status;
18309aebddd1SJeff Kirsher }
18319aebddd1SJeff Kirsher 
18329aebddd1SJeff Kirsher /* set the EQ delay interval of an EQ to specified value
18339aebddd1SJeff Kirsher  * Uses async mcc
18349aebddd1SJeff Kirsher  */
1835b502ae8dSKalesh AP static int __be_cmd_modify_eqd(struct be_adapter *adapter,
1836b502ae8dSKalesh AP 			       struct be_set_eqd *set_eqd, int num)
18379aebddd1SJeff Kirsher {
18389aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
18399aebddd1SJeff Kirsher 	struct be_cmd_req_modify_eq_delay *req;
18402632bafdSSathya Perla 	int status = 0, i;
18419aebddd1SJeff Kirsher 
18429aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
18439aebddd1SJeff Kirsher 
18449aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
18459aebddd1SJeff Kirsher 	if (!wrb) {
18469aebddd1SJeff Kirsher 		status = -EBUSY;
18479aebddd1SJeff Kirsher 		goto err;
18489aebddd1SJeff Kirsher 	}
18499aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
18509aebddd1SJeff Kirsher 
1851106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1852a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req), wrb,
1853a2cc4e0bSSathya Perla 			       NULL);
18549aebddd1SJeff Kirsher 
18552632bafdSSathya Perla 	req->num_eq = cpu_to_le32(num);
18562632bafdSSathya Perla 	for (i = 0; i < num; i++) {
18572632bafdSSathya Perla 		req->set_eqd[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
18582632bafdSSathya Perla 		req->set_eqd[i].phase = 0;
18592632bafdSSathya Perla 		req->set_eqd[i].delay_multiplier =
18602632bafdSSathya Perla 				cpu_to_le32(set_eqd[i].delay_multiplier);
18612632bafdSSathya Perla 	}
18629aebddd1SJeff Kirsher 
18639aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
18649aebddd1SJeff Kirsher err:
18659aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
18669aebddd1SJeff Kirsher 	return status;
18679aebddd1SJeff Kirsher }
18689aebddd1SJeff Kirsher 
186993676703SKalesh AP int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
187093676703SKalesh AP 		      int num)
187193676703SKalesh AP {
187293676703SKalesh AP 	int num_eqs, i = 0;
187393676703SKalesh AP 
187493676703SKalesh AP 	while (num) {
187593676703SKalesh AP 		num_eqs = min(num, 8);
187693676703SKalesh AP 		__be_cmd_modify_eqd(adapter, &set_eqd[i], num_eqs);
187793676703SKalesh AP 		i += num_eqs;
187893676703SKalesh AP 		num -= num_eqs;
187993676703SKalesh AP 	}
188093676703SKalesh AP 
188193676703SKalesh AP 	return 0;
188293676703SKalesh AP }
188393676703SKalesh AP 
18849aebddd1SJeff Kirsher /* Uses sycnhronous mcc */
18859aebddd1SJeff Kirsher int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
1886435452aaSVasundhara Volam 		       u32 num, u32 domain)
18879aebddd1SJeff Kirsher {
18889aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
18899aebddd1SJeff Kirsher 	struct be_cmd_req_vlan_config *req;
18909aebddd1SJeff Kirsher 	int status;
18919aebddd1SJeff Kirsher 
18929aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
18939aebddd1SJeff Kirsher 
18949aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
18959aebddd1SJeff Kirsher 	if (!wrb) {
18969aebddd1SJeff Kirsher 		status = -EBUSY;
18979aebddd1SJeff Kirsher 		goto err;
18989aebddd1SJeff Kirsher 	}
18999aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
19009aebddd1SJeff Kirsher 
1901106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1902a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req),
1903a2cc4e0bSSathya Perla 			       wrb, NULL);
1904435452aaSVasundhara Volam 	req->hdr.domain = domain;
19059aebddd1SJeff Kirsher 
19069aebddd1SJeff Kirsher 	req->interface_id = if_id;
1907012bd387SAjit Khaparde 	req->untagged = BE_IF_FLAGS_UNTAGGED & be_if_cap_flags(adapter) ? 1 : 0;
19089aebddd1SJeff Kirsher 	req->num_vlan = num;
19099aebddd1SJeff Kirsher 	memcpy(req->normal_vlan, vtag_array,
19109aebddd1SJeff Kirsher 	       req->num_vlan * sizeof(vtag_array[0]));
19119aebddd1SJeff Kirsher 
19129aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
19139aebddd1SJeff Kirsher err:
19149aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
19159aebddd1SJeff Kirsher 	return status;
19169aebddd1SJeff Kirsher }
19179aebddd1SJeff Kirsher 
1918ac34b743SSathya Perla static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
19199aebddd1SJeff Kirsher {
19209aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
19219aebddd1SJeff Kirsher 	struct be_dma_mem *mem = &adapter->rx_filter;
19229aebddd1SJeff Kirsher 	struct be_cmd_req_rx_filter *req = mem->va;
19239aebddd1SJeff Kirsher 	int status;
19249aebddd1SJeff Kirsher 
19259aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
19269aebddd1SJeff Kirsher 
19279aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
19289aebddd1SJeff Kirsher 	if (!wrb) {
19299aebddd1SJeff Kirsher 		status = -EBUSY;
19309aebddd1SJeff Kirsher 		goto err;
19319aebddd1SJeff Kirsher 	}
19329aebddd1SJeff Kirsher 	memset(req, 0, sizeof(*req));
1933106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1934106df1e3SSomnath Kotur 			       OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req),
1935106df1e3SSomnath Kotur 			       wrb, mem);
19369aebddd1SJeff Kirsher 
19379aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(adapter->if_handle);
1938ac34b743SSathya Perla 	req->if_flags_mask = cpu_to_le32(flags);
1939ac34b743SSathya Perla 	req->if_flags = (value == ON) ? req->if_flags_mask : 0;
1940d9d604f8SAjit Khaparde 
1941ac34b743SSathya Perla 	if (flags & BE_IF_FLAGS_MULTICAST) {
19429aebddd1SJeff Kirsher 		struct netdev_hw_addr *ha;
19439aebddd1SJeff Kirsher 		int i = 0;
19449aebddd1SJeff Kirsher 
19451610c79fSPadmanabh Ratnakar 		/* Reset mcast promisc mode if already set by setting mask
19461610c79fSPadmanabh Ratnakar 		 * and not setting flags field
19471610c79fSPadmanabh Ratnakar 		 */
19481610c79fSPadmanabh Ratnakar 		req->if_flags_mask |=
1949abb93951SPadmanabh Ratnakar 			cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS &
195092bf14abSSathya Perla 				    be_if_cap_flags(adapter));
1951016f97b1SPadmanabh Ratnakar 		req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev));
19529aebddd1SJeff Kirsher 		netdev_for_each_mc_addr(ha, adapter->netdev)
19539aebddd1SJeff Kirsher 			memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
19549aebddd1SJeff Kirsher 	}
19559aebddd1SJeff Kirsher 
19569aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
19579aebddd1SJeff Kirsher err:
19589aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
19599aebddd1SJeff Kirsher 	return status;
19609aebddd1SJeff Kirsher }
19619aebddd1SJeff Kirsher 
1962ac34b743SSathya Perla int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
1963ac34b743SSathya Perla {
1964ac34b743SSathya Perla 	struct device *dev = &adapter->pdev->dev;
1965ac34b743SSathya Perla 
1966ac34b743SSathya Perla 	if ((flags & be_if_cap_flags(adapter)) != flags) {
1967ac34b743SSathya Perla 		dev_warn(dev, "Cannot set rx filter flags 0x%x\n", flags);
1968ac34b743SSathya Perla 		dev_warn(dev, "Interface is capable of 0x%x flags only\n",
1969ac34b743SSathya Perla 			 be_if_cap_flags(adapter));
1970ac34b743SSathya Perla 	}
1971ac34b743SSathya Perla 	flags &= be_if_cap_flags(adapter);
1972ac34b743SSathya Perla 
1973ac34b743SSathya Perla 	return __be_cmd_rx_filter(adapter, flags, value);
1974ac34b743SSathya Perla }
1975ac34b743SSathya Perla 
19769aebddd1SJeff Kirsher /* Uses synchrounous mcc */
19779aebddd1SJeff Kirsher int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
19789aebddd1SJeff Kirsher {
19799aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
19809aebddd1SJeff Kirsher 	struct be_cmd_req_set_flow_control *req;
19819aebddd1SJeff Kirsher 	int status;
19829aebddd1SJeff Kirsher 
1983f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
1984f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
1985f25b119cSPadmanabh Ratnakar 		return -EPERM;
1986f25b119cSPadmanabh Ratnakar 
19879aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
19889aebddd1SJeff Kirsher 
19899aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
19909aebddd1SJeff Kirsher 	if (!wrb) {
19919aebddd1SJeff Kirsher 		status = -EBUSY;
19929aebddd1SJeff Kirsher 		goto err;
19939aebddd1SJeff Kirsher 	}
19949aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
19959aebddd1SJeff Kirsher 
1996106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1997a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req),
1998a2cc4e0bSSathya Perla 			       wrb, NULL);
19999aebddd1SJeff Kirsher 
2000b29812c1SSuresh Reddy 	req->hdr.version = 1;
20019aebddd1SJeff Kirsher 	req->tx_flow_control = cpu_to_le16((u16)tx_fc);
20029aebddd1SJeff Kirsher 	req->rx_flow_control = cpu_to_le16((u16)rx_fc);
20039aebddd1SJeff Kirsher 
20049aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
20059aebddd1SJeff Kirsher 
20069aebddd1SJeff Kirsher err:
20079aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
2008b29812c1SSuresh Reddy 
2009b29812c1SSuresh Reddy 	if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED)
2010b29812c1SSuresh Reddy 		return  -EOPNOTSUPP;
2011b29812c1SSuresh Reddy 
20129aebddd1SJeff Kirsher 	return status;
20139aebddd1SJeff Kirsher }
20149aebddd1SJeff Kirsher 
20159aebddd1SJeff Kirsher /* Uses sycn mcc */
20169aebddd1SJeff Kirsher int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
20179aebddd1SJeff Kirsher {
20189aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20199aebddd1SJeff Kirsher 	struct be_cmd_req_get_flow_control *req;
20209aebddd1SJeff Kirsher 	int status;
20219aebddd1SJeff Kirsher 
2022f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
2023f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
2024f25b119cSPadmanabh Ratnakar 		return -EPERM;
2025f25b119cSPadmanabh Ratnakar 
20269aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
20279aebddd1SJeff Kirsher 
20289aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
20299aebddd1SJeff Kirsher 	if (!wrb) {
20309aebddd1SJeff Kirsher 		status = -EBUSY;
20319aebddd1SJeff Kirsher 		goto err;
20329aebddd1SJeff Kirsher 	}
20339aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
20349aebddd1SJeff Kirsher 
2035106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2036a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req),
2037a2cc4e0bSSathya Perla 			       wrb, NULL);
20389aebddd1SJeff Kirsher 
20399aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
20409aebddd1SJeff Kirsher 	if (!status) {
20419aebddd1SJeff Kirsher 		struct be_cmd_resp_get_flow_control *resp =
20429aebddd1SJeff Kirsher 						embedded_payload(wrb);
204303d28ffeSKalesh AP 
20449aebddd1SJeff Kirsher 		*tx_fc = le16_to_cpu(resp->tx_flow_control);
20459aebddd1SJeff Kirsher 		*rx_fc = le16_to_cpu(resp->rx_flow_control);
20469aebddd1SJeff Kirsher 	}
20479aebddd1SJeff Kirsher 
20489aebddd1SJeff Kirsher err:
20499aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
20509aebddd1SJeff Kirsher 	return status;
20519aebddd1SJeff Kirsher }
20529aebddd1SJeff Kirsher 
20539aebddd1SJeff Kirsher /* Uses mbox */
2054e97e3cdaSKalesh AP int be_cmd_query_fw_cfg(struct be_adapter *adapter)
20559aebddd1SJeff Kirsher {
20569aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20579aebddd1SJeff Kirsher 	struct be_cmd_req_query_fw_cfg *req;
20589aebddd1SJeff Kirsher 	int status;
20599aebddd1SJeff Kirsher 
20609aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
20619aebddd1SJeff Kirsher 		return -1;
20629aebddd1SJeff Kirsher 
20639aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
20649aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
20659aebddd1SJeff Kirsher 
2066106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2067a2cc4e0bSSathya Perla 			       OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
2068a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
20699aebddd1SJeff Kirsher 
20709aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
20719aebddd1SJeff Kirsher 	if (!status) {
20729aebddd1SJeff Kirsher 		struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
207303d28ffeSKalesh AP 
2074e97e3cdaSKalesh AP 		adapter->port_num = le32_to_cpu(resp->phys_port);
2075e97e3cdaSKalesh AP 		adapter->function_mode = le32_to_cpu(resp->function_mode);
2076e97e3cdaSKalesh AP 		adapter->function_caps = le32_to_cpu(resp->function_caps);
2077e97e3cdaSKalesh AP 		adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
2078acbafeb1SSathya Perla 		dev_info(&adapter->pdev->dev,
2079acbafeb1SSathya Perla 			 "FW config: function_mode=0x%x, function_caps=0x%x\n",
2080acbafeb1SSathya Perla 			 adapter->function_mode, adapter->function_caps);
20819aebddd1SJeff Kirsher 	}
20829aebddd1SJeff Kirsher 
20839aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
20849aebddd1SJeff Kirsher 	return status;
20859aebddd1SJeff Kirsher }
20869aebddd1SJeff Kirsher 
20879aebddd1SJeff Kirsher /* Uses mbox */
20889aebddd1SJeff Kirsher int be_cmd_reset_function(struct be_adapter *adapter)
20899aebddd1SJeff Kirsher {
20909aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20919aebddd1SJeff Kirsher 	struct be_cmd_req_hdr *req;
20929aebddd1SJeff Kirsher 	int status;
20939aebddd1SJeff Kirsher 
2094bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter)) {
2095bf99e50dSPadmanabh Ratnakar 		iowrite32(SLI_PORT_CONTROL_IP_MASK,
2096bf99e50dSPadmanabh Ratnakar 			  adapter->db + SLIPORT_CONTROL_OFFSET);
20979fa465c0SSathya Perla 		status = lancer_wait_ready(adapter);
20989fa465c0SSathya Perla 		if (status)
2099bf99e50dSPadmanabh Ratnakar 			dev_err(&adapter->pdev->dev,
2100bf99e50dSPadmanabh Ratnakar 				"Adapter in non recoverable error\n");
2101bf99e50dSPadmanabh Ratnakar 		return status;
2102bf99e50dSPadmanabh Ratnakar 	}
2103bf99e50dSPadmanabh Ratnakar 
21049aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
21059aebddd1SJeff Kirsher 		return -1;
21069aebddd1SJeff Kirsher 
21079aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
21089aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21099aebddd1SJeff Kirsher 
2110106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
2111a2cc4e0bSSathya Perla 			       OPCODE_COMMON_FUNCTION_RESET, sizeof(*req), wrb,
2112a2cc4e0bSSathya Perla 			       NULL);
21139aebddd1SJeff Kirsher 
21149aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
21159aebddd1SJeff Kirsher 
21169aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
21179aebddd1SJeff Kirsher 	return status;
21189aebddd1SJeff Kirsher }
21199aebddd1SJeff Kirsher 
2120594ad54aSSuresh Reddy int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
212133cb0fa7SBen Hutchings 		      u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey)
21229aebddd1SJeff Kirsher {
21239aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21249aebddd1SJeff Kirsher 	struct be_cmd_req_rss_config *req;
21259aebddd1SJeff Kirsher 	int status;
21269aebddd1SJeff Kirsher 
2127da1388d6SVasundhara Volam 	if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
2128da1388d6SVasundhara Volam 		return 0;
2129da1388d6SVasundhara Volam 
2130b51aa367SKalesh AP 	spin_lock_bh(&adapter->mcc_lock);
21319aebddd1SJeff Kirsher 
2132b51aa367SKalesh AP 	wrb = wrb_from_mccq(adapter);
2133b51aa367SKalesh AP 	if (!wrb) {
2134b51aa367SKalesh AP 		status = -EBUSY;
2135b51aa367SKalesh AP 		goto err;
2136b51aa367SKalesh AP 	}
21379aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21389aebddd1SJeff Kirsher 
2139106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
2140106df1e3SSomnath Kotur 			       OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
21419aebddd1SJeff Kirsher 
21429aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(adapter->if_handle);
2143594ad54aSSuresh Reddy 	req->enable_rss = cpu_to_le16(rss_hash_opts);
21449aebddd1SJeff Kirsher 	req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
2145594ad54aSSuresh Reddy 
2146b51aa367SKalesh AP 	if (!BEx_chip(adapter))
2147594ad54aSSuresh Reddy 		req->hdr.version = 1;
2148594ad54aSSuresh Reddy 
21499aebddd1SJeff Kirsher 	memcpy(req->cpu_table, rsstable, table_size);
2150e2557877SVenkata Duvvuru 	memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
21519aebddd1SJeff Kirsher 	be_dws_cpu_to_le(req->hash, sizeof(req->hash));
21529aebddd1SJeff Kirsher 
2153b51aa367SKalesh AP 	status = be_mcc_notify_wait(adapter);
2154b51aa367SKalesh AP err:
2155b51aa367SKalesh AP 	spin_unlock_bh(&adapter->mcc_lock);
21569aebddd1SJeff Kirsher 	return status;
21579aebddd1SJeff Kirsher }
21589aebddd1SJeff Kirsher 
21599aebddd1SJeff Kirsher /* Uses sync mcc */
21609aebddd1SJeff Kirsher int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
21619aebddd1SJeff Kirsher 			    u8 bcn, u8 sts, u8 state)
21629aebddd1SJeff Kirsher {
21639aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21649aebddd1SJeff Kirsher 	struct be_cmd_req_enable_disable_beacon *req;
21659aebddd1SJeff Kirsher 	int status;
21669aebddd1SJeff Kirsher 
21679aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
21689aebddd1SJeff Kirsher 
21699aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
21709aebddd1SJeff Kirsher 	if (!wrb) {
21719aebddd1SJeff Kirsher 		status = -EBUSY;
21729aebddd1SJeff Kirsher 		goto err;
21739aebddd1SJeff Kirsher 	}
21749aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21759aebddd1SJeff Kirsher 
2176106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2177a2cc4e0bSSathya Perla 			       OPCODE_COMMON_ENABLE_DISABLE_BEACON,
2178a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
21799aebddd1SJeff Kirsher 
21809aebddd1SJeff Kirsher 	req->port_num = port_num;
21819aebddd1SJeff Kirsher 	req->beacon_state = state;
21829aebddd1SJeff Kirsher 	req->beacon_duration = bcn;
21839aebddd1SJeff Kirsher 	req->status_duration = sts;
21849aebddd1SJeff Kirsher 
21859aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
21869aebddd1SJeff Kirsher 
21879aebddd1SJeff Kirsher err:
21889aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
21899aebddd1SJeff Kirsher 	return status;
21909aebddd1SJeff Kirsher }
21919aebddd1SJeff Kirsher 
21929aebddd1SJeff Kirsher /* Uses sync mcc */
21939aebddd1SJeff Kirsher int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
21949aebddd1SJeff Kirsher {
21959aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21969aebddd1SJeff Kirsher 	struct be_cmd_req_get_beacon_state *req;
21979aebddd1SJeff Kirsher 	int status;
21989aebddd1SJeff Kirsher 
21999aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
22009aebddd1SJeff Kirsher 
22019aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
22029aebddd1SJeff Kirsher 	if (!wrb) {
22039aebddd1SJeff Kirsher 		status = -EBUSY;
22049aebddd1SJeff Kirsher 		goto err;
22059aebddd1SJeff Kirsher 	}
22069aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
22079aebddd1SJeff Kirsher 
2208106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2209a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req),
2210a2cc4e0bSSathya Perla 			       wrb, NULL);
22119aebddd1SJeff Kirsher 
22129aebddd1SJeff Kirsher 	req->port_num = port_num;
22139aebddd1SJeff Kirsher 
22149aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
22159aebddd1SJeff Kirsher 	if (!status) {
22169aebddd1SJeff Kirsher 		struct be_cmd_resp_get_beacon_state *resp =
22179aebddd1SJeff Kirsher 						embedded_payload(wrb);
221803d28ffeSKalesh AP 
22199aebddd1SJeff Kirsher 		*state = resp->beacon_state;
22209aebddd1SJeff Kirsher 	}
22219aebddd1SJeff Kirsher 
22229aebddd1SJeff Kirsher err:
22239aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
22249aebddd1SJeff Kirsher 	return status;
22259aebddd1SJeff Kirsher }
22269aebddd1SJeff Kirsher 
2227e36edd9dSMark Leonard /* Uses sync mcc */
2228e36edd9dSMark Leonard int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2229e36edd9dSMark Leonard 				      u8 page_num, u8 *data)
2230e36edd9dSMark Leonard {
2231e36edd9dSMark Leonard 	struct be_dma_mem cmd;
2232e36edd9dSMark Leonard 	struct be_mcc_wrb *wrb;
2233e36edd9dSMark Leonard 	struct be_cmd_req_port_type *req;
2234e36edd9dSMark Leonard 	int status;
2235e36edd9dSMark Leonard 
2236e36edd9dSMark Leonard 	if (page_num > TR_PAGE_A2)
2237e36edd9dSMark Leonard 		return -EINVAL;
2238e36edd9dSMark Leonard 
2239e36edd9dSMark Leonard 	cmd.size = sizeof(struct be_cmd_resp_port_type);
2240e36edd9dSMark Leonard 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
2241e36edd9dSMark Leonard 	if (!cmd.va) {
2242e36edd9dSMark Leonard 		dev_err(&adapter->pdev->dev, "Memory allocation failed\n");
2243e36edd9dSMark Leonard 		return -ENOMEM;
2244e36edd9dSMark Leonard 	}
2245e36edd9dSMark Leonard 	memset(cmd.va, 0, cmd.size);
2246e36edd9dSMark Leonard 
2247e36edd9dSMark Leonard 	spin_lock_bh(&adapter->mcc_lock);
2248e36edd9dSMark Leonard 
2249e36edd9dSMark Leonard 	wrb = wrb_from_mccq(adapter);
2250e36edd9dSMark Leonard 	if (!wrb) {
2251e36edd9dSMark Leonard 		status = -EBUSY;
2252e36edd9dSMark Leonard 		goto err;
2253e36edd9dSMark Leonard 	}
2254e36edd9dSMark Leonard 	req = cmd.va;
2255e36edd9dSMark Leonard 
2256e36edd9dSMark Leonard 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2257e36edd9dSMark Leonard 			       OPCODE_COMMON_READ_TRANSRECV_DATA,
2258e36edd9dSMark Leonard 			       cmd.size, wrb, &cmd);
2259e36edd9dSMark Leonard 
2260e36edd9dSMark Leonard 	req->port = cpu_to_le32(adapter->hba_port_num);
2261e36edd9dSMark Leonard 	req->page_num = cpu_to_le32(page_num);
2262e36edd9dSMark Leonard 	status = be_mcc_notify_wait(adapter);
2263e36edd9dSMark Leonard 	if (!status) {
2264e36edd9dSMark Leonard 		struct be_cmd_resp_port_type *resp = cmd.va;
2265e36edd9dSMark Leonard 
2266e36edd9dSMark Leonard 		memcpy(data, resp->page_data, PAGE_DATA_LEN);
2267e36edd9dSMark Leonard 	}
2268e36edd9dSMark Leonard err:
2269e36edd9dSMark Leonard 	spin_unlock_bh(&adapter->mcc_lock);
2270e36edd9dSMark Leonard 	pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
2271e36edd9dSMark Leonard 	return status;
2272e36edd9dSMark Leonard }
2273e36edd9dSMark Leonard 
22749aebddd1SJeff Kirsher int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2275f67ef7baSPadmanabh Ratnakar 			    u32 data_size, u32 data_offset,
2276f67ef7baSPadmanabh Ratnakar 			    const char *obj_name, u32 *data_written,
2277f67ef7baSPadmanabh Ratnakar 			    u8 *change_status, u8 *addn_status)
22789aebddd1SJeff Kirsher {
22799aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
22809aebddd1SJeff Kirsher 	struct lancer_cmd_req_write_object *req;
22819aebddd1SJeff Kirsher 	struct lancer_cmd_resp_write_object *resp;
22829aebddd1SJeff Kirsher 	void *ctxt = NULL;
22839aebddd1SJeff Kirsher 	int status;
22849aebddd1SJeff Kirsher 
22859aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
22869aebddd1SJeff Kirsher 	adapter->flash_status = 0;
22879aebddd1SJeff Kirsher 
22889aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
22899aebddd1SJeff Kirsher 	if (!wrb) {
22909aebddd1SJeff Kirsher 		status = -EBUSY;
22919aebddd1SJeff Kirsher 		goto err_unlock;
22929aebddd1SJeff Kirsher 	}
22939aebddd1SJeff Kirsher 
22949aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
22959aebddd1SJeff Kirsher 
2296106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
22979aebddd1SJeff Kirsher 			       OPCODE_COMMON_WRITE_OBJECT,
2298106df1e3SSomnath Kotur 			       sizeof(struct lancer_cmd_req_write_object), wrb,
2299106df1e3SSomnath Kotur 			       NULL);
23009aebddd1SJeff Kirsher 
23019aebddd1SJeff Kirsher 	ctxt = &req->context;
23029aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23039aebddd1SJeff Kirsher 		      write_length, ctxt, data_size);
23049aebddd1SJeff Kirsher 
23059aebddd1SJeff Kirsher 	if (data_size == 0)
23069aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23079aebddd1SJeff Kirsher 			      eof, ctxt, 1);
23089aebddd1SJeff Kirsher 	else
23099aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23109aebddd1SJeff Kirsher 			      eof, ctxt, 0);
23119aebddd1SJeff Kirsher 
23129aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
23139aebddd1SJeff Kirsher 	req->write_offset = cpu_to_le32(data_offset);
2314242eb470SVasundhara Volam 	strlcpy(req->object_name, obj_name, sizeof(req->object_name));
23159aebddd1SJeff Kirsher 	req->descriptor_count = cpu_to_le32(1);
23169aebddd1SJeff Kirsher 	req->buf_len = cpu_to_le32(data_size);
23179aebddd1SJeff Kirsher 	req->addr_low = cpu_to_le32((cmd->dma +
23189aebddd1SJeff Kirsher 				     sizeof(struct lancer_cmd_req_write_object))
23199aebddd1SJeff Kirsher 				    & 0xFFFFFFFF);
23209aebddd1SJeff Kirsher 	req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
23219aebddd1SJeff Kirsher 				sizeof(struct lancer_cmd_req_write_object)));
23229aebddd1SJeff Kirsher 
23239aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
23249aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
23259aebddd1SJeff Kirsher 
23265eeff635SSuresh Reddy 	if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2327701962d0SSomnath Kotur 					 msecs_to_jiffies(60000)))
2328fd45160cSKalesh AP 		status = -ETIMEDOUT;
23299aebddd1SJeff Kirsher 	else
23309aebddd1SJeff Kirsher 		status = adapter->flash_status;
23319aebddd1SJeff Kirsher 
23329aebddd1SJeff Kirsher 	resp = embedded_payload(wrb);
2333f67ef7baSPadmanabh Ratnakar 	if (!status) {
23349aebddd1SJeff Kirsher 		*data_written = le32_to_cpu(resp->actual_write_len);
2335f67ef7baSPadmanabh Ratnakar 		*change_status = resp->change_status;
2336f67ef7baSPadmanabh Ratnakar 	} else {
23379aebddd1SJeff Kirsher 		*addn_status = resp->additional_status;
2338f67ef7baSPadmanabh Ratnakar 	}
23399aebddd1SJeff Kirsher 
23409aebddd1SJeff Kirsher 	return status;
23419aebddd1SJeff Kirsher 
23429aebddd1SJeff Kirsher err_unlock:
23439aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
23449aebddd1SJeff Kirsher 	return status;
23459aebddd1SJeff Kirsher }
23469aebddd1SJeff Kirsher 
23476809cee0SRavikumar Nelavelli int be_cmd_query_cable_type(struct be_adapter *adapter)
23486809cee0SRavikumar Nelavelli {
23496809cee0SRavikumar Nelavelli 	u8 page_data[PAGE_DATA_LEN];
23506809cee0SRavikumar Nelavelli 	int status;
23516809cee0SRavikumar Nelavelli 
23526809cee0SRavikumar Nelavelli 	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
23536809cee0SRavikumar Nelavelli 						   page_data);
23546809cee0SRavikumar Nelavelli 	if (!status) {
23556809cee0SRavikumar Nelavelli 		switch (adapter->phy.interface_type) {
23566809cee0SRavikumar Nelavelli 		case PHY_TYPE_QSFP:
23576809cee0SRavikumar Nelavelli 			adapter->phy.cable_type =
23586809cee0SRavikumar Nelavelli 				page_data[QSFP_PLUS_CABLE_TYPE_OFFSET];
23596809cee0SRavikumar Nelavelli 			break;
23606809cee0SRavikumar Nelavelli 		case PHY_TYPE_SFP_PLUS_10GB:
23616809cee0SRavikumar Nelavelli 			adapter->phy.cable_type =
23626809cee0SRavikumar Nelavelli 				page_data[SFP_PLUS_CABLE_TYPE_OFFSET];
23636809cee0SRavikumar Nelavelli 			break;
23646809cee0SRavikumar Nelavelli 		default:
23656809cee0SRavikumar Nelavelli 			adapter->phy.cable_type = 0;
23666809cee0SRavikumar Nelavelli 			break;
23676809cee0SRavikumar Nelavelli 		}
23686809cee0SRavikumar Nelavelli 	}
23696809cee0SRavikumar Nelavelli 	return status;
23706809cee0SRavikumar Nelavelli }
23716809cee0SRavikumar Nelavelli 
237221252377SVasundhara Volam int be_cmd_query_sfp_info(struct be_adapter *adapter)
237321252377SVasundhara Volam {
237421252377SVasundhara Volam 	u8 page_data[PAGE_DATA_LEN];
237521252377SVasundhara Volam 	int status;
237621252377SVasundhara Volam 
237721252377SVasundhara Volam 	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
237821252377SVasundhara Volam 						   page_data);
237921252377SVasundhara Volam 	if (!status) {
238021252377SVasundhara Volam 		strlcpy(adapter->phy.vendor_name, page_data +
238121252377SVasundhara Volam 			SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
238221252377SVasundhara Volam 		strlcpy(adapter->phy.vendor_pn,
238321252377SVasundhara Volam 			page_data + SFP_VENDOR_PN_OFFSET,
238421252377SVasundhara Volam 			SFP_VENDOR_NAME_LEN - 1);
238521252377SVasundhara Volam 	}
238621252377SVasundhara Volam 
238721252377SVasundhara Volam 	return status;
238821252377SVasundhara Volam }
238921252377SVasundhara Volam 
2390f0613380SKalesh AP int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
2391f0613380SKalesh AP {
2392f0613380SKalesh AP 	struct lancer_cmd_req_delete_object *req;
2393f0613380SKalesh AP 	struct be_mcc_wrb *wrb;
2394f0613380SKalesh AP 	int status;
2395f0613380SKalesh AP 
2396f0613380SKalesh AP 	spin_lock_bh(&adapter->mcc_lock);
2397f0613380SKalesh AP 
2398f0613380SKalesh AP 	wrb = wrb_from_mccq(adapter);
2399f0613380SKalesh AP 	if (!wrb) {
2400f0613380SKalesh AP 		status = -EBUSY;
2401f0613380SKalesh AP 		goto err;
2402f0613380SKalesh AP 	}
2403f0613380SKalesh AP 
2404f0613380SKalesh AP 	req = embedded_payload(wrb);
2405f0613380SKalesh AP 
2406f0613380SKalesh AP 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2407f0613380SKalesh AP 			       OPCODE_COMMON_DELETE_OBJECT,
2408f0613380SKalesh AP 			       sizeof(*req), wrb, NULL);
2409f0613380SKalesh AP 
2410242eb470SVasundhara Volam 	strlcpy(req->object_name, obj_name, sizeof(req->object_name));
2411f0613380SKalesh AP 
2412f0613380SKalesh AP 	status = be_mcc_notify_wait(adapter);
2413f0613380SKalesh AP err:
2414f0613380SKalesh AP 	spin_unlock_bh(&adapter->mcc_lock);
2415f0613380SKalesh AP 	return status;
2416f0613380SKalesh AP }
2417f0613380SKalesh AP 
2418de49bd5aSPadmanabh Ratnakar int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2419de49bd5aSPadmanabh Ratnakar 			   u32 data_size, u32 data_offset, const char *obj_name,
2420de49bd5aSPadmanabh Ratnakar 			   u32 *data_read, u32 *eof, u8 *addn_status)
2421de49bd5aSPadmanabh Ratnakar {
2422de49bd5aSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
2423de49bd5aSPadmanabh Ratnakar 	struct lancer_cmd_req_read_object *req;
2424de49bd5aSPadmanabh Ratnakar 	struct lancer_cmd_resp_read_object *resp;
2425de49bd5aSPadmanabh Ratnakar 	int status;
2426de49bd5aSPadmanabh Ratnakar 
2427de49bd5aSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
2428de49bd5aSPadmanabh Ratnakar 
2429de49bd5aSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
2430de49bd5aSPadmanabh Ratnakar 	if (!wrb) {
2431de49bd5aSPadmanabh Ratnakar 		status = -EBUSY;
2432de49bd5aSPadmanabh Ratnakar 		goto err_unlock;
2433de49bd5aSPadmanabh Ratnakar 	}
2434de49bd5aSPadmanabh Ratnakar 
2435de49bd5aSPadmanabh Ratnakar 	req = embedded_payload(wrb);
2436de49bd5aSPadmanabh Ratnakar 
2437de49bd5aSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2438de49bd5aSPadmanabh Ratnakar 			       OPCODE_COMMON_READ_OBJECT,
2439de49bd5aSPadmanabh Ratnakar 			       sizeof(struct lancer_cmd_req_read_object), wrb,
2440de49bd5aSPadmanabh Ratnakar 			       NULL);
2441de49bd5aSPadmanabh Ratnakar 
2442de49bd5aSPadmanabh Ratnakar 	req->desired_read_len = cpu_to_le32(data_size);
2443de49bd5aSPadmanabh Ratnakar 	req->read_offset = cpu_to_le32(data_offset);
2444de49bd5aSPadmanabh Ratnakar 	strcpy(req->object_name, obj_name);
2445de49bd5aSPadmanabh Ratnakar 	req->descriptor_count = cpu_to_le32(1);
2446de49bd5aSPadmanabh Ratnakar 	req->buf_len = cpu_to_le32(data_size);
2447de49bd5aSPadmanabh Ratnakar 	req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
2448de49bd5aSPadmanabh Ratnakar 	req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));
2449de49bd5aSPadmanabh Ratnakar 
2450de49bd5aSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
2451de49bd5aSPadmanabh Ratnakar 
2452de49bd5aSPadmanabh Ratnakar 	resp = embedded_payload(wrb);
2453de49bd5aSPadmanabh Ratnakar 	if (!status) {
2454de49bd5aSPadmanabh Ratnakar 		*data_read = le32_to_cpu(resp->actual_read_len);
2455de49bd5aSPadmanabh Ratnakar 		*eof = le32_to_cpu(resp->eof);
2456de49bd5aSPadmanabh Ratnakar 	} else {
2457de49bd5aSPadmanabh Ratnakar 		*addn_status = resp->additional_status;
2458de49bd5aSPadmanabh Ratnakar 	}
2459de49bd5aSPadmanabh Ratnakar 
2460de49bd5aSPadmanabh Ratnakar err_unlock:
2461de49bd5aSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
2462de49bd5aSPadmanabh Ratnakar 	return status;
2463de49bd5aSPadmanabh Ratnakar }
2464de49bd5aSPadmanabh Ratnakar 
24659aebddd1SJeff Kirsher int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
246670a7b525SVasundhara Volam 			  u32 flash_type, u32 flash_opcode, u32 img_offset,
246770a7b525SVasundhara Volam 			  u32 buf_size)
24689aebddd1SJeff Kirsher {
24699aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
24709aebddd1SJeff Kirsher 	struct be_cmd_write_flashrom *req;
24719aebddd1SJeff Kirsher 	int status;
24729aebddd1SJeff Kirsher 
24739aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
24749aebddd1SJeff Kirsher 	adapter->flash_status = 0;
24759aebddd1SJeff Kirsher 
24769aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
24779aebddd1SJeff Kirsher 	if (!wrb) {
24789aebddd1SJeff Kirsher 		status = -EBUSY;
24799aebddd1SJeff Kirsher 		goto err_unlock;
24809aebddd1SJeff Kirsher 	}
24819aebddd1SJeff Kirsher 	req = cmd->va;
24829aebddd1SJeff Kirsher 
2483106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2484a2cc4e0bSSathya Perla 			       OPCODE_COMMON_WRITE_FLASHROM, cmd->size, wrb,
2485a2cc4e0bSSathya Perla 			       cmd);
24869aebddd1SJeff Kirsher 
24879aebddd1SJeff Kirsher 	req->params.op_type = cpu_to_le32(flash_type);
248870a7b525SVasundhara Volam 	if (flash_type == OPTYPE_OFFSET_SPECIFIED)
248970a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(img_offset);
249070a7b525SVasundhara Volam 
24919aebddd1SJeff Kirsher 	req->params.op_code = cpu_to_le32(flash_opcode);
24929aebddd1SJeff Kirsher 	req->params.data_buf_size = cpu_to_le32(buf_size);
24939aebddd1SJeff Kirsher 
24949aebddd1SJeff Kirsher 	be_mcc_notify(adapter);
24959aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
24969aebddd1SJeff Kirsher 
24975eeff635SSuresh Reddy 	if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2498e2edb7d5SSathya Perla 					 msecs_to_jiffies(40000)))
2499fd45160cSKalesh AP 		status = -ETIMEDOUT;
25009aebddd1SJeff Kirsher 	else
25019aebddd1SJeff Kirsher 		status = adapter->flash_status;
25029aebddd1SJeff Kirsher 
25039aebddd1SJeff Kirsher 	return status;
25049aebddd1SJeff Kirsher 
25059aebddd1SJeff Kirsher err_unlock:
25069aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25079aebddd1SJeff Kirsher 	return status;
25089aebddd1SJeff Kirsher }
25099aebddd1SJeff Kirsher 
25109aebddd1SJeff Kirsher int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
251170a7b525SVasundhara Volam 			 u16 img_optype, u32 img_offset, u32 crc_offset)
25129aebddd1SJeff Kirsher {
2513be716446SPadmanabh Ratnakar 	struct be_cmd_read_flash_crc *req;
251470a7b525SVasundhara Volam 	struct be_mcc_wrb *wrb;
25159aebddd1SJeff Kirsher 	int status;
25169aebddd1SJeff Kirsher 
25179aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
25189aebddd1SJeff Kirsher 
25199aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25209aebddd1SJeff Kirsher 	if (!wrb) {
25219aebddd1SJeff Kirsher 		status = -EBUSY;
25229aebddd1SJeff Kirsher 		goto err;
25239aebddd1SJeff Kirsher 	}
25249aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
25259aebddd1SJeff Kirsher 
2526106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2527be716446SPadmanabh Ratnakar 			       OPCODE_COMMON_READ_FLASHROM, sizeof(*req),
2528be716446SPadmanabh Ratnakar 			       wrb, NULL);
25299aebddd1SJeff Kirsher 
253070a7b525SVasundhara Volam 	req->params.op_type = cpu_to_le32(img_optype);
253170a7b525SVasundhara Volam 	if (img_optype == OPTYPE_OFFSET_SPECIFIED)
253270a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(img_offset + crc_offset);
253370a7b525SVasundhara Volam 	else
253470a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(crc_offset);
253570a7b525SVasundhara Volam 
25369aebddd1SJeff Kirsher 	req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
25379aebddd1SJeff Kirsher 	req->params.data_buf_size = cpu_to_le32(0x4);
25389aebddd1SJeff Kirsher 
25399aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
25409aebddd1SJeff Kirsher 	if (!status)
2541be716446SPadmanabh Ratnakar 		memcpy(flashed_crc, req->crc, 4);
25429aebddd1SJeff Kirsher 
25439aebddd1SJeff Kirsher err:
25449aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25459aebddd1SJeff Kirsher 	return status;
25469aebddd1SJeff Kirsher }
25479aebddd1SJeff Kirsher 
25489aebddd1SJeff Kirsher int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
25499aebddd1SJeff Kirsher 			    struct be_dma_mem *nonemb_cmd)
25509aebddd1SJeff Kirsher {
25519aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
25529aebddd1SJeff Kirsher 	struct be_cmd_req_acpi_wol_magic_config *req;
25539aebddd1SJeff Kirsher 	int status;
25549aebddd1SJeff Kirsher 
25559aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
25569aebddd1SJeff Kirsher 
25579aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25589aebddd1SJeff Kirsher 	if (!wrb) {
25599aebddd1SJeff Kirsher 		status = -EBUSY;
25609aebddd1SJeff Kirsher 		goto err;
25619aebddd1SJeff Kirsher 	}
25629aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
25639aebddd1SJeff Kirsher 
2564106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
2565a2cc4e0bSSathya Perla 			       OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req),
2566a2cc4e0bSSathya Perla 			       wrb, nonemb_cmd);
25679aebddd1SJeff Kirsher 	memcpy(req->magic_mac, mac, ETH_ALEN);
25689aebddd1SJeff Kirsher 
25699aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
25709aebddd1SJeff Kirsher 
25719aebddd1SJeff Kirsher err:
25729aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25739aebddd1SJeff Kirsher 	return status;
25749aebddd1SJeff Kirsher }
25759aebddd1SJeff Kirsher 
25769aebddd1SJeff Kirsher int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
25779aebddd1SJeff Kirsher 			u8 loopback_type, u8 enable)
25789aebddd1SJeff Kirsher {
25799aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
25809aebddd1SJeff Kirsher 	struct be_cmd_req_set_lmode *req;
25819aebddd1SJeff Kirsher 	int status;
25829aebddd1SJeff Kirsher 
25839aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
25849aebddd1SJeff Kirsher 
25859aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25869aebddd1SJeff Kirsher 	if (!wrb) {
25879aebddd1SJeff Kirsher 		status = -EBUSY;
25889aebddd1SJeff Kirsher 		goto err;
25899aebddd1SJeff Kirsher 	}
25909aebddd1SJeff Kirsher 
25919aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
25929aebddd1SJeff Kirsher 
2593106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2594a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, sizeof(*req),
2595a2cc4e0bSSathya Perla 			       wrb, NULL);
25969aebddd1SJeff Kirsher 
25979aebddd1SJeff Kirsher 	req->src_port = port_num;
25989aebddd1SJeff Kirsher 	req->dest_port = port_num;
25999aebddd1SJeff Kirsher 	req->loopback_type = loopback_type;
26009aebddd1SJeff Kirsher 	req->loopback_state = enable;
26019aebddd1SJeff Kirsher 
26029aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
26039aebddd1SJeff Kirsher err:
26049aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
26059aebddd1SJeff Kirsher 	return status;
26069aebddd1SJeff Kirsher }
26079aebddd1SJeff Kirsher 
26089aebddd1SJeff Kirsher int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
2609a2cc4e0bSSathya Perla 			 u32 loopback_type, u32 pkt_size, u32 num_pkts,
2610a2cc4e0bSSathya Perla 			 u64 pattern)
26119aebddd1SJeff Kirsher {
26129aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
26139aebddd1SJeff Kirsher 	struct be_cmd_req_loopback_test *req;
26145eeff635SSuresh Reddy 	struct be_cmd_resp_loopback_test *resp;
26159aebddd1SJeff Kirsher 	int status;
26169aebddd1SJeff Kirsher 
26179aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
26189aebddd1SJeff Kirsher 
26199aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
26209aebddd1SJeff Kirsher 	if (!wrb) {
26219aebddd1SJeff Kirsher 		status = -EBUSY;
26229aebddd1SJeff Kirsher 		goto err;
26239aebddd1SJeff Kirsher 	}
26249aebddd1SJeff Kirsher 
26259aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
26269aebddd1SJeff Kirsher 
2627106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2628a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req), wrb,
2629a2cc4e0bSSathya Perla 			       NULL);
26309aebddd1SJeff Kirsher 
26315eeff635SSuresh Reddy 	req->hdr.timeout = cpu_to_le32(15);
26329aebddd1SJeff Kirsher 	req->pattern = cpu_to_le64(pattern);
26339aebddd1SJeff Kirsher 	req->src_port = cpu_to_le32(port_num);
26349aebddd1SJeff Kirsher 	req->dest_port = cpu_to_le32(port_num);
26359aebddd1SJeff Kirsher 	req->pkt_size = cpu_to_le32(pkt_size);
26369aebddd1SJeff Kirsher 	req->num_pkts = cpu_to_le32(num_pkts);
26379aebddd1SJeff Kirsher 	req->loopback_type = cpu_to_le32(loopback_type);
26389aebddd1SJeff Kirsher 
26395eeff635SSuresh Reddy 	be_mcc_notify(adapter);
26409aebddd1SJeff Kirsher 
26415eeff635SSuresh Reddy 	spin_unlock_bh(&adapter->mcc_lock);
26425eeff635SSuresh Reddy 
26435eeff635SSuresh Reddy 	wait_for_completion(&adapter->et_cmd_compl);
26445eeff635SSuresh Reddy 	resp = embedded_payload(wrb);
26455eeff635SSuresh Reddy 	status = le32_to_cpu(resp->status);
26465eeff635SSuresh Reddy 
26475eeff635SSuresh Reddy 	return status;
26489aebddd1SJeff Kirsher err:
26499aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
26509aebddd1SJeff Kirsher 	return status;
26519aebddd1SJeff Kirsher }
26529aebddd1SJeff Kirsher 
26539aebddd1SJeff Kirsher int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
26549aebddd1SJeff Kirsher 			u32 byte_cnt, struct be_dma_mem *cmd)
26559aebddd1SJeff Kirsher {
26569aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
26579aebddd1SJeff Kirsher 	struct be_cmd_req_ddrdma_test *req;
26589aebddd1SJeff Kirsher 	int status;
26599aebddd1SJeff Kirsher 	int i, j = 0;
26609aebddd1SJeff Kirsher 
26619aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
26629aebddd1SJeff Kirsher 
26639aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
26649aebddd1SJeff Kirsher 	if (!wrb) {
26659aebddd1SJeff Kirsher 		status = -EBUSY;
26669aebddd1SJeff Kirsher 		goto err;
26679aebddd1SJeff Kirsher 	}
26689aebddd1SJeff Kirsher 	req = cmd->va;
2669106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2670a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size, wrb,
2671a2cc4e0bSSathya Perla 			       cmd);
26729aebddd1SJeff Kirsher 
26739aebddd1SJeff Kirsher 	req->pattern = cpu_to_le64(pattern);
26749aebddd1SJeff Kirsher 	req->byte_count = cpu_to_le32(byte_cnt);
26759aebddd1SJeff Kirsher 	for (i = 0; i < byte_cnt; i++) {
26769aebddd1SJeff Kirsher 		req->snd_buff[i] = (u8)(pattern >> (j*8));
26779aebddd1SJeff Kirsher 		j++;
26789aebddd1SJeff Kirsher 		if (j > 7)
26799aebddd1SJeff Kirsher 			j = 0;
26809aebddd1SJeff Kirsher 	}
26819aebddd1SJeff Kirsher 
26829aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
26839aebddd1SJeff Kirsher 
26849aebddd1SJeff Kirsher 	if (!status) {
26859aebddd1SJeff Kirsher 		struct be_cmd_resp_ddrdma_test *resp;
268603d28ffeSKalesh AP 
26879aebddd1SJeff Kirsher 		resp = cmd->va;
26889aebddd1SJeff Kirsher 		if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
26899aebddd1SJeff Kirsher 		    resp->snd_err) {
26909aebddd1SJeff Kirsher 			status = -1;
26919aebddd1SJeff Kirsher 		}
26929aebddd1SJeff Kirsher 	}
26939aebddd1SJeff Kirsher 
26949aebddd1SJeff Kirsher err:
26959aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
26969aebddd1SJeff Kirsher 	return status;
26979aebddd1SJeff Kirsher }
26989aebddd1SJeff Kirsher 
26999aebddd1SJeff Kirsher int be_cmd_get_seeprom_data(struct be_adapter *adapter,
27009aebddd1SJeff Kirsher 			    struct be_dma_mem *nonemb_cmd)
27019aebddd1SJeff Kirsher {
27029aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
27039aebddd1SJeff Kirsher 	struct be_cmd_req_seeprom_read *req;
27049aebddd1SJeff Kirsher 	int status;
27059aebddd1SJeff Kirsher 
27069aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27079aebddd1SJeff Kirsher 
27089aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27099aebddd1SJeff Kirsher 	if (!wrb) {
27109aebddd1SJeff Kirsher 		status = -EBUSY;
27119aebddd1SJeff Kirsher 		goto err;
27129aebddd1SJeff Kirsher 	}
27139aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
27149aebddd1SJeff Kirsher 
2715106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2716106df1e3SSomnath Kotur 			       OPCODE_COMMON_SEEPROM_READ, sizeof(*req), wrb,
2717106df1e3SSomnath Kotur 			       nonemb_cmd);
27189aebddd1SJeff Kirsher 
27199aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
27209aebddd1SJeff Kirsher 
27219aebddd1SJeff Kirsher err:
27229aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
27239aebddd1SJeff Kirsher 	return status;
27249aebddd1SJeff Kirsher }
27259aebddd1SJeff Kirsher 
272642f11cf2SAjit Khaparde int be_cmd_get_phy_info(struct be_adapter *adapter)
27279aebddd1SJeff Kirsher {
27289aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
27299aebddd1SJeff Kirsher 	struct be_cmd_req_get_phy_info *req;
27309aebddd1SJeff Kirsher 	struct be_dma_mem cmd;
27319aebddd1SJeff Kirsher 	int status;
27329aebddd1SJeff Kirsher 
2733f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
2734f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
2735f25b119cSPadmanabh Ratnakar 		return -EPERM;
2736f25b119cSPadmanabh Ratnakar 
27379aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27389aebddd1SJeff Kirsher 
27399aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27409aebddd1SJeff Kirsher 	if (!wrb) {
27419aebddd1SJeff Kirsher 		status = -EBUSY;
27429aebddd1SJeff Kirsher 		goto err;
27439aebddd1SJeff Kirsher 	}
27449aebddd1SJeff Kirsher 	cmd.size = sizeof(struct be_cmd_req_get_phy_info);
2745a2cc4e0bSSathya Perla 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
27469aebddd1SJeff Kirsher 	if (!cmd.va) {
27479aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
27489aebddd1SJeff Kirsher 		status = -ENOMEM;
27499aebddd1SJeff Kirsher 		goto err;
27509aebddd1SJeff Kirsher 	}
27519aebddd1SJeff Kirsher 
27529aebddd1SJeff Kirsher 	req = cmd.va;
27539aebddd1SJeff Kirsher 
2754106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2755106df1e3SSomnath Kotur 			       OPCODE_COMMON_GET_PHY_DETAILS, sizeof(*req),
2756106df1e3SSomnath Kotur 			       wrb, &cmd);
27579aebddd1SJeff Kirsher 
27589aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
27599aebddd1SJeff Kirsher 	if (!status) {
27609aebddd1SJeff Kirsher 		struct be_phy_info *resp_phy_info =
27619aebddd1SJeff Kirsher 				cmd.va + sizeof(struct be_cmd_req_hdr);
276203d28ffeSKalesh AP 
276342f11cf2SAjit Khaparde 		adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
276442f11cf2SAjit Khaparde 		adapter->phy.interface_type =
27659aebddd1SJeff Kirsher 			le16_to_cpu(resp_phy_info->interface_type);
276642f11cf2SAjit Khaparde 		adapter->phy.auto_speeds_supported =
276742f11cf2SAjit Khaparde 			le16_to_cpu(resp_phy_info->auto_speeds_supported);
276842f11cf2SAjit Khaparde 		adapter->phy.fixed_speeds_supported =
276942f11cf2SAjit Khaparde 			le16_to_cpu(resp_phy_info->fixed_speeds_supported);
277042f11cf2SAjit Khaparde 		adapter->phy.misc_params =
277142f11cf2SAjit Khaparde 			le32_to_cpu(resp_phy_info->misc_params);
277268cb7e47SVasundhara Volam 
277368cb7e47SVasundhara Volam 		if (BE2_chip(adapter)) {
277468cb7e47SVasundhara Volam 			adapter->phy.fixed_speeds_supported =
277568cb7e47SVasundhara Volam 				BE_SUPPORTED_SPEED_10GBPS |
277668cb7e47SVasundhara Volam 				BE_SUPPORTED_SPEED_1GBPS;
277768cb7e47SVasundhara Volam 		}
27789aebddd1SJeff Kirsher 	}
2779a2cc4e0bSSathya Perla 	pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
27809aebddd1SJeff Kirsher err:
27819aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
27829aebddd1SJeff Kirsher 	return status;
27839aebddd1SJeff Kirsher }
27849aebddd1SJeff Kirsher 
2785bc0ee163SLad, Prabhakar static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
27869aebddd1SJeff Kirsher {
27879aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
27889aebddd1SJeff Kirsher 	struct be_cmd_req_set_qos *req;
27899aebddd1SJeff Kirsher 	int status;
27909aebddd1SJeff Kirsher 
27919aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27929aebddd1SJeff Kirsher 
27939aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27949aebddd1SJeff Kirsher 	if (!wrb) {
27959aebddd1SJeff Kirsher 		status = -EBUSY;
27969aebddd1SJeff Kirsher 		goto err;
27979aebddd1SJeff Kirsher 	}
27989aebddd1SJeff Kirsher 
27999aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
28009aebddd1SJeff Kirsher 
2801106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2802106df1e3SSomnath Kotur 			       OPCODE_COMMON_SET_QOS, sizeof(*req), wrb, NULL);
28039aebddd1SJeff Kirsher 
28049aebddd1SJeff Kirsher 	req->hdr.domain = domain;
28059aebddd1SJeff Kirsher 	req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC);
28069aebddd1SJeff Kirsher 	req->max_bps_nic = cpu_to_le32(bps);
28079aebddd1SJeff Kirsher 
28089aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
28099aebddd1SJeff Kirsher 
28109aebddd1SJeff Kirsher err:
28119aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
28129aebddd1SJeff Kirsher 	return status;
28139aebddd1SJeff Kirsher }
28149aebddd1SJeff Kirsher 
28159aebddd1SJeff Kirsher int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
28169aebddd1SJeff Kirsher {
28179aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
28189aebddd1SJeff Kirsher 	struct be_cmd_req_cntl_attribs *req;
28199aebddd1SJeff Kirsher 	struct be_cmd_resp_cntl_attribs *resp;
28209aebddd1SJeff Kirsher 	int status;
28219aebddd1SJeff Kirsher 	int payload_len = max(sizeof(*req), sizeof(*resp));
28229aebddd1SJeff Kirsher 	struct mgmt_controller_attrib *attribs;
28239aebddd1SJeff Kirsher 	struct be_dma_mem attribs_cmd;
28249aebddd1SJeff Kirsher 
2825d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
2826d98ef50fSSuresh Reddy 		return -1;
2827d98ef50fSSuresh Reddy 
28289aebddd1SJeff Kirsher 	memset(&attribs_cmd, 0, sizeof(struct be_dma_mem));
28299aebddd1SJeff Kirsher 	attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs);
28309aebddd1SJeff Kirsher 	attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size,
28319aebddd1SJeff Kirsher 					      &attribs_cmd.dma);
28329aebddd1SJeff Kirsher 	if (!attribs_cmd.va) {
2833a2cc4e0bSSathya Perla 		dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
2834d98ef50fSSuresh Reddy 		status = -ENOMEM;
2835d98ef50fSSuresh Reddy 		goto err;
28369aebddd1SJeff Kirsher 	}
28379aebddd1SJeff Kirsher 
28389aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
28399aebddd1SJeff Kirsher 	if (!wrb) {
28409aebddd1SJeff Kirsher 		status = -EBUSY;
28419aebddd1SJeff Kirsher 		goto err;
28429aebddd1SJeff Kirsher 	}
28439aebddd1SJeff Kirsher 	req = attribs_cmd.va;
28449aebddd1SJeff Kirsher 
2845106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2846a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len,
2847a2cc4e0bSSathya Perla 			       wrb, &attribs_cmd);
28489aebddd1SJeff Kirsher 
28499aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
28509aebddd1SJeff Kirsher 	if (!status) {
28519aebddd1SJeff Kirsher 		attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
28529aebddd1SJeff Kirsher 		adapter->hba_port_num = attribs->hba_attribs.phy_port;
28539aebddd1SJeff Kirsher 	}
28549aebddd1SJeff Kirsher 
28559aebddd1SJeff Kirsher err:
28569aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
2857d98ef50fSSuresh Reddy 	if (attribs_cmd.va)
2858d98ef50fSSuresh Reddy 		pci_free_consistent(adapter->pdev, attribs_cmd.size,
2859d98ef50fSSuresh Reddy 				    attribs_cmd.va, attribs_cmd.dma);
28609aebddd1SJeff Kirsher 	return status;
28619aebddd1SJeff Kirsher }
28629aebddd1SJeff Kirsher 
28639aebddd1SJeff Kirsher /* Uses mbox */
28649aebddd1SJeff Kirsher int be_cmd_req_native_mode(struct be_adapter *adapter)
28659aebddd1SJeff Kirsher {
28669aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
28679aebddd1SJeff Kirsher 	struct be_cmd_req_set_func_cap *req;
28689aebddd1SJeff Kirsher 	int status;
28699aebddd1SJeff Kirsher 
28709aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
28719aebddd1SJeff Kirsher 		return -1;
28729aebddd1SJeff Kirsher 
28739aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
28749aebddd1SJeff Kirsher 	if (!wrb) {
28759aebddd1SJeff Kirsher 		status = -EBUSY;
28769aebddd1SJeff Kirsher 		goto err;
28779aebddd1SJeff Kirsher 	}
28789aebddd1SJeff Kirsher 
28799aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
28809aebddd1SJeff Kirsher 
2881106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2882a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP,
2883a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
28849aebddd1SJeff Kirsher 
28859aebddd1SJeff Kirsher 	req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS |
28869aebddd1SJeff Kirsher 				CAPABILITY_BE3_NATIVE_ERX_API);
28879aebddd1SJeff Kirsher 	req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API);
28889aebddd1SJeff Kirsher 
28899aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
28909aebddd1SJeff Kirsher 	if (!status) {
28919aebddd1SJeff Kirsher 		struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
289203d28ffeSKalesh AP 
28939aebddd1SJeff Kirsher 		adapter->be3_native = le32_to_cpu(resp->cap_flags) &
28949aebddd1SJeff Kirsher 					CAPABILITY_BE3_NATIVE_ERX_API;
2895d379142bSSathya Perla 		if (!adapter->be3_native)
2896d379142bSSathya Perla 			dev_warn(&adapter->pdev->dev,
2897d379142bSSathya Perla 				 "adapter not in advanced mode\n");
28989aebddd1SJeff Kirsher 	}
28999aebddd1SJeff Kirsher err:
29009aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
29019aebddd1SJeff Kirsher 	return status;
29029aebddd1SJeff Kirsher }
2903590c391dSPadmanabh Ratnakar 
2904f25b119cSPadmanabh Ratnakar /* Get privilege(s) for a function */
2905f25b119cSPadmanabh Ratnakar int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
2906f25b119cSPadmanabh Ratnakar 			     u32 domain)
2907f25b119cSPadmanabh Ratnakar {
2908f25b119cSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
2909f25b119cSPadmanabh Ratnakar 	struct be_cmd_req_get_fn_privileges *req;
2910f25b119cSPadmanabh Ratnakar 	int status;
2911f25b119cSPadmanabh Ratnakar 
2912f25b119cSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
2913f25b119cSPadmanabh Ratnakar 
2914f25b119cSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
2915f25b119cSPadmanabh Ratnakar 	if (!wrb) {
2916f25b119cSPadmanabh Ratnakar 		status = -EBUSY;
2917f25b119cSPadmanabh Ratnakar 		goto err;
2918f25b119cSPadmanabh Ratnakar 	}
2919f25b119cSPadmanabh Ratnakar 
2920f25b119cSPadmanabh Ratnakar 	req = embedded_payload(wrb);
2921f25b119cSPadmanabh Ratnakar 
2922f25b119cSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2923f25b119cSPadmanabh Ratnakar 			       OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req),
2924f25b119cSPadmanabh Ratnakar 			       wrb, NULL);
2925f25b119cSPadmanabh Ratnakar 
2926f25b119cSPadmanabh Ratnakar 	req->hdr.domain = domain;
2927f25b119cSPadmanabh Ratnakar 
2928f25b119cSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
2929f25b119cSPadmanabh Ratnakar 	if (!status) {
2930f25b119cSPadmanabh Ratnakar 		struct be_cmd_resp_get_fn_privileges *resp =
2931f25b119cSPadmanabh Ratnakar 						embedded_payload(wrb);
293203d28ffeSKalesh AP 
2933f25b119cSPadmanabh Ratnakar 		*privilege = le32_to_cpu(resp->privilege_mask);
293402308d74SSuresh Reddy 
293502308d74SSuresh Reddy 		/* In UMC mode FW does not return right privileges.
293602308d74SSuresh Reddy 		 * Override with correct privilege equivalent to PF.
293702308d74SSuresh Reddy 		 */
293802308d74SSuresh Reddy 		if (BEx_chip(adapter) && be_is_mc(adapter) &&
293902308d74SSuresh Reddy 		    be_physfn(adapter))
294002308d74SSuresh Reddy 			*privilege = MAX_PRIVILEGES;
2941f25b119cSPadmanabh Ratnakar 	}
2942f25b119cSPadmanabh Ratnakar 
2943f25b119cSPadmanabh Ratnakar err:
2944f25b119cSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
2945f25b119cSPadmanabh Ratnakar 	return status;
2946f25b119cSPadmanabh Ratnakar }
2947f25b119cSPadmanabh Ratnakar 
294804a06028SSathya Perla /* Set privilege(s) for a function */
294904a06028SSathya Perla int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
295004a06028SSathya Perla 			     u32 domain)
295104a06028SSathya Perla {
295204a06028SSathya Perla 	struct be_mcc_wrb *wrb;
295304a06028SSathya Perla 	struct be_cmd_req_set_fn_privileges *req;
295404a06028SSathya Perla 	int status;
295504a06028SSathya Perla 
295604a06028SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
295704a06028SSathya Perla 
295804a06028SSathya Perla 	wrb = wrb_from_mccq(adapter);
295904a06028SSathya Perla 	if (!wrb) {
296004a06028SSathya Perla 		status = -EBUSY;
296104a06028SSathya Perla 		goto err;
296204a06028SSathya Perla 	}
296304a06028SSathya Perla 
296404a06028SSathya Perla 	req = embedded_payload(wrb);
296504a06028SSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
296604a06028SSathya Perla 			       OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req),
296704a06028SSathya Perla 			       wrb, NULL);
296804a06028SSathya Perla 	req->hdr.domain = domain;
296904a06028SSathya Perla 	if (lancer_chip(adapter))
297004a06028SSathya Perla 		req->privileges_lancer = cpu_to_le32(privileges);
297104a06028SSathya Perla 	else
297204a06028SSathya Perla 		req->privileges = cpu_to_le32(privileges);
297304a06028SSathya Perla 
297404a06028SSathya Perla 	status = be_mcc_notify_wait(adapter);
297504a06028SSathya Perla err:
297604a06028SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
297704a06028SSathya Perla 	return status;
297804a06028SSathya Perla }
297904a06028SSathya Perla 
29805a712c13SSathya Perla /* pmac_id_valid: true => pmac_id is supplied and MAC address is requested.
29815a712c13SSathya Perla  * pmac_id_valid: false => pmac_id or MAC address is requested.
29825a712c13SSathya Perla  *		  If pmac_id is returned, pmac_id_valid is returned as true
29835a712c13SSathya Perla  */
29841578e777SPadmanabh Ratnakar int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
2985b188f090SSuresh Reddy 			     bool *pmac_id_valid, u32 *pmac_id, u32 if_handle,
2986b188f090SSuresh Reddy 			     u8 domain)
2987590c391dSPadmanabh Ratnakar {
2988590c391dSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
2989590c391dSPadmanabh Ratnakar 	struct be_cmd_req_get_mac_list *req;
2990590c391dSPadmanabh Ratnakar 	int status;
2991590c391dSPadmanabh Ratnakar 	int mac_count;
2992e5e1ee89SPadmanabh Ratnakar 	struct be_dma_mem get_mac_list_cmd;
2993e5e1ee89SPadmanabh Ratnakar 	int i;
2994e5e1ee89SPadmanabh Ratnakar 
2995e5e1ee89SPadmanabh Ratnakar 	memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
2996e5e1ee89SPadmanabh Ratnakar 	get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
2997e5e1ee89SPadmanabh Ratnakar 	get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev,
2998e5e1ee89SPadmanabh Ratnakar 						   get_mac_list_cmd.size,
2999e5e1ee89SPadmanabh Ratnakar 						   &get_mac_list_cmd.dma);
3000e5e1ee89SPadmanabh Ratnakar 
3001e5e1ee89SPadmanabh Ratnakar 	if (!get_mac_list_cmd.va) {
3002e5e1ee89SPadmanabh Ratnakar 		dev_err(&adapter->pdev->dev,
3003e5e1ee89SPadmanabh Ratnakar 			"Memory allocation failure during GET_MAC_LIST\n");
3004e5e1ee89SPadmanabh Ratnakar 		return -ENOMEM;
3005e5e1ee89SPadmanabh Ratnakar 	}
3006590c391dSPadmanabh Ratnakar 
3007590c391dSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
3008590c391dSPadmanabh Ratnakar 
3009590c391dSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
3010590c391dSPadmanabh Ratnakar 	if (!wrb) {
3011590c391dSPadmanabh Ratnakar 		status = -EBUSY;
3012e5e1ee89SPadmanabh Ratnakar 		goto out;
3013590c391dSPadmanabh Ratnakar 	}
3014e5e1ee89SPadmanabh Ratnakar 
3015e5e1ee89SPadmanabh Ratnakar 	req = get_mac_list_cmd.va;
3016590c391dSPadmanabh Ratnakar 
3017590c391dSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3018bf591f51SSathya Perla 			       OPCODE_COMMON_GET_MAC_LIST,
3019bf591f51SSathya Perla 			       get_mac_list_cmd.size, wrb, &get_mac_list_cmd);
3020590c391dSPadmanabh Ratnakar 	req->hdr.domain = domain;
3021e5e1ee89SPadmanabh Ratnakar 	req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
30225a712c13SSathya Perla 	if (*pmac_id_valid) {
30235a712c13SSathya Perla 		req->mac_id = cpu_to_le32(*pmac_id);
3024b188f090SSuresh Reddy 		req->iface_id = cpu_to_le16(if_handle);
30255a712c13SSathya Perla 		req->perm_override = 0;
30265a712c13SSathya Perla 	} else {
3027e5e1ee89SPadmanabh Ratnakar 		req->perm_override = 1;
30285a712c13SSathya Perla 	}
3029590c391dSPadmanabh Ratnakar 
3030590c391dSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
3031590c391dSPadmanabh Ratnakar 	if (!status) {
3032590c391dSPadmanabh Ratnakar 		struct be_cmd_resp_get_mac_list *resp =
3033e5e1ee89SPadmanabh Ratnakar 						get_mac_list_cmd.va;
30345a712c13SSathya Perla 
30355a712c13SSathya Perla 		if (*pmac_id_valid) {
30365a712c13SSathya Perla 			memcpy(mac, resp->macid_macaddr.mac_addr_id.macaddr,
30375a712c13SSathya Perla 			       ETH_ALEN);
30385a712c13SSathya Perla 			goto out;
30395a712c13SSathya Perla 		}
30405a712c13SSathya Perla 
3041e5e1ee89SPadmanabh Ratnakar 		mac_count = resp->true_mac_count + resp->pseudo_mac_count;
3042e5e1ee89SPadmanabh Ratnakar 		/* Mac list returned could contain one or more active mac_ids
3043dbedd44eSJoe Perches 		 * or one or more true or pseudo permanent mac addresses.
30441578e777SPadmanabh Ratnakar 		 * If an active mac_id is present, return first active mac_id
30451578e777SPadmanabh Ratnakar 		 * found.
3046e5e1ee89SPadmanabh Ratnakar 		 */
3047590c391dSPadmanabh Ratnakar 		for (i = 0; i < mac_count; i++) {
3048e5e1ee89SPadmanabh Ratnakar 			struct get_list_macaddr *mac_entry;
3049e5e1ee89SPadmanabh Ratnakar 			u16 mac_addr_size;
3050e5e1ee89SPadmanabh Ratnakar 			u32 mac_id;
3051e5e1ee89SPadmanabh Ratnakar 
3052e5e1ee89SPadmanabh Ratnakar 			mac_entry = &resp->macaddr_list[i];
3053e5e1ee89SPadmanabh Ratnakar 			mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
3054e5e1ee89SPadmanabh Ratnakar 			/* mac_id is a 32 bit value and mac_addr size
3055e5e1ee89SPadmanabh Ratnakar 			 * is 6 bytes
3056e5e1ee89SPadmanabh Ratnakar 			 */
3057e5e1ee89SPadmanabh Ratnakar 			if (mac_addr_size == sizeof(u32)) {
30585a712c13SSathya Perla 				*pmac_id_valid = true;
3059e5e1ee89SPadmanabh Ratnakar 				mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
3060e5e1ee89SPadmanabh Ratnakar 				*pmac_id = le32_to_cpu(mac_id);
3061e5e1ee89SPadmanabh Ratnakar 				goto out;
3062590c391dSPadmanabh Ratnakar 			}
3063590c391dSPadmanabh Ratnakar 		}
30641578e777SPadmanabh Ratnakar 		/* If no active mac_id found, return first mac addr */
30655a712c13SSathya Perla 		*pmac_id_valid = false;
3066e5e1ee89SPadmanabh Ratnakar 		memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
3067e5e1ee89SPadmanabh Ratnakar 		       ETH_ALEN);
3068590c391dSPadmanabh Ratnakar 	}
3069590c391dSPadmanabh Ratnakar 
3070e5e1ee89SPadmanabh Ratnakar out:
3071590c391dSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
3072e5e1ee89SPadmanabh Ratnakar 	pci_free_consistent(adapter->pdev, get_mac_list_cmd.size,
3073e5e1ee89SPadmanabh Ratnakar 			    get_mac_list_cmd.va, get_mac_list_cmd.dma);
3074590c391dSPadmanabh Ratnakar 	return status;
3075590c391dSPadmanabh Ratnakar }
3076590c391dSPadmanabh Ratnakar 
3077a2cc4e0bSSathya Perla int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id,
3078a2cc4e0bSSathya Perla 			  u8 *mac, u32 if_handle, bool active, u32 domain)
30795a712c13SSathya Perla {
3080b188f090SSuresh Reddy 	if (!active)
3081b188f090SSuresh Reddy 		be_cmd_get_mac_from_list(adapter, mac, &active, &curr_pmac_id,
3082b188f090SSuresh Reddy 					 if_handle, domain);
30833175d8c2SSathya Perla 	if (BEx_chip(adapter))
30845a712c13SSathya Perla 		return be_cmd_mac_addr_query(adapter, mac, false,
3085b188f090SSuresh Reddy 					     if_handle, curr_pmac_id);
30863175d8c2SSathya Perla 	else
30873175d8c2SSathya Perla 		/* Fetch the MAC address using pmac_id */
30883175d8c2SSathya Perla 		return be_cmd_get_mac_from_list(adapter, mac, &active,
3089b188f090SSuresh Reddy 						&curr_pmac_id,
3090b188f090SSuresh Reddy 						if_handle, domain);
30915a712c13SSathya Perla }
30925a712c13SSathya Perla 
309395046b92SSathya Perla int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
309495046b92SSathya Perla {
309595046b92SSathya Perla 	int status;
309695046b92SSathya Perla 	bool pmac_valid = false;
309795046b92SSathya Perla 
3098c7bf7169SJoe Perches 	eth_zero_addr(mac);
309995046b92SSathya Perla 
31003175d8c2SSathya Perla 	if (BEx_chip(adapter)) {
31013175d8c2SSathya Perla 		if (be_physfn(adapter))
31023175d8c2SSathya Perla 			status = be_cmd_mac_addr_query(adapter, mac, true, 0,
31033175d8c2SSathya Perla 						       0);
310495046b92SSathya Perla 		else
310595046b92SSathya Perla 			status = be_cmd_mac_addr_query(adapter, mac, false,
310695046b92SSathya Perla 						       adapter->if_handle, 0);
31073175d8c2SSathya Perla 	} else {
31083175d8c2SSathya Perla 		status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
3109b188f090SSuresh Reddy 						  NULL, adapter->if_handle, 0);
31103175d8c2SSathya Perla 	}
31113175d8c2SSathya Perla 
311295046b92SSathya Perla 	return status;
311395046b92SSathya Perla }
311495046b92SSathya Perla 
3115590c391dSPadmanabh Ratnakar /* Uses synchronous MCCQ */
3116590c391dSPadmanabh Ratnakar int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
3117590c391dSPadmanabh Ratnakar 			u8 mac_count, u32 domain)
3118590c391dSPadmanabh Ratnakar {
3119590c391dSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
3120590c391dSPadmanabh Ratnakar 	struct be_cmd_req_set_mac_list *req;
3121590c391dSPadmanabh Ratnakar 	int status;
3122590c391dSPadmanabh Ratnakar 	struct be_dma_mem cmd;
3123590c391dSPadmanabh Ratnakar 
3124590c391dSPadmanabh Ratnakar 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3125590c391dSPadmanabh Ratnakar 	cmd.size = sizeof(struct be_cmd_req_set_mac_list);
3126590c391dSPadmanabh Ratnakar 	cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size,
3127590c391dSPadmanabh Ratnakar 				    &cmd.dma, GFP_KERNEL);
3128d0320f75SJoe Perches 	if (!cmd.va)
3129590c391dSPadmanabh Ratnakar 		return -ENOMEM;
3130590c391dSPadmanabh Ratnakar 
3131590c391dSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
3132590c391dSPadmanabh Ratnakar 
3133590c391dSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
3134590c391dSPadmanabh Ratnakar 	if (!wrb) {
3135590c391dSPadmanabh Ratnakar 		status = -EBUSY;
3136590c391dSPadmanabh Ratnakar 		goto err;
3137590c391dSPadmanabh Ratnakar 	}
3138590c391dSPadmanabh Ratnakar 
3139590c391dSPadmanabh Ratnakar 	req = cmd.va;
3140590c391dSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3141590c391dSPadmanabh Ratnakar 			       OPCODE_COMMON_SET_MAC_LIST, sizeof(*req),
3142590c391dSPadmanabh Ratnakar 			       wrb, &cmd);
3143590c391dSPadmanabh Ratnakar 
3144590c391dSPadmanabh Ratnakar 	req->hdr.domain = domain;
3145590c391dSPadmanabh Ratnakar 	req->mac_count = mac_count;
3146590c391dSPadmanabh Ratnakar 	if (mac_count)
3147590c391dSPadmanabh Ratnakar 		memcpy(req->mac, mac_array, ETH_ALEN*mac_count);
3148590c391dSPadmanabh Ratnakar 
3149590c391dSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
3150590c391dSPadmanabh Ratnakar 
3151590c391dSPadmanabh Ratnakar err:
3152a2cc4e0bSSathya Perla 	dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
3153590c391dSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
3154590c391dSPadmanabh Ratnakar 	return status;
3155590c391dSPadmanabh Ratnakar }
31564762f6ceSAjit Khaparde 
31573175d8c2SSathya Perla /* Wrapper to delete any active MACs and provision the new mac.
31583175d8c2SSathya Perla  * Changes to MAC_LIST are allowed iff none of the MAC addresses in the
31593175d8c2SSathya Perla  * current list are active.
31603175d8c2SSathya Perla  */
31613175d8c2SSathya Perla int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
31623175d8c2SSathya Perla {
31633175d8c2SSathya Perla 	bool active_mac = false;
31643175d8c2SSathya Perla 	u8 old_mac[ETH_ALEN];
31653175d8c2SSathya Perla 	u32 pmac_id;
31663175d8c2SSathya Perla 	int status;
31673175d8c2SSathya Perla 
31683175d8c2SSathya Perla 	status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
3169b188f090SSuresh Reddy 					  &pmac_id, if_id, dom);
3170b188f090SSuresh Reddy 
31713175d8c2SSathya Perla 	if (!status && active_mac)
31723175d8c2SSathya Perla 		be_cmd_pmac_del(adapter, if_id, pmac_id, dom);
31733175d8c2SSathya Perla 
31743175d8c2SSathya Perla 	return be_cmd_set_mac_list(adapter, mac, mac ? 1 : 0, dom);
31753175d8c2SSathya Perla }
31763175d8c2SSathya Perla 
3177f1f3ee1bSAjit Khaparde int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
3178e7bcbd7bSKalesh AP 			  u32 domain, u16 intf_id, u16 hsw_mode, u8 spoofchk)
3179f1f3ee1bSAjit Khaparde {
3180f1f3ee1bSAjit Khaparde 	struct be_mcc_wrb *wrb;
3181f1f3ee1bSAjit Khaparde 	struct be_cmd_req_set_hsw_config *req;
3182f1f3ee1bSAjit Khaparde 	void *ctxt;
3183f1f3ee1bSAjit Khaparde 	int status;
3184f1f3ee1bSAjit Khaparde 
3185f1f3ee1bSAjit Khaparde 	spin_lock_bh(&adapter->mcc_lock);
3186f1f3ee1bSAjit Khaparde 
3187f1f3ee1bSAjit Khaparde 	wrb = wrb_from_mccq(adapter);
3188f1f3ee1bSAjit Khaparde 	if (!wrb) {
3189f1f3ee1bSAjit Khaparde 		status = -EBUSY;
3190f1f3ee1bSAjit Khaparde 		goto err;
3191f1f3ee1bSAjit Khaparde 	}
3192f1f3ee1bSAjit Khaparde 
3193f1f3ee1bSAjit Khaparde 	req = embedded_payload(wrb);
3194f1f3ee1bSAjit Khaparde 	ctxt = &req->context;
3195f1f3ee1bSAjit Khaparde 
3196f1f3ee1bSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3197a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb,
3198a2cc4e0bSSathya Perla 			       NULL);
3199f1f3ee1bSAjit Khaparde 
3200f1f3ee1bSAjit Khaparde 	req->hdr.domain = domain;
3201f1f3ee1bSAjit Khaparde 	AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
3202f1f3ee1bSAjit Khaparde 	if (pvid) {
3203f1f3ee1bSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
3204f1f3ee1bSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
3205f1f3ee1bSAjit Khaparde 	}
3206a77dcb8cSAjit Khaparde 	if (!BEx_chip(adapter) && hsw_mode) {
3207a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
3208a77dcb8cSAjit Khaparde 			      ctxt, adapter->hba_port_num);
3209a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
3210a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
3211a77dcb8cSAjit Khaparde 			      ctxt, hsw_mode);
3212a77dcb8cSAjit Khaparde 	}
3213f1f3ee1bSAjit Khaparde 
3214e7bcbd7bSKalesh AP 	/* Enable/disable both mac and vlan spoof checking */
3215e7bcbd7bSKalesh AP 	if (!BEx_chip(adapter) && spoofchk) {
3216e7bcbd7bSKalesh AP 		AMAP_SET_BITS(struct amap_set_hsw_context, mac_spoofchk,
3217e7bcbd7bSKalesh AP 			      ctxt, spoofchk);
3218e7bcbd7bSKalesh AP 		AMAP_SET_BITS(struct amap_set_hsw_context, vlan_spoofchk,
3219e7bcbd7bSKalesh AP 			      ctxt, spoofchk);
3220e7bcbd7bSKalesh AP 	}
3221e7bcbd7bSKalesh AP 
3222f1f3ee1bSAjit Khaparde 	be_dws_cpu_to_le(req->context, sizeof(req->context));
3223f1f3ee1bSAjit Khaparde 	status = be_mcc_notify_wait(adapter);
3224f1f3ee1bSAjit Khaparde 
3225f1f3ee1bSAjit Khaparde err:
3226f1f3ee1bSAjit Khaparde 	spin_unlock_bh(&adapter->mcc_lock);
3227f1f3ee1bSAjit Khaparde 	return status;
3228f1f3ee1bSAjit Khaparde }
3229f1f3ee1bSAjit Khaparde 
3230f1f3ee1bSAjit Khaparde /* Get Hyper switch config */
3231f1f3ee1bSAjit Khaparde int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
3232e7bcbd7bSKalesh AP 			  u32 domain, u16 intf_id, u8 *mode, bool *spoofchk)
3233f1f3ee1bSAjit Khaparde {
3234f1f3ee1bSAjit Khaparde 	struct be_mcc_wrb *wrb;
3235f1f3ee1bSAjit Khaparde 	struct be_cmd_req_get_hsw_config *req;
3236f1f3ee1bSAjit Khaparde 	void *ctxt;
3237f1f3ee1bSAjit Khaparde 	int status;
3238f1f3ee1bSAjit Khaparde 	u16 vid;
3239f1f3ee1bSAjit Khaparde 
3240f1f3ee1bSAjit Khaparde 	spin_lock_bh(&adapter->mcc_lock);
3241f1f3ee1bSAjit Khaparde 
3242f1f3ee1bSAjit Khaparde 	wrb = wrb_from_mccq(adapter);
3243f1f3ee1bSAjit Khaparde 	if (!wrb) {
3244f1f3ee1bSAjit Khaparde 		status = -EBUSY;
3245f1f3ee1bSAjit Khaparde 		goto err;
3246f1f3ee1bSAjit Khaparde 	}
3247f1f3ee1bSAjit Khaparde 
3248f1f3ee1bSAjit Khaparde 	req = embedded_payload(wrb);
3249f1f3ee1bSAjit Khaparde 	ctxt = &req->context;
3250f1f3ee1bSAjit Khaparde 
3251f1f3ee1bSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3252a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb,
3253a2cc4e0bSSathya Perla 			       NULL);
3254f1f3ee1bSAjit Khaparde 
3255f1f3ee1bSAjit Khaparde 	req->hdr.domain = domain;
3256a77dcb8cSAjit Khaparde 	AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3257a77dcb8cSAjit Khaparde 		      ctxt, intf_id);
3258f1f3ee1bSAjit Khaparde 	AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
3259a77dcb8cSAjit Khaparde 
32602c07c1d7SVasundhara Volam 	if (!BEx_chip(adapter) && mode) {
3261a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3262a77dcb8cSAjit Khaparde 			      ctxt, adapter->hba_port_num);
3263a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
3264a77dcb8cSAjit Khaparde 	}
3265f1f3ee1bSAjit Khaparde 	be_dws_cpu_to_le(req->context, sizeof(req->context));
3266f1f3ee1bSAjit Khaparde 
3267f1f3ee1bSAjit Khaparde 	status = be_mcc_notify_wait(adapter);
3268f1f3ee1bSAjit Khaparde 	if (!status) {
3269f1f3ee1bSAjit Khaparde 		struct be_cmd_resp_get_hsw_config *resp =
3270f1f3ee1bSAjit Khaparde 						embedded_payload(wrb);
327103d28ffeSKalesh AP 
3272a2cc4e0bSSathya Perla 		be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
3273f1f3ee1bSAjit Khaparde 		vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3274f1f3ee1bSAjit Khaparde 				    pvid, &resp->context);
3275a77dcb8cSAjit Khaparde 		if (pvid)
3276f1f3ee1bSAjit Khaparde 			*pvid = le16_to_cpu(vid);
3277a77dcb8cSAjit Khaparde 		if (mode)
3278a77dcb8cSAjit Khaparde 			*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3279a77dcb8cSAjit Khaparde 					      port_fwd_type, &resp->context);
3280e7bcbd7bSKalesh AP 		if (spoofchk)
3281e7bcbd7bSKalesh AP 			*spoofchk =
3282e7bcbd7bSKalesh AP 				AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3283e7bcbd7bSKalesh AP 					      spoofchk, &resp->context);
3284f1f3ee1bSAjit Khaparde 	}
3285f1f3ee1bSAjit Khaparde 
3286f1f3ee1bSAjit Khaparde err:
3287f1f3ee1bSAjit Khaparde 	spin_unlock_bh(&adapter->mcc_lock);
3288f1f3ee1bSAjit Khaparde 	return status;
3289f1f3ee1bSAjit Khaparde }
3290f1f3ee1bSAjit Khaparde 
3291f7062ee5SSathya Perla static bool be_is_wol_excluded(struct be_adapter *adapter)
3292f7062ee5SSathya Perla {
3293f7062ee5SSathya Perla 	struct pci_dev *pdev = adapter->pdev;
3294f7062ee5SSathya Perla 
329518c57c74SKalesh AP 	if (be_virtfn(adapter))
3296f7062ee5SSathya Perla 		return true;
3297f7062ee5SSathya Perla 
3298f7062ee5SSathya Perla 	switch (pdev->subsystem_device) {
3299f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID1:
3300f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID2:
3301f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID3:
3302f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID4:
3303f7062ee5SSathya Perla 		return true;
3304f7062ee5SSathya Perla 	default:
3305f7062ee5SSathya Perla 		return false;
3306f7062ee5SSathya Perla 	}
3307f7062ee5SSathya Perla }
3308f7062ee5SSathya Perla 
33094762f6ceSAjit Khaparde int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
33104762f6ceSAjit Khaparde {
33114762f6ceSAjit Khaparde 	struct be_mcc_wrb *wrb;
33124762f6ceSAjit Khaparde 	struct be_cmd_req_acpi_wol_magic_config_v1 *req;
331376a9e08eSSuresh Reddy 	int status = 0;
33144762f6ceSAjit Khaparde 	struct be_dma_mem cmd;
33154762f6ceSAjit Khaparde 
3316f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
3317f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_ETH))
3318f25b119cSPadmanabh Ratnakar 		return -EPERM;
3319f25b119cSPadmanabh Ratnakar 
332076a9e08eSSuresh Reddy 	if (be_is_wol_excluded(adapter))
332176a9e08eSSuresh Reddy 		return status;
332276a9e08eSSuresh Reddy 
3323d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3324d98ef50fSSuresh Reddy 		return -1;
3325d98ef50fSSuresh Reddy 
33264762f6ceSAjit Khaparde 	memset(&cmd, 0, sizeof(struct be_dma_mem));
33274762f6ceSAjit Khaparde 	cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
3328a2cc4e0bSSathya Perla 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
33294762f6ceSAjit Khaparde 	if (!cmd.va) {
3330a2cc4e0bSSathya Perla 		dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
3331d98ef50fSSuresh Reddy 		status = -ENOMEM;
3332d98ef50fSSuresh Reddy 		goto err;
33334762f6ceSAjit Khaparde 	}
33344762f6ceSAjit Khaparde 
33354762f6ceSAjit Khaparde 	wrb = wrb_from_mbox(adapter);
33364762f6ceSAjit Khaparde 	if (!wrb) {
33374762f6ceSAjit Khaparde 		status = -EBUSY;
33384762f6ceSAjit Khaparde 		goto err;
33394762f6ceSAjit Khaparde 	}
33404762f6ceSAjit Khaparde 
33414762f6ceSAjit Khaparde 	req = cmd.va;
33424762f6ceSAjit Khaparde 
33434762f6ceSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
33444762f6ceSAjit Khaparde 			       OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
334576a9e08eSSuresh Reddy 			       sizeof(*req), wrb, &cmd);
33464762f6ceSAjit Khaparde 
33474762f6ceSAjit Khaparde 	req->hdr.version = 1;
33484762f6ceSAjit Khaparde 	req->query_options = BE_GET_WOL_CAP;
33494762f6ceSAjit Khaparde 
33504762f6ceSAjit Khaparde 	status = be_mbox_notify_wait(adapter);
33514762f6ceSAjit Khaparde 	if (!status) {
33524762f6ceSAjit Khaparde 		struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
335303d28ffeSKalesh AP 
33544762f6ceSAjit Khaparde 		resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *)cmd.va;
33554762f6ceSAjit Khaparde 
33564762f6ceSAjit Khaparde 		adapter->wol_cap = resp->wol_settings;
335776a9e08eSSuresh Reddy 		if (adapter->wol_cap & BE_WOL_CAP)
335876a9e08eSSuresh Reddy 			adapter->wol_en = true;
33594762f6ceSAjit Khaparde 	}
33604762f6ceSAjit Khaparde err:
33614762f6ceSAjit Khaparde 	mutex_unlock(&adapter->mbox_lock);
3362d98ef50fSSuresh Reddy 	if (cmd.va)
33634762f6ceSAjit Khaparde 		pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
33644762f6ceSAjit Khaparde 	return status;
3365941a77d5SSomnath Kotur 
3366941a77d5SSomnath Kotur }
3367baaa08d1SVasundhara Volam 
3368baaa08d1SVasundhara Volam int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level)
3369baaa08d1SVasundhara Volam {
3370baaa08d1SVasundhara Volam 	struct be_dma_mem extfat_cmd;
3371baaa08d1SVasundhara Volam 	struct be_fat_conf_params *cfgs;
3372baaa08d1SVasundhara Volam 	int status;
3373baaa08d1SVasundhara Volam 	int i, j;
3374baaa08d1SVasundhara Volam 
3375baaa08d1SVasundhara Volam 	memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3376baaa08d1SVasundhara Volam 	extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3377baaa08d1SVasundhara Volam 	extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
3378baaa08d1SVasundhara Volam 					     &extfat_cmd.dma);
3379baaa08d1SVasundhara Volam 	if (!extfat_cmd.va)
3380baaa08d1SVasundhara Volam 		return -ENOMEM;
3381baaa08d1SVasundhara Volam 
3382baaa08d1SVasundhara Volam 	status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3383baaa08d1SVasundhara Volam 	if (status)
3384baaa08d1SVasundhara Volam 		goto err;
3385baaa08d1SVasundhara Volam 
3386baaa08d1SVasundhara Volam 	cfgs = (struct be_fat_conf_params *)
3387baaa08d1SVasundhara Volam 			(extfat_cmd.va + sizeof(struct be_cmd_resp_hdr));
3388baaa08d1SVasundhara Volam 	for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
3389baaa08d1SVasundhara Volam 		u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
339003d28ffeSKalesh AP 
3391baaa08d1SVasundhara Volam 		for (j = 0; j < num_modes; j++) {
3392baaa08d1SVasundhara Volam 			if (cfgs->module[i].trace_lvl[j].mode == MODE_UART)
3393baaa08d1SVasundhara Volam 				cfgs->module[i].trace_lvl[j].dbg_lvl =
3394baaa08d1SVasundhara Volam 							cpu_to_le32(level);
3395baaa08d1SVasundhara Volam 		}
3396baaa08d1SVasundhara Volam 	}
3397baaa08d1SVasundhara Volam 
3398baaa08d1SVasundhara Volam 	status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs);
3399baaa08d1SVasundhara Volam err:
3400baaa08d1SVasundhara Volam 	pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
3401baaa08d1SVasundhara Volam 			    extfat_cmd.dma);
3402baaa08d1SVasundhara Volam 	return status;
3403baaa08d1SVasundhara Volam }
3404baaa08d1SVasundhara Volam 
3405baaa08d1SVasundhara Volam int be_cmd_get_fw_log_level(struct be_adapter *adapter)
3406baaa08d1SVasundhara Volam {
3407baaa08d1SVasundhara Volam 	struct be_dma_mem extfat_cmd;
3408baaa08d1SVasundhara Volam 	struct be_fat_conf_params *cfgs;
3409baaa08d1SVasundhara Volam 	int status, j;
3410baaa08d1SVasundhara Volam 	int level = 0;
3411baaa08d1SVasundhara Volam 
3412baaa08d1SVasundhara Volam 	memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3413baaa08d1SVasundhara Volam 	extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3414baaa08d1SVasundhara Volam 	extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
3415baaa08d1SVasundhara Volam 					     &extfat_cmd.dma);
3416baaa08d1SVasundhara Volam 
3417baaa08d1SVasundhara Volam 	if (!extfat_cmd.va) {
3418baaa08d1SVasundhara Volam 		dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
3419baaa08d1SVasundhara Volam 			__func__);
3420baaa08d1SVasundhara Volam 		goto err;
3421baaa08d1SVasundhara Volam 	}
3422baaa08d1SVasundhara Volam 
3423baaa08d1SVasundhara Volam 	status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3424baaa08d1SVasundhara Volam 	if (!status) {
3425baaa08d1SVasundhara Volam 		cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
3426baaa08d1SVasundhara Volam 						sizeof(struct be_cmd_resp_hdr));
342703d28ffeSKalesh AP 
3428baaa08d1SVasundhara Volam 		for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
3429baaa08d1SVasundhara Volam 			if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
3430baaa08d1SVasundhara Volam 				level = cfgs->module[0].trace_lvl[j].dbg_lvl;
3431baaa08d1SVasundhara Volam 		}
3432baaa08d1SVasundhara Volam 	}
3433baaa08d1SVasundhara Volam 	pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
3434baaa08d1SVasundhara Volam 			    extfat_cmd.dma);
3435baaa08d1SVasundhara Volam err:
3436baaa08d1SVasundhara Volam 	return level;
3437baaa08d1SVasundhara Volam }
3438baaa08d1SVasundhara Volam 
3439941a77d5SSomnath Kotur int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
3440941a77d5SSomnath Kotur 				   struct be_dma_mem *cmd)
3441941a77d5SSomnath Kotur {
3442941a77d5SSomnath Kotur 	struct be_mcc_wrb *wrb;
3443941a77d5SSomnath Kotur 	struct be_cmd_req_get_ext_fat_caps *req;
3444941a77d5SSomnath Kotur 	int status;
3445941a77d5SSomnath Kotur 
3446941a77d5SSomnath Kotur 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3447941a77d5SSomnath Kotur 		return -1;
3448941a77d5SSomnath Kotur 
3449941a77d5SSomnath Kotur 	wrb = wrb_from_mbox(adapter);
3450941a77d5SSomnath Kotur 	if (!wrb) {
3451941a77d5SSomnath Kotur 		status = -EBUSY;
3452941a77d5SSomnath Kotur 		goto err;
3453941a77d5SSomnath Kotur 	}
3454941a77d5SSomnath Kotur 
3455941a77d5SSomnath Kotur 	req = cmd->va;
3456941a77d5SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3457941a77d5SSomnath Kotur 			       OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
3458941a77d5SSomnath Kotur 			       cmd->size, wrb, cmd);
3459941a77d5SSomnath Kotur 	req->parameter_type = cpu_to_le32(1);
3460941a77d5SSomnath Kotur 
3461941a77d5SSomnath Kotur 	status = be_mbox_notify_wait(adapter);
3462941a77d5SSomnath Kotur err:
3463941a77d5SSomnath Kotur 	mutex_unlock(&adapter->mbox_lock);
3464941a77d5SSomnath Kotur 	return status;
3465941a77d5SSomnath Kotur }
3466941a77d5SSomnath Kotur 
3467941a77d5SSomnath Kotur int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
3468941a77d5SSomnath Kotur 				   struct be_dma_mem *cmd,
3469941a77d5SSomnath Kotur 				   struct be_fat_conf_params *configs)
3470941a77d5SSomnath Kotur {
3471941a77d5SSomnath Kotur 	struct be_mcc_wrb *wrb;
3472941a77d5SSomnath Kotur 	struct be_cmd_req_set_ext_fat_caps *req;
3473941a77d5SSomnath Kotur 	int status;
3474941a77d5SSomnath Kotur 
3475941a77d5SSomnath Kotur 	spin_lock_bh(&adapter->mcc_lock);
3476941a77d5SSomnath Kotur 
3477941a77d5SSomnath Kotur 	wrb = wrb_from_mccq(adapter);
3478941a77d5SSomnath Kotur 	if (!wrb) {
3479941a77d5SSomnath Kotur 		status = -EBUSY;
3480941a77d5SSomnath Kotur 		goto err;
3481941a77d5SSomnath Kotur 	}
3482941a77d5SSomnath Kotur 
3483941a77d5SSomnath Kotur 	req = cmd->va;
3484941a77d5SSomnath Kotur 	memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
3485941a77d5SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3486941a77d5SSomnath Kotur 			       OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
3487941a77d5SSomnath Kotur 			       cmd->size, wrb, cmd);
3488941a77d5SSomnath Kotur 
3489941a77d5SSomnath Kotur 	status = be_mcc_notify_wait(adapter);
3490941a77d5SSomnath Kotur err:
3491941a77d5SSomnath Kotur 	spin_unlock_bh(&adapter->mcc_lock);
3492941a77d5SSomnath Kotur 	return status;
34934762f6ceSAjit Khaparde }
34946a4ab669SParav Pandit 
349521252377SVasundhara Volam int be_cmd_query_port_name(struct be_adapter *adapter)
3496b4e32a71SPadmanabh Ratnakar {
3497b4e32a71SPadmanabh Ratnakar 	struct be_cmd_req_get_port_name *req;
349821252377SVasundhara Volam 	struct be_mcc_wrb *wrb;
3499b4e32a71SPadmanabh Ratnakar 	int status;
3500b4e32a71SPadmanabh Ratnakar 
350121252377SVasundhara Volam 	if (mutex_lock_interruptible(&adapter->mbox_lock))
350221252377SVasundhara Volam 		return -1;
3503b4e32a71SPadmanabh Ratnakar 
350421252377SVasundhara Volam 	wrb = wrb_from_mbox(adapter);
3505b4e32a71SPadmanabh Ratnakar 	req = embedded_payload(wrb);
3506b4e32a71SPadmanabh Ratnakar 
3507b4e32a71SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3508b4e32a71SPadmanabh Ratnakar 			       OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
3509b4e32a71SPadmanabh Ratnakar 			       NULL);
351021252377SVasundhara Volam 	if (!BEx_chip(adapter))
3511b4e32a71SPadmanabh Ratnakar 		req->hdr.version = 1;
3512b4e32a71SPadmanabh Ratnakar 
351321252377SVasundhara Volam 	status = be_mbox_notify_wait(adapter);
3514b4e32a71SPadmanabh Ratnakar 	if (!status) {
3515b4e32a71SPadmanabh Ratnakar 		struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
351603d28ffeSKalesh AP 
351721252377SVasundhara Volam 		adapter->port_name = resp->port_name[adapter->hba_port_num];
3518b4e32a71SPadmanabh Ratnakar 	} else {
351921252377SVasundhara Volam 		adapter->port_name = adapter->hba_port_num + '0';
3520b4e32a71SPadmanabh Ratnakar 	}
352121252377SVasundhara Volam 
352221252377SVasundhara Volam 	mutex_unlock(&adapter->mbox_lock);
3523b4e32a71SPadmanabh Ratnakar 	return status;
3524b4e32a71SPadmanabh Ratnakar }
3525b4e32a71SPadmanabh Ratnakar 
352610cccf60SVasundhara Volam /* Descriptor type */
352710cccf60SVasundhara Volam enum {
352810cccf60SVasundhara Volam 	FUNC_DESC = 1,
352910cccf60SVasundhara Volam 	VFT_DESC = 2
353010cccf60SVasundhara Volam };
353110cccf60SVasundhara Volam 
353210cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
353310cccf60SVasundhara Volam 					       int desc_type)
3534abb93951SPadmanabh Ratnakar {
3535150d58c7SVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
353610cccf60SVasundhara Volam 	struct be_nic_res_desc *nic;
3537abb93951SPadmanabh Ratnakar 	int i;
3538abb93951SPadmanabh Ratnakar 
3539abb93951SPadmanabh Ratnakar 	for (i = 0; i < desc_count; i++) {
3540150d58c7SVasundhara Volam 		if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
354110cccf60SVasundhara Volam 		    hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
354210cccf60SVasundhara Volam 			nic = (struct be_nic_res_desc *)hdr;
354310cccf60SVasundhara Volam 			if (desc_type == FUNC_DESC ||
354410cccf60SVasundhara Volam 			    (desc_type == VFT_DESC &&
354510cccf60SVasundhara Volam 			     nic->flags & (1 << VFT_SHIFT)))
354610cccf60SVasundhara Volam 				return nic;
354710cccf60SVasundhara Volam 		}
3548150d58c7SVasundhara Volam 
3549150d58c7SVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3550150d58c7SVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3551150d58c7SVasundhara Volam 	}
3552950e2958SWei Yang 	return NULL;
3553abb93951SPadmanabh Ratnakar }
3554abb93951SPadmanabh Ratnakar 
355510cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count)
355610cccf60SVasundhara Volam {
355710cccf60SVasundhara Volam 	return be_get_nic_desc(buf, desc_count, VFT_DESC);
355810cccf60SVasundhara Volam }
355910cccf60SVasundhara Volam 
356010cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count)
356110cccf60SVasundhara Volam {
356210cccf60SVasundhara Volam 	return be_get_nic_desc(buf, desc_count, FUNC_DESC);
356310cccf60SVasundhara Volam }
356410cccf60SVasundhara Volam 
3565150d58c7SVasundhara Volam static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
3566150d58c7SVasundhara Volam 						 u32 desc_count)
3567150d58c7SVasundhara Volam {
3568150d58c7SVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3569150d58c7SVasundhara Volam 	struct be_pcie_res_desc *pcie;
3570150d58c7SVasundhara Volam 	int i;
3571150d58c7SVasundhara Volam 
3572150d58c7SVasundhara Volam 	for (i = 0; i < desc_count; i++) {
3573150d58c7SVasundhara Volam 		if ((hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
3574150d58c7SVasundhara Volam 		     hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1)) {
3575150d58c7SVasundhara Volam 			pcie = (struct be_pcie_res_desc	*)hdr;
3576150d58c7SVasundhara Volam 			if (pcie->pf_num == devfn)
3577150d58c7SVasundhara Volam 				return pcie;
3578150d58c7SVasundhara Volam 		}
3579150d58c7SVasundhara Volam 
3580150d58c7SVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3581150d58c7SVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3582150d58c7SVasundhara Volam 	}
3583abb93951SPadmanabh Ratnakar 	return NULL;
3584abb93951SPadmanabh Ratnakar }
3585abb93951SPadmanabh Ratnakar 
3586f93f160bSVasundhara Volam static struct be_port_res_desc *be_get_port_desc(u8 *buf, u32 desc_count)
3587f93f160bSVasundhara Volam {
3588f93f160bSVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3589f93f160bSVasundhara Volam 	int i;
3590f93f160bSVasundhara Volam 
3591f93f160bSVasundhara Volam 	for (i = 0; i < desc_count; i++) {
3592f93f160bSVasundhara Volam 		if (hdr->desc_type == PORT_RESOURCE_DESC_TYPE_V1)
3593f93f160bSVasundhara Volam 			return (struct be_port_res_desc *)hdr;
3594f93f160bSVasundhara Volam 
3595f93f160bSVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3596f93f160bSVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3597f93f160bSVasundhara Volam 	}
3598f93f160bSVasundhara Volam 	return NULL;
3599f93f160bSVasundhara Volam }
3600f93f160bSVasundhara Volam 
360192bf14abSSathya Perla static void be_copy_nic_desc(struct be_resources *res,
360292bf14abSSathya Perla 			     struct be_nic_res_desc *desc)
360392bf14abSSathya Perla {
360492bf14abSSathya Perla 	res->max_uc_mac = le16_to_cpu(desc->unicast_mac_count);
360592bf14abSSathya Perla 	res->max_vlans = le16_to_cpu(desc->vlan_count);
360692bf14abSSathya Perla 	res->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
360792bf14abSSathya Perla 	res->max_tx_qs = le16_to_cpu(desc->txq_count);
360892bf14abSSathya Perla 	res->max_rss_qs = le16_to_cpu(desc->rssq_count);
360992bf14abSSathya Perla 	res->max_rx_qs = le16_to_cpu(desc->rq_count);
361092bf14abSSathya Perla 	res->max_evt_qs = le16_to_cpu(desc->eq_count);
3611f2858738SVasundhara Volam 	res->max_cq_count = le16_to_cpu(desc->cq_count);
3612f2858738SVasundhara Volam 	res->max_iface_count = le16_to_cpu(desc->iface_count);
3613f2858738SVasundhara Volam 	res->max_mcc_count = le16_to_cpu(desc->mcc_count);
361492bf14abSSathya Perla 	/* Clear flags that driver is not interested in */
361592bf14abSSathya Perla 	res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
361692bf14abSSathya Perla 				BE_IF_CAP_FLAGS_WANT;
361792bf14abSSathya Perla }
361892bf14abSSathya Perla 
3619abb93951SPadmanabh Ratnakar /* Uses Mbox */
362092bf14abSSathya Perla int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
3621abb93951SPadmanabh Ratnakar {
3622abb93951SPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
3623abb93951SPadmanabh Ratnakar 	struct be_cmd_req_get_func_config *req;
3624abb93951SPadmanabh Ratnakar 	int status;
3625abb93951SPadmanabh Ratnakar 	struct be_dma_mem cmd;
3626abb93951SPadmanabh Ratnakar 
3627d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3628d98ef50fSSuresh Reddy 		return -1;
3629d98ef50fSSuresh Reddy 
3630abb93951SPadmanabh Ratnakar 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3631abb93951SPadmanabh Ratnakar 	cmd.size = sizeof(struct be_cmd_resp_get_func_config);
3632a2cc4e0bSSathya Perla 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
3633abb93951SPadmanabh Ratnakar 	if (!cmd.va) {
3634abb93951SPadmanabh Ratnakar 		dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
3635d98ef50fSSuresh Reddy 		status = -ENOMEM;
3636d98ef50fSSuresh Reddy 		goto err;
3637abb93951SPadmanabh Ratnakar 	}
3638abb93951SPadmanabh Ratnakar 
3639abb93951SPadmanabh Ratnakar 	wrb = wrb_from_mbox(adapter);
3640abb93951SPadmanabh Ratnakar 	if (!wrb) {
3641abb93951SPadmanabh Ratnakar 		status = -EBUSY;
3642abb93951SPadmanabh Ratnakar 		goto err;
3643abb93951SPadmanabh Ratnakar 	}
3644abb93951SPadmanabh Ratnakar 
3645abb93951SPadmanabh Ratnakar 	req = cmd.va;
3646abb93951SPadmanabh Ratnakar 
3647abb93951SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3648abb93951SPadmanabh Ratnakar 			       OPCODE_COMMON_GET_FUNC_CONFIG,
3649abb93951SPadmanabh Ratnakar 			       cmd.size, wrb, &cmd);
3650abb93951SPadmanabh Ratnakar 
365128710c55SKalesh AP 	if (skyhawk_chip(adapter))
365228710c55SKalesh AP 		req->hdr.version = 1;
365328710c55SKalesh AP 
3654abb93951SPadmanabh Ratnakar 	status = be_mbox_notify_wait(adapter);
3655abb93951SPadmanabh Ratnakar 	if (!status) {
3656abb93951SPadmanabh Ratnakar 		struct be_cmd_resp_get_func_config *resp = cmd.va;
3657abb93951SPadmanabh Ratnakar 		u32 desc_count = le32_to_cpu(resp->desc_count);
3658150d58c7SVasundhara Volam 		struct be_nic_res_desc *desc;
3659abb93951SPadmanabh Ratnakar 
366010cccf60SVasundhara Volam 		desc = be_get_func_nic_desc(resp->func_param, desc_count);
3661abb93951SPadmanabh Ratnakar 		if (!desc) {
3662abb93951SPadmanabh Ratnakar 			status = -EINVAL;
3663abb93951SPadmanabh Ratnakar 			goto err;
3664abb93951SPadmanabh Ratnakar 		}
3665abb93951SPadmanabh Ratnakar 
3666d5c18473SPadmanabh Ratnakar 		adapter->pf_number = desc->pf_num;
366792bf14abSSathya Perla 		be_copy_nic_desc(res, desc);
3668abb93951SPadmanabh Ratnakar 	}
3669abb93951SPadmanabh Ratnakar err:
3670abb93951SPadmanabh Ratnakar 	mutex_unlock(&adapter->mbox_lock);
3671d98ef50fSSuresh Reddy 	if (cmd.va)
3672d98ef50fSSuresh Reddy 		pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
3673abb93951SPadmanabh Ratnakar 	return status;
3674abb93951SPadmanabh Ratnakar }
3675abb93951SPadmanabh Ratnakar 
3676ba48c0c9SVasundhara Volam /* Will use MBOX only if MCCQ has not been created */
367792bf14abSSathya Perla int be_cmd_get_profile_config(struct be_adapter *adapter,
3678f2858738SVasundhara Volam 			      struct be_resources *res, u8 query, u8 domain)
3679a05f99dbSVasundhara Volam {
3680150d58c7SVasundhara Volam 	struct be_cmd_resp_get_profile_config *resp;
3681ba48c0c9SVasundhara Volam 	struct be_cmd_req_get_profile_config *req;
368210cccf60SVasundhara Volam 	struct be_nic_res_desc *vf_res;
3683150d58c7SVasundhara Volam 	struct be_pcie_res_desc *pcie;
3684f93f160bSVasundhara Volam 	struct be_port_res_desc *port;
3685150d58c7SVasundhara Volam 	struct be_nic_res_desc *nic;
3686ba48c0c9SVasundhara Volam 	struct be_mcc_wrb wrb = {0};
3687a05f99dbSVasundhara Volam 	struct be_dma_mem cmd;
3688f2858738SVasundhara Volam 	u16 desc_count;
3689a05f99dbSVasundhara Volam 	int status;
3690a05f99dbSVasundhara Volam 
3691a05f99dbSVasundhara Volam 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3692a05f99dbSVasundhara Volam 	cmd.size = sizeof(struct be_cmd_resp_get_profile_config);
3693150d58c7SVasundhara Volam 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
3694150d58c7SVasundhara Volam 	if (!cmd.va)
3695a05f99dbSVasundhara Volam 		return -ENOMEM;
3696a05f99dbSVasundhara Volam 
3697ba48c0c9SVasundhara Volam 	req = cmd.va;
3698ba48c0c9SVasundhara Volam 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3699ba48c0c9SVasundhara Volam 			       OPCODE_COMMON_GET_PROFILE_CONFIG,
3700ba48c0c9SVasundhara Volam 			       cmd.size, &wrb, &cmd);
3701ba48c0c9SVasundhara Volam 
3702ba48c0c9SVasundhara Volam 	req->hdr.domain = domain;
3703ba48c0c9SVasundhara Volam 	if (!lancer_chip(adapter))
3704ba48c0c9SVasundhara Volam 		req->hdr.version = 1;
3705ba48c0c9SVasundhara Volam 	req->type = ACTIVE_PROFILE_TYPE;
3706ba48c0c9SVasundhara Volam 
3707f2858738SVasundhara Volam 	/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
3708f2858738SVasundhara Volam 	 * descriptors with all bits set to "1" for the fields which can be
3709f2858738SVasundhara Volam 	 * modified using SET_PROFILE_CONFIG cmd.
3710f2858738SVasundhara Volam 	 */
3711f2858738SVasundhara Volam 	if (query == RESOURCE_MODIFIABLE)
3712f2858738SVasundhara Volam 		req->type |= QUERY_MODIFIABLE_FIELDS_TYPE;
3713f2858738SVasundhara Volam 
3714ba48c0c9SVasundhara Volam 	status = be_cmd_notify_wait(adapter, &wrb);
3715150d58c7SVasundhara Volam 	if (status)
3716abb93951SPadmanabh Ratnakar 		goto err;
3717150d58c7SVasundhara Volam 
3718150d58c7SVasundhara Volam 	resp = cmd.va;
3719f2858738SVasundhara Volam 	desc_count = le16_to_cpu(resp->desc_count);
3720150d58c7SVasundhara Volam 
3721150d58c7SVasundhara Volam 	pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
3722150d58c7SVasundhara Volam 				desc_count);
3723150d58c7SVasundhara Volam 	if (pcie)
372492bf14abSSathya Perla 		res->max_vfs = le16_to_cpu(pcie->num_vfs);
3725150d58c7SVasundhara Volam 
3726f93f160bSVasundhara Volam 	port = be_get_port_desc(resp->func_param, desc_count);
3727f93f160bSVasundhara Volam 	if (port)
3728f93f160bSVasundhara Volam 		adapter->mc_type = port->mc_type;
3729f93f160bSVasundhara Volam 
373010cccf60SVasundhara Volam 	nic = be_get_func_nic_desc(resp->func_param, desc_count);
373192bf14abSSathya Perla 	if (nic)
373292bf14abSSathya Perla 		be_copy_nic_desc(res, nic);
373392bf14abSSathya Perla 
373410cccf60SVasundhara Volam 	vf_res = be_get_vft_desc(resp->func_param, desc_count);
373510cccf60SVasundhara Volam 	if (vf_res)
373610cccf60SVasundhara Volam 		res->vf_if_cap_flags = vf_res->cap_flags;
3737abb93951SPadmanabh Ratnakar err:
3738a05f99dbSVasundhara Volam 	if (cmd.va)
3739150d58c7SVasundhara Volam 		pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
3740abb93951SPadmanabh Ratnakar 	return status;
3741abb93951SPadmanabh Ratnakar }
3742abb93951SPadmanabh Ratnakar 
3743bec84e6bSVasundhara Volam /* Will use MBOX only if MCCQ has not been created */
3744bec84e6bSVasundhara Volam static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
3745bec84e6bSVasundhara Volam 				     int size, int count, u8 version, u8 domain)
3746d5c18473SPadmanabh Ratnakar {
3747d5c18473SPadmanabh Ratnakar 	struct be_cmd_req_set_profile_config *req;
3748bec84e6bSVasundhara Volam 	struct be_mcc_wrb wrb = {0};
3749bec84e6bSVasundhara Volam 	struct be_dma_mem cmd;
3750d5c18473SPadmanabh Ratnakar 	int status;
3751d5c18473SPadmanabh Ratnakar 
3752bec84e6bSVasundhara Volam 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3753bec84e6bSVasundhara Volam 	cmd.size = sizeof(struct be_cmd_req_set_profile_config);
3754bec84e6bSVasundhara Volam 	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
3755bec84e6bSVasundhara Volam 	if (!cmd.va)
3756bec84e6bSVasundhara Volam 		return -ENOMEM;
3757d5c18473SPadmanabh Ratnakar 
3758bec84e6bSVasundhara Volam 	req = cmd.va;
3759d5c18473SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3760bec84e6bSVasundhara Volam 			       OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
3761bec84e6bSVasundhara Volam 			       &wrb, &cmd);
3762a401801cSSathya Perla 	req->hdr.version = version;
3763d5c18473SPadmanabh Ratnakar 	req->hdr.domain = domain;
3764bec84e6bSVasundhara Volam 	req->desc_count = cpu_to_le32(count);
3765a401801cSSathya Perla 	memcpy(req->desc, desc, size);
3766d5c18473SPadmanabh Ratnakar 
3767bec84e6bSVasundhara Volam 	status = be_cmd_notify_wait(adapter, &wrb);
3768bec84e6bSVasundhara Volam 
3769bec84e6bSVasundhara Volam 	if (cmd.va)
3770bec84e6bSVasundhara Volam 		pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
3771d5c18473SPadmanabh Ratnakar 	return status;
3772d5c18473SPadmanabh Ratnakar }
3773d5c18473SPadmanabh Ratnakar 
3774a401801cSSathya Perla /* Mark all fields invalid */
3775bec84e6bSVasundhara Volam static void be_reset_nic_desc(struct be_nic_res_desc *nic)
3776a401801cSSathya Perla {
3777a401801cSSathya Perla 	memset(nic, 0, sizeof(*nic));
3778a401801cSSathya Perla 	nic->unicast_mac_count = 0xFFFF;
3779a401801cSSathya Perla 	nic->mcc_count = 0xFFFF;
3780a401801cSSathya Perla 	nic->vlan_count = 0xFFFF;
3781a401801cSSathya Perla 	nic->mcast_mac_count = 0xFFFF;
3782a401801cSSathya Perla 	nic->txq_count = 0xFFFF;
3783a401801cSSathya Perla 	nic->rq_count = 0xFFFF;
3784a401801cSSathya Perla 	nic->rssq_count = 0xFFFF;
3785a401801cSSathya Perla 	nic->lro_count = 0xFFFF;
3786a401801cSSathya Perla 	nic->cq_count = 0xFFFF;
3787a401801cSSathya Perla 	nic->toe_conn_count = 0xFFFF;
3788a401801cSSathya Perla 	nic->eq_count = 0xFFFF;
37890f77ba73SRavikumar Nelavelli 	nic->iface_count = 0xFFFF;
3790a401801cSSathya Perla 	nic->link_param = 0xFF;
37910f77ba73SRavikumar Nelavelli 	nic->channel_id_param = cpu_to_le16(0xF000);
3792a401801cSSathya Perla 	nic->acpi_params = 0xFF;
3793a401801cSSathya Perla 	nic->wol_param = 0x0F;
37940f77ba73SRavikumar Nelavelli 	nic->tunnel_iface_count = 0xFFFF;
37950f77ba73SRavikumar Nelavelli 	nic->direct_tenant_iface_count = 0xFFFF;
3796bec84e6bSVasundhara Volam 	nic->bw_min = 0xFFFFFFFF;
3797a401801cSSathya Perla 	nic->bw_max = 0xFFFFFFFF;
3798a401801cSSathya Perla }
3799a401801cSSathya Perla 
3800bec84e6bSVasundhara Volam /* Mark all fields invalid */
3801bec84e6bSVasundhara Volam static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
3802bec84e6bSVasundhara Volam {
3803bec84e6bSVasundhara Volam 	memset(pcie, 0, sizeof(*pcie));
3804bec84e6bSVasundhara Volam 	pcie->sriov_state = 0xFF;
3805bec84e6bSVasundhara Volam 	pcie->pf_state = 0xFF;
3806bec84e6bSVasundhara Volam 	pcie->pf_type = 0xFF;
3807bec84e6bSVasundhara Volam 	pcie->num_vfs = 0xFFFF;
3808bec84e6bSVasundhara Volam }
3809bec84e6bSVasundhara Volam 
38100f77ba73SRavikumar Nelavelli int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
38110f77ba73SRavikumar Nelavelli 		      u8 domain)
3812a401801cSSathya Perla {
3813a401801cSSathya Perla 	struct be_nic_res_desc nic_desc;
38140f77ba73SRavikumar Nelavelli 	u32 bw_percent;
38150f77ba73SRavikumar Nelavelli 	u16 version = 0;
38160f77ba73SRavikumar Nelavelli 
38170f77ba73SRavikumar Nelavelli 	if (BE3_chip(adapter))
38180f77ba73SRavikumar Nelavelli 		return be_cmd_set_qos(adapter, max_rate / 10, domain);
3819a401801cSSathya Perla 
3820a401801cSSathya Perla 	be_reset_nic_desc(&nic_desc);
38210f77ba73SRavikumar Nelavelli 	nic_desc.pf_num = adapter->pf_number;
38220f77ba73SRavikumar Nelavelli 	nic_desc.vf_num = domain;
382358bdeaa6SKalesh AP 	nic_desc.bw_min = 0;
38240f77ba73SRavikumar Nelavelli 	if (lancer_chip(adapter)) {
3825a401801cSSathya Perla 		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
3826a401801cSSathya Perla 		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
3827a401801cSSathya Perla 		nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
3828a401801cSSathya Perla 					(1 << NOSV_SHIFT);
38290f77ba73SRavikumar Nelavelli 		nic_desc.bw_max = cpu_to_le32(max_rate / 10);
38300f77ba73SRavikumar Nelavelli 	} else {
38310f77ba73SRavikumar Nelavelli 		version = 1;
38320f77ba73SRavikumar Nelavelli 		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
38330f77ba73SRavikumar Nelavelli 		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
38340f77ba73SRavikumar Nelavelli 		nic_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
38350f77ba73SRavikumar Nelavelli 		bw_percent = max_rate ? (max_rate * 100) / link_speed : 100;
38360f77ba73SRavikumar Nelavelli 		nic_desc.bw_max = cpu_to_le32(bw_percent);
38370f77ba73SRavikumar Nelavelli 	}
3838a401801cSSathya Perla 
3839a401801cSSathya Perla 	return be_cmd_set_profile_config(adapter, &nic_desc,
38400f77ba73SRavikumar Nelavelli 					 nic_desc.hdr.desc_len,
3841bec84e6bSVasundhara Volam 					 1, version, domain);
3842bec84e6bSVasundhara Volam }
3843bec84e6bSVasundhara Volam 
3844f2858738SVasundhara Volam static void be_fill_vf_res_template(struct be_adapter *adapter,
3845f2858738SVasundhara Volam 				    struct be_resources pool_res,
3846f2858738SVasundhara Volam 				    u16 num_vfs, u16 num_vf_qs,
3847f2858738SVasundhara Volam 				    struct be_nic_res_desc *nic_vft)
3848f2858738SVasundhara Volam {
3849f2858738SVasundhara Volam 	u32 vf_if_cap_flags = pool_res.vf_if_cap_flags;
3850f2858738SVasundhara Volam 	struct be_resources res_mod = {0};
3851f2858738SVasundhara Volam 
3852f2858738SVasundhara Volam 	/* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd,
3853f2858738SVasundhara Volam 	 * which are modifiable using SET_PROFILE_CONFIG cmd.
3854f2858738SVasundhara Volam 	 */
3855f2858738SVasundhara Volam 	be_cmd_get_profile_config(adapter, &res_mod, RESOURCE_MODIFIABLE, 0);
3856f2858738SVasundhara Volam 
3857f2858738SVasundhara Volam 	/* If RSS IFACE capability flags are modifiable for a VF, set the
3858f2858738SVasundhara Volam 	 * capability flag as valid and set RSS and DEFQ_RSS IFACE flags if
3859f2858738SVasundhara Volam 	 * more than 1 RSSQ is available for a VF.
3860f2858738SVasundhara Volam 	 * Otherwise, provision only 1 queue pair for VF.
3861f2858738SVasundhara Volam 	 */
3862f2858738SVasundhara Volam 	if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
3863f2858738SVasundhara Volam 		nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
3864f2858738SVasundhara Volam 		if (num_vf_qs > 1) {
3865f2858738SVasundhara Volam 			vf_if_cap_flags |= BE_IF_FLAGS_RSS;
3866f2858738SVasundhara Volam 			if (pool_res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS)
3867f2858738SVasundhara Volam 				vf_if_cap_flags |= BE_IF_FLAGS_DEFQ_RSS;
3868f2858738SVasundhara Volam 		} else {
3869f2858738SVasundhara Volam 			vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
3870f2858738SVasundhara Volam 					     BE_IF_FLAGS_DEFQ_RSS);
3871f2858738SVasundhara Volam 		}
3872f2858738SVasundhara Volam 
3873f2858738SVasundhara Volam 		nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
3874f2858738SVasundhara Volam 	} else {
3875f2858738SVasundhara Volam 		num_vf_qs = 1;
3876f2858738SVasundhara Volam 	}
3877f2858738SVasundhara Volam 
3878f2858738SVasundhara Volam 	nic_vft->rq_count = cpu_to_le16(num_vf_qs);
3879f2858738SVasundhara Volam 	nic_vft->txq_count = cpu_to_le16(num_vf_qs);
3880f2858738SVasundhara Volam 	nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
3881f2858738SVasundhara Volam 	nic_vft->cq_count = cpu_to_le16(pool_res.max_cq_count /
3882f2858738SVasundhara Volam 					(num_vfs + 1));
3883f2858738SVasundhara Volam 
3884f2858738SVasundhara Volam 	/* Distribute unicast MACs, VLANs, IFACE count and MCCQ count equally
3885f2858738SVasundhara Volam 	 * among the PF and it's VFs, if the fields are changeable
3886f2858738SVasundhara Volam 	 */
3887f2858738SVasundhara Volam 	if (res_mod.max_uc_mac == FIELD_MODIFIABLE)
3888f2858738SVasundhara Volam 		nic_vft->unicast_mac_count = cpu_to_le16(pool_res.max_uc_mac /
3889f2858738SVasundhara Volam 							 (num_vfs + 1));
3890f2858738SVasundhara Volam 
3891f2858738SVasundhara Volam 	if (res_mod.max_vlans == FIELD_MODIFIABLE)
3892f2858738SVasundhara Volam 		nic_vft->vlan_count = cpu_to_le16(pool_res.max_vlans /
3893f2858738SVasundhara Volam 						  (num_vfs + 1));
3894f2858738SVasundhara Volam 
3895f2858738SVasundhara Volam 	if (res_mod.max_iface_count == FIELD_MODIFIABLE)
3896f2858738SVasundhara Volam 		nic_vft->iface_count = cpu_to_le16(pool_res.max_iface_count /
3897f2858738SVasundhara Volam 						   (num_vfs + 1));
3898f2858738SVasundhara Volam 
3899f2858738SVasundhara Volam 	if (res_mod.max_mcc_count == FIELD_MODIFIABLE)
3900f2858738SVasundhara Volam 		nic_vft->mcc_count = cpu_to_le16(pool_res.max_mcc_count /
3901f2858738SVasundhara Volam 						 (num_vfs + 1));
3902f2858738SVasundhara Volam }
3903f2858738SVasundhara Volam 
3904bec84e6bSVasundhara Volam int be_cmd_set_sriov_config(struct be_adapter *adapter,
3905f2858738SVasundhara Volam 			    struct be_resources pool_res, u16 num_vfs,
3906f2858738SVasundhara Volam 			    u16 num_vf_qs)
3907bec84e6bSVasundhara Volam {
3908bec84e6bSVasundhara Volam 	struct {
3909bec84e6bSVasundhara Volam 		struct be_pcie_res_desc pcie;
3910bec84e6bSVasundhara Volam 		struct be_nic_res_desc nic_vft;
3911bec84e6bSVasundhara Volam 	} __packed desc;
3912bec84e6bSVasundhara Volam 
3913bec84e6bSVasundhara Volam 	/* PF PCIE descriptor */
3914bec84e6bSVasundhara Volam 	be_reset_pcie_desc(&desc.pcie);
3915bec84e6bSVasundhara Volam 	desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
3916bec84e6bSVasundhara Volam 	desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3917f2858738SVasundhara Volam 	desc.pcie.flags = BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
3918bec84e6bSVasundhara Volam 	desc.pcie.pf_num = adapter->pdev->devfn;
3919bec84e6bSVasundhara Volam 	desc.pcie.sriov_state = num_vfs ? 1 : 0;
3920bec84e6bSVasundhara Volam 	desc.pcie.num_vfs = cpu_to_le16(num_vfs);
3921bec84e6bSVasundhara Volam 
3922bec84e6bSVasundhara Volam 	/* VF NIC Template descriptor */
3923bec84e6bSVasundhara Volam 	be_reset_nic_desc(&desc.nic_vft);
3924bec84e6bSVasundhara Volam 	desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
3925bec84e6bSVasundhara Volam 	desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3926f2858738SVasundhara Volam 	desc.nic_vft.flags = BIT(VFT_SHIFT) | BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
3927bec84e6bSVasundhara Volam 	desc.nic_vft.pf_num = adapter->pdev->devfn;
3928bec84e6bSVasundhara Volam 	desc.nic_vft.vf_num = 0;
3929bec84e6bSVasundhara Volam 
3930f2858738SVasundhara Volam 	be_fill_vf_res_template(adapter, pool_res, num_vfs, num_vf_qs,
3931f2858738SVasundhara Volam 				&desc.nic_vft);
3932bec84e6bSVasundhara Volam 
3933bec84e6bSVasundhara Volam 	return be_cmd_set_profile_config(adapter, &desc,
3934bec84e6bSVasundhara Volam 					 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
3935a401801cSSathya Perla }
3936a401801cSSathya Perla 
3937a401801cSSathya Perla int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
3938a401801cSSathya Perla {
3939a401801cSSathya Perla 	struct be_mcc_wrb *wrb;
3940a401801cSSathya Perla 	struct be_cmd_req_manage_iface_filters *req;
3941a401801cSSathya Perla 	int status;
3942a401801cSSathya Perla 
3943a401801cSSathya Perla 	if (iface == 0xFFFFFFFF)
3944a401801cSSathya Perla 		return -1;
3945a401801cSSathya Perla 
3946a401801cSSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
3947a401801cSSathya Perla 
3948a401801cSSathya Perla 	wrb = wrb_from_mccq(adapter);
3949a401801cSSathya Perla 	if (!wrb) {
3950a401801cSSathya Perla 		status = -EBUSY;
3951a401801cSSathya Perla 		goto err;
3952a401801cSSathya Perla 	}
3953a401801cSSathya Perla 	req = embedded_payload(wrb);
3954a401801cSSathya Perla 
3955a401801cSSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3956a401801cSSathya Perla 			       OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req),
3957a401801cSSathya Perla 			       wrb, NULL);
3958a401801cSSathya Perla 	req->op = op;
3959a401801cSSathya Perla 	req->target_iface_id = cpu_to_le32(iface);
3960a401801cSSathya Perla 
3961a401801cSSathya Perla 	status = be_mcc_notify_wait(adapter);
3962a401801cSSathya Perla err:
3963a401801cSSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
3964a401801cSSathya Perla 	return status;
3965a401801cSSathya Perla }
3966a401801cSSathya Perla 
3967a401801cSSathya Perla int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
3968a401801cSSathya Perla {
3969a401801cSSathya Perla 	struct be_port_res_desc port_desc;
3970a401801cSSathya Perla 
3971a401801cSSathya Perla 	memset(&port_desc, 0, sizeof(port_desc));
3972a401801cSSathya Perla 	port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1;
3973a401801cSSathya Perla 	port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3974a401801cSSathya Perla 	port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
3975a401801cSSathya Perla 	port_desc.link_num = adapter->hba_port_num;
3976a401801cSSathya Perla 	if (port) {
3977a401801cSSathya Perla 		port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) |
3978a401801cSSathya Perla 					(1 << RCVID_SHIFT);
3979a401801cSSathya Perla 		port_desc.nv_port = swab16(port);
3980a401801cSSathya Perla 	} else {
3981a401801cSSathya Perla 		port_desc.nv_flags = NV_TYPE_DISABLED;
3982a401801cSSathya Perla 		port_desc.nv_port = 0;
3983a401801cSSathya Perla 	}
3984a401801cSSathya Perla 
3985a401801cSSathya Perla 	return be_cmd_set_profile_config(adapter, &port_desc,
3986bec84e6bSVasundhara Volam 					 RESOURCE_DESC_SIZE_V1, 1, 1, 0);
3987a401801cSSathya Perla }
3988a401801cSSathya Perla 
39894c876616SSathya Perla int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
39904c876616SSathya Perla 		     int vf_num)
39914c876616SSathya Perla {
39924c876616SSathya Perla 	struct be_mcc_wrb *wrb;
39934c876616SSathya Perla 	struct be_cmd_req_get_iface_list *req;
39944c876616SSathya Perla 	struct be_cmd_resp_get_iface_list *resp;
39954c876616SSathya Perla 	int status;
39964c876616SSathya Perla 
39974c876616SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
39984c876616SSathya Perla 
39994c876616SSathya Perla 	wrb = wrb_from_mccq(adapter);
40004c876616SSathya Perla 	if (!wrb) {
40014c876616SSathya Perla 		status = -EBUSY;
40024c876616SSathya Perla 		goto err;
40034c876616SSathya Perla 	}
40044c876616SSathya Perla 	req = embedded_payload(wrb);
40054c876616SSathya Perla 
40064c876616SSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
40074c876616SSathya Perla 			       OPCODE_COMMON_GET_IFACE_LIST, sizeof(*resp),
40084c876616SSathya Perla 			       wrb, NULL);
40094c876616SSathya Perla 	req->hdr.domain = vf_num + 1;
40104c876616SSathya Perla 
40114c876616SSathya Perla 	status = be_mcc_notify_wait(adapter);
40124c876616SSathya Perla 	if (!status) {
40134c876616SSathya Perla 		resp = (struct be_cmd_resp_get_iface_list *)req;
40144c876616SSathya Perla 		vf_cfg->if_handle = le32_to_cpu(resp->if_desc.if_id);
40154c876616SSathya Perla 	}
40164c876616SSathya Perla 
40174c876616SSathya Perla err:
40184c876616SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
40194c876616SSathya Perla 	return status;
40204c876616SSathya Perla }
40214c876616SSathya Perla 
40225c510811SSomnath Kotur static int lancer_wait_idle(struct be_adapter *adapter)
40235c510811SSomnath Kotur {
40245c510811SSomnath Kotur #define SLIPORT_IDLE_TIMEOUT 30
40255c510811SSomnath Kotur 	u32 reg_val;
40265c510811SSomnath Kotur 	int status = 0, i;
40275c510811SSomnath Kotur 
40285c510811SSomnath Kotur 	for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
40295c510811SSomnath Kotur 		reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
40305c510811SSomnath Kotur 		if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
40315c510811SSomnath Kotur 			break;
40325c510811SSomnath Kotur 
40335c510811SSomnath Kotur 		ssleep(1);
40345c510811SSomnath Kotur 	}
40355c510811SSomnath Kotur 
40365c510811SSomnath Kotur 	if (i == SLIPORT_IDLE_TIMEOUT)
40375c510811SSomnath Kotur 		status = -1;
40385c510811SSomnath Kotur 
40395c510811SSomnath Kotur 	return status;
40405c510811SSomnath Kotur }
40415c510811SSomnath Kotur 
40425c510811SSomnath Kotur int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
40435c510811SSomnath Kotur {
40445c510811SSomnath Kotur 	int status = 0;
40455c510811SSomnath Kotur 
40465c510811SSomnath Kotur 	status = lancer_wait_idle(adapter);
40475c510811SSomnath Kotur 	if (status)
40485c510811SSomnath Kotur 		return status;
40495c510811SSomnath Kotur 
40505c510811SSomnath Kotur 	iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);
40515c510811SSomnath Kotur 
40525c510811SSomnath Kotur 	return status;
40535c510811SSomnath Kotur }
40545c510811SSomnath Kotur 
40555c510811SSomnath Kotur /* Routine to check whether dump image is present or not */
40565c510811SSomnath Kotur bool dump_present(struct be_adapter *adapter)
40575c510811SSomnath Kotur {
40585c510811SSomnath Kotur 	u32 sliport_status = 0;
40595c510811SSomnath Kotur 
40605c510811SSomnath Kotur 	sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
40615c510811SSomnath Kotur 	return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
40625c510811SSomnath Kotur }
40635c510811SSomnath Kotur 
40645c510811SSomnath Kotur int lancer_initiate_dump(struct be_adapter *adapter)
40655c510811SSomnath Kotur {
4066f0613380SKalesh AP 	struct device *dev = &adapter->pdev->dev;
40675c510811SSomnath Kotur 	int status;
40685c510811SSomnath Kotur 
4069f0613380SKalesh AP 	if (dump_present(adapter)) {
4070f0613380SKalesh AP 		dev_info(dev, "Previous dump not cleared, not forcing dump\n");
4071f0613380SKalesh AP 		return -EEXIST;
4072f0613380SKalesh AP 	}
4073f0613380SKalesh AP 
40745c510811SSomnath Kotur 	/* give firmware reset and diagnostic dump */
40755c510811SSomnath Kotur 	status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
40765c510811SSomnath Kotur 				     PHYSDEV_CONTROL_DD_MASK);
40775c510811SSomnath Kotur 	if (status < 0) {
4078f0613380SKalesh AP 		dev_err(dev, "FW reset failed\n");
40795c510811SSomnath Kotur 		return status;
40805c510811SSomnath Kotur 	}
40815c510811SSomnath Kotur 
40825c510811SSomnath Kotur 	status = lancer_wait_idle(adapter);
40835c510811SSomnath Kotur 	if (status)
40845c510811SSomnath Kotur 		return status;
40855c510811SSomnath Kotur 
40865c510811SSomnath Kotur 	if (!dump_present(adapter)) {
4087f0613380SKalesh AP 		dev_err(dev, "FW dump not generated\n");
4088f0613380SKalesh AP 		return -EIO;
40895c510811SSomnath Kotur 	}
40905c510811SSomnath Kotur 
40915c510811SSomnath Kotur 	return 0;
40925c510811SSomnath Kotur }
40935c510811SSomnath Kotur 
4094f0613380SKalesh AP int lancer_delete_dump(struct be_adapter *adapter)
4095f0613380SKalesh AP {
4096f0613380SKalesh AP 	int status;
4097f0613380SKalesh AP 
4098f0613380SKalesh AP 	status = lancer_cmd_delete_object(adapter, LANCER_FW_DUMP_FILE);
4099f0613380SKalesh AP 	return be_cmd_status(status);
4100f0613380SKalesh AP }
4101f0613380SKalesh AP 
4102dcf7ebbaSPadmanabh Ratnakar /* Uses sync mcc */
4103dcf7ebbaSPadmanabh Ratnakar int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
4104dcf7ebbaSPadmanabh Ratnakar {
4105dcf7ebbaSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
4106dcf7ebbaSPadmanabh Ratnakar 	struct be_cmd_enable_disable_vf *req;
4107dcf7ebbaSPadmanabh Ratnakar 	int status;
4108dcf7ebbaSPadmanabh Ratnakar 
41090599863dSVasundhara Volam 	if (BEx_chip(adapter))
4110dcf7ebbaSPadmanabh Ratnakar 		return 0;
4111dcf7ebbaSPadmanabh Ratnakar 
4112dcf7ebbaSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
4113dcf7ebbaSPadmanabh Ratnakar 
4114dcf7ebbaSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
4115dcf7ebbaSPadmanabh Ratnakar 	if (!wrb) {
4116dcf7ebbaSPadmanabh Ratnakar 		status = -EBUSY;
4117dcf7ebbaSPadmanabh Ratnakar 		goto err;
4118dcf7ebbaSPadmanabh Ratnakar 	}
4119dcf7ebbaSPadmanabh Ratnakar 
4120dcf7ebbaSPadmanabh Ratnakar 	req = embedded_payload(wrb);
4121dcf7ebbaSPadmanabh Ratnakar 
4122dcf7ebbaSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4123dcf7ebbaSPadmanabh Ratnakar 			       OPCODE_COMMON_ENABLE_DISABLE_VF, sizeof(*req),
4124dcf7ebbaSPadmanabh Ratnakar 			       wrb, NULL);
4125dcf7ebbaSPadmanabh Ratnakar 
4126dcf7ebbaSPadmanabh Ratnakar 	req->hdr.domain = domain;
4127dcf7ebbaSPadmanabh Ratnakar 	req->enable = 1;
4128dcf7ebbaSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
4129dcf7ebbaSPadmanabh Ratnakar err:
4130dcf7ebbaSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
4131dcf7ebbaSPadmanabh Ratnakar 	return status;
4132dcf7ebbaSPadmanabh Ratnakar }
4133dcf7ebbaSPadmanabh Ratnakar 
413468c45a2dSSomnath Kotur int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
413568c45a2dSSomnath Kotur {
413668c45a2dSSomnath Kotur 	struct be_mcc_wrb *wrb;
413768c45a2dSSomnath Kotur 	struct be_cmd_req_intr_set *req;
413868c45a2dSSomnath Kotur 	int status;
413968c45a2dSSomnath Kotur 
414068c45a2dSSomnath Kotur 	if (mutex_lock_interruptible(&adapter->mbox_lock))
414168c45a2dSSomnath Kotur 		return -1;
414268c45a2dSSomnath Kotur 
414368c45a2dSSomnath Kotur 	wrb = wrb_from_mbox(adapter);
414468c45a2dSSomnath Kotur 
414568c45a2dSSomnath Kotur 	req = embedded_payload(wrb);
414668c45a2dSSomnath Kotur 
414768c45a2dSSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
414868c45a2dSSomnath Kotur 			       OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req),
414968c45a2dSSomnath Kotur 			       wrb, NULL);
415068c45a2dSSomnath Kotur 
415168c45a2dSSomnath Kotur 	req->intr_enabled = intr_enable;
415268c45a2dSSomnath Kotur 
415368c45a2dSSomnath Kotur 	status = be_mbox_notify_wait(adapter);
415468c45a2dSSomnath Kotur 
415568c45a2dSSomnath Kotur 	mutex_unlock(&adapter->mbox_lock);
415668c45a2dSSomnath Kotur 	return status;
415768c45a2dSSomnath Kotur }
415868c45a2dSSomnath Kotur 
4159542963b7SVasundhara Volam /* Uses MBOX */
4160542963b7SVasundhara Volam int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile_id)
4161542963b7SVasundhara Volam {
4162542963b7SVasundhara Volam 	struct be_cmd_req_get_active_profile *req;
4163542963b7SVasundhara Volam 	struct be_mcc_wrb *wrb;
4164542963b7SVasundhara Volam 	int status;
4165542963b7SVasundhara Volam 
4166542963b7SVasundhara Volam 	if (mutex_lock_interruptible(&adapter->mbox_lock))
4167542963b7SVasundhara Volam 		return -1;
4168542963b7SVasundhara Volam 
4169542963b7SVasundhara Volam 	wrb = wrb_from_mbox(adapter);
4170542963b7SVasundhara Volam 	if (!wrb) {
4171542963b7SVasundhara Volam 		status = -EBUSY;
4172542963b7SVasundhara Volam 		goto err;
4173542963b7SVasundhara Volam 	}
4174542963b7SVasundhara Volam 
4175542963b7SVasundhara Volam 	req = embedded_payload(wrb);
4176542963b7SVasundhara Volam 
4177542963b7SVasundhara Volam 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4178542963b7SVasundhara Volam 			       OPCODE_COMMON_GET_ACTIVE_PROFILE, sizeof(*req),
4179542963b7SVasundhara Volam 			       wrb, NULL);
4180542963b7SVasundhara Volam 
4181542963b7SVasundhara Volam 	status = be_mbox_notify_wait(adapter);
4182542963b7SVasundhara Volam 	if (!status) {
4183542963b7SVasundhara Volam 		struct be_cmd_resp_get_active_profile *resp =
4184542963b7SVasundhara Volam 							embedded_payload(wrb);
418503d28ffeSKalesh AP 
4186542963b7SVasundhara Volam 		*profile_id = le16_to_cpu(resp->active_profile_id);
4187542963b7SVasundhara Volam 	}
4188542963b7SVasundhara Volam 
4189542963b7SVasundhara Volam err:
4190542963b7SVasundhara Volam 	mutex_unlock(&adapter->mbox_lock);
4191542963b7SVasundhara Volam 	return status;
4192542963b7SVasundhara Volam }
4193542963b7SVasundhara Volam 
4194bdce2ad7SSuresh Reddy int be_cmd_set_logical_link_config(struct be_adapter *adapter,
4195bdce2ad7SSuresh Reddy 				   int link_state, u8 domain)
4196bdce2ad7SSuresh Reddy {
4197bdce2ad7SSuresh Reddy 	struct be_mcc_wrb *wrb;
4198bdce2ad7SSuresh Reddy 	struct be_cmd_req_set_ll_link *req;
4199bdce2ad7SSuresh Reddy 	int status;
4200bdce2ad7SSuresh Reddy 
4201bdce2ad7SSuresh Reddy 	if (BEx_chip(adapter) || lancer_chip(adapter))
420218fd6025SKalesh AP 		return -EOPNOTSUPP;
4203bdce2ad7SSuresh Reddy 
4204bdce2ad7SSuresh Reddy 	spin_lock_bh(&adapter->mcc_lock);
4205bdce2ad7SSuresh Reddy 
4206bdce2ad7SSuresh Reddy 	wrb = wrb_from_mccq(adapter);
4207bdce2ad7SSuresh Reddy 	if (!wrb) {
4208bdce2ad7SSuresh Reddy 		status = -EBUSY;
4209bdce2ad7SSuresh Reddy 		goto err;
4210bdce2ad7SSuresh Reddy 	}
4211bdce2ad7SSuresh Reddy 
4212bdce2ad7SSuresh Reddy 	req = embedded_payload(wrb);
4213bdce2ad7SSuresh Reddy 
4214bdce2ad7SSuresh Reddy 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4215bdce2ad7SSuresh Reddy 			       OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG,
4216bdce2ad7SSuresh Reddy 			       sizeof(*req), wrb, NULL);
4217bdce2ad7SSuresh Reddy 
4218bdce2ad7SSuresh Reddy 	req->hdr.version = 1;
4219bdce2ad7SSuresh Reddy 	req->hdr.domain = domain;
4220bdce2ad7SSuresh Reddy 
4221bdce2ad7SSuresh Reddy 	if (link_state == IFLA_VF_LINK_STATE_ENABLE)
4222bdce2ad7SSuresh Reddy 		req->link_config |= 1;
4223bdce2ad7SSuresh Reddy 
4224bdce2ad7SSuresh Reddy 	if (link_state == IFLA_VF_LINK_STATE_AUTO)
4225bdce2ad7SSuresh Reddy 		req->link_config |= 1 << PLINK_TRACK_SHIFT;
4226bdce2ad7SSuresh Reddy 
4227bdce2ad7SSuresh Reddy 	status = be_mcc_notify_wait(adapter);
4228bdce2ad7SSuresh Reddy err:
4229bdce2ad7SSuresh Reddy 	spin_unlock_bh(&adapter->mcc_lock);
4230bdce2ad7SSuresh Reddy 	return status;
4231bdce2ad7SSuresh Reddy }
4232bdce2ad7SSuresh Reddy 
42336a4ab669SParav Pandit int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
42346a4ab669SParav Pandit 		    int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
42356a4ab669SParav Pandit {
42366a4ab669SParav Pandit 	struct be_adapter *adapter = netdev_priv(netdev_handle);
42376a4ab669SParav Pandit 	struct be_mcc_wrb *wrb;
42386a4ab669SParav Pandit 	struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *)wrb_payload;
42396a4ab669SParav Pandit 	struct be_cmd_req_hdr *req;
42406a4ab669SParav Pandit 	struct be_cmd_resp_hdr *resp;
42416a4ab669SParav Pandit 	int status;
42426a4ab669SParav Pandit 
42436a4ab669SParav Pandit 	spin_lock_bh(&adapter->mcc_lock);
42446a4ab669SParav Pandit 
42456a4ab669SParav Pandit 	wrb = wrb_from_mccq(adapter);
42466a4ab669SParav Pandit 	if (!wrb) {
42476a4ab669SParav Pandit 		status = -EBUSY;
42486a4ab669SParav Pandit 		goto err;
42496a4ab669SParav Pandit 	}
42506a4ab669SParav Pandit 	req = embedded_payload(wrb);
42516a4ab669SParav Pandit 	resp = embedded_payload(wrb);
42526a4ab669SParav Pandit 
42536a4ab669SParav Pandit 	be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
42546a4ab669SParav Pandit 			       hdr->opcode, wrb_payload_size, wrb, NULL);
42556a4ab669SParav Pandit 	memcpy(req, wrb_payload, wrb_payload_size);
42566a4ab669SParav Pandit 	be_dws_cpu_to_le(req, wrb_payload_size);
42576a4ab669SParav Pandit 
42586a4ab669SParav Pandit 	status = be_mcc_notify_wait(adapter);
42596a4ab669SParav Pandit 	if (cmd_status)
42606a4ab669SParav Pandit 		*cmd_status = (status & 0xffff);
42616a4ab669SParav Pandit 	if (ext_status)
42626a4ab669SParav Pandit 		*ext_status = 0;
42636a4ab669SParav Pandit 	memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
42646a4ab669SParav Pandit 	be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
42656a4ab669SParav Pandit err:
42666a4ab669SParav Pandit 	spin_unlock_bh(&adapter->mcc_lock);
42676a4ab669SParav Pandit 	return status;
42686a4ab669SParav Pandit }
42696a4ab669SParav Pandit EXPORT_SYMBOL(be_roce_mcc_cmd);
4270