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 
91efaa408eSSuresh Reddy static int 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))
97efaa408eSSuresh Reddy 		return -EIO;
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);
104efaa408eSSuresh Reddy 
105efaa408eSSuresh Reddy 	return 0;
1069aebddd1SJeff Kirsher }
1079aebddd1SJeff Kirsher 
1089aebddd1SJeff Kirsher /* To check if valid bit is set, check the entire word as we don't know
1099aebddd1SJeff Kirsher  * the endianness of the data (old entry is host endian while a new entry is
1109aebddd1SJeff Kirsher  * little endian) */
1119aebddd1SJeff Kirsher static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
1129aebddd1SJeff Kirsher {
1139e9ff4b7SSathya Perla 	u32 flags;
1149e9ff4b7SSathya Perla 
1159aebddd1SJeff Kirsher 	if (compl->flags != 0) {
1169e9ff4b7SSathya Perla 		flags = le32_to_cpu(compl->flags);
1179e9ff4b7SSathya Perla 		if (flags & CQE_FLAGS_VALID_MASK) {
1189e9ff4b7SSathya Perla 			compl->flags = flags;
1199aebddd1SJeff Kirsher 			return true;
1209aebddd1SJeff Kirsher 		}
1219aebddd1SJeff Kirsher 	}
1229e9ff4b7SSathya Perla 	return false;
1239e9ff4b7SSathya Perla }
1249aebddd1SJeff Kirsher 
1259aebddd1SJeff Kirsher /* Need to reset the entire word that houses the valid bit */
1269aebddd1SJeff Kirsher static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
1279aebddd1SJeff Kirsher {
1289aebddd1SJeff Kirsher 	compl->flags = 0;
1299aebddd1SJeff Kirsher }
1309aebddd1SJeff Kirsher 
131652bf646SPadmanabh Ratnakar static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
132652bf646SPadmanabh Ratnakar {
133652bf646SPadmanabh Ratnakar 	unsigned long addr;
134652bf646SPadmanabh Ratnakar 
135652bf646SPadmanabh Ratnakar 	addr = tag1;
136652bf646SPadmanabh Ratnakar 	addr = ((addr << 16) << 16) | tag0;
137652bf646SPadmanabh Ratnakar 	return (void *)addr;
138652bf646SPadmanabh Ratnakar }
139652bf646SPadmanabh Ratnakar 
1404c60005fSKalesh AP static bool be_skip_err_log(u8 opcode, u16 base_status, u16 addl_status)
1414c60005fSKalesh AP {
1424c60005fSKalesh AP 	if (base_status == MCC_STATUS_NOT_SUPPORTED ||
1434c60005fSKalesh AP 	    base_status == MCC_STATUS_ILLEGAL_REQUEST ||
1444c60005fSKalesh AP 	    addl_status == MCC_ADDL_STATUS_TOO_MANY_INTERFACES ||
14577be8c1cSKalesh AP 	    addl_status == MCC_ADDL_STATUS_INSUFFICIENT_VLANS ||
1464c60005fSKalesh AP 	    (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
1474c60005fSKalesh AP 	    (base_status == MCC_STATUS_ILLEGAL_FIELD ||
1484c60005fSKalesh AP 	     addl_status == MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH)))
1494c60005fSKalesh AP 		return true;
1504c60005fSKalesh AP 	else
1514c60005fSKalesh AP 		return false;
1524c60005fSKalesh AP }
1534c60005fSKalesh AP 
154559b633fSSathya Perla /* Place holder for all the async MCC cmds wherein the caller is not in a busy
155559b633fSSathya Perla  * loop (has not issued be_mcc_notify_wait())
156559b633fSSathya Perla  */
157559b633fSSathya Perla static void be_async_cmd_process(struct be_adapter *adapter,
158559b633fSSathya Perla 				 struct be_mcc_compl *compl,
159559b633fSSathya Perla 				 struct be_cmd_resp_hdr *resp_hdr)
160559b633fSSathya Perla {
161559b633fSSathya Perla 	enum mcc_base_status base_status = base_status(compl->status);
162559b633fSSathya Perla 	u8 opcode = 0, subsystem = 0;
163559b633fSSathya Perla 
164559b633fSSathya Perla 	if (resp_hdr) {
165559b633fSSathya Perla 		opcode = resp_hdr->opcode;
166559b633fSSathya Perla 		subsystem = resp_hdr->subsystem;
167559b633fSSathya Perla 	}
168559b633fSSathya Perla 
169559b633fSSathya Perla 	if (opcode == OPCODE_LOWLEVEL_LOOPBACK_TEST &&
170559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
171559b633fSSathya Perla 		complete(&adapter->et_cmd_compl);
172559b633fSSathya Perla 		return;
173559b633fSSathya Perla 	}
174559b633fSSathya Perla 
1759c855975SSuresh Reddy 	if (opcode == OPCODE_LOWLEVEL_SET_LOOPBACK_MODE &&
1769c855975SSuresh Reddy 	    subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
1779c855975SSuresh Reddy 		complete(&adapter->et_cmd_compl);
1789c855975SSuresh Reddy 		return;
1799c855975SSuresh Reddy 	}
1809c855975SSuresh Reddy 
181559b633fSSathya Perla 	if ((opcode == OPCODE_COMMON_WRITE_FLASHROM ||
182559b633fSSathya Perla 	     opcode == OPCODE_COMMON_WRITE_OBJECT) &&
183559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_COMMON) {
184559b633fSSathya Perla 		adapter->flash_status = compl->status;
185559b633fSSathya Perla 		complete(&adapter->et_cmd_compl);
186559b633fSSathya Perla 		return;
187559b633fSSathya Perla 	}
188559b633fSSathya Perla 
189559b633fSSathya Perla 	if ((opcode == OPCODE_ETH_GET_STATISTICS ||
190559b633fSSathya Perla 	     opcode == OPCODE_ETH_GET_PPORT_STATS) &&
191559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_ETH &&
192559b633fSSathya Perla 	    base_status == MCC_STATUS_SUCCESS) {
193559b633fSSathya Perla 		be_parse_stats(adapter);
194559b633fSSathya Perla 		adapter->stats_cmd_sent = false;
195559b633fSSathya Perla 		return;
196559b633fSSathya Perla 	}
197559b633fSSathya Perla 
198559b633fSSathya Perla 	if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
199559b633fSSathya Perla 	    subsystem == CMD_SUBSYSTEM_COMMON) {
200559b633fSSathya Perla 		if (base_status == MCC_STATUS_SUCCESS) {
201559b633fSSathya Perla 			struct be_cmd_resp_get_cntl_addnl_attribs *resp =
202559b633fSSathya Perla 							(void *)resp_hdr;
20329e9122bSVenkata Duvvuru 			adapter->hwmon_info.be_on_die_temp =
204559b633fSSathya Perla 						resp->on_die_temperature;
205559b633fSSathya Perla 		} else {
206559b633fSSathya Perla 			adapter->be_get_temp_freq = 0;
20729e9122bSVenkata Duvvuru 			adapter->hwmon_info.be_on_die_temp =
20829e9122bSVenkata Duvvuru 						BE_INVALID_DIE_TEMP;
209559b633fSSathya Perla 		}
210559b633fSSathya Perla 		return;
211559b633fSSathya Perla 	}
212559b633fSSathya Perla }
213559b633fSSathya Perla 
2149aebddd1SJeff Kirsher static int be_mcc_compl_process(struct be_adapter *adapter,
2159aebddd1SJeff Kirsher 				struct be_mcc_compl *compl)
2169aebddd1SJeff Kirsher {
2174c60005fSKalesh AP 	enum mcc_base_status base_status;
2184c60005fSKalesh AP 	enum mcc_addl_status addl_status;
219652bf646SPadmanabh Ratnakar 	struct be_cmd_resp_hdr *resp_hdr;
220652bf646SPadmanabh Ratnakar 	u8 opcode = 0, subsystem = 0;
2219aebddd1SJeff Kirsher 
2229aebddd1SJeff Kirsher 	/* Just swap the status to host endian; mcc tag is opaquely copied
2239aebddd1SJeff Kirsher 	 * from mcc_wrb */
2249aebddd1SJeff Kirsher 	be_dws_le_to_cpu(compl, 4);
2259aebddd1SJeff Kirsher 
2264c60005fSKalesh AP 	base_status = base_status(compl->status);
2274c60005fSKalesh AP 	addl_status = addl_status(compl->status);
22896c9b2e4SVasundhara Volam 
229652bf646SPadmanabh Ratnakar 	resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
230652bf646SPadmanabh Ratnakar 	if (resp_hdr) {
231652bf646SPadmanabh Ratnakar 		opcode = resp_hdr->opcode;
232652bf646SPadmanabh Ratnakar 		subsystem = resp_hdr->subsystem;
233652bf646SPadmanabh Ratnakar 	}
234652bf646SPadmanabh Ratnakar 
235559b633fSSathya Perla 	be_async_cmd_process(adapter, compl, resp_hdr);
2365eeff635SSuresh Reddy 
237559b633fSSathya Perla 	if (base_status != MCC_STATUS_SUCCESS &&
238559b633fSSathya Perla 	    !be_skip_err_log(opcode, base_status, addl_status)) {
2394c60005fSKalesh AP 		if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
24097f1d8cdSVasundhara Volam 			dev_warn(&adapter->pdev->dev,
241522609f2SVasundhara Volam 				 "VF is not privileged to issue opcode %d-%d\n",
24297f1d8cdSVasundhara Volam 				 opcode, subsystem);
2439aebddd1SJeff Kirsher 		} else {
24497f1d8cdSVasundhara Volam 			dev_err(&adapter->pdev->dev,
24597f1d8cdSVasundhara Volam 				"opcode %d-%d failed:status %d-%d\n",
2464c60005fSKalesh AP 				opcode, subsystem, base_status, addl_status);
2479aebddd1SJeff Kirsher 		}
2489aebddd1SJeff Kirsher 	}
2494c60005fSKalesh AP 	return compl->status;
2509aebddd1SJeff Kirsher }
2519aebddd1SJeff Kirsher 
2529aebddd1SJeff Kirsher /* Link state evt is a string of bytes; no need for endian swapping */
2539aebddd1SJeff Kirsher static void be_async_link_state_process(struct be_adapter *adapter,
2543acf19d9SSathya Perla 					struct be_mcc_compl *compl)
2559aebddd1SJeff Kirsher {
2563acf19d9SSathya Perla 	struct be_async_event_link_state *evt =
2573acf19d9SSathya Perla 			(struct be_async_event_link_state *)compl;
2583acf19d9SSathya Perla 
259b236916aSAjit Khaparde 	/* When link status changes, link speed must be re-queried from FW */
26042f11cf2SAjit Khaparde 	adapter->phy.link_speed = -1;
261b236916aSAjit Khaparde 
262bdce2ad7SSuresh Reddy 	/* On BEx the FW does not send a separate link status
263bdce2ad7SSuresh Reddy 	 * notification for physical and logical link.
264bdce2ad7SSuresh Reddy 	 * On other chips just process the logical link
265bdce2ad7SSuresh Reddy 	 * status notification
266bdce2ad7SSuresh Reddy 	 */
267bdce2ad7SSuresh Reddy 	if (!BEx_chip(adapter) &&
2682e177a5cSPadmanabh Ratnakar 	    !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK))
2692e177a5cSPadmanabh Ratnakar 		return;
2702e177a5cSPadmanabh Ratnakar 
271b236916aSAjit Khaparde 	/* For the initial link status do not rely on the ASYNC event as
272b236916aSAjit Khaparde 	 * it may not be received in some cases.
273b236916aSAjit Khaparde 	 */
274b236916aSAjit Khaparde 	if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
275bdce2ad7SSuresh Reddy 		be_link_status_update(adapter,
276bdce2ad7SSuresh Reddy 				      evt->port_link_status & LINK_STATUS_MASK);
2779aebddd1SJeff Kirsher }
2789aebddd1SJeff Kirsher 
27921252377SVasundhara Volam static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
28021252377SVasundhara Volam 						  struct be_mcc_compl *compl)
28121252377SVasundhara Volam {
28221252377SVasundhara Volam 	struct be_async_event_misconfig_port *evt =
28321252377SVasundhara Volam 			(struct be_async_event_misconfig_port *)compl;
28421252377SVasundhara Volam 	u32 sfp_mismatch_evt = le32_to_cpu(evt->event_data_word1);
28521252377SVasundhara Volam 	struct device *dev = &adapter->pdev->dev;
28621252377SVasundhara Volam 	u8 port_misconfig_evt;
28721252377SVasundhara Volam 
28821252377SVasundhara Volam 	port_misconfig_evt =
28921252377SVasundhara Volam 		((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
29021252377SVasundhara Volam 
29121252377SVasundhara Volam 	/* Log an error message that would allow a user to determine
29221252377SVasundhara Volam 	 * whether the SFPs have an issue
29321252377SVasundhara Volam 	 */
29421252377SVasundhara Volam 	dev_info(dev, "Port %c: %s %s", adapter->port_name,
29521252377SVasundhara Volam 		 be_port_misconfig_evt_desc[port_misconfig_evt],
29621252377SVasundhara Volam 		 be_port_misconfig_remedy_desc[port_misconfig_evt]);
29721252377SVasundhara Volam 
29821252377SVasundhara Volam 	if (port_misconfig_evt == INCOMPATIBLE_SFP)
29921252377SVasundhara Volam 		adapter->flags |= BE_FLAGS_EVT_INCOMPATIBLE_SFP;
30021252377SVasundhara Volam }
30121252377SVasundhara Volam 
3029aebddd1SJeff Kirsher /* Grp5 CoS Priority evt */
3039aebddd1SJeff Kirsher static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
3043acf19d9SSathya Perla 					       struct be_mcc_compl *compl)
3059aebddd1SJeff Kirsher {
3063acf19d9SSathya Perla 	struct be_async_event_grp5_cos_priority *evt =
3073acf19d9SSathya Perla 			(struct be_async_event_grp5_cos_priority *)compl;
3083acf19d9SSathya Perla 
3099aebddd1SJeff Kirsher 	if (evt->valid) {
3109aebddd1SJeff Kirsher 		adapter->vlan_prio_bmap = evt->available_priority_bmap;
3119aebddd1SJeff Kirsher 		adapter->recommended_prio &= ~VLAN_PRIO_MASK;
3129aebddd1SJeff Kirsher 		adapter->recommended_prio =
3139aebddd1SJeff Kirsher 			evt->reco_default_priority << VLAN_PRIO_SHIFT;
3149aebddd1SJeff Kirsher 	}
3159aebddd1SJeff Kirsher }
3169aebddd1SJeff Kirsher 
317323ff71eSSathya Perla /* Grp5 QOS Speed evt: qos_link_speed is in units of 10 Mbps */
3189aebddd1SJeff Kirsher static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
3193acf19d9SSathya Perla 					    struct be_mcc_compl *compl)
3209aebddd1SJeff Kirsher {
3213acf19d9SSathya Perla 	struct be_async_event_grp5_qos_link_speed *evt =
3223acf19d9SSathya Perla 			(struct be_async_event_grp5_qos_link_speed *)compl;
3233acf19d9SSathya Perla 
324323ff71eSSathya Perla 	if (adapter->phy.link_speed >= 0 &&
325323ff71eSSathya Perla 	    evt->physical_port == adapter->port_num)
326323ff71eSSathya Perla 		adapter->phy.link_speed = le16_to_cpu(evt->qos_link_speed) * 10;
3279aebddd1SJeff Kirsher }
3289aebddd1SJeff Kirsher 
3299aebddd1SJeff Kirsher /*Grp5 PVID evt*/
3309aebddd1SJeff Kirsher static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
3313acf19d9SSathya Perla 					     struct be_mcc_compl *compl)
3329aebddd1SJeff Kirsher {
3333acf19d9SSathya Perla 	struct be_async_event_grp5_pvid_state *evt =
3343acf19d9SSathya Perla 			(struct be_async_event_grp5_pvid_state *)compl;
3353acf19d9SSathya Perla 
336bdac85b5SRavikumar Nelavelli 	if (evt->enabled) {
337939cf306SSomnath Kotur 		adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK;
338bdac85b5SRavikumar Nelavelli 		dev_info(&adapter->pdev->dev, "LPVID: %d\n", adapter->pvid);
339bdac85b5SRavikumar Nelavelli 	} else {
3409aebddd1SJeff Kirsher 		adapter->pvid = 0;
3419aebddd1SJeff Kirsher 	}
342bdac85b5SRavikumar Nelavelli }
3439aebddd1SJeff Kirsher 
344760c295eSVenkata Duvvuru #define MGMT_ENABLE_MASK	0x4
345760c295eSVenkata Duvvuru static void be_async_grp5_fw_control_process(struct be_adapter *adapter,
346760c295eSVenkata Duvvuru 					     struct be_mcc_compl *compl)
347760c295eSVenkata Duvvuru {
348760c295eSVenkata Duvvuru 	struct be_async_fw_control *evt = (struct be_async_fw_control *)compl;
349760c295eSVenkata Duvvuru 	u32 evt_dw1 = le32_to_cpu(evt->event_data_word1);
350760c295eSVenkata Duvvuru 
351760c295eSVenkata Duvvuru 	if (evt_dw1 & MGMT_ENABLE_MASK) {
352760c295eSVenkata Duvvuru 		adapter->flags |= BE_FLAGS_OS2BMC;
353760c295eSVenkata Duvvuru 		adapter->bmc_filt_mask = le32_to_cpu(evt->event_data_word2);
354760c295eSVenkata Duvvuru 	} else {
355760c295eSVenkata Duvvuru 		adapter->flags &= ~BE_FLAGS_OS2BMC;
356760c295eSVenkata Duvvuru 	}
357760c295eSVenkata Duvvuru }
358760c295eSVenkata Duvvuru 
3599aebddd1SJeff Kirsher static void be_async_grp5_evt_process(struct be_adapter *adapter,
3603acf19d9SSathya Perla 				      struct be_mcc_compl *compl)
3619aebddd1SJeff Kirsher {
3623acf19d9SSathya Perla 	u8 event_type = (compl->flags >> ASYNC_EVENT_TYPE_SHIFT) &
3633acf19d9SSathya Perla 				ASYNC_EVENT_TYPE_MASK;
3649aebddd1SJeff Kirsher 
3659aebddd1SJeff Kirsher 	switch (event_type) {
3669aebddd1SJeff Kirsher 	case ASYNC_EVENT_COS_PRIORITY:
3673acf19d9SSathya Perla 		be_async_grp5_cos_priority_process(adapter, compl);
3689aebddd1SJeff Kirsher 		break;
3699aebddd1SJeff Kirsher 	case ASYNC_EVENT_QOS_SPEED:
3703acf19d9SSathya Perla 		be_async_grp5_qos_speed_process(adapter, compl);
3719aebddd1SJeff Kirsher 		break;
3729aebddd1SJeff Kirsher 	case ASYNC_EVENT_PVID_STATE:
3733acf19d9SSathya Perla 		be_async_grp5_pvid_state_process(adapter, compl);
3749aebddd1SJeff Kirsher 		break;
375760c295eSVenkata Duvvuru 	/* Async event to disable/enable os2bmc and/or mac-learning */
376760c295eSVenkata Duvvuru 	case ASYNC_EVENT_FW_CONTROL:
377760c295eSVenkata Duvvuru 		be_async_grp5_fw_control_process(adapter, compl);
378760c295eSVenkata Duvvuru 		break;
3799aebddd1SJeff Kirsher 	default:
3809aebddd1SJeff Kirsher 		break;
3819aebddd1SJeff Kirsher 	}
3829aebddd1SJeff Kirsher }
3839aebddd1SJeff Kirsher 
384bc0c3405SAjit Khaparde static void be_async_dbg_evt_process(struct be_adapter *adapter,
3853acf19d9SSathya Perla 				     struct be_mcc_compl *cmp)
386bc0c3405SAjit Khaparde {
387bc0c3405SAjit Khaparde 	u8 event_type = 0;
388bc0c3405SAjit Khaparde 	struct be_async_event_qnq *evt = (struct be_async_event_qnq *)cmp;
389bc0c3405SAjit Khaparde 
3903acf19d9SSathya Perla 	event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
3913acf19d9SSathya Perla 			ASYNC_EVENT_TYPE_MASK;
392bc0c3405SAjit Khaparde 
393bc0c3405SAjit Khaparde 	switch (event_type) {
394bc0c3405SAjit Khaparde 	case ASYNC_DEBUG_EVENT_TYPE_QNQ:
395bc0c3405SAjit Khaparde 		if (evt->valid)
396bc0c3405SAjit Khaparde 			adapter->qnq_vid = le16_to_cpu(evt->vlan_tag);
397bc0c3405SAjit Khaparde 		adapter->flags |= BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
398bc0c3405SAjit Khaparde 	break;
399bc0c3405SAjit Khaparde 	default:
40005ccaa2bSVasundhara Volam 		dev_warn(&adapter->pdev->dev, "Unknown debug event 0x%x!\n",
40105ccaa2bSVasundhara Volam 			 event_type);
402bc0c3405SAjit Khaparde 	break;
403bc0c3405SAjit Khaparde 	}
404bc0c3405SAjit Khaparde }
405bc0c3405SAjit Khaparde 
40621252377SVasundhara Volam static void be_async_sliport_evt_process(struct be_adapter *adapter,
40721252377SVasundhara Volam 					 struct be_mcc_compl *cmp)
40821252377SVasundhara Volam {
40921252377SVasundhara Volam 	u8 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
41021252377SVasundhara Volam 			ASYNC_EVENT_TYPE_MASK;
41121252377SVasundhara Volam 
41221252377SVasundhara Volam 	if (event_type == ASYNC_EVENT_PORT_MISCONFIG)
41321252377SVasundhara Volam 		be_async_port_misconfig_event_process(adapter, cmp);
41421252377SVasundhara Volam }
41521252377SVasundhara Volam 
4163acf19d9SSathya Perla static inline bool is_link_state_evt(u32 flags)
4179aebddd1SJeff Kirsher {
4183acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4199aebddd1SJeff Kirsher 			ASYNC_EVENT_CODE_LINK_STATE;
4209aebddd1SJeff Kirsher }
4219aebddd1SJeff Kirsher 
4223acf19d9SSathya Perla static inline bool is_grp5_evt(u32 flags)
4239aebddd1SJeff Kirsher {
4243acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4253acf19d9SSathya Perla 			ASYNC_EVENT_CODE_GRP_5;
4269aebddd1SJeff Kirsher }
4279aebddd1SJeff Kirsher 
4283acf19d9SSathya Perla static inline bool is_dbg_evt(u32 flags)
429bc0c3405SAjit Khaparde {
4303acf19d9SSathya Perla 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
4313acf19d9SSathya Perla 			ASYNC_EVENT_CODE_QNQ;
4323acf19d9SSathya Perla }
4333acf19d9SSathya Perla 
43421252377SVasundhara Volam static inline bool is_sliport_evt(u32 flags)
43521252377SVasundhara Volam {
43621252377SVasundhara Volam 	return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
43721252377SVasundhara Volam 		ASYNC_EVENT_CODE_SLIPORT;
43821252377SVasundhara Volam }
43921252377SVasundhara Volam 
4403acf19d9SSathya Perla static void be_mcc_event_process(struct be_adapter *adapter,
4413acf19d9SSathya Perla 				 struct be_mcc_compl *compl)
4423acf19d9SSathya Perla {
4433acf19d9SSathya Perla 	if (is_link_state_evt(compl->flags))
4443acf19d9SSathya Perla 		be_async_link_state_process(adapter, compl);
4453acf19d9SSathya Perla 	else if (is_grp5_evt(compl->flags))
4463acf19d9SSathya Perla 		be_async_grp5_evt_process(adapter, compl);
4473acf19d9SSathya Perla 	else if (is_dbg_evt(compl->flags))
4483acf19d9SSathya Perla 		be_async_dbg_evt_process(adapter, compl);
44921252377SVasundhara Volam 	else if (is_sliport_evt(compl->flags))
45021252377SVasundhara Volam 		be_async_sliport_evt_process(adapter, compl);
451bc0c3405SAjit Khaparde }
452bc0c3405SAjit Khaparde 
4539aebddd1SJeff Kirsher static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
4549aebddd1SJeff Kirsher {
4559aebddd1SJeff Kirsher 	struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
4569aebddd1SJeff Kirsher 	struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
4579aebddd1SJeff Kirsher 
4589aebddd1SJeff Kirsher 	if (be_mcc_compl_is_new(compl)) {
4599aebddd1SJeff Kirsher 		queue_tail_inc(mcc_cq);
4609aebddd1SJeff Kirsher 		return compl;
4619aebddd1SJeff Kirsher 	}
4629aebddd1SJeff Kirsher 	return NULL;
4639aebddd1SJeff Kirsher }
4649aebddd1SJeff Kirsher 
4659aebddd1SJeff Kirsher void be_async_mcc_enable(struct be_adapter *adapter)
4669aebddd1SJeff Kirsher {
4679aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_cq_lock);
4689aebddd1SJeff Kirsher 
4699aebddd1SJeff Kirsher 	be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
4709aebddd1SJeff Kirsher 	adapter->mcc_obj.rearm_cq = true;
4719aebddd1SJeff Kirsher 
4729aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_cq_lock);
4739aebddd1SJeff Kirsher }
4749aebddd1SJeff Kirsher 
4759aebddd1SJeff Kirsher void be_async_mcc_disable(struct be_adapter *adapter)
4769aebddd1SJeff Kirsher {
477a323d9bfSSathya Perla 	spin_lock_bh(&adapter->mcc_cq_lock);
478a323d9bfSSathya Perla 
4799aebddd1SJeff Kirsher 	adapter->mcc_obj.rearm_cq = false;
480a323d9bfSSathya Perla 	be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
481a323d9bfSSathya Perla 
482a323d9bfSSathya Perla 	spin_unlock_bh(&adapter->mcc_cq_lock);
4839aebddd1SJeff Kirsher }
4849aebddd1SJeff Kirsher 
48510ef9ab4SSathya Perla int be_process_mcc(struct be_adapter *adapter)
4869aebddd1SJeff Kirsher {
4879aebddd1SJeff Kirsher 	struct be_mcc_compl *compl;
48810ef9ab4SSathya Perla 	int num = 0, status = 0;
4899aebddd1SJeff Kirsher 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
4909aebddd1SJeff Kirsher 
491072a9c48SAmerigo Wang 	spin_lock(&adapter->mcc_cq_lock);
4923acf19d9SSathya Perla 
4939aebddd1SJeff Kirsher 	while ((compl = be_mcc_compl_get(adapter))) {
4949aebddd1SJeff Kirsher 		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
4953acf19d9SSathya Perla 			be_mcc_event_process(adapter, compl);
4969aebddd1SJeff Kirsher 		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
49710ef9ab4SSathya Perla 			status = be_mcc_compl_process(adapter, compl);
4989aebddd1SJeff Kirsher 			atomic_dec(&mcc_obj->q.used);
4999aebddd1SJeff Kirsher 		}
5009aebddd1SJeff Kirsher 		be_mcc_compl_use(compl);
5019aebddd1SJeff Kirsher 		num++;
5029aebddd1SJeff Kirsher 	}
5039aebddd1SJeff Kirsher 
50410ef9ab4SSathya Perla 	if (num)
50510ef9ab4SSathya Perla 		be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
50610ef9ab4SSathya Perla 
507072a9c48SAmerigo Wang 	spin_unlock(&adapter->mcc_cq_lock);
50810ef9ab4SSathya Perla 	return status;
5099aebddd1SJeff Kirsher }
5109aebddd1SJeff Kirsher 
5119aebddd1SJeff Kirsher /* Wait till no more pending mcc requests are present */
5129aebddd1SJeff Kirsher static int be_mcc_wait_compl(struct be_adapter *adapter)
5139aebddd1SJeff Kirsher {
5149aebddd1SJeff Kirsher #define mcc_timeout		120000 /* 12s timeout */
51510ef9ab4SSathya Perla 	int i, status = 0;
5169aebddd1SJeff Kirsher 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
5179aebddd1SJeff Kirsher 
5186589ade0SSathya Perla 	for (i = 0; i < mcc_timeout; i++) {
519954f6825SVenkata Duvvuru 		if (be_check_error(adapter, BE_ERROR_ANY))
5209aebddd1SJeff Kirsher 			return -EIO;
5219aebddd1SJeff Kirsher 
522072a9c48SAmerigo Wang 		local_bh_disable();
52310ef9ab4SSathya Perla 		status = be_process_mcc(adapter);
524072a9c48SAmerigo Wang 		local_bh_enable();
5259aebddd1SJeff Kirsher 
5269aebddd1SJeff Kirsher 		if (atomic_read(&mcc_obj->q.used) == 0)
5279aebddd1SJeff Kirsher 			break;
5289aebddd1SJeff Kirsher 		udelay(100);
5299aebddd1SJeff Kirsher 	}
5309aebddd1SJeff Kirsher 	if (i == mcc_timeout) {
5316589ade0SSathya Perla 		dev_err(&adapter->pdev->dev, "FW not responding\n");
532954f6825SVenkata Duvvuru 		be_set_error(adapter, BE_ERROR_FW);
533652bf646SPadmanabh Ratnakar 		return -EIO;
5349aebddd1SJeff Kirsher 	}
5359aebddd1SJeff Kirsher 	return status;
5369aebddd1SJeff Kirsher }
5379aebddd1SJeff Kirsher 
5389aebddd1SJeff Kirsher /* Notify MCC requests and wait for completion */
5399aebddd1SJeff Kirsher static int be_mcc_notify_wait(struct be_adapter *adapter)
5409aebddd1SJeff Kirsher {
541652bf646SPadmanabh Ratnakar 	int status;
542652bf646SPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
543652bf646SPadmanabh Ratnakar 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
544652bf646SPadmanabh Ratnakar 	u16 index = mcc_obj->q.head;
545652bf646SPadmanabh Ratnakar 	struct be_cmd_resp_hdr *resp;
546652bf646SPadmanabh Ratnakar 
547652bf646SPadmanabh Ratnakar 	index_dec(&index, mcc_obj->q.len);
548652bf646SPadmanabh Ratnakar 	wrb = queue_index_node(&mcc_obj->q, index);
549652bf646SPadmanabh Ratnakar 
550652bf646SPadmanabh Ratnakar 	resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
551652bf646SPadmanabh Ratnakar 
552efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
553efaa408eSSuresh Reddy 	if (status)
554efaa408eSSuresh Reddy 		goto out;
555652bf646SPadmanabh Ratnakar 
556652bf646SPadmanabh Ratnakar 	status = be_mcc_wait_compl(adapter);
557652bf646SPadmanabh Ratnakar 	if (status == -EIO)
558652bf646SPadmanabh Ratnakar 		goto out;
559652bf646SPadmanabh Ratnakar 
5604c60005fSKalesh AP 	status = (resp->base_status |
5614c60005fSKalesh AP 		  ((resp->addl_status & CQE_ADDL_STATUS_MASK) <<
5624c60005fSKalesh AP 		   CQE_ADDL_STATUS_SHIFT));
563652bf646SPadmanabh Ratnakar out:
564652bf646SPadmanabh Ratnakar 	return status;
5659aebddd1SJeff Kirsher }
5669aebddd1SJeff Kirsher 
5679aebddd1SJeff Kirsher static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
5689aebddd1SJeff Kirsher {
5699aebddd1SJeff Kirsher 	int msecs = 0;
5709aebddd1SJeff Kirsher 	u32 ready;
5719aebddd1SJeff Kirsher 
5726589ade0SSathya Perla 	do {
573954f6825SVenkata Duvvuru 		if (be_check_error(adapter, BE_ERROR_ANY))
5749aebddd1SJeff Kirsher 			return -EIO;
5759aebddd1SJeff Kirsher 
5769aebddd1SJeff Kirsher 		ready = ioread32(db);
577434b3648SSathya Perla 		if (ready == 0xffffffff)
5789aebddd1SJeff Kirsher 			return -1;
5799aebddd1SJeff Kirsher 
5809aebddd1SJeff Kirsher 		ready &= MPU_MAILBOX_DB_RDY_MASK;
5819aebddd1SJeff Kirsher 		if (ready)
5829aebddd1SJeff Kirsher 			break;
5839aebddd1SJeff Kirsher 
5849aebddd1SJeff Kirsher 		if (msecs > 4000) {
5856589ade0SSathya Perla 			dev_err(&adapter->pdev->dev, "FW not responding\n");
586954f6825SVenkata Duvvuru 			be_set_error(adapter, BE_ERROR_FW);
587f67ef7baSPadmanabh Ratnakar 			be_detect_error(adapter);
5889aebddd1SJeff Kirsher 			return -1;
5899aebddd1SJeff Kirsher 		}
5909aebddd1SJeff Kirsher 
5919aebddd1SJeff Kirsher 		msleep(1);
5929aebddd1SJeff Kirsher 		msecs++;
5939aebddd1SJeff Kirsher 	} while (true);
5949aebddd1SJeff Kirsher 
5959aebddd1SJeff Kirsher 	return 0;
5969aebddd1SJeff Kirsher }
5979aebddd1SJeff Kirsher 
5989aebddd1SJeff Kirsher /*
5999aebddd1SJeff Kirsher  * Insert the mailbox address into the doorbell in two steps
6009aebddd1SJeff Kirsher  * Polls on the mbox doorbell till a command completion (or a timeout) occurs
6019aebddd1SJeff Kirsher  */
6029aebddd1SJeff Kirsher static int be_mbox_notify_wait(struct be_adapter *adapter)
6039aebddd1SJeff Kirsher {
6049aebddd1SJeff Kirsher 	int status;
6059aebddd1SJeff Kirsher 	u32 val = 0;
6069aebddd1SJeff Kirsher 	void __iomem *db = adapter->db + MPU_MAILBOX_DB_OFFSET;
6079aebddd1SJeff Kirsher 	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
6089aebddd1SJeff Kirsher 	struct be_mcc_mailbox *mbox = mbox_mem->va;
6099aebddd1SJeff Kirsher 	struct be_mcc_compl *compl = &mbox->compl;
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 |= MPU_MAILBOX_DB_HI_MASK;
6179aebddd1SJeff Kirsher 	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
6189aebddd1SJeff Kirsher 	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
6199aebddd1SJeff Kirsher 	iowrite32(val, db);
6209aebddd1SJeff Kirsher 
6219aebddd1SJeff Kirsher 	/* wait for ready to be set */
6229aebddd1SJeff Kirsher 	status = be_mbox_db_ready_wait(adapter, db);
6239aebddd1SJeff Kirsher 	if (status != 0)
6249aebddd1SJeff Kirsher 		return status;
6259aebddd1SJeff Kirsher 
6269aebddd1SJeff Kirsher 	val = 0;
6279aebddd1SJeff Kirsher 	/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
6289aebddd1SJeff Kirsher 	val |= (u32)(mbox_mem->dma >> 4) << 2;
6299aebddd1SJeff Kirsher 	iowrite32(val, db);
6309aebddd1SJeff Kirsher 
6319aebddd1SJeff Kirsher 	status = be_mbox_db_ready_wait(adapter, db);
6329aebddd1SJeff Kirsher 	if (status != 0)
6339aebddd1SJeff Kirsher 		return status;
6349aebddd1SJeff Kirsher 
6359aebddd1SJeff Kirsher 	/* A cq entry has been made now */
6369aebddd1SJeff Kirsher 	if (be_mcc_compl_is_new(compl)) {
6379aebddd1SJeff Kirsher 		status = be_mcc_compl_process(adapter, &mbox->compl);
6389aebddd1SJeff Kirsher 		be_mcc_compl_use(compl);
6399aebddd1SJeff Kirsher 		if (status)
6409aebddd1SJeff Kirsher 			return status;
6419aebddd1SJeff Kirsher 	} else {
6429aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev, "invalid mailbox completion\n");
6439aebddd1SJeff Kirsher 		return -1;
6449aebddd1SJeff Kirsher 	}
6459aebddd1SJeff Kirsher 	return 0;
6469aebddd1SJeff Kirsher }
6479aebddd1SJeff Kirsher 
648c5b3ad4cSSathya Perla static u16 be_POST_stage_get(struct be_adapter *adapter)
6499aebddd1SJeff Kirsher {
6509aebddd1SJeff Kirsher 	u32 sem;
6519aebddd1SJeff Kirsher 
652c5b3ad4cSSathya Perla 	if (BEx_chip(adapter))
653c5b3ad4cSSathya Perla 		sem  = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
6549aebddd1SJeff Kirsher 	else
655c5b3ad4cSSathya Perla 		pci_read_config_dword(adapter->pdev,
656c5b3ad4cSSathya Perla 				      SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
657c5b3ad4cSSathya Perla 
658c5b3ad4cSSathya Perla 	return sem & POST_STAGE_MASK;
6599aebddd1SJeff Kirsher }
6609aebddd1SJeff Kirsher 
66187f20c26SGavin Shan static int lancer_wait_ready(struct be_adapter *adapter)
662bf99e50dSPadmanabh Ratnakar {
663bf99e50dSPadmanabh Ratnakar #define SLIPORT_READY_TIMEOUT 30
664bf99e50dSPadmanabh Ratnakar 	u32 sliport_status;
665e673244aSKalesh AP 	int i;
666bf99e50dSPadmanabh Ratnakar 
667bf99e50dSPadmanabh Ratnakar 	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
668bf99e50dSPadmanabh Ratnakar 		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
669bf99e50dSPadmanabh Ratnakar 		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
6709fa465c0SSathya Perla 			return 0;
6719fa465c0SSathya Perla 
6729fa465c0SSathya Perla 		if (sliport_status & SLIPORT_STATUS_ERR_MASK &&
6739fa465c0SSathya Perla 		    !(sliport_status & SLIPORT_STATUS_RN_MASK))
6749fa465c0SSathya Perla 			return -EIO;
675bf99e50dSPadmanabh Ratnakar 
676bf99e50dSPadmanabh Ratnakar 		msleep(1000);
677bf99e50dSPadmanabh Ratnakar 	}
678bf99e50dSPadmanabh Ratnakar 
679e673244aSKalesh AP 	return sliport_status ? : -1;
680bf99e50dSPadmanabh Ratnakar }
681bf99e50dSPadmanabh Ratnakar 
682bf99e50dSPadmanabh Ratnakar int be_fw_wait_ready(struct be_adapter *adapter)
6839aebddd1SJeff Kirsher {
6849aebddd1SJeff Kirsher 	u16 stage;
6859aebddd1SJeff Kirsher 	int status, timeout = 0;
6869aebddd1SJeff Kirsher 	struct device *dev = &adapter->pdev->dev;
6879aebddd1SJeff Kirsher 
688bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter)) {
689bf99e50dSPadmanabh Ratnakar 		status = lancer_wait_ready(adapter);
690e673244aSKalesh AP 		if (status) {
691e673244aSKalesh AP 			stage = status;
692e673244aSKalesh AP 			goto err;
693e673244aSKalesh AP 		}
694e673244aSKalesh AP 		return 0;
695bf99e50dSPadmanabh Ratnakar 	}
696bf99e50dSPadmanabh Ratnakar 
6979aebddd1SJeff Kirsher 	do {
698ca3de6b2SSathya Perla 		/* There's no means to poll POST state on BE2/3 VFs */
699ca3de6b2SSathya Perla 		if (BEx_chip(adapter) && be_virtfn(adapter))
700ca3de6b2SSathya Perla 			return 0;
701ca3de6b2SSathya Perla 
702c5b3ad4cSSathya Perla 		stage = be_POST_stage_get(adapter);
70366d29cbcSGavin Shan 		if (stage == POST_STAGE_ARMFW_RDY)
70466d29cbcSGavin Shan 			return 0;
70566d29cbcSGavin Shan 
706a2cc4e0bSSathya Perla 		dev_info(dev, "Waiting for POST, %ds elapsed\n", timeout);
7079aebddd1SJeff Kirsher 		if (msleep_interruptible(2000)) {
7089aebddd1SJeff Kirsher 			dev_err(dev, "Waiting for POST aborted\n");
7099aebddd1SJeff Kirsher 			return -EINTR;
7109aebddd1SJeff Kirsher 		}
7119aebddd1SJeff Kirsher 		timeout += 2;
7123ab81b5fSSomnath Kotur 	} while (timeout < 60);
7139aebddd1SJeff Kirsher 
714e673244aSKalesh AP err:
715e673244aSKalesh AP 	dev_err(dev, "POST timeout; stage=%#x\n", stage);
7169fa465c0SSathya Perla 	return -ETIMEDOUT;
7179aebddd1SJeff Kirsher }
7189aebddd1SJeff Kirsher 
7199aebddd1SJeff Kirsher static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
7209aebddd1SJeff Kirsher {
7219aebddd1SJeff Kirsher 	return &wrb->payload.sgl[0];
7229aebddd1SJeff Kirsher }
7239aebddd1SJeff Kirsher 
724a2cc4e0bSSathya Perla static inline void fill_wrb_tags(struct be_mcc_wrb *wrb, unsigned long addr)
725bea50988SSathya Perla {
726bea50988SSathya Perla 	wrb->tag0 = addr & 0xFFFFFFFF;
727bea50988SSathya Perla 	wrb->tag1 = upper_32_bits(addr);
728bea50988SSathya Perla }
7299aebddd1SJeff Kirsher 
7309aebddd1SJeff Kirsher /* Don't touch the hdr after it's prepared */
731106df1e3SSomnath Kotur /* mem will be NULL for embedded commands */
732106df1e3SSomnath Kotur static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
733106df1e3SSomnath Kotur 				   u8 subsystem, u8 opcode, int cmd_len,
734a2cc4e0bSSathya Perla 				   struct be_mcc_wrb *wrb,
735a2cc4e0bSSathya Perla 				   struct be_dma_mem *mem)
7369aebddd1SJeff Kirsher {
737106df1e3SSomnath Kotur 	struct be_sge *sge;
738106df1e3SSomnath Kotur 
7399aebddd1SJeff Kirsher 	req_hdr->opcode = opcode;
7409aebddd1SJeff Kirsher 	req_hdr->subsystem = subsystem;
7419aebddd1SJeff Kirsher 	req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
7429aebddd1SJeff Kirsher 	req_hdr->version = 0;
743bea50988SSathya Perla 	fill_wrb_tags(wrb, (ulong) req_hdr);
744106df1e3SSomnath Kotur 	wrb->payload_length = cmd_len;
745106df1e3SSomnath Kotur 	if (mem) {
746106df1e3SSomnath Kotur 		wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
747106df1e3SSomnath Kotur 			MCC_WRB_SGE_CNT_SHIFT;
748106df1e3SSomnath Kotur 		sge = nonembedded_sgl(wrb);
749106df1e3SSomnath Kotur 		sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
750106df1e3SSomnath Kotur 		sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
751106df1e3SSomnath Kotur 		sge->len = cpu_to_le32(mem->size);
752106df1e3SSomnath Kotur 	} else
753106df1e3SSomnath Kotur 		wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
754106df1e3SSomnath Kotur 	be_dws_cpu_to_le(wrb, 8);
7559aebddd1SJeff Kirsher }
7569aebddd1SJeff Kirsher 
7579aebddd1SJeff Kirsher static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
7589aebddd1SJeff Kirsher 				      struct be_dma_mem *mem)
7599aebddd1SJeff Kirsher {
7609aebddd1SJeff Kirsher 	int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
7619aebddd1SJeff Kirsher 	u64 dma = (u64)mem->dma;
7629aebddd1SJeff Kirsher 
7639aebddd1SJeff Kirsher 	for (i = 0; i < buf_pages; i++) {
7649aebddd1SJeff Kirsher 		pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
7659aebddd1SJeff Kirsher 		pages[i].hi = cpu_to_le32(upper_32_bits(dma));
7669aebddd1SJeff Kirsher 		dma += PAGE_SIZE_4K;
7679aebddd1SJeff Kirsher 	}
7689aebddd1SJeff Kirsher }
7699aebddd1SJeff Kirsher 
7709aebddd1SJeff Kirsher static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
7719aebddd1SJeff Kirsher {
7729aebddd1SJeff Kirsher 	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
7739aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb
7749aebddd1SJeff Kirsher 		= &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
7759aebddd1SJeff Kirsher 	memset(wrb, 0, sizeof(*wrb));
7769aebddd1SJeff Kirsher 	return wrb;
7779aebddd1SJeff Kirsher }
7789aebddd1SJeff Kirsher 
7799aebddd1SJeff Kirsher static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
7809aebddd1SJeff Kirsher {
7819aebddd1SJeff Kirsher 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
7829aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
7839aebddd1SJeff Kirsher 
784aa790db9SPadmanabh Ratnakar 	if (!mccq->created)
785aa790db9SPadmanabh Ratnakar 		return NULL;
786aa790db9SPadmanabh Ratnakar 
7874d277125SVasundhara Volam 	if (atomic_read(&mccq->used) >= mccq->len)
7889aebddd1SJeff Kirsher 		return NULL;
7899aebddd1SJeff Kirsher 
7909aebddd1SJeff Kirsher 	wrb = queue_head_node(mccq);
7919aebddd1SJeff Kirsher 	queue_head_inc(mccq);
7929aebddd1SJeff Kirsher 	atomic_inc(&mccq->used);
7939aebddd1SJeff Kirsher 	memset(wrb, 0, sizeof(*wrb));
7949aebddd1SJeff Kirsher 	return wrb;
7959aebddd1SJeff Kirsher }
7969aebddd1SJeff Kirsher 
797bea50988SSathya Perla static bool use_mcc(struct be_adapter *adapter)
798bea50988SSathya Perla {
799bea50988SSathya Perla 	return adapter->mcc_obj.q.created;
800bea50988SSathya Perla }
801bea50988SSathya Perla 
802bea50988SSathya Perla /* Must be used only in process context */
803bea50988SSathya Perla static int be_cmd_lock(struct be_adapter *adapter)
804bea50988SSathya Perla {
805bea50988SSathya Perla 	if (use_mcc(adapter)) {
806bea50988SSathya Perla 		spin_lock_bh(&adapter->mcc_lock);
807bea50988SSathya Perla 		return 0;
808bea50988SSathya Perla 	} else {
809bea50988SSathya Perla 		return mutex_lock_interruptible(&adapter->mbox_lock);
810bea50988SSathya Perla 	}
811bea50988SSathya Perla }
812bea50988SSathya Perla 
813bea50988SSathya Perla /* Must be used only in process context */
814bea50988SSathya Perla static void be_cmd_unlock(struct be_adapter *adapter)
815bea50988SSathya Perla {
816bea50988SSathya Perla 	if (use_mcc(adapter))
817bea50988SSathya Perla 		spin_unlock_bh(&adapter->mcc_lock);
818bea50988SSathya Perla 	else
819bea50988SSathya Perla 		return mutex_unlock(&adapter->mbox_lock);
820bea50988SSathya Perla }
821bea50988SSathya Perla 
822bea50988SSathya Perla static struct be_mcc_wrb *be_cmd_copy(struct be_adapter *adapter,
823bea50988SSathya Perla 				      struct be_mcc_wrb *wrb)
824bea50988SSathya Perla {
825bea50988SSathya Perla 	struct be_mcc_wrb *dest_wrb;
826bea50988SSathya Perla 
827bea50988SSathya Perla 	if (use_mcc(adapter)) {
828bea50988SSathya Perla 		dest_wrb = wrb_from_mccq(adapter);
829bea50988SSathya Perla 		if (!dest_wrb)
830bea50988SSathya Perla 			return NULL;
831bea50988SSathya Perla 	} else {
832bea50988SSathya Perla 		dest_wrb = wrb_from_mbox(adapter);
833bea50988SSathya Perla 	}
834bea50988SSathya Perla 
835bea50988SSathya Perla 	memcpy(dest_wrb, wrb, sizeof(*wrb));
836bea50988SSathya Perla 	if (wrb->embedded & cpu_to_le32(MCC_WRB_EMBEDDED_MASK))
837bea50988SSathya Perla 		fill_wrb_tags(dest_wrb, (ulong) embedded_payload(wrb));
838bea50988SSathya Perla 
839bea50988SSathya Perla 	return dest_wrb;
840bea50988SSathya Perla }
841bea50988SSathya Perla 
842bea50988SSathya Perla /* Must be used only in process context */
843bea50988SSathya Perla static int be_cmd_notify_wait(struct be_adapter *adapter,
844bea50988SSathya Perla 			      struct be_mcc_wrb *wrb)
845bea50988SSathya Perla {
846bea50988SSathya Perla 	struct be_mcc_wrb *dest_wrb;
847bea50988SSathya Perla 	int status;
848bea50988SSathya Perla 
849bea50988SSathya Perla 	status = be_cmd_lock(adapter);
850bea50988SSathya Perla 	if (status)
851bea50988SSathya Perla 		return status;
852bea50988SSathya Perla 
853bea50988SSathya Perla 	dest_wrb = be_cmd_copy(adapter, wrb);
8540c884567SSuresh Reddy 	if (!dest_wrb) {
8550c884567SSuresh Reddy 		status = -EBUSY;
8560c884567SSuresh Reddy 		goto unlock;
8570c884567SSuresh Reddy 	}
858bea50988SSathya Perla 
859bea50988SSathya Perla 	if (use_mcc(adapter))
860bea50988SSathya Perla 		status = be_mcc_notify_wait(adapter);
861bea50988SSathya Perla 	else
862bea50988SSathya Perla 		status = be_mbox_notify_wait(adapter);
863bea50988SSathya Perla 
864bea50988SSathya Perla 	if (!status)
865bea50988SSathya Perla 		memcpy(wrb, dest_wrb, sizeof(*wrb));
866bea50988SSathya Perla 
8670c884567SSuresh Reddy unlock:
868bea50988SSathya Perla 	be_cmd_unlock(adapter);
869bea50988SSathya Perla 	return status;
870bea50988SSathya Perla }
871bea50988SSathya Perla 
8729aebddd1SJeff Kirsher /* Tell fw we're about to start firing cmds by writing a
8739aebddd1SJeff Kirsher  * special pattern across the wrb hdr; uses mbox
8749aebddd1SJeff Kirsher  */
8759aebddd1SJeff Kirsher int be_cmd_fw_init(struct be_adapter *adapter)
8769aebddd1SJeff Kirsher {
8779aebddd1SJeff Kirsher 	u8 *wrb;
8789aebddd1SJeff Kirsher 	int status;
8799aebddd1SJeff Kirsher 
880bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter))
881bf99e50dSPadmanabh Ratnakar 		return 0;
882bf99e50dSPadmanabh Ratnakar 
8839aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
8849aebddd1SJeff Kirsher 		return -1;
8859aebddd1SJeff Kirsher 
8869aebddd1SJeff Kirsher 	wrb = (u8 *)wrb_from_mbox(adapter);
8879aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8889aebddd1SJeff Kirsher 	*wrb++ = 0x12;
8899aebddd1SJeff Kirsher 	*wrb++ = 0x34;
8909aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8919aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
8929aebddd1SJeff Kirsher 	*wrb++ = 0x56;
8939aebddd1SJeff Kirsher 	*wrb++ = 0x78;
8949aebddd1SJeff Kirsher 	*wrb = 0xFF;
8959aebddd1SJeff Kirsher 
8969aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
8979aebddd1SJeff Kirsher 
8989aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
8999aebddd1SJeff Kirsher 	return status;
9009aebddd1SJeff Kirsher }
9019aebddd1SJeff Kirsher 
9029aebddd1SJeff Kirsher /* Tell fw we're done with firing cmds by writing a
9039aebddd1SJeff Kirsher  * special pattern across the wrb hdr; uses mbox
9049aebddd1SJeff Kirsher  */
9059aebddd1SJeff Kirsher int be_cmd_fw_clean(struct be_adapter *adapter)
9069aebddd1SJeff Kirsher {
9079aebddd1SJeff Kirsher 	u8 *wrb;
9089aebddd1SJeff Kirsher 	int status;
9099aebddd1SJeff Kirsher 
910bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter))
911bf99e50dSPadmanabh Ratnakar 		return 0;
912bf99e50dSPadmanabh Ratnakar 
9139aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
9149aebddd1SJeff Kirsher 		return -1;
9159aebddd1SJeff Kirsher 
9169aebddd1SJeff Kirsher 	wrb = (u8 *)wrb_from_mbox(adapter);
9179aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9189aebddd1SJeff Kirsher 	*wrb++ = 0xAA;
9199aebddd1SJeff Kirsher 	*wrb++ = 0xBB;
9209aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9219aebddd1SJeff Kirsher 	*wrb++ = 0xFF;
9229aebddd1SJeff Kirsher 	*wrb++ = 0xCC;
9239aebddd1SJeff Kirsher 	*wrb++ = 0xDD;
9249aebddd1SJeff Kirsher 	*wrb = 0xFF;
9259aebddd1SJeff Kirsher 
9269aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
9279aebddd1SJeff Kirsher 
9289aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
9299aebddd1SJeff Kirsher 	return status;
9309aebddd1SJeff Kirsher }
931bf99e50dSPadmanabh Ratnakar 
932f2f781a7SSathya Perla int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo)
9339aebddd1SJeff Kirsher {
9349aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
9359aebddd1SJeff Kirsher 	struct be_cmd_req_eq_create *req;
936f2f781a7SSathya Perla 	struct be_dma_mem *q_mem = &eqo->q.dma_mem;
937f2f781a7SSathya Perla 	int status, ver = 0;
9389aebddd1SJeff Kirsher 
9399aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
9409aebddd1SJeff Kirsher 		return -1;
9419aebddd1SJeff Kirsher 
9429aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
9439aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
9449aebddd1SJeff Kirsher 
945106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
946a2cc4e0bSSathya Perla 			       OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb,
947a2cc4e0bSSathya Perla 			       NULL);
9489aebddd1SJeff Kirsher 
949f2f781a7SSathya Perla 	/* Support for EQ_CREATEv2 available only SH-R onwards */
950f2f781a7SSathya Perla 	if (!(BEx_chip(adapter) || lancer_chip(adapter)))
951f2f781a7SSathya Perla 		ver = 2;
952f2f781a7SSathya Perla 
953f2f781a7SSathya Perla 	req->hdr.version = ver;
9549aebddd1SJeff Kirsher 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
9559aebddd1SJeff Kirsher 
9569aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
9579aebddd1SJeff Kirsher 	/* 4byte eqe*/
9589aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
9599aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_eq_context, count, req->context,
960f2f781a7SSathya Perla 		      __ilog2_u32(eqo->q.len / 256));
9619aebddd1SJeff Kirsher 	be_dws_cpu_to_le(req->context, sizeof(req->context));
9629aebddd1SJeff Kirsher 
9639aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
9649aebddd1SJeff Kirsher 
9659aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
9669aebddd1SJeff Kirsher 	if (!status) {
9679aebddd1SJeff Kirsher 		struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
96803d28ffeSKalesh AP 
969f2f781a7SSathya Perla 		eqo->q.id = le16_to_cpu(resp->eq_id);
970f2f781a7SSathya Perla 		eqo->msix_idx =
971f2f781a7SSathya Perla 			(ver == 2) ? le16_to_cpu(resp->msix_idx) : eqo->idx;
972f2f781a7SSathya Perla 		eqo->q.created = true;
9739aebddd1SJeff Kirsher 	}
9749aebddd1SJeff Kirsher 
9759aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
9769aebddd1SJeff Kirsher 	return status;
9779aebddd1SJeff Kirsher }
9789aebddd1SJeff Kirsher 
979f9449ab7SSathya Perla /* Use MCC */
9809aebddd1SJeff Kirsher int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
9815ee4979bSSathya Perla 			  bool permanent, u32 if_handle, u32 pmac_id)
9829aebddd1SJeff Kirsher {
9839aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
9849aebddd1SJeff Kirsher 	struct be_cmd_req_mac_query *req;
9859aebddd1SJeff Kirsher 	int status;
9869aebddd1SJeff Kirsher 
987f9449ab7SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
9889aebddd1SJeff Kirsher 
989f9449ab7SSathya Perla 	wrb = wrb_from_mccq(adapter);
990f9449ab7SSathya Perla 	if (!wrb) {
991f9449ab7SSathya Perla 		status = -EBUSY;
992f9449ab7SSathya Perla 		goto err;
993f9449ab7SSathya Perla 	}
9949aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
9959aebddd1SJeff Kirsher 
996106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
997a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req), wrb,
998a2cc4e0bSSathya Perla 			       NULL);
9995ee4979bSSathya Perla 	req->type = MAC_ADDRESS_TYPE_NETWORK;
10009aebddd1SJeff Kirsher 	if (permanent) {
10019aebddd1SJeff Kirsher 		req->permanent = 1;
10029aebddd1SJeff Kirsher 	} else {
10039aebddd1SJeff Kirsher 		req->if_id = cpu_to_le16((u16)if_handle);
1004590c391dSPadmanabh Ratnakar 		req->pmac_id = cpu_to_le32(pmac_id);
10059aebddd1SJeff Kirsher 		req->permanent = 0;
10069aebddd1SJeff Kirsher 	}
10079aebddd1SJeff Kirsher 
1008f9449ab7SSathya Perla 	status = be_mcc_notify_wait(adapter);
10099aebddd1SJeff Kirsher 	if (!status) {
10109aebddd1SJeff Kirsher 		struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
101103d28ffeSKalesh AP 
10129aebddd1SJeff Kirsher 		memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
10139aebddd1SJeff Kirsher 	}
10149aebddd1SJeff Kirsher 
1015f9449ab7SSathya Perla err:
1016f9449ab7SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
10179aebddd1SJeff Kirsher 	return status;
10189aebddd1SJeff Kirsher }
10199aebddd1SJeff Kirsher 
10209aebddd1SJeff Kirsher /* Uses synchronous MCCQ */
10219aebddd1SJeff Kirsher int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
10229aebddd1SJeff Kirsher 		    u32 if_id, u32 *pmac_id, u32 domain)
10239aebddd1SJeff Kirsher {
10249aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
10259aebddd1SJeff Kirsher 	struct be_cmd_req_pmac_add *req;
10269aebddd1SJeff Kirsher 	int status;
10279aebddd1SJeff Kirsher 
10289aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
10299aebddd1SJeff Kirsher 
10309aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
10319aebddd1SJeff Kirsher 	if (!wrb) {
10329aebddd1SJeff Kirsher 		status = -EBUSY;
10339aebddd1SJeff Kirsher 		goto err;
10349aebddd1SJeff Kirsher 	}
10359aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
10369aebddd1SJeff Kirsher 
1037106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1038a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req), wrb,
1039a2cc4e0bSSathya Perla 			       NULL);
10409aebddd1SJeff Kirsher 
10419aebddd1SJeff Kirsher 	req->hdr.domain = domain;
10429aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(if_id);
10439aebddd1SJeff Kirsher 	memcpy(req->mac_address, mac_addr, ETH_ALEN);
10449aebddd1SJeff Kirsher 
10459aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
10469aebddd1SJeff Kirsher 	if (!status) {
10479aebddd1SJeff Kirsher 		struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
104803d28ffeSKalesh AP 
10499aebddd1SJeff Kirsher 		*pmac_id = le32_to_cpu(resp->pmac_id);
10509aebddd1SJeff Kirsher 	}
10519aebddd1SJeff Kirsher 
10529aebddd1SJeff Kirsher err:
10539aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
1054e3a7ae2cSSomnath Kotur 
1055e3a7ae2cSSomnath Kotur 	 if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
1056e3a7ae2cSSomnath Kotur 		status = -EPERM;
1057e3a7ae2cSSomnath Kotur 
10589aebddd1SJeff Kirsher 	return status;
10599aebddd1SJeff Kirsher }
10609aebddd1SJeff Kirsher 
10619aebddd1SJeff Kirsher /* Uses synchronous MCCQ */
106230128031SSathya Perla int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
10639aebddd1SJeff Kirsher {
10649aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
10659aebddd1SJeff Kirsher 	struct be_cmd_req_pmac_del *req;
10669aebddd1SJeff Kirsher 	int status;
10679aebddd1SJeff Kirsher 
106830128031SSathya Perla 	if (pmac_id == -1)
106930128031SSathya Perla 		return 0;
107030128031SSathya Perla 
10719aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
10729aebddd1SJeff Kirsher 
10739aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
10749aebddd1SJeff Kirsher 	if (!wrb) {
10759aebddd1SJeff Kirsher 		status = -EBUSY;
10769aebddd1SJeff Kirsher 		goto err;
10779aebddd1SJeff Kirsher 	}
10789aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
10799aebddd1SJeff Kirsher 
1080106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1081cd3307aaSKalesh AP 			       OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req),
1082cd3307aaSKalesh AP 			       wrb, NULL);
10839aebddd1SJeff Kirsher 
10849aebddd1SJeff Kirsher 	req->hdr.domain = dom;
10859aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(if_id);
10869aebddd1SJeff Kirsher 	req->pmac_id = cpu_to_le32(pmac_id);
10879aebddd1SJeff Kirsher 
10889aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
10899aebddd1SJeff Kirsher 
10909aebddd1SJeff Kirsher err:
10919aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
10929aebddd1SJeff Kirsher 	return status;
10939aebddd1SJeff Kirsher }
10949aebddd1SJeff Kirsher 
10959aebddd1SJeff Kirsher /* Uses Mbox */
109610ef9ab4SSathya Perla int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
109710ef9ab4SSathya Perla 		     struct be_queue_info *eq, bool no_delay, int coalesce_wm)
10989aebddd1SJeff Kirsher {
10999aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
11009aebddd1SJeff Kirsher 	struct be_cmd_req_cq_create *req;
11019aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &cq->dma_mem;
11029aebddd1SJeff Kirsher 	void *ctxt;
11039aebddd1SJeff Kirsher 	int status;
11049aebddd1SJeff Kirsher 
11059aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
11069aebddd1SJeff Kirsher 		return -1;
11079aebddd1SJeff Kirsher 
11089aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
11099aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
11109aebddd1SJeff Kirsher 	ctxt = &req->context;
11119aebddd1SJeff Kirsher 
1112106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1113a2cc4e0bSSathya Perla 			       OPCODE_COMMON_CQ_CREATE, sizeof(*req), wrb,
1114a2cc4e0bSSathya Perla 			       NULL);
11159aebddd1SJeff Kirsher 
11169aebddd1SJeff Kirsher 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1117bbdc42f8SAjit Khaparde 
1118bbdc42f8SAjit Khaparde 	if (BEx_chip(adapter)) {
11199aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
11209aebddd1SJeff Kirsher 			      coalesce_wm);
11219aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
11229aebddd1SJeff Kirsher 			      ctxt, no_delay);
11239aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
11249aebddd1SJeff Kirsher 			      __ilog2_u32(cq->len / 256));
11259aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
11269aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
11279aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
1128bbdc42f8SAjit Khaparde 	} else {
1129bbdc42f8SAjit Khaparde 		req->hdr.version = 2;
1130bbdc42f8SAjit Khaparde 		req->page_size = 1; /* 1 for 4K */
113109e83a9dSAjit Khaparde 
113209e83a9dSAjit Khaparde 		/* coalesce-wm field in this cmd is not relevant to Lancer.
113309e83a9dSAjit Khaparde 		 * Lancer uses COMMON_MODIFY_CQ to set this field
113409e83a9dSAjit Khaparde 		 */
113509e83a9dSAjit Khaparde 		if (!lancer_chip(adapter))
113609e83a9dSAjit Khaparde 			AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
113709e83a9dSAjit Khaparde 				      ctxt, coalesce_wm);
1138bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
1139bbdc42f8SAjit Khaparde 			      no_delay);
1140bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
1141bbdc42f8SAjit Khaparde 			      __ilog2_u32(cq->len / 256));
1142bbdc42f8SAjit Khaparde 		AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
1143a2cc4e0bSSathya Perla 		AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
1144a2cc4e0bSSathya Perla 		AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
11459aebddd1SJeff Kirsher 	}
11469aebddd1SJeff Kirsher 
11479aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
11489aebddd1SJeff Kirsher 
11499aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
11509aebddd1SJeff Kirsher 
11519aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
11529aebddd1SJeff Kirsher 	if (!status) {
11539aebddd1SJeff Kirsher 		struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
115403d28ffeSKalesh AP 
11559aebddd1SJeff Kirsher 		cq->id = le16_to_cpu(resp->cq_id);
11569aebddd1SJeff Kirsher 		cq->created = true;
11579aebddd1SJeff Kirsher 	}
11589aebddd1SJeff Kirsher 
11599aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
11609aebddd1SJeff Kirsher 
11619aebddd1SJeff Kirsher 	return status;
11629aebddd1SJeff Kirsher }
11639aebddd1SJeff Kirsher 
11649aebddd1SJeff Kirsher static u32 be_encoded_q_len(int q_len)
11659aebddd1SJeff Kirsher {
11669aebddd1SJeff Kirsher 	u32 len_encoded = fls(q_len); /* log2(len) + 1 */
116703d28ffeSKalesh AP 
11689aebddd1SJeff Kirsher 	if (len_encoded == 16)
11699aebddd1SJeff Kirsher 		len_encoded = 0;
11709aebddd1SJeff Kirsher 	return len_encoded;
11719aebddd1SJeff Kirsher }
11729aebddd1SJeff Kirsher 
11734188e7dfSJingoo Han static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
11749aebddd1SJeff Kirsher 				  struct be_queue_info *mccq,
11759aebddd1SJeff Kirsher 				  struct be_queue_info *cq)
11769aebddd1SJeff Kirsher {
11779aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
11789aebddd1SJeff Kirsher 	struct be_cmd_req_mcc_ext_create *req;
11799aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &mccq->dma_mem;
11809aebddd1SJeff Kirsher 	void *ctxt;
11819aebddd1SJeff Kirsher 	int status;
11829aebddd1SJeff Kirsher 
11839aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
11849aebddd1SJeff Kirsher 		return -1;
11859aebddd1SJeff Kirsher 
11869aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
11879aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
11889aebddd1SJeff Kirsher 	ctxt = &req->context;
11899aebddd1SJeff Kirsher 
1190106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1191a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req), wrb,
1192a2cc4e0bSSathya Perla 			       NULL);
11939aebddd1SJeff Kirsher 
11949aebddd1SJeff Kirsher 	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1195666d39c7SVasundhara Volam 	if (BEx_chip(adapter)) {
11969aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
11979aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
11989aebddd1SJeff Kirsher 			      be_encoded_q_len(mccq->len));
11999aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
1200666d39c7SVasundhara Volam 	} else {
1201666d39c7SVasundhara Volam 		req->hdr.version = 1;
1202666d39c7SVasundhara Volam 		req->cq_id = cpu_to_le16(cq->id);
1203666d39c7SVasundhara Volam 
1204666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, ring_size, ctxt,
1205666d39c7SVasundhara Volam 			      be_encoded_q_len(mccq->len));
1206666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, valid, ctxt, 1);
1207666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_id,
1208666d39c7SVasundhara Volam 			      ctxt, cq->id);
1209666d39c7SVasundhara Volam 		AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_valid,
1210666d39c7SVasundhara Volam 			      ctxt, 1);
12119aebddd1SJeff Kirsher 	}
12129aebddd1SJeff Kirsher 
121321252377SVasundhara Volam 	/* Subscribe to Link State, Sliport Event and Group 5 Events
121421252377SVasundhara Volam 	 * (bits 1, 5 and 17 set)
121521252377SVasundhara Volam 	 */
121621252377SVasundhara Volam 	req->async_event_bitmap[0] =
121721252377SVasundhara Volam 			cpu_to_le32(BIT(ASYNC_EVENT_CODE_LINK_STATE) |
121821252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_GRP_5) |
121921252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_QNQ) |
122021252377SVasundhara Volam 				    BIT(ASYNC_EVENT_CODE_SLIPORT));
122121252377SVasundhara Volam 
12229aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
12239aebddd1SJeff Kirsher 
12249aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
12259aebddd1SJeff Kirsher 
12269aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
12279aebddd1SJeff Kirsher 	if (!status) {
12289aebddd1SJeff Kirsher 		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
122903d28ffeSKalesh AP 
12309aebddd1SJeff Kirsher 		mccq->id = le16_to_cpu(resp->id);
12319aebddd1SJeff Kirsher 		mccq->created = true;
12329aebddd1SJeff Kirsher 	}
12339aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
12349aebddd1SJeff Kirsher 
12359aebddd1SJeff Kirsher 	return status;
12369aebddd1SJeff Kirsher }
12379aebddd1SJeff Kirsher 
12384188e7dfSJingoo Han static int be_cmd_mccq_org_create(struct be_adapter *adapter,
12399aebddd1SJeff Kirsher 				  struct be_queue_info *mccq,
12409aebddd1SJeff Kirsher 				  struct be_queue_info *cq)
12419aebddd1SJeff Kirsher {
12429aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
12439aebddd1SJeff Kirsher 	struct be_cmd_req_mcc_create *req;
12449aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &mccq->dma_mem;
12459aebddd1SJeff Kirsher 	void *ctxt;
12469aebddd1SJeff Kirsher 	int status;
12479aebddd1SJeff Kirsher 
12489aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
12499aebddd1SJeff Kirsher 		return -1;
12509aebddd1SJeff Kirsher 
12519aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
12529aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
12539aebddd1SJeff Kirsher 	ctxt = &req->context;
12549aebddd1SJeff Kirsher 
1255106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1256a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MCC_CREATE, sizeof(*req), wrb,
1257a2cc4e0bSSathya Perla 			       NULL);
12589aebddd1SJeff Kirsher 
12599aebddd1SJeff Kirsher 	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
12609aebddd1SJeff Kirsher 
12619aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
12629aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
12639aebddd1SJeff Kirsher 		      be_encoded_q_len(mccq->len));
12649aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
12659aebddd1SJeff Kirsher 
12669aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
12679aebddd1SJeff Kirsher 
12689aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
12699aebddd1SJeff Kirsher 
12709aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
12719aebddd1SJeff Kirsher 	if (!status) {
12729aebddd1SJeff Kirsher 		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
127303d28ffeSKalesh AP 
12749aebddd1SJeff Kirsher 		mccq->id = le16_to_cpu(resp->id);
12759aebddd1SJeff Kirsher 		mccq->created = true;
12769aebddd1SJeff Kirsher 	}
12779aebddd1SJeff Kirsher 
12789aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
12799aebddd1SJeff Kirsher 	return status;
12809aebddd1SJeff Kirsher }
12819aebddd1SJeff Kirsher 
12829aebddd1SJeff Kirsher int be_cmd_mccq_create(struct be_adapter *adapter,
1283a2cc4e0bSSathya Perla 		       struct be_queue_info *mccq, struct be_queue_info *cq)
12849aebddd1SJeff Kirsher {
12859aebddd1SJeff Kirsher 	int status;
12869aebddd1SJeff Kirsher 
12879aebddd1SJeff Kirsher 	status = be_cmd_mccq_ext_create(adapter, mccq, cq);
1288666d39c7SVasundhara Volam 	if (status && BEx_chip(adapter)) {
12899aebddd1SJeff Kirsher 		dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
12909aebddd1SJeff Kirsher 			"or newer to avoid conflicting priorities between NIC "
12919aebddd1SJeff Kirsher 			"and FCoE traffic");
12929aebddd1SJeff Kirsher 		status = be_cmd_mccq_org_create(adapter, mccq, cq);
12939aebddd1SJeff Kirsher 	}
12949aebddd1SJeff Kirsher 	return status;
12959aebddd1SJeff Kirsher }
12969aebddd1SJeff Kirsher 
129794d73aaaSVasundhara Volam int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo)
12989aebddd1SJeff Kirsher {
12997707133cSSathya Perla 	struct be_mcc_wrb wrb = {0};
13009aebddd1SJeff Kirsher 	struct be_cmd_req_eth_tx_create *req;
130194d73aaaSVasundhara Volam 	struct be_queue_info *txq = &txo->q;
130294d73aaaSVasundhara Volam 	struct be_queue_info *cq = &txo->cq;
13039aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &txq->dma_mem;
130494d73aaaSVasundhara Volam 	int status, ver = 0;
13059aebddd1SJeff Kirsher 
13067707133cSSathya Perla 	req = embedded_payload(&wrb);
1307106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
13087707133cSSathya Perla 			       OPCODE_ETH_TX_CREATE, sizeof(*req), &wrb, NULL);
13099aebddd1SJeff Kirsher 
13109aebddd1SJeff Kirsher 	if (lancer_chip(adapter)) {
13119aebddd1SJeff Kirsher 		req->hdr.version = 1;
131294d73aaaSVasundhara Volam 	} else if (BEx_chip(adapter)) {
131394d73aaaSVasundhara Volam 		if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC)
131494d73aaaSVasundhara Volam 			req->hdr.version = 2;
131594d73aaaSVasundhara Volam 	} else { /* For SH */
131694d73aaaSVasundhara Volam 		req->hdr.version = 2;
13179aebddd1SJeff Kirsher 	}
13189aebddd1SJeff Kirsher 
131981b02655SVasundhara Volam 	if (req->hdr.version > 0)
132081b02655SVasundhara Volam 		req->if_id = cpu_to_le16(adapter->if_handle);
13219aebddd1SJeff Kirsher 	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
13229aebddd1SJeff Kirsher 	req->ulp_num = BE_ULP1_NUM;
13239aebddd1SJeff Kirsher 	req->type = BE_ETH_TX_RING_TYPE_STANDARD;
132494d73aaaSVasundhara Volam 	req->cq_id = cpu_to_le16(cq->id);
132594d73aaaSVasundhara Volam 	req->queue_size = be_encoded_q_len(txq->len);
13269aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
132794d73aaaSVasundhara Volam 	ver = req->hdr.version;
132894d73aaaSVasundhara Volam 
13297707133cSSathya Perla 	status = be_cmd_notify_wait(adapter, &wrb);
13309aebddd1SJeff Kirsher 	if (!status) {
13317707133cSSathya Perla 		struct be_cmd_resp_eth_tx_create *resp = embedded_payload(&wrb);
133203d28ffeSKalesh AP 
13339aebddd1SJeff Kirsher 		txq->id = le16_to_cpu(resp->cid);
133494d73aaaSVasundhara Volam 		if (ver == 2)
133594d73aaaSVasundhara Volam 			txo->db_offset = le32_to_cpu(resp->db_offset);
133694d73aaaSVasundhara Volam 		else
133794d73aaaSVasundhara Volam 			txo->db_offset = DB_TXULP1_OFFSET;
13389aebddd1SJeff Kirsher 		txq->created = true;
13399aebddd1SJeff Kirsher 	}
13409aebddd1SJeff Kirsher 
13419aebddd1SJeff Kirsher 	return status;
13429aebddd1SJeff Kirsher }
13439aebddd1SJeff Kirsher 
13449aebddd1SJeff Kirsher /* Uses MCC */
13459aebddd1SJeff Kirsher int be_cmd_rxq_create(struct be_adapter *adapter,
13469aebddd1SJeff Kirsher 		      struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
134710ef9ab4SSathya Perla 		      u32 if_id, u32 rss, u8 *rss_id)
13489aebddd1SJeff Kirsher {
13499aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
13509aebddd1SJeff Kirsher 	struct be_cmd_req_eth_rx_create *req;
13519aebddd1SJeff Kirsher 	struct be_dma_mem *q_mem = &rxq->dma_mem;
13529aebddd1SJeff Kirsher 	int status;
13539aebddd1SJeff Kirsher 
13549aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
13559aebddd1SJeff Kirsher 
13569aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
13579aebddd1SJeff Kirsher 	if (!wrb) {
13589aebddd1SJeff Kirsher 		status = -EBUSY;
13599aebddd1SJeff Kirsher 		goto err;
13609aebddd1SJeff Kirsher 	}
13619aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
13629aebddd1SJeff Kirsher 
1363106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1364106df1e3SSomnath Kotur 			       OPCODE_ETH_RX_CREATE, sizeof(*req), wrb, NULL);
13659aebddd1SJeff Kirsher 
13669aebddd1SJeff Kirsher 	req->cq_id = cpu_to_le16(cq_id);
13679aebddd1SJeff Kirsher 	req->frag_size = fls(frag_size) - 1;
13689aebddd1SJeff Kirsher 	req->num_pages = 2;
13699aebddd1SJeff Kirsher 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
13709aebddd1SJeff Kirsher 	req->interface_id = cpu_to_le32(if_id);
137110ef9ab4SSathya Perla 	req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
13729aebddd1SJeff Kirsher 	req->rss_queue = cpu_to_le32(rss);
13739aebddd1SJeff Kirsher 
13749aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
13759aebddd1SJeff Kirsher 	if (!status) {
13769aebddd1SJeff Kirsher 		struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
137703d28ffeSKalesh AP 
13789aebddd1SJeff Kirsher 		rxq->id = le16_to_cpu(resp->id);
13799aebddd1SJeff Kirsher 		rxq->created = true;
13809aebddd1SJeff Kirsher 		*rss_id = resp->rss_id;
13819aebddd1SJeff Kirsher 	}
13829aebddd1SJeff Kirsher 
13839aebddd1SJeff Kirsher err:
13849aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
13859aebddd1SJeff Kirsher 	return status;
13869aebddd1SJeff Kirsher }
13879aebddd1SJeff Kirsher 
13889aebddd1SJeff Kirsher /* Generic destroyer function for all types of queues
13899aebddd1SJeff Kirsher  * Uses Mbox
13909aebddd1SJeff Kirsher  */
13919aebddd1SJeff Kirsher int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
13929aebddd1SJeff Kirsher 		     int queue_type)
13939aebddd1SJeff Kirsher {
13949aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
13959aebddd1SJeff Kirsher 	struct be_cmd_req_q_destroy *req;
13969aebddd1SJeff Kirsher 	u8 subsys = 0, opcode = 0;
13979aebddd1SJeff Kirsher 	int status;
13989aebddd1SJeff Kirsher 
13999aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
14009aebddd1SJeff Kirsher 		return -1;
14019aebddd1SJeff Kirsher 
14029aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
14039aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
14049aebddd1SJeff Kirsher 
14059aebddd1SJeff Kirsher 	switch (queue_type) {
14069aebddd1SJeff Kirsher 	case QTYPE_EQ:
14079aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
14089aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_EQ_DESTROY;
14099aebddd1SJeff Kirsher 		break;
14109aebddd1SJeff Kirsher 	case QTYPE_CQ:
14119aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
14129aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_CQ_DESTROY;
14139aebddd1SJeff Kirsher 		break;
14149aebddd1SJeff Kirsher 	case QTYPE_TXQ:
14159aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_ETH;
14169aebddd1SJeff Kirsher 		opcode = OPCODE_ETH_TX_DESTROY;
14179aebddd1SJeff Kirsher 		break;
14189aebddd1SJeff Kirsher 	case QTYPE_RXQ:
14199aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_ETH;
14209aebddd1SJeff Kirsher 		opcode = OPCODE_ETH_RX_DESTROY;
14219aebddd1SJeff Kirsher 		break;
14229aebddd1SJeff Kirsher 	case QTYPE_MCCQ:
14239aebddd1SJeff Kirsher 		subsys = CMD_SUBSYSTEM_COMMON;
14249aebddd1SJeff Kirsher 		opcode = OPCODE_COMMON_MCC_DESTROY;
14259aebddd1SJeff Kirsher 		break;
14269aebddd1SJeff Kirsher 	default:
14279aebddd1SJeff Kirsher 		BUG();
14289aebddd1SJeff Kirsher 	}
14299aebddd1SJeff Kirsher 
1430106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req), wrb,
1431106df1e3SSomnath Kotur 			       NULL);
14329aebddd1SJeff Kirsher 	req->id = cpu_to_le16(q->id);
14339aebddd1SJeff Kirsher 
14349aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
14359aebddd1SJeff Kirsher 	q->created = false;
14369aebddd1SJeff Kirsher 
14379aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
14389aebddd1SJeff Kirsher 	return status;
14399aebddd1SJeff Kirsher }
14409aebddd1SJeff Kirsher 
14419aebddd1SJeff Kirsher /* Uses MCC */
14429aebddd1SJeff Kirsher int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
14439aebddd1SJeff Kirsher {
14449aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
14459aebddd1SJeff Kirsher 	struct be_cmd_req_q_destroy *req;
14469aebddd1SJeff Kirsher 	int status;
14479aebddd1SJeff Kirsher 
14489aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
14499aebddd1SJeff Kirsher 
14509aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
14519aebddd1SJeff Kirsher 	if (!wrb) {
14529aebddd1SJeff Kirsher 		status = -EBUSY;
14539aebddd1SJeff Kirsher 		goto err;
14549aebddd1SJeff Kirsher 	}
14559aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
14569aebddd1SJeff Kirsher 
1457106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1458106df1e3SSomnath Kotur 			       OPCODE_ETH_RX_DESTROY, sizeof(*req), wrb, NULL);
14599aebddd1SJeff Kirsher 	req->id = cpu_to_le16(q->id);
14609aebddd1SJeff Kirsher 
14619aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
14629aebddd1SJeff Kirsher 	q->created = false;
14639aebddd1SJeff Kirsher 
14649aebddd1SJeff Kirsher err:
14659aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
14669aebddd1SJeff Kirsher 	return status;
14679aebddd1SJeff Kirsher }
14689aebddd1SJeff Kirsher 
14699aebddd1SJeff Kirsher /* Create an rx filtering policy configuration on an i/f
1470bea50988SSathya Perla  * Will use MBOX only if MCCQ has not been created.
14719aebddd1SJeff Kirsher  */
14729aebddd1SJeff Kirsher int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
14731578e777SPadmanabh Ratnakar 		     u32 *if_handle, u32 domain)
14749aebddd1SJeff Kirsher {
1475bea50988SSathya Perla 	struct be_mcc_wrb wrb = {0};
14769aebddd1SJeff Kirsher 	struct be_cmd_req_if_create *req;
14779aebddd1SJeff Kirsher 	int status;
14789aebddd1SJeff Kirsher 
1479bea50988SSathya Perla 	req = embedded_payload(&wrb);
1480106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1481a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_INTERFACE_CREATE,
1482a2cc4e0bSSathya Perla 			       sizeof(*req), &wrb, NULL);
14839aebddd1SJeff Kirsher 	req->hdr.domain = domain;
14849aebddd1SJeff Kirsher 	req->capability_flags = cpu_to_le32(cap_flags);
14859aebddd1SJeff Kirsher 	req->enable_flags = cpu_to_le32(en_flags);
1486f9449ab7SSathya Perla 	req->pmac_invalid = true;
14879aebddd1SJeff Kirsher 
1488bea50988SSathya Perla 	status = be_cmd_notify_wait(adapter, &wrb);
14899aebddd1SJeff Kirsher 	if (!status) {
1490bea50988SSathya Perla 		struct be_cmd_resp_if_create *resp = embedded_payload(&wrb);
149103d28ffeSKalesh AP 
14929aebddd1SJeff Kirsher 		*if_handle = le32_to_cpu(resp->interface_id);
1493b5bb9776SSathya Perla 
1494b5bb9776SSathya Perla 		/* Hack to retrieve VF's pmac-id on BE3 */
149518c57c74SKalesh AP 		if (BE3_chip(adapter) && be_virtfn(adapter))
1496b5bb9776SSathya Perla 			adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id);
14979aebddd1SJeff Kirsher 	}
14989aebddd1SJeff Kirsher 	return status;
14999aebddd1SJeff Kirsher }
15009aebddd1SJeff Kirsher 
1501f9449ab7SSathya Perla /* Uses MCCQ */
150230128031SSathya Perla int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
15039aebddd1SJeff Kirsher {
15049aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
15059aebddd1SJeff Kirsher 	struct be_cmd_req_if_destroy *req;
15069aebddd1SJeff Kirsher 	int status;
15079aebddd1SJeff Kirsher 
150830128031SSathya Perla 	if (interface_id == -1)
1509f9449ab7SSathya Perla 		return 0;
15109aebddd1SJeff Kirsher 
1511f9449ab7SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
1512f9449ab7SSathya Perla 
1513f9449ab7SSathya Perla 	wrb = wrb_from_mccq(adapter);
1514f9449ab7SSathya Perla 	if (!wrb) {
1515f9449ab7SSathya Perla 		status = -EBUSY;
1516f9449ab7SSathya Perla 		goto err;
1517f9449ab7SSathya Perla 	}
15189aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
15199aebddd1SJeff Kirsher 
1520106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1521a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_INTERFACE_DESTROY,
1522a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
15239aebddd1SJeff Kirsher 	req->hdr.domain = domain;
15249aebddd1SJeff Kirsher 	req->interface_id = cpu_to_le32(interface_id);
15259aebddd1SJeff Kirsher 
1526f9449ab7SSathya Perla 	status = be_mcc_notify_wait(adapter);
1527f9449ab7SSathya Perla err:
1528f9449ab7SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
15299aebddd1SJeff Kirsher 	return status;
15309aebddd1SJeff Kirsher }
15319aebddd1SJeff Kirsher 
15329aebddd1SJeff Kirsher /* Get stats is a non embedded command: the request is not embedded inside
15339aebddd1SJeff Kirsher  * WRB but is a separate dma memory block
15349aebddd1SJeff Kirsher  * Uses asynchronous MCC
15359aebddd1SJeff Kirsher  */
15369aebddd1SJeff Kirsher int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
15379aebddd1SJeff Kirsher {
15389aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
15399aebddd1SJeff Kirsher 	struct be_cmd_req_hdr *hdr;
15409aebddd1SJeff Kirsher 	int status = 0;
15419aebddd1SJeff Kirsher 
15429aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
15439aebddd1SJeff Kirsher 
15449aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
15459aebddd1SJeff Kirsher 	if (!wrb) {
15469aebddd1SJeff Kirsher 		status = -EBUSY;
15479aebddd1SJeff Kirsher 		goto err;
15489aebddd1SJeff Kirsher 	}
15499aebddd1SJeff Kirsher 	hdr = nonemb_cmd->va;
15509aebddd1SJeff Kirsher 
1551106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
1552a2cc4e0bSSathya Perla 			       OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb,
1553a2cc4e0bSSathya Perla 			       nonemb_cmd);
15549aebddd1SJeff Kirsher 
1555ca34fe38SSathya Perla 	/* version 1 of the cmd is not supported only by BE2 */
155661000861SAjit Khaparde 	if (BE2_chip(adapter))
155761000861SAjit Khaparde 		hdr->version = 0;
155861000861SAjit Khaparde 	if (BE3_chip(adapter) || lancer_chip(adapter))
15599aebddd1SJeff Kirsher 		hdr->version = 1;
156061000861SAjit Khaparde 	else
156161000861SAjit Khaparde 		hdr->version = 2;
15629aebddd1SJeff Kirsher 
1563efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
1564efaa408eSSuresh Reddy 	if (status)
1565efaa408eSSuresh Reddy 		goto err;
1566efaa408eSSuresh Reddy 
15679aebddd1SJeff Kirsher 	adapter->stats_cmd_sent = true;
15689aebddd1SJeff Kirsher 
15699aebddd1SJeff Kirsher err:
15709aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
15719aebddd1SJeff Kirsher 	return status;
15729aebddd1SJeff Kirsher }
15739aebddd1SJeff Kirsher 
15749aebddd1SJeff Kirsher /* Lancer Stats */
15759aebddd1SJeff Kirsher int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
15769aebddd1SJeff Kirsher 			       struct be_dma_mem *nonemb_cmd)
15779aebddd1SJeff Kirsher {
15789aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
15799aebddd1SJeff Kirsher 	struct lancer_cmd_req_pport_stats *req;
15809aebddd1SJeff Kirsher 	int status = 0;
15819aebddd1SJeff Kirsher 
1582f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
1583f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_ETH))
1584f25b119cSPadmanabh Ratnakar 		return -EPERM;
1585f25b119cSPadmanabh Ratnakar 
15869aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
15879aebddd1SJeff Kirsher 
15889aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
15899aebddd1SJeff Kirsher 	if (!wrb) {
15909aebddd1SJeff Kirsher 		status = -EBUSY;
15919aebddd1SJeff Kirsher 		goto err;
15929aebddd1SJeff Kirsher 	}
15939aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
15949aebddd1SJeff Kirsher 
1595106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1596a2cc4e0bSSathya Perla 			       OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size,
1597a2cc4e0bSSathya Perla 			       wrb, nonemb_cmd);
15989aebddd1SJeff Kirsher 
1599d51ebd33SPadmanabh Ratnakar 	req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
16009aebddd1SJeff Kirsher 	req->cmd_params.params.reset_stats = 0;
16019aebddd1SJeff Kirsher 
1602efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
1603efaa408eSSuresh Reddy 	if (status)
1604efaa408eSSuresh Reddy 		goto err;
1605efaa408eSSuresh Reddy 
16069aebddd1SJeff Kirsher 	adapter->stats_cmd_sent = true;
16079aebddd1SJeff Kirsher 
16089aebddd1SJeff Kirsher err:
16099aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
16109aebddd1SJeff Kirsher 	return status;
16119aebddd1SJeff Kirsher }
16129aebddd1SJeff Kirsher 
1613323ff71eSSathya Perla static int be_mac_to_link_speed(int mac_speed)
1614323ff71eSSathya Perla {
1615323ff71eSSathya Perla 	switch (mac_speed) {
1616323ff71eSSathya Perla 	case PHY_LINK_SPEED_ZERO:
1617323ff71eSSathya Perla 		return 0;
1618323ff71eSSathya Perla 	case PHY_LINK_SPEED_10MBPS:
1619323ff71eSSathya Perla 		return 10;
1620323ff71eSSathya Perla 	case PHY_LINK_SPEED_100MBPS:
1621323ff71eSSathya Perla 		return 100;
1622323ff71eSSathya Perla 	case PHY_LINK_SPEED_1GBPS:
1623323ff71eSSathya Perla 		return 1000;
1624323ff71eSSathya Perla 	case PHY_LINK_SPEED_10GBPS:
1625323ff71eSSathya Perla 		return 10000;
1626b971f847SVasundhara Volam 	case PHY_LINK_SPEED_20GBPS:
1627b971f847SVasundhara Volam 		return 20000;
1628b971f847SVasundhara Volam 	case PHY_LINK_SPEED_25GBPS:
1629b971f847SVasundhara Volam 		return 25000;
1630b971f847SVasundhara Volam 	case PHY_LINK_SPEED_40GBPS:
1631b971f847SVasundhara Volam 		return 40000;
1632323ff71eSSathya Perla 	}
1633323ff71eSSathya Perla 	return 0;
1634323ff71eSSathya Perla }
1635323ff71eSSathya Perla 
1636323ff71eSSathya Perla /* Uses synchronous mcc
1637323ff71eSSathya Perla  * Returns link_speed in Mbps
1638323ff71eSSathya Perla  */
1639323ff71eSSathya Perla int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
1640323ff71eSSathya Perla 			     u8 *link_status, u32 dom)
16419aebddd1SJeff Kirsher {
16429aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
16439aebddd1SJeff Kirsher 	struct be_cmd_req_link_status *req;
16449aebddd1SJeff Kirsher 	int status;
16459aebddd1SJeff Kirsher 
16469aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
16479aebddd1SJeff Kirsher 
1648b236916aSAjit Khaparde 	if (link_status)
1649b236916aSAjit Khaparde 		*link_status = LINK_DOWN;
1650b236916aSAjit Khaparde 
16519aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
16529aebddd1SJeff Kirsher 	if (!wrb) {
16539aebddd1SJeff Kirsher 		status = -EBUSY;
16549aebddd1SJeff Kirsher 		goto err;
16559aebddd1SJeff Kirsher 	}
16569aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
16579aebddd1SJeff Kirsher 
165857cd80d4SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1659a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1660a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
166157cd80d4SPadmanabh Ratnakar 
1662ca34fe38SSathya Perla 	/* version 1 of the cmd is not supported only by BE2 */
1663ca34fe38SSathya Perla 	if (!BE2_chip(adapter))
1664daad6167SPadmanabh Ratnakar 		req->hdr.version = 1;
1665daad6167SPadmanabh Ratnakar 
166657cd80d4SPadmanabh Ratnakar 	req->hdr.domain = dom;
16679aebddd1SJeff Kirsher 
16689aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
16699aebddd1SJeff Kirsher 	if (!status) {
16709aebddd1SJeff Kirsher 		struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
167103d28ffeSKalesh AP 
1672323ff71eSSathya Perla 		if (link_speed) {
1673323ff71eSSathya Perla 			*link_speed = resp->link_speed ?
1674323ff71eSSathya Perla 				      le16_to_cpu(resp->link_speed) * 10 :
1675323ff71eSSathya Perla 				      be_mac_to_link_speed(resp->mac_speed);
1676323ff71eSSathya Perla 
1677323ff71eSSathya Perla 			if (!resp->logical_link_status)
1678323ff71eSSathya Perla 				*link_speed = 0;
16799aebddd1SJeff Kirsher 		}
1680b236916aSAjit Khaparde 		if (link_status)
1681b236916aSAjit Khaparde 			*link_status = resp->logical_link_status;
16829aebddd1SJeff Kirsher 	}
16839aebddd1SJeff Kirsher 
16849aebddd1SJeff Kirsher err:
16859aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
16869aebddd1SJeff Kirsher 	return status;
16879aebddd1SJeff Kirsher }
16889aebddd1SJeff Kirsher 
16899aebddd1SJeff Kirsher /* Uses synchronous mcc */
16909aebddd1SJeff Kirsher int be_cmd_get_die_temperature(struct be_adapter *adapter)
16919aebddd1SJeff Kirsher {
16929aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
16939aebddd1SJeff Kirsher 	struct be_cmd_req_get_cntl_addnl_attribs *req;
1694117affe3SVasundhara Volam 	int status = 0;
16959aebddd1SJeff Kirsher 
16969aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
16979aebddd1SJeff Kirsher 
16989aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
16999aebddd1SJeff Kirsher 	if (!wrb) {
17009aebddd1SJeff Kirsher 		status = -EBUSY;
17019aebddd1SJeff Kirsher 		goto err;
17029aebddd1SJeff Kirsher 	}
17039aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
17049aebddd1SJeff Kirsher 
1705106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1706a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES,
1707a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
17089aebddd1SJeff Kirsher 
1709efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
17109aebddd1SJeff Kirsher err:
17119aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
17129aebddd1SJeff Kirsher 	return status;
17139aebddd1SJeff Kirsher }
17149aebddd1SJeff Kirsher 
17159aebddd1SJeff Kirsher /* Uses synchronous mcc */
17169aebddd1SJeff Kirsher int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
17179aebddd1SJeff Kirsher {
17189aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
17199aebddd1SJeff Kirsher 	struct be_cmd_req_get_fat *req;
17209aebddd1SJeff Kirsher 	int status;
17219aebddd1SJeff Kirsher 
17229aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
17239aebddd1SJeff Kirsher 
17249aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
17259aebddd1SJeff Kirsher 	if (!wrb) {
17269aebddd1SJeff Kirsher 		status = -EBUSY;
17279aebddd1SJeff Kirsher 		goto err;
17289aebddd1SJeff Kirsher 	}
17299aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
17309aebddd1SJeff Kirsher 
1731106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1732a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MANAGE_FAT, sizeof(*req), wrb,
1733a2cc4e0bSSathya Perla 			       NULL);
17349aebddd1SJeff Kirsher 	req->fat_operation = cpu_to_le32(QUERY_FAT);
17359aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
17369aebddd1SJeff Kirsher 	if (!status) {
17379aebddd1SJeff Kirsher 		struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
173803d28ffeSKalesh AP 
17399aebddd1SJeff Kirsher 		if (log_size && resp->log_size)
17409aebddd1SJeff Kirsher 			*log_size = le32_to_cpu(resp->log_size) -
17419aebddd1SJeff Kirsher 					sizeof(u32);
17429aebddd1SJeff Kirsher 	}
17439aebddd1SJeff Kirsher err:
17449aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
17459aebddd1SJeff Kirsher 	return status;
17469aebddd1SJeff Kirsher }
17479aebddd1SJeff Kirsher 
1748c5f156deSVasundhara Volam int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
17499aebddd1SJeff Kirsher {
17509aebddd1SJeff Kirsher 	struct be_dma_mem get_fat_cmd;
17519aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
17529aebddd1SJeff Kirsher 	struct be_cmd_req_get_fat *req;
17539aebddd1SJeff Kirsher 	u32 offset = 0, total_size, buf_size,
17549aebddd1SJeff Kirsher 				log_offset = sizeof(u32), payload_len;
1755c5f156deSVasundhara Volam 	int status = 0;
17569aebddd1SJeff Kirsher 
17579aebddd1SJeff Kirsher 	if (buf_len == 0)
1758c5f156deSVasundhara Volam 		return -EIO;
17599aebddd1SJeff Kirsher 
17609aebddd1SJeff Kirsher 	total_size = buf_len;
17619aebddd1SJeff Kirsher 
17629aebddd1SJeff Kirsher 	get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
1763e51000dbSSriharsha Basavapatna 	get_fat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
17649aebddd1SJeff Kirsher 					     get_fat_cmd.size,
1765e51000dbSSriharsha Basavapatna 					     &get_fat_cmd.dma, GFP_ATOMIC);
17669aebddd1SJeff Kirsher 	if (!get_fat_cmd.va) {
17679aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev,
1768cd3307aaSKalesh AP 			"Memory allocation failure while reading FAT data\n");
1769c5f156deSVasundhara Volam 		return -ENOMEM;
17709aebddd1SJeff Kirsher 	}
17719aebddd1SJeff Kirsher 
17729aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
17739aebddd1SJeff Kirsher 
17749aebddd1SJeff Kirsher 	while (total_size) {
17759aebddd1SJeff Kirsher 		buf_size = min(total_size, (u32)60*1024);
17769aebddd1SJeff Kirsher 		total_size -= buf_size;
17779aebddd1SJeff Kirsher 
17789aebddd1SJeff Kirsher 		wrb = wrb_from_mccq(adapter);
17799aebddd1SJeff Kirsher 		if (!wrb) {
17809aebddd1SJeff Kirsher 			status = -EBUSY;
17819aebddd1SJeff Kirsher 			goto err;
17829aebddd1SJeff Kirsher 		}
17839aebddd1SJeff Kirsher 		req = get_fat_cmd.va;
17849aebddd1SJeff Kirsher 
17859aebddd1SJeff Kirsher 		payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
1786106df1e3SSomnath Kotur 		be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1787a2cc4e0bSSathya Perla 				       OPCODE_COMMON_MANAGE_FAT, payload_len,
1788a2cc4e0bSSathya Perla 				       wrb, &get_fat_cmd);
17899aebddd1SJeff Kirsher 
17909aebddd1SJeff Kirsher 		req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
17919aebddd1SJeff Kirsher 		req->read_log_offset = cpu_to_le32(log_offset);
17929aebddd1SJeff Kirsher 		req->read_log_length = cpu_to_le32(buf_size);
17939aebddd1SJeff Kirsher 		req->data_buffer_size = cpu_to_le32(buf_size);
17949aebddd1SJeff Kirsher 
17959aebddd1SJeff Kirsher 		status = be_mcc_notify_wait(adapter);
17969aebddd1SJeff Kirsher 		if (!status) {
17979aebddd1SJeff Kirsher 			struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
179803d28ffeSKalesh AP 
17999aebddd1SJeff Kirsher 			memcpy(buf + offset,
18009aebddd1SJeff Kirsher 			       resp->data_buffer,
180192aa9214SSomnath Kotur 			       le32_to_cpu(resp->read_log_length));
18029aebddd1SJeff Kirsher 		} else {
18039aebddd1SJeff Kirsher 			dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
18049aebddd1SJeff Kirsher 			goto err;
18059aebddd1SJeff Kirsher 		}
18069aebddd1SJeff Kirsher 		offset += buf_size;
18079aebddd1SJeff Kirsher 		log_offset += buf_size;
18089aebddd1SJeff Kirsher 	}
18099aebddd1SJeff Kirsher err:
1810e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size,
1811a2cc4e0bSSathya Perla 			  get_fat_cmd.va, get_fat_cmd.dma);
18129aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
1813c5f156deSVasundhara Volam 	return status;
18149aebddd1SJeff Kirsher }
18159aebddd1SJeff Kirsher 
181604b71175SSathya Perla /* Uses synchronous mcc */
1817e97e3cdaSKalesh AP int be_cmd_get_fw_ver(struct be_adapter *adapter)
18189aebddd1SJeff Kirsher {
18199aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
18209aebddd1SJeff Kirsher 	struct be_cmd_req_get_fw_version *req;
18219aebddd1SJeff Kirsher 	int status;
18229aebddd1SJeff Kirsher 
182304b71175SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
18249aebddd1SJeff Kirsher 
182504b71175SSathya Perla 	wrb = wrb_from_mccq(adapter);
182604b71175SSathya Perla 	if (!wrb) {
182704b71175SSathya Perla 		status = -EBUSY;
182804b71175SSathya Perla 		goto err;
182904b71175SSathya Perla 	}
183004b71175SSathya Perla 
18319aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
18329aebddd1SJeff Kirsher 
1833106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1834a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_FW_VERSION, sizeof(*req), wrb,
1835a2cc4e0bSSathya Perla 			       NULL);
183604b71175SSathya Perla 	status = be_mcc_notify_wait(adapter);
18379aebddd1SJeff Kirsher 	if (!status) {
18389aebddd1SJeff Kirsher 		struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
1839acbafeb1SSathya Perla 
1840242eb470SVasundhara Volam 		strlcpy(adapter->fw_ver, resp->firmware_version_string,
1841242eb470SVasundhara Volam 			sizeof(adapter->fw_ver));
1842242eb470SVasundhara Volam 		strlcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string,
1843242eb470SVasundhara Volam 			sizeof(adapter->fw_on_flash));
18449aebddd1SJeff Kirsher 	}
184504b71175SSathya Perla err:
184604b71175SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
18479aebddd1SJeff Kirsher 	return status;
18489aebddd1SJeff Kirsher }
18499aebddd1SJeff Kirsher 
18509aebddd1SJeff Kirsher /* set the EQ delay interval of an EQ to specified value
18519aebddd1SJeff Kirsher  * Uses async mcc
18529aebddd1SJeff Kirsher  */
1853b502ae8dSKalesh AP static int __be_cmd_modify_eqd(struct be_adapter *adapter,
1854b502ae8dSKalesh AP 			       struct be_set_eqd *set_eqd, int num)
18559aebddd1SJeff Kirsher {
18569aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
18579aebddd1SJeff Kirsher 	struct be_cmd_req_modify_eq_delay *req;
18582632bafdSSathya Perla 	int status = 0, i;
18599aebddd1SJeff Kirsher 
18609aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
18619aebddd1SJeff Kirsher 
18629aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
18639aebddd1SJeff Kirsher 	if (!wrb) {
18649aebddd1SJeff Kirsher 		status = -EBUSY;
18659aebddd1SJeff Kirsher 		goto err;
18669aebddd1SJeff Kirsher 	}
18679aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
18689aebddd1SJeff Kirsher 
1869106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1870a2cc4e0bSSathya Perla 			       OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req), wrb,
1871a2cc4e0bSSathya Perla 			       NULL);
18729aebddd1SJeff Kirsher 
18732632bafdSSathya Perla 	req->num_eq = cpu_to_le32(num);
18742632bafdSSathya Perla 	for (i = 0; i < num; i++) {
18752632bafdSSathya Perla 		req->set_eqd[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
18762632bafdSSathya Perla 		req->set_eqd[i].phase = 0;
18772632bafdSSathya Perla 		req->set_eqd[i].delay_multiplier =
18782632bafdSSathya Perla 				cpu_to_le32(set_eqd[i].delay_multiplier);
18792632bafdSSathya Perla 	}
18809aebddd1SJeff Kirsher 
1881efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
18829aebddd1SJeff Kirsher err:
18839aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
18849aebddd1SJeff Kirsher 	return status;
18859aebddd1SJeff Kirsher }
18869aebddd1SJeff Kirsher 
188793676703SKalesh AP int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
188893676703SKalesh AP 		      int num)
188993676703SKalesh AP {
189093676703SKalesh AP 	int num_eqs, i = 0;
189193676703SKalesh AP 
189293676703SKalesh AP 	while (num) {
189393676703SKalesh AP 		num_eqs = min(num, 8);
189493676703SKalesh AP 		__be_cmd_modify_eqd(adapter, &set_eqd[i], num_eqs);
189593676703SKalesh AP 		i += num_eqs;
189693676703SKalesh AP 		num -= num_eqs;
189793676703SKalesh AP 	}
189893676703SKalesh AP 
189993676703SKalesh AP 	return 0;
190093676703SKalesh AP }
190193676703SKalesh AP 
19029aebddd1SJeff Kirsher /* Uses sycnhronous mcc */
19039aebddd1SJeff Kirsher int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
1904435452aaSVasundhara Volam 		       u32 num, u32 domain)
19059aebddd1SJeff Kirsher {
19069aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
19079aebddd1SJeff Kirsher 	struct be_cmd_req_vlan_config *req;
19089aebddd1SJeff Kirsher 	int status;
19099aebddd1SJeff Kirsher 
19109aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
19119aebddd1SJeff Kirsher 
19129aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
19139aebddd1SJeff Kirsher 	if (!wrb) {
19149aebddd1SJeff Kirsher 		status = -EBUSY;
19159aebddd1SJeff Kirsher 		goto err;
19169aebddd1SJeff Kirsher 	}
19179aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
19189aebddd1SJeff Kirsher 
1919106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1920a2cc4e0bSSathya Perla 			       OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req),
1921a2cc4e0bSSathya Perla 			       wrb, NULL);
1922435452aaSVasundhara Volam 	req->hdr.domain = domain;
19239aebddd1SJeff Kirsher 
19249aebddd1SJeff Kirsher 	req->interface_id = if_id;
1925012bd387SAjit Khaparde 	req->untagged = BE_IF_FLAGS_UNTAGGED & be_if_cap_flags(adapter) ? 1 : 0;
19269aebddd1SJeff Kirsher 	req->num_vlan = num;
19279aebddd1SJeff Kirsher 	memcpy(req->normal_vlan, vtag_array,
19289aebddd1SJeff Kirsher 	       req->num_vlan * sizeof(vtag_array[0]));
19299aebddd1SJeff Kirsher 
19309aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
19319aebddd1SJeff Kirsher err:
19329aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
19339aebddd1SJeff Kirsher 	return status;
19349aebddd1SJeff Kirsher }
19359aebddd1SJeff Kirsher 
1936ac34b743SSathya Perla static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
19379aebddd1SJeff Kirsher {
19389aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
19399aebddd1SJeff Kirsher 	struct be_dma_mem *mem = &adapter->rx_filter;
19409aebddd1SJeff Kirsher 	struct be_cmd_req_rx_filter *req = mem->va;
19419aebddd1SJeff Kirsher 	int status;
19429aebddd1SJeff Kirsher 
19439aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
19449aebddd1SJeff Kirsher 
19459aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
19469aebddd1SJeff Kirsher 	if (!wrb) {
19479aebddd1SJeff Kirsher 		status = -EBUSY;
19489aebddd1SJeff Kirsher 		goto err;
19499aebddd1SJeff Kirsher 	}
19509aebddd1SJeff Kirsher 	memset(req, 0, sizeof(*req));
1951106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1952106df1e3SSomnath Kotur 			       OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req),
1953106df1e3SSomnath Kotur 			       wrb, mem);
19549aebddd1SJeff Kirsher 
19559aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(adapter->if_handle);
1956ac34b743SSathya Perla 	req->if_flags_mask = cpu_to_le32(flags);
1957ac34b743SSathya Perla 	req->if_flags = (value == ON) ? req->if_flags_mask : 0;
1958d9d604f8SAjit Khaparde 
1959ac34b743SSathya Perla 	if (flags & BE_IF_FLAGS_MULTICAST) {
19609aebddd1SJeff Kirsher 		struct netdev_hw_addr *ha;
19619aebddd1SJeff Kirsher 		int i = 0;
19629aebddd1SJeff Kirsher 
19631610c79fSPadmanabh Ratnakar 		/* Reset mcast promisc mode if already set by setting mask
19641610c79fSPadmanabh Ratnakar 		 * and not setting flags field
19651610c79fSPadmanabh Ratnakar 		 */
19661610c79fSPadmanabh Ratnakar 		req->if_flags_mask |=
1967abb93951SPadmanabh Ratnakar 			cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS &
196892bf14abSSathya Perla 				    be_if_cap_flags(adapter));
1969016f97b1SPadmanabh Ratnakar 		req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev));
19709aebddd1SJeff Kirsher 		netdev_for_each_mc_addr(ha, adapter->netdev)
19719aebddd1SJeff Kirsher 			memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
19729aebddd1SJeff Kirsher 	}
19739aebddd1SJeff Kirsher 
1974b6588879SSathya Perla 	status = be_mcc_notify_wait(adapter);
19759aebddd1SJeff Kirsher err:
19769aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
19779aebddd1SJeff Kirsher 	return status;
19789aebddd1SJeff Kirsher }
19799aebddd1SJeff Kirsher 
1980ac34b743SSathya Perla int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
1981ac34b743SSathya Perla {
1982ac34b743SSathya Perla 	struct device *dev = &adapter->pdev->dev;
1983ac34b743SSathya Perla 
1984ac34b743SSathya Perla 	if ((flags & be_if_cap_flags(adapter)) != flags) {
1985ac34b743SSathya Perla 		dev_warn(dev, "Cannot set rx filter flags 0x%x\n", flags);
1986ac34b743SSathya Perla 		dev_warn(dev, "Interface is capable of 0x%x flags only\n",
1987ac34b743SSathya Perla 			 be_if_cap_flags(adapter));
1988ac34b743SSathya Perla 	}
1989ac34b743SSathya Perla 	flags &= be_if_cap_flags(adapter);
1990196e3735SKalesh AP 	if (!flags)
1991196e3735SKalesh AP 		return -ENOTSUPP;
1992ac34b743SSathya Perla 
1993ac34b743SSathya Perla 	return __be_cmd_rx_filter(adapter, flags, value);
1994ac34b743SSathya Perla }
1995ac34b743SSathya Perla 
19969aebddd1SJeff Kirsher /* Uses synchrounous mcc */
19979aebddd1SJeff Kirsher int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
19989aebddd1SJeff Kirsher {
19999aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20009aebddd1SJeff Kirsher 	struct be_cmd_req_set_flow_control *req;
20019aebddd1SJeff Kirsher 	int status;
20029aebddd1SJeff Kirsher 
2003f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
2004f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
2005f25b119cSPadmanabh Ratnakar 		return -EPERM;
2006f25b119cSPadmanabh Ratnakar 
20079aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
20089aebddd1SJeff Kirsher 
20099aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
20109aebddd1SJeff Kirsher 	if (!wrb) {
20119aebddd1SJeff Kirsher 		status = -EBUSY;
20129aebddd1SJeff Kirsher 		goto err;
20139aebddd1SJeff Kirsher 	}
20149aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
20159aebddd1SJeff Kirsher 
2016106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2017a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req),
2018a2cc4e0bSSathya Perla 			       wrb, NULL);
20199aebddd1SJeff Kirsher 
2020b29812c1SSuresh Reddy 	req->hdr.version = 1;
20219aebddd1SJeff Kirsher 	req->tx_flow_control = cpu_to_le16((u16)tx_fc);
20229aebddd1SJeff Kirsher 	req->rx_flow_control = cpu_to_le16((u16)rx_fc);
20239aebddd1SJeff Kirsher 
20249aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
20259aebddd1SJeff Kirsher 
20269aebddd1SJeff Kirsher err:
20279aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
2028b29812c1SSuresh Reddy 
2029b29812c1SSuresh Reddy 	if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED)
2030b29812c1SSuresh Reddy 		return  -EOPNOTSUPP;
2031b29812c1SSuresh Reddy 
20329aebddd1SJeff Kirsher 	return status;
20339aebddd1SJeff Kirsher }
20349aebddd1SJeff Kirsher 
20359aebddd1SJeff Kirsher /* Uses sycn mcc */
20369aebddd1SJeff Kirsher int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
20379aebddd1SJeff Kirsher {
20389aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20399aebddd1SJeff Kirsher 	struct be_cmd_req_get_flow_control *req;
20409aebddd1SJeff Kirsher 	int status;
20419aebddd1SJeff Kirsher 
2042f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
2043f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
2044f25b119cSPadmanabh Ratnakar 		return -EPERM;
2045f25b119cSPadmanabh Ratnakar 
20469aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
20479aebddd1SJeff Kirsher 
20489aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
20499aebddd1SJeff Kirsher 	if (!wrb) {
20509aebddd1SJeff Kirsher 		status = -EBUSY;
20519aebddd1SJeff Kirsher 		goto err;
20529aebddd1SJeff Kirsher 	}
20539aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
20549aebddd1SJeff Kirsher 
2055106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2056a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req),
2057a2cc4e0bSSathya Perla 			       wrb, NULL);
20589aebddd1SJeff Kirsher 
20599aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
20609aebddd1SJeff Kirsher 	if (!status) {
20619aebddd1SJeff Kirsher 		struct be_cmd_resp_get_flow_control *resp =
20629aebddd1SJeff Kirsher 						embedded_payload(wrb);
206303d28ffeSKalesh AP 
20649aebddd1SJeff Kirsher 		*tx_fc = le16_to_cpu(resp->tx_flow_control);
20659aebddd1SJeff Kirsher 		*rx_fc = le16_to_cpu(resp->rx_flow_control);
20669aebddd1SJeff Kirsher 	}
20679aebddd1SJeff Kirsher 
20689aebddd1SJeff Kirsher err:
20699aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
20709aebddd1SJeff Kirsher 	return status;
20719aebddd1SJeff Kirsher }
20729aebddd1SJeff Kirsher 
20739aebddd1SJeff Kirsher /* Uses mbox */
2074e97e3cdaSKalesh AP int be_cmd_query_fw_cfg(struct be_adapter *adapter)
20759aebddd1SJeff Kirsher {
20769aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
20779aebddd1SJeff Kirsher 	struct be_cmd_req_query_fw_cfg *req;
20789aebddd1SJeff Kirsher 	int status;
20799aebddd1SJeff Kirsher 
20809aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
20819aebddd1SJeff Kirsher 		return -1;
20829aebddd1SJeff Kirsher 
20839aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
20849aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
20859aebddd1SJeff Kirsher 
2086106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2087a2cc4e0bSSathya Perla 			       OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
2088a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
20899aebddd1SJeff Kirsher 
20909aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
20919aebddd1SJeff Kirsher 	if (!status) {
20929aebddd1SJeff Kirsher 		struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
209303d28ffeSKalesh AP 
2094e97e3cdaSKalesh AP 		adapter->port_num = le32_to_cpu(resp->phys_port);
2095e97e3cdaSKalesh AP 		adapter->function_mode = le32_to_cpu(resp->function_mode);
2096e97e3cdaSKalesh AP 		adapter->function_caps = le32_to_cpu(resp->function_caps);
2097e97e3cdaSKalesh AP 		adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
2098acbafeb1SSathya Perla 		dev_info(&adapter->pdev->dev,
2099acbafeb1SSathya Perla 			 "FW config: function_mode=0x%x, function_caps=0x%x\n",
2100acbafeb1SSathya Perla 			 adapter->function_mode, adapter->function_caps);
21019aebddd1SJeff Kirsher 	}
21029aebddd1SJeff Kirsher 
21039aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
21049aebddd1SJeff Kirsher 	return status;
21059aebddd1SJeff Kirsher }
21069aebddd1SJeff Kirsher 
21079aebddd1SJeff Kirsher /* Uses mbox */
21089aebddd1SJeff Kirsher int be_cmd_reset_function(struct be_adapter *adapter)
21099aebddd1SJeff Kirsher {
21109aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21119aebddd1SJeff Kirsher 	struct be_cmd_req_hdr *req;
21129aebddd1SJeff Kirsher 	int status;
21139aebddd1SJeff Kirsher 
2114bf99e50dSPadmanabh Ratnakar 	if (lancer_chip(adapter)) {
2115bf99e50dSPadmanabh Ratnakar 		iowrite32(SLI_PORT_CONTROL_IP_MASK,
2116bf99e50dSPadmanabh Ratnakar 			  adapter->db + SLIPORT_CONTROL_OFFSET);
21179fa465c0SSathya Perla 		status = lancer_wait_ready(adapter);
21189fa465c0SSathya Perla 		if (status)
2119bf99e50dSPadmanabh Ratnakar 			dev_err(&adapter->pdev->dev,
2120bf99e50dSPadmanabh Ratnakar 				"Adapter in non recoverable error\n");
2121bf99e50dSPadmanabh Ratnakar 		return status;
2122bf99e50dSPadmanabh Ratnakar 	}
2123bf99e50dSPadmanabh Ratnakar 
21249aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
21259aebddd1SJeff Kirsher 		return -1;
21269aebddd1SJeff Kirsher 
21279aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
21289aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21299aebddd1SJeff Kirsher 
2130106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
2131a2cc4e0bSSathya Perla 			       OPCODE_COMMON_FUNCTION_RESET, sizeof(*req), wrb,
2132a2cc4e0bSSathya Perla 			       NULL);
21339aebddd1SJeff Kirsher 
21349aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
21359aebddd1SJeff Kirsher 
21369aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
21379aebddd1SJeff Kirsher 	return status;
21389aebddd1SJeff Kirsher }
21399aebddd1SJeff Kirsher 
2140594ad54aSSuresh Reddy int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
214133cb0fa7SBen Hutchings 		      u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey)
21429aebddd1SJeff Kirsher {
21439aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21449aebddd1SJeff Kirsher 	struct be_cmd_req_rss_config *req;
21459aebddd1SJeff Kirsher 	int status;
21469aebddd1SJeff Kirsher 
2147da1388d6SVasundhara Volam 	if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
2148da1388d6SVasundhara Volam 		return 0;
2149da1388d6SVasundhara Volam 
2150b51aa367SKalesh AP 	spin_lock_bh(&adapter->mcc_lock);
21519aebddd1SJeff Kirsher 
2152b51aa367SKalesh AP 	wrb = wrb_from_mccq(adapter);
2153b51aa367SKalesh AP 	if (!wrb) {
2154b51aa367SKalesh AP 		status = -EBUSY;
2155b51aa367SKalesh AP 		goto err;
2156b51aa367SKalesh AP 	}
21579aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21589aebddd1SJeff Kirsher 
2159106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
2160106df1e3SSomnath Kotur 			       OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
21619aebddd1SJeff Kirsher 
21629aebddd1SJeff Kirsher 	req->if_id = cpu_to_le32(adapter->if_handle);
2163594ad54aSSuresh Reddy 	req->enable_rss = cpu_to_le16(rss_hash_opts);
21649aebddd1SJeff Kirsher 	req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
2165594ad54aSSuresh Reddy 
2166b51aa367SKalesh AP 	if (!BEx_chip(adapter))
2167594ad54aSSuresh Reddy 		req->hdr.version = 1;
2168594ad54aSSuresh Reddy 
21699aebddd1SJeff Kirsher 	memcpy(req->cpu_table, rsstable, table_size);
2170e2557877SVenkata Duvvuru 	memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
21719aebddd1SJeff Kirsher 	be_dws_cpu_to_le(req->hash, sizeof(req->hash));
21729aebddd1SJeff Kirsher 
2173b51aa367SKalesh AP 	status = be_mcc_notify_wait(adapter);
2174b51aa367SKalesh AP err:
2175b51aa367SKalesh AP 	spin_unlock_bh(&adapter->mcc_lock);
21769aebddd1SJeff Kirsher 	return status;
21779aebddd1SJeff Kirsher }
21789aebddd1SJeff Kirsher 
21799aebddd1SJeff Kirsher /* Uses sync mcc */
21809aebddd1SJeff Kirsher int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
21819aebddd1SJeff Kirsher 			    u8 bcn, u8 sts, u8 state)
21829aebddd1SJeff Kirsher {
21839aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
21849aebddd1SJeff Kirsher 	struct be_cmd_req_enable_disable_beacon *req;
21859aebddd1SJeff Kirsher 	int status;
21869aebddd1SJeff Kirsher 
21879aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
21889aebddd1SJeff Kirsher 
21899aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
21909aebddd1SJeff Kirsher 	if (!wrb) {
21919aebddd1SJeff Kirsher 		status = -EBUSY;
21929aebddd1SJeff Kirsher 		goto err;
21939aebddd1SJeff Kirsher 	}
21949aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
21959aebddd1SJeff Kirsher 
2196106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2197a2cc4e0bSSathya Perla 			       OPCODE_COMMON_ENABLE_DISABLE_BEACON,
2198a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
21999aebddd1SJeff Kirsher 
22009aebddd1SJeff Kirsher 	req->port_num = port_num;
22019aebddd1SJeff Kirsher 	req->beacon_state = state;
22029aebddd1SJeff Kirsher 	req->beacon_duration = bcn;
22039aebddd1SJeff Kirsher 	req->status_duration = sts;
22049aebddd1SJeff Kirsher 
22059aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
22069aebddd1SJeff Kirsher 
22079aebddd1SJeff Kirsher err:
22089aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
22099aebddd1SJeff Kirsher 	return status;
22109aebddd1SJeff Kirsher }
22119aebddd1SJeff Kirsher 
22129aebddd1SJeff Kirsher /* Uses sync mcc */
22139aebddd1SJeff Kirsher int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
22149aebddd1SJeff Kirsher {
22159aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
22169aebddd1SJeff Kirsher 	struct be_cmd_req_get_beacon_state *req;
22179aebddd1SJeff Kirsher 	int status;
22189aebddd1SJeff Kirsher 
22199aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
22209aebddd1SJeff Kirsher 
22219aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
22229aebddd1SJeff Kirsher 	if (!wrb) {
22239aebddd1SJeff Kirsher 		status = -EBUSY;
22249aebddd1SJeff Kirsher 		goto err;
22259aebddd1SJeff Kirsher 	}
22269aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
22279aebddd1SJeff Kirsher 
2228106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2229a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req),
2230a2cc4e0bSSathya Perla 			       wrb, NULL);
22319aebddd1SJeff Kirsher 
22329aebddd1SJeff Kirsher 	req->port_num = port_num;
22339aebddd1SJeff Kirsher 
22349aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
22359aebddd1SJeff Kirsher 	if (!status) {
22369aebddd1SJeff Kirsher 		struct be_cmd_resp_get_beacon_state *resp =
22379aebddd1SJeff Kirsher 						embedded_payload(wrb);
223803d28ffeSKalesh AP 
22399aebddd1SJeff Kirsher 		*state = resp->beacon_state;
22409aebddd1SJeff Kirsher 	}
22419aebddd1SJeff Kirsher 
22429aebddd1SJeff Kirsher err:
22439aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
22449aebddd1SJeff Kirsher 	return status;
22459aebddd1SJeff Kirsher }
22469aebddd1SJeff Kirsher 
2247e36edd9dSMark Leonard /* Uses sync mcc */
2248e36edd9dSMark Leonard int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2249e36edd9dSMark Leonard 				      u8 page_num, u8 *data)
2250e36edd9dSMark Leonard {
2251e36edd9dSMark Leonard 	struct be_dma_mem cmd;
2252e36edd9dSMark Leonard 	struct be_mcc_wrb *wrb;
2253e36edd9dSMark Leonard 	struct be_cmd_req_port_type *req;
2254e36edd9dSMark Leonard 	int status;
2255e36edd9dSMark Leonard 
2256e36edd9dSMark Leonard 	if (page_num > TR_PAGE_A2)
2257e36edd9dSMark Leonard 		return -EINVAL;
2258e36edd9dSMark Leonard 
2259e36edd9dSMark Leonard 	cmd.size = sizeof(struct be_cmd_resp_port_type);
2260e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
2261e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
2262e36edd9dSMark Leonard 	if (!cmd.va) {
2263e36edd9dSMark Leonard 		dev_err(&adapter->pdev->dev, "Memory allocation failed\n");
2264e36edd9dSMark Leonard 		return -ENOMEM;
2265e36edd9dSMark Leonard 	}
2266e36edd9dSMark Leonard 
2267e36edd9dSMark Leonard 	spin_lock_bh(&adapter->mcc_lock);
2268e36edd9dSMark Leonard 
2269e36edd9dSMark Leonard 	wrb = wrb_from_mccq(adapter);
2270e36edd9dSMark Leonard 	if (!wrb) {
2271e36edd9dSMark Leonard 		status = -EBUSY;
2272e36edd9dSMark Leonard 		goto err;
2273e36edd9dSMark Leonard 	}
2274e36edd9dSMark Leonard 	req = cmd.va;
2275e36edd9dSMark Leonard 
2276e36edd9dSMark Leonard 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2277e36edd9dSMark Leonard 			       OPCODE_COMMON_READ_TRANSRECV_DATA,
2278e36edd9dSMark Leonard 			       cmd.size, wrb, &cmd);
2279e36edd9dSMark Leonard 
2280e36edd9dSMark Leonard 	req->port = cpu_to_le32(adapter->hba_port_num);
2281e36edd9dSMark Leonard 	req->page_num = cpu_to_le32(page_num);
2282e36edd9dSMark Leonard 	status = be_mcc_notify_wait(adapter);
2283e36edd9dSMark Leonard 	if (!status) {
2284e36edd9dSMark Leonard 		struct be_cmd_resp_port_type *resp = cmd.va;
2285e36edd9dSMark Leonard 
2286e36edd9dSMark Leonard 		memcpy(data, resp->page_data, PAGE_DATA_LEN);
2287e36edd9dSMark Leonard 	}
2288e36edd9dSMark Leonard err:
2289e36edd9dSMark Leonard 	spin_unlock_bh(&adapter->mcc_lock);
2290e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
2291e36edd9dSMark Leonard 	return status;
2292e36edd9dSMark Leonard }
2293e36edd9dSMark Leonard 
22949aebddd1SJeff Kirsher int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2295f67ef7baSPadmanabh Ratnakar 			    u32 data_size, u32 data_offset,
2296f67ef7baSPadmanabh Ratnakar 			    const char *obj_name, u32 *data_written,
2297f67ef7baSPadmanabh Ratnakar 			    u8 *change_status, u8 *addn_status)
22989aebddd1SJeff Kirsher {
22999aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
23009aebddd1SJeff Kirsher 	struct lancer_cmd_req_write_object *req;
23019aebddd1SJeff Kirsher 	struct lancer_cmd_resp_write_object *resp;
23029aebddd1SJeff Kirsher 	void *ctxt = NULL;
23039aebddd1SJeff Kirsher 	int status;
23049aebddd1SJeff Kirsher 
23059aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
23069aebddd1SJeff Kirsher 	adapter->flash_status = 0;
23079aebddd1SJeff Kirsher 
23089aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
23099aebddd1SJeff Kirsher 	if (!wrb) {
23109aebddd1SJeff Kirsher 		status = -EBUSY;
23119aebddd1SJeff Kirsher 		goto err_unlock;
23129aebddd1SJeff Kirsher 	}
23139aebddd1SJeff Kirsher 
23149aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
23159aebddd1SJeff Kirsher 
2316106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
23179aebddd1SJeff Kirsher 			       OPCODE_COMMON_WRITE_OBJECT,
2318106df1e3SSomnath Kotur 			       sizeof(struct lancer_cmd_req_write_object), wrb,
2319106df1e3SSomnath Kotur 			       NULL);
23209aebddd1SJeff Kirsher 
23219aebddd1SJeff Kirsher 	ctxt = &req->context;
23229aebddd1SJeff Kirsher 	AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23239aebddd1SJeff Kirsher 		      write_length, ctxt, data_size);
23249aebddd1SJeff Kirsher 
23259aebddd1SJeff Kirsher 	if (data_size == 0)
23269aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23279aebddd1SJeff Kirsher 			      eof, ctxt, 1);
23289aebddd1SJeff Kirsher 	else
23299aebddd1SJeff Kirsher 		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
23309aebddd1SJeff Kirsher 			      eof, ctxt, 0);
23319aebddd1SJeff Kirsher 
23329aebddd1SJeff Kirsher 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
23339aebddd1SJeff Kirsher 	req->write_offset = cpu_to_le32(data_offset);
2334242eb470SVasundhara Volam 	strlcpy(req->object_name, obj_name, sizeof(req->object_name));
23359aebddd1SJeff Kirsher 	req->descriptor_count = cpu_to_le32(1);
23369aebddd1SJeff Kirsher 	req->buf_len = cpu_to_le32(data_size);
23379aebddd1SJeff Kirsher 	req->addr_low = cpu_to_le32((cmd->dma +
23389aebddd1SJeff Kirsher 				     sizeof(struct lancer_cmd_req_write_object))
23399aebddd1SJeff Kirsher 				    & 0xFFFFFFFF);
23409aebddd1SJeff Kirsher 	req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
23419aebddd1SJeff Kirsher 				sizeof(struct lancer_cmd_req_write_object)));
23429aebddd1SJeff Kirsher 
2343efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
2344efaa408eSSuresh Reddy 	if (status)
2345efaa408eSSuresh Reddy 		goto err_unlock;
2346efaa408eSSuresh Reddy 
23479aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
23489aebddd1SJeff Kirsher 
23495eeff635SSuresh Reddy 	if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2350701962d0SSomnath Kotur 					 msecs_to_jiffies(60000)))
2351fd45160cSKalesh AP 		status = -ETIMEDOUT;
23529aebddd1SJeff Kirsher 	else
23539aebddd1SJeff Kirsher 		status = adapter->flash_status;
23549aebddd1SJeff Kirsher 
23559aebddd1SJeff Kirsher 	resp = embedded_payload(wrb);
2356f67ef7baSPadmanabh Ratnakar 	if (!status) {
23579aebddd1SJeff Kirsher 		*data_written = le32_to_cpu(resp->actual_write_len);
2358f67ef7baSPadmanabh Ratnakar 		*change_status = resp->change_status;
2359f67ef7baSPadmanabh Ratnakar 	} else {
23609aebddd1SJeff Kirsher 		*addn_status = resp->additional_status;
2361f67ef7baSPadmanabh Ratnakar 	}
23629aebddd1SJeff Kirsher 
23639aebddd1SJeff Kirsher 	return status;
23649aebddd1SJeff Kirsher 
23659aebddd1SJeff Kirsher err_unlock:
23669aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
23679aebddd1SJeff Kirsher 	return status;
23689aebddd1SJeff Kirsher }
23699aebddd1SJeff Kirsher 
23706809cee0SRavikumar Nelavelli int be_cmd_query_cable_type(struct be_adapter *adapter)
23716809cee0SRavikumar Nelavelli {
23726809cee0SRavikumar Nelavelli 	u8 page_data[PAGE_DATA_LEN];
23736809cee0SRavikumar Nelavelli 	int status;
23746809cee0SRavikumar Nelavelli 
23756809cee0SRavikumar Nelavelli 	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
23766809cee0SRavikumar Nelavelli 						   page_data);
23776809cee0SRavikumar Nelavelli 	if (!status) {
23786809cee0SRavikumar Nelavelli 		switch (adapter->phy.interface_type) {
23796809cee0SRavikumar Nelavelli 		case PHY_TYPE_QSFP:
23806809cee0SRavikumar Nelavelli 			adapter->phy.cable_type =
23816809cee0SRavikumar Nelavelli 				page_data[QSFP_PLUS_CABLE_TYPE_OFFSET];
23826809cee0SRavikumar Nelavelli 			break;
23836809cee0SRavikumar Nelavelli 		case PHY_TYPE_SFP_PLUS_10GB:
23846809cee0SRavikumar Nelavelli 			adapter->phy.cable_type =
23856809cee0SRavikumar Nelavelli 				page_data[SFP_PLUS_CABLE_TYPE_OFFSET];
23866809cee0SRavikumar Nelavelli 			break;
23876809cee0SRavikumar Nelavelli 		default:
23886809cee0SRavikumar Nelavelli 			adapter->phy.cable_type = 0;
23896809cee0SRavikumar Nelavelli 			break;
23906809cee0SRavikumar Nelavelli 		}
23916809cee0SRavikumar Nelavelli 	}
23926809cee0SRavikumar Nelavelli 	return status;
23936809cee0SRavikumar Nelavelli }
23946809cee0SRavikumar Nelavelli 
239521252377SVasundhara Volam int be_cmd_query_sfp_info(struct be_adapter *adapter)
239621252377SVasundhara Volam {
239721252377SVasundhara Volam 	u8 page_data[PAGE_DATA_LEN];
239821252377SVasundhara Volam 	int status;
239921252377SVasundhara Volam 
240021252377SVasundhara Volam 	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
240121252377SVasundhara Volam 						   page_data);
240221252377SVasundhara Volam 	if (!status) {
240321252377SVasundhara Volam 		strlcpy(adapter->phy.vendor_name, page_data +
240421252377SVasundhara Volam 			SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
240521252377SVasundhara Volam 		strlcpy(adapter->phy.vendor_pn,
240621252377SVasundhara Volam 			page_data + SFP_VENDOR_PN_OFFSET,
240721252377SVasundhara Volam 			SFP_VENDOR_NAME_LEN - 1);
240821252377SVasundhara Volam 	}
240921252377SVasundhara Volam 
241021252377SVasundhara Volam 	return status;
241121252377SVasundhara Volam }
241221252377SVasundhara Volam 
2413f0613380SKalesh AP int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
2414f0613380SKalesh AP {
2415f0613380SKalesh AP 	struct lancer_cmd_req_delete_object *req;
2416f0613380SKalesh AP 	struct be_mcc_wrb *wrb;
2417f0613380SKalesh AP 	int status;
2418f0613380SKalesh AP 
2419f0613380SKalesh AP 	spin_lock_bh(&adapter->mcc_lock);
2420f0613380SKalesh AP 
2421f0613380SKalesh AP 	wrb = wrb_from_mccq(adapter);
2422f0613380SKalesh AP 	if (!wrb) {
2423f0613380SKalesh AP 		status = -EBUSY;
2424f0613380SKalesh AP 		goto err;
2425f0613380SKalesh AP 	}
2426f0613380SKalesh AP 
2427f0613380SKalesh AP 	req = embedded_payload(wrb);
2428f0613380SKalesh AP 
2429f0613380SKalesh AP 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2430f0613380SKalesh AP 			       OPCODE_COMMON_DELETE_OBJECT,
2431f0613380SKalesh AP 			       sizeof(*req), wrb, NULL);
2432f0613380SKalesh AP 
2433242eb470SVasundhara Volam 	strlcpy(req->object_name, obj_name, sizeof(req->object_name));
2434f0613380SKalesh AP 
2435f0613380SKalesh AP 	status = be_mcc_notify_wait(adapter);
2436f0613380SKalesh AP err:
2437f0613380SKalesh AP 	spin_unlock_bh(&adapter->mcc_lock);
2438f0613380SKalesh AP 	return status;
2439f0613380SKalesh AP }
2440f0613380SKalesh AP 
2441de49bd5aSPadmanabh Ratnakar int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2442de49bd5aSPadmanabh Ratnakar 			   u32 data_size, u32 data_offset, const char *obj_name,
2443de49bd5aSPadmanabh Ratnakar 			   u32 *data_read, u32 *eof, u8 *addn_status)
2444de49bd5aSPadmanabh Ratnakar {
2445de49bd5aSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
2446de49bd5aSPadmanabh Ratnakar 	struct lancer_cmd_req_read_object *req;
2447de49bd5aSPadmanabh Ratnakar 	struct lancer_cmd_resp_read_object *resp;
2448de49bd5aSPadmanabh Ratnakar 	int status;
2449de49bd5aSPadmanabh Ratnakar 
2450de49bd5aSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
2451de49bd5aSPadmanabh Ratnakar 
2452de49bd5aSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
2453de49bd5aSPadmanabh Ratnakar 	if (!wrb) {
2454de49bd5aSPadmanabh Ratnakar 		status = -EBUSY;
2455de49bd5aSPadmanabh Ratnakar 		goto err_unlock;
2456de49bd5aSPadmanabh Ratnakar 	}
2457de49bd5aSPadmanabh Ratnakar 
2458de49bd5aSPadmanabh Ratnakar 	req = embedded_payload(wrb);
2459de49bd5aSPadmanabh Ratnakar 
2460de49bd5aSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2461de49bd5aSPadmanabh Ratnakar 			       OPCODE_COMMON_READ_OBJECT,
2462de49bd5aSPadmanabh Ratnakar 			       sizeof(struct lancer_cmd_req_read_object), wrb,
2463de49bd5aSPadmanabh Ratnakar 			       NULL);
2464de49bd5aSPadmanabh Ratnakar 
2465de49bd5aSPadmanabh Ratnakar 	req->desired_read_len = cpu_to_le32(data_size);
2466de49bd5aSPadmanabh Ratnakar 	req->read_offset = cpu_to_le32(data_offset);
2467de49bd5aSPadmanabh Ratnakar 	strcpy(req->object_name, obj_name);
2468de49bd5aSPadmanabh Ratnakar 	req->descriptor_count = cpu_to_le32(1);
2469de49bd5aSPadmanabh Ratnakar 	req->buf_len = cpu_to_le32(data_size);
2470de49bd5aSPadmanabh Ratnakar 	req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
2471de49bd5aSPadmanabh Ratnakar 	req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));
2472de49bd5aSPadmanabh Ratnakar 
2473de49bd5aSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
2474de49bd5aSPadmanabh Ratnakar 
2475de49bd5aSPadmanabh Ratnakar 	resp = embedded_payload(wrb);
2476de49bd5aSPadmanabh Ratnakar 	if (!status) {
2477de49bd5aSPadmanabh Ratnakar 		*data_read = le32_to_cpu(resp->actual_read_len);
2478de49bd5aSPadmanabh Ratnakar 		*eof = le32_to_cpu(resp->eof);
2479de49bd5aSPadmanabh Ratnakar 	} else {
2480de49bd5aSPadmanabh Ratnakar 		*addn_status = resp->additional_status;
2481de49bd5aSPadmanabh Ratnakar 	}
2482de49bd5aSPadmanabh Ratnakar 
2483de49bd5aSPadmanabh Ratnakar err_unlock:
2484de49bd5aSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
2485de49bd5aSPadmanabh Ratnakar 	return status;
2486de49bd5aSPadmanabh Ratnakar }
2487de49bd5aSPadmanabh Ratnakar 
24889aebddd1SJeff Kirsher int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
248970a7b525SVasundhara Volam 			  u32 flash_type, u32 flash_opcode, u32 img_offset,
249070a7b525SVasundhara Volam 			  u32 buf_size)
24919aebddd1SJeff Kirsher {
24929aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
24939aebddd1SJeff Kirsher 	struct be_cmd_write_flashrom *req;
24949aebddd1SJeff Kirsher 	int status;
24959aebddd1SJeff Kirsher 
24969aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
24979aebddd1SJeff Kirsher 	adapter->flash_status = 0;
24989aebddd1SJeff Kirsher 
24999aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25009aebddd1SJeff Kirsher 	if (!wrb) {
25019aebddd1SJeff Kirsher 		status = -EBUSY;
25029aebddd1SJeff Kirsher 		goto err_unlock;
25039aebddd1SJeff Kirsher 	}
25049aebddd1SJeff Kirsher 	req = cmd->va;
25059aebddd1SJeff Kirsher 
2506106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2507a2cc4e0bSSathya Perla 			       OPCODE_COMMON_WRITE_FLASHROM, cmd->size, wrb,
2508a2cc4e0bSSathya Perla 			       cmd);
25099aebddd1SJeff Kirsher 
25109aebddd1SJeff Kirsher 	req->params.op_type = cpu_to_le32(flash_type);
251170a7b525SVasundhara Volam 	if (flash_type == OPTYPE_OFFSET_SPECIFIED)
251270a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(img_offset);
251370a7b525SVasundhara Volam 
25149aebddd1SJeff Kirsher 	req->params.op_code = cpu_to_le32(flash_opcode);
25159aebddd1SJeff Kirsher 	req->params.data_buf_size = cpu_to_le32(buf_size);
25169aebddd1SJeff Kirsher 
2517efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
2518efaa408eSSuresh Reddy 	if (status)
2519efaa408eSSuresh Reddy 		goto err_unlock;
2520efaa408eSSuresh Reddy 
25219aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25229aebddd1SJeff Kirsher 
25235eeff635SSuresh Reddy 	if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2524e2edb7d5SSathya Perla 					 msecs_to_jiffies(40000)))
2525fd45160cSKalesh AP 		status = -ETIMEDOUT;
25269aebddd1SJeff Kirsher 	else
25279aebddd1SJeff Kirsher 		status = adapter->flash_status;
25289aebddd1SJeff Kirsher 
25299aebddd1SJeff Kirsher 	return status;
25309aebddd1SJeff Kirsher 
25319aebddd1SJeff Kirsher err_unlock:
25329aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25339aebddd1SJeff Kirsher 	return status;
25349aebddd1SJeff Kirsher }
25359aebddd1SJeff Kirsher 
25369aebddd1SJeff Kirsher int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
253770a7b525SVasundhara Volam 			 u16 img_optype, u32 img_offset, u32 crc_offset)
25389aebddd1SJeff Kirsher {
2539be716446SPadmanabh Ratnakar 	struct be_cmd_read_flash_crc *req;
254070a7b525SVasundhara Volam 	struct be_mcc_wrb *wrb;
25419aebddd1SJeff Kirsher 	int status;
25429aebddd1SJeff Kirsher 
25439aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
25449aebddd1SJeff Kirsher 
25459aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25469aebddd1SJeff Kirsher 	if (!wrb) {
25479aebddd1SJeff Kirsher 		status = -EBUSY;
25489aebddd1SJeff Kirsher 		goto err;
25499aebddd1SJeff Kirsher 	}
25509aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
25519aebddd1SJeff Kirsher 
2552106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2553be716446SPadmanabh Ratnakar 			       OPCODE_COMMON_READ_FLASHROM, sizeof(*req),
2554be716446SPadmanabh Ratnakar 			       wrb, NULL);
25559aebddd1SJeff Kirsher 
255670a7b525SVasundhara Volam 	req->params.op_type = cpu_to_le32(img_optype);
255770a7b525SVasundhara Volam 	if (img_optype == OPTYPE_OFFSET_SPECIFIED)
255870a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(img_offset + crc_offset);
255970a7b525SVasundhara Volam 	else
256070a7b525SVasundhara Volam 		req->params.offset = cpu_to_le32(crc_offset);
256170a7b525SVasundhara Volam 
25629aebddd1SJeff Kirsher 	req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
25639aebddd1SJeff Kirsher 	req->params.data_buf_size = cpu_to_le32(0x4);
25649aebddd1SJeff Kirsher 
25659aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
25669aebddd1SJeff Kirsher 	if (!status)
2567be716446SPadmanabh Ratnakar 		memcpy(flashed_crc, req->crc, 4);
25689aebddd1SJeff Kirsher 
25699aebddd1SJeff Kirsher err:
25709aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25719aebddd1SJeff Kirsher 	return status;
25729aebddd1SJeff Kirsher }
25739aebddd1SJeff Kirsher 
25749aebddd1SJeff Kirsher int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
25759aebddd1SJeff Kirsher 			    struct be_dma_mem *nonemb_cmd)
25769aebddd1SJeff Kirsher {
25779aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
25789aebddd1SJeff Kirsher 	struct be_cmd_req_acpi_wol_magic_config *req;
25799aebddd1SJeff Kirsher 	int status;
25809aebddd1SJeff Kirsher 
25819aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
25829aebddd1SJeff Kirsher 
25839aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
25849aebddd1SJeff Kirsher 	if (!wrb) {
25859aebddd1SJeff Kirsher 		status = -EBUSY;
25869aebddd1SJeff Kirsher 		goto err;
25879aebddd1SJeff Kirsher 	}
25889aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
25899aebddd1SJeff Kirsher 
2590106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
2591a2cc4e0bSSathya Perla 			       OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req),
2592a2cc4e0bSSathya Perla 			       wrb, nonemb_cmd);
25939aebddd1SJeff Kirsher 	memcpy(req->magic_mac, mac, ETH_ALEN);
25949aebddd1SJeff Kirsher 
25959aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
25969aebddd1SJeff Kirsher 
25979aebddd1SJeff Kirsher err:
25989aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
25999aebddd1SJeff Kirsher 	return status;
26009aebddd1SJeff Kirsher }
26019aebddd1SJeff Kirsher 
26029aebddd1SJeff Kirsher int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
26039aebddd1SJeff Kirsher 			u8 loopback_type, u8 enable)
26049aebddd1SJeff Kirsher {
26059aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
26069aebddd1SJeff Kirsher 	struct be_cmd_req_set_lmode *req;
26079aebddd1SJeff Kirsher 	int status;
26089aebddd1SJeff Kirsher 
26099aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
26109aebddd1SJeff Kirsher 
26119aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
26129aebddd1SJeff Kirsher 	if (!wrb) {
26139aebddd1SJeff Kirsher 		status = -EBUSY;
26149c855975SSuresh Reddy 		goto err_unlock;
26159aebddd1SJeff Kirsher 	}
26169aebddd1SJeff Kirsher 
26179aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
26189aebddd1SJeff Kirsher 
2619106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2620a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, sizeof(*req),
2621a2cc4e0bSSathya Perla 			       wrb, NULL);
26229aebddd1SJeff Kirsher 
26239aebddd1SJeff Kirsher 	req->src_port = port_num;
26249aebddd1SJeff Kirsher 	req->dest_port = port_num;
26259aebddd1SJeff Kirsher 	req->loopback_type = loopback_type;
26269aebddd1SJeff Kirsher 	req->loopback_state = enable;
26279aebddd1SJeff Kirsher 
26289c855975SSuresh Reddy 	status = be_mcc_notify(adapter);
26299c855975SSuresh Reddy 	if (status)
26309c855975SSuresh Reddy 		goto err_unlock;
26319c855975SSuresh Reddy 
26329c855975SSuresh Reddy 	spin_unlock_bh(&adapter->mcc_lock);
26339c855975SSuresh Reddy 
26349c855975SSuresh Reddy 	if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
26359c855975SSuresh Reddy 					 msecs_to_jiffies(SET_LB_MODE_TIMEOUT)))
26369c855975SSuresh Reddy 		status = -ETIMEDOUT;
26379c855975SSuresh Reddy 
26389c855975SSuresh Reddy 	return status;
26399c855975SSuresh Reddy 
26409c855975SSuresh Reddy err_unlock:
26419aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
26429aebddd1SJeff Kirsher 	return status;
26439aebddd1SJeff Kirsher }
26449aebddd1SJeff Kirsher 
26459aebddd1SJeff Kirsher int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
2646a2cc4e0bSSathya Perla 			 u32 loopback_type, u32 pkt_size, u32 num_pkts,
2647a2cc4e0bSSathya Perla 			 u64 pattern)
26489aebddd1SJeff Kirsher {
26499aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
26509aebddd1SJeff Kirsher 	struct be_cmd_req_loopback_test *req;
26515eeff635SSuresh Reddy 	struct be_cmd_resp_loopback_test *resp;
26529aebddd1SJeff Kirsher 	int status;
26539aebddd1SJeff Kirsher 
26549aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
26559aebddd1SJeff Kirsher 
26569aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
26579aebddd1SJeff Kirsher 	if (!wrb) {
26589aebddd1SJeff Kirsher 		status = -EBUSY;
26599aebddd1SJeff Kirsher 		goto err;
26609aebddd1SJeff Kirsher 	}
26619aebddd1SJeff Kirsher 
26629aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
26639aebddd1SJeff Kirsher 
2664106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2665a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req), wrb,
2666a2cc4e0bSSathya Perla 			       NULL);
26679aebddd1SJeff Kirsher 
26685eeff635SSuresh Reddy 	req->hdr.timeout = cpu_to_le32(15);
26699aebddd1SJeff Kirsher 	req->pattern = cpu_to_le64(pattern);
26709aebddd1SJeff Kirsher 	req->src_port = cpu_to_le32(port_num);
26719aebddd1SJeff Kirsher 	req->dest_port = cpu_to_le32(port_num);
26729aebddd1SJeff Kirsher 	req->pkt_size = cpu_to_le32(pkt_size);
26739aebddd1SJeff Kirsher 	req->num_pkts = cpu_to_le32(num_pkts);
26749aebddd1SJeff Kirsher 	req->loopback_type = cpu_to_le32(loopback_type);
26759aebddd1SJeff Kirsher 
2676efaa408eSSuresh Reddy 	status = be_mcc_notify(adapter);
2677efaa408eSSuresh Reddy 	if (status)
2678efaa408eSSuresh Reddy 		goto err;
26799aebddd1SJeff Kirsher 
26805eeff635SSuresh Reddy 	spin_unlock_bh(&adapter->mcc_lock);
26815eeff635SSuresh Reddy 
26825eeff635SSuresh Reddy 	wait_for_completion(&adapter->et_cmd_compl);
26835eeff635SSuresh Reddy 	resp = embedded_payload(wrb);
26845eeff635SSuresh Reddy 	status = le32_to_cpu(resp->status);
26855eeff635SSuresh Reddy 
26865eeff635SSuresh Reddy 	return status;
26879aebddd1SJeff Kirsher err:
26889aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
26899aebddd1SJeff Kirsher 	return status;
26909aebddd1SJeff Kirsher }
26919aebddd1SJeff Kirsher 
26929aebddd1SJeff Kirsher int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
26939aebddd1SJeff Kirsher 			u32 byte_cnt, struct be_dma_mem *cmd)
26949aebddd1SJeff Kirsher {
26959aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
26969aebddd1SJeff Kirsher 	struct be_cmd_req_ddrdma_test *req;
26979aebddd1SJeff Kirsher 	int status;
26989aebddd1SJeff Kirsher 	int i, j = 0;
26999aebddd1SJeff Kirsher 
27009aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27019aebddd1SJeff Kirsher 
27029aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27039aebddd1SJeff Kirsher 	if (!wrb) {
27049aebddd1SJeff Kirsher 		status = -EBUSY;
27059aebddd1SJeff Kirsher 		goto err;
27069aebddd1SJeff Kirsher 	}
27079aebddd1SJeff Kirsher 	req = cmd->va;
2708106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
2709a2cc4e0bSSathya Perla 			       OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size, wrb,
2710a2cc4e0bSSathya Perla 			       cmd);
27119aebddd1SJeff Kirsher 
27129aebddd1SJeff Kirsher 	req->pattern = cpu_to_le64(pattern);
27139aebddd1SJeff Kirsher 	req->byte_count = cpu_to_le32(byte_cnt);
27149aebddd1SJeff Kirsher 	for (i = 0; i < byte_cnt; i++) {
27159aebddd1SJeff Kirsher 		req->snd_buff[i] = (u8)(pattern >> (j*8));
27169aebddd1SJeff Kirsher 		j++;
27179aebddd1SJeff Kirsher 		if (j > 7)
27189aebddd1SJeff Kirsher 			j = 0;
27199aebddd1SJeff Kirsher 	}
27209aebddd1SJeff Kirsher 
27219aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
27229aebddd1SJeff Kirsher 
27239aebddd1SJeff Kirsher 	if (!status) {
27249aebddd1SJeff Kirsher 		struct be_cmd_resp_ddrdma_test *resp;
272503d28ffeSKalesh AP 
27269aebddd1SJeff Kirsher 		resp = cmd->va;
27279aebddd1SJeff Kirsher 		if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
27289aebddd1SJeff Kirsher 		    resp->snd_err) {
27299aebddd1SJeff Kirsher 			status = -1;
27309aebddd1SJeff Kirsher 		}
27319aebddd1SJeff Kirsher 	}
27329aebddd1SJeff Kirsher 
27339aebddd1SJeff Kirsher err:
27349aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
27359aebddd1SJeff Kirsher 	return status;
27369aebddd1SJeff Kirsher }
27379aebddd1SJeff Kirsher 
27389aebddd1SJeff Kirsher int be_cmd_get_seeprom_data(struct be_adapter *adapter,
27399aebddd1SJeff Kirsher 			    struct be_dma_mem *nonemb_cmd)
27409aebddd1SJeff Kirsher {
27419aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
27429aebddd1SJeff Kirsher 	struct be_cmd_req_seeprom_read *req;
27439aebddd1SJeff Kirsher 	int status;
27449aebddd1SJeff Kirsher 
27459aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27469aebddd1SJeff Kirsher 
27479aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27489aebddd1SJeff Kirsher 	if (!wrb) {
27499aebddd1SJeff Kirsher 		status = -EBUSY;
27509aebddd1SJeff Kirsher 		goto err;
27519aebddd1SJeff Kirsher 	}
27529aebddd1SJeff Kirsher 	req = nonemb_cmd->va;
27539aebddd1SJeff Kirsher 
2754106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2755106df1e3SSomnath Kotur 			       OPCODE_COMMON_SEEPROM_READ, sizeof(*req), wrb,
2756106df1e3SSomnath Kotur 			       nonemb_cmd);
27579aebddd1SJeff Kirsher 
27589aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
27599aebddd1SJeff Kirsher 
27609aebddd1SJeff Kirsher err:
27619aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
27629aebddd1SJeff Kirsher 	return status;
27639aebddd1SJeff Kirsher }
27649aebddd1SJeff Kirsher 
276542f11cf2SAjit Khaparde int be_cmd_get_phy_info(struct be_adapter *adapter)
27669aebddd1SJeff Kirsher {
27679aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
27689aebddd1SJeff Kirsher 	struct be_cmd_req_get_phy_info *req;
27699aebddd1SJeff Kirsher 	struct be_dma_mem cmd;
27709aebddd1SJeff Kirsher 	int status;
27719aebddd1SJeff Kirsher 
2772f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
2773f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_COMMON))
2774f25b119cSPadmanabh Ratnakar 		return -EPERM;
2775f25b119cSPadmanabh Ratnakar 
27769aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
27779aebddd1SJeff Kirsher 
27789aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
27799aebddd1SJeff Kirsher 	if (!wrb) {
27809aebddd1SJeff Kirsher 		status = -EBUSY;
27819aebddd1SJeff Kirsher 		goto err;
27829aebddd1SJeff Kirsher 	}
27839aebddd1SJeff Kirsher 	cmd.size = sizeof(struct be_cmd_req_get_phy_info);
2784e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
2785e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
27869aebddd1SJeff Kirsher 	if (!cmd.va) {
27879aebddd1SJeff Kirsher 		dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
27889aebddd1SJeff Kirsher 		status = -ENOMEM;
27899aebddd1SJeff Kirsher 		goto err;
27909aebddd1SJeff Kirsher 	}
27919aebddd1SJeff Kirsher 
27929aebddd1SJeff Kirsher 	req = cmd.va;
27939aebddd1SJeff Kirsher 
2794106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2795106df1e3SSomnath Kotur 			       OPCODE_COMMON_GET_PHY_DETAILS, sizeof(*req),
2796106df1e3SSomnath Kotur 			       wrb, &cmd);
27979aebddd1SJeff Kirsher 
27989aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
27999aebddd1SJeff Kirsher 	if (!status) {
28009aebddd1SJeff Kirsher 		struct be_phy_info *resp_phy_info =
28019aebddd1SJeff Kirsher 				cmd.va + sizeof(struct be_cmd_req_hdr);
280203d28ffeSKalesh AP 
280342f11cf2SAjit Khaparde 		adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
280442f11cf2SAjit Khaparde 		adapter->phy.interface_type =
28059aebddd1SJeff Kirsher 			le16_to_cpu(resp_phy_info->interface_type);
280642f11cf2SAjit Khaparde 		adapter->phy.auto_speeds_supported =
280742f11cf2SAjit Khaparde 			le16_to_cpu(resp_phy_info->auto_speeds_supported);
280842f11cf2SAjit Khaparde 		adapter->phy.fixed_speeds_supported =
280942f11cf2SAjit Khaparde 			le16_to_cpu(resp_phy_info->fixed_speeds_supported);
281042f11cf2SAjit Khaparde 		adapter->phy.misc_params =
281142f11cf2SAjit Khaparde 			le32_to_cpu(resp_phy_info->misc_params);
281268cb7e47SVasundhara Volam 
281368cb7e47SVasundhara Volam 		if (BE2_chip(adapter)) {
281468cb7e47SVasundhara Volam 			adapter->phy.fixed_speeds_supported =
281568cb7e47SVasundhara Volam 				BE_SUPPORTED_SPEED_10GBPS |
281668cb7e47SVasundhara Volam 				BE_SUPPORTED_SPEED_1GBPS;
281768cb7e47SVasundhara Volam 		}
28189aebddd1SJeff Kirsher 	}
2819e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
28209aebddd1SJeff Kirsher err:
28219aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
28229aebddd1SJeff Kirsher 	return status;
28239aebddd1SJeff Kirsher }
28249aebddd1SJeff Kirsher 
2825bc0ee163SLad, Prabhakar static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
28269aebddd1SJeff Kirsher {
28279aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
28289aebddd1SJeff Kirsher 	struct be_cmd_req_set_qos *req;
28299aebddd1SJeff Kirsher 	int status;
28309aebddd1SJeff Kirsher 
28319aebddd1SJeff Kirsher 	spin_lock_bh(&adapter->mcc_lock);
28329aebddd1SJeff Kirsher 
28339aebddd1SJeff Kirsher 	wrb = wrb_from_mccq(adapter);
28349aebddd1SJeff Kirsher 	if (!wrb) {
28359aebddd1SJeff Kirsher 		status = -EBUSY;
28369aebddd1SJeff Kirsher 		goto err;
28379aebddd1SJeff Kirsher 	}
28389aebddd1SJeff Kirsher 
28399aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
28409aebddd1SJeff Kirsher 
2841106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2842106df1e3SSomnath Kotur 			       OPCODE_COMMON_SET_QOS, sizeof(*req), wrb, NULL);
28439aebddd1SJeff Kirsher 
28449aebddd1SJeff Kirsher 	req->hdr.domain = domain;
28459aebddd1SJeff Kirsher 	req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC);
28469aebddd1SJeff Kirsher 	req->max_bps_nic = cpu_to_le32(bps);
28479aebddd1SJeff Kirsher 
28489aebddd1SJeff Kirsher 	status = be_mcc_notify_wait(adapter);
28499aebddd1SJeff Kirsher 
28509aebddd1SJeff Kirsher err:
28519aebddd1SJeff Kirsher 	spin_unlock_bh(&adapter->mcc_lock);
28529aebddd1SJeff Kirsher 	return status;
28539aebddd1SJeff Kirsher }
28549aebddd1SJeff Kirsher 
28559aebddd1SJeff Kirsher int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
28569aebddd1SJeff Kirsher {
28579aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
28589aebddd1SJeff Kirsher 	struct be_cmd_req_cntl_attribs *req;
28599aebddd1SJeff Kirsher 	struct be_cmd_resp_cntl_attribs *resp;
2860a155a5dbSSriharsha Basavapatna 	int status, i;
28619aebddd1SJeff Kirsher 	int payload_len = max(sizeof(*req), sizeof(*resp));
28629aebddd1SJeff Kirsher 	struct mgmt_controller_attrib *attribs;
28639aebddd1SJeff Kirsher 	struct be_dma_mem attribs_cmd;
2864a155a5dbSSriharsha Basavapatna 	u32 *serial_num;
28659aebddd1SJeff Kirsher 
2866d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
2867d98ef50fSSuresh Reddy 		return -1;
2868d98ef50fSSuresh Reddy 
28699aebddd1SJeff Kirsher 	memset(&attribs_cmd, 0, sizeof(struct be_dma_mem));
28709aebddd1SJeff Kirsher 	attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs);
2871e51000dbSSriharsha Basavapatna 	attribs_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
2872e51000dbSSriharsha Basavapatna 					     attribs_cmd.size,
2873e51000dbSSriharsha Basavapatna 					     &attribs_cmd.dma, GFP_ATOMIC);
28749aebddd1SJeff Kirsher 	if (!attribs_cmd.va) {
2875a2cc4e0bSSathya Perla 		dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
2876d98ef50fSSuresh Reddy 		status = -ENOMEM;
2877d98ef50fSSuresh Reddy 		goto err;
28789aebddd1SJeff Kirsher 	}
28799aebddd1SJeff Kirsher 
28809aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
28819aebddd1SJeff Kirsher 	if (!wrb) {
28829aebddd1SJeff Kirsher 		status = -EBUSY;
28839aebddd1SJeff Kirsher 		goto err;
28849aebddd1SJeff Kirsher 	}
28859aebddd1SJeff Kirsher 	req = attribs_cmd.va;
28869aebddd1SJeff Kirsher 
2887106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2888a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len,
2889a2cc4e0bSSathya Perla 			       wrb, &attribs_cmd);
28909aebddd1SJeff Kirsher 
28919aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
28929aebddd1SJeff Kirsher 	if (!status) {
28939aebddd1SJeff Kirsher 		attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
28949aebddd1SJeff Kirsher 		adapter->hba_port_num = attribs->hba_attribs.phy_port;
289572ef3a88SSomnath Kotur 		adapter->pci_func_num = attribs->pci_func_num;
2896a155a5dbSSriharsha Basavapatna 		serial_num = attribs->hba_attribs.controller_serial_number;
2897a155a5dbSSriharsha Basavapatna 		for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
2898a155a5dbSSriharsha Basavapatna 			adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
2899a155a5dbSSriharsha Basavapatna 				(BIT_MASK(16) - 1);
29009aebddd1SJeff Kirsher 	}
29019aebddd1SJeff Kirsher 
29029aebddd1SJeff Kirsher err:
29039aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
2904d98ef50fSSuresh Reddy 	if (attribs_cmd.va)
2905e51000dbSSriharsha Basavapatna 		dma_free_coherent(&adapter->pdev->dev, attribs_cmd.size,
2906d98ef50fSSuresh Reddy 				  attribs_cmd.va, attribs_cmd.dma);
29079aebddd1SJeff Kirsher 	return status;
29089aebddd1SJeff Kirsher }
29099aebddd1SJeff Kirsher 
29109aebddd1SJeff Kirsher /* Uses mbox */
29119aebddd1SJeff Kirsher int be_cmd_req_native_mode(struct be_adapter *adapter)
29129aebddd1SJeff Kirsher {
29139aebddd1SJeff Kirsher 	struct be_mcc_wrb *wrb;
29149aebddd1SJeff Kirsher 	struct be_cmd_req_set_func_cap *req;
29159aebddd1SJeff Kirsher 	int status;
29169aebddd1SJeff Kirsher 
29179aebddd1SJeff Kirsher 	if (mutex_lock_interruptible(&adapter->mbox_lock))
29189aebddd1SJeff Kirsher 		return -1;
29199aebddd1SJeff Kirsher 
29209aebddd1SJeff Kirsher 	wrb = wrb_from_mbox(adapter);
29219aebddd1SJeff Kirsher 	if (!wrb) {
29229aebddd1SJeff Kirsher 		status = -EBUSY;
29239aebddd1SJeff Kirsher 		goto err;
29249aebddd1SJeff Kirsher 	}
29259aebddd1SJeff Kirsher 
29269aebddd1SJeff Kirsher 	req = embedded_payload(wrb);
29279aebddd1SJeff Kirsher 
2928106df1e3SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2929a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP,
2930a2cc4e0bSSathya Perla 			       sizeof(*req), wrb, NULL);
29319aebddd1SJeff Kirsher 
29329aebddd1SJeff Kirsher 	req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS |
29339aebddd1SJeff Kirsher 				CAPABILITY_BE3_NATIVE_ERX_API);
29349aebddd1SJeff Kirsher 	req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API);
29359aebddd1SJeff Kirsher 
29369aebddd1SJeff Kirsher 	status = be_mbox_notify_wait(adapter);
29379aebddd1SJeff Kirsher 	if (!status) {
29389aebddd1SJeff Kirsher 		struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
293903d28ffeSKalesh AP 
29409aebddd1SJeff Kirsher 		adapter->be3_native = le32_to_cpu(resp->cap_flags) &
29419aebddd1SJeff Kirsher 					CAPABILITY_BE3_NATIVE_ERX_API;
2942d379142bSSathya Perla 		if (!adapter->be3_native)
2943d379142bSSathya Perla 			dev_warn(&adapter->pdev->dev,
2944d379142bSSathya Perla 				 "adapter not in advanced mode\n");
29459aebddd1SJeff Kirsher 	}
29469aebddd1SJeff Kirsher err:
29479aebddd1SJeff Kirsher 	mutex_unlock(&adapter->mbox_lock);
29489aebddd1SJeff Kirsher 	return status;
29499aebddd1SJeff Kirsher }
2950590c391dSPadmanabh Ratnakar 
2951f25b119cSPadmanabh Ratnakar /* Get privilege(s) for a function */
2952f25b119cSPadmanabh Ratnakar int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
2953f25b119cSPadmanabh Ratnakar 			     u32 domain)
2954f25b119cSPadmanabh Ratnakar {
2955f25b119cSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
2956f25b119cSPadmanabh Ratnakar 	struct be_cmd_req_get_fn_privileges *req;
2957f25b119cSPadmanabh Ratnakar 	int status;
2958f25b119cSPadmanabh Ratnakar 
2959f25b119cSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
2960f25b119cSPadmanabh Ratnakar 
2961f25b119cSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
2962f25b119cSPadmanabh Ratnakar 	if (!wrb) {
2963f25b119cSPadmanabh Ratnakar 		status = -EBUSY;
2964f25b119cSPadmanabh Ratnakar 		goto err;
2965f25b119cSPadmanabh Ratnakar 	}
2966f25b119cSPadmanabh Ratnakar 
2967f25b119cSPadmanabh Ratnakar 	req = embedded_payload(wrb);
2968f25b119cSPadmanabh Ratnakar 
2969f25b119cSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2970f25b119cSPadmanabh Ratnakar 			       OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req),
2971f25b119cSPadmanabh Ratnakar 			       wrb, NULL);
2972f25b119cSPadmanabh Ratnakar 
2973f25b119cSPadmanabh Ratnakar 	req->hdr.domain = domain;
2974f25b119cSPadmanabh Ratnakar 
2975f25b119cSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
2976f25b119cSPadmanabh Ratnakar 	if (!status) {
2977f25b119cSPadmanabh Ratnakar 		struct be_cmd_resp_get_fn_privileges *resp =
2978f25b119cSPadmanabh Ratnakar 						embedded_payload(wrb);
297903d28ffeSKalesh AP 
2980f25b119cSPadmanabh Ratnakar 		*privilege = le32_to_cpu(resp->privilege_mask);
298102308d74SSuresh Reddy 
298202308d74SSuresh Reddy 		/* In UMC mode FW does not return right privileges.
298302308d74SSuresh Reddy 		 * Override with correct privilege equivalent to PF.
298402308d74SSuresh Reddy 		 */
298502308d74SSuresh Reddy 		if (BEx_chip(adapter) && be_is_mc(adapter) &&
298602308d74SSuresh Reddy 		    be_physfn(adapter))
298702308d74SSuresh Reddy 			*privilege = MAX_PRIVILEGES;
2988f25b119cSPadmanabh Ratnakar 	}
2989f25b119cSPadmanabh Ratnakar 
2990f25b119cSPadmanabh Ratnakar err:
2991f25b119cSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
2992f25b119cSPadmanabh Ratnakar 	return status;
2993f25b119cSPadmanabh Ratnakar }
2994f25b119cSPadmanabh Ratnakar 
299504a06028SSathya Perla /* Set privilege(s) for a function */
299604a06028SSathya Perla int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
299704a06028SSathya Perla 			     u32 domain)
299804a06028SSathya Perla {
299904a06028SSathya Perla 	struct be_mcc_wrb *wrb;
300004a06028SSathya Perla 	struct be_cmd_req_set_fn_privileges *req;
300104a06028SSathya Perla 	int status;
300204a06028SSathya Perla 
300304a06028SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
300404a06028SSathya Perla 
300504a06028SSathya Perla 	wrb = wrb_from_mccq(adapter);
300604a06028SSathya Perla 	if (!wrb) {
300704a06028SSathya Perla 		status = -EBUSY;
300804a06028SSathya Perla 		goto err;
300904a06028SSathya Perla 	}
301004a06028SSathya Perla 
301104a06028SSathya Perla 	req = embedded_payload(wrb);
301204a06028SSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
301304a06028SSathya Perla 			       OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req),
301404a06028SSathya Perla 			       wrb, NULL);
301504a06028SSathya Perla 	req->hdr.domain = domain;
301604a06028SSathya Perla 	if (lancer_chip(adapter))
301704a06028SSathya Perla 		req->privileges_lancer = cpu_to_le32(privileges);
301804a06028SSathya Perla 	else
301904a06028SSathya Perla 		req->privileges = cpu_to_le32(privileges);
302004a06028SSathya Perla 
302104a06028SSathya Perla 	status = be_mcc_notify_wait(adapter);
302204a06028SSathya Perla err:
302304a06028SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
302404a06028SSathya Perla 	return status;
302504a06028SSathya Perla }
302604a06028SSathya Perla 
30275a712c13SSathya Perla /* pmac_id_valid: true => pmac_id is supplied and MAC address is requested.
30285a712c13SSathya Perla  * pmac_id_valid: false => pmac_id or MAC address is requested.
30295a712c13SSathya Perla  *		  If pmac_id is returned, pmac_id_valid is returned as true
30305a712c13SSathya Perla  */
30311578e777SPadmanabh Ratnakar int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
3032b188f090SSuresh Reddy 			     bool *pmac_id_valid, u32 *pmac_id, u32 if_handle,
3033b188f090SSuresh Reddy 			     u8 domain)
3034590c391dSPadmanabh Ratnakar {
3035590c391dSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
3036590c391dSPadmanabh Ratnakar 	struct be_cmd_req_get_mac_list *req;
3037590c391dSPadmanabh Ratnakar 	int status;
3038590c391dSPadmanabh Ratnakar 	int mac_count;
3039e5e1ee89SPadmanabh Ratnakar 	struct be_dma_mem get_mac_list_cmd;
3040e5e1ee89SPadmanabh Ratnakar 	int i;
3041e5e1ee89SPadmanabh Ratnakar 
3042e5e1ee89SPadmanabh Ratnakar 	memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
3043e5e1ee89SPadmanabh Ratnakar 	get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
3044e51000dbSSriharsha Basavapatna 	get_mac_list_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
3045e5e1ee89SPadmanabh Ratnakar 						  get_mac_list_cmd.size,
3046e51000dbSSriharsha Basavapatna 						  &get_mac_list_cmd.dma,
3047e51000dbSSriharsha Basavapatna 						  GFP_ATOMIC);
3048e5e1ee89SPadmanabh Ratnakar 
3049e5e1ee89SPadmanabh Ratnakar 	if (!get_mac_list_cmd.va) {
3050e5e1ee89SPadmanabh Ratnakar 		dev_err(&adapter->pdev->dev,
3051e5e1ee89SPadmanabh Ratnakar 			"Memory allocation failure during GET_MAC_LIST\n");
3052e5e1ee89SPadmanabh Ratnakar 		return -ENOMEM;
3053e5e1ee89SPadmanabh Ratnakar 	}
3054590c391dSPadmanabh Ratnakar 
3055590c391dSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
3056590c391dSPadmanabh Ratnakar 
3057590c391dSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
3058590c391dSPadmanabh Ratnakar 	if (!wrb) {
3059590c391dSPadmanabh Ratnakar 		status = -EBUSY;
3060e5e1ee89SPadmanabh Ratnakar 		goto out;
3061590c391dSPadmanabh Ratnakar 	}
3062e5e1ee89SPadmanabh Ratnakar 
3063e5e1ee89SPadmanabh Ratnakar 	req = get_mac_list_cmd.va;
3064590c391dSPadmanabh Ratnakar 
3065590c391dSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3066bf591f51SSathya Perla 			       OPCODE_COMMON_GET_MAC_LIST,
3067bf591f51SSathya Perla 			       get_mac_list_cmd.size, wrb, &get_mac_list_cmd);
3068590c391dSPadmanabh Ratnakar 	req->hdr.domain = domain;
3069e5e1ee89SPadmanabh Ratnakar 	req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
30705a712c13SSathya Perla 	if (*pmac_id_valid) {
30715a712c13SSathya Perla 		req->mac_id = cpu_to_le32(*pmac_id);
3072b188f090SSuresh Reddy 		req->iface_id = cpu_to_le16(if_handle);
30735a712c13SSathya Perla 		req->perm_override = 0;
30745a712c13SSathya Perla 	} else {
3075e5e1ee89SPadmanabh Ratnakar 		req->perm_override = 1;
30765a712c13SSathya Perla 	}
3077590c391dSPadmanabh Ratnakar 
3078590c391dSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
3079590c391dSPadmanabh Ratnakar 	if (!status) {
3080590c391dSPadmanabh Ratnakar 		struct be_cmd_resp_get_mac_list *resp =
3081e5e1ee89SPadmanabh Ratnakar 						get_mac_list_cmd.va;
30825a712c13SSathya Perla 
30835a712c13SSathya Perla 		if (*pmac_id_valid) {
30845a712c13SSathya Perla 			memcpy(mac, resp->macid_macaddr.mac_addr_id.macaddr,
30855a712c13SSathya Perla 			       ETH_ALEN);
30865a712c13SSathya Perla 			goto out;
30875a712c13SSathya Perla 		}
30885a712c13SSathya Perla 
3089e5e1ee89SPadmanabh Ratnakar 		mac_count = resp->true_mac_count + resp->pseudo_mac_count;
3090e5e1ee89SPadmanabh Ratnakar 		/* Mac list returned could contain one or more active mac_ids
3091dbedd44eSJoe Perches 		 * or one or more true or pseudo permanent mac addresses.
30921578e777SPadmanabh Ratnakar 		 * If an active mac_id is present, return first active mac_id
30931578e777SPadmanabh Ratnakar 		 * found.
3094e5e1ee89SPadmanabh Ratnakar 		 */
3095590c391dSPadmanabh Ratnakar 		for (i = 0; i < mac_count; i++) {
3096e5e1ee89SPadmanabh Ratnakar 			struct get_list_macaddr *mac_entry;
3097e5e1ee89SPadmanabh Ratnakar 			u16 mac_addr_size;
3098e5e1ee89SPadmanabh Ratnakar 			u32 mac_id;
3099e5e1ee89SPadmanabh Ratnakar 
3100e5e1ee89SPadmanabh Ratnakar 			mac_entry = &resp->macaddr_list[i];
3101e5e1ee89SPadmanabh Ratnakar 			mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
3102e5e1ee89SPadmanabh Ratnakar 			/* mac_id is a 32 bit value and mac_addr size
3103e5e1ee89SPadmanabh Ratnakar 			 * is 6 bytes
3104e5e1ee89SPadmanabh Ratnakar 			 */
3105e5e1ee89SPadmanabh Ratnakar 			if (mac_addr_size == sizeof(u32)) {
31065a712c13SSathya Perla 				*pmac_id_valid = true;
3107e5e1ee89SPadmanabh Ratnakar 				mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
3108e5e1ee89SPadmanabh Ratnakar 				*pmac_id = le32_to_cpu(mac_id);
3109e5e1ee89SPadmanabh Ratnakar 				goto out;
3110590c391dSPadmanabh Ratnakar 			}
3111590c391dSPadmanabh Ratnakar 		}
31121578e777SPadmanabh Ratnakar 		/* If no active mac_id found, return first mac addr */
31135a712c13SSathya Perla 		*pmac_id_valid = false;
3114e5e1ee89SPadmanabh Ratnakar 		memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
3115e5e1ee89SPadmanabh Ratnakar 		       ETH_ALEN);
3116590c391dSPadmanabh Ratnakar 	}
3117590c391dSPadmanabh Ratnakar 
3118e5e1ee89SPadmanabh Ratnakar out:
3119590c391dSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
3120e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size,
3121e5e1ee89SPadmanabh Ratnakar 			  get_mac_list_cmd.va, get_mac_list_cmd.dma);
3122590c391dSPadmanabh Ratnakar 	return status;
3123590c391dSPadmanabh Ratnakar }
3124590c391dSPadmanabh Ratnakar 
3125a2cc4e0bSSathya Perla int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id,
3126a2cc4e0bSSathya Perla 			  u8 *mac, u32 if_handle, bool active, u32 domain)
31275a712c13SSathya Perla {
3128b188f090SSuresh Reddy 	if (!active)
3129b188f090SSuresh Reddy 		be_cmd_get_mac_from_list(adapter, mac, &active, &curr_pmac_id,
3130b188f090SSuresh Reddy 					 if_handle, domain);
31313175d8c2SSathya Perla 	if (BEx_chip(adapter))
31325a712c13SSathya Perla 		return be_cmd_mac_addr_query(adapter, mac, false,
3133b188f090SSuresh Reddy 					     if_handle, curr_pmac_id);
31343175d8c2SSathya Perla 	else
31353175d8c2SSathya Perla 		/* Fetch the MAC address using pmac_id */
31363175d8c2SSathya Perla 		return be_cmd_get_mac_from_list(adapter, mac, &active,
3137b188f090SSuresh Reddy 						&curr_pmac_id,
3138b188f090SSuresh Reddy 						if_handle, domain);
31395a712c13SSathya Perla }
31405a712c13SSathya Perla 
314195046b92SSathya Perla int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
314295046b92SSathya Perla {
314395046b92SSathya Perla 	int status;
314495046b92SSathya Perla 	bool pmac_valid = false;
314595046b92SSathya Perla 
3146c7bf7169SJoe Perches 	eth_zero_addr(mac);
314795046b92SSathya Perla 
31483175d8c2SSathya Perla 	if (BEx_chip(adapter)) {
31493175d8c2SSathya Perla 		if (be_physfn(adapter))
31503175d8c2SSathya Perla 			status = be_cmd_mac_addr_query(adapter, mac, true, 0,
31513175d8c2SSathya Perla 						       0);
315295046b92SSathya Perla 		else
315395046b92SSathya Perla 			status = be_cmd_mac_addr_query(adapter, mac, false,
315495046b92SSathya Perla 						       adapter->if_handle, 0);
31553175d8c2SSathya Perla 	} else {
31563175d8c2SSathya Perla 		status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
3157b188f090SSuresh Reddy 						  NULL, adapter->if_handle, 0);
31583175d8c2SSathya Perla 	}
31593175d8c2SSathya Perla 
316095046b92SSathya Perla 	return status;
316195046b92SSathya Perla }
316295046b92SSathya Perla 
3163590c391dSPadmanabh Ratnakar /* Uses synchronous MCCQ */
3164590c391dSPadmanabh Ratnakar int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
3165590c391dSPadmanabh Ratnakar 			u8 mac_count, u32 domain)
3166590c391dSPadmanabh Ratnakar {
3167590c391dSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
3168590c391dSPadmanabh Ratnakar 	struct be_cmd_req_set_mac_list *req;
3169590c391dSPadmanabh Ratnakar 	int status;
3170590c391dSPadmanabh Ratnakar 	struct be_dma_mem cmd;
3171590c391dSPadmanabh Ratnakar 
3172590c391dSPadmanabh Ratnakar 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3173590c391dSPadmanabh Ratnakar 	cmd.size = sizeof(struct be_cmd_req_set_mac_list);
3174e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3175e51000dbSSriharsha Basavapatna 				     GFP_KERNEL);
3176d0320f75SJoe Perches 	if (!cmd.va)
3177590c391dSPadmanabh Ratnakar 		return -ENOMEM;
3178590c391dSPadmanabh Ratnakar 
3179590c391dSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
3180590c391dSPadmanabh Ratnakar 
3181590c391dSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
3182590c391dSPadmanabh Ratnakar 	if (!wrb) {
3183590c391dSPadmanabh Ratnakar 		status = -EBUSY;
3184590c391dSPadmanabh Ratnakar 		goto err;
3185590c391dSPadmanabh Ratnakar 	}
3186590c391dSPadmanabh Ratnakar 
3187590c391dSPadmanabh Ratnakar 	req = cmd.va;
3188590c391dSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3189590c391dSPadmanabh Ratnakar 			       OPCODE_COMMON_SET_MAC_LIST, sizeof(*req),
3190590c391dSPadmanabh Ratnakar 			       wrb, &cmd);
3191590c391dSPadmanabh Ratnakar 
3192590c391dSPadmanabh Ratnakar 	req->hdr.domain = domain;
3193590c391dSPadmanabh Ratnakar 	req->mac_count = mac_count;
3194590c391dSPadmanabh Ratnakar 	if (mac_count)
3195590c391dSPadmanabh Ratnakar 		memcpy(req->mac, mac_array, ETH_ALEN*mac_count);
3196590c391dSPadmanabh Ratnakar 
3197590c391dSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
3198590c391dSPadmanabh Ratnakar 
3199590c391dSPadmanabh Ratnakar err:
3200a2cc4e0bSSathya Perla 	dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
3201590c391dSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
3202590c391dSPadmanabh Ratnakar 	return status;
3203590c391dSPadmanabh Ratnakar }
32044762f6ceSAjit Khaparde 
32053175d8c2SSathya Perla /* Wrapper to delete any active MACs and provision the new mac.
32063175d8c2SSathya Perla  * Changes to MAC_LIST are allowed iff none of the MAC addresses in the
32073175d8c2SSathya Perla  * current list are active.
32083175d8c2SSathya Perla  */
32093175d8c2SSathya Perla int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
32103175d8c2SSathya Perla {
32113175d8c2SSathya Perla 	bool active_mac = false;
32123175d8c2SSathya Perla 	u8 old_mac[ETH_ALEN];
32133175d8c2SSathya Perla 	u32 pmac_id;
32143175d8c2SSathya Perla 	int status;
32153175d8c2SSathya Perla 
32163175d8c2SSathya Perla 	status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
3217b188f090SSuresh Reddy 					  &pmac_id, if_id, dom);
3218b188f090SSuresh Reddy 
32193175d8c2SSathya Perla 	if (!status && active_mac)
32203175d8c2SSathya Perla 		be_cmd_pmac_del(adapter, if_id, pmac_id, dom);
32213175d8c2SSathya Perla 
32223175d8c2SSathya Perla 	return be_cmd_set_mac_list(adapter, mac, mac ? 1 : 0, dom);
32233175d8c2SSathya Perla }
32243175d8c2SSathya Perla 
3225f1f3ee1bSAjit Khaparde int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
3226e7bcbd7bSKalesh AP 			  u32 domain, u16 intf_id, u16 hsw_mode, u8 spoofchk)
3227f1f3ee1bSAjit Khaparde {
3228f1f3ee1bSAjit Khaparde 	struct be_mcc_wrb *wrb;
3229f1f3ee1bSAjit Khaparde 	struct be_cmd_req_set_hsw_config *req;
3230f1f3ee1bSAjit Khaparde 	void *ctxt;
3231f1f3ee1bSAjit Khaparde 	int status;
3232f1f3ee1bSAjit Khaparde 
3233f1f3ee1bSAjit Khaparde 	spin_lock_bh(&adapter->mcc_lock);
3234f1f3ee1bSAjit Khaparde 
3235f1f3ee1bSAjit Khaparde 	wrb = wrb_from_mccq(adapter);
3236f1f3ee1bSAjit Khaparde 	if (!wrb) {
3237f1f3ee1bSAjit Khaparde 		status = -EBUSY;
3238f1f3ee1bSAjit Khaparde 		goto err;
3239f1f3ee1bSAjit Khaparde 	}
3240f1f3ee1bSAjit Khaparde 
3241f1f3ee1bSAjit Khaparde 	req = embedded_payload(wrb);
3242f1f3ee1bSAjit Khaparde 	ctxt = &req->context;
3243f1f3ee1bSAjit Khaparde 
3244f1f3ee1bSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3245a2cc4e0bSSathya Perla 			       OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb,
3246a2cc4e0bSSathya Perla 			       NULL);
3247f1f3ee1bSAjit Khaparde 
3248f1f3ee1bSAjit Khaparde 	req->hdr.domain = domain;
3249f1f3ee1bSAjit Khaparde 	AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
3250f1f3ee1bSAjit Khaparde 	if (pvid) {
3251f1f3ee1bSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
3252f1f3ee1bSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
3253f1f3ee1bSAjit Khaparde 	}
3254a77dcb8cSAjit Khaparde 	if (!BEx_chip(adapter) && hsw_mode) {
3255a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
3256a77dcb8cSAjit Khaparde 			      ctxt, adapter->hba_port_num);
3257a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
3258a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
3259a77dcb8cSAjit Khaparde 			      ctxt, hsw_mode);
3260a77dcb8cSAjit Khaparde 	}
3261f1f3ee1bSAjit Khaparde 
3262e7bcbd7bSKalesh AP 	/* Enable/disable both mac and vlan spoof checking */
3263e7bcbd7bSKalesh AP 	if (!BEx_chip(adapter) && spoofchk) {
3264e7bcbd7bSKalesh AP 		AMAP_SET_BITS(struct amap_set_hsw_context, mac_spoofchk,
3265e7bcbd7bSKalesh AP 			      ctxt, spoofchk);
3266e7bcbd7bSKalesh AP 		AMAP_SET_BITS(struct amap_set_hsw_context, vlan_spoofchk,
3267e7bcbd7bSKalesh AP 			      ctxt, spoofchk);
3268e7bcbd7bSKalesh AP 	}
3269e7bcbd7bSKalesh AP 
3270f1f3ee1bSAjit Khaparde 	be_dws_cpu_to_le(req->context, sizeof(req->context));
3271f1f3ee1bSAjit Khaparde 	status = be_mcc_notify_wait(adapter);
3272f1f3ee1bSAjit Khaparde 
3273f1f3ee1bSAjit Khaparde err:
3274f1f3ee1bSAjit Khaparde 	spin_unlock_bh(&adapter->mcc_lock);
3275f1f3ee1bSAjit Khaparde 	return status;
3276f1f3ee1bSAjit Khaparde }
3277f1f3ee1bSAjit Khaparde 
3278f1f3ee1bSAjit Khaparde /* Get Hyper switch config */
3279f1f3ee1bSAjit Khaparde int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
3280e7bcbd7bSKalesh AP 			  u32 domain, u16 intf_id, u8 *mode, bool *spoofchk)
3281f1f3ee1bSAjit Khaparde {
3282f1f3ee1bSAjit Khaparde 	struct be_mcc_wrb *wrb;
3283f1f3ee1bSAjit Khaparde 	struct be_cmd_req_get_hsw_config *req;
3284f1f3ee1bSAjit Khaparde 	void *ctxt;
3285f1f3ee1bSAjit Khaparde 	int status;
3286f1f3ee1bSAjit Khaparde 	u16 vid;
3287f1f3ee1bSAjit Khaparde 
3288f1f3ee1bSAjit Khaparde 	spin_lock_bh(&adapter->mcc_lock);
3289f1f3ee1bSAjit Khaparde 
3290f1f3ee1bSAjit Khaparde 	wrb = wrb_from_mccq(adapter);
3291f1f3ee1bSAjit Khaparde 	if (!wrb) {
3292f1f3ee1bSAjit Khaparde 		status = -EBUSY;
3293f1f3ee1bSAjit Khaparde 		goto err;
3294f1f3ee1bSAjit Khaparde 	}
3295f1f3ee1bSAjit Khaparde 
3296f1f3ee1bSAjit Khaparde 	req = embedded_payload(wrb);
3297f1f3ee1bSAjit Khaparde 	ctxt = &req->context;
3298f1f3ee1bSAjit Khaparde 
3299f1f3ee1bSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3300a2cc4e0bSSathya Perla 			       OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb,
3301a2cc4e0bSSathya Perla 			       NULL);
3302f1f3ee1bSAjit Khaparde 
3303f1f3ee1bSAjit Khaparde 	req->hdr.domain = domain;
3304a77dcb8cSAjit Khaparde 	AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3305a77dcb8cSAjit Khaparde 		      ctxt, intf_id);
3306f1f3ee1bSAjit Khaparde 	AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
3307a77dcb8cSAjit Khaparde 
33082c07c1d7SVasundhara Volam 	if (!BEx_chip(adapter) && mode) {
3309a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3310a77dcb8cSAjit Khaparde 			      ctxt, adapter->hba_port_num);
3311a77dcb8cSAjit Khaparde 		AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
3312a77dcb8cSAjit Khaparde 	}
3313f1f3ee1bSAjit Khaparde 	be_dws_cpu_to_le(req->context, sizeof(req->context));
3314f1f3ee1bSAjit Khaparde 
3315f1f3ee1bSAjit Khaparde 	status = be_mcc_notify_wait(adapter);
3316f1f3ee1bSAjit Khaparde 	if (!status) {
3317f1f3ee1bSAjit Khaparde 		struct be_cmd_resp_get_hsw_config *resp =
3318f1f3ee1bSAjit Khaparde 						embedded_payload(wrb);
331903d28ffeSKalesh AP 
3320a2cc4e0bSSathya Perla 		be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
3321f1f3ee1bSAjit Khaparde 		vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3322f1f3ee1bSAjit Khaparde 				    pvid, &resp->context);
3323a77dcb8cSAjit Khaparde 		if (pvid)
3324f1f3ee1bSAjit Khaparde 			*pvid = le16_to_cpu(vid);
3325a77dcb8cSAjit Khaparde 		if (mode)
3326a77dcb8cSAjit Khaparde 			*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3327a77dcb8cSAjit Khaparde 					      port_fwd_type, &resp->context);
3328e7bcbd7bSKalesh AP 		if (spoofchk)
3329e7bcbd7bSKalesh AP 			*spoofchk =
3330e7bcbd7bSKalesh AP 				AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3331e7bcbd7bSKalesh AP 					      spoofchk, &resp->context);
3332f1f3ee1bSAjit Khaparde 	}
3333f1f3ee1bSAjit Khaparde 
3334f1f3ee1bSAjit Khaparde err:
3335f1f3ee1bSAjit Khaparde 	spin_unlock_bh(&adapter->mcc_lock);
3336f1f3ee1bSAjit Khaparde 	return status;
3337f1f3ee1bSAjit Khaparde }
3338f1f3ee1bSAjit Khaparde 
3339f7062ee5SSathya Perla static bool be_is_wol_excluded(struct be_adapter *adapter)
3340f7062ee5SSathya Perla {
3341f7062ee5SSathya Perla 	struct pci_dev *pdev = adapter->pdev;
3342f7062ee5SSathya Perla 
334318c57c74SKalesh AP 	if (be_virtfn(adapter))
3344f7062ee5SSathya Perla 		return true;
3345f7062ee5SSathya Perla 
3346f7062ee5SSathya Perla 	switch (pdev->subsystem_device) {
3347f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID1:
3348f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID2:
3349f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID3:
3350f7062ee5SSathya Perla 	case OC_SUBSYS_DEVICE_ID4:
3351f7062ee5SSathya Perla 		return true;
3352f7062ee5SSathya Perla 	default:
3353f7062ee5SSathya Perla 		return false;
3354f7062ee5SSathya Perla 	}
3355f7062ee5SSathya Perla }
3356f7062ee5SSathya Perla 
33574762f6ceSAjit Khaparde int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
33584762f6ceSAjit Khaparde {
33594762f6ceSAjit Khaparde 	struct be_mcc_wrb *wrb;
33604762f6ceSAjit Khaparde 	struct be_cmd_req_acpi_wol_magic_config_v1 *req;
336176a9e08eSSuresh Reddy 	int status = 0;
33624762f6ceSAjit Khaparde 	struct be_dma_mem cmd;
33634762f6ceSAjit Khaparde 
3364f25b119cSPadmanabh Ratnakar 	if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
3365f25b119cSPadmanabh Ratnakar 			    CMD_SUBSYSTEM_ETH))
3366f25b119cSPadmanabh Ratnakar 		return -EPERM;
3367f25b119cSPadmanabh Ratnakar 
336876a9e08eSSuresh Reddy 	if (be_is_wol_excluded(adapter))
336976a9e08eSSuresh Reddy 		return status;
337076a9e08eSSuresh Reddy 
3371d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3372d98ef50fSSuresh Reddy 		return -1;
3373d98ef50fSSuresh Reddy 
33744762f6ceSAjit Khaparde 	memset(&cmd, 0, sizeof(struct be_dma_mem));
33754762f6ceSAjit Khaparde 	cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
3376e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3377e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
33784762f6ceSAjit Khaparde 	if (!cmd.va) {
3379a2cc4e0bSSathya Perla 		dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
3380d98ef50fSSuresh Reddy 		status = -ENOMEM;
3381d98ef50fSSuresh Reddy 		goto err;
33824762f6ceSAjit Khaparde 	}
33834762f6ceSAjit Khaparde 
33844762f6ceSAjit Khaparde 	wrb = wrb_from_mbox(adapter);
33854762f6ceSAjit Khaparde 	if (!wrb) {
33864762f6ceSAjit Khaparde 		status = -EBUSY;
33874762f6ceSAjit Khaparde 		goto err;
33884762f6ceSAjit Khaparde 	}
33894762f6ceSAjit Khaparde 
33904762f6ceSAjit Khaparde 	req = cmd.va;
33914762f6ceSAjit Khaparde 
33924762f6ceSAjit Khaparde 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
33934762f6ceSAjit Khaparde 			       OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
339476a9e08eSSuresh Reddy 			       sizeof(*req), wrb, &cmd);
33954762f6ceSAjit Khaparde 
33964762f6ceSAjit Khaparde 	req->hdr.version = 1;
33974762f6ceSAjit Khaparde 	req->query_options = BE_GET_WOL_CAP;
33984762f6ceSAjit Khaparde 
33994762f6ceSAjit Khaparde 	status = be_mbox_notify_wait(adapter);
34004762f6ceSAjit Khaparde 	if (!status) {
34014762f6ceSAjit Khaparde 		struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
340203d28ffeSKalesh AP 
34034762f6ceSAjit Khaparde 		resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *)cmd.va;
34044762f6ceSAjit Khaparde 
34054762f6ceSAjit Khaparde 		adapter->wol_cap = resp->wol_settings;
340676a9e08eSSuresh Reddy 		if (adapter->wol_cap & BE_WOL_CAP)
340776a9e08eSSuresh Reddy 			adapter->wol_en = true;
34084762f6ceSAjit Khaparde 	}
34094762f6ceSAjit Khaparde err:
34104762f6ceSAjit Khaparde 	mutex_unlock(&adapter->mbox_lock);
3411d98ef50fSSuresh Reddy 	if (cmd.va)
3412e51000dbSSriharsha Basavapatna 		dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
3413e51000dbSSriharsha Basavapatna 				  cmd.dma);
34144762f6ceSAjit Khaparde 	return status;
3415941a77d5SSomnath Kotur 
3416941a77d5SSomnath Kotur }
3417baaa08d1SVasundhara Volam 
3418baaa08d1SVasundhara Volam int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level)
3419baaa08d1SVasundhara Volam {
3420baaa08d1SVasundhara Volam 	struct be_dma_mem extfat_cmd;
3421baaa08d1SVasundhara Volam 	struct be_fat_conf_params *cfgs;
3422baaa08d1SVasundhara Volam 	int status;
3423baaa08d1SVasundhara Volam 	int i, j;
3424baaa08d1SVasundhara Volam 
3425baaa08d1SVasundhara Volam 	memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3426baaa08d1SVasundhara Volam 	extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3427e51000dbSSriharsha Basavapatna 	extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
3428e51000dbSSriharsha Basavapatna 					    extfat_cmd.size, &extfat_cmd.dma,
3429e51000dbSSriharsha Basavapatna 					    GFP_ATOMIC);
3430baaa08d1SVasundhara Volam 	if (!extfat_cmd.va)
3431baaa08d1SVasundhara Volam 		return -ENOMEM;
3432baaa08d1SVasundhara Volam 
3433baaa08d1SVasundhara Volam 	status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3434baaa08d1SVasundhara Volam 	if (status)
3435baaa08d1SVasundhara Volam 		goto err;
3436baaa08d1SVasundhara Volam 
3437baaa08d1SVasundhara Volam 	cfgs = (struct be_fat_conf_params *)
3438baaa08d1SVasundhara Volam 			(extfat_cmd.va + sizeof(struct be_cmd_resp_hdr));
3439baaa08d1SVasundhara Volam 	for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
3440baaa08d1SVasundhara Volam 		u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
344103d28ffeSKalesh AP 
3442baaa08d1SVasundhara Volam 		for (j = 0; j < num_modes; j++) {
3443baaa08d1SVasundhara Volam 			if (cfgs->module[i].trace_lvl[j].mode == MODE_UART)
3444baaa08d1SVasundhara Volam 				cfgs->module[i].trace_lvl[j].dbg_lvl =
3445baaa08d1SVasundhara Volam 							cpu_to_le32(level);
3446baaa08d1SVasundhara Volam 		}
3447baaa08d1SVasundhara Volam 	}
3448baaa08d1SVasundhara Volam 
3449baaa08d1SVasundhara Volam 	status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs);
3450baaa08d1SVasundhara Volam err:
3451e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va,
3452baaa08d1SVasundhara Volam 			  extfat_cmd.dma);
3453baaa08d1SVasundhara Volam 	return status;
3454baaa08d1SVasundhara Volam }
3455baaa08d1SVasundhara Volam 
3456baaa08d1SVasundhara Volam int be_cmd_get_fw_log_level(struct be_adapter *adapter)
3457baaa08d1SVasundhara Volam {
3458baaa08d1SVasundhara Volam 	struct be_dma_mem extfat_cmd;
3459baaa08d1SVasundhara Volam 	struct be_fat_conf_params *cfgs;
3460baaa08d1SVasundhara Volam 	int status, j;
3461baaa08d1SVasundhara Volam 	int level = 0;
3462baaa08d1SVasundhara Volam 
3463baaa08d1SVasundhara Volam 	memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3464baaa08d1SVasundhara Volam 	extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3465e51000dbSSriharsha Basavapatna 	extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
3466e51000dbSSriharsha Basavapatna 					    extfat_cmd.size, &extfat_cmd.dma,
3467e51000dbSSriharsha Basavapatna 					    GFP_ATOMIC);
3468baaa08d1SVasundhara Volam 
3469baaa08d1SVasundhara Volam 	if (!extfat_cmd.va) {
3470baaa08d1SVasundhara Volam 		dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
3471baaa08d1SVasundhara Volam 			__func__);
3472baaa08d1SVasundhara Volam 		goto err;
3473baaa08d1SVasundhara Volam 	}
3474baaa08d1SVasundhara Volam 
3475baaa08d1SVasundhara Volam 	status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3476baaa08d1SVasundhara Volam 	if (!status) {
3477baaa08d1SVasundhara Volam 		cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
3478baaa08d1SVasundhara Volam 						sizeof(struct be_cmd_resp_hdr));
347903d28ffeSKalesh AP 
3480baaa08d1SVasundhara Volam 		for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
3481baaa08d1SVasundhara Volam 			if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
3482baaa08d1SVasundhara Volam 				level = cfgs->module[0].trace_lvl[j].dbg_lvl;
3483baaa08d1SVasundhara Volam 		}
3484baaa08d1SVasundhara Volam 	}
3485e51000dbSSriharsha Basavapatna 	dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va,
3486baaa08d1SVasundhara Volam 			  extfat_cmd.dma);
3487baaa08d1SVasundhara Volam err:
3488baaa08d1SVasundhara Volam 	return level;
3489baaa08d1SVasundhara Volam }
3490baaa08d1SVasundhara Volam 
3491941a77d5SSomnath Kotur int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
3492941a77d5SSomnath Kotur 				   struct be_dma_mem *cmd)
3493941a77d5SSomnath Kotur {
3494941a77d5SSomnath Kotur 	struct be_mcc_wrb *wrb;
3495941a77d5SSomnath Kotur 	struct be_cmd_req_get_ext_fat_caps *req;
3496941a77d5SSomnath Kotur 	int status;
3497941a77d5SSomnath Kotur 
3498941a77d5SSomnath Kotur 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3499941a77d5SSomnath Kotur 		return -1;
3500941a77d5SSomnath Kotur 
3501941a77d5SSomnath Kotur 	wrb = wrb_from_mbox(adapter);
3502941a77d5SSomnath Kotur 	if (!wrb) {
3503941a77d5SSomnath Kotur 		status = -EBUSY;
3504941a77d5SSomnath Kotur 		goto err;
3505941a77d5SSomnath Kotur 	}
3506941a77d5SSomnath Kotur 
3507941a77d5SSomnath Kotur 	req = cmd->va;
3508941a77d5SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3509941a77d5SSomnath Kotur 			       OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
3510941a77d5SSomnath Kotur 			       cmd->size, wrb, cmd);
3511941a77d5SSomnath Kotur 	req->parameter_type = cpu_to_le32(1);
3512941a77d5SSomnath Kotur 
3513941a77d5SSomnath Kotur 	status = be_mbox_notify_wait(adapter);
3514941a77d5SSomnath Kotur err:
3515941a77d5SSomnath Kotur 	mutex_unlock(&adapter->mbox_lock);
3516941a77d5SSomnath Kotur 	return status;
3517941a77d5SSomnath Kotur }
3518941a77d5SSomnath Kotur 
3519941a77d5SSomnath Kotur int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
3520941a77d5SSomnath Kotur 				   struct be_dma_mem *cmd,
3521941a77d5SSomnath Kotur 				   struct be_fat_conf_params *configs)
3522941a77d5SSomnath Kotur {
3523941a77d5SSomnath Kotur 	struct be_mcc_wrb *wrb;
3524941a77d5SSomnath Kotur 	struct be_cmd_req_set_ext_fat_caps *req;
3525941a77d5SSomnath Kotur 	int status;
3526941a77d5SSomnath Kotur 
3527941a77d5SSomnath Kotur 	spin_lock_bh(&adapter->mcc_lock);
3528941a77d5SSomnath Kotur 
3529941a77d5SSomnath Kotur 	wrb = wrb_from_mccq(adapter);
3530941a77d5SSomnath Kotur 	if (!wrb) {
3531941a77d5SSomnath Kotur 		status = -EBUSY;
3532941a77d5SSomnath Kotur 		goto err;
3533941a77d5SSomnath Kotur 	}
3534941a77d5SSomnath Kotur 
3535941a77d5SSomnath Kotur 	req = cmd->va;
3536941a77d5SSomnath Kotur 	memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
3537941a77d5SSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3538941a77d5SSomnath Kotur 			       OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
3539941a77d5SSomnath Kotur 			       cmd->size, wrb, cmd);
3540941a77d5SSomnath Kotur 
3541941a77d5SSomnath Kotur 	status = be_mcc_notify_wait(adapter);
3542941a77d5SSomnath Kotur err:
3543941a77d5SSomnath Kotur 	spin_unlock_bh(&adapter->mcc_lock);
3544941a77d5SSomnath Kotur 	return status;
35454762f6ceSAjit Khaparde }
35466a4ab669SParav Pandit 
354721252377SVasundhara Volam int be_cmd_query_port_name(struct be_adapter *adapter)
3548b4e32a71SPadmanabh Ratnakar {
3549b4e32a71SPadmanabh Ratnakar 	struct be_cmd_req_get_port_name *req;
355021252377SVasundhara Volam 	struct be_mcc_wrb *wrb;
3551b4e32a71SPadmanabh Ratnakar 	int status;
3552b4e32a71SPadmanabh Ratnakar 
355321252377SVasundhara Volam 	if (mutex_lock_interruptible(&adapter->mbox_lock))
355421252377SVasundhara Volam 		return -1;
3555b4e32a71SPadmanabh Ratnakar 
355621252377SVasundhara Volam 	wrb = wrb_from_mbox(adapter);
3557b4e32a71SPadmanabh Ratnakar 	req = embedded_payload(wrb);
3558b4e32a71SPadmanabh Ratnakar 
3559b4e32a71SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3560b4e32a71SPadmanabh Ratnakar 			       OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
3561b4e32a71SPadmanabh Ratnakar 			       NULL);
356221252377SVasundhara Volam 	if (!BEx_chip(adapter))
3563b4e32a71SPadmanabh Ratnakar 		req->hdr.version = 1;
3564b4e32a71SPadmanabh Ratnakar 
356521252377SVasundhara Volam 	status = be_mbox_notify_wait(adapter);
3566b4e32a71SPadmanabh Ratnakar 	if (!status) {
3567b4e32a71SPadmanabh Ratnakar 		struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
356803d28ffeSKalesh AP 
356921252377SVasundhara Volam 		adapter->port_name = resp->port_name[adapter->hba_port_num];
3570b4e32a71SPadmanabh Ratnakar 	} else {
357121252377SVasundhara Volam 		adapter->port_name = adapter->hba_port_num + '0';
3572b4e32a71SPadmanabh Ratnakar 	}
357321252377SVasundhara Volam 
357421252377SVasundhara Volam 	mutex_unlock(&adapter->mbox_lock);
3575b4e32a71SPadmanabh Ratnakar 	return status;
3576b4e32a71SPadmanabh Ratnakar }
3577b4e32a71SPadmanabh Ratnakar 
357810cccf60SVasundhara Volam /* Descriptor type */
357910cccf60SVasundhara Volam enum {
358010cccf60SVasundhara Volam 	FUNC_DESC = 1,
358110cccf60SVasundhara Volam 	VFT_DESC = 2
358210cccf60SVasundhara Volam };
358310cccf60SVasundhara Volam 
358410cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
358510cccf60SVasundhara Volam 					       int desc_type)
3586abb93951SPadmanabh Ratnakar {
3587150d58c7SVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
358810cccf60SVasundhara Volam 	struct be_nic_res_desc *nic;
3589abb93951SPadmanabh Ratnakar 	int i;
3590abb93951SPadmanabh Ratnakar 
3591abb93951SPadmanabh Ratnakar 	for (i = 0; i < desc_count; i++) {
3592150d58c7SVasundhara Volam 		if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
359310cccf60SVasundhara Volam 		    hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
359410cccf60SVasundhara Volam 			nic = (struct be_nic_res_desc *)hdr;
359510cccf60SVasundhara Volam 			if (desc_type == FUNC_DESC ||
359610cccf60SVasundhara Volam 			    (desc_type == VFT_DESC &&
359710cccf60SVasundhara Volam 			     nic->flags & (1 << VFT_SHIFT)))
359810cccf60SVasundhara Volam 				return nic;
359910cccf60SVasundhara Volam 		}
3600150d58c7SVasundhara Volam 
3601150d58c7SVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3602150d58c7SVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3603150d58c7SVasundhara Volam 	}
3604950e2958SWei Yang 	return NULL;
3605abb93951SPadmanabh Ratnakar }
3606abb93951SPadmanabh Ratnakar 
360710cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count)
360810cccf60SVasundhara Volam {
360910cccf60SVasundhara Volam 	return be_get_nic_desc(buf, desc_count, VFT_DESC);
361010cccf60SVasundhara Volam }
361110cccf60SVasundhara Volam 
361210cccf60SVasundhara Volam static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count)
361310cccf60SVasundhara Volam {
361410cccf60SVasundhara Volam 	return be_get_nic_desc(buf, desc_count, FUNC_DESC);
361510cccf60SVasundhara Volam }
361610cccf60SVasundhara Volam 
3617150d58c7SVasundhara Volam static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
3618150d58c7SVasundhara Volam 						 u32 desc_count)
3619150d58c7SVasundhara Volam {
3620150d58c7SVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3621150d58c7SVasundhara Volam 	struct be_pcie_res_desc *pcie;
3622150d58c7SVasundhara Volam 	int i;
3623150d58c7SVasundhara Volam 
3624150d58c7SVasundhara Volam 	for (i = 0; i < desc_count; i++) {
3625150d58c7SVasundhara Volam 		if ((hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
3626150d58c7SVasundhara Volam 		     hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1)) {
3627150d58c7SVasundhara Volam 			pcie = (struct be_pcie_res_desc	*)hdr;
3628150d58c7SVasundhara Volam 			if (pcie->pf_num == devfn)
3629150d58c7SVasundhara Volam 				return pcie;
3630150d58c7SVasundhara Volam 		}
3631150d58c7SVasundhara Volam 
3632150d58c7SVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3633150d58c7SVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3634150d58c7SVasundhara Volam 	}
3635abb93951SPadmanabh Ratnakar 	return NULL;
3636abb93951SPadmanabh Ratnakar }
3637abb93951SPadmanabh Ratnakar 
3638f93f160bSVasundhara Volam static struct be_port_res_desc *be_get_port_desc(u8 *buf, u32 desc_count)
3639f93f160bSVasundhara Volam {
3640f93f160bSVasundhara Volam 	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3641f93f160bSVasundhara Volam 	int i;
3642f93f160bSVasundhara Volam 
3643f93f160bSVasundhara Volam 	for (i = 0; i < desc_count; i++) {
3644f93f160bSVasundhara Volam 		if (hdr->desc_type == PORT_RESOURCE_DESC_TYPE_V1)
3645f93f160bSVasundhara Volam 			return (struct be_port_res_desc *)hdr;
3646f93f160bSVasundhara Volam 
3647f93f160bSVasundhara Volam 		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3648f93f160bSVasundhara Volam 		hdr = (void *)hdr + hdr->desc_len;
3649f93f160bSVasundhara Volam 	}
3650f93f160bSVasundhara Volam 	return NULL;
3651f93f160bSVasundhara Volam }
3652f93f160bSVasundhara Volam 
365392bf14abSSathya Perla static void be_copy_nic_desc(struct be_resources *res,
365492bf14abSSathya Perla 			     struct be_nic_res_desc *desc)
365592bf14abSSathya Perla {
365692bf14abSSathya Perla 	res->max_uc_mac = le16_to_cpu(desc->unicast_mac_count);
365792bf14abSSathya Perla 	res->max_vlans = le16_to_cpu(desc->vlan_count);
365892bf14abSSathya Perla 	res->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
365992bf14abSSathya Perla 	res->max_tx_qs = le16_to_cpu(desc->txq_count);
366092bf14abSSathya Perla 	res->max_rss_qs = le16_to_cpu(desc->rssq_count);
366192bf14abSSathya Perla 	res->max_rx_qs = le16_to_cpu(desc->rq_count);
366292bf14abSSathya Perla 	res->max_evt_qs = le16_to_cpu(desc->eq_count);
3663f2858738SVasundhara Volam 	res->max_cq_count = le16_to_cpu(desc->cq_count);
3664f2858738SVasundhara Volam 	res->max_iface_count = le16_to_cpu(desc->iface_count);
3665f2858738SVasundhara Volam 	res->max_mcc_count = le16_to_cpu(desc->mcc_count);
366692bf14abSSathya Perla 	/* Clear flags that driver is not interested in */
366792bf14abSSathya Perla 	res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
366892bf14abSSathya Perla 				BE_IF_CAP_FLAGS_WANT;
366992bf14abSSathya Perla }
367092bf14abSSathya Perla 
3671abb93951SPadmanabh Ratnakar /* Uses Mbox */
367292bf14abSSathya Perla int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
3673abb93951SPadmanabh Ratnakar {
3674abb93951SPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
3675abb93951SPadmanabh Ratnakar 	struct be_cmd_req_get_func_config *req;
3676abb93951SPadmanabh Ratnakar 	int status;
3677abb93951SPadmanabh Ratnakar 	struct be_dma_mem cmd;
3678abb93951SPadmanabh Ratnakar 
3679d98ef50fSSuresh Reddy 	if (mutex_lock_interruptible(&adapter->mbox_lock))
3680d98ef50fSSuresh Reddy 		return -1;
3681d98ef50fSSuresh Reddy 
3682abb93951SPadmanabh Ratnakar 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3683abb93951SPadmanabh Ratnakar 	cmd.size = sizeof(struct be_cmd_resp_get_func_config);
3684e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3685e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
3686abb93951SPadmanabh Ratnakar 	if (!cmd.va) {
3687abb93951SPadmanabh Ratnakar 		dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
3688d98ef50fSSuresh Reddy 		status = -ENOMEM;
3689d98ef50fSSuresh Reddy 		goto err;
3690abb93951SPadmanabh Ratnakar 	}
3691abb93951SPadmanabh Ratnakar 
3692abb93951SPadmanabh Ratnakar 	wrb = wrb_from_mbox(adapter);
3693abb93951SPadmanabh Ratnakar 	if (!wrb) {
3694abb93951SPadmanabh Ratnakar 		status = -EBUSY;
3695abb93951SPadmanabh Ratnakar 		goto err;
3696abb93951SPadmanabh Ratnakar 	}
3697abb93951SPadmanabh Ratnakar 
3698abb93951SPadmanabh Ratnakar 	req = cmd.va;
3699abb93951SPadmanabh Ratnakar 
3700abb93951SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3701abb93951SPadmanabh Ratnakar 			       OPCODE_COMMON_GET_FUNC_CONFIG,
3702abb93951SPadmanabh Ratnakar 			       cmd.size, wrb, &cmd);
3703abb93951SPadmanabh Ratnakar 
370428710c55SKalesh AP 	if (skyhawk_chip(adapter))
370528710c55SKalesh AP 		req->hdr.version = 1;
370628710c55SKalesh AP 
3707abb93951SPadmanabh Ratnakar 	status = be_mbox_notify_wait(adapter);
3708abb93951SPadmanabh Ratnakar 	if (!status) {
3709abb93951SPadmanabh Ratnakar 		struct be_cmd_resp_get_func_config *resp = cmd.va;
3710abb93951SPadmanabh Ratnakar 		u32 desc_count = le32_to_cpu(resp->desc_count);
3711150d58c7SVasundhara Volam 		struct be_nic_res_desc *desc;
3712abb93951SPadmanabh Ratnakar 
371310cccf60SVasundhara Volam 		desc = be_get_func_nic_desc(resp->func_param, desc_count);
3714abb93951SPadmanabh Ratnakar 		if (!desc) {
3715abb93951SPadmanabh Ratnakar 			status = -EINVAL;
3716abb93951SPadmanabh Ratnakar 			goto err;
3717abb93951SPadmanabh Ratnakar 		}
3718d5c18473SPadmanabh Ratnakar 		adapter->pf_number = desc->pf_num;
371992bf14abSSathya Perla 		be_copy_nic_desc(res, desc);
3720abb93951SPadmanabh Ratnakar 	}
3721abb93951SPadmanabh Ratnakar err:
3722abb93951SPadmanabh Ratnakar 	mutex_unlock(&adapter->mbox_lock);
3723d98ef50fSSuresh Reddy 	if (cmd.va)
3724e51000dbSSriharsha Basavapatna 		dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
3725e51000dbSSriharsha Basavapatna 				  cmd.dma);
3726abb93951SPadmanabh Ratnakar 	return status;
3727abb93951SPadmanabh Ratnakar }
3728abb93951SPadmanabh Ratnakar 
372972ef3a88SSomnath Kotur /* Will use MBOX only if MCCQ has not been created
373072ef3a88SSomnath Kotur  * non-zero domain => a PF is querying this on behalf of a VF
373172ef3a88SSomnath Kotur  * zero domain => a PF or a VF is querying this for itself
373272ef3a88SSomnath Kotur  */
373392bf14abSSathya Perla int be_cmd_get_profile_config(struct be_adapter *adapter,
3734f2858738SVasundhara Volam 			      struct be_resources *res, u8 query, u8 domain)
3735a05f99dbSVasundhara Volam {
3736150d58c7SVasundhara Volam 	struct be_cmd_resp_get_profile_config *resp;
3737ba48c0c9SVasundhara Volam 	struct be_cmd_req_get_profile_config *req;
373810cccf60SVasundhara Volam 	struct be_nic_res_desc *vf_res;
3739150d58c7SVasundhara Volam 	struct be_pcie_res_desc *pcie;
3740f93f160bSVasundhara Volam 	struct be_port_res_desc *port;
3741150d58c7SVasundhara Volam 	struct be_nic_res_desc *nic;
3742ba48c0c9SVasundhara Volam 	struct be_mcc_wrb wrb = {0};
3743a05f99dbSVasundhara Volam 	struct be_dma_mem cmd;
3744f2858738SVasundhara Volam 	u16 desc_count;
3745a05f99dbSVasundhara Volam 	int status;
3746a05f99dbSVasundhara Volam 
3747a05f99dbSVasundhara Volam 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3748a05f99dbSVasundhara Volam 	cmd.size = sizeof(struct be_cmd_resp_get_profile_config);
3749e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3750e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
3751150d58c7SVasundhara Volam 	if (!cmd.va)
3752a05f99dbSVasundhara Volam 		return -ENOMEM;
3753a05f99dbSVasundhara Volam 
3754ba48c0c9SVasundhara Volam 	req = cmd.va;
3755ba48c0c9SVasundhara Volam 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3756ba48c0c9SVasundhara Volam 			       OPCODE_COMMON_GET_PROFILE_CONFIG,
3757ba48c0c9SVasundhara Volam 			       cmd.size, &wrb, &cmd);
3758ba48c0c9SVasundhara Volam 
3759ba48c0c9SVasundhara Volam 	if (!lancer_chip(adapter))
3760ba48c0c9SVasundhara Volam 		req->hdr.version = 1;
3761ba48c0c9SVasundhara Volam 	req->type = ACTIVE_PROFILE_TYPE;
376272ef3a88SSomnath Kotur 	/* When a function is querying profile information relating to
376372ef3a88SSomnath Kotur 	 * itself hdr.pf_number must be set to it's pci_func_num + 1
376472ef3a88SSomnath Kotur 	 */
376572ef3a88SSomnath Kotur 	req->hdr.domain = domain;
376672ef3a88SSomnath Kotur 	if (domain == 0)
376772ef3a88SSomnath Kotur 		req->hdr.pf_num = adapter->pci_func_num + 1;
3768ba48c0c9SVasundhara Volam 
3769f2858738SVasundhara Volam 	/* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
3770f2858738SVasundhara Volam 	 * descriptors with all bits set to "1" for the fields which can be
3771f2858738SVasundhara Volam 	 * modified using SET_PROFILE_CONFIG cmd.
3772f2858738SVasundhara Volam 	 */
3773f2858738SVasundhara Volam 	if (query == RESOURCE_MODIFIABLE)
3774f2858738SVasundhara Volam 		req->type |= QUERY_MODIFIABLE_FIELDS_TYPE;
3775f2858738SVasundhara Volam 
3776ba48c0c9SVasundhara Volam 	status = be_cmd_notify_wait(adapter, &wrb);
3777150d58c7SVasundhara Volam 	if (status)
3778abb93951SPadmanabh Ratnakar 		goto err;
3779150d58c7SVasundhara Volam 
3780150d58c7SVasundhara Volam 	resp = cmd.va;
3781f2858738SVasundhara Volam 	desc_count = le16_to_cpu(resp->desc_count);
3782150d58c7SVasundhara Volam 
3783150d58c7SVasundhara Volam 	pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
3784150d58c7SVasundhara Volam 				desc_count);
3785150d58c7SVasundhara Volam 	if (pcie)
378692bf14abSSathya Perla 		res->max_vfs = le16_to_cpu(pcie->num_vfs);
3787150d58c7SVasundhara Volam 
3788f93f160bSVasundhara Volam 	port = be_get_port_desc(resp->func_param, desc_count);
3789f93f160bSVasundhara Volam 	if (port)
3790f93f160bSVasundhara Volam 		adapter->mc_type = port->mc_type;
3791f93f160bSVasundhara Volam 
379210cccf60SVasundhara Volam 	nic = be_get_func_nic_desc(resp->func_param, desc_count);
379392bf14abSSathya Perla 	if (nic)
379492bf14abSSathya Perla 		be_copy_nic_desc(res, nic);
379592bf14abSSathya Perla 
379610cccf60SVasundhara Volam 	vf_res = be_get_vft_desc(resp->func_param, desc_count);
379710cccf60SVasundhara Volam 	if (vf_res)
379810cccf60SVasundhara Volam 		res->vf_if_cap_flags = vf_res->cap_flags;
3799abb93951SPadmanabh Ratnakar err:
3800a05f99dbSVasundhara Volam 	if (cmd.va)
3801e51000dbSSriharsha Basavapatna 		dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
3802e51000dbSSriharsha Basavapatna 				  cmd.dma);
3803abb93951SPadmanabh Ratnakar 	return status;
3804abb93951SPadmanabh Ratnakar }
3805abb93951SPadmanabh Ratnakar 
3806bec84e6bSVasundhara Volam /* Will use MBOX only if MCCQ has not been created */
3807bec84e6bSVasundhara Volam static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
3808bec84e6bSVasundhara Volam 				     int size, int count, u8 version, u8 domain)
3809d5c18473SPadmanabh Ratnakar {
3810d5c18473SPadmanabh Ratnakar 	struct be_cmd_req_set_profile_config *req;
3811bec84e6bSVasundhara Volam 	struct be_mcc_wrb wrb = {0};
3812bec84e6bSVasundhara Volam 	struct be_dma_mem cmd;
3813d5c18473SPadmanabh Ratnakar 	int status;
3814d5c18473SPadmanabh Ratnakar 
3815bec84e6bSVasundhara Volam 	memset(&cmd, 0, sizeof(struct be_dma_mem));
3816bec84e6bSVasundhara Volam 	cmd.size = sizeof(struct be_cmd_req_set_profile_config);
3817e51000dbSSriharsha Basavapatna 	cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3818e51000dbSSriharsha Basavapatna 				     GFP_ATOMIC);
3819bec84e6bSVasundhara Volam 	if (!cmd.va)
3820bec84e6bSVasundhara Volam 		return -ENOMEM;
3821d5c18473SPadmanabh Ratnakar 
3822bec84e6bSVasundhara Volam 	req = cmd.va;
3823d5c18473SPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3824bec84e6bSVasundhara Volam 			       OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
3825bec84e6bSVasundhara Volam 			       &wrb, &cmd);
3826a401801cSSathya Perla 	req->hdr.version = version;
3827d5c18473SPadmanabh Ratnakar 	req->hdr.domain = domain;
3828bec84e6bSVasundhara Volam 	req->desc_count = cpu_to_le32(count);
3829a401801cSSathya Perla 	memcpy(req->desc, desc, size);
3830d5c18473SPadmanabh Ratnakar 
3831bec84e6bSVasundhara Volam 	status = be_cmd_notify_wait(adapter, &wrb);
3832bec84e6bSVasundhara Volam 
3833bec84e6bSVasundhara Volam 	if (cmd.va)
3834e51000dbSSriharsha Basavapatna 		dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
3835e51000dbSSriharsha Basavapatna 				  cmd.dma);
3836d5c18473SPadmanabh Ratnakar 	return status;
3837d5c18473SPadmanabh Ratnakar }
3838d5c18473SPadmanabh Ratnakar 
3839a401801cSSathya Perla /* Mark all fields invalid */
3840bec84e6bSVasundhara Volam static void be_reset_nic_desc(struct be_nic_res_desc *nic)
3841a401801cSSathya Perla {
3842a401801cSSathya Perla 	memset(nic, 0, sizeof(*nic));
3843a401801cSSathya Perla 	nic->unicast_mac_count = 0xFFFF;
3844a401801cSSathya Perla 	nic->mcc_count = 0xFFFF;
3845a401801cSSathya Perla 	nic->vlan_count = 0xFFFF;
3846a401801cSSathya Perla 	nic->mcast_mac_count = 0xFFFF;
3847a401801cSSathya Perla 	nic->txq_count = 0xFFFF;
3848a401801cSSathya Perla 	nic->rq_count = 0xFFFF;
3849a401801cSSathya Perla 	nic->rssq_count = 0xFFFF;
3850a401801cSSathya Perla 	nic->lro_count = 0xFFFF;
3851a401801cSSathya Perla 	nic->cq_count = 0xFFFF;
3852a401801cSSathya Perla 	nic->toe_conn_count = 0xFFFF;
3853a401801cSSathya Perla 	nic->eq_count = 0xFFFF;
38540f77ba73SRavikumar Nelavelli 	nic->iface_count = 0xFFFF;
3855a401801cSSathya Perla 	nic->link_param = 0xFF;
38560f77ba73SRavikumar Nelavelli 	nic->channel_id_param = cpu_to_le16(0xF000);
3857a401801cSSathya Perla 	nic->acpi_params = 0xFF;
3858a401801cSSathya Perla 	nic->wol_param = 0x0F;
38590f77ba73SRavikumar Nelavelli 	nic->tunnel_iface_count = 0xFFFF;
38600f77ba73SRavikumar Nelavelli 	nic->direct_tenant_iface_count = 0xFFFF;
3861bec84e6bSVasundhara Volam 	nic->bw_min = 0xFFFFFFFF;
3862a401801cSSathya Perla 	nic->bw_max = 0xFFFFFFFF;
3863a401801cSSathya Perla }
3864a401801cSSathya Perla 
3865bec84e6bSVasundhara Volam /* Mark all fields invalid */
3866bec84e6bSVasundhara Volam static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
3867bec84e6bSVasundhara Volam {
3868bec84e6bSVasundhara Volam 	memset(pcie, 0, sizeof(*pcie));
3869bec84e6bSVasundhara Volam 	pcie->sriov_state = 0xFF;
3870bec84e6bSVasundhara Volam 	pcie->pf_state = 0xFF;
3871bec84e6bSVasundhara Volam 	pcie->pf_type = 0xFF;
3872bec84e6bSVasundhara Volam 	pcie->num_vfs = 0xFFFF;
3873bec84e6bSVasundhara Volam }
3874bec84e6bSVasundhara Volam 
38750f77ba73SRavikumar Nelavelli int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
38760f77ba73SRavikumar Nelavelli 		      u8 domain)
3877a401801cSSathya Perla {
3878a401801cSSathya Perla 	struct be_nic_res_desc nic_desc;
38790f77ba73SRavikumar Nelavelli 	u32 bw_percent;
38800f77ba73SRavikumar Nelavelli 	u16 version = 0;
38810f77ba73SRavikumar Nelavelli 
38820f77ba73SRavikumar Nelavelli 	if (BE3_chip(adapter))
38830f77ba73SRavikumar Nelavelli 		return be_cmd_set_qos(adapter, max_rate / 10, domain);
3884a401801cSSathya Perla 
3885a401801cSSathya Perla 	be_reset_nic_desc(&nic_desc);
38860f77ba73SRavikumar Nelavelli 	nic_desc.pf_num = adapter->pf_number;
38870f77ba73SRavikumar Nelavelli 	nic_desc.vf_num = domain;
388858bdeaa6SKalesh AP 	nic_desc.bw_min = 0;
38890f77ba73SRavikumar Nelavelli 	if (lancer_chip(adapter)) {
3890a401801cSSathya Perla 		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
3891a401801cSSathya Perla 		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
3892a401801cSSathya Perla 		nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
3893a401801cSSathya Perla 					(1 << NOSV_SHIFT);
38940f77ba73SRavikumar Nelavelli 		nic_desc.bw_max = cpu_to_le32(max_rate / 10);
38950f77ba73SRavikumar Nelavelli 	} else {
38960f77ba73SRavikumar Nelavelli 		version = 1;
38970f77ba73SRavikumar Nelavelli 		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
38980f77ba73SRavikumar Nelavelli 		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
38990f77ba73SRavikumar Nelavelli 		nic_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
39000f77ba73SRavikumar Nelavelli 		bw_percent = max_rate ? (max_rate * 100) / link_speed : 100;
39010f77ba73SRavikumar Nelavelli 		nic_desc.bw_max = cpu_to_le32(bw_percent);
39020f77ba73SRavikumar Nelavelli 	}
3903a401801cSSathya Perla 
3904a401801cSSathya Perla 	return be_cmd_set_profile_config(adapter, &nic_desc,
39050f77ba73SRavikumar Nelavelli 					 nic_desc.hdr.desc_len,
3906bec84e6bSVasundhara Volam 					 1, version, domain);
3907bec84e6bSVasundhara Volam }
3908bec84e6bSVasundhara Volam 
3909f2858738SVasundhara Volam static void be_fill_vf_res_template(struct be_adapter *adapter,
3910f2858738SVasundhara Volam 				    struct be_resources pool_res,
3911f2858738SVasundhara Volam 				    u16 num_vfs, u16 num_vf_qs,
3912f2858738SVasundhara Volam 				    struct be_nic_res_desc *nic_vft)
3913f2858738SVasundhara Volam {
3914f2858738SVasundhara Volam 	u32 vf_if_cap_flags = pool_res.vf_if_cap_flags;
3915f2858738SVasundhara Volam 	struct be_resources res_mod = {0};
3916f2858738SVasundhara Volam 
3917f2858738SVasundhara Volam 	/* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd,
3918f2858738SVasundhara Volam 	 * which are modifiable using SET_PROFILE_CONFIG cmd.
3919f2858738SVasundhara Volam 	 */
3920f2858738SVasundhara Volam 	be_cmd_get_profile_config(adapter, &res_mod, RESOURCE_MODIFIABLE, 0);
3921f2858738SVasundhara Volam 
3922f2858738SVasundhara Volam 	/* If RSS IFACE capability flags are modifiable for a VF, set the
3923f2858738SVasundhara Volam 	 * capability flag as valid and set RSS and DEFQ_RSS IFACE flags if
3924f2858738SVasundhara Volam 	 * more than 1 RSSQ is available for a VF.
3925f2858738SVasundhara Volam 	 * Otherwise, provision only 1 queue pair for VF.
3926f2858738SVasundhara Volam 	 */
3927f2858738SVasundhara Volam 	if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
3928f2858738SVasundhara Volam 		nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
3929f2858738SVasundhara Volam 		if (num_vf_qs > 1) {
3930f2858738SVasundhara Volam 			vf_if_cap_flags |= BE_IF_FLAGS_RSS;
3931f2858738SVasundhara Volam 			if (pool_res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS)
3932f2858738SVasundhara Volam 				vf_if_cap_flags |= BE_IF_FLAGS_DEFQ_RSS;
3933f2858738SVasundhara Volam 		} else {
3934f2858738SVasundhara Volam 			vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
3935f2858738SVasundhara Volam 					     BE_IF_FLAGS_DEFQ_RSS);
3936f2858738SVasundhara Volam 		}
3937f2858738SVasundhara Volam 	} else {
3938f2858738SVasundhara Volam 		num_vf_qs = 1;
3939f2858738SVasundhara Volam 	}
3940f2858738SVasundhara Volam 
3941196e3735SKalesh AP 	if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS) {
3942196e3735SKalesh AP 		nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
3943196e3735SKalesh AP 		vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS;
3944196e3735SKalesh AP 	}
3945196e3735SKalesh AP 
3946196e3735SKalesh AP 	nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
3947f2858738SVasundhara Volam 	nic_vft->rq_count = cpu_to_le16(num_vf_qs);
3948f2858738SVasundhara Volam 	nic_vft->txq_count = cpu_to_le16(num_vf_qs);
3949f2858738SVasundhara Volam 	nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
3950f2858738SVasundhara Volam 	nic_vft->cq_count = cpu_to_le16(pool_res.max_cq_count /
3951f2858738SVasundhara Volam 					(num_vfs + 1));
3952f2858738SVasundhara Volam 
3953f2858738SVasundhara Volam 	/* Distribute unicast MACs, VLANs, IFACE count and MCCQ count equally
3954f2858738SVasundhara Volam 	 * among the PF and it's VFs, if the fields are changeable
3955f2858738SVasundhara Volam 	 */
3956f2858738SVasundhara Volam 	if (res_mod.max_uc_mac == FIELD_MODIFIABLE)
3957f2858738SVasundhara Volam 		nic_vft->unicast_mac_count = cpu_to_le16(pool_res.max_uc_mac /
3958f2858738SVasundhara Volam 							 (num_vfs + 1));
3959f2858738SVasundhara Volam 
3960f2858738SVasundhara Volam 	if (res_mod.max_vlans == FIELD_MODIFIABLE)
3961f2858738SVasundhara Volam 		nic_vft->vlan_count = cpu_to_le16(pool_res.max_vlans /
3962f2858738SVasundhara Volam 						  (num_vfs + 1));
3963f2858738SVasundhara Volam 
3964f2858738SVasundhara Volam 	if (res_mod.max_iface_count == FIELD_MODIFIABLE)
3965f2858738SVasundhara Volam 		nic_vft->iface_count = cpu_to_le16(pool_res.max_iface_count /
3966f2858738SVasundhara Volam 						   (num_vfs + 1));
3967f2858738SVasundhara Volam 
3968f2858738SVasundhara Volam 	if (res_mod.max_mcc_count == FIELD_MODIFIABLE)
3969f2858738SVasundhara Volam 		nic_vft->mcc_count = cpu_to_le16(pool_res.max_mcc_count /
3970f2858738SVasundhara Volam 						 (num_vfs + 1));
3971f2858738SVasundhara Volam }
3972f2858738SVasundhara Volam 
3973bec84e6bSVasundhara Volam int be_cmd_set_sriov_config(struct be_adapter *adapter,
3974f2858738SVasundhara Volam 			    struct be_resources pool_res, u16 num_vfs,
3975f2858738SVasundhara Volam 			    u16 num_vf_qs)
3976bec84e6bSVasundhara Volam {
3977bec84e6bSVasundhara Volam 	struct {
3978bec84e6bSVasundhara Volam 		struct be_pcie_res_desc pcie;
3979bec84e6bSVasundhara Volam 		struct be_nic_res_desc nic_vft;
3980bec84e6bSVasundhara Volam 	} __packed desc;
3981bec84e6bSVasundhara Volam 
3982bec84e6bSVasundhara Volam 	/* PF PCIE descriptor */
3983bec84e6bSVasundhara Volam 	be_reset_pcie_desc(&desc.pcie);
3984bec84e6bSVasundhara Volam 	desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
3985bec84e6bSVasundhara Volam 	desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3986f2858738SVasundhara Volam 	desc.pcie.flags = BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
3987bec84e6bSVasundhara Volam 	desc.pcie.pf_num = adapter->pdev->devfn;
3988bec84e6bSVasundhara Volam 	desc.pcie.sriov_state = num_vfs ? 1 : 0;
3989bec84e6bSVasundhara Volam 	desc.pcie.num_vfs = cpu_to_le16(num_vfs);
3990bec84e6bSVasundhara Volam 
3991bec84e6bSVasundhara Volam 	/* VF NIC Template descriptor */
3992bec84e6bSVasundhara Volam 	be_reset_nic_desc(&desc.nic_vft);
3993bec84e6bSVasundhara Volam 	desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
3994bec84e6bSVasundhara Volam 	desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3995f2858738SVasundhara Volam 	desc.nic_vft.flags = BIT(VFT_SHIFT) | BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
3996bec84e6bSVasundhara Volam 	desc.nic_vft.pf_num = adapter->pdev->devfn;
3997bec84e6bSVasundhara Volam 	desc.nic_vft.vf_num = 0;
3998bec84e6bSVasundhara Volam 
3999f2858738SVasundhara Volam 	be_fill_vf_res_template(adapter, pool_res, num_vfs, num_vf_qs,
4000f2858738SVasundhara Volam 				&desc.nic_vft);
4001bec84e6bSVasundhara Volam 
4002bec84e6bSVasundhara Volam 	return be_cmd_set_profile_config(adapter, &desc,
4003bec84e6bSVasundhara Volam 					 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
4004a401801cSSathya Perla }
4005a401801cSSathya Perla 
4006a401801cSSathya Perla int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
4007a401801cSSathya Perla {
4008a401801cSSathya Perla 	struct be_mcc_wrb *wrb;
4009a401801cSSathya Perla 	struct be_cmd_req_manage_iface_filters *req;
4010a401801cSSathya Perla 	int status;
4011a401801cSSathya Perla 
4012a401801cSSathya Perla 	if (iface == 0xFFFFFFFF)
4013a401801cSSathya Perla 		return -1;
4014a401801cSSathya Perla 
4015a401801cSSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
4016a401801cSSathya Perla 
4017a401801cSSathya Perla 	wrb = wrb_from_mccq(adapter);
4018a401801cSSathya Perla 	if (!wrb) {
4019a401801cSSathya Perla 		status = -EBUSY;
4020a401801cSSathya Perla 		goto err;
4021a401801cSSathya Perla 	}
4022a401801cSSathya Perla 	req = embedded_payload(wrb);
4023a401801cSSathya Perla 
4024a401801cSSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4025a401801cSSathya Perla 			       OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req),
4026a401801cSSathya Perla 			       wrb, NULL);
4027a401801cSSathya Perla 	req->op = op;
4028a401801cSSathya Perla 	req->target_iface_id = cpu_to_le32(iface);
4029a401801cSSathya Perla 
4030a401801cSSathya Perla 	status = be_mcc_notify_wait(adapter);
4031a401801cSSathya Perla err:
4032a401801cSSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
4033a401801cSSathya Perla 	return status;
4034a401801cSSathya Perla }
4035a401801cSSathya Perla 
4036a401801cSSathya Perla int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
4037a401801cSSathya Perla {
4038a401801cSSathya Perla 	struct be_port_res_desc port_desc;
4039a401801cSSathya Perla 
4040a401801cSSathya Perla 	memset(&port_desc, 0, sizeof(port_desc));
4041a401801cSSathya Perla 	port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1;
4042a401801cSSathya Perla 	port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
4043a401801cSSathya Perla 	port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
4044a401801cSSathya Perla 	port_desc.link_num = adapter->hba_port_num;
4045a401801cSSathya Perla 	if (port) {
4046a401801cSSathya Perla 		port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) |
4047a401801cSSathya Perla 					(1 << RCVID_SHIFT);
4048a401801cSSathya Perla 		port_desc.nv_port = swab16(port);
4049a401801cSSathya Perla 	} else {
4050a401801cSSathya Perla 		port_desc.nv_flags = NV_TYPE_DISABLED;
4051a401801cSSathya Perla 		port_desc.nv_port = 0;
4052a401801cSSathya Perla 	}
4053a401801cSSathya Perla 
4054a401801cSSathya Perla 	return be_cmd_set_profile_config(adapter, &port_desc,
4055bec84e6bSVasundhara Volam 					 RESOURCE_DESC_SIZE_V1, 1, 1, 0);
4056a401801cSSathya Perla }
4057a401801cSSathya Perla 
40584c876616SSathya Perla int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
40594c876616SSathya Perla 		     int vf_num)
40604c876616SSathya Perla {
40614c876616SSathya Perla 	struct be_mcc_wrb *wrb;
40624c876616SSathya Perla 	struct be_cmd_req_get_iface_list *req;
40634c876616SSathya Perla 	struct be_cmd_resp_get_iface_list *resp;
40644c876616SSathya Perla 	int status;
40654c876616SSathya Perla 
40664c876616SSathya Perla 	spin_lock_bh(&adapter->mcc_lock);
40674c876616SSathya Perla 
40684c876616SSathya Perla 	wrb = wrb_from_mccq(adapter);
40694c876616SSathya Perla 	if (!wrb) {
40704c876616SSathya Perla 		status = -EBUSY;
40714c876616SSathya Perla 		goto err;
40724c876616SSathya Perla 	}
40734c876616SSathya Perla 	req = embedded_payload(wrb);
40744c876616SSathya Perla 
40754c876616SSathya Perla 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
40764c876616SSathya Perla 			       OPCODE_COMMON_GET_IFACE_LIST, sizeof(*resp),
40774c876616SSathya Perla 			       wrb, NULL);
40784c876616SSathya Perla 	req->hdr.domain = vf_num + 1;
40794c876616SSathya Perla 
40804c876616SSathya Perla 	status = be_mcc_notify_wait(adapter);
40814c876616SSathya Perla 	if (!status) {
40824c876616SSathya Perla 		resp = (struct be_cmd_resp_get_iface_list *)req;
40834c876616SSathya Perla 		vf_cfg->if_handle = le32_to_cpu(resp->if_desc.if_id);
40844c876616SSathya Perla 	}
40854c876616SSathya Perla 
40864c876616SSathya Perla err:
40874c876616SSathya Perla 	spin_unlock_bh(&adapter->mcc_lock);
40884c876616SSathya Perla 	return status;
40894c876616SSathya Perla }
40904c876616SSathya Perla 
40915c510811SSomnath Kotur static int lancer_wait_idle(struct be_adapter *adapter)
40925c510811SSomnath Kotur {
40935c510811SSomnath Kotur #define SLIPORT_IDLE_TIMEOUT 30
40945c510811SSomnath Kotur 	u32 reg_val;
40955c510811SSomnath Kotur 	int status = 0, i;
40965c510811SSomnath Kotur 
40975c510811SSomnath Kotur 	for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
40985c510811SSomnath Kotur 		reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
40995c510811SSomnath Kotur 		if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
41005c510811SSomnath Kotur 			break;
41015c510811SSomnath Kotur 
41025c510811SSomnath Kotur 		ssleep(1);
41035c510811SSomnath Kotur 	}
41045c510811SSomnath Kotur 
41055c510811SSomnath Kotur 	if (i == SLIPORT_IDLE_TIMEOUT)
41065c510811SSomnath Kotur 		status = -1;
41075c510811SSomnath Kotur 
41085c510811SSomnath Kotur 	return status;
41095c510811SSomnath Kotur }
41105c510811SSomnath Kotur 
41115c510811SSomnath Kotur int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
41125c510811SSomnath Kotur {
41135c510811SSomnath Kotur 	int status = 0;
41145c510811SSomnath Kotur 
41155c510811SSomnath Kotur 	status = lancer_wait_idle(adapter);
41165c510811SSomnath Kotur 	if (status)
41175c510811SSomnath Kotur 		return status;
41185c510811SSomnath Kotur 
41195c510811SSomnath Kotur 	iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);
41205c510811SSomnath Kotur 
41215c510811SSomnath Kotur 	return status;
41225c510811SSomnath Kotur }
41235c510811SSomnath Kotur 
41245c510811SSomnath Kotur /* Routine to check whether dump image is present or not */
41255c510811SSomnath Kotur bool dump_present(struct be_adapter *adapter)
41265c510811SSomnath Kotur {
41275c510811SSomnath Kotur 	u32 sliport_status = 0;
41285c510811SSomnath Kotur 
41295c510811SSomnath Kotur 	sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
41305c510811SSomnath Kotur 	return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
41315c510811SSomnath Kotur }
41325c510811SSomnath Kotur 
41335c510811SSomnath Kotur int lancer_initiate_dump(struct be_adapter *adapter)
41345c510811SSomnath Kotur {
4135f0613380SKalesh AP 	struct device *dev = &adapter->pdev->dev;
41365c510811SSomnath Kotur 	int status;
41375c510811SSomnath Kotur 
4138f0613380SKalesh AP 	if (dump_present(adapter)) {
4139f0613380SKalesh AP 		dev_info(dev, "Previous dump not cleared, not forcing dump\n");
4140f0613380SKalesh AP 		return -EEXIST;
4141f0613380SKalesh AP 	}
4142f0613380SKalesh AP 
41435c510811SSomnath Kotur 	/* give firmware reset and diagnostic dump */
41445c510811SSomnath Kotur 	status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
41455c510811SSomnath Kotur 				     PHYSDEV_CONTROL_DD_MASK);
41465c510811SSomnath Kotur 	if (status < 0) {
4147f0613380SKalesh AP 		dev_err(dev, "FW reset failed\n");
41485c510811SSomnath Kotur 		return status;
41495c510811SSomnath Kotur 	}
41505c510811SSomnath Kotur 
41515c510811SSomnath Kotur 	status = lancer_wait_idle(adapter);
41525c510811SSomnath Kotur 	if (status)
41535c510811SSomnath Kotur 		return status;
41545c510811SSomnath Kotur 
41555c510811SSomnath Kotur 	if (!dump_present(adapter)) {
4156f0613380SKalesh AP 		dev_err(dev, "FW dump not generated\n");
4157f0613380SKalesh AP 		return -EIO;
41585c510811SSomnath Kotur 	}
41595c510811SSomnath Kotur 
41605c510811SSomnath Kotur 	return 0;
41615c510811SSomnath Kotur }
41625c510811SSomnath Kotur 
4163f0613380SKalesh AP int lancer_delete_dump(struct be_adapter *adapter)
4164f0613380SKalesh AP {
4165f0613380SKalesh AP 	int status;
4166f0613380SKalesh AP 
4167f0613380SKalesh AP 	status = lancer_cmd_delete_object(adapter, LANCER_FW_DUMP_FILE);
4168f0613380SKalesh AP 	return be_cmd_status(status);
4169f0613380SKalesh AP }
4170f0613380SKalesh AP 
4171dcf7ebbaSPadmanabh Ratnakar /* Uses sync mcc */
4172dcf7ebbaSPadmanabh Ratnakar int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
4173dcf7ebbaSPadmanabh Ratnakar {
4174dcf7ebbaSPadmanabh Ratnakar 	struct be_mcc_wrb *wrb;
4175dcf7ebbaSPadmanabh Ratnakar 	struct be_cmd_enable_disable_vf *req;
4176dcf7ebbaSPadmanabh Ratnakar 	int status;
4177dcf7ebbaSPadmanabh Ratnakar 
41780599863dSVasundhara Volam 	if (BEx_chip(adapter))
4179dcf7ebbaSPadmanabh Ratnakar 		return 0;
4180dcf7ebbaSPadmanabh Ratnakar 
4181dcf7ebbaSPadmanabh Ratnakar 	spin_lock_bh(&adapter->mcc_lock);
4182dcf7ebbaSPadmanabh Ratnakar 
4183dcf7ebbaSPadmanabh Ratnakar 	wrb = wrb_from_mccq(adapter);
4184dcf7ebbaSPadmanabh Ratnakar 	if (!wrb) {
4185dcf7ebbaSPadmanabh Ratnakar 		status = -EBUSY;
4186dcf7ebbaSPadmanabh Ratnakar 		goto err;
4187dcf7ebbaSPadmanabh Ratnakar 	}
4188dcf7ebbaSPadmanabh Ratnakar 
4189dcf7ebbaSPadmanabh Ratnakar 	req = embedded_payload(wrb);
4190dcf7ebbaSPadmanabh Ratnakar 
4191dcf7ebbaSPadmanabh Ratnakar 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4192dcf7ebbaSPadmanabh Ratnakar 			       OPCODE_COMMON_ENABLE_DISABLE_VF, sizeof(*req),
4193dcf7ebbaSPadmanabh Ratnakar 			       wrb, NULL);
4194dcf7ebbaSPadmanabh Ratnakar 
4195dcf7ebbaSPadmanabh Ratnakar 	req->hdr.domain = domain;
4196dcf7ebbaSPadmanabh Ratnakar 	req->enable = 1;
4197dcf7ebbaSPadmanabh Ratnakar 	status = be_mcc_notify_wait(adapter);
4198dcf7ebbaSPadmanabh Ratnakar err:
4199dcf7ebbaSPadmanabh Ratnakar 	spin_unlock_bh(&adapter->mcc_lock);
4200dcf7ebbaSPadmanabh Ratnakar 	return status;
4201dcf7ebbaSPadmanabh Ratnakar }
4202dcf7ebbaSPadmanabh Ratnakar 
420368c45a2dSSomnath Kotur int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
420468c45a2dSSomnath Kotur {
420568c45a2dSSomnath Kotur 	struct be_mcc_wrb *wrb;
420668c45a2dSSomnath Kotur 	struct be_cmd_req_intr_set *req;
420768c45a2dSSomnath Kotur 	int status;
420868c45a2dSSomnath Kotur 
420968c45a2dSSomnath Kotur 	if (mutex_lock_interruptible(&adapter->mbox_lock))
421068c45a2dSSomnath Kotur 		return -1;
421168c45a2dSSomnath Kotur 
421268c45a2dSSomnath Kotur 	wrb = wrb_from_mbox(adapter);
421368c45a2dSSomnath Kotur 
421468c45a2dSSomnath Kotur 	req = embedded_payload(wrb);
421568c45a2dSSomnath Kotur 
421668c45a2dSSomnath Kotur 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
421768c45a2dSSomnath Kotur 			       OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req),
421868c45a2dSSomnath Kotur 			       wrb, NULL);
421968c45a2dSSomnath Kotur 
422068c45a2dSSomnath Kotur 	req->intr_enabled = intr_enable;
422168c45a2dSSomnath Kotur 
422268c45a2dSSomnath Kotur 	status = be_mbox_notify_wait(adapter);
422368c45a2dSSomnath Kotur 
422468c45a2dSSomnath Kotur 	mutex_unlock(&adapter->mbox_lock);
422568c45a2dSSomnath Kotur 	return status;
422668c45a2dSSomnath Kotur }
422768c45a2dSSomnath Kotur 
4228542963b7SVasundhara Volam /* Uses MBOX */
4229542963b7SVasundhara Volam int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile_id)
4230542963b7SVasundhara Volam {
4231542963b7SVasundhara Volam 	struct be_cmd_req_get_active_profile *req;
4232542963b7SVasundhara Volam 	struct be_mcc_wrb *wrb;
4233542963b7SVasundhara Volam 	int status;
4234542963b7SVasundhara Volam 
4235542963b7SVasundhara Volam 	if (mutex_lock_interruptible(&adapter->mbox_lock))
4236542963b7SVasundhara Volam 		return -1;
4237542963b7SVasundhara Volam 
4238542963b7SVasundhara Volam 	wrb = wrb_from_mbox(adapter);
4239542963b7SVasundhara Volam 	if (!wrb) {
4240542963b7SVasundhara Volam 		status = -EBUSY;
4241542963b7SVasundhara Volam 		goto err;
4242542963b7SVasundhara Volam 	}
4243542963b7SVasundhara Volam 
4244542963b7SVasundhara Volam 	req = embedded_payload(wrb);
4245542963b7SVasundhara Volam 
4246542963b7SVasundhara Volam 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4247542963b7SVasundhara Volam 			       OPCODE_COMMON_GET_ACTIVE_PROFILE, sizeof(*req),
4248542963b7SVasundhara Volam 			       wrb, NULL);
4249542963b7SVasundhara Volam 
4250542963b7SVasundhara Volam 	status = be_mbox_notify_wait(adapter);
4251542963b7SVasundhara Volam 	if (!status) {
4252542963b7SVasundhara Volam 		struct be_cmd_resp_get_active_profile *resp =
4253542963b7SVasundhara Volam 							embedded_payload(wrb);
425403d28ffeSKalesh AP 
4255542963b7SVasundhara Volam 		*profile_id = le16_to_cpu(resp->active_profile_id);
4256542963b7SVasundhara Volam 	}
4257542963b7SVasundhara Volam 
4258542963b7SVasundhara Volam err:
4259542963b7SVasundhara Volam 	mutex_unlock(&adapter->mbox_lock);
4260542963b7SVasundhara Volam 	return status;
4261542963b7SVasundhara Volam }
4262542963b7SVasundhara Volam 
4263d9d426afSSuresh Reddy int __be_cmd_set_logical_link_config(struct be_adapter *adapter,
4264d9d426afSSuresh Reddy 				     int link_state, int version, u8 domain)
4265bdce2ad7SSuresh Reddy {
4266bdce2ad7SSuresh Reddy 	struct be_mcc_wrb *wrb;
4267bdce2ad7SSuresh Reddy 	struct be_cmd_req_set_ll_link *req;
4268bdce2ad7SSuresh Reddy 	int status;
4269bdce2ad7SSuresh Reddy 
4270bdce2ad7SSuresh Reddy 	spin_lock_bh(&adapter->mcc_lock);
4271bdce2ad7SSuresh Reddy 
4272bdce2ad7SSuresh Reddy 	wrb = wrb_from_mccq(adapter);
4273bdce2ad7SSuresh Reddy 	if (!wrb) {
4274bdce2ad7SSuresh Reddy 		status = -EBUSY;
4275bdce2ad7SSuresh Reddy 		goto err;
4276bdce2ad7SSuresh Reddy 	}
4277bdce2ad7SSuresh Reddy 
4278bdce2ad7SSuresh Reddy 	req = embedded_payload(wrb);
4279bdce2ad7SSuresh Reddy 
4280bdce2ad7SSuresh Reddy 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4281bdce2ad7SSuresh Reddy 			       OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG,
4282bdce2ad7SSuresh Reddy 			       sizeof(*req), wrb, NULL);
4283bdce2ad7SSuresh Reddy 
4284d9d426afSSuresh Reddy 	req->hdr.version = version;
4285bdce2ad7SSuresh Reddy 	req->hdr.domain = domain;
4286bdce2ad7SSuresh Reddy 
4287d9d426afSSuresh Reddy 	if (link_state == IFLA_VF_LINK_STATE_ENABLE ||
4288d9d426afSSuresh Reddy 	    link_state == IFLA_VF_LINK_STATE_AUTO)
4289d9d426afSSuresh Reddy 		req->link_config |= PLINK_ENABLE;
4290bdce2ad7SSuresh Reddy 
4291bdce2ad7SSuresh Reddy 	if (link_state == IFLA_VF_LINK_STATE_AUTO)
4292d9d426afSSuresh Reddy 		req->link_config |= PLINK_TRACK;
4293bdce2ad7SSuresh Reddy 
4294bdce2ad7SSuresh Reddy 	status = be_mcc_notify_wait(adapter);
4295bdce2ad7SSuresh Reddy err:
4296bdce2ad7SSuresh Reddy 	spin_unlock_bh(&adapter->mcc_lock);
4297bdce2ad7SSuresh Reddy 	return status;
4298bdce2ad7SSuresh Reddy }
4299bdce2ad7SSuresh Reddy 
4300d9d426afSSuresh Reddy int be_cmd_set_logical_link_config(struct be_adapter *adapter,
4301d9d426afSSuresh Reddy 				   int link_state, u8 domain)
4302d9d426afSSuresh Reddy {
4303d9d426afSSuresh Reddy 	int status;
4304d9d426afSSuresh Reddy 
4305d9d426afSSuresh Reddy 	if (BEx_chip(adapter))
4306d9d426afSSuresh Reddy 		return -EOPNOTSUPP;
4307d9d426afSSuresh Reddy 
4308d9d426afSSuresh Reddy 	status = __be_cmd_set_logical_link_config(adapter, link_state,
4309d9d426afSSuresh Reddy 						  2, domain);
4310d9d426afSSuresh Reddy 
4311d9d426afSSuresh Reddy 	/* Version 2 of the command will not be recognized by older FW.
4312d9d426afSSuresh Reddy 	 * On such a failure issue version 1 of the command.
4313d9d426afSSuresh Reddy 	 */
4314d9d426afSSuresh Reddy 	if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST)
4315d9d426afSSuresh Reddy 		status = __be_cmd_set_logical_link_config(adapter, link_state,
4316d9d426afSSuresh Reddy 							  1, domain);
4317d9d426afSSuresh Reddy 	return status;
4318d9d426afSSuresh Reddy }
43196a4ab669SParav Pandit int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
43206a4ab669SParav Pandit 		    int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
43216a4ab669SParav Pandit {
43226a4ab669SParav Pandit 	struct be_adapter *adapter = netdev_priv(netdev_handle);
43236a4ab669SParav Pandit 	struct be_mcc_wrb *wrb;
43246a4ab669SParav Pandit 	struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *)wrb_payload;
43256a4ab669SParav Pandit 	struct be_cmd_req_hdr *req;
43266a4ab669SParav Pandit 	struct be_cmd_resp_hdr *resp;
43276a4ab669SParav Pandit 	int status;
43286a4ab669SParav Pandit 
43296a4ab669SParav Pandit 	spin_lock_bh(&adapter->mcc_lock);
43306a4ab669SParav Pandit 
43316a4ab669SParav Pandit 	wrb = wrb_from_mccq(adapter);
43326a4ab669SParav Pandit 	if (!wrb) {
43336a4ab669SParav Pandit 		status = -EBUSY;
43346a4ab669SParav Pandit 		goto err;
43356a4ab669SParav Pandit 	}
43366a4ab669SParav Pandit 	req = embedded_payload(wrb);
43376a4ab669SParav Pandit 	resp = embedded_payload(wrb);
43386a4ab669SParav Pandit 
43396a4ab669SParav Pandit 	be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
43406a4ab669SParav Pandit 			       hdr->opcode, wrb_payload_size, wrb, NULL);
43416a4ab669SParav Pandit 	memcpy(req, wrb_payload, wrb_payload_size);
43426a4ab669SParav Pandit 	be_dws_cpu_to_le(req, wrb_payload_size);
43436a4ab669SParav Pandit 
43446a4ab669SParav Pandit 	status = be_mcc_notify_wait(adapter);
43456a4ab669SParav Pandit 	if (cmd_status)
43466a4ab669SParav Pandit 		*cmd_status = (status & 0xffff);
43476a4ab669SParav Pandit 	if (ext_status)
43486a4ab669SParav Pandit 		*ext_status = 0;
43496a4ab669SParav Pandit 	memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
43506a4ab669SParav Pandit 	be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
43516a4ab669SParav Pandit err:
43526a4ab669SParav Pandit 	spin_unlock_bh(&adapter->mcc_lock);
43536a4ab669SParav Pandit 	return status;
43546a4ab669SParav Pandit }
43556a4ab669SParav Pandit EXPORT_SYMBOL(be_roce_mcc_cmd);
4356