Merge remote-tracking branch 'omap_dss2/for-next'
[deliverable/linux.git] / drivers / net / ethernet / emulex / benet / be_cmds.c
CommitLineData
6b7c5b94 1/*
7dfbe7d7 2 * Copyright (C) 2005 - 2016 Broadcom
6b7c5b94
SP
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
d2145cde 11 * linux-drivers@emulex.com
6b7c5b94 12 *
d2145cde
AK
13 * Emulex
14 * 3333 Susan Street
15 * Costa Mesa, CA 92626
6b7c5b94
SP
16 */
17
6a4ab669 18#include <linux/module.h>
6b7c5b94 19#include "be.h"
8788fdc2 20#include "be_cmds.h"
6b7c5b94 21
51d1f98a
AK
22char *be_misconfig_evt_port_state[] = {
23 "Physical Link is functional",
24 "Optics faulted/incorrectly installed/not installed - Reseat optics. If issue not resolved, replace.",
25 "Optics of two types installed – Remove one optic or install matching pair of optics.",
26 "Incompatible optics – Replace with compatible optics for card to function.",
27 "Unqualified optics – Replace with Avago optics for Warranty and Technical Support.",
28 "Uncertified optics – Replace with Avago-certified optics to enable link operation."
21252377
VV
29};
30
51d1f98a
AK
31static char *be_port_misconfig_evt_severity[] = {
32 "KERN_WARN",
33 "KERN_INFO",
34 "KERN_ERR",
35 "KERN_WARN"
36};
37
38static char *phy_state_oper_desc[] = {
39 "Link is non-operational",
40 "Link is operational",
21252377
VV
41 ""
42};
43
f25b119c
PR
44static struct be_cmd_priv_map cmd_priv_map[] = {
45 {
46 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
47 CMD_SUBSYSTEM_ETH,
48 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
49 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
50 },
51 {
52 OPCODE_COMMON_GET_FLOW_CONTROL,
53 CMD_SUBSYSTEM_COMMON,
54 BE_PRIV_LNKQUERY | BE_PRIV_VHADM |
55 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
56 },
57 {
58 OPCODE_COMMON_SET_FLOW_CONTROL,
59 CMD_SUBSYSTEM_COMMON,
60 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
61 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
62 },
63 {
64 OPCODE_ETH_GET_PPORT_STATS,
65 CMD_SUBSYSTEM_ETH,
66 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
67 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
68 },
69 {
70 OPCODE_COMMON_GET_PHY_DETAILS,
71 CMD_SUBSYSTEM_COMMON,
72 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
73 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
2e365b1b
SK
74 },
75 {
76 OPCODE_LOWLEVEL_HOST_DDR_DMA,
77 CMD_SUBSYSTEM_LOWLEVEL,
78 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
79 },
80 {
81 OPCODE_LOWLEVEL_LOOPBACK_TEST,
82 CMD_SUBSYSTEM_LOWLEVEL,
83 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
84 },
85 {
86 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
87 CMD_SUBSYSTEM_LOWLEVEL,
88 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
89 },
884476be
SK
90 {
91 OPCODE_COMMON_SET_HSW_CONFIG,
92 CMD_SUBSYSTEM_COMMON,
93 BE_PRIV_DEVCFG | BE_PRIV_VHADM
94 },
62259ac4
SK
95 {
96 OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
97 CMD_SUBSYSTEM_COMMON,
98 BE_PRIV_DEVCFG
99 }
f25b119c
PR
100};
101
a2cc4e0b 102static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
f25b119c
PR
103{
104 int i;
105 int num_entries = sizeof(cmd_priv_map)/sizeof(struct be_cmd_priv_map);
106 u32 cmd_privileges = adapter->cmd_privileges;
107
108 for (i = 0; i < num_entries; i++)
109 if (opcode == cmd_priv_map[i].opcode &&
110 subsystem == cmd_priv_map[i].subsystem)
111 if (!(cmd_privileges & cmd_priv_map[i].priv_mask))
112 return false;
113
114 return true;
115}
116
3de09455
SK
117static inline void *embedded_payload(struct be_mcc_wrb *wrb)
118{
119 return wrb->payload.embedded_payload;
120}
609ff3bb 121
efaa408e 122static int be_mcc_notify(struct be_adapter *adapter)
5fb379ee 123{
8788fdc2 124 struct be_queue_info *mccq = &adapter->mcc_obj.q;
5fb379ee
SP
125 u32 val = 0;
126
954f6825 127 if (be_check_error(adapter, BE_ERROR_ANY))
efaa408e 128 return -EIO;
7acc2087 129
5fb379ee
SP
130 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
131 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
f3eb62d2
SP
132
133 wmb();
8788fdc2 134 iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
efaa408e
SR
135
136 return 0;
5fb379ee
SP
137}
138
139/* To check if valid bit is set, check the entire word as we don't know
140 * the endianness of the data (old entry is host endian while a new entry is
141 * little endian) */
efd2e40a 142static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
5fb379ee 143{
9e9ff4b7
SP
144 u32 flags;
145
5fb379ee 146 if (compl->flags != 0) {
9e9ff4b7
SP
147 flags = le32_to_cpu(compl->flags);
148 if (flags & CQE_FLAGS_VALID_MASK) {
149 compl->flags = flags;
150 return true;
151 }
5fb379ee 152 }
9e9ff4b7 153 return false;
5fb379ee
SP
154}
155
156/* Need to reset the entire word that houses the valid bit */
efd2e40a 157static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
5fb379ee
SP
158{
159 compl->flags = 0;
160}
161
652bf646
PR
162static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
163{
164 unsigned long addr;
165
166 addr = tag1;
167 addr = ((addr << 16) << 16) | tag0;
168 return (void *)addr;
169}
170
4c60005f
KA
171static bool be_skip_err_log(u8 opcode, u16 base_status, u16 addl_status)
172{
173 if (base_status == MCC_STATUS_NOT_SUPPORTED ||
174 base_status == MCC_STATUS_ILLEGAL_REQUEST ||
175 addl_status == MCC_ADDL_STATUS_TOO_MANY_INTERFACES ||
77be8c1c 176 addl_status == MCC_ADDL_STATUS_INSUFFICIENT_VLANS ||
4c60005f
KA
177 (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
178 (base_status == MCC_STATUS_ILLEGAL_FIELD ||
179 addl_status == MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH)))
180 return true;
181 else
182 return false;
183}
184
559b633f
SP
185/* Place holder for all the async MCC cmds wherein the caller is not in a busy
186 * loop (has not issued be_mcc_notify_wait())
187 */
188static void be_async_cmd_process(struct be_adapter *adapter,
189 struct be_mcc_compl *compl,
190 struct be_cmd_resp_hdr *resp_hdr)
191{
192 enum mcc_base_status base_status = base_status(compl->status);
193 u8 opcode = 0, subsystem = 0;
194
195 if (resp_hdr) {
196 opcode = resp_hdr->opcode;
197 subsystem = resp_hdr->subsystem;
198 }
199
200 if (opcode == OPCODE_LOWLEVEL_LOOPBACK_TEST &&
201 subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
202 complete(&adapter->et_cmd_compl);
203 return;
204 }
205
9c855975
SR
206 if (opcode == OPCODE_LOWLEVEL_SET_LOOPBACK_MODE &&
207 subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
208 complete(&adapter->et_cmd_compl);
209 return;
210 }
211
559b633f
SP
212 if ((opcode == OPCODE_COMMON_WRITE_FLASHROM ||
213 opcode == OPCODE_COMMON_WRITE_OBJECT) &&
214 subsystem == CMD_SUBSYSTEM_COMMON) {
215 adapter->flash_status = compl->status;
216 complete(&adapter->et_cmd_compl);
217 return;
218 }
219
220 if ((opcode == OPCODE_ETH_GET_STATISTICS ||
221 opcode == OPCODE_ETH_GET_PPORT_STATS) &&
222 subsystem == CMD_SUBSYSTEM_ETH &&
223 base_status == MCC_STATUS_SUCCESS) {
224 be_parse_stats(adapter);
225 adapter->stats_cmd_sent = false;
226 return;
227 }
228
229 if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
230 subsystem == CMD_SUBSYSTEM_COMMON) {
231 if (base_status == MCC_STATUS_SUCCESS) {
232 struct be_cmd_resp_get_cntl_addnl_attribs *resp =
233 (void *)resp_hdr;
29e9122b 234 adapter->hwmon_info.be_on_die_temp =
559b633f
SP
235 resp->on_die_temperature;
236 } else {
237 adapter->be_get_temp_freq = 0;
29e9122b
VD
238 adapter->hwmon_info.be_on_die_temp =
239 BE_INVALID_DIE_TEMP;
559b633f
SP
240 }
241 return;
242 }
243}
244
8788fdc2 245static int be_mcc_compl_process(struct be_adapter *adapter,
652bf646 246 struct be_mcc_compl *compl)
5fb379ee 247{
4c60005f
KA
248 enum mcc_base_status base_status;
249 enum mcc_addl_status addl_status;
652bf646
PR
250 struct be_cmd_resp_hdr *resp_hdr;
251 u8 opcode = 0, subsystem = 0;
5fb379ee
SP
252
253 /* Just swap the status to host endian; mcc tag is opaquely copied
254 * from mcc_wrb */
255 be_dws_le_to_cpu(compl, 4);
256
4c60005f
KA
257 base_status = base_status(compl->status);
258 addl_status = addl_status(compl->status);
96c9b2e4 259
652bf646 260 resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
652bf646
PR
261 if (resp_hdr) {
262 opcode = resp_hdr->opcode;
263 subsystem = resp_hdr->subsystem;
264 }
265
559b633f 266 be_async_cmd_process(adapter, compl, resp_hdr);
3de09455 267
559b633f
SP
268 if (base_status != MCC_STATUS_SUCCESS &&
269 !be_skip_err_log(opcode, base_status, addl_status)) {
fa5c867d
SR
270 if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST ||
271 addl_status == MCC_ADDL_STATUS_INSUFFICIENT_PRIVILEGES) {
97f1d8cd 272 dev_warn(&adapter->pdev->dev,
522609f2 273 "VF is not privileged to issue opcode %d-%d\n",
97f1d8cd 274 opcode, subsystem);
2b3f291b 275 } else {
97f1d8cd
VV
276 dev_err(&adapter->pdev->dev,
277 "opcode %d-%d failed:status %d-%d\n",
4c60005f 278 opcode, subsystem, base_status, addl_status);
2b3f291b 279 }
5fb379ee 280 }
4c60005f 281 return compl->status;
5fb379ee
SP
282}
283
a8f447bd 284/* Link state evt is a string of bytes; no need for endian swapping */
8788fdc2 285static void be_async_link_state_process(struct be_adapter *adapter,
3acf19d9 286 struct be_mcc_compl *compl)
a8f447bd 287{
3acf19d9
SP
288 struct be_async_event_link_state *evt =
289 (struct be_async_event_link_state *)compl;
290
b236916a 291 /* When link status changes, link speed must be re-queried from FW */
42f11cf2 292 adapter->phy.link_speed = -1;
b236916a 293
bdce2ad7
SR
294 /* On BEx the FW does not send a separate link status
295 * notification for physical and logical link.
296 * On other chips just process the logical link
297 * status notification
298 */
299 if (!BEx_chip(adapter) &&
2e177a5c
PR
300 !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK))
301 return;
302
b236916a
AK
303 /* For the initial link status do not rely on the ASYNC event as
304 * it may not be received in some cases.
305 */
306 if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
bdce2ad7
SR
307 be_link_status_update(adapter,
308 evt->port_link_status & LINK_STATUS_MASK);
a8f447bd
SP
309}
310
21252377
VV
311static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
312 struct be_mcc_compl *compl)
313{
314 struct be_async_event_misconfig_port *evt =
315 (struct be_async_event_misconfig_port *)compl;
51d1f98a
AK
316 u32 sfp_misconfig_evt_word1 = le32_to_cpu(evt->event_data_word1);
317 u32 sfp_misconfig_evt_word2 = le32_to_cpu(evt->event_data_word2);
318 u8 phy_oper_state = PHY_STATE_OPER_MSG_NONE;
21252377 319 struct device *dev = &adapter->pdev->dev;
51d1f98a
AK
320 u8 msg_severity = DEFAULT_MSG_SEVERITY;
321 u8 phy_state_info;
322 u8 new_phy_state;
323
324 new_phy_state =
325 (sfp_misconfig_evt_word1 >> (adapter->hba_port_num * 8)) & 0xff;
326
327 if (new_phy_state == adapter->phy_state)
328 return;
329
330 adapter->phy_state = new_phy_state;
21252377 331
51d1f98a
AK
332 /* for older fw that doesn't populate link effect data */
333 if (!sfp_misconfig_evt_word2)
334 goto log_message;
21252377 335
51d1f98a
AK
336 phy_state_info =
337 (sfp_misconfig_evt_word2 >> (adapter->hba_port_num * 8)) & 0xff;
338
339 if (phy_state_info & PHY_STATE_INFO_VALID) {
340 msg_severity = (phy_state_info & PHY_STATE_MSG_SEVERITY) >> 1;
341
342 if (be_phy_unqualified(new_phy_state))
343 phy_oper_state = (phy_state_info & PHY_STATE_OPER);
344 }
345
346log_message:
21252377
VV
347 /* Log an error message that would allow a user to determine
348 * whether the SFPs have an issue
349 */
51d1f98a
AK
350 if (be_phy_state_unknown(new_phy_state))
351 dev_printk(be_port_misconfig_evt_severity[msg_severity], dev,
352 "Port %c: Unrecognized Optics state: 0x%x. %s",
353 adapter->port_name,
354 new_phy_state,
355 phy_state_oper_desc[phy_oper_state]);
356 else
357 dev_printk(be_port_misconfig_evt_severity[msg_severity], dev,
358 "Port %c: %s %s",
359 adapter->port_name,
360 be_misconfig_evt_port_state[new_phy_state],
361 phy_state_oper_desc[phy_oper_state]);
362
363 /* Log Vendor name and part no. if a misconfigured SFP is detected */
364 if (be_phy_misconfigured(new_phy_state))
365 adapter->flags |= BE_FLAGS_PHY_MISCONFIGURED;
21252377
VV
366}
367
cc4ce020
SK
368/* Grp5 CoS Priority evt */
369static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
3acf19d9 370 struct be_mcc_compl *compl)
cc4ce020 371{
3acf19d9
SP
372 struct be_async_event_grp5_cos_priority *evt =
373 (struct be_async_event_grp5_cos_priority *)compl;
374
cc4ce020
SK
375 if (evt->valid) {
376 adapter->vlan_prio_bmap = evt->available_priority_bmap;
fdf81bfb 377 adapter->recommended_prio_bits =
cc4ce020
SK
378 evt->reco_default_priority << VLAN_PRIO_SHIFT;
379 }
380}
381
323ff71e 382/* Grp5 QOS Speed evt: qos_link_speed is in units of 10 Mbps */
cc4ce020 383static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
3acf19d9 384 struct be_mcc_compl *compl)
cc4ce020 385{
3acf19d9
SP
386 struct be_async_event_grp5_qos_link_speed *evt =
387 (struct be_async_event_grp5_qos_link_speed *)compl;
388
323ff71e
SP
389 if (adapter->phy.link_speed >= 0 &&
390 evt->physical_port == adapter->port_num)
391 adapter->phy.link_speed = le16_to_cpu(evt->qos_link_speed) * 10;
cc4ce020
SK
392}
393
3968fa1e
AK
394/*Grp5 PVID evt*/
395static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
3acf19d9 396 struct be_mcc_compl *compl)
3968fa1e 397{
3acf19d9
SP
398 struct be_async_event_grp5_pvid_state *evt =
399 (struct be_async_event_grp5_pvid_state *)compl;
400
bdac85b5 401 if (evt->enabled) {
939cf306 402 adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK;
bdac85b5
RN
403 dev_info(&adapter->pdev->dev, "LPVID: %d\n", adapter->pvid);
404 } else {
3968fa1e 405 adapter->pvid = 0;
bdac85b5 406 }
3968fa1e
AK
407}
408
760c295e
VD
409#define MGMT_ENABLE_MASK 0x4
410static void be_async_grp5_fw_control_process(struct be_adapter *adapter,
411 struct be_mcc_compl *compl)
412{
413 struct be_async_fw_control *evt = (struct be_async_fw_control *)compl;
414 u32 evt_dw1 = le32_to_cpu(evt->event_data_word1);
415
416 if (evt_dw1 & MGMT_ENABLE_MASK) {
417 adapter->flags |= BE_FLAGS_OS2BMC;
418 adapter->bmc_filt_mask = le32_to_cpu(evt->event_data_word2);
419 } else {
420 adapter->flags &= ~BE_FLAGS_OS2BMC;
421 }
422}
423
cc4ce020 424static void be_async_grp5_evt_process(struct be_adapter *adapter,
3acf19d9 425 struct be_mcc_compl *compl)
cc4ce020 426{
3acf19d9
SP
427 u8 event_type = (compl->flags >> ASYNC_EVENT_TYPE_SHIFT) &
428 ASYNC_EVENT_TYPE_MASK;
cc4ce020
SK
429
430 switch (event_type) {
431 case ASYNC_EVENT_COS_PRIORITY:
3acf19d9
SP
432 be_async_grp5_cos_priority_process(adapter, compl);
433 break;
cc4ce020 434 case ASYNC_EVENT_QOS_SPEED:
3acf19d9
SP
435 be_async_grp5_qos_speed_process(adapter, compl);
436 break;
3968fa1e 437 case ASYNC_EVENT_PVID_STATE:
3acf19d9
SP
438 be_async_grp5_pvid_state_process(adapter, compl);
439 break;
760c295e
VD
440 /* Async event to disable/enable os2bmc and/or mac-learning */
441 case ASYNC_EVENT_FW_CONTROL:
442 be_async_grp5_fw_control_process(adapter, compl);
443 break;
cc4ce020 444 default:
cc4ce020
SK
445 break;
446 }
447}
448
bc0c3405 449static void be_async_dbg_evt_process(struct be_adapter *adapter,
3acf19d9 450 struct be_mcc_compl *cmp)
bc0c3405
AK
451{
452 u8 event_type = 0;
504fbf1e 453 struct be_async_event_qnq *evt = (struct be_async_event_qnq *)cmp;
bc0c3405 454
3acf19d9
SP
455 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
456 ASYNC_EVENT_TYPE_MASK;
bc0c3405
AK
457
458 switch (event_type) {
459 case ASYNC_DEBUG_EVENT_TYPE_QNQ:
460 if (evt->valid)
461 adapter->qnq_vid = le16_to_cpu(evt->vlan_tag);
462 adapter->flags |= BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
463 break;
464 default:
05ccaa2b
VV
465 dev_warn(&adapter->pdev->dev, "Unknown debug event 0x%x!\n",
466 event_type);
bc0c3405
AK
467 break;
468 }
469}
470
21252377
VV
471static void be_async_sliport_evt_process(struct be_adapter *adapter,
472 struct be_mcc_compl *cmp)
473{
474 u8 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
475 ASYNC_EVENT_TYPE_MASK;
476
477 if (event_type == ASYNC_EVENT_PORT_MISCONFIG)
478 be_async_port_misconfig_event_process(adapter, cmp);
479}
480
3acf19d9 481static inline bool is_link_state_evt(u32 flags)
a8f447bd 482{
3acf19d9
SP
483 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
484 ASYNC_EVENT_CODE_LINK_STATE;
a8f447bd 485}
5fb379ee 486
3acf19d9 487static inline bool is_grp5_evt(u32 flags)
cc4ce020 488{
3acf19d9
SP
489 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
490 ASYNC_EVENT_CODE_GRP_5;
cc4ce020
SK
491}
492
3acf19d9 493static inline bool is_dbg_evt(u32 flags)
bc0c3405 494{
3acf19d9
SP
495 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
496 ASYNC_EVENT_CODE_QNQ;
497}
498
21252377
VV
499static inline bool is_sliport_evt(u32 flags)
500{
501 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
502 ASYNC_EVENT_CODE_SLIPORT;
503}
504
3acf19d9
SP
505static void be_mcc_event_process(struct be_adapter *adapter,
506 struct be_mcc_compl *compl)
507{
508 if (is_link_state_evt(compl->flags))
509 be_async_link_state_process(adapter, compl);
510 else if (is_grp5_evt(compl->flags))
511 be_async_grp5_evt_process(adapter, compl);
512 else if (is_dbg_evt(compl->flags))
513 be_async_dbg_evt_process(adapter, compl);
21252377
VV
514 else if (is_sliport_evt(compl->flags))
515 be_async_sliport_evt_process(adapter, compl);
bc0c3405
AK
516}
517
efd2e40a 518static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
5fb379ee 519{
8788fdc2 520 struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
efd2e40a 521 struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
5fb379ee
SP
522
523 if (be_mcc_compl_is_new(compl)) {
524 queue_tail_inc(mcc_cq);
525 return compl;
526 }
527 return NULL;
528}
529
7a1e9b20
SP
530void be_async_mcc_enable(struct be_adapter *adapter)
531{
532 spin_lock_bh(&adapter->mcc_cq_lock);
533
534 be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
535 adapter->mcc_obj.rearm_cq = true;
536
537 spin_unlock_bh(&adapter->mcc_cq_lock);
538}
539
540void be_async_mcc_disable(struct be_adapter *adapter)
541{
a323d9bf
SP
542 spin_lock_bh(&adapter->mcc_cq_lock);
543
7a1e9b20 544 adapter->mcc_obj.rearm_cq = false;
a323d9bf
SP
545 be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
546
547 spin_unlock_bh(&adapter->mcc_cq_lock);
7a1e9b20
SP
548}
549
10ef9ab4 550int be_process_mcc(struct be_adapter *adapter)
5fb379ee 551{
efd2e40a 552 struct be_mcc_compl *compl;
10ef9ab4 553 int num = 0, status = 0;
7a1e9b20 554 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
5fb379ee 555
072a9c48 556 spin_lock(&adapter->mcc_cq_lock);
3acf19d9 557
8788fdc2 558 while ((compl = be_mcc_compl_get(adapter))) {
a8f447bd 559 if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
3acf19d9 560 be_mcc_event_process(adapter, compl);
b31c50a7 561 } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
3acf19d9
SP
562 status = be_mcc_compl_process(adapter, compl);
563 atomic_dec(&mcc_obj->q.used);
5fb379ee
SP
564 }
565 be_mcc_compl_use(compl);
566 num++;
567 }
b31c50a7 568
10ef9ab4
SP
569 if (num)
570 be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
571
072a9c48 572 spin_unlock(&adapter->mcc_cq_lock);
10ef9ab4 573 return status;
5fb379ee
SP
574}
575
6ac7b687 576/* Wait till no more pending mcc requests are present */
b31c50a7 577static int be_mcc_wait_compl(struct be_adapter *adapter)
6ac7b687 578{
b7172414 579#define mcc_timeout 12000 /* 12s timeout */
10ef9ab4 580 int i, status = 0;
f31e50a8
SP
581 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
582
6ac7b687 583 for (i = 0; i < mcc_timeout; i++) {
954f6825 584 if (be_check_error(adapter, BE_ERROR_ANY))
6589ade0
SP
585 return -EIO;
586
072a9c48 587 local_bh_disable();
10ef9ab4 588 status = be_process_mcc(adapter);
072a9c48 589 local_bh_enable();
b31c50a7 590
f31e50a8 591 if (atomic_read(&mcc_obj->q.used) == 0)
6ac7b687 592 break;
b7172414 593 usleep_range(500, 1000);
6ac7b687 594 }
b31c50a7 595 if (i == mcc_timeout) {
6589ade0 596 dev_err(&adapter->pdev->dev, "FW not responding\n");
954f6825 597 be_set_error(adapter, BE_ERROR_FW);
652bf646 598 return -EIO;
b31c50a7 599 }
f31e50a8 600 return status;
6ac7b687
SP
601}
602
603/* Notify MCC requests and wait for completion */
b31c50a7 604static int be_mcc_notify_wait(struct be_adapter *adapter)
6ac7b687 605{
652bf646
PR
606 int status;
607 struct be_mcc_wrb *wrb;
608 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
b0fd2eb2 609 u32 index = mcc_obj->q.head;
652bf646
PR
610 struct be_cmd_resp_hdr *resp;
611
612 index_dec(&index, mcc_obj->q.len);
613 wrb = queue_index_node(&mcc_obj->q, index);
614
615 resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
616
efaa408e
SR
617 status = be_mcc_notify(adapter);
618 if (status)
619 goto out;
652bf646
PR
620
621 status = be_mcc_wait_compl(adapter);
622 if (status == -EIO)
623 goto out;
624
4c60005f
KA
625 status = (resp->base_status |
626 ((resp->addl_status & CQE_ADDL_STATUS_MASK) <<
627 CQE_ADDL_STATUS_SHIFT));
652bf646
PR
628out:
629 return status;
6ac7b687
SP
630}
631
5f0b849e 632static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
6b7c5b94 633{
f25b03a7 634 int msecs = 0;
6b7c5b94
SP
635 u32 ready;
636
637 do {
954f6825 638 if (be_check_error(adapter, BE_ERROR_ANY))
6589ade0
SP
639 return -EIO;
640
cf588477 641 ready = ioread32(db);
434b3648 642 if (ready == 0xffffffff)
cf588477 643 return -1;
cf588477
SP
644
645 ready &= MPU_MAILBOX_DB_RDY_MASK;
6b7c5b94
SP
646 if (ready)
647 break;
648
f25b03a7 649 if (msecs > 4000) {
6589ade0 650 dev_err(&adapter->pdev->dev, "FW not responding\n");
954f6825 651 be_set_error(adapter, BE_ERROR_FW);
f67ef7ba 652 be_detect_error(adapter);
6b7c5b94
SP
653 return -1;
654 }
655
1dbf53a2 656 msleep(1);
f25b03a7 657 msecs++;
6b7c5b94
SP
658 } while (true);
659
660 return 0;
661}
662
663/*
664 * Insert the mailbox address into the doorbell in two steps
5fb379ee 665 * Polls on the mbox doorbell till a command completion (or a timeout) occurs
6b7c5b94 666 */
b31c50a7 667static int be_mbox_notify_wait(struct be_adapter *adapter)
6b7c5b94
SP
668{
669 int status;
6b7c5b94 670 u32 val = 0;
8788fdc2
SP
671 void __iomem *db = adapter->db + MPU_MAILBOX_DB_OFFSET;
672 struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
6b7c5b94 673 struct be_mcc_mailbox *mbox = mbox_mem->va;
efd2e40a 674 struct be_mcc_compl *compl = &mbox->compl;
6b7c5b94 675
cf588477
SP
676 /* wait for ready to be set */
677 status = be_mbox_db_ready_wait(adapter, db);
678 if (status != 0)
679 return status;
680
6b7c5b94
SP
681 val |= MPU_MAILBOX_DB_HI_MASK;
682 /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
683 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
684 iowrite32(val, db);
685
686 /* wait for ready to be set */
5f0b849e 687 status = be_mbox_db_ready_wait(adapter, db);
6b7c5b94
SP
688 if (status != 0)
689 return status;
690
691 val = 0;
6b7c5b94
SP
692 /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
693 val |= (u32)(mbox_mem->dma >> 4) << 2;
694 iowrite32(val, db);
695
5f0b849e 696 status = be_mbox_db_ready_wait(adapter, db);
6b7c5b94
SP
697 if (status != 0)
698 return status;
699
5fb379ee 700 /* A cq entry has been made now */
efd2e40a
SP
701 if (be_mcc_compl_is_new(compl)) {
702 status = be_mcc_compl_process(adapter, &mbox->compl);
703 be_mcc_compl_use(compl);
5fb379ee
SP
704 if (status)
705 return status;
706 } else {
5f0b849e 707 dev_err(&adapter->pdev->dev, "invalid mailbox completion\n");
6b7c5b94
SP
708 return -1;
709 }
5fb379ee 710 return 0;
6b7c5b94
SP
711}
712
710f3e59 713u16 be_POST_stage_get(struct be_adapter *adapter)
6b7c5b94 714{
fe6d2a38
SP
715 u32 sem;
716
c5b3ad4c
SP
717 if (BEx_chip(adapter))
718 sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
6b7c5b94 719 else
c5b3ad4c
SP
720 pci_read_config_dword(adapter->pdev,
721 SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
722
723 return sem & POST_STAGE_MASK;
6b7c5b94
SP
724}
725
87f20c26 726static int lancer_wait_ready(struct be_adapter *adapter)
bf99e50d
PR
727{
728#define SLIPORT_READY_TIMEOUT 30
729 u32 sliport_status;
e673244a 730 int i;
bf99e50d
PR
731
732 for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
733 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
734 if (sliport_status & SLIPORT_STATUS_RDY_MASK)
9fa465c0 735 return 0;
67297ad8 736
9fa465c0
SP
737 if (sliport_status & SLIPORT_STATUS_ERR_MASK &&
738 !(sliport_status & SLIPORT_STATUS_RN_MASK))
739 return -EIO;
67297ad8 740
9fa465c0 741 msleep(1000);
bf99e50d 742 }
67297ad8 743
9fa465c0 744 return sliport_status ? : -1;
bf99e50d
PR
745}
746
747int be_fw_wait_ready(struct be_adapter *adapter)
6b7c5b94 748{
43a04fdc
SP
749 u16 stage;
750 int status, timeout = 0;
6ed35eea 751 struct device *dev = &adapter->pdev->dev;
6b7c5b94 752
bf99e50d
PR
753 if (lancer_chip(adapter)) {
754 status = lancer_wait_ready(adapter);
e673244a
KA
755 if (status) {
756 stage = status;
757 goto err;
758 }
759 return 0;
bf99e50d
PR
760 }
761
43a04fdc 762 do {
ca3de6b2
SP
763 /* There's no means to poll POST state on BE2/3 VFs */
764 if (BEx_chip(adapter) && be_virtfn(adapter))
765 return 0;
766
c5b3ad4c 767 stage = be_POST_stage_get(adapter);
66d29cbc 768 if (stage == POST_STAGE_ARMFW_RDY)
43a04fdc 769 return 0;
66d29cbc 770
a2cc4e0b 771 dev_info(dev, "Waiting for POST, %ds elapsed\n", timeout);
66d29cbc
GS
772 if (msleep_interruptible(2000)) {
773 dev_err(dev, "Waiting for POST aborted\n");
774 return -EINTR;
43a04fdc 775 }
66d29cbc 776 timeout += 2;
3ab81b5f 777 } while (timeout < 60);
6b7c5b94 778
e673244a
KA
779err:
780 dev_err(dev, "POST timeout; stage=%#x\n", stage);
9fa465c0 781 return -ETIMEDOUT;
6b7c5b94
SP
782}
783
6b7c5b94
SP
784static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
785{
786 return &wrb->payload.sgl[0];
787}
788
a2cc4e0b 789static inline void fill_wrb_tags(struct be_mcc_wrb *wrb, unsigned long addr)
bea50988
SP
790{
791 wrb->tag0 = addr & 0xFFFFFFFF;
792 wrb->tag1 = upper_32_bits(addr);
793}
6b7c5b94
SP
794
795/* Don't touch the hdr after it's prepared */
106df1e3
SK
796/* mem will be NULL for embedded commands */
797static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
a2cc4e0b
SP
798 u8 subsystem, u8 opcode, int cmd_len,
799 struct be_mcc_wrb *wrb,
800 struct be_dma_mem *mem)
6b7c5b94 801{
106df1e3
SK
802 struct be_sge *sge;
803
6b7c5b94
SP
804 req_hdr->opcode = opcode;
805 req_hdr->subsystem = subsystem;
806 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
07793d33 807 req_hdr->version = 0;
bea50988 808 fill_wrb_tags(wrb, (ulong) req_hdr);
106df1e3
SK
809 wrb->payload_length = cmd_len;
810 if (mem) {
811 wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
812 MCC_WRB_SGE_CNT_SHIFT;
813 sge = nonembedded_sgl(wrb);
814 sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
815 sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
816 sge->len = cpu_to_le32(mem->size);
817 } else
818 wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
819 be_dws_cpu_to_le(wrb, 8);
6b7c5b94
SP
820}
821
822static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
a2cc4e0b 823 struct be_dma_mem *mem)
6b7c5b94
SP
824{
825 int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
826 u64 dma = (u64)mem->dma;
827
828 for (i = 0; i < buf_pages; i++) {
829 pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
830 pages[i].hi = cpu_to_le32(upper_32_bits(dma));
831 dma += PAGE_SIZE_4K;
832 }
833}
834
b31c50a7 835static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
6b7c5b94 836{
b31c50a7
SP
837 struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
838 struct be_mcc_wrb *wrb
839 = &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
840 memset(wrb, 0, sizeof(*wrb));
841 return wrb;
6b7c5b94
SP
842}
843
b31c50a7 844static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
5fb379ee 845{
b31c50a7
SP
846 struct be_queue_info *mccq = &adapter->mcc_obj.q;
847 struct be_mcc_wrb *wrb;
848
aa790db9
PR
849 if (!mccq->created)
850 return NULL;
851
4d277125 852 if (atomic_read(&mccq->used) >= mccq->len)
713d0394 853 return NULL;
713d0394 854
b31c50a7
SP
855 wrb = queue_head_node(mccq);
856 queue_head_inc(mccq);
857 atomic_inc(&mccq->used);
858 memset(wrb, 0, sizeof(*wrb));
5fb379ee
SP
859 return wrb;
860}
861
bea50988
SP
862static bool use_mcc(struct be_adapter *adapter)
863{
864 return adapter->mcc_obj.q.created;
865}
866
867/* Must be used only in process context */
868static int be_cmd_lock(struct be_adapter *adapter)
869{
870 if (use_mcc(adapter)) {
b7172414 871 mutex_lock(&adapter->mcc_lock);
bea50988
SP
872 return 0;
873 } else {
874 return mutex_lock_interruptible(&adapter->mbox_lock);
875 }
876}
877
878/* Must be used only in process context */
879static void be_cmd_unlock(struct be_adapter *adapter)
880{
881 if (use_mcc(adapter))
b7172414 882 return mutex_unlock(&adapter->mcc_lock);
bea50988
SP
883 else
884 return mutex_unlock(&adapter->mbox_lock);
885}
886
887static struct be_mcc_wrb *be_cmd_copy(struct be_adapter *adapter,
888 struct be_mcc_wrb *wrb)
889{
890 struct be_mcc_wrb *dest_wrb;
891
892 if (use_mcc(adapter)) {
893 dest_wrb = wrb_from_mccq(adapter);
894 if (!dest_wrb)
895 return NULL;
896 } else {
897 dest_wrb = wrb_from_mbox(adapter);
898 }
899
900 memcpy(dest_wrb, wrb, sizeof(*wrb));
901 if (wrb->embedded & cpu_to_le32(MCC_WRB_EMBEDDED_MASK))
902 fill_wrb_tags(dest_wrb, (ulong) embedded_payload(wrb));
903
904 return dest_wrb;
905}
906
907/* Must be used only in process context */
908static int be_cmd_notify_wait(struct be_adapter *adapter,
909 struct be_mcc_wrb *wrb)
910{
911 struct be_mcc_wrb *dest_wrb;
912 int status;
913
914 status = be_cmd_lock(adapter);
915 if (status)
916 return status;
917
918 dest_wrb = be_cmd_copy(adapter, wrb);
0c884567
SR
919 if (!dest_wrb) {
920 status = -EBUSY;
921 goto unlock;
922 }
bea50988
SP
923
924 if (use_mcc(adapter))
925 status = be_mcc_notify_wait(adapter);
926 else
927 status = be_mbox_notify_wait(adapter);
928
929 if (!status)
930 memcpy(wrb, dest_wrb, sizeof(*wrb));
931
0c884567 932unlock:
bea50988
SP
933 be_cmd_unlock(adapter);
934 return status;
935}
936
2243e2e9
SP
937/* Tell fw we're about to start firing cmds by writing a
938 * special pattern across the wrb hdr; uses mbox
939 */
940int be_cmd_fw_init(struct be_adapter *adapter)
941{
942 u8 *wrb;
943 int status;
944
bf99e50d
PR
945 if (lancer_chip(adapter))
946 return 0;
947
2984961c
IV
948 if (mutex_lock_interruptible(&adapter->mbox_lock))
949 return -1;
2243e2e9
SP
950
951 wrb = (u8 *)wrb_from_mbox(adapter);
359a972f
SP
952 *wrb++ = 0xFF;
953 *wrb++ = 0x12;
954 *wrb++ = 0x34;
955 *wrb++ = 0xFF;
956 *wrb++ = 0xFF;
957 *wrb++ = 0x56;
958 *wrb++ = 0x78;
959 *wrb = 0xFF;
2243e2e9
SP
960
961 status = be_mbox_notify_wait(adapter);
962
2984961c 963 mutex_unlock(&adapter->mbox_lock);
2243e2e9
SP
964 return status;
965}
966
967/* Tell fw we're done with firing cmds by writing a
968 * special pattern across the wrb hdr; uses mbox
969 */
970int be_cmd_fw_clean(struct be_adapter *adapter)
971{
972 u8 *wrb;
973 int status;
974
bf99e50d
PR
975 if (lancer_chip(adapter))
976 return 0;
977
2984961c
IV
978 if (mutex_lock_interruptible(&adapter->mbox_lock))
979 return -1;
2243e2e9
SP
980
981 wrb = (u8 *)wrb_from_mbox(adapter);
982 *wrb++ = 0xFF;
983 *wrb++ = 0xAA;
984 *wrb++ = 0xBB;
985 *wrb++ = 0xFF;
986 *wrb++ = 0xFF;
987 *wrb++ = 0xCC;
988 *wrb++ = 0xDD;
989 *wrb = 0xFF;
990
991 status = be_mbox_notify_wait(adapter);
992
2984961c 993 mutex_unlock(&adapter->mbox_lock);
2243e2e9
SP
994 return status;
995}
bf99e50d 996
f2f781a7 997int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo)
6b7c5b94 998{
b31c50a7
SP
999 struct be_mcc_wrb *wrb;
1000 struct be_cmd_req_eq_create *req;
f2f781a7
SP
1001 struct be_dma_mem *q_mem = &eqo->q.dma_mem;
1002 int status, ver = 0;
6b7c5b94 1003
2984961c
IV
1004 if (mutex_lock_interruptible(&adapter->mbox_lock))
1005 return -1;
b31c50a7
SP
1006
1007 wrb = wrb_from_mbox(adapter);
1008 req = embedded_payload(wrb);
6b7c5b94 1009
106df1e3 1010 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1011 OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb,
1012 NULL);
6b7c5b94 1013
f2f781a7
SP
1014 /* Support for EQ_CREATEv2 available only SH-R onwards */
1015 if (!(BEx_chip(adapter) || lancer_chip(adapter)))
1016 ver = 2;
1017
1018 req->hdr.version = ver;
6b7c5b94
SP
1019 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1020
6b7c5b94
SP
1021 AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
1022 /* 4byte eqe*/
1023 AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
1024 AMAP_SET_BITS(struct amap_eq_context, count, req->context,
f2f781a7 1025 __ilog2_u32(eqo->q.len / 256));
6b7c5b94
SP
1026 be_dws_cpu_to_le(req->context, sizeof(req->context));
1027
1028 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1029
b31c50a7 1030 status = be_mbox_notify_wait(adapter);
6b7c5b94 1031 if (!status) {
b31c50a7 1032 struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
03d28ffe 1033
f2f781a7
SP
1034 eqo->q.id = le16_to_cpu(resp->eq_id);
1035 eqo->msix_idx =
1036 (ver == 2) ? le16_to_cpu(resp->msix_idx) : eqo->idx;
1037 eqo->q.created = true;
6b7c5b94 1038 }
b31c50a7 1039
2984961c 1040 mutex_unlock(&adapter->mbox_lock);
6b7c5b94
SP
1041 return status;
1042}
1043
f9449ab7 1044/* Use MCC */
8788fdc2 1045int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
5ee4979b 1046 bool permanent, u32 if_handle, u32 pmac_id)
6b7c5b94 1047{
b31c50a7
SP
1048 struct be_mcc_wrb *wrb;
1049 struct be_cmd_req_mac_query *req;
6b7c5b94
SP
1050 int status;
1051
b7172414 1052 mutex_lock(&adapter->mcc_lock);
b31c50a7 1053
f9449ab7
SP
1054 wrb = wrb_from_mccq(adapter);
1055 if (!wrb) {
1056 status = -EBUSY;
1057 goto err;
1058 }
b31c50a7 1059 req = embedded_payload(wrb);
6b7c5b94 1060
106df1e3 1061 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1062 OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req), wrb,
1063 NULL);
5ee4979b 1064 req->type = MAC_ADDRESS_TYPE_NETWORK;
6b7c5b94
SP
1065 if (permanent) {
1066 req->permanent = 1;
1067 } else {
504fbf1e 1068 req->if_id = cpu_to_le16((u16)if_handle);
590c391d 1069 req->pmac_id = cpu_to_le32(pmac_id);
6b7c5b94
SP
1070 req->permanent = 0;
1071 }
1072
f9449ab7 1073 status = be_mcc_notify_wait(adapter);
b31c50a7
SP
1074 if (!status) {
1075 struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
03d28ffe 1076
6b7c5b94 1077 memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
b31c50a7 1078 }
6b7c5b94 1079
f9449ab7 1080err:
b7172414 1081 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1082 return status;
1083}
1084
b31c50a7 1085/* Uses synchronous MCCQ */
8788fdc2 1086int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
a2cc4e0b 1087 u32 if_id, u32 *pmac_id, u32 domain)
6b7c5b94 1088{
b31c50a7
SP
1089 struct be_mcc_wrb *wrb;
1090 struct be_cmd_req_pmac_add *req;
6b7c5b94
SP
1091 int status;
1092
b7172414 1093 mutex_lock(&adapter->mcc_lock);
b31c50a7
SP
1094
1095 wrb = wrb_from_mccq(adapter);
713d0394
SP
1096 if (!wrb) {
1097 status = -EBUSY;
1098 goto err;
1099 }
b31c50a7 1100 req = embedded_payload(wrb);
6b7c5b94 1101
106df1e3 1102 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1103 OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req), wrb,
1104 NULL);
6b7c5b94 1105
f8617e08 1106 req->hdr.domain = domain;
6b7c5b94
SP
1107 req->if_id = cpu_to_le32(if_id);
1108 memcpy(req->mac_address, mac_addr, ETH_ALEN);
1109
b31c50a7 1110 status = be_mcc_notify_wait(adapter);
6b7c5b94
SP
1111 if (!status) {
1112 struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
03d28ffe 1113
6b7c5b94
SP
1114 *pmac_id = le32_to_cpu(resp->pmac_id);
1115 }
1116
713d0394 1117err:
b7172414 1118 mutex_unlock(&adapter->mcc_lock);
e3a7ae2c
SK
1119
1120 if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
1121 status = -EPERM;
1122
6b7c5b94
SP
1123 return status;
1124}
1125
b31c50a7 1126/* Uses synchronous MCCQ */
30128031 1127int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
6b7c5b94 1128{
b31c50a7
SP
1129 struct be_mcc_wrb *wrb;
1130 struct be_cmd_req_pmac_del *req;
6b7c5b94
SP
1131 int status;
1132
30128031
SP
1133 if (pmac_id == -1)
1134 return 0;
1135
b7172414 1136 mutex_lock(&adapter->mcc_lock);
b31c50a7
SP
1137
1138 wrb = wrb_from_mccq(adapter);
713d0394
SP
1139 if (!wrb) {
1140 status = -EBUSY;
1141 goto err;
1142 }
b31c50a7 1143 req = embedded_payload(wrb);
6b7c5b94 1144
106df1e3 1145 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
cd3307aa
KA
1146 OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req),
1147 wrb, NULL);
6b7c5b94 1148
f8617e08 1149 req->hdr.domain = dom;
6b7c5b94
SP
1150 req->if_id = cpu_to_le32(if_id);
1151 req->pmac_id = cpu_to_le32(pmac_id);
1152
b31c50a7
SP
1153 status = be_mcc_notify_wait(adapter);
1154
713d0394 1155err:
b7172414 1156 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1157 return status;
1158}
1159
b31c50a7 1160/* Uses Mbox */
10ef9ab4 1161int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
a2cc4e0b 1162 struct be_queue_info *eq, bool no_delay, int coalesce_wm)
6b7c5b94 1163{
b31c50a7
SP
1164 struct be_mcc_wrb *wrb;
1165 struct be_cmd_req_cq_create *req;
6b7c5b94 1166 struct be_dma_mem *q_mem = &cq->dma_mem;
b31c50a7 1167 void *ctxt;
6b7c5b94
SP
1168 int status;
1169
2984961c
IV
1170 if (mutex_lock_interruptible(&adapter->mbox_lock))
1171 return -1;
b31c50a7
SP
1172
1173 wrb = wrb_from_mbox(adapter);
1174 req = embedded_payload(wrb);
1175 ctxt = &req->context;
6b7c5b94 1176
106df1e3 1177 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1178 OPCODE_COMMON_CQ_CREATE, sizeof(*req), wrb,
1179 NULL);
6b7c5b94
SP
1180
1181 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
bbdc42f8
AK
1182
1183 if (BEx_chip(adapter)) {
fe6d2a38 1184 AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
a2cc4e0b 1185 coalesce_wm);
fe6d2a38 1186 AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
a2cc4e0b 1187 ctxt, no_delay);
fe6d2a38 1188 AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
a2cc4e0b 1189 __ilog2_u32(cq->len / 256));
fe6d2a38 1190 AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
fe6d2a38
SP
1191 AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
1192 AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
bbdc42f8
AK
1193 } else {
1194 req->hdr.version = 2;
1195 req->page_size = 1; /* 1 for 4K */
09e83a9d
AK
1196
1197 /* coalesce-wm field in this cmd is not relevant to Lancer.
1198 * Lancer uses COMMON_MODIFY_CQ to set this field
1199 */
1200 if (!lancer_chip(adapter))
1201 AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
1202 ctxt, coalesce_wm);
bbdc42f8 1203 AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
a2cc4e0b 1204 no_delay);
bbdc42f8 1205 AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
a2cc4e0b 1206 __ilog2_u32(cq->len / 256));
bbdc42f8 1207 AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
a2cc4e0b
SP
1208 AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
1209 AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
fe6d2a38 1210 }
6b7c5b94 1211
6b7c5b94
SP
1212 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1213
1214 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1215
b31c50a7 1216 status = be_mbox_notify_wait(adapter);
6b7c5b94 1217 if (!status) {
b31c50a7 1218 struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
03d28ffe 1219
6b7c5b94
SP
1220 cq->id = le16_to_cpu(resp->cq_id);
1221 cq->created = true;
1222 }
b31c50a7 1223
2984961c 1224 mutex_unlock(&adapter->mbox_lock);
5fb379ee
SP
1225
1226 return status;
1227}
1228
1229static u32 be_encoded_q_len(int q_len)
1230{
1231 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
03d28ffe 1232
5fb379ee
SP
1233 if (len_encoded == 16)
1234 len_encoded = 0;
1235 return len_encoded;
1236}
1237
4188e7df 1238static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
a2cc4e0b
SP
1239 struct be_queue_info *mccq,
1240 struct be_queue_info *cq)
5fb379ee 1241{
b31c50a7 1242 struct be_mcc_wrb *wrb;
34b1ef04 1243 struct be_cmd_req_mcc_ext_create *req;
5fb379ee 1244 struct be_dma_mem *q_mem = &mccq->dma_mem;
b31c50a7 1245 void *ctxt;
5fb379ee
SP
1246 int status;
1247
2984961c
IV
1248 if (mutex_lock_interruptible(&adapter->mbox_lock))
1249 return -1;
b31c50a7
SP
1250
1251 wrb = wrb_from_mbox(adapter);
1252 req = embedded_payload(wrb);
1253 ctxt = &req->context;
5fb379ee 1254
106df1e3 1255 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1256 OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req), wrb,
1257 NULL);
5fb379ee 1258
d4a2ac3e 1259 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
666d39c7 1260 if (BEx_chip(adapter)) {
fe6d2a38
SP
1261 AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
1262 AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
a2cc4e0b 1263 be_encoded_q_len(mccq->len));
fe6d2a38 1264 AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
666d39c7
VV
1265 } else {
1266 req->hdr.version = 1;
1267 req->cq_id = cpu_to_le16(cq->id);
1268
1269 AMAP_SET_BITS(struct amap_mcc_context_v1, ring_size, ctxt,
1270 be_encoded_q_len(mccq->len));
1271 AMAP_SET_BITS(struct amap_mcc_context_v1, valid, ctxt, 1);
1272 AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_id,
1273 ctxt, cq->id);
1274 AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_valid,
1275 ctxt, 1);
fe6d2a38 1276 }
5fb379ee 1277
21252377
VV
1278 /* Subscribe to Link State, Sliport Event and Group 5 Events
1279 * (bits 1, 5 and 17 set)
1280 */
1281 req->async_event_bitmap[0] =
1282 cpu_to_le32(BIT(ASYNC_EVENT_CODE_LINK_STATE) |
1283 BIT(ASYNC_EVENT_CODE_GRP_5) |
1284 BIT(ASYNC_EVENT_CODE_QNQ) |
1285 BIT(ASYNC_EVENT_CODE_SLIPORT));
1286
5fb379ee
SP
1287 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1288
1289 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1290
b31c50a7 1291 status = be_mbox_notify_wait(adapter);
5fb379ee
SP
1292 if (!status) {
1293 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
03d28ffe 1294
5fb379ee
SP
1295 mccq->id = le16_to_cpu(resp->id);
1296 mccq->created = true;
1297 }
2984961c 1298 mutex_unlock(&adapter->mbox_lock);
6b7c5b94
SP
1299
1300 return status;
1301}
1302
4188e7df 1303static int be_cmd_mccq_org_create(struct be_adapter *adapter,
a2cc4e0b
SP
1304 struct be_queue_info *mccq,
1305 struct be_queue_info *cq)
34b1ef04
SK
1306{
1307 struct be_mcc_wrb *wrb;
1308 struct be_cmd_req_mcc_create *req;
1309 struct be_dma_mem *q_mem = &mccq->dma_mem;
1310 void *ctxt;
1311 int status;
1312
1313 if (mutex_lock_interruptible(&adapter->mbox_lock))
1314 return -1;
1315
1316 wrb = wrb_from_mbox(adapter);
1317 req = embedded_payload(wrb);
1318 ctxt = &req->context;
1319
106df1e3 1320 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1321 OPCODE_COMMON_MCC_CREATE, sizeof(*req), wrb,
1322 NULL);
34b1ef04
SK
1323
1324 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1325
1326 AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
1327 AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
a2cc4e0b 1328 be_encoded_q_len(mccq->len));
34b1ef04
SK
1329 AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
1330
1331 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1332
1333 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1334
1335 status = be_mbox_notify_wait(adapter);
1336 if (!status) {
1337 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
03d28ffe 1338
34b1ef04
SK
1339 mccq->id = le16_to_cpu(resp->id);
1340 mccq->created = true;
1341 }
1342
1343 mutex_unlock(&adapter->mbox_lock);
1344 return status;
1345}
1346
1347int be_cmd_mccq_create(struct be_adapter *adapter,
a2cc4e0b 1348 struct be_queue_info *mccq, struct be_queue_info *cq)
34b1ef04
SK
1349{
1350 int status;
1351
1352 status = be_cmd_mccq_ext_create(adapter, mccq, cq);
666d39c7 1353 if (status && BEx_chip(adapter)) {
34b1ef04
SK
1354 dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
1355 "or newer to avoid conflicting priorities between NIC "
1356 "and FCoE traffic");
1357 status = be_cmd_mccq_org_create(adapter, mccq, cq);
1358 }
1359 return status;
1360}
1361
94d73aaa 1362int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo)
6b7c5b94 1363{
7707133c 1364 struct be_mcc_wrb wrb = {0};
b31c50a7 1365 struct be_cmd_req_eth_tx_create *req;
94d73aaa
VV
1366 struct be_queue_info *txq = &txo->q;
1367 struct be_queue_info *cq = &txo->cq;
6b7c5b94 1368 struct be_dma_mem *q_mem = &txq->dma_mem;
94d73aaa 1369 int status, ver = 0;
6b7c5b94 1370
7707133c 1371 req = embedded_payload(&wrb);
106df1e3 1372 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b 1373 OPCODE_ETH_TX_CREATE, sizeof(*req), &wrb, NULL);
6b7c5b94 1374
8b7756ca
PR
1375 if (lancer_chip(adapter)) {
1376 req->hdr.version = 1;
94d73aaa
VV
1377 } else if (BEx_chip(adapter)) {
1378 if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC)
1379 req->hdr.version = 2;
1380 } else { /* For SH */
1381 req->hdr.version = 2;
8b7756ca
PR
1382 }
1383
81b02655
VV
1384 if (req->hdr.version > 0)
1385 req->if_id = cpu_to_le16(adapter->if_handle);
6b7c5b94
SP
1386 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
1387 req->ulp_num = BE_ULP1_NUM;
1388 req->type = BE_ETH_TX_RING_TYPE_STANDARD;
94d73aaa
VV
1389 req->cq_id = cpu_to_le16(cq->id);
1390 req->queue_size = be_encoded_q_len(txq->len);
6b7c5b94 1391 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
94d73aaa
VV
1392 ver = req->hdr.version;
1393
7707133c 1394 status = be_cmd_notify_wait(adapter, &wrb);
6b7c5b94 1395 if (!status) {
7707133c 1396 struct be_cmd_resp_eth_tx_create *resp = embedded_payload(&wrb);
03d28ffe 1397
6b7c5b94 1398 txq->id = le16_to_cpu(resp->cid);
94d73aaa
VV
1399 if (ver == 2)
1400 txo->db_offset = le32_to_cpu(resp->db_offset);
1401 else
1402 txo->db_offset = DB_TXULP1_OFFSET;
6b7c5b94
SP
1403 txq->created = true;
1404 }
b31c50a7 1405
6b7c5b94
SP
1406 return status;
1407}
1408
482c9e79 1409/* Uses MCC */
8788fdc2 1410int be_cmd_rxq_create(struct be_adapter *adapter,
a2cc4e0b
SP
1411 struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
1412 u32 if_id, u32 rss, u8 *rss_id)
6b7c5b94 1413{
b31c50a7
SP
1414 struct be_mcc_wrb *wrb;
1415 struct be_cmd_req_eth_rx_create *req;
6b7c5b94
SP
1416 struct be_dma_mem *q_mem = &rxq->dma_mem;
1417 int status;
1418
b7172414 1419 mutex_lock(&adapter->mcc_lock);
b31c50a7 1420
482c9e79
SP
1421 wrb = wrb_from_mccq(adapter);
1422 if (!wrb) {
1423 status = -EBUSY;
1424 goto err;
1425 }
b31c50a7 1426 req = embedded_payload(wrb);
6b7c5b94 1427
106df1e3 1428 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b 1429 OPCODE_ETH_RX_CREATE, sizeof(*req), wrb, NULL);
6b7c5b94
SP
1430
1431 req->cq_id = cpu_to_le16(cq_id);
1432 req->frag_size = fls(frag_size) - 1;
1433 req->num_pages = 2;
1434 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1435 req->interface_id = cpu_to_le32(if_id);
10ef9ab4 1436 req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
6b7c5b94
SP
1437 req->rss_queue = cpu_to_le32(rss);
1438
482c9e79 1439 status = be_mcc_notify_wait(adapter);
6b7c5b94
SP
1440 if (!status) {
1441 struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
03d28ffe 1442
6b7c5b94
SP
1443 rxq->id = le16_to_cpu(resp->id);
1444 rxq->created = true;
3abcdeda 1445 *rss_id = resp->rss_id;
6b7c5b94 1446 }
b31c50a7 1447
482c9e79 1448err:
b7172414 1449 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1450 return status;
1451}
1452
b31c50a7
SP
1453/* Generic destroyer function for all types of queues
1454 * Uses Mbox
1455 */
8788fdc2 1456int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
a2cc4e0b 1457 int queue_type)
6b7c5b94 1458{
b31c50a7
SP
1459 struct be_mcc_wrb *wrb;
1460 struct be_cmd_req_q_destroy *req;
6b7c5b94
SP
1461 u8 subsys = 0, opcode = 0;
1462 int status;
1463
2984961c
IV
1464 if (mutex_lock_interruptible(&adapter->mbox_lock))
1465 return -1;
6b7c5b94 1466
b31c50a7
SP
1467 wrb = wrb_from_mbox(adapter);
1468 req = embedded_payload(wrb);
1469
6b7c5b94
SP
1470 switch (queue_type) {
1471 case QTYPE_EQ:
1472 subsys = CMD_SUBSYSTEM_COMMON;
1473 opcode = OPCODE_COMMON_EQ_DESTROY;
1474 break;
1475 case QTYPE_CQ:
1476 subsys = CMD_SUBSYSTEM_COMMON;
1477 opcode = OPCODE_COMMON_CQ_DESTROY;
1478 break;
1479 case QTYPE_TXQ:
1480 subsys = CMD_SUBSYSTEM_ETH;
1481 opcode = OPCODE_ETH_TX_DESTROY;
1482 break;
1483 case QTYPE_RXQ:
1484 subsys = CMD_SUBSYSTEM_ETH;
1485 opcode = OPCODE_ETH_RX_DESTROY;
1486 break;
5fb379ee
SP
1487 case QTYPE_MCCQ:
1488 subsys = CMD_SUBSYSTEM_COMMON;
1489 opcode = OPCODE_COMMON_MCC_DESTROY;
1490 break;
6b7c5b94 1491 default:
5f0b849e 1492 BUG();
6b7c5b94 1493 }
d744b44e 1494
106df1e3 1495 be_wrb_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req), wrb,
a2cc4e0b 1496 NULL);
6b7c5b94
SP
1497 req->id = cpu_to_le16(q->id);
1498
b31c50a7 1499 status = be_mbox_notify_wait(adapter);
aa790db9 1500 q->created = false;
5f0b849e 1501
2984961c 1502 mutex_unlock(&adapter->mbox_lock);
482c9e79
SP
1503 return status;
1504}
6b7c5b94 1505
482c9e79
SP
1506/* Uses MCC */
1507int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
1508{
1509 struct be_mcc_wrb *wrb;
1510 struct be_cmd_req_q_destroy *req;
1511 int status;
1512
b7172414 1513 mutex_lock(&adapter->mcc_lock);
482c9e79
SP
1514
1515 wrb = wrb_from_mccq(adapter);
1516 if (!wrb) {
1517 status = -EBUSY;
1518 goto err;
1519 }
1520 req = embedded_payload(wrb);
1521
106df1e3 1522 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b 1523 OPCODE_ETH_RX_DESTROY, sizeof(*req), wrb, NULL);
482c9e79
SP
1524 req->id = cpu_to_le16(q->id);
1525
1526 status = be_mcc_notify_wait(adapter);
aa790db9 1527 q->created = false;
482c9e79
SP
1528
1529err:
b7172414 1530 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1531 return status;
1532}
1533
b31c50a7 1534/* Create an rx filtering policy configuration on an i/f
bea50988 1535 * Will use MBOX only if MCCQ has not been created.
b31c50a7 1536 */
73d540f2 1537int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
1578e777 1538 u32 *if_handle, u32 domain)
6b7c5b94 1539{
bea50988 1540 struct be_mcc_wrb wrb = {0};
b31c50a7 1541 struct be_cmd_req_if_create *req;
6b7c5b94
SP
1542 int status;
1543
bea50988 1544 req = embedded_payload(&wrb);
106df1e3 1545 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1546 OPCODE_COMMON_NTWK_INTERFACE_CREATE,
1547 sizeof(*req), &wrb, NULL);
ba343c77 1548 req->hdr.domain = domain;
73d540f2
SP
1549 req->capability_flags = cpu_to_le32(cap_flags);
1550 req->enable_flags = cpu_to_le32(en_flags);
1578e777 1551 req->pmac_invalid = true;
6b7c5b94 1552
bea50988 1553 status = be_cmd_notify_wait(adapter, &wrb);
6b7c5b94 1554 if (!status) {
bea50988 1555 struct be_cmd_resp_if_create *resp = embedded_payload(&wrb);
03d28ffe 1556
6b7c5b94 1557 *if_handle = le32_to_cpu(resp->interface_id);
b5bb9776
SP
1558
1559 /* Hack to retrieve VF's pmac-id on BE3 */
18c57c74 1560 if (BE3_chip(adapter) && be_virtfn(adapter))
b5bb9776 1561 adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id);
6b7c5b94 1562 }
6b7c5b94
SP
1563 return status;
1564}
1565
62219066 1566/* Uses MCCQ if available else MBOX */
30128031 1567int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
6b7c5b94 1568{
62219066 1569 struct be_mcc_wrb wrb = {0};
b31c50a7 1570 struct be_cmd_req_if_destroy *req;
6b7c5b94
SP
1571 int status;
1572
30128031 1573 if (interface_id == -1)
f9449ab7 1574 return 0;
b31c50a7 1575
62219066 1576 req = embedded_payload(&wrb);
6b7c5b94 1577
106df1e3 1578 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b 1579 OPCODE_COMMON_NTWK_INTERFACE_DESTROY,
62219066 1580 sizeof(*req), &wrb, NULL);
658681f7 1581 req->hdr.domain = domain;
6b7c5b94 1582 req->interface_id = cpu_to_le32(interface_id);
b31c50a7 1583
62219066 1584 status = be_cmd_notify_wait(adapter, &wrb);
6b7c5b94
SP
1585 return status;
1586}
1587
1588/* Get stats is a non embedded command: the request is not embedded inside
1589 * WRB but is a separate dma memory block
b31c50a7 1590 * Uses asynchronous MCC
6b7c5b94 1591 */
8788fdc2 1592int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
6b7c5b94 1593{
b31c50a7 1594 struct be_mcc_wrb *wrb;
89a88ab8 1595 struct be_cmd_req_hdr *hdr;
713d0394 1596 int status = 0;
6b7c5b94 1597
b7172414 1598 mutex_lock(&adapter->mcc_lock);
6b7c5b94 1599
b31c50a7 1600 wrb = wrb_from_mccq(adapter);
713d0394
SP
1601 if (!wrb) {
1602 status = -EBUSY;
1603 goto err;
1604 }
89a88ab8 1605 hdr = nonemb_cmd->va;
6b7c5b94 1606
106df1e3 1607 be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b
SP
1608 OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb,
1609 nonemb_cmd);
89a88ab8 1610
ca34fe38 1611 /* version 1 of the cmd is not supported only by BE2 */
61000861
AK
1612 if (BE2_chip(adapter))
1613 hdr->version = 0;
1614 if (BE3_chip(adapter) || lancer_chip(adapter))
89a88ab8 1615 hdr->version = 1;
61000861
AK
1616 else
1617 hdr->version = 2;
89a88ab8 1618
efaa408e
SR
1619 status = be_mcc_notify(adapter);
1620 if (status)
1621 goto err;
1622
b2aebe6d 1623 adapter->stats_cmd_sent = true;
6b7c5b94 1624
713d0394 1625err:
b7172414 1626 mutex_unlock(&adapter->mcc_lock);
713d0394 1627 return status;
6b7c5b94
SP
1628}
1629
005d5696
SX
1630/* Lancer Stats */
1631int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
a2cc4e0b 1632 struct be_dma_mem *nonemb_cmd)
005d5696 1633{
005d5696
SX
1634 struct be_mcc_wrb *wrb;
1635 struct lancer_cmd_req_pport_stats *req;
005d5696
SX
1636 int status = 0;
1637
f25b119c
PR
1638 if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
1639 CMD_SUBSYSTEM_ETH))
1640 return -EPERM;
1641
b7172414 1642 mutex_lock(&adapter->mcc_lock);
005d5696
SX
1643
1644 wrb = wrb_from_mccq(adapter);
1645 if (!wrb) {
1646 status = -EBUSY;
1647 goto err;
1648 }
1649 req = nonemb_cmd->va;
005d5696 1650
106df1e3 1651 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b
SP
1652 OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size,
1653 wrb, nonemb_cmd);
005d5696 1654
d51ebd33 1655 req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
005d5696
SX
1656 req->cmd_params.params.reset_stats = 0;
1657
efaa408e
SR
1658 status = be_mcc_notify(adapter);
1659 if (status)
1660 goto err;
1661
005d5696
SX
1662 adapter->stats_cmd_sent = true;
1663
1664err:
b7172414 1665 mutex_unlock(&adapter->mcc_lock);
005d5696
SX
1666 return status;
1667}
1668
323ff71e
SP
1669static int be_mac_to_link_speed(int mac_speed)
1670{
1671 switch (mac_speed) {
1672 case PHY_LINK_SPEED_ZERO:
1673 return 0;
1674 case PHY_LINK_SPEED_10MBPS:
1675 return 10;
1676 case PHY_LINK_SPEED_100MBPS:
1677 return 100;
1678 case PHY_LINK_SPEED_1GBPS:
1679 return 1000;
1680 case PHY_LINK_SPEED_10GBPS:
1681 return 10000;
b971f847
VV
1682 case PHY_LINK_SPEED_20GBPS:
1683 return 20000;
1684 case PHY_LINK_SPEED_25GBPS:
1685 return 25000;
1686 case PHY_LINK_SPEED_40GBPS:
1687 return 40000;
323ff71e
SP
1688 }
1689 return 0;
1690}
1691
1692/* Uses synchronous mcc
1693 * Returns link_speed in Mbps
1694 */
1695int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
1696 u8 *link_status, u32 dom)
6b7c5b94 1697{
b31c50a7
SP
1698 struct be_mcc_wrb *wrb;
1699 struct be_cmd_req_link_status *req;
6b7c5b94
SP
1700 int status;
1701
b7172414 1702 mutex_lock(&adapter->mcc_lock);
b31c50a7 1703
b236916a
AK
1704 if (link_status)
1705 *link_status = LINK_DOWN;
1706
b31c50a7 1707 wrb = wrb_from_mccq(adapter);
713d0394
SP
1708 if (!wrb) {
1709 status = -EBUSY;
1710 goto err;
1711 }
b31c50a7 1712 req = embedded_payload(wrb);
a8f447bd 1713
57cd80d4 1714 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1715 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1716 sizeof(*req), wrb, NULL);
57cd80d4 1717
ca34fe38
SP
1718 /* version 1 of the cmd is not supported only by BE2 */
1719 if (!BE2_chip(adapter))
daad6167
PR
1720 req->hdr.version = 1;
1721
57cd80d4 1722 req->hdr.domain = dom;
6b7c5b94 1723
b31c50a7 1724 status = be_mcc_notify_wait(adapter);
6b7c5b94
SP
1725 if (!status) {
1726 struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
03d28ffe 1727
323ff71e
SP
1728 if (link_speed) {
1729 *link_speed = resp->link_speed ?
1730 le16_to_cpu(resp->link_speed) * 10 :
1731 be_mac_to_link_speed(resp->mac_speed);
1732
1733 if (!resp->logical_link_status)
1734 *link_speed = 0;
0388f251 1735 }
b236916a
AK
1736 if (link_status)
1737 *link_status = resp->logical_link_status;
6b7c5b94
SP
1738 }
1739
713d0394 1740err:
b7172414 1741 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1742 return status;
1743}
1744
609ff3bb
AK
1745/* Uses synchronous mcc */
1746int be_cmd_get_die_temperature(struct be_adapter *adapter)
1747{
1748 struct be_mcc_wrb *wrb;
1749 struct be_cmd_req_get_cntl_addnl_attribs *req;
117affe3 1750 int status = 0;
609ff3bb 1751
b7172414 1752 mutex_lock(&adapter->mcc_lock);
609ff3bb
AK
1753
1754 wrb = wrb_from_mccq(adapter);
1755 if (!wrb) {
1756 status = -EBUSY;
1757 goto err;
1758 }
1759 req = embedded_payload(wrb);
1760
106df1e3 1761 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1762 OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES,
1763 sizeof(*req), wrb, NULL);
609ff3bb 1764
efaa408e 1765 status = be_mcc_notify(adapter);
609ff3bb 1766err:
b7172414 1767 mutex_unlock(&adapter->mcc_lock);
609ff3bb
AK
1768 return status;
1769}
1770
311fddc7 1771/* Uses synchronous mcc */
fd7ff6f0 1772int be_cmd_get_fat_dump_len(struct be_adapter *adapter, u32 *dump_size)
311fddc7 1773{
fd7ff6f0 1774 struct be_mcc_wrb wrb = {0};
311fddc7
SK
1775 struct be_cmd_req_get_fat *req;
1776 int status;
1777
fd7ff6f0 1778 req = embedded_payload(&wrb);
311fddc7 1779
106df1e3 1780 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
fd7ff6f0
VD
1781 OPCODE_COMMON_MANAGE_FAT, sizeof(*req),
1782 &wrb, NULL);
311fddc7 1783 req->fat_operation = cpu_to_le32(QUERY_FAT);
fd7ff6f0 1784 status = be_cmd_notify_wait(adapter, &wrb);
311fddc7 1785 if (!status) {
fd7ff6f0 1786 struct be_cmd_resp_get_fat *resp = embedded_payload(&wrb);
03d28ffe 1787
fd7ff6f0
VD
1788 if (dump_size && resp->log_size)
1789 *dump_size = le32_to_cpu(resp->log_size) -
fe2a70ee 1790 sizeof(u32);
311fddc7 1791 }
311fddc7
SK
1792 return status;
1793}
1794
fd7ff6f0 1795int be_cmd_get_fat_dump(struct be_adapter *adapter, u32 buf_len, void *buf)
311fddc7
SK
1796{
1797 struct be_dma_mem get_fat_cmd;
1798 struct be_mcc_wrb *wrb;
1799 struct be_cmd_req_get_fat *req;
fe2a70ee
SK
1800 u32 offset = 0, total_size, buf_size,
1801 log_offset = sizeof(u32), payload_len;
fd7ff6f0 1802 int status;
311fddc7
SK
1803
1804 if (buf_len == 0)
fd7ff6f0 1805 return 0;
311fddc7
SK
1806
1807 total_size = buf_len;
1808
fe2a70ee 1809 get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
e51000db
SB
1810 get_fat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
1811 get_fat_cmd.size,
1812 &get_fat_cmd.dma, GFP_ATOMIC);
fd7ff6f0 1813 if (!get_fat_cmd.va)
c5f156de 1814 return -ENOMEM;
fe2a70ee 1815
b7172414 1816 mutex_lock(&adapter->mcc_lock);
311fddc7 1817
311fddc7
SK
1818 while (total_size) {
1819 buf_size = min(total_size, (u32)60*1024);
1820 total_size -= buf_size;
1821
fe2a70ee
SK
1822 wrb = wrb_from_mccq(adapter);
1823 if (!wrb) {
1824 status = -EBUSY;
311fddc7
SK
1825 goto err;
1826 }
1827 req = get_fat_cmd.va;
311fddc7 1828
fe2a70ee 1829 payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
106df1e3 1830 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1831 OPCODE_COMMON_MANAGE_FAT, payload_len,
1832 wrb, &get_fat_cmd);
311fddc7
SK
1833
1834 req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
1835 req->read_log_offset = cpu_to_le32(log_offset);
1836 req->read_log_length = cpu_to_le32(buf_size);
1837 req->data_buffer_size = cpu_to_le32(buf_size);
1838
1839 status = be_mcc_notify_wait(adapter);
1840 if (!status) {
1841 struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
03d28ffe 1842
311fddc7 1843 memcpy(buf + offset,
a2cc4e0b
SP
1844 resp->data_buffer,
1845 le32_to_cpu(resp->read_log_length));
fe2a70ee 1846 } else {
311fddc7 1847 dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
fe2a70ee
SK
1848 goto err;
1849 }
311fddc7
SK
1850 offset += buf_size;
1851 log_offset += buf_size;
1852 }
1853err:
e51000db
SB
1854 dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size,
1855 get_fat_cmd.va, get_fat_cmd.dma);
b7172414 1856 mutex_unlock(&adapter->mcc_lock);
c5f156de 1857 return status;
311fddc7
SK
1858}
1859
04b71175 1860/* Uses synchronous mcc */
e97e3cda 1861int be_cmd_get_fw_ver(struct be_adapter *adapter)
6b7c5b94 1862{
b31c50a7
SP
1863 struct be_mcc_wrb *wrb;
1864 struct be_cmd_req_get_fw_version *req;
6b7c5b94
SP
1865 int status;
1866
b7172414 1867 mutex_lock(&adapter->mcc_lock);
b31c50a7 1868
04b71175
SP
1869 wrb = wrb_from_mccq(adapter);
1870 if (!wrb) {
1871 status = -EBUSY;
1872 goto err;
1873 }
6b7c5b94 1874
04b71175 1875 req = embedded_payload(wrb);
6b7c5b94 1876
106df1e3 1877 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1878 OPCODE_COMMON_GET_FW_VERSION, sizeof(*req), wrb,
1879 NULL);
04b71175 1880 status = be_mcc_notify_wait(adapter);
6b7c5b94
SP
1881 if (!status) {
1882 struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
acbafeb1 1883
242eb470
VV
1884 strlcpy(adapter->fw_ver, resp->firmware_version_string,
1885 sizeof(adapter->fw_ver));
1886 strlcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string,
1887 sizeof(adapter->fw_on_flash));
6b7c5b94 1888 }
04b71175 1889err:
b7172414 1890 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1891 return status;
1892}
1893
b31c50a7
SP
1894/* set the EQ delay interval of an EQ to specified value
1895 * Uses async mcc
1896 */
b502ae8d
KA
1897static int __be_cmd_modify_eqd(struct be_adapter *adapter,
1898 struct be_set_eqd *set_eqd, int num)
6b7c5b94 1899{
b31c50a7
SP
1900 struct be_mcc_wrb *wrb;
1901 struct be_cmd_req_modify_eq_delay *req;
2632bafd 1902 int status = 0, i;
6b7c5b94 1903
b7172414 1904 mutex_lock(&adapter->mcc_lock);
b31c50a7
SP
1905
1906 wrb = wrb_from_mccq(adapter);
713d0394
SP
1907 if (!wrb) {
1908 status = -EBUSY;
1909 goto err;
1910 }
b31c50a7 1911 req = embedded_payload(wrb);
6b7c5b94 1912
106df1e3 1913 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1914 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req), wrb,
1915 NULL);
6b7c5b94 1916
2632bafd
SP
1917 req->num_eq = cpu_to_le32(num);
1918 for (i = 0; i < num; i++) {
1919 req->set_eqd[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
1920 req->set_eqd[i].phase = 0;
1921 req->set_eqd[i].delay_multiplier =
1922 cpu_to_le32(set_eqd[i].delay_multiplier);
1923 }
6b7c5b94 1924
efaa408e 1925 status = be_mcc_notify(adapter);
713d0394 1926err:
b7172414 1927 mutex_unlock(&adapter->mcc_lock);
713d0394 1928 return status;
6b7c5b94
SP
1929}
1930
93676703
KA
1931int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
1932 int num)
1933{
1934 int num_eqs, i = 0;
1935
c8ba4ad0
SR
1936 while (num) {
1937 num_eqs = min(num, 8);
1938 __be_cmd_modify_eqd(adapter, &set_eqd[i], num_eqs);
1939 i += num_eqs;
1940 num -= num_eqs;
93676703
KA
1941 }
1942
1943 return 0;
1944}
1945
b31c50a7 1946/* Uses sycnhronous mcc */
8788fdc2 1947int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
435452aa 1948 u32 num, u32 domain)
6b7c5b94 1949{
b31c50a7
SP
1950 struct be_mcc_wrb *wrb;
1951 struct be_cmd_req_vlan_config *req;
6b7c5b94
SP
1952 int status;
1953
b7172414 1954 mutex_lock(&adapter->mcc_lock);
b31c50a7
SP
1955
1956 wrb = wrb_from_mccq(adapter);
713d0394
SP
1957 if (!wrb) {
1958 status = -EBUSY;
1959 goto err;
1960 }
b31c50a7 1961 req = embedded_payload(wrb);
6b7c5b94 1962
106df1e3 1963 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1964 OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req),
1965 wrb, NULL);
435452aa 1966 req->hdr.domain = domain;
6b7c5b94
SP
1967
1968 req->interface_id = if_id;
012bd387 1969 req->untagged = BE_IF_FLAGS_UNTAGGED & be_if_cap_flags(adapter) ? 1 : 0;
6b7c5b94 1970 req->num_vlan = num;
4d567d97
KA
1971 memcpy(req->normal_vlan, vtag_array,
1972 req->num_vlan * sizeof(vtag_array[0]));
6b7c5b94 1973
b31c50a7 1974 status = be_mcc_notify_wait(adapter);
713d0394 1975err:
b7172414 1976 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
1977 return status;
1978}
1979
ac34b743 1980static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
6b7c5b94 1981{
6ac7b687 1982 struct be_mcc_wrb *wrb;
5b8821b7
SP
1983 struct be_dma_mem *mem = &adapter->rx_filter;
1984 struct be_cmd_req_rx_filter *req = mem->va;
e7b909a6 1985 int status;
6b7c5b94 1986
b7172414 1987 mutex_lock(&adapter->mcc_lock);
6ac7b687 1988
b31c50a7 1989 wrb = wrb_from_mccq(adapter);
713d0394
SP
1990 if (!wrb) {
1991 status = -EBUSY;
1992 goto err;
1993 }
5b8821b7 1994 memset(req, 0, sizeof(*req));
106df1e3 1995 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
1996 OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req),
1997 wrb, mem);
6b7c5b94 1998
5b8821b7 1999 req->if_id = cpu_to_le32(adapter->if_handle);
ac34b743
SP
2000 req->if_flags_mask = cpu_to_le32(flags);
2001 req->if_flags = (value == ON) ? req->if_flags_mask : 0;
2002
2003 if (flags & BE_IF_FLAGS_MULTICAST) {
b7172414 2004 int i;
24307eef 2005
1610c79f
PR
2006 /* Reset mcast promisc mode if already set by setting mask
2007 * and not setting flags field
2008 */
abb93951
PR
2009 req->if_flags_mask |=
2010 cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS &
92bf14ab 2011 be_if_cap_flags(adapter));
b7172414
SP
2012 req->mcast_num = cpu_to_le32(adapter->mc_count);
2013 for (i = 0; i < adapter->mc_count; i++)
2014 ether_addr_copy(req->mcast_mac[i].byte,
2015 adapter->mc_list[i].mac);
6b7c5b94
SP
2016 }
2017
b6588879 2018 status = be_mcc_notify_wait(adapter);
713d0394 2019err:
b7172414 2020 mutex_unlock(&adapter->mcc_lock);
e7b909a6 2021 return status;
6b7c5b94
SP
2022}
2023
ac34b743
SP
2024int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
2025{
2026 struct device *dev = &adapter->pdev->dev;
2027
2028 if ((flags & be_if_cap_flags(adapter)) != flags) {
2029 dev_warn(dev, "Cannot set rx filter flags 0x%x\n", flags);
2030 dev_warn(dev, "Interface is capable of 0x%x flags only\n",
2031 be_if_cap_flags(adapter));
2032 }
2033 flags &= be_if_cap_flags(adapter);
196e3735
KA
2034 if (!flags)
2035 return -ENOTSUPP;
ac34b743
SP
2036
2037 return __be_cmd_rx_filter(adapter, flags, value);
2038}
2039
b31c50a7 2040/* Uses synchrounous mcc */
8788fdc2 2041int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
6b7c5b94 2042{
b31c50a7
SP
2043 struct be_mcc_wrb *wrb;
2044 struct be_cmd_req_set_flow_control *req;
6b7c5b94
SP
2045 int status;
2046
f25b119c
PR
2047 if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
2048 CMD_SUBSYSTEM_COMMON))
2049 return -EPERM;
2050
b7172414 2051 mutex_lock(&adapter->mcc_lock);
6b7c5b94 2052
b31c50a7 2053 wrb = wrb_from_mccq(adapter);
713d0394
SP
2054 if (!wrb) {
2055 status = -EBUSY;
2056 goto err;
2057 }
b31c50a7 2058 req = embedded_payload(wrb);
6b7c5b94 2059
106df1e3 2060 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2061 OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req),
2062 wrb, NULL);
6b7c5b94 2063
b29812c1 2064 req->hdr.version = 1;
6b7c5b94
SP
2065 req->tx_flow_control = cpu_to_le16((u16)tx_fc);
2066 req->rx_flow_control = cpu_to_le16((u16)rx_fc);
2067
b31c50a7 2068 status = be_mcc_notify_wait(adapter);
6b7c5b94 2069
713d0394 2070err:
b7172414 2071 mutex_unlock(&adapter->mcc_lock);
b29812c1
SR
2072
2073 if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED)
2074 return -EOPNOTSUPP;
2075
6b7c5b94
SP
2076 return status;
2077}
2078
b31c50a7 2079/* Uses sycn mcc */
8788fdc2 2080int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
6b7c5b94 2081{
b31c50a7
SP
2082 struct be_mcc_wrb *wrb;
2083 struct be_cmd_req_get_flow_control *req;
6b7c5b94
SP
2084 int status;
2085
f25b119c
PR
2086 if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
2087 CMD_SUBSYSTEM_COMMON))
2088 return -EPERM;
2089
b7172414 2090 mutex_lock(&adapter->mcc_lock);
6b7c5b94 2091
b31c50a7 2092 wrb = wrb_from_mccq(adapter);
713d0394
SP
2093 if (!wrb) {
2094 status = -EBUSY;
2095 goto err;
2096 }
b31c50a7 2097 req = embedded_payload(wrb);
6b7c5b94 2098
106df1e3 2099 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2100 OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req),
2101 wrb, NULL);
6b7c5b94 2102
b31c50a7 2103 status = be_mcc_notify_wait(adapter);
6b7c5b94
SP
2104 if (!status) {
2105 struct be_cmd_resp_get_flow_control *resp =
2106 embedded_payload(wrb);
03d28ffe 2107
6b7c5b94
SP
2108 *tx_fc = le16_to_cpu(resp->tx_flow_control);
2109 *rx_fc = le16_to_cpu(resp->rx_flow_control);
2110 }
2111
713d0394 2112err:
b7172414 2113 mutex_unlock(&adapter->mcc_lock);
6b7c5b94
SP
2114 return status;
2115}
2116
b31c50a7 2117/* Uses mbox */
e97e3cda 2118int be_cmd_query_fw_cfg(struct be_adapter *adapter)
6b7c5b94 2119{
b31c50a7
SP
2120 struct be_mcc_wrb *wrb;
2121 struct be_cmd_req_query_fw_cfg *req;
6b7c5b94
SP
2122 int status;
2123
2984961c
IV
2124 if (mutex_lock_interruptible(&adapter->mbox_lock))
2125 return -1;
6b7c5b94 2126
b31c50a7
SP
2127 wrb = wrb_from_mbox(adapter);
2128 req = embedded_payload(wrb);
6b7c5b94 2129
106df1e3 2130 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2131 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
2132 sizeof(*req), wrb, NULL);
6b7c5b94 2133
b31c50a7 2134 status = be_mbox_notify_wait(adapter);
6b7c5b94
SP
2135 if (!status) {
2136 struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
03d28ffe 2137
e97e3cda
KA
2138 adapter->port_num = le32_to_cpu(resp->phys_port);
2139 adapter->function_mode = le32_to_cpu(resp->function_mode);
2140 adapter->function_caps = le32_to_cpu(resp->function_caps);
2141 adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
acbafeb1
SP
2142 dev_info(&adapter->pdev->dev,
2143 "FW config: function_mode=0x%x, function_caps=0x%x\n",
2144 adapter->function_mode, adapter->function_caps);
6b7c5b94
SP
2145 }
2146
2984961c 2147 mutex_unlock(&adapter->mbox_lock);
6b7c5b94
SP
2148 return status;
2149}
14074eab 2150
b31c50a7 2151/* Uses mbox */
14074eab 2152int be_cmd_reset_function(struct be_adapter *adapter)
2153{
b31c50a7
SP
2154 struct be_mcc_wrb *wrb;
2155 struct be_cmd_req_hdr *req;
14074eab 2156 int status;
2157
bf99e50d 2158 if (lancer_chip(adapter)) {
9fa465c0
SP
2159 iowrite32(SLI_PORT_CONTROL_IP_MASK,
2160 adapter->db + SLIPORT_CONTROL_OFFSET);
bf99e50d 2161 status = lancer_wait_ready(adapter);
9fa465c0 2162 if (status)
bf99e50d
PR
2163 dev_err(&adapter->pdev->dev,
2164 "Adapter in non recoverable error\n");
bf99e50d
PR
2165 return status;
2166 }
2167
2984961c
IV
2168 if (mutex_lock_interruptible(&adapter->mbox_lock))
2169 return -1;
14074eab 2170
b31c50a7
SP
2171 wrb = wrb_from_mbox(adapter);
2172 req = embedded_payload(wrb);
14074eab 2173
106df1e3 2174 be_wrb_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2175 OPCODE_COMMON_FUNCTION_RESET, sizeof(*req), wrb,
2176 NULL);
14074eab 2177
b31c50a7 2178 status = be_mbox_notify_wait(adapter);
14074eab 2179
2984961c 2180 mutex_unlock(&adapter->mbox_lock);
14074eab 2181 return status;
2182}
84517482 2183
594ad54a 2184int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
33cb0fa7 2185 u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey)
3abcdeda
SP
2186{
2187 struct be_mcc_wrb *wrb;
2188 struct be_cmd_req_rss_config *req;
3abcdeda
SP
2189 int status;
2190
da1388d6
VV
2191 if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
2192 return 0;
2193
b7172414 2194 mutex_lock(&adapter->mcc_lock);
3abcdeda 2195
b51aa367
KA
2196 wrb = wrb_from_mccq(adapter);
2197 if (!wrb) {
2198 status = -EBUSY;
2199 goto err;
2200 }
3abcdeda
SP
2201 req = embedded_payload(wrb);
2202
106df1e3 2203 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b 2204 OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
3abcdeda
SP
2205
2206 req->if_id = cpu_to_le32(adapter->if_handle);
594ad54a
SR
2207 req->enable_rss = cpu_to_le16(rss_hash_opts);
2208 req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
d3bd3a5e 2209
b51aa367 2210 if (!BEx_chip(adapter))
d3bd3a5e 2211 req->hdr.version = 1;
d3bd3a5e 2212
3abcdeda 2213 memcpy(req->cpu_table, rsstable, table_size);
e2557877 2214 memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
3abcdeda
SP
2215 be_dws_cpu_to_le(req->hash, sizeof(req->hash));
2216
b51aa367
KA
2217 status = be_mcc_notify_wait(adapter);
2218err:
b7172414 2219 mutex_unlock(&adapter->mcc_lock);
3abcdeda
SP
2220 return status;
2221}
2222
fad9ab2c
SB
2223/* Uses sync mcc */
2224int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
a2cc4e0b 2225 u8 bcn, u8 sts, u8 state)
fad9ab2c
SB
2226{
2227 struct be_mcc_wrb *wrb;
2228 struct be_cmd_req_enable_disable_beacon *req;
2229 int status;
2230
b7172414 2231 mutex_lock(&adapter->mcc_lock);
fad9ab2c
SB
2232
2233 wrb = wrb_from_mccq(adapter);
713d0394
SP
2234 if (!wrb) {
2235 status = -EBUSY;
2236 goto err;
2237 }
fad9ab2c
SB
2238 req = embedded_payload(wrb);
2239
106df1e3 2240 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2241 OPCODE_COMMON_ENABLE_DISABLE_BEACON,
2242 sizeof(*req), wrb, NULL);
fad9ab2c
SB
2243
2244 req->port_num = port_num;
2245 req->beacon_state = state;
2246 req->beacon_duration = bcn;
2247 req->status_duration = sts;
2248
2249 status = be_mcc_notify_wait(adapter);
2250
713d0394 2251err:
b7172414 2252 mutex_unlock(&adapter->mcc_lock);
fad9ab2c
SB
2253 return status;
2254}
2255
2256/* Uses sync mcc */
2257int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
2258{
2259 struct be_mcc_wrb *wrb;
2260 struct be_cmd_req_get_beacon_state *req;
2261 int status;
2262
b7172414 2263 mutex_lock(&adapter->mcc_lock);
fad9ab2c
SB
2264
2265 wrb = wrb_from_mccq(adapter);
713d0394
SP
2266 if (!wrb) {
2267 status = -EBUSY;
2268 goto err;
2269 }
fad9ab2c
SB
2270 req = embedded_payload(wrb);
2271
106df1e3 2272 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2273 OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req),
2274 wrb, NULL);
fad9ab2c
SB
2275
2276 req->port_num = port_num;
2277
2278 status = be_mcc_notify_wait(adapter);
2279 if (!status) {
2280 struct be_cmd_resp_get_beacon_state *resp =
2281 embedded_payload(wrb);
03d28ffe 2282
fad9ab2c
SB
2283 *state = resp->beacon_state;
2284 }
2285
713d0394 2286err:
b7172414 2287 mutex_unlock(&adapter->mcc_lock);
fad9ab2c
SB
2288 return status;
2289}
2290
e36edd9d
ML
2291/* Uses sync mcc */
2292int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2293 u8 page_num, u8 *data)
2294{
2295 struct be_dma_mem cmd;
2296 struct be_mcc_wrb *wrb;
2297 struct be_cmd_req_port_type *req;
2298 int status;
2299
2300 if (page_num > TR_PAGE_A2)
2301 return -EINVAL;
2302
2303 cmd.size = sizeof(struct be_cmd_resp_port_type);
e51000db
SB
2304 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
2305 GFP_ATOMIC);
e36edd9d
ML
2306 if (!cmd.va) {
2307 dev_err(&adapter->pdev->dev, "Memory allocation failed\n");
2308 return -ENOMEM;
2309 }
e36edd9d 2310
b7172414 2311 mutex_lock(&adapter->mcc_lock);
e36edd9d
ML
2312
2313 wrb = wrb_from_mccq(adapter);
2314 if (!wrb) {
2315 status = -EBUSY;
2316 goto err;
2317 }
2318 req = cmd.va;
2319
2320 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2321 OPCODE_COMMON_READ_TRANSRECV_DATA,
2322 cmd.size, wrb, &cmd);
2323
2324 req->port = cpu_to_le32(adapter->hba_port_num);
2325 req->page_num = cpu_to_le32(page_num);
2326 status = be_mcc_notify_wait(adapter);
2327 if (!status) {
2328 struct be_cmd_resp_port_type *resp = cmd.va;
2329
2330 memcpy(data, resp->page_data, PAGE_DATA_LEN);
2331 }
2332err:
b7172414 2333 mutex_unlock(&adapter->mcc_lock);
e51000db 2334 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
e36edd9d
ML
2335 return status;
2336}
2337
a23113b5
SR
2338static int lancer_cmd_write_object(struct be_adapter *adapter,
2339 struct be_dma_mem *cmd, u32 data_size,
2340 u32 data_offset, const char *obj_name,
2341 u32 *data_written, u8 *change_status,
2342 u8 *addn_status)
485bf569
SN
2343{
2344 struct be_mcc_wrb *wrb;
2345 struct lancer_cmd_req_write_object *req;
2346 struct lancer_cmd_resp_write_object *resp;
2347 void *ctxt = NULL;
2348 int status;
2349
b7172414 2350 mutex_lock(&adapter->mcc_lock);
485bf569
SN
2351 adapter->flash_status = 0;
2352
2353 wrb = wrb_from_mccq(adapter);
2354 if (!wrb) {
2355 status = -EBUSY;
2356 goto err_unlock;
2357 }
2358
2359 req = embedded_payload(wrb);
2360
106df1e3 2361 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2362 OPCODE_COMMON_WRITE_OBJECT,
2363 sizeof(struct lancer_cmd_req_write_object), wrb,
2364 NULL);
485bf569
SN
2365
2366 ctxt = &req->context;
2367 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
a2cc4e0b 2368 write_length, ctxt, data_size);
485bf569
SN
2369
2370 if (data_size == 0)
2371 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
a2cc4e0b 2372 eof, ctxt, 1);
485bf569
SN
2373 else
2374 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
a2cc4e0b 2375 eof, ctxt, 0);
485bf569
SN
2376
2377 be_dws_cpu_to_le(ctxt, sizeof(req->context));
2378 req->write_offset = cpu_to_le32(data_offset);
242eb470 2379 strlcpy(req->object_name, obj_name, sizeof(req->object_name));
485bf569
SN
2380 req->descriptor_count = cpu_to_le32(1);
2381 req->buf_len = cpu_to_le32(data_size);
2382 req->addr_low = cpu_to_le32((cmd->dma +
a2cc4e0b
SP
2383 sizeof(struct lancer_cmd_req_write_object))
2384 & 0xFFFFFFFF);
485bf569
SN
2385 req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
2386 sizeof(struct lancer_cmd_req_write_object)));
2387
efaa408e
SR
2388 status = be_mcc_notify(adapter);
2389 if (status)
2390 goto err_unlock;
2391
b7172414 2392 mutex_unlock(&adapter->mcc_lock);
485bf569 2393
5eeff635 2394 if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
701962d0 2395 msecs_to_jiffies(60000)))
fd45160c 2396 status = -ETIMEDOUT;
485bf569
SN
2397 else
2398 status = adapter->flash_status;
2399
2400 resp = embedded_payload(wrb);
f67ef7ba 2401 if (!status) {
485bf569 2402 *data_written = le32_to_cpu(resp->actual_write_len);
f67ef7ba
PR
2403 *change_status = resp->change_status;
2404 } else {
485bf569 2405 *addn_status = resp->additional_status;
f67ef7ba 2406 }
485bf569
SN
2407
2408 return status;
2409
2410err_unlock:
b7172414 2411 mutex_unlock(&adapter->mcc_lock);
485bf569
SN
2412 return status;
2413}
2414
6809cee0
RN
2415int be_cmd_query_cable_type(struct be_adapter *adapter)
2416{
2417 u8 page_data[PAGE_DATA_LEN];
2418 int status;
2419
2420 status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
2421 page_data);
2422 if (!status) {
2423 switch (adapter->phy.interface_type) {
2424 case PHY_TYPE_QSFP:
2425 adapter->phy.cable_type =
2426 page_data[QSFP_PLUS_CABLE_TYPE_OFFSET];
2427 break;
2428 case PHY_TYPE_SFP_PLUS_10GB:
2429 adapter->phy.cable_type =
2430 page_data[SFP_PLUS_CABLE_TYPE_OFFSET];
2431 break;
2432 default:
2433 adapter->phy.cable_type = 0;
2434 break;
2435 }
2436 }
2437 return status;
2438}
2439
21252377
VV
2440int be_cmd_query_sfp_info(struct be_adapter *adapter)
2441{
2442 u8 page_data[PAGE_DATA_LEN];
2443 int status;
2444
2445 status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
2446 page_data);
2447 if (!status) {
2448 strlcpy(adapter->phy.vendor_name, page_data +
2449 SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
2450 strlcpy(adapter->phy.vendor_pn,
2451 page_data + SFP_VENDOR_PN_OFFSET,
2452 SFP_VENDOR_NAME_LEN - 1);
2453 }
2454
2455 return status;
2456}
2457
a23113b5
SR
2458static int lancer_cmd_delete_object(struct be_adapter *adapter,
2459 const char *obj_name)
f0613380
KA
2460{
2461 struct lancer_cmd_req_delete_object *req;
2462 struct be_mcc_wrb *wrb;
2463 int status;
2464
b7172414 2465 mutex_lock(&adapter->mcc_lock);
f0613380
KA
2466
2467 wrb = wrb_from_mccq(adapter);
2468 if (!wrb) {
2469 status = -EBUSY;
2470 goto err;
2471 }
2472
2473 req = embedded_payload(wrb);
2474
2475 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2476 OPCODE_COMMON_DELETE_OBJECT,
2477 sizeof(*req), wrb, NULL);
2478
242eb470 2479 strlcpy(req->object_name, obj_name, sizeof(req->object_name));
f0613380
KA
2480
2481 status = be_mcc_notify_wait(adapter);
2482err:
b7172414 2483 mutex_unlock(&adapter->mcc_lock);
f0613380
KA
2484 return status;
2485}
2486
de49bd5a 2487int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
a2cc4e0b
SP
2488 u32 data_size, u32 data_offset, const char *obj_name,
2489 u32 *data_read, u32 *eof, u8 *addn_status)
de49bd5a
PR
2490{
2491 struct be_mcc_wrb *wrb;
2492 struct lancer_cmd_req_read_object *req;
2493 struct lancer_cmd_resp_read_object *resp;
2494 int status;
2495
b7172414 2496 mutex_lock(&adapter->mcc_lock);
de49bd5a
PR
2497
2498 wrb = wrb_from_mccq(adapter);
2499 if (!wrb) {
2500 status = -EBUSY;
2501 goto err_unlock;
2502 }
2503
2504 req = embedded_payload(wrb);
2505
2506 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2507 OPCODE_COMMON_READ_OBJECT,
2508 sizeof(struct lancer_cmd_req_read_object), wrb,
2509 NULL);
de49bd5a
PR
2510
2511 req->desired_read_len = cpu_to_le32(data_size);
2512 req->read_offset = cpu_to_le32(data_offset);
2513 strcpy(req->object_name, obj_name);
2514 req->descriptor_count = cpu_to_le32(1);
2515 req->buf_len = cpu_to_le32(data_size);
2516 req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
2517 req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));
2518
2519 status = be_mcc_notify_wait(adapter);
2520
2521 resp = embedded_payload(wrb);
2522 if (!status) {
2523 *data_read = le32_to_cpu(resp->actual_read_len);
2524 *eof = le32_to_cpu(resp->eof);
2525 } else {
2526 *addn_status = resp->additional_status;
2527 }
2528
2529err_unlock:
b7172414 2530 mutex_unlock(&adapter->mcc_lock);
de49bd5a
PR
2531 return status;
2532}
2533
a23113b5
SR
2534static int be_cmd_write_flashrom(struct be_adapter *adapter,
2535 struct be_dma_mem *cmd, u32 flash_type,
2536 u32 flash_opcode, u32 img_offset, u32 buf_size)
84517482 2537{
b31c50a7 2538 struct be_mcc_wrb *wrb;
3f0d4560 2539 struct be_cmd_write_flashrom *req;
84517482
AK
2540 int status;
2541
b7172414 2542 mutex_lock(&adapter->mcc_lock);
dd131e76 2543 adapter->flash_status = 0;
b31c50a7
SP
2544
2545 wrb = wrb_from_mccq(adapter);
713d0394
SP
2546 if (!wrb) {
2547 status = -EBUSY;
2892d9c2 2548 goto err_unlock;
713d0394
SP
2549 }
2550 req = cmd->va;
84517482 2551
106df1e3 2552 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
2553 OPCODE_COMMON_WRITE_FLASHROM, cmd->size, wrb,
2554 cmd);
84517482
AK
2555
2556 req->params.op_type = cpu_to_le32(flash_type);
70a7b525
VV
2557 if (flash_type == OPTYPE_OFFSET_SPECIFIED)
2558 req->params.offset = cpu_to_le32(img_offset);
2559
84517482
AK
2560 req->params.op_code = cpu_to_le32(flash_opcode);
2561 req->params.data_buf_size = cpu_to_le32(buf_size);
2562
efaa408e
SR
2563 status = be_mcc_notify(adapter);
2564 if (status)
2565 goto err_unlock;
2566
b7172414 2567 mutex_unlock(&adapter->mcc_lock);
dd131e76 2568
5eeff635
SR
2569 if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2570 msecs_to_jiffies(40000)))
fd45160c 2571 status = -ETIMEDOUT;
dd131e76
SB
2572 else
2573 status = adapter->flash_status;
84517482 2574
2892d9c2
DC
2575 return status;
2576
2577err_unlock:
b7172414 2578 mutex_unlock(&adapter->mcc_lock);
84517482
AK
2579 return status;
2580}
fa9a6fed 2581
a23113b5
SR
2582static int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
2583 u16 img_optype, u32 img_offset, u32 crc_offset)
fa9a6fed 2584{
be716446 2585 struct be_cmd_read_flash_crc *req;
70a7b525 2586 struct be_mcc_wrb *wrb;
fa9a6fed
SB
2587 int status;
2588
b7172414 2589 mutex_lock(&adapter->mcc_lock);
fa9a6fed
SB
2590
2591 wrb = wrb_from_mccq(adapter);
713d0394
SP
2592 if (!wrb) {
2593 status = -EBUSY;
2594 goto err;
2595 }
fa9a6fed
SB
2596 req = embedded_payload(wrb);
2597
106df1e3 2598 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
be716446
PR
2599 OPCODE_COMMON_READ_FLASHROM, sizeof(*req),
2600 wrb, NULL);
fa9a6fed 2601
70a7b525
VV
2602 req->params.op_type = cpu_to_le32(img_optype);
2603 if (img_optype == OPTYPE_OFFSET_SPECIFIED)
2604 req->params.offset = cpu_to_le32(img_offset + crc_offset);
2605 else
2606 req->params.offset = cpu_to_le32(crc_offset);
2607
fa9a6fed 2608 req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
8b93b710 2609 req->params.data_buf_size = cpu_to_le32(0x4);
fa9a6fed
SB
2610
2611 status = be_mcc_notify_wait(adapter);
2612 if (!status)
be716446 2613 memcpy(flashed_crc, req->crc, 4);
fa9a6fed 2614
713d0394 2615err:
b7172414 2616 mutex_unlock(&adapter->mcc_lock);
fa9a6fed
SB
2617 return status;
2618}
71d8d1b5 2619
a23113b5
SR
2620static char flash_cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
2621
2622static bool phy_flashing_required(struct be_adapter *adapter)
2623{
2624 return (adapter->phy.phy_type == PHY_TYPE_TN_8022 &&
2625 adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
2626}
2627
2628static bool is_comp_in_ufi(struct be_adapter *adapter,
2629 struct flash_section_info *fsec, int type)
2630{
2631 int i = 0, img_type = 0;
2632 struct flash_section_info_g2 *fsec_g2 = NULL;
2633
2634 if (BE2_chip(adapter))
2635 fsec_g2 = (struct flash_section_info_g2 *)fsec;
2636
2637 for (i = 0; i < MAX_FLASH_COMP; i++) {
2638 if (fsec_g2)
2639 img_type = le32_to_cpu(fsec_g2->fsec_entry[i].type);
2640 else
2641 img_type = le32_to_cpu(fsec->fsec_entry[i].type);
2642
2643 if (img_type == type)
2644 return true;
2645 }
2646 return false;
2647}
2648
2649static struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
2650 int header_size,
2651 const struct firmware *fw)
2652{
2653 struct flash_section_info *fsec = NULL;
2654 const u8 *p = fw->data;
2655
2656 p += header_size;
2657 while (p < (fw->data + fw->size)) {
2658 fsec = (struct flash_section_info *)p;
2659 if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie)))
2660 return fsec;
2661 p += 32;
2662 }
2663 return NULL;
2664}
2665
2666static int be_check_flash_crc(struct be_adapter *adapter, const u8 *p,
2667 u32 img_offset, u32 img_size, int hdr_size,
2668 u16 img_optype, bool *crc_match)
2669{
2670 u32 crc_offset;
2671 int status;
2672 u8 crc[4];
2673
2674 status = be_cmd_get_flash_crc(adapter, crc, img_optype, img_offset,
2675 img_size - 4);
2676 if (status)
2677 return status;
2678
2679 crc_offset = hdr_size + img_offset + img_size - 4;
2680
2681 /* Skip flashing, if crc of flashed region matches */
2682 if (!memcmp(crc, p + crc_offset, 4))
2683 *crc_match = true;
2684 else
2685 *crc_match = false;
2686
2687 return status;
2688}
2689
2690static int be_flash(struct be_adapter *adapter, const u8 *img,
2691 struct be_dma_mem *flash_cmd, int optype, int img_size,
2692 u32 img_offset)
2693{
2694 u32 flash_op, num_bytes, total_bytes = img_size, bytes_sent = 0;
2695 struct be_cmd_write_flashrom *req = flash_cmd->va;
2696 int status;
2697
2698 while (total_bytes) {
2699 num_bytes = min_t(u32, 32 * 1024, total_bytes);
2700
2701 total_bytes -= num_bytes;
2702
2703 if (!total_bytes) {
2704 if (optype == OPTYPE_PHY_FW)
2705 flash_op = FLASHROM_OPER_PHY_FLASH;
2706 else
2707 flash_op = FLASHROM_OPER_FLASH;
2708 } else {
2709 if (optype == OPTYPE_PHY_FW)
2710 flash_op = FLASHROM_OPER_PHY_SAVE;
2711 else
2712 flash_op = FLASHROM_OPER_SAVE;
2713 }
2714
2715 memcpy(req->data_buf, img, num_bytes);
2716 img += num_bytes;
2717 status = be_cmd_write_flashrom(adapter, flash_cmd, optype,
2718 flash_op, img_offset +
2719 bytes_sent, num_bytes);
2720 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST &&
2721 optype == OPTYPE_PHY_FW)
2722 break;
2723 else if (status)
2724 return status;
2725
2726 bytes_sent += num_bytes;
2727 }
2728 return 0;
2729}
2730
2731/* For BE2, BE3 and BE3-R */
2732static int be_flash_BEx(struct be_adapter *adapter,
2733 const struct firmware *fw,
2734 struct be_dma_mem *flash_cmd, int num_of_images)
2735{
2736 int img_hdrs_size = (num_of_images * sizeof(struct image_hdr));
2737 struct device *dev = &adapter->pdev->dev;
2738 struct flash_section_info *fsec = NULL;
2739 int status, i, filehdr_size, num_comp;
2740 const struct flash_comp *pflashcomp;
2741 bool crc_match;
2742 const u8 *p;
2743
2744 struct flash_comp gen3_flash_types[] = {
2745 { BE3_ISCSI_PRIMARY_IMAGE_START, OPTYPE_ISCSI_ACTIVE,
2746 BE3_COMP_MAX_SIZE, IMAGE_FIRMWARE_ISCSI},
2747 { BE3_REDBOOT_START, OPTYPE_REDBOOT,
2748 BE3_REDBOOT_COMP_MAX_SIZE, IMAGE_BOOT_CODE},
2749 { BE3_ISCSI_BIOS_START, OPTYPE_BIOS,
2750 BE3_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_ISCSI},
2751 { BE3_PXE_BIOS_START, OPTYPE_PXE_BIOS,
2752 BE3_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_PXE},
2753 { BE3_FCOE_BIOS_START, OPTYPE_FCOE_BIOS,
2754 BE3_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_FCOE},
2755 { BE3_ISCSI_BACKUP_IMAGE_START, OPTYPE_ISCSI_BACKUP,
2756 BE3_COMP_MAX_SIZE, IMAGE_FIRMWARE_BACKUP_ISCSI},
2757 { BE3_FCOE_PRIMARY_IMAGE_START, OPTYPE_FCOE_FW_ACTIVE,
2758 BE3_COMP_MAX_SIZE, IMAGE_FIRMWARE_FCOE},
2759 { BE3_FCOE_BACKUP_IMAGE_START, OPTYPE_FCOE_FW_BACKUP,
2760 BE3_COMP_MAX_SIZE, IMAGE_FIRMWARE_BACKUP_FCOE},
2761 { BE3_NCSI_START, OPTYPE_NCSI_FW,
2762 BE3_NCSI_COMP_MAX_SIZE, IMAGE_NCSI},
2763 { BE3_PHY_FW_START, OPTYPE_PHY_FW,
2764 BE3_PHY_FW_COMP_MAX_SIZE, IMAGE_FIRMWARE_PHY}
2765 };
2766
2767 struct flash_comp gen2_flash_types[] = {
2768 { BE2_ISCSI_PRIMARY_IMAGE_START, OPTYPE_ISCSI_ACTIVE,
2769 BE2_COMP_MAX_SIZE, IMAGE_FIRMWARE_ISCSI},
2770 { BE2_REDBOOT_START, OPTYPE_REDBOOT,
2771 BE2_REDBOOT_COMP_MAX_SIZE, IMAGE_BOOT_CODE},
2772 { BE2_ISCSI_BIOS_START, OPTYPE_BIOS,
2773 BE2_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_ISCSI},
2774 { BE2_PXE_BIOS_START, OPTYPE_PXE_BIOS,
2775 BE2_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_PXE},
2776 { BE2_FCOE_BIOS_START, OPTYPE_FCOE_BIOS,
2777 BE2_BIOS_COMP_MAX_SIZE, IMAGE_OPTION_ROM_FCOE},
2778 { BE2_ISCSI_BACKUP_IMAGE_START, OPTYPE_ISCSI_BACKUP,
2779 BE2_COMP_MAX_SIZE, IMAGE_FIRMWARE_BACKUP_ISCSI},
2780 { BE2_FCOE_PRIMARY_IMAGE_START, OPTYPE_FCOE_FW_ACTIVE,
2781 BE2_COMP_MAX_SIZE, IMAGE_FIRMWARE_FCOE},
2782 { BE2_FCOE_BACKUP_IMAGE_START, OPTYPE_FCOE_FW_BACKUP,
2783 BE2_COMP_MAX_SIZE, IMAGE_FIRMWARE_BACKUP_FCOE}
2784 };
2785
2786 if (BE3_chip(adapter)) {
2787 pflashcomp = gen3_flash_types;
2788 filehdr_size = sizeof(struct flash_file_hdr_g3);
2789 num_comp = ARRAY_SIZE(gen3_flash_types);
2790 } else {
2791 pflashcomp = gen2_flash_types;
2792 filehdr_size = sizeof(struct flash_file_hdr_g2);
2793 num_comp = ARRAY_SIZE(gen2_flash_types);
2794 img_hdrs_size = 0;
2795 }
2796
2797 /* Get flash section info*/
2798 fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
2799 if (!fsec) {
2800 dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
2801 return -1;
2802 }
2803 for (i = 0; i < num_comp; i++) {
2804 if (!is_comp_in_ufi(adapter, fsec, pflashcomp[i].img_type))
2805 continue;
2806
2807 if ((pflashcomp[i].optype == OPTYPE_NCSI_FW) &&
2808 memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
2809 continue;
2810
2811 if (pflashcomp[i].optype == OPTYPE_PHY_FW &&
2812 !phy_flashing_required(adapter))
2813 continue;
2814
2815 if (pflashcomp[i].optype == OPTYPE_REDBOOT) {
2816 status = be_check_flash_crc(adapter, fw->data,
2817 pflashcomp[i].offset,
2818 pflashcomp[i].size,
2819 filehdr_size +
2820 img_hdrs_size,
2821 OPTYPE_REDBOOT, &crc_match);
2822 if (status) {
2823 dev_err(dev,
2824 "Could not get CRC for 0x%x region\n",
2825 pflashcomp[i].optype);
2826 continue;
2827 }
2828
2829 if (crc_match)
2830 continue;
2831 }
2832
2833 p = fw->data + filehdr_size + pflashcomp[i].offset +
2834 img_hdrs_size;
2835 if (p + pflashcomp[i].size > fw->data + fw->size)
2836 return -1;
2837
2838 status = be_flash(adapter, p, flash_cmd, pflashcomp[i].optype,
2839 pflashcomp[i].size, 0);
2840 if (status) {
2841 dev_err(dev, "Flashing section type 0x%x failed\n",
2842 pflashcomp[i].img_type);
2843 return status;
2844 }
2845 }
2846 return 0;
2847}
2848
2849static u16 be_get_img_optype(struct flash_section_entry fsec_entry)
2850{
2851 u32 img_type = le32_to_cpu(fsec_entry.type);
2852 u16 img_optype = le16_to_cpu(fsec_entry.optype);
2853
2854 if (img_optype != 0xFFFF)
2855 return img_optype;
2856
2857 switch (img_type) {
2858 case IMAGE_FIRMWARE_ISCSI:
2859 img_optype = OPTYPE_ISCSI_ACTIVE;
2860 break;
2861 case IMAGE_BOOT_CODE:
2862 img_optype = OPTYPE_REDBOOT;
2863 break;
2864 case IMAGE_OPTION_ROM_ISCSI:
2865 img_optype = OPTYPE_BIOS;
2866 break;
2867 case IMAGE_OPTION_ROM_PXE:
2868 img_optype = OPTYPE_PXE_BIOS;
2869 break;
2870 case IMAGE_OPTION_ROM_FCOE:
2871 img_optype = OPTYPE_FCOE_BIOS;
2872 break;
2873 case IMAGE_FIRMWARE_BACKUP_ISCSI:
2874 img_optype = OPTYPE_ISCSI_BACKUP;
2875 break;
2876 case IMAGE_NCSI:
2877 img_optype = OPTYPE_NCSI_FW;
2878 break;
2879 case IMAGE_FLASHISM_JUMPVECTOR:
2880 img_optype = OPTYPE_FLASHISM_JUMPVECTOR;
2881 break;
2882 case IMAGE_FIRMWARE_PHY:
2883 img_optype = OPTYPE_SH_PHY_FW;
2884 break;
2885 case IMAGE_REDBOOT_DIR:
2886 img_optype = OPTYPE_REDBOOT_DIR;
2887 break;
2888 case IMAGE_REDBOOT_CONFIG:
2889 img_optype = OPTYPE_REDBOOT_CONFIG;
2890 break;
2891 case IMAGE_UFI_DIR:
2892 img_optype = OPTYPE_UFI_DIR;
2893 break;
2894 default:
2895 break;
2896 }
2897
2898 return img_optype;
2899}
2900
2901static int be_flash_skyhawk(struct be_adapter *adapter,
2902 const struct firmware *fw,
2903 struct be_dma_mem *flash_cmd, int num_of_images)
2904{
2905 int img_hdrs_size = num_of_images * sizeof(struct image_hdr);
2906 bool crc_match, old_fw_img, flash_offset_support = true;
2907 struct device *dev = &adapter->pdev->dev;
2908 struct flash_section_info *fsec = NULL;
2909 u32 img_offset, img_size, img_type;
2910 u16 img_optype, flash_optype;
2911 int status, i, filehdr_size;
2912 const u8 *p;
2913
2914 filehdr_size = sizeof(struct flash_file_hdr_g3);
2915 fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
2916 if (!fsec) {
2917 dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
2918 return -EINVAL;
2919 }
2920
2921retry_flash:
2922 for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) {
2923 img_offset = le32_to_cpu(fsec->fsec_entry[i].offset);
2924 img_size = le32_to_cpu(fsec->fsec_entry[i].pad_size);
2925 img_type = le32_to_cpu(fsec->fsec_entry[i].type);
2926 img_optype = be_get_img_optype(fsec->fsec_entry[i]);
2927 old_fw_img = fsec->fsec_entry[i].optype == 0xFFFF;
2928
2929 if (img_optype == 0xFFFF)
2930 continue;
2931
2932 if (flash_offset_support)
2933 flash_optype = OPTYPE_OFFSET_SPECIFIED;
2934 else
2935 flash_optype = img_optype;
2936
2937 /* Don't bother verifying CRC if an old FW image is being
2938 * flashed
2939 */
2940 if (old_fw_img)
2941 goto flash;
2942
2943 status = be_check_flash_crc(adapter, fw->data, img_offset,
2944 img_size, filehdr_size +
2945 img_hdrs_size, flash_optype,
2946 &crc_match);
2947 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
2948 base_status(status) == MCC_STATUS_ILLEGAL_FIELD) {
2949 /* The current FW image on the card does not support
2950 * OFFSET based flashing. Retry using older mechanism
2951 * of OPTYPE based flashing
2952 */
2953 if (flash_optype == OPTYPE_OFFSET_SPECIFIED) {
2954 flash_offset_support = false;
2955 goto retry_flash;
2956 }
2957
2958 /* The current FW image on the card does not recognize
2959 * the new FLASH op_type. The FW download is partially
2960 * complete. Reboot the server now to enable FW image
2961 * to recognize the new FLASH op_type. To complete the
2962 * remaining process, download the same FW again after
2963 * the reboot.
2964 */
2965 dev_err(dev, "Flash incomplete. Reset the server\n");
2966 dev_err(dev, "Download FW image again after reset\n");
2967 return -EAGAIN;
2968 } else if (status) {
2969 dev_err(dev, "Could not get CRC for 0x%x region\n",
2970 img_optype);
2971 return -EFAULT;
2972 }
2973
2974 if (crc_match)
2975 continue;
2976
2977flash:
2978 p = fw->data + filehdr_size + img_offset + img_hdrs_size;
2979 if (p + img_size > fw->data + fw->size)
2980 return -1;
2981
2982 status = be_flash(adapter, p, flash_cmd, flash_optype, img_size,
2983 img_offset);
2984
2985 /* The current FW image on the card does not support OFFSET
2986 * based flashing. Retry using older mechanism of OPTYPE based
2987 * flashing
2988 */
2989 if (base_status(status) == MCC_STATUS_ILLEGAL_FIELD &&
2990 flash_optype == OPTYPE_OFFSET_SPECIFIED) {
2991 flash_offset_support = false;
2992 goto retry_flash;
2993 }
2994
2995 /* For old FW images ignore ILLEGAL_FIELD error or errors on
2996 * UFI_DIR region
2997 */
2998 if (old_fw_img &&
2999 (base_status(status) == MCC_STATUS_ILLEGAL_FIELD ||
3000 (img_optype == OPTYPE_UFI_DIR &&
3001 base_status(status) == MCC_STATUS_FAILED))) {
3002 continue;
3003 } else if (status) {
3004 dev_err(dev, "Flashing section type 0x%x failed\n",
3005 img_type);
6b525782
SR
3006
3007 switch (addl_status(status)) {
3008 case MCC_ADDL_STATUS_MISSING_SIGNATURE:
3009 dev_err(dev,
3010 "Digital signature missing in FW\n");
3011 return -EINVAL;
3012 case MCC_ADDL_STATUS_INVALID_SIGNATURE:
3013 dev_err(dev,
3014 "Invalid digital signature in FW\n");
3015 return -EINVAL;
3016 default:
3017 return -EFAULT;
3018 }
a23113b5
SR
3019 }
3020 }
3021 return 0;
3022}
3023
3024int lancer_fw_download(struct be_adapter *adapter,
3025 const struct firmware *fw)
3026{
3027 struct device *dev = &adapter->pdev->dev;
3028 struct be_dma_mem flash_cmd;
3029 const u8 *data_ptr = NULL;
3030 u8 *dest_image_ptr = NULL;
3031 size_t image_size = 0;
3032 u32 chunk_size = 0;
3033 u32 data_written = 0;
3034 u32 offset = 0;
3035 int status = 0;
3036 u8 add_status = 0;
3037 u8 change_status;
3038
3039 if (!IS_ALIGNED(fw->size, sizeof(u32))) {
3040 dev_err(dev, "FW image size should be multiple of 4\n");
3041 return -EINVAL;
3042 }
3043
3044 flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
3045 + LANCER_FW_DOWNLOAD_CHUNK;
3046 flash_cmd.va = dma_zalloc_coherent(dev, flash_cmd.size,
3047 &flash_cmd.dma, GFP_KERNEL);
3048 if (!flash_cmd.va)
3049 return -ENOMEM;
3050
3051 dest_image_ptr = flash_cmd.va +
3052 sizeof(struct lancer_cmd_req_write_object);
3053 image_size = fw->size;
3054 data_ptr = fw->data;
3055
3056 while (image_size) {
3057 chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
3058
3059 /* Copy the image chunk content. */
3060 memcpy(dest_image_ptr, data_ptr, chunk_size);
3061
3062 status = lancer_cmd_write_object(adapter, &flash_cmd,
3063 chunk_size, offset,
3064 LANCER_FW_DOWNLOAD_LOCATION,
3065 &data_written, &change_status,
3066 &add_status);
3067 if (status)
3068 break;
3069
3070 offset += data_written;
3071 data_ptr += data_written;
3072 image_size -= data_written;
3073 }
3074
3075 if (!status) {
3076 /* Commit the FW written */
3077 status = lancer_cmd_write_object(adapter, &flash_cmd,
3078 0, offset,
3079 LANCER_FW_DOWNLOAD_LOCATION,
3080 &data_written, &change_status,
3081 &add_status);
3082 }
3083
3084 dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
3085 if (status) {
3086 dev_err(dev, "Firmware load error\n");
3087 return be_cmd_status(status);
3088 }
3089
3090 dev_info(dev, "Firmware flashed successfully\n");
3091
3092 if (change_status == LANCER_FW_RESET_NEEDED) {
3093 dev_info(dev, "Resetting adapter to activate new FW\n");
3094 status = lancer_physdev_ctrl(adapter,
3095 PHYSDEV_CONTROL_FW_RESET_MASK);
3096 if (status) {
3097 dev_err(dev, "Adapter busy, could not reset FW\n");
3098 dev_err(dev, "Reboot server to activate new FW\n");
3099 }
3100 } else if (change_status != LANCER_NO_RESET_NEEDED) {
3101 dev_info(dev, "Reboot server to activate new FW\n");
3102 }
3103
3104 return 0;
3105}
3106
3107/* Check if the flash image file is compatible with the adapter that
3108 * is being flashed.
3109 */
3110static bool be_check_ufi_compatibility(struct be_adapter *adapter,
3111 struct flash_file_hdr_g3 *fhdr)
3112{
3113 if (!fhdr) {
3114 dev_err(&adapter->pdev->dev, "Invalid FW UFI file");
3115 return false;
3116 }
3117
3118 /* First letter of the build version is used to identify
3119 * which chip this image file is meant for.
3120 */
3121 switch (fhdr->build[0]) {
3122 case BLD_STR_UFI_TYPE_SH:
3123 if (!skyhawk_chip(adapter))
3124 return false;
3125 break;
3126 case BLD_STR_UFI_TYPE_BE3:
3127 if (!BE3_chip(adapter))
3128 return false;
3129 break;
3130 case BLD_STR_UFI_TYPE_BE2:
3131 if (!BE2_chip(adapter))
3132 return false;
3133 break;
3134 default:
3135 return false;
3136 }
3137
3138 /* In BE3 FW images the "asic_type_rev" field doesn't track the
3139 * asic_rev of the chips it is compatible with.
3140 * When asic_type_rev is 0 the image is compatible only with
3141 * pre-BE3-R chips (asic_rev < 0x10)
3142 */
3143 if (BEx_chip(adapter) && fhdr->asic_type_rev == 0)
3144 return adapter->asic_rev < 0x10;
3145 else
3146 return (fhdr->asic_type_rev >= adapter->asic_rev);
3147}
3148
3149int be_fw_download(struct be_adapter *adapter, const struct firmware *fw)
3150{
3151 struct device *dev = &adapter->pdev->dev;
3152 struct flash_file_hdr_g3 *fhdr3;
3153 struct image_hdr *img_hdr_ptr;
3154 int status = 0, i, num_imgs;
3155 struct be_dma_mem flash_cmd;
3156
3157 fhdr3 = (struct flash_file_hdr_g3 *)fw->data;
3158 if (!be_check_ufi_compatibility(adapter, fhdr3)) {
3159 dev_err(dev, "Flash image is not compatible with adapter\n");
3160 return -EINVAL;
3161 }
3162
3163 flash_cmd.size = sizeof(struct be_cmd_write_flashrom);
3164 flash_cmd.va = dma_zalloc_coherent(dev, flash_cmd.size, &flash_cmd.dma,
3165 GFP_KERNEL);
3166 if (!flash_cmd.va)
3167 return -ENOMEM;
3168
3169 num_imgs = le32_to_cpu(fhdr3->num_imgs);
3170 for (i = 0; i < num_imgs; i++) {
3171 img_hdr_ptr = (struct image_hdr *)(fw->data +
3172 (sizeof(struct flash_file_hdr_g3) +
3173 i * sizeof(struct image_hdr)));
3174 if (!BE2_chip(adapter) &&
3175 le32_to_cpu(img_hdr_ptr->imageid) != 1)
3176 continue;
3177
3178 if (skyhawk_chip(adapter))
3179 status = be_flash_skyhawk(adapter, fw, &flash_cmd,
3180 num_imgs);
3181 else
3182 status = be_flash_BEx(adapter, fw, &flash_cmd,
3183 num_imgs);
3184 }
3185
3186 dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
3187 if (!status)
3188 dev_info(dev, "Firmware flashed successfully\n");
3189
3190 return status;
3191}
3192
c196b02c 3193int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
a2cc4e0b 3194 struct be_dma_mem *nonemb_cmd)
71d8d1b5
AK
3195{
3196 struct be_mcc_wrb *wrb;
3197 struct be_cmd_req_acpi_wol_magic_config *req;
71d8d1b5
AK
3198 int status;
3199
b7172414 3200 mutex_lock(&adapter->mcc_lock);
71d8d1b5
AK
3201
3202 wrb = wrb_from_mccq(adapter);
3203 if (!wrb) {
3204 status = -EBUSY;
3205 goto err;
3206 }
3207 req = nonemb_cmd->va;
71d8d1b5 3208
106df1e3 3209 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
a2cc4e0b
SP
3210 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req),
3211 wrb, nonemb_cmd);
71d8d1b5
AK
3212 memcpy(req->magic_mac, mac, ETH_ALEN);
3213
71d8d1b5
AK
3214 status = be_mcc_notify_wait(adapter);
3215
3216err:
b7172414 3217 mutex_unlock(&adapter->mcc_lock);
71d8d1b5
AK
3218 return status;
3219}
ff33a6e2 3220
fced9999
SB
3221int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
3222 u8 loopback_type, u8 enable)
3223{
3224 struct be_mcc_wrb *wrb;
3225 struct be_cmd_req_set_lmode *req;
3226 int status;
3227
2e365b1b
SK
3228 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
3229 CMD_SUBSYSTEM_LOWLEVEL))
3230 return -EPERM;
3231
b7172414 3232 mutex_lock(&adapter->mcc_lock);
fced9999
SB
3233
3234 wrb = wrb_from_mccq(adapter);
3235 if (!wrb) {
3236 status = -EBUSY;
9c855975 3237 goto err_unlock;
fced9999
SB
3238 }
3239
3240 req = embedded_payload(wrb);
3241
106df1e3 3242 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
a2cc4e0b
SP
3243 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, sizeof(*req),
3244 wrb, NULL);
fced9999
SB
3245
3246 req->src_port = port_num;
3247 req->dest_port = port_num;
3248 req->loopback_type = loopback_type;
3249 req->loopback_state = enable;
3250
9c855975
SR
3251 status = be_mcc_notify(adapter);
3252 if (status)
3253 goto err_unlock;
3254
b7172414 3255 mutex_unlock(&adapter->mcc_lock);
9c855975
SR
3256
3257 if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
3258 msecs_to_jiffies(SET_LB_MODE_TIMEOUT)))
3259 status = -ETIMEDOUT;
3260
3261 return status;
3262
3263err_unlock:
b7172414 3264 mutex_unlock(&adapter->mcc_lock);
fced9999
SB
3265 return status;
3266}
3267
ff33a6e2 3268int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
a2cc4e0b
SP
3269 u32 loopback_type, u32 pkt_size, u32 num_pkts,
3270 u64 pattern)
ff33a6e2
S
3271{
3272 struct be_mcc_wrb *wrb;
3273 struct be_cmd_req_loopback_test *req;
5eeff635 3274 struct be_cmd_resp_loopback_test *resp;
ff33a6e2
S
3275 int status;
3276
2e365b1b
SK
3277 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_LOOPBACK_TEST,
3278 CMD_SUBSYSTEM_LOWLEVEL))
3279 return -EPERM;
3280
b7172414 3281 mutex_lock(&adapter->mcc_lock);
ff33a6e2
S
3282
3283 wrb = wrb_from_mccq(adapter);
3284 if (!wrb) {
3285 status = -EBUSY;
3286 goto err;
3287 }
3288
3289 req = embedded_payload(wrb);
3290
106df1e3 3291 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
a2cc4e0b
SP
3292 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req), wrb,
3293 NULL);
ff33a6e2 3294
5eeff635 3295 req->hdr.timeout = cpu_to_le32(15);
ff33a6e2
S
3296 req->pattern = cpu_to_le64(pattern);
3297 req->src_port = cpu_to_le32(port_num);
3298 req->dest_port = cpu_to_le32(port_num);
3299 req->pkt_size = cpu_to_le32(pkt_size);
3300 req->num_pkts = cpu_to_le32(num_pkts);
3301 req->loopback_type = cpu_to_le32(loopback_type);
3302
efaa408e
SR
3303 status = be_mcc_notify(adapter);
3304 if (status)
3305 goto err;
5eeff635 3306
b7172414 3307 mutex_unlock(&adapter->mcc_lock);
ff33a6e2 3308
5eeff635
SR
3309 wait_for_completion(&adapter->et_cmd_compl);
3310 resp = embedded_payload(wrb);
3311 status = le32_to_cpu(resp->status);
3312
3313 return status;
ff33a6e2 3314err:
b7172414 3315 mutex_unlock(&adapter->mcc_lock);
ff33a6e2
S
3316 return status;
3317}
3318
3319int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
a2cc4e0b 3320 u32 byte_cnt, struct be_dma_mem *cmd)
ff33a6e2
S
3321{
3322 struct be_mcc_wrb *wrb;
3323 struct be_cmd_req_ddrdma_test *req;
ff33a6e2
S
3324 int status;
3325 int i, j = 0;
3326
2e365b1b
SK
3327 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_HOST_DDR_DMA,
3328 CMD_SUBSYSTEM_LOWLEVEL))
3329 return -EPERM;
3330
b7172414 3331 mutex_lock(&adapter->mcc_lock);
ff33a6e2
S
3332
3333 wrb = wrb_from_mccq(adapter);
3334 if (!wrb) {
3335 status = -EBUSY;
3336 goto err;
3337 }
3338 req = cmd->va;
106df1e3 3339 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
a2cc4e0b
SP
3340 OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size, wrb,
3341 cmd);
ff33a6e2
S
3342
3343 req->pattern = cpu_to_le64(pattern);
3344 req->byte_count = cpu_to_le32(byte_cnt);
3345 for (i = 0; i < byte_cnt; i++) {
3346 req->snd_buff[i] = (u8)(pattern >> (j*8));
3347 j++;
3348 if (j > 7)
3349 j = 0;
3350 }
3351
3352 status = be_mcc_notify_wait(adapter);
3353
3354 if (!status) {
3355 struct be_cmd_resp_ddrdma_test *resp;
03d28ffe 3356
ff33a6e2
S
3357 resp = cmd->va;
3358 if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
cd3307aa 3359 resp->snd_err) {
ff33a6e2
S
3360 status = -1;
3361 }
3362 }
3363
3364err:
b7172414 3365 mutex_unlock(&adapter->mcc_lock);
ff33a6e2
S
3366 return status;
3367}
368c0ca2 3368
c196b02c 3369int be_cmd_get_seeprom_data(struct be_adapter *adapter,
a2cc4e0b 3370 struct be_dma_mem *nonemb_cmd)
368c0ca2
SB
3371{
3372 struct be_mcc_wrb *wrb;
3373 struct be_cmd_req_seeprom_read *req;
368c0ca2
SB
3374 int status;
3375
b7172414 3376 mutex_lock(&adapter->mcc_lock);
368c0ca2
SB
3377
3378 wrb = wrb_from_mccq(adapter);
e45ff01d
AK
3379 if (!wrb) {
3380 status = -EBUSY;
3381 goto err;
3382 }
368c0ca2 3383 req = nonemb_cmd->va;
368c0ca2 3384
106df1e3 3385 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3386 OPCODE_COMMON_SEEPROM_READ, sizeof(*req), wrb,
3387 nonemb_cmd);
368c0ca2
SB
3388
3389 status = be_mcc_notify_wait(adapter);
3390
e45ff01d 3391err:
b7172414 3392 mutex_unlock(&adapter->mcc_lock);
368c0ca2
SB
3393 return status;
3394}
ee3cb629 3395
42f11cf2 3396int be_cmd_get_phy_info(struct be_adapter *adapter)
ee3cb629
AK
3397{
3398 struct be_mcc_wrb *wrb;
3399 struct be_cmd_req_get_phy_info *req;
306f1348 3400 struct be_dma_mem cmd;
ee3cb629
AK
3401 int status;
3402
f25b119c
PR
3403 if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
3404 CMD_SUBSYSTEM_COMMON))
3405 return -EPERM;
3406
b7172414 3407 mutex_lock(&adapter->mcc_lock);
ee3cb629
AK
3408
3409 wrb = wrb_from_mccq(adapter);
3410 if (!wrb) {
3411 status = -EBUSY;
3412 goto err;
3413 }
306f1348 3414 cmd.size = sizeof(struct be_cmd_req_get_phy_info);
e51000db
SB
3415 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3416 GFP_ATOMIC);
306f1348
SP
3417 if (!cmd.va) {
3418 dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
3419 status = -ENOMEM;
3420 goto err;
3421 }
ee3cb629 3422
306f1348 3423 req = cmd.va;
ee3cb629 3424
106df1e3 3425 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3426 OPCODE_COMMON_GET_PHY_DETAILS, sizeof(*req),
3427 wrb, &cmd);
ee3cb629
AK
3428
3429 status = be_mcc_notify_wait(adapter);
306f1348
SP
3430 if (!status) {
3431 struct be_phy_info *resp_phy_info =
3432 cmd.va + sizeof(struct be_cmd_req_hdr);
03d28ffe 3433
42f11cf2
AK
3434 adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
3435 adapter->phy.interface_type =
306f1348 3436 le16_to_cpu(resp_phy_info->interface_type);
42f11cf2
AK
3437 adapter->phy.auto_speeds_supported =
3438 le16_to_cpu(resp_phy_info->auto_speeds_supported);
3439 adapter->phy.fixed_speeds_supported =
3440 le16_to_cpu(resp_phy_info->fixed_speeds_supported);
3441 adapter->phy.misc_params =
3442 le32_to_cpu(resp_phy_info->misc_params);
68cb7e47
VV
3443
3444 if (BE2_chip(adapter)) {
3445 adapter->phy.fixed_speeds_supported =
3446 BE_SUPPORTED_SPEED_10GBPS |
3447 BE_SUPPORTED_SPEED_1GBPS;
3448 }
306f1348 3449 }
e51000db 3450 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
ee3cb629 3451err:
b7172414 3452 mutex_unlock(&adapter->mcc_lock);
ee3cb629
AK
3453 return status;
3454}
e1d18735 3455
bc0ee163 3456static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
e1d18735
AK
3457{
3458 struct be_mcc_wrb *wrb;
3459 struct be_cmd_req_set_qos *req;
3460 int status;
3461
b7172414 3462 mutex_lock(&adapter->mcc_lock);
e1d18735
AK
3463
3464 wrb = wrb_from_mccq(adapter);
3465 if (!wrb) {
3466 status = -EBUSY;
3467 goto err;
3468 }
3469
3470 req = embedded_payload(wrb);
3471
106df1e3 3472 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b 3473 OPCODE_COMMON_SET_QOS, sizeof(*req), wrb, NULL);
e1d18735
AK
3474
3475 req->hdr.domain = domain;
6bff57a7
AK
3476 req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC);
3477 req->max_bps_nic = cpu_to_le32(bps);
e1d18735
AK
3478
3479 status = be_mcc_notify_wait(adapter);
3480
3481err:
b7172414 3482 mutex_unlock(&adapter->mcc_lock);
e1d18735
AK
3483 return status;
3484}
9e1453c5
AK
3485
3486int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
3487{
3488 struct be_mcc_wrb *wrb;
3489 struct be_cmd_req_cntl_attribs *req;
3490 struct be_cmd_resp_cntl_attribs *resp;
a155a5db 3491 int status, i;
9e1453c5
AK
3492 int payload_len = max(sizeof(*req), sizeof(*resp));
3493 struct mgmt_controller_attrib *attribs;
3494 struct be_dma_mem attribs_cmd;
a155a5db 3495 u32 *serial_num;
9e1453c5 3496
d98ef50f
SR
3497 if (mutex_lock_interruptible(&adapter->mbox_lock))
3498 return -1;
3499
9e1453c5
AK
3500 memset(&attribs_cmd, 0, sizeof(struct be_dma_mem));
3501 attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs);
e51000db
SB
3502 attribs_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
3503 attribs_cmd.size,
3504 &attribs_cmd.dma, GFP_ATOMIC);
9e1453c5 3505 if (!attribs_cmd.va) {
a2cc4e0b 3506 dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
d98ef50f
SR
3507 status = -ENOMEM;
3508 goto err;
9e1453c5
AK
3509 }
3510
9e1453c5
AK
3511 wrb = wrb_from_mbox(adapter);
3512 if (!wrb) {
3513 status = -EBUSY;
3514 goto err;
3515 }
3516 req = attribs_cmd.va;
9e1453c5 3517
106df1e3 3518 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3519 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len,
3520 wrb, &attribs_cmd);
9e1453c5
AK
3521
3522 status = be_mbox_notify_wait(adapter);
3523 if (!status) {
43d620c8 3524 attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
9e1453c5 3525 adapter->hba_port_num = attribs->hba_attribs.phy_port;
a155a5db
SB
3526 serial_num = attribs->hba_attribs.controller_serial_number;
3527 for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
3528 adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
3529 (BIT_MASK(16) - 1);
9e1453c5
AK
3530 }
3531
3532err:
3533 mutex_unlock(&adapter->mbox_lock);
d98ef50f 3534 if (attribs_cmd.va)
e51000db
SB
3535 dma_free_coherent(&adapter->pdev->dev, attribs_cmd.size,
3536 attribs_cmd.va, attribs_cmd.dma);
9e1453c5
AK
3537 return status;
3538}
2e588f84
SP
3539
3540/* Uses mbox */
2dc1deb6 3541int be_cmd_req_native_mode(struct be_adapter *adapter)
2e588f84
SP
3542{
3543 struct be_mcc_wrb *wrb;
3544 struct be_cmd_req_set_func_cap *req;
3545 int status;
3546
3547 if (mutex_lock_interruptible(&adapter->mbox_lock))
3548 return -1;
3549
3550 wrb = wrb_from_mbox(adapter);
3551 if (!wrb) {
3552 status = -EBUSY;
3553 goto err;
3554 }
3555
3556 req = embedded_payload(wrb);
3557
106df1e3 3558 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3559 OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP,
3560 sizeof(*req), wrb, NULL);
2e588f84
SP
3561
3562 req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS |
3563 CAPABILITY_BE3_NATIVE_ERX_API);
3564 req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API);
3565
3566 status = be_mbox_notify_wait(adapter);
3567 if (!status) {
3568 struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
03d28ffe 3569
2e588f84
SP
3570 adapter->be3_native = le32_to_cpu(resp->cap_flags) &
3571 CAPABILITY_BE3_NATIVE_ERX_API;
d379142b
SP
3572 if (!adapter->be3_native)
3573 dev_warn(&adapter->pdev->dev,
3574 "adapter not in advanced mode\n");
2e588f84
SP
3575 }
3576err:
3577 mutex_unlock(&adapter->mbox_lock);
3578 return status;
3579}
590c391d 3580
f25b119c
PR
3581/* Get privilege(s) for a function */
3582int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
3583 u32 domain)
3584{
3585 struct be_mcc_wrb *wrb;
3586 struct be_cmd_req_get_fn_privileges *req;
3587 int status;
3588
b7172414 3589 mutex_lock(&adapter->mcc_lock);
f25b119c
PR
3590
3591 wrb = wrb_from_mccq(adapter);
3592 if (!wrb) {
3593 status = -EBUSY;
3594 goto err;
3595 }
3596
3597 req = embedded_payload(wrb);
3598
3599 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3600 OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req),
3601 wrb, NULL);
3602
3603 req->hdr.domain = domain;
3604
3605 status = be_mcc_notify_wait(adapter);
3606 if (!status) {
3607 struct be_cmd_resp_get_fn_privileges *resp =
3608 embedded_payload(wrb);
03d28ffe 3609
f25b119c 3610 *privilege = le32_to_cpu(resp->privilege_mask);
02308d74
SR
3611
3612 /* In UMC mode FW does not return right privileges.
3613 * Override with correct privilege equivalent to PF.
3614 */
3615 if (BEx_chip(adapter) && be_is_mc(adapter) &&
3616 be_physfn(adapter))
3617 *privilege = MAX_PRIVILEGES;
f25b119c
PR
3618 }
3619
3620err:
b7172414 3621 mutex_unlock(&adapter->mcc_lock);
f25b119c
PR
3622 return status;
3623}
3624
04a06028
SP
3625/* Set privilege(s) for a function */
3626int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
3627 u32 domain)
3628{
3629 struct be_mcc_wrb *wrb;
3630 struct be_cmd_req_set_fn_privileges *req;
3631 int status;
3632
b7172414 3633 mutex_lock(&adapter->mcc_lock);
04a06028
SP
3634
3635 wrb = wrb_from_mccq(adapter);
3636 if (!wrb) {
3637 status = -EBUSY;
3638 goto err;
3639 }
3640
3641 req = embedded_payload(wrb);
3642 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3643 OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req),
3644 wrb, NULL);
3645 req->hdr.domain = domain;
3646 if (lancer_chip(adapter))
3647 req->privileges_lancer = cpu_to_le32(privileges);
3648 else
3649 req->privileges = cpu_to_le32(privileges);
3650
3651 status = be_mcc_notify_wait(adapter);
3652err:
b7172414 3653 mutex_unlock(&adapter->mcc_lock);
04a06028
SP
3654 return status;
3655}
3656
5a712c13
SP
3657/* pmac_id_valid: true => pmac_id is supplied and MAC address is requested.
3658 * pmac_id_valid: false => pmac_id or MAC address is requested.
3659 * If pmac_id is returned, pmac_id_valid is returned as true
3660 */
1578e777 3661int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
b188f090
SR
3662 bool *pmac_id_valid, u32 *pmac_id, u32 if_handle,
3663 u8 domain)
590c391d
PR
3664{
3665 struct be_mcc_wrb *wrb;
3666 struct be_cmd_req_get_mac_list *req;
3667 int status;
3668 int mac_count;
e5e1ee89
PR
3669 struct be_dma_mem get_mac_list_cmd;
3670 int i;
3671
3672 memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
3673 get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
e51000db
SB
3674 get_mac_list_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
3675 get_mac_list_cmd.size,
3676 &get_mac_list_cmd.dma,
3677 GFP_ATOMIC);
e5e1ee89
PR
3678
3679 if (!get_mac_list_cmd.va) {
3680 dev_err(&adapter->pdev->dev,
a2cc4e0b 3681 "Memory allocation failure during GET_MAC_LIST\n");
e5e1ee89
PR
3682 return -ENOMEM;
3683 }
590c391d 3684
b7172414 3685 mutex_lock(&adapter->mcc_lock);
590c391d
PR
3686
3687 wrb = wrb_from_mccq(adapter);
3688 if (!wrb) {
3689 status = -EBUSY;
e5e1ee89 3690 goto out;
590c391d 3691 }
e5e1ee89
PR
3692
3693 req = get_mac_list_cmd.va;
590c391d
PR
3694
3695 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
bf591f51
SP
3696 OPCODE_COMMON_GET_MAC_LIST,
3697 get_mac_list_cmd.size, wrb, &get_mac_list_cmd);
590c391d 3698 req->hdr.domain = domain;
e5e1ee89 3699 req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
5a712c13
SP
3700 if (*pmac_id_valid) {
3701 req->mac_id = cpu_to_le32(*pmac_id);
b188f090 3702 req->iface_id = cpu_to_le16(if_handle);
5a712c13
SP
3703 req->perm_override = 0;
3704 } else {
3705 req->perm_override = 1;
3706 }
590c391d
PR
3707
3708 status = be_mcc_notify_wait(adapter);
3709 if (!status) {
3710 struct be_cmd_resp_get_mac_list *resp =
e5e1ee89 3711 get_mac_list_cmd.va;
5a712c13
SP
3712
3713 if (*pmac_id_valid) {
3714 memcpy(mac, resp->macid_macaddr.mac_addr_id.macaddr,
3715 ETH_ALEN);
3716 goto out;
3717 }
3718
e5e1ee89
PR
3719 mac_count = resp->true_mac_count + resp->pseudo_mac_count;
3720 /* Mac list returned could contain one or more active mac_ids
dbedd44e 3721 * or one or more true or pseudo permanent mac addresses.
1578e777
PR
3722 * If an active mac_id is present, return first active mac_id
3723 * found.
e5e1ee89 3724 */
590c391d 3725 for (i = 0; i < mac_count; i++) {
e5e1ee89
PR
3726 struct get_list_macaddr *mac_entry;
3727 u16 mac_addr_size;
3728 u32 mac_id;
3729
3730 mac_entry = &resp->macaddr_list[i];
3731 mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
3732 /* mac_id is a 32 bit value and mac_addr size
3733 * is 6 bytes
3734 */
3735 if (mac_addr_size == sizeof(u32)) {
5a712c13 3736 *pmac_id_valid = true;
e5e1ee89
PR
3737 mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
3738 *pmac_id = le32_to_cpu(mac_id);
3739 goto out;
590c391d 3740 }
590c391d 3741 }
1578e777 3742 /* If no active mac_id found, return first mac addr */
5a712c13 3743 *pmac_id_valid = false;
e5e1ee89 3744 memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
a2cc4e0b 3745 ETH_ALEN);
590c391d
PR
3746 }
3747
e5e1ee89 3748out:
b7172414 3749 mutex_unlock(&adapter->mcc_lock);
e51000db
SB
3750 dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size,
3751 get_mac_list_cmd.va, get_mac_list_cmd.dma);
590c391d
PR
3752 return status;
3753}
3754
a2cc4e0b
SP
3755int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id,
3756 u8 *mac, u32 if_handle, bool active, u32 domain)
5a712c13 3757{
b188f090
SR
3758 if (!active)
3759 be_cmd_get_mac_from_list(adapter, mac, &active, &curr_pmac_id,
3760 if_handle, domain);
3175d8c2 3761 if (BEx_chip(adapter))
5a712c13 3762 return be_cmd_mac_addr_query(adapter, mac, false,
b188f090 3763 if_handle, curr_pmac_id);
3175d8c2
SP
3764 else
3765 /* Fetch the MAC address using pmac_id */
3766 return be_cmd_get_mac_from_list(adapter, mac, &active,
b188f090
SR
3767 &curr_pmac_id,
3768 if_handle, domain);
5a712c13
SP
3769}
3770
95046b92
SP
3771int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
3772{
3773 int status;
3774 bool pmac_valid = false;
3775
c7bf7169 3776 eth_zero_addr(mac);
95046b92 3777
3175d8c2
SP
3778 if (BEx_chip(adapter)) {
3779 if (be_physfn(adapter))
3780 status = be_cmd_mac_addr_query(adapter, mac, true, 0,
3781 0);
3782 else
3783 status = be_cmd_mac_addr_query(adapter, mac, false,
3784 adapter->if_handle, 0);
3785 } else {
95046b92 3786 status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
b188f090 3787 NULL, adapter->if_handle, 0);
3175d8c2
SP
3788 }
3789
95046b92
SP
3790 return status;
3791}
3792
590c391d
PR
3793/* Uses synchronous MCCQ */
3794int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
3795 u8 mac_count, u32 domain)
3796{
3797 struct be_mcc_wrb *wrb;
3798 struct be_cmd_req_set_mac_list *req;
3799 int status;
3800 struct be_dma_mem cmd;
3801
3802 memset(&cmd, 0, sizeof(struct be_dma_mem));
3803 cmd.size = sizeof(struct be_cmd_req_set_mac_list);
e51000db
SB
3804 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
3805 GFP_KERNEL);
d0320f75 3806 if (!cmd.va)
590c391d 3807 return -ENOMEM;
590c391d 3808
b7172414 3809 mutex_lock(&adapter->mcc_lock);
590c391d
PR
3810
3811 wrb = wrb_from_mccq(adapter);
3812 if (!wrb) {
3813 status = -EBUSY;
3814 goto err;
3815 }
3816
3817 req = cmd.va;
3818 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3819 OPCODE_COMMON_SET_MAC_LIST, sizeof(*req),
3820 wrb, &cmd);
590c391d
PR
3821
3822 req->hdr.domain = domain;
3823 req->mac_count = mac_count;
3824 if (mac_count)
3825 memcpy(req->mac, mac_array, ETH_ALEN*mac_count);
3826
3827 status = be_mcc_notify_wait(adapter);
3828
3829err:
a2cc4e0b 3830 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
b7172414 3831 mutex_unlock(&adapter->mcc_lock);
590c391d
PR
3832 return status;
3833}
4762f6ce 3834
3175d8c2
SP
3835/* Wrapper to delete any active MACs and provision the new mac.
3836 * Changes to MAC_LIST are allowed iff none of the MAC addresses in the
3837 * current list are active.
3838 */
3839int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
3840{
3841 bool active_mac = false;
3842 u8 old_mac[ETH_ALEN];
3843 u32 pmac_id;
3844 int status;
3845
3846 status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
b188f090
SR
3847 &pmac_id, if_id, dom);
3848
3175d8c2
SP
3849 if (!status && active_mac)
3850 be_cmd_pmac_del(adapter, if_id, pmac_id, dom);
3851
3852 return be_cmd_set_mac_list(adapter, mac, mac ? 1 : 0, dom);
3853}
3854
f1f3ee1b 3855int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
e7bcbd7b 3856 u32 domain, u16 intf_id, u16 hsw_mode, u8 spoofchk)
f1f3ee1b
AK
3857{
3858 struct be_mcc_wrb *wrb;
3859 struct be_cmd_req_set_hsw_config *req;
3860 void *ctxt;
3861 int status;
3862
884476be
SK
3863 if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_HSW_CONFIG,
3864 CMD_SUBSYSTEM_COMMON))
3865 return -EPERM;
3866
b7172414 3867 mutex_lock(&adapter->mcc_lock);
f1f3ee1b
AK
3868
3869 wrb = wrb_from_mccq(adapter);
3870 if (!wrb) {
3871 status = -EBUSY;
3872 goto err;
3873 }
3874
3875 req = embedded_payload(wrb);
3876 ctxt = &req->context;
3877
3878 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3879 OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb,
3880 NULL);
f1f3ee1b
AK
3881
3882 req->hdr.domain = domain;
3883 AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
3884 if (pvid) {
3885 AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
3886 AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
3887 }
884476be 3888 if (hsw_mode) {
a77dcb8c
AK
3889 AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
3890 ctxt, adapter->hba_port_num);
3891 AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
3892 AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
3893 ctxt, hsw_mode);
3894 }
f1f3ee1b 3895
e7bcbd7b
KA
3896 /* Enable/disable both mac and vlan spoof checking */
3897 if (!BEx_chip(adapter) && spoofchk) {
3898 AMAP_SET_BITS(struct amap_set_hsw_context, mac_spoofchk,
3899 ctxt, spoofchk);
3900 AMAP_SET_BITS(struct amap_set_hsw_context, vlan_spoofchk,
3901 ctxt, spoofchk);
3902 }
3903
f1f3ee1b
AK
3904 be_dws_cpu_to_le(req->context, sizeof(req->context));
3905 status = be_mcc_notify_wait(adapter);
3906
3907err:
b7172414 3908 mutex_unlock(&adapter->mcc_lock);
f1f3ee1b
AK
3909 return status;
3910}
3911
3912/* Get Hyper switch config */
3913int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
e7bcbd7b 3914 u32 domain, u16 intf_id, u8 *mode, bool *spoofchk)
f1f3ee1b
AK
3915{
3916 struct be_mcc_wrb *wrb;
3917 struct be_cmd_req_get_hsw_config *req;
3918 void *ctxt;
3919 int status;
3920 u16 vid;
3921
b7172414 3922 mutex_lock(&adapter->mcc_lock);
f1f3ee1b
AK
3923
3924 wrb = wrb_from_mccq(adapter);
3925 if (!wrb) {
3926 status = -EBUSY;
3927 goto err;
3928 }
3929
3930 req = embedded_payload(wrb);
3931 ctxt = &req->context;
3932
3933 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
a2cc4e0b
SP
3934 OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb,
3935 NULL);
f1f3ee1b
AK
3936
3937 req->hdr.domain = domain;
a77dcb8c
AK
3938 AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3939 ctxt, intf_id);
f1f3ee1b 3940 AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
a77dcb8c 3941
2c07c1d7 3942 if (!BEx_chip(adapter) && mode) {
a77dcb8c
AK
3943 AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3944 ctxt, adapter->hba_port_num);
3945 AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
3946 }
f1f3ee1b
AK
3947 be_dws_cpu_to_le(req->context, sizeof(req->context));
3948
3949 status = be_mcc_notify_wait(adapter);
3950 if (!status) {
3951 struct be_cmd_resp_get_hsw_config *resp =
3952 embedded_payload(wrb);
03d28ffe 3953
a2cc4e0b 3954 be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
f1f3ee1b 3955 vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
a2cc4e0b 3956 pvid, &resp->context);
a77dcb8c
AK
3957 if (pvid)
3958 *pvid = le16_to_cpu(vid);
3959 if (mode)
3960 *mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3961 port_fwd_type, &resp->context);
e7bcbd7b
KA
3962 if (spoofchk)
3963 *spoofchk =
3964 AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3965 spoofchk, &resp->context);
f1f3ee1b
AK
3966 }
3967
3968err:
b7172414 3969 mutex_unlock(&adapter->mcc_lock);
f1f3ee1b
AK
3970 return status;
3971}
3972
f7062ee5
SP
3973static bool be_is_wol_excluded(struct be_adapter *adapter)
3974{
3975 struct pci_dev *pdev = adapter->pdev;
3976
18c57c74 3977 if (be_virtfn(adapter))
f7062ee5
SP
3978 return true;
3979
3980 switch (pdev->subsystem_device) {
3981 case OC_SUBSYS_DEVICE_ID1:
3982 case OC_SUBSYS_DEVICE_ID2:
3983 case OC_SUBSYS_DEVICE_ID3:
3984 case OC_SUBSYS_DEVICE_ID4:
3985 return true;
3986 default:
3987 return false;
3988 }
3989}
3990
4762f6ce
AK
3991int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
3992{
3993 struct be_mcc_wrb *wrb;
3994 struct be_cmd_req_acpi_wol_magic_config_v1 *req;
76a9e08e 3995 int status = 0;
4762f6ce
AK
3996 struct be_dma_mem cmd;
3997
f25b119c
PR
3998 if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
3999 CMD_SUBSYSTEM_ETH))
4000 return -EPERM;
4001
76a9e08e
SR
4002 if (be_is_wol_excluded(adapter))
4003 return status;
4004
d98ef50f
SR
4005 if (mutex_lock_interruptible(&adapter->mbox_lock))
4006 return -1;
4007
4762f6ce
AK
4008 memset(&cmd, 0, sizeof(struct be_dma_mem));
4009 cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
e51000db
SB
4010 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
4011 GFP_ATOMIC);
4762f6ce 4012 if (!cmd.va) {
a2cc4e0b 4013 dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
d98ef50f
SR
4014 status = -ENOMEM;
4015 goto err;
4762f6ce
AK
4016 }
4017
4762f6ce
AK
4018 wrb = wrb_from_mbox(adapter);
4019 if (!wrb) {
4020 status = -EBUSY;
4021 goto err;
4022 }
4023
4024 req = cmd.va;
4025
4026 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
4027 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
76a9e08e 4028 sizeof(*req), wrb, &cmd);
4762f6ce
AK
4029
4030 req->hdr.version = 1;
4031 req->query_options = BE_GET_WOL_CAP;
4032
4033 status = be_mbox_notify_wait(adapter);
4034 if (!status) {
4035 struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
03d28ffe 4036
504fbf1e 4037 resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *)cmd.va;
4762f6ce 4038
4762f6ce 4039 adapter->wol_cap = resp->wol_settings;
45f13df7
SB
4040
4041 /* Non-zero macaddr indicates WOL is enabled */
4042 if (adapter->wol_cap & BE_WOL_CAP &&
4043 !is_zero_ether_addr(resp->magic_mac))
76a9e08e 4044 adapter->wol_en = true;
4762f6ce
AK
4045 }
4046err:
4047 mutex_unlock(&adapter->mbox_lock);
d98ef50f 4048 if (cmd.va)
e51000db
SB
4049 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
4050 cmd.dma);
4762f6ce 4051 return status;
941a77d5
SK
4052
4053}
baaa08d1
VV
4054
4055int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level)
4056{
4057 struct be_dma_mem extfat_cmd;
4058 struct be_fat_conf_params *cfgs;
4059 int status;
4060 int i, j;
4061
4062 memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
4063 extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
e51000db
SB
4064 extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
4065 extfat_cmd.size, &extfat_cmd.dma,
4066 GFP_ATOMIC);
baaa08d1
VV
4067 if (!extfat_cmd.va)
4068 return -ENOMEM;
4069
4070 status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
4071 if (status)
4072 goto err;
4073
4074 cfgs = (struct be_fat_conf_params *)
4075 (extfat_cmd.va + sizeof(struct be_cmd_resp_hdr));
4076 for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
4077 u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
03d28ffe 4078
baaa08d1
VV
4079 for (j = 0; j < num_modes; j++) {
4080 if (cfgs->module[i].trace_lvl[j].mode == MODE_UART)
4081 cfgs->module[i].trace_lvl[j].dbg_lvl =
4082 cpu_to_le32(level);
4083 }
4084 }
4085
4086 status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs);
4087err:
e51000db
SB
4088 dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va,
4089 extfat_cmd.dma);
baaa08d1
VV
4090 return status;
4091}
4092
4093int be_cmd_get_fw_log_level(struct be_adapter *adapter)
4094{
4095 struct be_dma_mem extfat_cmd;
4096 struct be_fat_conf_params *cfgs;
4097 int status, j;
4098 int level = 0;
4099
4100 memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
4101 extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
e51000db
SB
4102 extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
4103 extfat_cmd.size, &extfat_cmd.dma,
4104 GFP_ATOMIC);
baaa08d1
VV
4105
4106 if (!extfat_cmd.va) {
4107 dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
4108 __func__);
4109 goto err;
4110 }
4111
4112 status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
4113 if (!status) {
4114 cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
4115 sizeof(struct be_cmd_resp_hdr));
03d28ffe 4116
baaa08d1
VV
4117 for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
4118 if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
4119 level = cfgs->module[0].trace_lvl[j].dbg_lvl;
4120 }
4121 }
e51000db
SB
4122 dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va,
4123 extfat_cmd.dma);
baaa08d1
VV
4124err:
4125 return level;
4126}
4127
941a77d5
SK
4128int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
4129 struct be_dma_mem *cmd)
4130{
4131 struct be_mcc_wrb *wrb;
4132 struct be_cmd_req_get_ext_fat_caps *req;
4133 int status;
4134
62259ac4
SK
4135 if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
4136 CMD_SUBSYSTEM_COMMON))
4137 return -EPERM;
4138
941a77d5
SK
4139 if (mutex_lock_interruptible(&adapter->mbox_lock))
4140 return -1;
4141
4142 wrb = wrb_from_mbox(adapter);
4143 if (!wrb) {
4144 status = -EBUSY;
4145 goto err;
4146 }
4147
4148 req = cmd->va;
4149 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
62259ac4 4150 OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
941a77d5
SK
4151 cmd->size, wrb, cmd);
4152 req->parameter_type = cpu_to_le32(1);
4153
4154 status = be_mbox_notify_wait(adapter);
4155err:
4156 mutex_unlock(&adapter->mbox_lock);
4157 return status;
4158}
4159
4160int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
4161 struct be_dma_mem *cmd,
4162 struct be_fat_conf_params *configs)
4163{
4164 struct be_mcc_wrb *wrb;
4165 struct be_cmd_req_set_ext_fat_caps *req;
4166 int status;
4167
b7172414 4168 mutex_lock(&adapter->mcc_lock);
941a77d5
SK
4169
4170 wrb = wrb_from_mccq(adapter);
4171 if (!wrb) {
4172 status = -EBUSY;
4173 goto err;
4174 }
4175
4176 req = cmd->va;
4177 memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
4178 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
62259ac4 4179 OPCODE_COMMON_SET_EXT_FAT_CAPABILITIES,
941a77d5
SK
4180 cmd->size, wrb, cmd);
4181
4182 status = be_mcc_notify_wait(adapter);
4183err:
b7172414 4184 mutex_unlock(&adapter->mcc_lock);
941a77d5 4185 return status;
4762f6ce 4186}
6a4ab669 4187
21252377 4188int be_cmd_query_port_name(struct be_adapter *adapter)
b4e32a71 4189{
b4e32a71 4190 struct be_cmd_req_get_port_name *req;
21252377 4191 struct be_mcc_wrb *wrb;
b4e32a71
PR
4192 int status;
4193
21252377
VV
4194 if (mutex_lock_interruptible(&adapter->mbox_lock))
4195 return -1;
b4e32a71 4196
21252377 4197 wrb = wrb_from_mbox(adapter);
b4e32a71
PR
4198 req = embedded_payload(wrb);
4199
4200 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4201 OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
4202 NULL);
21252377
VV
4203 if (!BEx_chip(adapter))
4204 req->hdr.version = 1;
b4e32a71 4205
21252377 4206 status = be_mbox_notify_wait(adapter);
b4e32a71
PR
4207 if (!status) {
4208 struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
03d28ffe 4209
21252377 4210 adapter->port_name = resp->port_name[adapter->hba_port_num];
b4e32a71 4211 } else {
21252377 4212 adapter->port_name = adapter->hba_port_num + '0';
b4e32a71 4213 }
21252377
VV
4214
4215 mutex_unlock(&adapter->mbox_lock);
b4e32a71
PR
4216 return status;
4217}
4218
980df249
SR
4219/* When more than 1 NIC descriptor is present in the descriptor list,
4220 * the caller must specify the pf_num to obtain the NIC descriptor
4221 * corresponding to its pci function.
4222 * get_vft must be true when the caller wants the VF-template desc of the
4223 * PF-pool.
4224 * The pf_num should be set to PF_NUM_IGNORE when the caller knows
4225 * that only it's NIC descriptor is present in the descriptor list.
4226 */
10cccf60 4227static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
980df249 4228 bool get_vft, u8 pf_num)
abb93951 4229{
150d58c7 4230 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
10cccf60 4231 struct be_nic_res_desc *nic;
abb93951
PR
4232 int i;
4233
4234 for (i = 0; i < desc_count; i++) {
150d58c7 4235 if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
10cccf60
VV
4236 hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
4237 nic = (struct be_nic_res_desc *)hdr;
980df249
SR
4238
4239 if ((pf_num == PF_NUM_IGNORE ||
4240 nic->pf_num == pf_num) &&
4241 (!get_vft || nic->flags & BIT(VFT_SHIFT)))
10cccf60
VV
4242 return nic;
4243 }
150d58c7
VV
4244 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
4245 hdr = (void *)hdr + hdr->desc_len;
abb93951 4246 }
150d58c7
VV
4247 return NULL;
4248}
4249
980df249
SR
4250static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count,
4251 u8 pf_num)
10cccf60 4252{
980df249 4253 return be_get_nic_desc(buf, desc_count, true, pf_num);
10cccf60
VV
4254}
4255
980df249
SR
4256static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count,
4257 u8 pf_num)
10cccf60 4258{
980df249 4259 return be_get_nic_desc(buf, desc_count, false, pf_num);
10cccf60
VV
4260}
4261
980df249
SR
4262static struct be_pcie_res_desc *be_get_pcie_desc(u8 *buf, u32 desc_count,
4263 u8 pf_num)
150d58c7
VV
4264{
4265 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
4266 struct be_pcie_res_desc *pcie;
4267 int i;
4268
4269 for (i = 0; i < desc_count; i++) {
980df249
SR
4270 if (hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
4271 hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1) {
4272 pcie = (struct be_pcie_res_desc *)hdr;
4273 if (pcie->pf_num == pf_num)
150d58c7
VV
4274 return pcie;
4275 }
abb93951 4276
150d58c7
VV
4277 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
4278 hdr = (void *)hdr + hdr->desc_len;
4279 }
950e2958 4280 return NULL;
abb93951
PR
4281}
4282
f93f160b
VV
4283static struct be_port_res_desc *be_get_port_desc(u8 *buf, u32 desc_count)
4284{
4285 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
4286 int i;
4287
4288 for (i = 0; i < desc_count; i++) {
4289 if (hdr->desc_type == PORT_RESOURCE_DESC_TYPE_V1)
4290 return (struct be_port_res_desc *)hdr;
4291
4292 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
4293 hdr = (void *)hdr + hdr->desc_len;
4294 }
4295 return NULL;
4296}
4297
92bf14ab
SP
4298static void be_copy_nic_desc(struct be_resources *res,
4299 struct be_nic_res_desc *desc)
4300{
4301 res->max_uc_mac = le16_to_cpu(desc->unicast_mac_count);
4302 res->max_vlans = le16_to_cpu(desc->vlan_count);
4303 res->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
4304 res->max_tx_qs = le16_to_cpu(desc->txq_count);
4305 res->max_rss_qs = le16_to_cpu(desc->rssq_count);
4306 res->max_rx_qs = le16_to_cpu(desc->rq_count);
4307 res->max_evt_qs = le16_to_cpu(desc->eq_count);
f2858738
VV
4308 res->max_cq_count = le16_to_cpu(desc->cq_count);
4309 res->max_iface_count = le16_to_cpu(desc->iface_count);
4310 res->max_mcc_count = le16_to_cpu(desc->mcc_count);
92bf14ab
SP
4311 /* Clear flags that driver is not interested in */
4312 res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
4313 BE_IF_CAP_FLAGS_WANT;
92bf14ab
SP
4314}
4315
abb93951 4316/* Uses Mbox */
92bf14ab 4317int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
abb93951
PR
4318{
4319 struct be_mcc_wrb *wrb;
4320 struct be_cmd_req_get_func_config *req;
4321 int status;
4322 struct be_dma_mem cmd;
4323
d98ef50f
SR
4324 if (mutex_lock_interruptible(&adapter->mbox_lock))
4325 return -1;
4326
abb93951
PR
4327 memset(&cmd, 0, sizeof(struct be_dma_mem));
4328 cmd.size = sizeof(struct be_cmd_resp_get_func_config);
e51000db
SB
4329 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
4330 GFP_ATOMIC);
abb93951
PR
4331 if (!cmd.va) {
4332 dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
d98ef50f
SR
4333 status = -ENOMEM;
4334 goto err;
abb93951 4335 }
abb93951
PR
4336
4337 wrb = wrb_from_mbox(adapter);
4338 if (!wrb) {
4339 status = -EBUSY;
4340 goto err;
4341 }
4342
4343 req = cmd.va;
4344
4345 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4346 OPCODE_COMMON_GET_FUNC_CONFIG,
4347 cmd.size, wrb, &cmd);
4348
28710c55
KA
4349 if (skyhawk_chip(adapter))
4350 req->hdr.version = 1;
4351
abb93951
PR
4352 status = be_mbox_notify_wait(adapter);
4353 if (!status) {
4354 struct be_cmd_resp_get_func_config *resp = cmd.va;
4355 u32 desc_count = le32_to_cpu(resp->desc_count);
150d58c7 4356 struct be_nic_res_desc *desc;
abb93951 4357
980df249
SR
4358 /* GET_FUNC_CONFIG returns resource descriptors of the
4359 * current function only. So, pf_num should be set to
4360 * PF_NUM_IGNORE.
4361 */
4362 desc = be_get_func_nic_desc(resp->func_param, desc_count,
4363 PF_NUM_IGNORE);
abb93951
PR
4364 if (!desc) {
4365 status = -EINVAL;
4366 goto err;
4367 }
980df249
SR
4368
4369 /* Store pf_num & vf_num for later use in GET_PROFILE_CONFIG */
4370 adapter->pf_num = desc->pf_num;
4371 adapter->vf_num = desc->vf_num;
4372
4373 if (res)
4374 be_copy_nic_desc(res, desc);
abb93951
PR
4375 }
4376err:
4377 mutex_unlock(&adapter->mbox_lock);
d98ef50f 4378 if (cmd.va)
e51000db
SB
4379 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
4380 cmd.dma);
abb93951
PR
4381 return status;
4382}
4383
de2b1e03
SK
4384/* This routine returns a list of all the NIC PF_nums in the adapter */
4385u16 be_get_nic_pf_num_list(u8 *buf, u32 desc_count, u16 *nic_pf_nums)
4386{
4387 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
4388 struct be_pcie_res_desc *pcie = NULL;
4389 int i;
4390 u16 nic_pf_count = 0;
4391
4392 for (i = 0; i < desc_count; i++) {
4393 if (hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
4394 hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1) {
4395 pcie = (struct be_pcie_res_desc *)hdr;
4396 if (pcie->pf_state && (pcie->pf_type == MISSION_NIC ||
4397 pcie->pf_type == MISSION_RDMA)) {
4398 nic_pf_nums[nic_pf_count++] = pcie->pf_num;
4399 }
4400 }
4401
4402 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
4403 hdr = (void *)hdr + hdr->desc_len;
4404 }
4405 return nic_pf_count;
4406}
4407
980df249 4408/* Will use MBOX only if MCCQ has not been created */
92bf14ab 4409int be_cmd_get_profile_config(struct be_adapter *adapter,
de2b1e03
SK
4410 struct be_resources *res,
4411 struct be_port_resources *port_res,
4412 u8 profile_type, u8 query, u8 domain)
a05f99db 4413{
150d58c7 4414 struct be_cmd_resp_get_profile_config *resp;
ba48c0c9 4415 struct be_cmd_req_get_profile_config *req;
10cccf60 4416 struct be_nic_res_desc *vf_res;
150d58c7 4417 struct be_pcie_res_desc *pcie;
f93f160b 4418 struct be_port_res_desc *port;
150d58c7 4419 struct be_nic_res_desc *nic;
ba48c0c9 4420 struct be_mcc_wrb wrb = {0};
a05f99db 4421 struct be_dma_mem cmd;
f2858738 4422 u16 desc_count;
a05f99db
VV
4423 int status;
4424
4425 memset(&cmd, 0, sizeof(struct be_dma_mem));
150d58c7 4426 cmd.size = sizeof(struct be_cmd_resp_get_profile_config);
e51000db
SB
4427 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
4428 GFP_ATOMIC);
150d58c7 4429 if (!cmd.va)
a05f99db 4430 return -ENOMEM;
a05f99db 4431
ba48c0c9
VV
4432 req = cmd.va;
4433 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4434 OPCODE_COMMON_GET_PROFILE_CONFIG,
4435 cmd.size, &wrb, &cmd);
4436
ba48c0c9
VV
4437 if (!lancer_chip(adapter))
4438 req->hdr.version = 1;
de2b1e03 4439 req->type = profile_type;
72ef3a88 4440 req->hdr.domain = domain;
ba48c0c9 4441
f2858738
VV
4442 /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
4443 * descriptors with all bits set to "1" for the fields which can be
4444 * modified using SET_PROFILE_CONFIG cmd.
4445 */
4446 if (query == RESOURCE_MODIFIABLE)
4447 req->type |= QUERY_MODIFIABLE_FIELDS_TYPE;
4448
ba48c0c9 4449 status = be_cmd_notify_wait(adapter, &wrb);
150d58c7
VV
4450 if (status)
4451 goto err;
abb93951 4452
150d58c7 4453 resp = cmd.va;
f2858738 4454 desc_count = le16_to_cpu(resp->desc_count);
abb93951 4455
de2b1e03
SK
4456 if (port_res) {
4457 u16 nic_pf_cnt = 0, i;
4458 u16 nic_pf_num_list[MAX_NIC_FUNCS];
4459
4460 nic_pf_cnt = be_get_nic_pf_num_list(resp->func_param,
4461 desc_count,
4462 nic_pf_num_list);
4463
4464 for (i = 0; i < nic_pf_cnt; i++) {
4465 nic = be_get_func_nic_desc(resp->func_param, desc_count,
4466 nic_pf_num_list[i]);
4467 if (nic->link_param == adapter->port_num) {
4468 port_res->nic_pfs++;
4469 pcie = be_get_pcie_desc(resp->func_param,
4470 desc_count,
4471 nic_pf_num_list[i]);
4472 port_res->max_vfs += le16_to_cpu(pcie->num_vfs);
4473 }
4474 }
4475 return status;
4476 }
4477
980df249
SR
4478 pcie = be_get_pcie_desc(resp->func_param, desc_count,
4479 adapter->pf_num);
150d58c7 4480 if (pcie)
92bf14ab 4481 res->max_vfs = le16_to_cpu(pcie->num_vfs);
150d58c7 4482
f93f160b
VV
4483 port = be_get_port_desc(resp->func_param, desc_count);
4484 if (port)
4485 adapter->mc_type = port->mc_type;
4486
980df249
SR
4487 nic = be_get_func_nic_desc(resp->func_param, desc_count,
4488 adapter->pf_num);
92bf14ab
SP
4489 if (nic)
4490 be_copy_nic_desc(res, nic);
4491
980df249
SR
4492 vf_res = be_get_vft_desc(resp->func_param, desc_count,
4493 adapter->pf_num);
10cccf60
VV
4494 if (vf_res)
4495 res->vf_if_cap_flags = vf_res->cap_flags;
abb93951 4496err:
a05f99db 4497 if (cmd.va)
e51000db
SB
4498 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
4499 cmd.dma);
abb93951
PR
4500 return status;
4501}
4502
bec84e6b
VV
4503/* Will use MBOX only if MCCQ has not been created */
4504static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
4505 int size, int count, u8 version, u8 domain)
d5c18473 4506{
d5c18473 4507 struct be_cmd_req_set_profile_config *req;
bec84e6b
VV
4508 struct be_mcc_wrb wrb = {0};
4509 struct be_dma_mem cmd;
d5c18473
PR
4510 int status;
4511
bec84e6b
VV
4512 memset(&cmd, 0, sizeof(struct be_dma_mem));
4513 cmd.size = sizeof(struct be_cmd_req_set_profile_config);
e51000db
SB
4514 cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
4515 GFP_ATOMIC);
bec84e6b
VV
4516 if (!cmd.va)
4517 return -ENOMEM;
d5c18473 4518
bec84e6b 4519 req = cmd.va;
d5c18473 4520 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
bec84e6b
VV
4521 OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
4522 &wrb, &cmd);
a401801c 4523 req->hdr.version = version;
d5c18473 4524 req->hdr.domain = domain;
bec84e6b 4525 req->desc_count = cpu_to_le32(count);
a401801c
SP
4526 memcpy(req->desc, desc, size);
4527
bec84e6b
VV
4528 status = be_cmd_notify_wait(adapter, &wrb);
4529
4530 if (cmd.va)
e51000db
SB
4531 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
4532 cmd.dma);
d5c18473
PR
4533 return status;
4534}
4535
a401801c 4536/* Mark all fields invalid */
b9263cbf 4537void be_reset_nic_desc(struct be_nic_res_desc *nic)
a401801c
SP
4538{
4539 memset(nic, 0, sizeof(*nic));
4540 nic->unicast_mac_count = 0xFFFF;
4541 nic->mcc_count = 0xFFFF;
4542 nic->vlan_count = 0xFFFF;
4543 nic->mcast_mac_count = 0xFFFF;
4544 nic->txq_count = 0xFFFF;
4545 nic->rq_count = 0xFFFF;
4546 nic->rssq_count = 0xFFFF;
4547 nic->lro_count = 0xFFFF;
4548 nic->cq_count = 0xFFFF;
4549 nic->toe_conn_count = 0xFFFF;
4550 nic->eq_count = 0xFFFF;
0f77ba73 4551 nic->iface_count = 0xFFFF;
a401801c 4552 nic->link_param = 0xFF;
0f77ba73 4553 nic->channel_id_param = cpu_to_le16(0xF000);
a401801c
SP
4554 nic->acpi_params = 0xFF;
4555 nic->wol_param = 0x0F;
0f77ba73
RN
4556 nic->tunnel_iface_count = 0xFFFF;
4557 nic->direct_tenant_iface_count = 0xFFFF;
bec84e6b 4558 nic->bw_min = 0xFFFFFFFF;
a401801c
SP
4559 nic->bw_max = 0xFFFFFFFF;
4560}
4561
bec84e6b
VV
4562/* Mark all fields invalid */
4563static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
4564{
4565 memset(pcie, 0, sizeof(*pcie));
4566 pcie->sriov_state = 0xFF;
4567 pcie->pf_state = 0xFF;
4568 pcie->pf_type = 0xFF;
4569 pcie->num_vfs = 0xFFFF;
4570}
4571
0f77ba73
RN
4572int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
4573 u8 domain)
a401801c 4574{
0f77ba73
RN
4575 struct be_nic_res_desc nic_desc;
4576 u32 bw_percent;
4577 u16 version = 0;
4578
4579 if (BE3_chip(adapter))
4580 return be_cmd_set_qos(adapter, max_rate / 10, domain);
a401801c 4581
0f77ba73 4582 be_reset_nic_desc(&nic_desc);
980df249 4583 nic_desc.pf_num = adapter->pf_num;
0f77ba73 4584 nic_desc.vf_num = domain;
58bdeaa6 4585 nic_desc.bw_min = 0;
0f77ba73 4586 if (lancer_chip(adapter)) {
a401801c
SP
4587 nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
4588 nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
4589 nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
4590 (1 << NOSV_SHIFT);
0f77ba73 4591 nic_desc.bw_max = cpu_to_le32(max_rate / 10);
a401801c 4592 } else {
0f77ba73
RN
4593 version = 1;
4594 nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
4595 nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
4596 nic_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
4597 bw_percent = max_rate ? (max_rate * 100) / link_speed : 100;
4598 nic_desc.bw_max = cpu_to_le32(bw_percent);
a401801c 4599 }
0f77ba73
RN
4600
4601 return be_cmd_set_profile_config(adapter, &nic_desc,
4602 nic_desc.hdr.desc_len,
bec84e6b
VV
4603 1, version, domain);
4604}
4605
4606int be_cmd_set_sriov_config(struct be_adapter *adapter,
f2858738 4607 struct be_resources pool_res, u16 num_vfs,
b9263cbf 4608 struct be_resources *vft_res)
bec84e6b
VV
4609{
4610 struct {
4611 struct be_pcie_res_desc pcie;
4612 struct be_nic_res_desc nic_vft;
4613 } __packed desc;
bec84e6b 4614
bec84e6b
VV
4615 /* PF PCIE descriptor */
4616 be_reset_pcie_desc(&desc.pcie);
4617 desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
4618 desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
f2858738 4619 desc.pcie.flags = BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
bec84e6b
VV
4620 desc.pcie.pf_num = adapter->pdev->devfn;
4621 desc.pcie.sriov_state = num_vfs ? 1 : 0;
4622 desc.pcie.num_vfs = cpu_to_le16(num_vfs);
4623
4624 /* VF NIC Template descriptor */
4625 be_reset_nic_desc(&desc.nic_vft);
4626 desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
4627 desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
b9263cbf
SR
4628 desc.nic_vft.flags = vft_res->flags | BIT(VFT_SHIFT) |
4629 BIT(IMM_SHIFT) | BIT(NOSV_SHIFT);
bec84e6b
VV
4630 desc.nic_vft.pf_num = adapter->pdev->devfn;
4631 desc.nic_vft.vf_num = 0;
b9263cbf
SR
4632 desc.nic_vft.cap_flags = cpu_to_le32(vft_res->vf_if_cap_flags);
4633 desc.nic_vft.rq_count = cpu_to_le16(vft_res->max_rx_qs);
4634 desc.nic_vft.txq_count = cpu_to_le16(vft_res->max_tx_qs);
4635 desc.nic_vft.rssq_count = cpu_to_le16(vft_res->max_rss_qs);
4636 desc.nic_vft.cq_count = cpu_to_le16(vft_res->max_cq_count);
4637
4638 if (vft_res->max_uc_mac)
4639 desc.nic_vft.unicast_mac_count =
4640 cpu_to_le16(vft_res->max_uc_mac);
4641 if (vft_res->max_vlans)
4642 desc.nic_vft.vlan_count = cpu_to_le16(vft_res->max_vlans);
4643 if (vft_res->max_iface_count)
4644 desc.nic_vft.iface_count =
4645 cpu_to_le16(vft_res->max_iface_count);
4646 if (vft_res->max_mcc_count)
4647 desc.nic_vft.mcc_count = cpu_to_le16(vft_res->max_mcc_count);
bec84e6b
VV
4648
4649 return be_cmd_set_profile_config(adapter, &desc,
4650 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
a401801c
SP
4651}
4652
4653int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
4654{
4655 struct be_mcc_wrb *wrb;
4656 struct be_cmd_req_manage_iface_filters *req;
4657 int status;
4658
4659 if (iface == 0xFFFFFFFF)
4660 return -1;
4661
b7172414 4662 mutex_lock(&adapter->mcc_lock);
a401801c
SP
4663
4664 wrb = wrb_from_mccq(adapter);
4665 if (!wrb) {
4666 status = -EBUSY;
4667 goto err;
4668 }
4669 req = embedded_payload(wrb);
4670
4671 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4672 OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req),
4673 wrb, NULL);
4674 req->op = op;
4675 req->target_iface_id = cpu_to_le32(iface);
4676
4677 status = be_mcc_notify_wait(adapter);
4678err:
b7172414 4679 mutex_unlock(&adapter->mcc_lock);
a401801c
SP
4680 return status;
4681}
4682
4683int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
4684{
4685 struct be_port_res_desc port_desc;
4686
4687 memset(&port_desc, 0, sizeof(port_desc));
4688 port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1;
4689 port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
4690 port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
4691 port_desc.link_num = adapter->hba_port_num;
4692 if (port) {
4693 port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) |
4694 (1 << RCVID_SHIFT);
4695 port_desc.nv_port = swab16(port);
4696 } else {
4697 port_desc.nv_flags = NV_TYPE_DISABLED;
4698 port_desc.nv_port = 0;
4699 }
4700
4701 return be_cmd_set_profile_config(adapter, &port_desc,
bec84e6b 4702 RESOURCE_DESC_SIZE_V1, 1, 1, 0);
a401801c
SP
4703}
4704
4c876616
SP
4705int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
4706 int vf_num)
4707{
4708 struct be_mcc_wrb *wrb;
4709 struct be_cmd_req_get_iface_list *req;
4710 struct be_cmd_resp_get_iface_list *resp;
4711 int status;
4712
b7172414 4713 mutex_lock(&adapter->mcc_lock);
4c876616
SP
4714
4715 wrb = wrb_from_mccq(adapter);
4716 if (!wrb) {
4717 status = -EBUSY;
4718 goto err;
4719 }
4720 req = embedded_payload(wrb);
4721
4722 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4723 OPCODE_COMMON_GET_IFACE_LIST, sizeof(*resp),
4724 wrb, NULL);
4725 req->hdr.domain = vf_num + 1;
4726
4727 status = be_mcc_notify_wait(adapter);
4728 if (!status) {
4729 resp = (struct be_cmd_resp_get_iface_list *)req;
4730 vf_cfg->if_handle = le32_to_cpu(resp->if_desc.if_id);
4731 }
4732
4733err:
b7172414 4734 mutex_unlock(&adapter->mcc_lock);
4c876616
SP
4735 return status;
4736}
4737
5c510811
SK
4738static int lancer_wait_idle(struct be_adapter *adapter)
4739{
4740#define SLIPORT_IDLE_TIMEOUT 30
4741 u32 reg_val;
4742 int status = 0, i;
4743
4744 for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
4745 reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
4746 if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
4747 break;
4748
4749 ssleep(1);
4750 }
4751
4752 if (i == SLIPORT_IDLE_TIMEOUT)
4753 status = -1;
4754
4755 return status;
4756}
4757
4758int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
4759{
4760 int status = 0;
4761
4762 status = lancer_wait_idle(adapter);
4763 if (status)
4764 return status;
4765
4766 iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);
4767
4768 return status;
4769}
4770
4771/* Routine to check whether dump image is present or not */
4772bool dump_present(struct be_adapter *adapter)
4773{
4774 u32 sliport_status = 0;
4775
4776 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
4777 return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
4778}
4779
4780int lancer_initiate_dump(struct be_adapter *adapter)
4781{
f0613380 4782 struct device *dev = &adapter->pdev->dev;
5c510811
SK
4783 int status;
4784
f0613380
KA
4785 if (dump_present(adapter)) {
4786 dev_info(dev, "Previous dump not cleared, not forcing dump\n");
4787 return -EEXIST;
4788 }
4789
5c510811
SK
4790 /* give firmware reset and diagnostic dump */
4791 status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
4792 PHYSDEV_CONTROL_DD_MASK);
4793 if (status < 0) {
f0613380 4794 dev_err(dev, "FW reset failed\n");
5c510811
SK
4795 return status;
4796 }
4797
4798 status = lancer_wait_idle(adapter);
4799 if (status)
4800 return status;
4801
4802 if (!dump_present(adapter)) {
f0613380
KA
4803 dev_err(dev, "FW dump not generated\n");
4804 return -EIO;
5c510811
SK
4805 }
4806
4807 return 0;
4808}
4809
f0613380
KA
4810int lancer_delete_dump(struct be_adapter *adapter)
4811{
4812 int status;
4813
4814 status = lancer_cmd_delete_object(adapter, LANCER_FW_DUMP_FILE);
4815 return be_cmd_status(status);
4816}
4817
dcf7ebba
PR
4818/* Uses sync mcc */
4819int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
4820{
4821 struct be_mcc_wrb *wrb;
4822 struct be_cmd_enable_disable_vf *req;
4823 int status;
4824
0599863d 4825 if (BEx_chip(adapter))
dcf7ebba
PR
4826 return 0;
4827
b7172414 4828 mutex_lock(&adapter->mcc_lock);
dcf7ebba
PR
4829
4830 wrb = wrb_from_mccq(adapter);
4831 if (!wrb) {
4832 status = -EBUSY;
4833 goto err;
4834 }
4835
4836 req = embedded_payload(wrb);
4837
4838 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4839 OPCODE_COMMON_ENABLE_DISABLE_VF, sizeof(*req),
4840 wrb, NULL);
4841
4842 req->hdr.domain = domain;
4843 req->enable = 1;
4844 status = be_mcc_notify_wait(adapter);
4845err:
b7172414 4846 mutex_unlock(&adapter->mcc_lock);
dcf7ebba
PR
4847 return status;
4848}
4849
68c45a2d
SK
4850int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
4851{
4852 struct be_mcc_wrb *wrb;
4853 struct be_cmd_req_intr_set *req;
4854 int status;
4855
4856 if (mutex_lock_interruptible(&adapter->mbox_lock))
4857 return -1;
4858
4859 wrb = wrb_from_mbox(adapter);
4860
4861 req = embedded_payload(wrb);
4862
4863 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4864 OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req),
4865 wrb, NULL);
4866
4867 req->intr_enabled = intr_enable;
4868
4869 status = be_mbox_notify_wait(adapter);
4870
4871 mutex_unlock(&adapter->mbox_lock);
4872 return status;
4873}
4874
542963b7
VV
4875/* Uses MBOX */
4876int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile_id)
4877{
4878 struct be_cmd_req_get_active_profile *req;
4879 struct be_mcc_wrb *wrb;
4880 int status;
4881
4882 if (mutex_lock_interruptible(&adapter->mbox_lock))
4883 return -1;
4884
4885 wrb = wrb_from_mbox(adapter);
4886 if (!wrb) {
4887 status = -EBUSY;
4888 goto err;
4889 }
4890
4891 req = embedded_payload(wrb);
4892
4893 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4894 OPCODE_COMMON_GET_ACTIVE_PROFILE, sizeof(*req),
4895 wrb, NULL);
4896
4897 status = be_mbox_notify_wait(adapter);
4898 if (!status) {
4899 struct be_cmd_resp_get_active_profile *resp =
4900 embedded_payload(wrb);
03d28ffe 4901
542963b7
VV
4902 *profile_id = le16_to_cpu(resp->active_profile_id);
4903 }
4904
4905err:
4906 mutex_unlock(&adapter->mbox_lock);
4907 return status;
4908}
4909
d9d426af
SR
4910int __be_cmd_set_logical_link_config(struct be_adapter *adapter,
4911 int link_state, int version, u8 domain)
bdce2ad7
SR
4912{
4913 struct be_mcc_wrb *wrb;
4914 struct be_cmd_req_set_ll_link *req;
4915 int status;
4916
b7172414 4917 mutex_lock(&adapter->mcc_lock);
bdce2ad7
SR
4918
4919 wrb = wrb_from_mccq(adapter);
4920 if (!wrb) {
4921 status = -EBUSY;
4922 goto err;
4923 }
4924
4925 req = embedded_payload(wrb);
4926
4927 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4928 OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG,
4929 sizeof(*req), wrb, NULL);
4930
d9d426af 4931 req->hdr.version = version;
bdce2ad7
SR
4932 req->hdr.domain = domain;
4933
d9d426af
SR
4934 if (link_state == IFLA_VF_LINK_STATE_ENABLE ||
4935 link_state == IFLA_VF_LINK_STATE_AUTO)
4936 req->link_config |= PLINK_ENABLE;
bdce2ad7
SR
4937
4938 if (link_state == IFLA_VF_LINK_STATE_AUTO)
d9d426af 4939 req->link_config |= PLINK_TRACK;
bdce2ad7
SR
4940
4941 status = be_mcc_notify_wait(adapter);
4942err:
b7172414 4943 mutex_unlock(&adapter->mcc_lock);
bdce2ad7
SR
4944 return status;
4945}
4946
d9d426af
SR
4947int be_cmd_set_logical_link_config(struct be_adapter *adapter,
4948 int link_state, u8 domain)
4949{
4950 int status;
4951
4952 if (BEx_chip(adapter))
4953 return -EOPNOTSUPP;
4954
4955 status = __be_cmd_set_logical_link_config(adapter, link_state,
4956 2, domain);
4957
4958 /* Version 2 of the command will not be recognized by older FW.
4959 * On such a failure issue version 1 of the command.
4960 */
4961 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST)
4962 status = __be_cmd_set_logical_link_config(adapter, link_state,
4963 1, domain);
4964 return status;
4965}
710f3e59
SB
4966
4967int be_cmd_set_features(struct be_adapter *adapter)
4968{
4969 struct be_cmd_resp_set_features *resp;
4970 struct be_cmd_req_set_features *req;
4971 struct be_mcc_wrb *wrb;
4972 int status;
4973
4974 if (mutex_lock_interruptible(&adapter->mcc_lock))
4975 return -1;
4976
4977 wrb = wrb_from_mccq(adapter);
4978 if (!wrb) {
4979 status = -EBUSY;
4980 goto err;
4981 }
4982
4983 req = embedded_payload(wrb);
4984
4985 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
4986 OPCODE_COMMON_SET_FEATURES,
4987 sizeof(*req), wrb, NULL);
4988
4989 req->features = cpu_to_le32(BE_FEATURE_UE_RECOVERY);
4990 req->parameter_len = cpu_to_le32(sizeof(struct be_req_ue_recovery));
4991 req->parameter.req.uer = cpu_to_le32(BE_UE_RECOVERY_UER_MASK);
4992
4993 status = be_mcc_notify_wait(adapter);
4994 if (status)
4995 goto err;
4996
4997 resp = embedded_payload(wrb);
4998
4999 adapter->error_recovery.ue_to_poll_time =
5000 le16_to_cpu(resp->parameter.resp.ue2rp);
5001 adapter->error_recovery.ue_to_reset_time =
5002 le16_to_cpu(resp->parameter.resp.ue2sr);
5003 adapter->error_recovery.recovery_supported = true;
5004err:
5005 /* Checking "MCC_STATUS_INVALID_LENGTH" for SKH as FW
5006 * returns this error in older firmware versions
5007 */
5008 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
5009 base_status(status) == MCC_STATUS_INVALID_LENGTH)
5010 dev_info(&adapter->pdev->dev,
5011 "Adapter does not support HW error recovery\n");
5012
5013 mutex_unlock(&adapter->mcc_lock);
5014 return status;
5015}
5016
6a4ab669 5017int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
a2cc4e0b 5018 int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
6a4ab669
PP
5019{
5020 struct be_adapter *adapter = netdev_priv(netdev_handle);
5021 struct be_mcc_wrb *wrb;
504fbf1e 5022 struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *)wrb_payload;
6a4ab669
PP
5023 struct be_cmd_req_hdr *req;
5024 struct be_cmd_resp_hdr *resp;
5025 int status;
5026
b7172414 5027 mutex_lock(&adapter->mcc_lock);
6a4ab669
PP
5028
5029 wrb = wrb_from_mccq(adapter);
5030 if (!wrb) {
5031 status = -EBUSY;
5032 goto err;
5033 }
5034 req = embedded_payload(wrb);
5035 resp = embedded_payload(wrb);
5036
5037 be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
5038 hdr->opcode, wrb_payload_size, wrb, NULL);
5039 memcpy(req, wrb_payload, wrb_payload_size);
5040 be_dws_cpu_to_le(req, wrb_payload_size);
5041
5042 status = be_mcc_notify_wait(adapter);
5043 if (cmd_status)
5044 *cmd_status = (status & 0xffff);
5045 if (ext_status)
5046 *ext_status = 0;
5047 memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
5048 be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
5049err:
b7172414 5050 mutex_unlock(&adapter->mcc_lock);
6a4ab669
PP
5051 return status;
5052}
5053EXPORT_SYMBOL(be_roce_mcc_cmd);
This page took 1.227328 seconds and 5 git commands to generate.