blob: 0538c0b4abeb4264a5a27d0dc3d88248d39b2bec [file] [log] [blame]
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001/*
Vasundhara Volam40263822014-02-12 16:09:07 +05302 * Copyright (C) 2005 - 2014 Emulex
Sathya Perla6b7c5b92009-03-11 23:32:03 -07003 * 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:
Ajit Khaparded2145cd2011-03-16 08:20:46 +000011 * linux-drivers@emulex.com
Sathya Perla6b7c5b92009-03-11 23:32:03 -070012 *
Ajit Khaparded2145cd2011-03-16 08:20:46 +000013 * Emulex
14 * 3333 Susan Street
15 * Costa Mesa, CA 92626
Sathya Perla6b7c5b92009-03-11 23:32:03 -070016 */
17
Parav Pandit6a4ab662012-03-26 14:27:12 +000018#include <linux/module.h>
Sathya Perla6b7c5b92009-03-11 23:32:03 -070019#include "be.h"
Sathya Perla8788fdc2009-07-27 22:52:03 +000020#include "be_cmds.h"
Sathya Perla6b7c5b92009-03-11 23:32:03 -070021
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +000022static struct be_cmd_priv_map cmd_priv_map[] = {
23 {
24 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
25 CMD_SUBSYSTEM_ETH,
26 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
27 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
28 },
29 {
30 OPCODE_COMMON_GET_FLOW_CONTROL,
31 CMD_SUBSYSTEM_COMMON,
32 BE_PRIV_LNKQUERY | BE_PRIV_VHADM |
33 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
34 },
35 {
36 OPCODE_COMMON_SET_FLOW_CONTROL,
37 CMD_SUBSYSTEM_COMMON,
38 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
39 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
40 },
41 {
42 OPCODE_ETH_GET_PPORT_STATS,
43 CMD_SUBSYSTEM_ETH,
44 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
45 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
46 },
47 {
48 OPCODE_COMMON_GET_PHY_DETAILS,
49 CMD_SUBSYSTEM_COMMON,
50 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
51 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
52 }
53};
54
Sathya Perlaa2cc4e02014-05-09 13:29:14 +053055static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +000056{
57 int i;
58 int num_entries = sizeof(cmd_priv_map)/sizeof(struct be_cmd_priv_map);
59 u32 cmd_privileges = adapter->cmd_privileges;
60
61 for (i = 0; i < num_entries; i++)
62 if (opcode == cmd_priv_map[i].opcode &&
63 subsystem == cmd_priv_map[i].subsystem)
64 if (!(cmd_privileges & cmd_priv_map[i].priv_mask))
65 return false;
66
67 return true;
68}
69
Somnath Kotur3de09452011-09-30 07:25:05 +000070static inline void *embedded_payload(struct be_mcc_wrb *wrb)
71{
72 return wrb->payload.embedded_payload;
73}
Ajit Khaparde609ff3b2011-02-20 11:42:07 +000074
Sathya Perla8788fdc2009-07-27 22:52:03 +000075static void be_mcc_notify(struct be_adapter *adapter)
Sathya Perla5fb379e2009-06-18 00:02:59 +000076{
Sathya Perla8788fdc2009-07-27 22:52:03 +000077 struct be_queue_info *mccq = &adapter->mcc_obj.q;
Sathya Perla5fb379e2009-06-18 00:02:59 +000078 u32 val = 0;
79
Sathya Perla6589ade2011-11-10 19:18:00 +000080 if (be_error(adapter))
Ajit Khaparde7acc2082011-02-11 13:38:17 +000081 return;
Ajit Khaparde7acc2082011-02-11 13:38:17 +000082
Sathya Perla5fb379e2009-06-18 00:02:59 +000083 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
84 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
Sathya Perlaf3eb62d2010-06-29 00:11:17 +000085
86 wmb();
Sathya Perla8788fdc2009-07-27 22:52:03 +000087 iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
Sathya Perla5fb379e2009-06-18 00:02:59 +000088}
89
90/* To check if valid bit is set, check the entire word as we don't know
91 * the endianness of the data (old entry is host endian while a new entry is
92 * little endian) */
Sathya Perlaefd2e402009-07-27 22:53:10 +000093static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
Sathya Perla5fb379e2009-06-18 00:02:59 +000094{
Sathya Perla9e9ff4b2013-02-12 23:05:19 +000095 u32 flags;
96
Sathya Perla5fb379e2009-06-18 00:02:59 +000097 if (compl->flags != 0) {
Sathya Perla9e9ff4b2013-02-12 23:05:19 +000098 flags = le32_to_cpu(compl->flags);
99 if (flags & CQE_FLAGS_VALID_MASK) {
100 compl->flags = flags;
101 return true;
102 }
Sathya Perla5fb379e2009-06-18 00:02:59 +0000103 }
Sathya Perla9e9ff4b2013-02-12 23:05:19 +0000104 return false;
Sathya Perla5fb379e2009-06-18 00:02:59 +0000105}
106
107/* Need to reset the entire word that houses the valid bit */
Sathya Perlaefd2e402009-07-27 22:53:10 +0000108static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
Sathya Perla5fb379e2009-06-18 00:02:59 +0000109{
110 compl->flags = 0;
111}
112
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000113static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
114{
115 unsigned long addr;
116
117 addr = tag1;
118 addr = ((addr << 16) << 16) | tag0;
119 return (void *)addr;
120}
121
Kalesh AP4c600052014-05-30 19:06:26 +0530122static bool be_skip_err_log(u8 opcode, u16 base_status, u16 addl_status)
123{
124 if (base_status == MCC_STATUS_NOT_SUPPORTED ||
125 base_status == MCC_STATUS_ILLEGAL_REQUEST ||
126 addl_status == MCC_ADDL_STATUS_TOO_MANY_INTERFACES ||
127 (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
128 (base_status == MCC_STATUS_ILLEGAL_FIELD ||
129 addl_status == MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH)))
130 return true;
131 else
132 return false;
133}
134
Sathya Perla559b6332014-05-30 19:06:27 +0530135/* Place holder for all the async MCC cmds wherein the caller is not in a busy
136 * loop (has not issued be_mcc_notify_wait())
137 */
138static void be_async_cmd_process(struct be_adapter *adapter,
139 struct be_mcc_compl *compl,
140 struct be_cmd_resp_hdr *resp_hdr)
141{
142 enum mcc_base_status base_status = base_status(compl->status);
143 u8 opcode = 0, subsystem = 0;
144
145 if (resp_hdr) {
146 opcode = resp_hdr->opcode;
147 subsystem = resp_hdr->subsystem;
148 }
149
150 if (opcode == OPCODE_LOWLEVEL_LOOPBACK_TEST &&
151 subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
152 complete(&adapter->et_cmd_compl);
153 return;
154 }
155
156 if ((opcode == OPCODE_COMMON_WRITE_FLASHROM ||
157 opcode == OPCODE_COMMON_WRITE_OBJECT) &&
158 subsystem == CMD_SUBSYSTEM_COMMON) {
159 adapter->flash_status = compl->status;
160 complete(&adapter->et_cmd_compl);
161 return;
162 }
163
164 if ((opcode == OPCODE_ETH_GET_STATISTICS ||
165 opcode == OPCODE_ETH_GET_PPORT_STATS) &&
166 subsystem == CMD_SUBSYSTEM_ETH &&
167 base_status == MCC_STATUS_SUCCESS) {
168 be_parse_stats(adapter);
169 adapter->stats_cmd_sent = false;
170 return;
171 }
172
173 if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
174 subsystem == CMD_SUBSYSTEM_COMMON) {
175 if (base_status == MCC_STATUS_SUCCESS) {
176 struct be_cmd_resp_get_cntl_addnl_attribs *resp =
177 (void *)resp_hdr;
178 adapter->drv_stats.be_on_die_temperature =
179 resp->on_die_temperature;
180 } else {
181 adapter->be_get_temp_freq = 0;
182 }
183 return;
184 }
185}
186
Sathya Perla8788fdc2009-07-27 22:52:03 +0000187static int be_mcc_compl_process(struct be_adapter *adapter,
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000188 struct be_mcc_compl *compl)
Sathya Perla5fb379e2009-06-18 00:02:59 +0000189{
Kalesh AP4c600052014-05-30 19:06:26 +0530190 enum mcc_base_status base_status;
191 enum mcc_addl_status addl_status;
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000192 struct be_cmd_resp_hdr *resp_hdr;
193 u8 opcode = 0, subsystem = 0;
Sathya Perla5fb379e2009-06-18 00:02:59 +0000194
195 /* Just swap the status to host endian; mcc tag is opaquely copied
196 * from mcc_wrb */
197 be_dws_le_to_cpu(compl, 4);
198
Kalesh AP4c600052014-05-30 19:06:26 +0530199 base_status = base_status(compl->status);
200 addl_status = addl_status(compl->status);
Vasundhara Volam96c9b2e2014-05-30 19:06:25 +0530201
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000202 resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000203 if (resp_hdr) {
204 opcode = resp_hdr->opcode;
205 subsystem = resp_hdr->subsystem;
206 }
207
Sathya Perla559b6332014-05-30 19:06:27 +0530208 be_async_cmd_process(adapter, compl, resp_hdr);
Suresh Reddy5eeff632014-01-06 13:02:24 +0530209
Sathya Perla559b6332014-05-30 19:06:27 +0530210 if (base_status != MCC_STATUS_SUCCESS &&
211 !be_skip_err_log(opcode, base_status, addl_status)) {
Vasundhara Volam96c9b2e2014-05-30 19:06:25 +0530212
Kalesh AP4c600052014-05-30 19:06:26 +0530213 if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
Vasundhara Volam97f1d8c2012-06-13 19:51:44 +0000214 dev_warn(&adapter->pdev->dev,
Vasundhara Volam522609f2012-08-28 20:37:44 +0000215 "VF is not privileged to issue opcode %d-%d\n",
Vasundhara Volam97f1d8c2012-06-13 19:51:44 +0000216 opcode, subsystem);
Sathya Perla2b3f2912011-06-29 23:32:56 +0000217 } else {
Vasundhara Volam97f1d8c2012-06-13 19:51:44 +0000218 dev_err(&adapter->pdev->dev,
219 "opcode %d-%d failed:status %d-%d\n",
Kalesh AP4c600052014-05-30 19:06:26 +0530220 opcode, subsystem, base_status, addl_status);
Sathya Perla2b3f2912011-06-29 23:32:56 +0000221 }
Sathya Perla5fb379e2009-06-18 00:02:59 +0000222 }
Kalesh AP4c600052014-05-30 19:06:26 +0530223 return compl->status;
Sathya Perla5fb379e2009-06-18 00:02:59 +0000224}
225
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000226/* Link state evt is a string of bytes; no need for endian swapping */
Sathya Perla8788fdc2009-07-27 22:52:03 +0000227static void be_async_link_state_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530228 struct be_async_event_link_state *evt)
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000229{
Ajit Khapardeb236916a2011-12-30 12:15:40 +0000230 /* When link status changes, link speed must be re-queried from FW */
Ajit Khaparde42f11cf2012-04-21 18:53:22 +0000231 adapter->phy.link_speed = -1;
Ajit Khapardeb236916a2011-12-30 12:15:40 +0000232
Suresh Reddybdce2ad2014-03-11 18:53:04 +0530233 /* On BEx the FW does not send a separate link status
234 * notification for physical and logical link.
235 * On other chips just process the logical link
236 * status notification
237 */
238 if (!BEx_chip(adapter) &&
Padmanabh Ratnakar2e177a52012-07-18 02:52:15 +0000239 !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK))
240 return;
241
Ajit Khapardeb236916a2011-12-30 12:15:40 +0000242 /* For the initial link status do not rely on the ASYNC event as
243 * it may not be received in some cases.
244 */
245 if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
Suresh Reddybdce2ad2014-03-11 18:53:04 +0530246 be_link_status_update(adapter,
247 evt->port_link_status & LINK_STATUS_MASK);
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000248}
249
Somnath Koturcc4ce022010-10-21 07:11:14 -0700250/* Grp5 CoS Priority evt */
251static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530252 struct
253 be_async_event_grp5_cos_priority
254 *evt)
Somnath Koturcc4ce022010-10-21 07:11:14 -0700255{
256 if (evt->valid) {
257 adapter->vlan_prio_bmap = evt->available_priority_bmap;
Ajit Khaparde60964dd2011-02-11 13:37:25 +0000258 adapter->recommended_prio &= ~VLAN_PRIO_MASK;
Somnath Koturcc4ce022010-10-21 07:11:14 -0700259 adapter->recommended_prio =
260 evt->reco_default_priority << VLAN_PRIO_SHIFT;
261 }
262}
263
Sathya Perla323ff712012-09-28 04:39:43 +0000264/* Grp5 QOS Speed evt: qos_link_speed is in units of 10 Mbps */
Somnath Koturcc4ce022010-10-21 07:11:14 -0700265static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530266 struct
267 be_async_event_grp5_qos_link_speed
268 *evt)
Somnath Koturcc4ce022010-10-21 07:11:14 -0700269{
Sathya Perla323ff712012-09-28 04:39:43 +0000270 if (adapter->phy.link_speed >= 0 &&
271 evt->physical_port == adapter->port_num)
272 adapter->phy.link_speed = le16_to_cpu(evt->qos_link_speed) * 10;
Somnath Koturcc4ce022010-10-21 07:11:14 -0700273}
274
Ajit Khaparde3968fa12011-02-20 11:41:53 +0000275/*Grp5 PVID evt*/
276static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530277 struct
278 be_async_event_grp5_pvid_state
279 *evt)
Ajit Khaparde3968fa12011-02-20 11:41:53 +0000280{
Ravikumar Nelavellibdac85b2014-03-11 18:53:05 +0530281 if (evt->enabled) {
Somnath Kotur939cf302011-08-18 21:51:49 -0700282 adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK;
Ravikumar Nelavellibdac85b2014-03-11 18:53:05 +0530283 dev_info(&adapter->pdev->dev, "LPVID: %d\n", adapter->pvid);
284 } else {
Ajit Khaparde3968fa12011-02-20 11:41:53 +0000285 adapter->pvid = 0;
Ravikumar Nelavellibdac85b2014-03-11 18:53:05 +0530286 }
Ajit Khaparde3968fa12011-02-20 11:41:53 +0000287}
288
Somnath Koturcc4ce022010-10-21 07:11:14 -0700289static void be_async_grp5_evt_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530290 u32 trailer, struct be_mcc_compl *evt)
Somnath Koturcc4ce022010-10-21 07:11:14 -0700291{
292 u8 event_type = 0;
293
294 event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
295 ASYNC_TRAILER_EVENT_TYPE_MASK;
296
297 switch (event_type) {
298 case ASYNC_EVENT_COS_PRIORITY:
299 be_async_grp5_cos_priority_process(adapter,
300 (struct be_async_event_grp5_cos_priority *)evt);
301 break;
302 case ASYNC_EVENT_QOS_SPEED:
303 be_async_grp5_qos_speed_process(adapter,
304 (struct be_async_event_grp5_qos_link_speed *)evt);
305 break;
Ajit Khaparde3968fa12011-02-20 11:41:53 +0000306 case ASYNC_EVENT_PVID_STATE:
307 be_async_grp5_pvid_state_process(adapter,
308 (struct be_async_event_grp5_pvid_state *)evt);
309 break;
Somnath Koturcc4ce022010-10-21 07:11:14 -0700310 default:
Vasundhara Volam05ccaa22013-08-06 09:27:19 +0530311 dev_warn(&adapter->pdev->dev, "Unknown grp5 event 0x%x!\n",
312 event_type);
Somnath Koturcc4ce022010-10-21 07:11:14 -0700313 break;
314 }
315}
316
Ajit Khapardebc0c3402013-04-24 11:52:50 +0000317static void be_async_dbg_evt_process(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530318 u32 trailer, struct be_mcc_compl *cmp)
Ajit Khapardebc0c3402013-04-24 11:52:50 +0000319{
320 u8 event_type = 0;
321 struct be_async_event_qnq *evt = (struct be_async_event_qnq *) cmp;
322
323 event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
324 ASYNC_TRAILER_EVENT_TYPE_MASK;
325
326 switch (event_type) {
327 case ASYNC_DEBUG_EVENT_TYPE_QNQ:
328 if (evt->valid)
329 adapter->qnq_vid = le16_to_cpu(evt->vlan_tag);
330 adapter->flags |= BE_FLAGS_QNQ_ASYNC_EVT_RCVD;
331 break;
332 default:
Vasundhara Volam05ccaa22013-08-06 09:27:19 +0530333 dev_warn(&adapter->pdev->dev, "Unknown debug event 0x%x!\n",
334 event_type);
Ajit Khapardebc0c3402013-04-24 11:52:50 +0000335 break;
336 }
337}
338
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000339static inline bool is_link_state_evt(u32 trailer)
340{
Eric Dumazet807540b2010-09-23 05:40:09 +0000341 return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000342 ASYNC_TRAILER_EVENT_CODE_MASK) ==
Eric Dumazet807540b2010-09-23 05:40:09 +0000343 ASYNC_EVENT_CODE_LINK_STATE;
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000344}
Sathya Perla5fb379e2009-06-18 00:02:59 +0000345
Somnath Koturcc4ce022010-10-21 07:11:14 -0700346static inline bool is_grp5_evt(u32 trailer)
347{
348 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
349 ASYNC_TRAILER_EVENT_CODE_MASK) ==
350 ASYNC_EVENT_CODE_GRP_5);
351}
352
Ajit Khapardebc0c3402013-04-24 11:52:50 +0000353static inline bool is_dbg_evt(u32 trailer)
354{
355 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
356 ASYNC_TRAILER_EVENT_CODE_MASK) ==
357 ASYNC_EVENT_CODE_QNQ);
358}
359
Sathya Perlaefd2e402009-07-27 22:53:10 +0000360static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
Sathya Perla5fb379e2009-06-18 00:02:59 +0000361{
Sathya Perla8788fdc2009-07-27 22:52:03 +0000362 struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
Sathya Perlaefd2e402009-07-27 22:53:10 +0000363 struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
Sathya Perla5fb379e2009-06-18 00:02:59 +0000364
365 if (be_mcc_compl_is_new(compl)) {
366 queue_tail_inc(mcc_cq);
367 return compl;
368 }
369 return NULL;
370}
371
Sathya Perla7a1e9b22010-02-17 01:35:11 +0000372void be_async_mcc_enable(struct be_adapter *adapter)
373{
374 spin_lock_bh(&adapter->mcc_cq_lock);
375
376 be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
377 adapter->mcc_obj.rearm_cq = true;
378
379 spin_unlock_bh(&adapter->mcc_cq_lock);
380}
381
382void be_async_mcc_disable(struct be_adapter *adapter)
383{
Sathya Perlaa323d9b2012-12-17 19:38:50 +0000384 spin_lock_bh(&adapter->mcc_cq_lock);
385
Sathya Perla7a1e9b22010-02-17 01:35:11 +0000386 adapter->mcc_obj.rearm_cq = false;
Sathya Perlaa323d9b2012-12-17 19:38:50 +0000387 be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
388
389 spin_unlock_bh(&adapter->mcc_cq_lock);
Sathya Perla7a1e9b22010-02-17 01:35:11 +0000390}
391
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000392int be_process_mcc(struct be_adapter *adapter)
Sathya Perla5fb379e2009-06-18 00:02:59 +0000393{
Sathya Perlaefd2e402009-07-27 22:53:10 +0000394 struct be_mcc_compl *compl;
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000395 int num = 0, status = 0;
Sathya Perla7a1e9b22010-02-17 01:35:11 +0000396 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
Sathya Perla5fb379e2009-06-18 00:02:59 +0000397
Amerigo Wang072a9c42012-08-24 21:41:11 +0000398 spin_lock(&adapter->mcc_cq_lock);
Sathya Perla8788fdc2009-07-27 22:52:03 +0000399 while ((compl = be_mcc_compl_get(adapter))) {
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000400 if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
401 /* Interpret flags as an async trailer */
Ajit Khaparde323f30b2010-09-03 06:24:13 +0000402 if (is_link_state_evt(compl->flags))
403 be_async_link_state_process(adapter,
Sathya Perlaa8f447bd2009-06-18 00:10:27 +0000404 (struct be_async_event_link_state *) compl);
Somnath Koturcc4ce022010-10-21 07:11:14 -0700405 else if (is_grp5_evt(compl->flags))
406 be_async_grp5_evt_process(adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530407 compl->flags, compl);
Ajit Khapardebc0c3402013-04-24 11:52:50 +0000408 else if (is_dbg_evt(compl->flags))
409 be_async_dbg_evt_process(adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530410 compl->flags, compl);
Sathya Perlab31c50a2009-09-17 10:30:13 -0700411 } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000412 status = be_mcc_compl_process(adapter, compl);
Sathya Perla7a1e9b22010-02-17 01:35:11 +0000413 atomic_dec(&mcc_obj->q.used);
Sathya Perla5fb379e2009-06-18 00:02:59 +0000414 }
415 be_mcc_compl_use(compl);
416 num++;
417 }
Sathya Perlab31c50a2009-09-17 10:30:13 -0700418
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000419 if (num)
420 be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
421
Amerigo Wang072a9c42012-08-24 21:41:11 +0000422 spin_unlock(&adapter->mcc_cq_lock);
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000423 return status;
Sathya Perla5fb379e2009-06-18 00:02:59 +0000424}
425
Sathya Perla6ac7b682009-06-18 00:05:54 +0000426/* Wait till no more pending mcc requests are present */
Sathya Perlab31c50a2009-09-17 10:30:13 -0700427static int be_mcc_wait_compl(struct be_adapter *adapter)
Sathya Perla6ac7b682009-06-18 00:05:54 +0000428{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700429#define mcc_timeout 120000 /* 12s timeout */
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000430 int i, status = 0;
Sathya Perlaf31e50a2010-03-02 03:56:39 -0800431 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
Sathya Perlab31c50a2009-09-17 10:30:13 -0700432
Sathya Perlaf31e50a2010-03-02 03:56:39 -0800433 for (i = 0; i < mcc_timeout; i++) {
Sathya Perla6589ade2011-11-10 19:18:00 +0000434 if (be_error(adapter))
435 return -EIO;
436
Amerigo Wang072a9c42012-08-24 21:41:11 +0000437 local_bh_disable();
Sathya Perla10ef9ab2012-02-09 18:05:27 +0000438 status = be_process_mcc(adapter);
Amerigo Wang072a9c42012-08-24 21:41:11 +0000439 local_bh_enable();
Sathya Perlaf31e50a2010-03-02 03:56:39 -0800440
441 if (atomic_read(&mcc_obj->q.used) == 0)
Sathya Perla6ac7b682009-06-18 00:05:54 +0000442 break;
443 udelay(100);
444 }
Sathya Perlab31c50a2009-09-17 10:30:13 -0700445 if (i == mcc_timeout) {
Sathya Perla6589ade2011-11-10 19:18:00 +0000446 dev_err(&adapter->pdev->dev, "FW not responding\n");
447 adapter->fw_timeout = true;
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000448 return -EIO;
Sathya Perlab31c50a2009-09-17 10:30:13 -0700449 }
Sathya Perlaf31e50a2010-03-02 03:56:39 -0800450 return status;
Sathya Perla6ac7b682009-06-18 00:05:54 +0000451}
452
453/* Notify MCC requests and wait for completion */
Sathya Perlab31c50a2009-09-17 10:30:13 -0700454static int be_mcc_notify_wait(struct be_adapter *adapter)
Sathya Perla6ac7b682009-06-18 00:05:54 +0000455{
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000456 int status;
457 struct be_mcc_wrb *wrb;
458 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
459 u16 index = mcc_obj->q.head;
460 struct be_cmd_resp_hdr *resp;
461
462 index_dec(&index, mcc_obj->q.len);
463 wrb = queue_index_node(&mcc_obj->q, index);
464
465 resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
466
Sathya Perla8788fdc2009-07-27 22:52:03 +0000467 be_mcc_notify(adapter);
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000468
469 status = be_mcc_wait_compl(adapter);
470 if (status == -EIO)
471 goto out;
472
Kalesh AP4c600052014-05-30 19:06:26 +0530473 status = (resp->base_status |
474 ((resp->addl_status & CQE_ADDL_STATUS_MASK) <<
475 CQE_ADDL_STATUS_SHIFT));
Padmanabh Ratnakar652bf642012-04-25 01:47:03 +0000476out:
477 return status;
Sathya Perla6ac7b682009-06-18 00:05:54 +0000478}
479
Sathya Perla5f0b8492009-07-27 22:52:56 +0000480static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700481{
Sathya Perlaf25b03a2010-05-30 23:34:14 +0000482 int msecs = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700483 u32 ready;
484
485 do {
Sathya Perla6589ade2011-11-10 19:18:00 +0000486 if (be_error(adapter))
487 return -EIO;
488
Sathya Perlacf588472010-02-14 21:22:01 +0000489 ready = ioread32(db);
Sathya Perla434b3642011-11-10 19:17:59 +0000490 if (ready == 0xffffffff)
Sathya Perlacf588472010-02-14 21:22:01 +0000491 return -1;
Sathya Perlacf588472010-02-14 21:22:01 +0000492
493 ready &= MPU_MAILBOX_DB_RDY_MASK;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700494 if (ready)
495 break;
496
Sathya Perlaf25b03a2010-05-30 23:34:14 +0000497 if (msecs > 4000) {
Sathya Perla6589ade2011-11-10 19:18:00 +0000498 dev_err(&adapter->pdev->dev, "FW not responding\n");
499 adapter->fw_timeout = true;
Padmanabh Ratnakarf67ef7b2012-07-12 03:57:09 +0000500 be_detect_error(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700501 return -1;
502 }
503
Sathya Perla1dbf53a2011-05-12 19:32:16 +0000504 msleep(1);
Sathya Perlaf25b03a2010-05-30 23:34:14 +0000505 msecs++;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700506 } while (true);
507
508 return 0;
509}
510
511/*
512 * Insert the mailbox address into the doorbell in two steps
Sathya Perla5fb379e2009-06-18 00:02:59 +0000513 * Polls on the mbox doorbell till a command completion (or a timeout) occurs
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700514 */
Sathya Perlab31c50a2009-09-17 10:30:13 -0700515static int be_mbox_notify_wait(struct be_adapter *adapter)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700516{
517 int status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700518 u32 val = 0;
Sathya Perla8788fdc2009-07-27 22:52:03 +0000519 void __iomem *db = adapter->db + MPU_MAILBOX_DB_OFFSET;
520 struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700521 struct be_mcc_mailbox *mbox = mbox_mem->va;
Sathya Perlaefd2e402009-07-27 22:53:10 +0000522 struct be_mcc_compl *compl = &mbox->compl;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700523
Sathya Perlacf588472010-02-14 21:22:01 +0000524 /* wait for ready to be set */
525 status = be_mbox_db_ready_wait(adapter, db);
526 if (status != 0)
527 return status;
528
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700529 val |= MPU_MAILBOX_DB_HI_MASK;
530 /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
531 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
532 iowrite32(val, db);
533
534 /* wait for ready to be set */
Sathya Perla5f0b8492009-07-27 22:52:56 +0000535 status = be_mbox_db_ready_wait(adapter, db);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700536 if (status != 0)
537 return status;
538
539 val = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700540 /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
541 val |= (u32)(mbox_mem->dma >> 4) << 2;
542 iowrite32(val, db);
543
Sathya Perla5f0b8492009-07-27 22:52:56 +0000544 status = be_mbox_db_ready_wait(adapter, db);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700545 if (status != 0)
546 return status;
547
Sathya Perla5fb379e2009-06-18 00:02:59 +0000548 /* A cq entry has been made now */
Sathya Perlaefd2e402009-07-27 22:53:10 +0000549 if (be_mcc_compl_is_new(compl)) {
550 status = be_mcc_compl_process(adapter, &mbox->compl);
551 be_mcc_compl_use(compl);
Sathya Perla5fb379e2009-06-18 00:02:59 +0000552 if (status)
553 return status;
554 } else {
Sathya Perla5f0b8492009-07-27 22:52:56 +0000555 dev_err(&adapter->pdev->dev, "invalid mailbox completion\n");
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700556 return -1;
557 }
Sathya Perla5fb379e2009-06-18 00:02:59 +0000558 return 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700559}
560
Sathya Perlac5b3ad42013-03-05 22:23:20 +0000561static u16 be_POST_stage_get(struct be_adapter *adapter)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700562{
Sathya Perlafe6d2a32010-11-21 23:25:50 +0000563 u32 sem;
564
Sathya Perlac5b3ad42013-03-05 22:23:20 +0000565 if (BEx_chip(adapter))
566 sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700567 else
Sathya Perlac5b3ad42013-03-05 22:23:20 +0000568 pci_read_config_dword(adapter->pdev,
569 SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
570
571 return sem & POST_STAGE_MASK;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700572}
573
Gavin Shan87f20c22013-10-29 17:30:57 +0800574static int lancer_wait_ready(struct be_adapter *adapter)
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000575{
576#define SLIPORT_READY_TIMEOUT 30
577 u32 sliport_status;
578 int status = 0, i;
579
580 for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
581 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
582 if (sliport_status & SLIPORT_STATUS_RDY_MASK)
583 break;
584
585 msleep(1000);
586 }
587
588 if (i == SLIPORT_READY_TIMEOUT)
589 status = -1;
590
591 return status;
592}
593
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000594static bool lancer_provisioning_error(struct be_adapter *adapter)
595{
596 u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
597 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
598 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530599 sliport_err1 = ioread32(adapter->db + SLIPORT_ERROR1_OFFSET);
600 sliport_err2 = ioread32(adapter->db + SLIPORT_ERROR2_OFFSET);
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000601
602 if (sliport_err1 == SLIPORT_ERROR_NO_RESOURCE1 &&
603 sliport_err2 == SLIPORT_ERROR_NO_RESOURCE2)
604 return true;
605 }
606 return false;
607}
608
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000609int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
610{
611 int status;
612 u32 sliport_status, err, reset_needed;
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000613 bool resource_error;
614
615 resource_error = lancer_provisioning_error(adapter);
616 if (resource_error)
Somnath Kotur01e5b2c2013-05-29 22:56:17 +0000617 return -EAGAIN;
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000618
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000619 status = lancer_wait_ready(adapter);
620 if (!status) {
621 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
622 err = sliport_status & SLIPORT_STATUS_ERR_MASK;
623 reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
624 if (err && reset_needed) {
625 iowrite32(SLI_PORT_CONTROL_IP_MASK,
626 adapter->db + SLIPORT_CONTROL_OFFSET);
627
628 /* check adapter has corrected the error */
629 status = lancer_wait_ready(adapter);
630 sliport_status = ioread32(adapter->db +
631 SLIPORT_STATUS_OFFSET);
632 sliport_status &= (SLIPORT_STATUS_ERR_MASK |
633 SLIPORT_STATUS_RN_MASK);
634 if (status || sliport_status)
635 status = -1;
636 } else if (err || reset_needed) {
637 status = -1;
638 }
639 }
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000640 /* Stop error recovery if error is not recoverable.
641 * No resource error is temporary errors and will go away
642 * when PF provisions resources.
643 */
644 resource_error = lancer_provisioning_error(adapter);
Somnath Kotur01e5b2c2013-05-29 22:56:17 +0000645 if (resource_error)
646 status = -EAGAIN;
Padmanabh Ratnakar67297ad2012-10-20 06:02:27 +0000647
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000648 return status;
649}
650
651int be_fw_wait_ready(struct be_adapter *adapter)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700652{
Sathya Perla43a04fdc2009-10-14 20:21:17 +0000653 u16 stage;
654 int status, timeout = 0;
Sathya Perla6ed35ee2011-05-12 19:32:15 +0000655 struct device *dev = &adapter->pdev->dev;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700656
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000657 if (lancer_chip(adapter)) {
658 status = lancer_wait_ready(adapter);
659 return status;
660 }
661
Sathya Perla43a04fdc2009-10-14 20:21:17 +0000662 do {
Sathya Perlac5b3ad42013-03-05 22:23:20 +0000663 stage = be_POST_stage_get(adapter);
Gavin Shan66d29cb2013-03-03 21:48:46 +0000664 if (stage == POST_STAGE_ARMFW_RDY)
Sathya Perla43a04fdc2009-10-14 20:21:17 +0000665 return 0;
Gavin Shan66d29cb2013-03-03 21:48:46 +0000666
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530667 dev_info(dev, "Waiting for POST, %ds elapsed\n", timeout);
Gavin Shan66d29cb2013-03-03 21:48:46 +0000668 if (msleep_interruptible(2000)) {
669 dev_err(dev, "Waiting for POST aborted\n");
670 return -EINTR;
Sathya Perla43a04fdc2009-10-14 20:21:17 +0000671 }
Gavin Shan66d29cb2013-03-03 21:48:46 +0000672 timeout += 2;
Somnath Kotur3ab81b52011-10-03 08:10:57 +0000673 } while (timeout < 60);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700674
Sathya Perla6ed35ee2011-05-12 19:32:15 +0000675 dev_err(dev, "POST timeout; stage=0x%x\n", stage);
Sathya Perla43a04fdc2009-10-14 20:21:17 +0000676 return -1;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700677}
678
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700679
680static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
681{
682 return &wrb->payload.sgl[0];
683}
684
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530685static inline void fill_wrb_tags(struct be_mcc_wrb *wrb, unsigned long addr)
Sathya Perlabea50982013-08-27 16:57:33 +0530686{
687 wrb->tag0 = addr & 0xFFFFFFFF;
688 wrb->tag1 = upper_32_bits(addr);
689}
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700690
691/* Don't touch the hdr after it's prepared */
Somnath Kotur106df1e2011-10-27 07:12:13 +0000692/* mem will be NULL for embedded commands */
693static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530694 u8 subsystem, u8 opcode, int cmd_len,
695 struct be_mcc_wrb *wrb,
696 struct be_dma_mem *mem)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700697{
Somnath Kotur106df1e2011-10-27 07:12:13 +0000698 struct be_sge *sge;
699
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700700 req_hdr->opcode = opcode;
701 req_hdr->subsystem = subsystem;
702 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
Ajit Khaparde07793d32010-02-16 00:18:46 +0000703 req_hdr->version = 0;
Sathya Perlabea50982013-08-27 16:57:33 +0530704 fill_wrb_tags(wrb, (ulong) req_hdr);
Somnath Kotur106df1e2011-10-27 07:12:13 +0000705 wrb->payload_length = cmd_len;
706 if (mem) {
707 wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
708 MCC_WRB_SGE_CNT_SHIFT;
709 sge = nonembedded_sgl(wrb);
710 sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
711 sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
712 sge->len = cpu_to_le32(mem->size);
713 } else
714 wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
715 be_dws_cpu_to_le(wrb, 8);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700716}
717
718static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530719 struct be_dma_mem *mem)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700720{
721 int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
722 u64 dma = (u64)mem->dma;
723
724 for (i = 0; i < buf_pages; i++) {
725 pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
726 pages[i].hi = cpu_to_le32(upper_32_bits(dma));
727 dma += PAGE_SIZE_4K;
728 }
729}
730
Sathya Perlab31c50a2009-09-17 10:30:13 -0700731static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700732{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700733 struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
734 struct be_mcc_wrb *wrb
735 = &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
736 memset(wrb, 0, sizeof(*wrb));
737 return wrb;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700738}
739
Sathya Perlab31c50a2009-09-17 10:30:13 -0700740static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
Sathya Perla5fb379e2009-06-18 00:02:59 +0000741{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700742 struct be_queue_info *mccq = &adapter->mcc_obj.q;
743 struct be_mcc_wrb *wrb;
744
Padmanabh Ratnakaraa790db2012-10-20 06:03:25 +0000745 if (!mccq->created)
746 return NULL;
747
Vasundhara Volam4d277122013-04-21 23:28:15 +0000748 if (atomic_read(&mccq->used) >= mccq->len)
Sathya Perla713d03942009-11-22 22:02:45 +0000749 return NULL;
Sathya Perla713d03942009-11-22 22:02:45 +0000750
Sathya Perlab31c50a2009-09-17 10:30:13 -0700751 wrb = queue_head_node(mccq);
752 queue_head_inc(mccq);
753 atomic_inc(&mccq->used);
754 memset(wrb, 0, sizeof(*wrb));
Sathya Perla5fb379e2009-06-18 00:02:59 +0000755 return wrb;
756}
757
Sathya Perlabea50982013-08-27 16:57:33 +0530758static bool use_mcc(struct be_adapter *adapter)
759{
760 return adapter->mcc_obj.q.created;
761}
762
763/* Must be used only in process context */
764static int be_cmd_lock(struct be_adapter *adapter)
765{
766 if (use_mcc(adapter)) {
767 spin_lock_bh(&adapter->mcc_lock);
768 return 0;
769 } else {
770 return mutex_lock_interruptible(&adapter->mbox_lock);
771 }
772}
773
774/* Must be used only in process context */
775static void be_cmd_unlock(struct be_adapter *adapter)
776{
777 if (use_mcc(adapter))
778 spin_unlock_bh(&adapter->mcc_lock);
779 else
780 return mutex_unlock(&adapter->mbox_lock);
781}
782
783static struct be_mcc_wrb *be_cmd_copy(struct be_adapter *adapter,
784 struct be_mcc_wrb *wrb)
785{
786 struct be_mcc_wrb *dest_wrb;
787
788 if (use_mcc(adapter)) {
789 dest_wrb = wrb_from_mccq(adapter);
790 if (!dest_wrb)
791 return NULL;
792 } else {
793 dest_wrb = wrb_from_mbox(adapter);
794 }
795
796 memcpy(dest_wrb, wrb, sizeof(*wrb));
797 if (wrb->embedded & cpu_to_le32(MCC_WRB_EMBEDDED_MASK))
798 fill_wrb_tags(dest_wrb, (ulong) embedded_payload(wrb));
799
800 return dest_wrb;
801}
802
803/* Must be used only in process context */
804static int be_cmd_notify_wait(struct be_adapter *adapter,
805 struct be_mcc_wrb *wrb)
806{
807 struct be_mcc_wrb *dest_wrb;
808 int status;
809
810 status = be_cmd_lock(adapter);
811 if (status)
812 return status;
813
814 dest_wrb = be_cmd_copy(adapter, wrb);
815 if (!dest_wrb)
816 return -EBUSY;
817
818 if (use_mcc(adapter))
819 status = be_mcc_notify_wait(adapter);
820 else
821 status = be_mbox_notify_wait(adapter);
822
823 if (!status)
824 memcpy(wrb, dest_wrb, sizeof(*wrb));
825
826 be_cmd_unlock(adapter);
827 return status;
828}
829
Sathya Perla2243e2e2009-11-22 22:02:03 +0000830/* Tell fw we're about to start firing cmds by writing a
831 * special pattern across the wrb hdr; uses mbox
832 */
833int be_cmd_fw_init(struct be_adapter *adapter)
834{
835 u8 *wrb;
836 int status;
837
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000838 if (lancer_chip(adapter))
839 return 0;
840
Ivan Vecera29849612010-12-14 05:43:19 +0000841 if (mutex_lock_interruptible(&adapter->mbox_lock))
842 return -1;
Sathya Perla2243e2e2009-11-22 22:02:03 +0000843
844 wrb = (u8 *)wrb_from_mbox(adapter);
Sathya Perla359a9722010-12-01 01:03:36 +0000845 *wrb++ = 0xFF;
846 *wrb++ = 0x12;
847 *wrb++ = 0x34;
848 *wrb++ = 0xFF;
849 *wrb++ = 0xFF;
850 *wrb++ = 0x56;
851 *wrb++ = 0x78;
852 *wrb = 0xFF;
Sathya Perla2243e2e2009-11-22 22:02:03 +0000853
854 status = be_mbox_notify_wait(adapter);
855
Ivan Vecera29849612010-12-14 05:43:19 +0000856 mutex_unlock(&adapter->mbox_lock);
Sathya Perla2243e2e2009-11-22 22:02:03 +0000857 return status;
858}
859
860/* Tell fw we're done with firing cmds by writing a
861 * special pattern across the wrb hdr; uses mbox
862 */
863int be_cmd_fw_clean(struct be_adapter *adapter)
864{
865 u8 *wrb;
866 int status;
867
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000868 if (lancer_chip(adapter))
869 return 0;
870
Ivan Vecera29849612010-12-14 05:43:19 +0000871 if (mutex_lock_interruptible(&adapter->mbox_lock))
872 return -1;
Sathya Perla2243e2e2009-11-22 22:02:03 +0000873
874 wrb = (u8 *)wrb_from_mbox(adapter);
875 *wrb++ = 0xFF;
876 *wrb++ = 0xAA;
877 *wrb++ = 0xBB;
878 *wrb++ = 0xFF;
879 *wrb++ = 0xFF;
880 *wrb++ = 0xCC;
881 *wrb++ = 0xDD;
882 *wrb = 0xFF;
883
884 status = be_mbox_notify_wait(adapter);
885
Ivan Vecera29849612010-12-14 05:43:19 +0000886 mutex_unlock(&adapter->mbox_lock);
Sathya Perla2243e2e2009-11-22 22:02:03 +0000887 return status;
888}
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +0000889
Sathya Perlaf2f781a2013-08-27 16:57:30 +0530890int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700891{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700892 struct be_mcc_wrb *wrb;
893 struct be_cmd_req_eq_create *req;
Sathya Perlaf2f781a2013-08-27 16:57:30 +0530894 struct be_dma_mem *q_mem = &eqo->q.dma_mem;
895 int status, ver = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700896
Ivan Vecera29849612010-12-14 05:43:19 +0000897 if (mutex_lock_interruptible(&adapter->mbox_lock))
898 return -1;
Sathya Perlab31c50a2009-09-17 10:30:13 -0700899
900 wrb = wrb_from_mbox(adapter);
901 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700902
Somnath Kotur106df1e2011-10-27 07:12:13 +0000903 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530904 OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb,
905 NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700906
Sathya Perlaf2f781a2013-08-27 16:57:30 +0530907 /* Support for EQ_CREATEv2 available only SH-R onwards */
908 if (!(BEx_chip(adapter) || lancer_chip(adapter)))
909 ver = 2;
910
911 req->hdr.version = ver;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700912 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
913
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700914 AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
915 /* 4byte eqe*/
916 AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
917 AMAP_SET_BITS(struct amap_eq_context, count, req->context,
Sathya Perlaf2f781a2013-08-27 16:57:30 +0530918 __ilog2_u32(eqo->q.len / 256));
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700919 be_dws_cpu_to_le(req->context, sizeof(req->context));
920
921 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
922
Sathya Perlab31c50a2009-09-17 10:30:13 -0700923 status = be_mbox_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700924 if (!status) {
Sathya Perlab31c50a2009-09-17 10:30:13 -0700925 struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
Sathya Perlaf2f781a2013-08-27 16:57:30 +0530926 eqo->q.id = le16_to_cpu(resp->eq_id);
927 eqo->msix_idx =
928 (ver == 2) ? le16_to_cpu(resp->msix_idx) : eqo->idx;
929 eqo->q.created = true;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700930 }
Sathya Perlab31c50a2009-09-17 10:30:13 -0700931
Ivan Vecera29849612010-12-14 05:43:19 +0000932 mutex_unlock(&adapter->mbox_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700933 return status;
934}
935
Sathya Perlaf9449ab2011-10-24 02:45:01 +0000936/* Use MCC */
Sathya Perla8788fdc2009-07-27 22:52:03 +0000937int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
Sathya Perla5ee49792012-09-28 04:39:41 +0000938 bool permanent, u32 if_handle, u32 pmac_id)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700939{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700940 struct be_mcc_wrb *wrb;
941 struct be_cmd_req_mac_query *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700942 int status;
943
Sathya Perlaf9449ab2011-10-24 02:45:01 +0000944 spin_lock_bh(&adapter->mcc_lock);
Sathya Perlab31c50a2009-09-17 10:30:13 -0700945
Sathya Perlaf9449ab2011-10-24 02:45:01 +0000946 wrb = wrb_from_mccq(adapter);
947 if (!wrb) {
948 status = -EBUSY;
949 goto err;
950 }
Sathya Perlab31c50a2009-09-17 10:30:13 -0700951 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700952
Somnath Kotur106df1e2011-10-27 07:12:13 +0000953 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530954 OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req), wrb,
955 NULL);
Sathya Perla5ee49792012-09-28 04:39:41 +0000956 req->type = MAC_ADDRESS_TYPE_NETWORK;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700957 if (permanent) {
958 req->permanent = 1;
959 } else {
Sathya Perlab31c50a2009-09-17 10:30:13 -0700960 req->if_id = cpu_to_le16((u16) if_handle);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +0000961 req->pmac_id = cpu_to_le32(pmac_id);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700962 req->permanent = 0;
963 }
964
Sathya Perlaf9449ab2011-10-24 02:45:01 +0000965 status = be_mcc_notify_wait(adapter);
Sathya Perlab31c50a2009-09-17 10:30:13 -0700966 if (!status) {
967 struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700968 memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
Sathya Perlab31c50a2009-09-17 10:30:13 -0700969 }
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700970
Sathya Perlaf9449ab2011-10-24 02:45:01 +0000971err:
972 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700973 return status;
974}
975
Sathya Perlab31c50a2009-09-17 10:30:13 -0700976/* Uses synchronous MCCQ */
Sathya Perla8788fdc2009-07-27 22:52:03 +0000977int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530978 u32 if_id, u32 *pmac_id, u32 domain)
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700979{
Sathya Perlab31c50a2009-09-17 10:30:13 -0700980 struct be_mcc_wrb *wrb;
981 struct be_cmd_req_pmac_add *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700982 int status;
983
Sathya Perlab31c50a2009-09-17 10:30:13 -0700984 spin_lock_bh(&adapter->mcc_lock);
985
986 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +0000987 if (!wrb) {
988 status = -EBUSY;
989 goto err;
990 }
Sathya Perlab31c50a2009-09-17 10:30:13 -0700991 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700992
Somnath Kotur106df1e2011-10-27 07:12:13 +0000993 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +0530994 OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req), wrb,
995 NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700996
Ajit Khapardef8617e02011-02-11 13:36:37 +0000997 req->hdr.domain = domain;
Sathya Perla6b7c5b92009-03-11 23:32:03 -0700998 req->if_id = cpu_to_le32(if_id);
999 memcpy(req->mac_address, mac_addr, ETH_ALEN);
1000
Sathya Perlab31c50a2009-09-17 10:30:13 -07001001 status = be_mcc_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001002 if (!status) {
1003 struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
1004 *pmac_id = le32_to_cpu(resp->pmac_id);
1005 }
1006
Sathya Perla713d03942009-11-22 22:02:45 +00001007err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001008 spin_unlock_bh(&adapter->mcc_lock);
Somnath Koture3a7ae22011-10-27 07:14:05 +00001009
1010 if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
1011 status = -EPERM;
1012
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001013 return status;
1014}
1015
Sathya Perlab31c50a2009-09-17 10:30:13 -07001016/* Uses synchronous MCCQ */
Sathya Perla30128032011-11-10 19:17:57 +00001017int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001018{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001019 struct be_mcc_wrb *wrb;
1020 struct be_cmd_req_pmac_del *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001021 int status;
1022
Sathya Perla30128032011-11-10 19:17:57 +00001023 if (pmac_id == -1)
1024 return 0;
1025
Sathya Perlab31c50a2009-09-17 10:30:13 -07001026 spin_lock_bh(&adapter->mcc_lock);
1027
1028 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001029 if (!wrb) {
1030 status = -EBUSY;
1031 goto err;
1032 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001033 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001034
Somnath Kotur106df1e2011-10-27 07:12:13 +00001035 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1036 OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req), wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001037
Ajit Khapardef8617e02011-02-11 13:36:37 +00001038 req->hdr.domain = dom;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001039 req->if_id = cpu_to_le32(if_id);
1040 req->pmac_id = cpu_to_le32(pmac_id);
1041
Sathya Perlab31c50a2009-09-17 10:30:13 -07001042 status = be_mcc_notify_wait(adapter);
1043
Sathya Perla713d03942009-11-22 22:02:45 +00001044err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001045 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001046 return status;
1047}
1048
Sathya Perlab31c50a2009-09-17 10:30:13 -07001049/* Uses Mbox */
Sathya Perla10ef9ab2012-02-09 18:05:27 +00001050int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301051 struct be_queue_info *eq, bool no_delay, int coalesce_wm)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001052{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001053 struct be_mcc_wrb *wrb;
1054 struct be_cmd_req_cq_create *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001055 struct be_dma_mem *q_mem = &cq->dma_mem;
Sathya Perlab31c50a2009-09-17 10:30:13 -07001056 void *ctxt;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001057 int status;
1058
Ivan Vecera29849612010-12-14 05:43:19 +00001059 if (mutex_lock_interruptible(&adapter->mbox_lock))
1060 return -1;
Sathya Perlab31c50a2009-09-17 10:30:13 -07001061
1062 wrb = wrb_from_mbox(adapter);
1063 req = embedded_payload(wrb);
1064 ctxt = &req->context;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001065
Somnath Kotur106df1e2011-10-27 07:12:13 +00001066 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301067 OPCODE_COMMON_CQ_CREATE, sizeof(*req), wrb,
1068 NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001069
1070 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
Ajit Khapardebbdc42f2013-05-01 09:37:17 +00001071
1072 if (BEx_chip(adapter)) {
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001073 AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301074 coalesce_wm);
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001075 AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301076 ctxt, no_delay);
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001077 AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301078 __ilog2_u32(cq->len / 256));
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001079 AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001080 AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
1081 AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
Ajit Khapardebbdc42f2013-05-01 09:37:17 +00001082 } else {
1083 req->hdr.version = 2;
1084 req->page_size = 1; /* 1 for 4K */
Ajit Khaparde09e83a92013-11-22 12:51:20 -06001085
1086 /* coalesce-wm field in this cmd is not relevant to Lancer.
1087 * Lancer uses COMMON_MODIFY_CQ to set this field
1088 */
1089 if (!lancer_chip(adapter))
1090 AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
1091 ctxt, coalesce_wm);
Ajit Khapardebbdc42f2013-05-01 09:37:17 +00001092 AMAP_SET_BITS(struct amap_cq_context_v2, nodelay, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301093 no_delay);
Ajit Khapardebbdc42f2013-05-01 09:37:17 +00001094 AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301095 __ilog2_u32(cq->len / 256));
Ajit Khapardebbdc42f2013-05-01 09:37:17 +00001096 AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301097 AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
1098 AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001099 }
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001100
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001101 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1102
1103 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1104
Sathya Perlab31c50a2009-09-17 10:30:13 -07001105 status = be_mbox_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001106 if (!status) {
Sathya Perlab31c50a2009-09-17 10:30:13 -07001107 struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001108 cq->id = le16_to_cpu(resp->cq_id);
1109 cq->created = true;
1110 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001111
Ivan Vecera29849612010-12-14 05:43:19 +00001112 mutex_unlock(&adapter->mbox_lock);
Sathya Perla5fb379e2009-06-18 00:02:59 +00001113
1114 return status;
1115}
1116
1117static u32 be_encoded_q_len(int q_len)
1118{
1119 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
1120 if (len_encoded == 16)
1121 len_encoded = 0;
1122 return len_encoded;
1123}
1124
Jingoo Han4188e7d2013-08-05 18:02:02 +09001125static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301126 struct be_queue_info *mccq,
1127 struct be_queue_info *cq)
Sathya Perla5fb379e2009-06-18 00:02:59 +00001128{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001129 struct be_mcc_wrb *wrb;
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001130 struct be_cmd_req_mcc_ext_create *req;
Sathya Perla5fb379e2009-06-18 00:02:59 +00001131 struct be_dma_mem *q_mem = &mccq->dma_mem;
Sathya Perlab31c50a2009-09-17 10:30:13 -07001132 void *ctxt;
Sathya Perla5fb379e2009-06-18 00:02:59 +00001133 int status;
1134
Ivan Vecera29849612010-12-14 05:43:19 +00001135 if (mutex_lock_interruptible(&adapter->mbox_lock))
1136 return -1;
Sathya Perlab31c50a2009-09-17 10:30:13 -07001137
1138 wrb = wrb_from_mbox(adapter);
1139 req = embedded_payload(wrb);
1140 ctxt = &req->context;
Sathya Perla5fb379e2009-06-18 00:02:59 +00001141
Somnath Kotur106df1e2011-10-27 07:12:13 +00001142 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301143 OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req), wrb,
1144 NULL);
Sathya Perla5fb379e2009-06-18 00:02:59 +00001145
Ajit Khaparded4a2ac32010-03-11 01:35:59 +00001146 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
Vasundhara Volam666d39c2014-01-15 13:23:31 +05301147 if (BEx_chip(adapter)) {
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001148 AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
1149 AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301150 be_encoded_q_len(mccq->len));
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001151 AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
Vasundhara Volam666d39c2014-01-15 13:23:31 +05301152 } else {
1153 req->hdr.version = 1;
1154 req->cq_id = cpu_to_le16(cq->id);
1155
1156 AMAP_SET_BITS(struct amap_mcc_context_v1, ring_size, ctxt,
1157 be_encoded_q_len(mccq->len));
1158 AMAP_SET_BITS(struct amap_mcc_context_v1, valid, ctxt, 1);
1159 AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_id,
1160 ctxt, cq->id);
1161 AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_valid,
1162 ctxt, 1);
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001163 }
1164
Somnath Koturcc4ce022010-10-21 07:11:14 -07001165 /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
Sathya Perlafe6d2a32010-11-21 23:25:50 +00001166 req->async_event_bitmap[0] = cpu_to_le32(0x00000022);
Ajit Khapardebc0c3402013-04-24 11:52:50 +00001167 req->async_event_bitmap[0] |= cpu_to_le32(1 << ASYNC_EVENT_CODE_QNQ);
Sathya Perla5fb379e2009-06-18 00:02:59 +00001168 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1169
1170 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1171
Sathya Perlab31c50a2009-09-17 10:30:13 -07001172 status = be_mbox_notify_wait(adapter);
Sathya Perla5fb379e2009-06-18 00:02:59 +00001173 if (!status) {
1174 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
1175 mccq->id = le16_to_cpu(resp->id);
1176 mccq->created = true;
1177 }
Ivan Vecera29849612010-12-14 05:43:19 +00001178 mutex_unlock(&adapter->mbox_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001179
1180 return status;
1181}
1182
Jingoo Han4188e7d2013-08-05 18:02:02 +09001183static int be_cmd_mccq_org_create(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301184 struct be_queue_info *mccq,
1185 struct be_queue_info *cq)
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001186{
1187 struct be_mcc_wrb *wrb;
1188 struct be_cmd_req_mcc_create *req;
1189 struct be_dma_mem *q_mem = &mccq->dma_mem;
1190 void *ctxt;
1191 int status;
1192
1193 if (mutex_lock_interruptible(&adapter->mbox_lock))
1194 return -1;
1195
1196 wrb = wrb_from_mbox(adapter);
1197 req = embedded_payload(wrb);
1198 ctxt = &req->context;
1199
Somnath Kotur106df1e2011-10-27 07:12:13 +00001200 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301201 OPCODE_COMMON_MCC_CREATE, sizeof(*req), wrb,
1202 NULL);
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001203
1204 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
1205
1206 AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
1207 AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301208 be_encoded_q_len(mccq->len));
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001209 AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
1210
1211 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1212
1213 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1214
1215 status = be_mbox_notify_wait(adapter);
1216 if (!status) {
1217 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
1218 mccq->id = le16_to_cpu(resp->id);
1219 mccq->created = true;
1220 }
1221
1222 mutex_unlock(&adapter->mbox_lock);
1223 return status;
1224}
1225
1226int be_cmd_mccq_create(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301227 struct be_queue_info *mccq, struct be_queue_info *cq)
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001228{
1229 int status;
1230
1231 status = be_cmd_mccq_ext_create(adapter, mccq, cq);
Vasundhara Volam666d39c2014-01-15 13:23:31 +05301232 if (status && BEx_chip(adapter)) {
Somnath Kotur34b1ef02011-06-01 00:33:22 +00001233 dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
1234 "or newer to avoid conflicting priorities between NIC "
1235 "and FCoE traffic");
1236 status = be_cmd_mccq_org_create(adapter, mccq, cq);
1237 }
1238 return status;
1239}
1240
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001241int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001242{
Sathya Perla77071332013-08-27 16:57:34 +05301243 struct be_mcc_wrb wrb = {0};
Sathya Perlab31c50a2009-09-17 10:30:13 -07001244 struct be_cmd_req_eth_tx_create *req;
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001245 struct be_queue_info *txq = &txo->q;
1246 struct be_queue_info *cq = &txo->cq;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001247 struct be_dma_mem *q_mem = &txq->dma_mem;
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001248 int status, ver = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001249
Sathya Perla77071332013-08-27 16:57:34 +05301250 req = embedded_payload(&wrb);
Somnath Kotur106df1e2011-10-27 07:12:13 +00001251 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301252 OPCODE_ETH_TX_CREATE, sizeof(*req), &wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001253
Padmanabh Ratnakar8b7756c2011-03-07 03:08:52 +00001254 if (lancer_chip(adapter)) {
1255 req->hdr.version = 1;
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001256 } else if (BEx_chip(adapter)) {
1257 if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC)
1258 req->hdr.version = 2;
1259 } else { /* For SH */
1260 req->hdr.version = 2;
Padmanabh Ratnakar8b7756c2011-03-07 03:08:52 +00001261 }
1262
Vasundhara Volam81b02652013-10-01 15:59:57 +05301263 if (req->hdr.version > 0)
1264 req->if_id = cpu_to_le16(adapter->if_handle);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001265 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
1266 req->ulp_num = BE_ULP1_NUM;
1267 req->type = BE_ETH_TX_RING_TYPE_STANDARD;
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001268 req->cq_id = cpu_to_le16(cq->id);
1269 req->queue_size = be_encoded_q_len(txq->len);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001270 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001271 ver = req->hdr.version;
1272
Sathya Perla77071332013-08-27 16:57:34 +05301273 status = be_cmd_notify_wait(adapter, &wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001274 if (!status) {
Sathya Perla77071332013-08-27 16:57:34 +05301275 struct be_cmd_resp_eth_tx_create *resp = embedded_payload(&wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001276 txq->id = le16_to_cpu(resp->cid);
Vasundhara Volam94d73aa2013-04-21 23:28:14 +00001277 if (ver == 2)
1278 txo->db_offset = le32_to_cpu(resp->db_offset);
1279 else
1280 txo->db_offset = DB_TXULP1_OFFSET;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001281 txq->created = true;
1282 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001283
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001284 return status;
1285}
1286
Sathya Perla482c9e72011-06-29 23:33:17 +00001287/* Uses MCC */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001288int be_cmd_rxq_create(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301289 struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
1290 u32 if_id, u32 rss, u8 *rss_id)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001291{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001292 struct be_mcc_wrb *wrb;
1293 struct be_cmd_req_eth_rx_create *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001294 struct be_dma_mem *q_mem = &rxq->dma_mem;
1295 int status;
1296
Sathya Perla482c9e72011-06-29 23:33:17 +00001297 spin_lock_bh(&adapter->mcc_lock);
Sathya Perlab31c50a2009-09-17 10:30:13 -07001298
Sathya Perla482c9e72011-06-29 23:33:17 +00001299 wrb = wrb_from_mccq(adapter);
1300 if (!wrb) {
1301 status = -EBUSY;
1302 goto err;
1303 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001304 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001305
Somnath Kotur106df1e2011-10-27 07:12:13 +00001306 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301307 OPCODE_ETH_RX_CREATE, sizeof(*req), wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001308
1309 req->cq_id = cpu_to_le16(cq_id);
1310 req->frag_size = fls(frag_size) - 1;
1311 req->num_pages = 2;
1312 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1313 req->interface_id = cpu_to_le32(if_id);
Sathya Perla10ef9ab2012-02-09 18:05:27 +00001314 req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001315 req->rss_queue = cpu_to_le32(rss);
1316
Sathya Perla482c9e72011-06-29 23:33:17 +00001317 status = be_mcc_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001318 if (!status) {
1319 struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
1320 rxq->id = le16_to_cpu(resp->id);
1321 rxq->created = true;
Sathya Perla3abcded2010-10-03 22:12:27 -07001322 *rss_id = resp->rss_id;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001323 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001324
Sathya Perla482c9e72011-06-29 23:33:17 +00001325err:
1326 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001327 return status;
1328}
1329
Sathya Perlab31c50a2009-09-17 10:30:13 -07001330/* Generic destroyer function for all types of queues
1331 * Uses Mbox
1332 */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001333int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301334 int queue_type)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001335{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001336 struct be_mcc_wrb *wrb;
1337 struct be_cmd_req_q_destroy *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001338 u8 subsys = 0, opcode = 0;
1339 int status;
1340
Ivan Vecera29849612010-12-14 05:43:19 +00001341 if (mutex_lock_interruptible(&adapter->mbox_lock))
1342 return -1;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001343
Sathya Perlab31c50a2009-09-17 10:30:13 -07001344 wrb = wrb_from_mbox(adapter);
1345 req = embedded_payload(wrb);
1346
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001347 switch (queue_type) {
1348 case QTYPE_EQ:
1349 subsys = CMD_SUBSYSTEM_COMMON;
1350 opcode = OPCODE_COMMON_EQ_DESTROY;
1351 break;
1352 case QTYPE_CQ:
1353 subsys = CMD_SUBSYSTEM_COMMON;
1354 opcode = OPCODE_COMMON_CQ_DESTROY;
1355 break;
1356 case QTYPE_TXQ:
1357 subsys = CMD_SUBSYSTEM_ETH;
1358 opcode = OPCODE_ETH_TX_DESTROY;
1359 break;
1360 case QTYPE_RXQ:
1361 subsys = CMD_SUBSYSTEM_ETH;
1362 opcode = OPCODE_ETH_RX_DESTROY;
1363 break;
Sathya Perla5fb379e2009-06-18 00:02:59 +00001364 case QTYPE_MCCQ:
1365 subsys = CMD_SUBSYSTEM_COMMON;
1366 opcode = OPCODE_COMMON_MCC_DESTROY;
1367 break;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001368 default:
Sathya Perla5f0b8492009-07-27 22:52:56 +00001369 BUG();
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001370 }
Ajit Khaparded744b442009-12-03 06:12:06 +00001371
Somnath Kotur106df1e2011-10-27 07:12:13 +00001372 be_wrb_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req), wrb,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301373 NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001374 req->id = cpu_to_le16(q->id);
1375
Sathya Perlab31c50a2009-09-17 10:30:13 -07001376 status = be_mbox_notify_wait(adapter);
Padmanabh Ratnakaraa790db2012-10-20 06:03:25 +00001377 q->created = false;
Sathya Perla5f0b8492009-07-27 22:52:56 +00001378
Ivan Vecera29849612010-12-14 05:43:19 +00001379 mutex_unlock(&adapter->mbox_lock);
Sathya Perla482c9e72011-06-29 23:33:17 +00001380 return status;
1381}
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001382
Sathya Perla482c9e72011-06-29 23:33:17 +00001383/* Uses MCC */
1384int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
1385{
1386 struct be_mcc_wrb *wrb;
1387 struct be_cmd_req_q_destroy *req;
1388 int status;
1389
1390 spin_lock_bh(&adapter->mcc_lock);
1391
1392 wrb = wrb_from_mccq(adapter);
1393 if (!wrb) {
1394 status = -EBUSY;
1395 goto err;
1396 }
1397 req = embedded_payload(wrb);
1398
Somnath Kotur106df1e2011-10-27 07:12:13 +00001399 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301400 OPCODE_ETH_RX_DESTROY, sizeof(*req), wrb, NULL);
Sathya Perla482c9e72011-06-29 23:33:17 +00001401 req->id = cpu_to_le16(q->id);
1402
1403 status = be_mcc_notify_wait(adapter);
Padmanabh Ratnakaraa790db2012-10-20 06:03:25 +00001404 q->created = false;
Sathya Perla482c9e72011-06-29 23:33:17 +00001405
1406err:
1407 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001408 return status;
1409}
1410
Sathya Perlab31c50a2009-09-17 10:30:13 -07001411/* Create an rx filtering policy configuration on an i/f
Sathya Perlabea50982013-08-27 16:57:33 +05301412 * Will use MBOX only if MCCQ has not been created.
Sathya Perlab31c50a2009-09-17 10:30:13 -07001413 */
Sathya Perla73d540f2009-10-14 20:20:42 +00001414int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
Padmanabh Ratnakar1578e772012-06-07 04:37:08 +00001415 u32 *if_handle, u32 domain)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001416{
Sathya Perlabea50982013-08-27 16:57:33 +05301417 struct be_mcc_wrb wrb = {0};
Sathya Perlab31c50a2009-09-17 10:30:13 -07001418 struct be_cmd_req_if_create *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001419 int status;
1420
Sathya Perlabea50982013-08-27 16:57:33 +05301421 req = embedded_payload(&wrb);
Somnath Kotur106df1e2011-10-27 07:12:13 +00001422 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301423 OPCODE_COMMON_NTWK_INTERFACE_CREATE,
1424 sizeof(*req), &wrb, NULL);
Sarveshwar Bandiba343c72010-03-31 02:56:12 +00001425 req->hdr.domain = domain;
Sathya Perla73d540f2009-10-14 20:20:42 +00001426 req->capability_flags = cpu_to_le32(cap_flags);
1427 req->enable_flags = cpu_to_le32(en_flags);
Padmanabh Ratnakar1578e772012-06-07 04:37:08 +00001428 req->pmac_invalid = true;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001429
Sathya Perlabea50982013-08-27 16:57:33 +05301430 status = be_cmd_notify_wait(adapter, &wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001431 if (!status) {
Sathya Perlabea50982013-08-27 16:57:33 +05301432 struct be_cmd_resp_if_create *resp = embedded_payload(&wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001433 *if_handle = le32_to_cpu(resp->interface_id);
Sathya Perlab5bb9772013-07-23 15:25:01 +05301434
1435 /* Hack to retrieve VF's pmac-id on BE3 */
1436 if (BE3_chip(adapter) && !be_physfn(adapter))
1437 adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001438 }
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001439 return status;
1440}
1441
Sathya Perlaf9449ab2011-10-24 02:45:01 +00001442/* Uses MCCQ */
Sathya Perla30128032011-11-10 19:17:57 +00001443int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001444{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001445 struct be_mcc_wrb *wrb;
1446 struct be_cmd_req_if_destroy *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001447 int status;
1448
Sathya Perla30128032011-11-10 19:17:57 +00001449 if (interface_id == -1)
Sathya Perlaf9449ab2011-10-24 02:45:01 +00001450 return 0;
Sathya Perlab31c50a2009-09-17 10:30:13 -07001451
Sathya Perlaf9449ab2011-10-24 02:45:01 +00001452 spin_lock_bh(&adapter->mcc_lock);
1453
1454 wrb = wrb_from_mccq(adapter);
1455 if (!wrb) {
1456 status = -EBUSY;
1457 goto err;
1458 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001459 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001460
Somnath Kotur106df1e2011-10-27 07:12:13 +00001461 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301462 OPCODE_COMMON_NTWK_INTERFACE_DESTROY,
1463 sizeof(*req), wrb, NULL);
Ajit Khaparde658681f2011-02-11 13:34:46 +00001464 req->hdr.domain = domain;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001465 req->interface_id = cpu_to_le32(interface_id);
Sathya Perlab31c50a2009-09-17 10:30:13 -07001466
Sathya Perlaf9449ab2011-10-24 02:45:01 +00001467 status = be_mcc_notify_wait(adapter);
1468err:
1469 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001470 return status;
1471}
1472
1473/* Get stats is a non embedded command: the request is not embedded inside
1474 * WRB but is a separate dma memory block
Sathya Perlab31c50a2009-09-17 10:30:13 -07001475 * Uses asynchronous MCC
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001476 */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001477int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001478{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001479 struct be_mcc_wrb *wrb;
Ajit Khaparde89a88ab2011-05-16 07:36:18 +00001480 struct be_cmd_req_hdr *hdr;
Sathya Perla713d03942009-11-22 22:02:45 +00001481 int status = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001482
Sathya Perlab31c50a2009-09-17 10:30:13 -07001483 spin_lock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001484
Sathya Perlab31c50a2009-09-17 10:30:13 -07001485 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001486 if (!wrb) {
1487 status = -EBUSY;
1488 goto err;
1489 }
Ajit Khaparde89a88ab2011-05-16 07:36:18 +00001490 hdr = nonemb_cmd->va;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001491
Somnath Kotur106df1e2011-10-27 07:12:13 +00001492 be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301493 OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb,
1494 nonemb_cmd);
Ajit Khaparde89a88ab2011-05-16 07:36:18 +00001495
Sathya Perlaca34fe32012-11-06 17:48:56 +00001496 /* version 1 of the cmd is not supported only by BE2 */
Ajit Khaparde61000862013-10-03 16:16:33 -05001497 if (BE2_chip(adapter))
1498 hdr->version = 0;
1499 if (BE3_chip(adapter) || lancer_chip(adapter))
Ajit Khaparde89a88ab2011-05-16 07:36:18 +00001500 hdr->version = 1;
Ajit Khaparde61000862013-10-03 16:16:33 -05001501 else
1502 hdr->version = 2;
Ajit Khaparde89a88ab2011-05-16 07:36:18 +00001503
Sathya Perlab31c50a2009-09-17 10:30:13 -07001504 be_mcc_notify(adapter);
Ajit Khapardeb2aebe62011-02-20 11:41:39 +00001505 adapter->stats_cmd_sent = true;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001506
Sathya Perla713d03942009-11-22 22:02:45 +00001507err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001508 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla713d03942009-11-22 22:02:45 +00001509 return status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001510}
1511
Selvin Xavier005d5692011-05-16 07:36:35 +00001512/* Lancer Stats */
1513int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301514 struct be_dma_mem *nonemb_cmd)
Selvin Xavier005d5692011-05-16 07:36:35 +00001515{
1516
1517 struct be_mcc_wrb *wrb;
1518 struct lancer_cmd_req_pport_stats *req;
Selvin Xavier005d5692011-05-16 07:36:35 +00001519 int status = 0;
1520
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00001521 if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
1522 CMD_SUBSYSTEM_ETH))
1523 return -EPERM;
1524
Selvin Xavier005d5692011-05-16 07:36:35 +00001525 spin_lock_bh(&adapter->mcc_lock);
1526
1527 wrb = wrb_from_mccq(adapter);
1528 if (!wrb) {
1529 status = -EBUSY;
1530 goto err;
1531 }
1532 req = nonemb_cmd->va;
Selvin Xavier005d5692011-05-16 07:36:35 +00001533
Somnath Kotur106df1e2011-10-27 07:12:13 +00001534 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301535 OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size,
1536 wrb, nonemb_cmd);
Selvin Xavier005d5692011-05-16 07:36:35 +00001537
Padmanabh Ratnakard51ebd32012-04-25 01:46:52 +00001538 req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
Selvin Xavier005d5692011-05-16 07:36:35 +00001539 req->cmd_params.params.reset_stats = 0;
1540
Selvin Xavier005d5692011-05-16 07:36:35 +00001541 be_mcc_notify(adapter);
1542 adapter->stats_cmd_sent = true;
1543
1544err:
1545 spin_unlock_bh(&adapter->mcc_lock);
1546 return status;
1547}
1548
Sathya Perla323ff712012-09-28 04:39:43 +00001549static int be_mac_to_link_speed(int mac_speed)
1550{
1551 switch (mac_speed) {
1552 case PHY_LINK_SPEED_ZERO:
1553 return 0;
1554 case PHY_LINK_SPEED_10MBPS:
1555 return 10;
1556 case PHY_LINK_SPEED_100MBPS:
1557 return 100;
1558 case PHY_LINK_SPEED_1GBPS:
1559 return 1000;
1560 case PHY_LINK_SPEED_10GBPS:
1561 return 10000;
Vasundhara Volamb971f842013-08-06 09:27:15 +05301562 case PHY_LINK_SPEED_20GBPS:
1563 return 20000;
1564 case PHY_LINK_SPEED_25GBPS:
1565 return 25000;
1566 case PHY_LINK_SPEED_40GBPS:
1567 return 40000;
Sathya Perla323ff712012-09-28 04:39:43 +00001568 }
1569 return 0;
1570}
1571
1572/* Uses synchronous mcc
1573 * Returns link_speed in Mbps
1574 */
1575int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
1576 u8 *link_status, u32 dom)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001577{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001578 struct be_mcc_wrb *wrb;
1579 struct be_cmd_req_link_status *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001580 int status;
1581
Sathya Perlab31c50a2009-09-17 10:30:13 -07001582 spin_lock_bh(&adapter->mcc_lock);
1583
Ajit Khapardeb236916a2011-12-30 12:15:40 +00001584 if (link_status)
1585 *link_status = LINK_DOWN;
1586
Sathya Perlab31c50a2009-09-17 10:30:13 -07001587 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001588 if (!wrb) {
1589 status = -EBUSY;
1590 goto err;
1591 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001592 req = embedded_payload(wrb);
Sathya Perlaa8f447bd2009-06-18 00:10:27 +00001593
Padmanabh Ratnakar57cd80d2012-02-03 09:49:46 +00001594 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301595 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1596 sizeof(*req), wrb, NULL);
Padmanabh Ratnakar57cd80d2012-02-03 09:49:46 +00001597
Sathya Perlaca34fe32012-11-06 17:48:56 +00001598 /* version 1 of the cmd is not supported only by BE2 */
1599 if (!BE2_chip(adapter))
Padmanabh Ratnakardaad6162011-11-16 02:03:45 +00001600 req->hdr.version = 1;
1601
Padmanabh Ratnakar57cd80d2012-02-03 09:49:46 +00001602 req->hdr.domain = dom;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001603
Sathya Perlab31c50a2009-09-17 10:30:13 -07001604 status = be_mcc_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001605 if (!status) {
1606 struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
Sathya Perla323ff712012-09-28 04:39:43 +00001607 if (link_speed) {
1608 *link_speed = resp->link_speed ?
1609 le16_to_cpu(resp->link_speed) * 10 :
1610 be_mac_to_link_speed(resp->mac_speed);
1611
1612 if (!resp->logical_link_status)
1613 *link_speed = 0;
Sarveshwar Bandi0388f252009-10-28 04:15:20 -07001614 }
Ajit Khapardeb236916a2011-12-30 12:15:40 +00001615 if (link_status)
1616 *link_status = resp->logical_link_status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001617 }
1618
Sathya Perla713d03942009-11-22 22:02:45 +00001619err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001620 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001621 return status;
1622}
1623
Ajit Khaparde609ff3b2011-02-20 11:42:07 +00001624/* Uses synchronous mcc */
1625int be_cmd_get_die_temperature(struct be_adapter *adapter)
1626{
1627 struct be_mcc_wrb *wrb;
1628 struct be_cmd_req_get_cntl_addnl_attribs *req;
Vasundhara Volam117affe2013-08-06 09:27:20 +05301629 int status = 0;
Ajit Khaparde609ff3b2011-02-20 11:42:07 +00001630
1631 spin_lock_bh(&adapter->mcc_lock);
1632
1633 wrb = wrb_from_mccq(adapter);
1634 if (!wrb) {
1635 status = -EBUSY;
1636 goto err;
1637 }
1638 req = embedded_payload(wrb);
1639
Somnath Kotur106df1e2011-10-27 07:12:13 +00001640 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301641 OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES,
1642 sizeof(*req), wrb, NULL);
Ajit Khaparde609ff3b2011-02-20 11:42:07 +00001643
Somnath Kotur3de09452011-09-30 07:25:05 +00001644 be_mcc_notify(adapter);
Ajit Khaparde609ff3b2011-02-20 11:42:07 +00001645
1646err:
1647 spin_unlock_bh(&adapter->mcc_lock);
1648 return status;
1649}
1650
Somnath Kotur311fddc2011-03-16 21:22:43 +00001651/* Uses synchronous mcc */
1652int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
1653{
1654 struct be_mcc_wrb *wrb;
1655 struct be_cmd_req_get_fat *req;
1656 int status;
1657
1658 spin_lock_bh(&adapter->mcc_lock);
1659
1660 wrb = wrb_from_mccq(adapter);
1661 if (!wrb) {
1662 status = -EBUSY;
1663 goto err;
1664 }
1665 req = embedded_payload(wrb);
1666
Somnath Kotur106df1e2011-10-27 07:12:13 +00001667 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301668 OPCODE_COMMON_MANAGE_FAT, sizeof(*req), wrb,
1669 NULL);
Somnath Kotur311fddc2011-03-16 21:22:43 +00001670 req->fat_operation = cpu_to_le32(QUERY_FAT);
1671 status = be_mcc_notify_wait(adapter);
1672 if (!status) {
1673 struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
1674 if (log_size && resp->log_size)
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001675 *log_size = le32_to_cpu(resp->log_size) -
1676 sizeof(u32);
Somnath Kotur311fddc2011-03-16 21:22:43 +00001677 }
1678err:
1679 spin_unlock_bh(&adapter->mcc_lock);
1680 return status;
1681}
1682
1683void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
1684{
1685 struct be_dma_mem get_fat_cmd;
1686 struct be_mcc_wrb *wrb;
1687 struct be_cmd_req_get_fat *req;
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001688 u32 offset = 0, total_size, buf_size,
1689 log_offset = sizeof(u32), payload_len;
Somnath Kotur311fddc2011-03-16 21:22:43 +00001690 int status;
1691
1692 if (buf_len == 0)
1693 return;
1694
1695 total_size = buf_len;
1696
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001697 get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
1698 get_fat_cmd.va = pci_alloc_consistent(adapter->pdev,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301699 get_fat_cmd.size,
1700 &get_fat_cmd.dma);
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001701 if (!get_fat_cmd.va) {
1702 status = -ENOMEM;
1703 dev_err(&adapter->pdev->dev,
1704 "Memory allocation failure while retrieving FAT data\n");
1705 return;
1706 }
1707
Somnath Kotur311fddc2011-03-16 21:22:43 +00001708 spin_lock_bh(&adapter->mcc_lock);
1709
Somnath Kotur311fddc2011-03-16 21:22:43 +00001710 while (total_size) {
1711 buf_size = min(total_size, (u32)60*1024);
1712 total_size -= buf_size;
1713
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001714 wrb = wrb_from_mccq(adapter);
1715 if (!wrb) {
1716 status = -EBUSY;
Somnath Kotur311fddc2011-03-16 21:22:43 +00001717 goto err;
1718 }
1719 req = get_fat_cmd.va;
Somnath Kotur311fddc2011-03-16 21:22:43 +00001720
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001721 payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
Somnath Kotur106df1e2011-10-27 07:12:13 +00001722 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301723 OPCODE_COMMON_MANAGE_FAT, payload_len,
1724 wrb, &get_fat_cmd);
Somnath Kotur311fddc2011-03-16 21:22:43 +00001725
1726 req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
1727 req->read_log_offset = cpu_to_le32(log_offset);
1728 req->read_log_length = cpu_to_le32(buf_size);
1729 req->data_buffer_size = cpu_to_le32(buf_size);
1730
1731 status = be_mcc_notify_wait(adapter);
1732 if (!status) {
1733 struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
1734 memcpy(buf + offset,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301735 resp->data_buffer,
1736 le32_to_cpu(resp->read_log_length));
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001737 } else {
Somnath Kotur311fddc2011-03-16 21:22:43 +00001738 dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001739 goto err;
1740 }
Somnath Kotur311fddc2011-03-16 21:22:43 +00001741 offset += buf_size;
1742 log_offset += buf_size;
1743 }
1744err:
Somnath Koturfe2a70e2011-04-21 03:18:12 +00001745 pci_free_consistent(adapter->pdev, get_fat_cmd.size,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301746 get_fat_cmd.va, get_fat_cmd.dma);
Somnath Kotur311fddc2011-03-16 21:22:43 +00001747 spin_unlock_bh(&adapter->mcc_lock);
1748}
1749
Sathya Perla04b71172011-09-27 13:30:27 -04001750/* Uses synchronous mcc */
1751int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301752 char *fw_on_flash)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001753{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001754 struct be_mcc_wrb *wrb;
1755 struct be_cmd_req_get_fw_version *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001756 int status;
1757
Sathya Perla04b71172011-09-27 13:30:27 -04001758 spin_lock_bh(&adapter->mcc_lock);
Sathya Perlab31c50a2009-09-17 10:30:13 -07001759
Sathya Perla04b71172011-09-27 13:30:27 -04001760 wrb = wrb_from_mccq(adapter);
1761 if (!wrb) {
1762 status = -EBUSY;
1763 goto err;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001764 }
1765
Sathya Perla04b71172011-09-27 13:30:27 -04001766 req = embedded_payload(wrb);
Sathya Perla04b71172011-09-27 13:30:27 -04001767
Somnath Kotur106df1e2011-10-27 07:12:13 +00001768 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301769 OPCODE_COMMON_GET_FW_VERSION, sizeof(*req), wrb,
1770 NULL);
Sathya Perla04b71172011-09-27 13:30:27 -04001771 status = be_mcc_notify_wait(adapter);
1772 if (!status) {
1773 struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
1774 strcpy(fw_ver, resp->firmware_version_string);
1775 if (fw_on_flash)
1776 strcpy(fw_on_flash, resp->fw_on_flash_version_string);
1777 }
1778err:
1779 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001780 return status;
1781}
1782
Sathya Perlab31c50a2009-09-17 10:30:13 -07001783/* set the EQ delay interval of an EQ to specified value
1784 * Uses async mcc
1785 */
Sathya Perla2632baf2013-10-01 16:00:00 +05301786int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
1787 int num)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001788{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001789 struct be_mcc_wrb *wrb;
1790 struct be_cmd_req_modify_eq_delay *req;
Sathya Perla2632baf2013-10-01 16:00:00 +05301791 int status = 0, i;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001792
Sathya Perlab31c50a2009-09-17 10:30:13 -07001793 spin_lock_bh(&adapter->mcc_lock);
1794
1795 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001796 if (!wrb) {
1797 status = -EBUSY;
1798 goto err;
1799 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001800 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001801
Somnath Kotur106df1e2011-10-27 07:12:13 +00001802 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301803 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req), wrb,
1804 NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001805
Sathya Perla2632baf2013-10-01 16:00:00 +05301806 req->num_eq = cpu_to_le32(num);
1807 for (i = 0; i < num; i++) {
1808 req->set_eqd[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
1809 req->set_eqd[i].phase = 0;
1810 req->set_eqd[i].delay_multiplier =
1811 cpu_to_le32(set_eqd[i].delay_multiplier);
1812 }
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001813
Sathya Perlab31c50a2009-09-17 10:30:13 -07001814 be_mcc_notify(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001815err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001816 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla713d03942009-11-22 22:02:45 +00001817 return status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001818}
1819
Sathya Perlab31c50a2009-09-17 10:30:13 -07001820/* Uses sycnhronous mcc */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001821int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
Kalesh AP4d567d92014-05-09 13:29:17 +05301822 u32 num)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001823{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001824 struct be_mcc_wrb *wrb;
1825 struct be_cmd_req_vlan_config *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001826 int status;
1827
Sathya Perlab31c50a2009-09-17 10:30:13 -07001828 spin_lock_bh(&adapter->mcc_lock);
1829
1830 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001831 if (!wrb) {
1832 status = -EBUSY;
1833 goto err;
1834 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001835 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001836
Somnath Kotur106df1e2011-10-27 07:12:13 +00001837 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301838 OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req),
1839 wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001840
1841 req->interface_id = if_id;
Ajit Khaparde012bd382013-11-18 10:44:24 -06001842 req->untagged = BE_IF_FLAGS_UNTAGGED & be_if_cap_flags(adapter) ? 1 : 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001843 req->num_vlan = num;
Kalesh AP4d567d92014-05-09 13:29:17 +05301844 memcpy(req->normal_vlan, vtag_array,
1845 req->num_vlan * sizeof(vtag_array[0]));
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001846
Sathya Perlab31c50a2009-09-17 10:30:13 -07001847 status = be_mcc_notify_wait(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001848err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001849 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001850 return status;
1851}
1852
Sathya Perla5b8821b2011-08-02 19:57:44 +00001853int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001854{
Sathya Perla6ac7b682009-06-18 00:05:54 +00001855 struct be_mcc_wrb *wrb;
Sathya Perla5b8821b2011-08-02 19:57:44 +00001856 struct be_dma_mem *mem = &adapter->rx_filter;
1857 struct be_cmd_req_rx_filter *req = mem->va;
Sathya Perlae7b909a2009-11-22 22:01:10 +00001858 int status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001859
Sathya Perla8788fdc2009-07-27 22:52:03 +00001860 spin_lock_bh(&adapter->mcc_lock);
Sathya Perla6ac7b682009-06-18 00:05:54 +00001861
Sathya Perlab31c50a2009-09-17 10:30:13 -07001862 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001863 if (!wrb) {
1864 status = -EBUSY;
1865 goto err;
1866 }
Sathya Perla5b8821b2011-08-02 19:57:44 +00001867 memset(req, 0, sizeof(*req));
Somnath Kotur106df1e2011-10-27 07:12:13 +00001868 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301869 OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req),
1870 wrb, mem);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001871
Sathya Perla5b8821b2011-08-02 19:57:44 +00001872 req->if_id = cpu_to_le32(adapter->if_handle);
1873 if (flags & IFF_PROMISC) {
1874 req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301875 BE_IF_FLAGS_VLAN_PROMISCUOUS |
1876 BE_IF_FLAGS_MCAST_PROMISCUOUS);
Sathya Perla5b8821b2011-08-02 19:57:44 +00001877 if (value == ON)
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301878 req->if_flags =
1879 cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
1880 BE_IF_FLAGS_VLAN_PROMISCUOUS |
1881 BE_IF_FLAGS_MCAST_PROMISCUOUS);
Sathya Perla5b8821b2011-08-02 19:57:44 +00001882 } else if (flags & IFF_ALLMULTI) {
1883 req->if_flags_mask = req->if_flags =
Sathya Perla8e7d3f62011-09-27 13:29:38 -04001884 cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
Ajit Khaparded9d604f2013-09-27 15:17:58 -05001885 } else if (flags & BE_FLAGS_VLAN_PROMISC) {
1886 req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_VLAN_PROMISCUOUS);
1887
1888 if (value == ON)
1889 req->if_flags =
1890 cpu_to_le32(BE_IF_FLAGS_VLAN_PROMISCUOUS);
Sathya Perla24307ee2009-06-18 00:09:25 +00001891 } else {
Sathya Perla5b8821b2011-08-02 19:57:44 +00001892 struct netdev_hw_addr *ha;
1893 int i = 0;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001894
Sathya Perla8e7d3f62011-09-27 13:29:38 -04001895 req->if_flags_mask = req->if_flags =
1896 cpu_to_le32(BE_IF_FLAGS_MULTICAST);
Padmanabh Ratnakar1610c792011-11-03 01:49:27 +00001897
1898 /* Reset mcast promisc mode if already set by setting mask
1899 * and not setting flags field
1900 */
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00001901 req->if_flags_mask |=
1902 cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS &
Sathya Perla92bf14a2013-08-27 16:57:32 +05301903 be_if_cap_flags(adapter));
Padmanabh Ratnakar016f97b2011-11-03 01:49:13 +00001904 req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev));
Sathya Perla5b8821b2011-08-02 19:57:44 +00001905 netdev_for_each_mc_addr(ha, adapter->netdev)
1906 memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
1907 }
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001908
Ajit Khaparde012bd382013-11-18 10:44:24 -06001909 if ((req->if_flags_mask & cpu_to_le32(be_if_cap_flags(adapter))) !=
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301910 req->if_flags_mask) {
Ajit Khaparde012bd382013-11-18 10:44:24 -06001911 dev_warn(&adapter->pdev->dev,
1912 "Cannot set rx filter flags 0x%x\n",
1913 req->if_flags_mask);
1914 dev_warn(&adapter->pdev->dev,
1915 "Interface is capable of 0x%x flags only\n",
1916 be_if_cap_flags(adapter));
1917 }
1918 req->if_flags_mask &= cpu_to_le32(be_if_cap_flags(adapter));
1919
Sathya Perla0d1d5872011-08-03 05:19:27 -07001920 status = be_mcc_notify_wait(adapter);
Ajit Khaparde012bd382013-11-18 10:44:24 -06001921
Sathya Perla713d03942009-11-22 22:02:45 +00001922err:
Sathya Perla8788fdc2009-07-27 22:52:03 +00001923 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perlae7b909a2009-11-22 22:01:10 +00001924 return status;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001925}
1926
Sathya Perlab31c50a2009-09-17 10:30:13 -07001927/* Uses synchrounous mcc */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001928int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001929{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001930 struct be_mcc_wrb *wrb;
1931 struct be_cmd_req_set_flow_control *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001932 int status;
1933
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00001934 if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
1935 CMD_SUBSYSTEM_COMMON))
1936 return -EPERM;
1937
Sathya Perlab31c50a2009-09-17 10:30:13 -07001938 spin_lock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001939
Sathya Perlab31c50a2009-09-17 10:30:13 -07001940 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001941 if (!wrb) {
1942 status = -EBUSY;
1943 goto err;
1944 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001945 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001946
Somnath Kotur106df1e2011-10-27 07:12:13 +00001947 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301948 OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req),
1949 wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001950
1951 req->tx_flow_control = cpu_to_le16((u16)tx_fc);
1952 req->rx_flow_control = cpu_to_le16((u16)rx_fc);
1953
Sathya Perlab31c50a2009-09-17 10:30:13 -07001954 status = be_mcc_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001955
Sathya Perla713d03942009-11-22 22:02:45 +00001956err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001957 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001958 return status;
1959}
1960
Sathya Perlab31c50a2009-09-17 10:30:13 -07001961/* Uses sycn mcc */
Sathya Perla8788fdc2009-07-27 22:52:03 +00001962int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001963{
Sathya Perlab31c50a2009-09-17 10:30:13 -07001964 struct be_mcc_wrb *wrb;
1965 struct be_cmd_req_get_flow_control *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001966 int status;
1967
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00001968 if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
1969 CMD_SUBSYSTEM_COMMON))
1970 return -EPERM;
1971
Sathya Perlab31c50a2009-09-17 10:30:13 -07001972 spin_lock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001973
Sathya Perlab31c50a2009-09-17 10:30:13 -07001974 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00001975 if (!wrb) {
1976 status = -EBUSY;
1977 goto err;
1978 }
Sathya Perlab31c50a2009-09-17 10:30:13 -07001979 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001980
Somnath Kotur106df1e2011-10-27 07:12:13 +00001981 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05301982 OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req),
1983 wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001984
Sathya Perlab31c50a2009-09-17 10:30:13 -07001985 status = be_mcc_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001986 if (!status) {
1987 struct be_cmd_resp_get_flow_control *resp =
1988 embedded_payload(wrb);
1989 *tx_fc = le16_to_cpu(resp->tx_flow_control);
1990 *rx_fc = le16_to_cpu(resp->rx_flow_control);
1991 }
1992
Sathya Perla713d03942009-11-22 22:02:45 +00001993err:
Sathya Perlab31c50a2009-09-17 10:30:13 -07001994 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07001995 return status;
1996}
1997
Sathya Perlab31c50a2009-09-17 10:30:13 -07001998/* Uses mbox */
Sathya Perla3abcded2010-10-03 22:12:27 -07001999int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
Vasundhara Volam0ad31572013-04-21 23:28:16 +00002000 u32 *mode, u32 *caps, u16 *asic_rev)
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002001{
Sathya Perlab31c50a2009-09-17 10:30:13 -07002002 struct be_mcc_wrb *wrb;
2003 struct be_cmd_req_query_fw_cfg *req;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002004 int status;
2005
Ivan Vecera29849612010-12-14 05:43:19 +00002006 if (mutex_lock_interruptible(&adapter->mbox_lock))
2007 return -1;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002008
Sathya Perlab31c50a2009-09-17 10:30:13 -07002009 wrb = wrb_from_mbox(adapter);
2010 req = embedded_payload(wrb);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002011
Somnath Kotur106df1e2011-10-27 07:12:13 +00002012 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302013 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
2014 sizeof(*req), wrb, NULL);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002015
Sathya Perlab31c50a2009-09-17 10:30:13 -07002016 status = be_mbox_notify_wait(adapter);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002017 if (!status) {
2018 struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
2019 *port_num = le32_to_cpu(resp->phys_port);
Ajit Khaparde3486be22010-07-23 02:04:54 +00002020 *mode = le32_to_cpu(resp->function_mode);
Sathya Perla3abcded2010-10-03 22:12:27 -07002021 *caps = le32_to_cpu(resp->function_caps);
Vasundhara Volam0ad31572013-04-21 23:28:16 +00002022 *asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002023 }
2024
Ivan Vecera29849612010-12-14 05:43:19 +00002025 mutex_unlock(&adapter->mbox_lock);
Sathya Perla6b7c5b92009-03-11 23:32:03 -07002026 return status;
2027}
sarveshwarb14074ea2009-08-05 13:05:24 -07002028
Sathya Perlab31c50a2009-09-17 10:30:13 -07002029/* Uses mbox */
sarveshwarb14074ea2009-08-05 13:05:24 -07002030int be_cmd_reset_function(struct be_adapter *adapter)
2031{
Sathya Perlab31c50a2009-09-17 10:30:13 -07002032 struct be_mcc_wrb *wrb;
2033 struct be_cmd_req_hdr *req;
sarveshwarb14074ea2009-08-05 13:05:24 -07002034 int status;
2035
Padmanabh Ratnakarbf99e502012-07-12 03:56:58 +00002036 if (lancer_chip(adapter)) {
2037 status = lancer_wait_ready(adapter);
2038 if (!status) {
2039 iowrite32(SLI_PORT_CONTROL_IP_MASK,
2040 adapter->db + SLIPORT_CONTROL_OFFSET);
2041 status = lancer_test_and_set_rdy_state(adapter);
2042 }
2043 if (status) {
2044 dev_err(&adapter->pdev->dev,
2045 "Adapter in non recoverable error\n");
2046 }
2047 return status;
2048 }
2049
Ivan Vecera29849612010-12-14 05:43:19 +00002050 if (mutex_lock_interruptible(&adapter->mbox_lock))
2051 return -1;
sarveshwarb14074ea2009-08-05 13:05:24 -07002052
Sathya Perlab31c50a2009-09-17 10:30:13 -07002053 wrb = wrb_from_mbox(adapter);
2054 req = embedded_payload(wrb);
sarveshwarb14074ea2009-08-05 13:05:24 -07002055
Somnath Kotur106df1e2011-10-27 07:12:13 +00002056 be_wrb_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302057 OPCODE_COMMON_FUNCTION_RESET, sizeof(*req), wrb,
2058 NULL);
sarveshwarb14074ea2009-08-05 13:05:24 -07002059
Sathya Perlab31c50a2009-09-17 10:30:13 -07002060 status = be_mbox_notify_wait(adapter);
sarveshwarb14074ea2009-08-05 13:05:24 -07002061
Ivan Vecera29849612010-12-14 05:43:19 +00002062 mutex_unlock(&adapter->mbox_lock);
sarveshwarb14074ea2009-08-05 13:05:24 -07002063 return status;
2064}
Ajit Khaparde84517482009-09-04 03:12:16 +00002065
Suresh Reddy594ad542013-04-25 23:03:20 +00002066int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302067 u32 rss_hash_opts, u16 table_size, u8 *rss_hkey)
Sathya Perla3abcded2010-10-03 22:12:27 -07002068{
2069 struct be_mcc_wrb *wrb;
2070 struct be_cmd_req_rss_config *req;
Sathya Perla3abcded2010-10-03 22:12:27 -07002071 int status;
2072
Vasundhara Volamda1388d2014-01-06 13:02:23 +05302073 if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
2074 return 0;
2075
Kalesh APb51aa362014-05-09 13:29:19 +05302076 spin_lock_bh(&adapter->mcc_lock);
Sathya Perla3abcded2010-10-03 22:12:27 -07002077
Kalesh APb51aa362014-05-09 13:29:19 +05302078 wrb = wrb_from_mccq(adapter);
2079 if (!wrb) {
2080 status = -EBUSY;
2081 goto err;
2082 }
Sathya Perla3abcded2010-10-03 22:12:27 -07002083 req = embedded_payload(wrb);
2084
Somnath Kotur106df1e2011-10-27 07:12:13 +00002085 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302086 OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
Sathya Perla3abcded2010-10-03 22:12:27 -07002087
2088 req->if_id = cpu_to_le32(adapter->if_handle);
Suresh Reddy594ad542013-04-25 23:03:20 +00002089 req->enable_rss = cpu_to_le16(rss_hash_opts);
Sathya Perla3abcded2010-10-03 22:12:27 -07002090 req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
Suresh Reddy594ad542013-04-25 23:03:20 +00002091
Kalesh APb51aa362014-05-09 13:29:19 +05302092 if (!BEx_chip(adapter))
Suresh Reddy594ad542013-04-25 23:03:20 +00002093 req->hdr.version = 1;
2094
Sathya Perla3abcded2010-10-03 22:12:27 -07002095 memcpy(req->cpu_table, rsstable, table_size);
Venkata Duvvurue2557872014-04-21 15:38:00 +05302096 memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
Sathya Perla3abcded2010-10-03 22:12:27 -07002097 be_dws_cpu_to_le(req->hash, sizeof(req->hash));
2098
Kalesh APb51aa362014-05-09 13:29:19 +05302099 status = be_mcc_notify_wait(adapter);
2100err:
2101 spin_unlock_bh(&adapter->mcc_lock);
Sathya Perla3abcded2010-10-03 22:12:27 -07002102 return status;
2103}
2104
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002105/* Uses sync mcc */
2106int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302107 u8 bcn, u8 sts, u8 state)
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002108{
2109 struct be_mcc_wrb *wrb;
2110 struct be_cmd_req_enable_disable_beacon *req;
2111 int status;
2112
2113 spin_lock_bh(&adapter->mcc_lock);
2114
2115 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00002116 if (!wrb) {
2117 status = -EBUSY;
2118 goto err;
2119 }
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002120 req = embedded_payload(wrb);
2121
Somnath Kotur106df1e2011-10-27 07:12:13 +00002122 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302123 OPCODE_COMMON_ENABLE_DISABLE_BEACON,
2124 sizeof(*req), wrb, NULL);
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002125
2126 req->port_num = port_num;
2127 req->beacon_state = state;
2128 req->beacon_duration = bcn;
2129 req->status_duration = sts;
2130
2131 status = be_mcc_notify_wait(adapter);
2132
Sathya Perla713d03942009-11-22 22:02:45 +00002133err:
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002134 spin_unlock_bh(&adapter->mcc_lock);
2135 return status;
2136}
2137
2138/* Uses sync mcc */
2139int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
2140{
2141 struct be_mcc_wrb *wrb;
2142 struct be_cmd_req_get_beacon_state *req;
2143 int status;
2144
2145 spin_lock_bh(&adapter->mcc_lock);
2146
2147 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00002148 if (!wrb) {
2149 status = -EBUSY;
2150 goto err;
2151 }
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002152 req = embedded_payload(wrb);
2153
Somnath Kotur106df1e2011-10-27 07:12:13 +00002154 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302155 OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req),
2156 wrb, NULL);
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002157
2158 req->port_num = port_num;
2159
2160 status = be_mcc_notify_wait(adapter);
2161 if (!status) {
2162 struct be_cmd_resp_get_beacon_state *resp =
2163 embedded_payload(wrb);
2164 *state = resp->beacon_state;
2165 }
2166
Sathya Perla713d03942009-11-22 22:02:45 +00002167err:
Sarveshwar Bandifad9ab22009-10-12 04:23:15 -07002168 spin_unlock_bh(&adapter->mcc_lock);
2169 return status;
2170}
2171
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002172int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
Padmanabh Ratnakarf67ef7b2012-07-12 03:57:09 +00002173 u32 data_size, u32 data_offset,
2174 const char *obj_name, u32 *data_written,
2175 u8 *change_status, u8 *addn_status)
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002176{
2177 struct be_mcc_wrb *wrb;
2178 struct lancer_cmd_req_write_object *req;
2179 struct lancer_cmd_resp_write_object *resp;
2180 void *ctxt = NULL;
2181 int status;
2182
2183 spin_lock_bh(&adapter->mcc_lock);
2184 adapter->flash_status = 0;
2185
2186 wrb = wrb_from_mccq(adapter);
2187 if (!wrb) {
2188 status = -EBUSY;
2189 goto err_unlock;
2190 }
2191
2192 req = embedded_payload(wrb);
2193
Somnath Kotur106df1e2011-10-27 07:12:13 +00002194 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302195 OPCODE_COMMON_WRITE_OBJECT,
2196 sizeof(struct lancer_cmd_req_write_object), wrb,
2197 NULL);
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002198
2199 ctxt = &req->context;
2200 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302201 write_length, ctxt, data_size);
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002202
2203 if (data_size == 0)
2204 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302205 eof, ctxt, 1);
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002206 else
2207 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302208 eof, ctxt, 0);
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002209
2210 be_dws_cpu_to_le(ctxt, sizeof(req->context));
2211 req->write_offset = cpu_to_le32(data_offset);
2212 strcpy(req->object_name, obj_name);
2213 req->descriptor_count = cpu_to_le32(1);
2214 req->buf_len = cpu_to_le32(data_size);
2215 req->addr_low = cpu_to_le32((cmd->dma +
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302216 sizeof(struct lancer_cmd_req_write_object))
2217 & 0xFFFFFFFF);
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002218 req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
2219 sizeof(struct lancer_cmd_req_write_object)));
2220
2221 be_mcc_notify(adapter);
2222 spin_unlock_bh(&adapter->mcc_lock);
2223
Suresh Reddy5eeff632014-01-06 13:02:24 +05302224 if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
Somnath Kotur701962d2013-05-02 03:36:34 +00002225 msecs_to_jiffies(60000)))
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002226 status = -1;
2227 else
2228 status = adapter->flash_status;
2229
2230 resp = embedded_payload(wrb);
Padmanabh Ratnakarf67ef7b2012-07-12 03:57:09 +00002231 if (!status) {
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002232 *data_written = le32_to_cpu(resp->actual_write_len);
Padmanabh Ratnakarf67ef7b2012-07-12 03:57:09 +00002233 *change_status = resp->change_status;
2234 } else {
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002235 *addn_status = resp->additional_status;
Padmanabh Ratnakarf67ef7b2012-07-12 03:57:09 +00002236 }
Shripad Nunjundarao485bf562011-05-16 07:36:59 +00002237
2238 return status;
2239
2240err_unlock:
2241 spin_unlock_bh(&adapter->mcc_lock);
2242 return status;
2243}
2244
Padmanabh Ratnakarde49bd52011-11-16 02:02:43 +00002245int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302246 u32 data_size, u32 data_offset, const char *obj_name,
2247 u32 *data_read, u32 *eof, u8 *addn_status)
Padmanabh Ratnakarde49bd52011-11-16 02:02:43 +00002248{
2249 struct be_mcc_wrb *wrb;
2250 struct lancer_cmd_req_read_object *req;
2251 struct lancer_cmd_resp_read_object *resp;
2252 int status;
2253
2254 spin_lock_bh(&adapter->mcc_lock);
2255
2256 wrb = wrb_from_mccq(adapter);
2257 if (!wrb) {
2258 status = -EBUSY;
2259 goto err_unlock;
2260 }
2261
2262 req = embedded_payload(wrb);
2263
2264 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302265 OPCODE_COMMON_READ_OBJECT,
2266 sizeof(struct lancer_cmd_req_read_object), wrb,
2267 NULL);
Padmanabh Ratnakarde49bd52011-11-16 02:02:43 +00002268
2269 req->desired_read_len = cpu_to_le32(data_size);
2270 req->read_offset = cpu_to_le32(data_offset);
2271 strcpy(req->object_name, obj_name);
2272 req->descriptor_count = cpu_to_le32(1);
2273 req->buf_len = cpu_to_le32(data_size);
2274 req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
2275 req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));
2276
2277 status = be_mcc_notify_wait(adapter);
2278
2279 resp = embedded_payload(wrb);
2280 if (!status) {
2281 *data_read = le32_to_cpu(resp->actual_read_len);
2282 *eof = le32_to_cpu(resp->eof);
2283 } else {
2284 *addn_status = resp->additional_status;
2285 }
2286
2287err_unlock:
2288 spin_unlock_bh(&adapter->mcc_lock);
2289 return status;
2290}
2291
Ajit Khaparde84517482009-09-04 03:12:16 +00002292int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302293 u32 flash_type, u32 flash_opcode, u32 buf_size)
Ajit Khaparde84517482009-09-04 03:12:16 +00002294{
Sathya Perlab31c50a2009-09-17 10:30:13 -07002295 struct be_mcc_wrb *wrb;
Ajit Khaparde3f0d4562010-02-09 01:30:35 +00002296 struct be_cmd_write_flashrom *req;
Ajit Khaparde84517482009-09-04 03:12:16 +00002297 int status;
2298
Sathya Perlab31c50a2009-09-17 10:30:13 -07002299 spin_lock_bh(&adapter->mcc_lock);
Sarveshwar Bandidd131e72010-05-25 16:16:32 -07002300 adapter->flash_status = 0;
Sathya Perlab31c50a2009-09-17 10:30:13 -07002301
2302 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00002303 if (!wrb) {
2304 status = -EBUSY;
Dan Carpenter2892d9c2010-05-26 04:46:35 +00002305 goto err_unlock;
Sathya Perla713d03942009-11-22 22:02:45 +00002306 }
2307 req = cmd->va;
Sathya Perlab31c50a2009-09-17 10:30:13 -07002308
Somnath Kotur106df1e2011-10-27 07:12:13 +00002309 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302310 OPCODE_COMMON_WRITE_FLASHROM, cmd->size, wrb,
2311 cmd);
Ajit Khaparde84517482009-09-04 03:12:16 +00002312
2313 req->params.op_type = cpu_to_le32(flash_type);
2314 req->params.op_code = cpu_to_le32(flash_opcode);
2315 req->params.data_buf_size = cpu_to_le32(buf_size);
2316
Sarveshwar Bandidd131e72010-05-25 16:16:32 -07002317 be_mcc_notify(adapter);
2318 spin_unlock_bh(&adapter->mcc_lock);
2319
Suresh Reddy5eeff632014-01-06 13:02:24 +05302320 if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
2321 msecs_to_jiffies(40000)))
Sarveshwar Bandidd131e72010-05-25 16:16:32 -07002322 status = -1;
2323 else
2324 status = adapter->flash_status;
Ajit Khaparde84517482009-09-04 03:12:16 +00002325
Dan Carpenter2892d9c2010-05-26 04:46:35 +00002326 return status;
2327
2328err_unlock:
2329 spin_unlock_bh(&adapter->mcc_lock);
Ajit Khaparde84517482009-09-04 03:12:16 +00002330 return status;
2331}
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002332
Ajit Khaparde3f0d4562010-02-09 01:30:35 +00002333int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
Vasundhara Volam96c9b2e2014-05-30 19:06:25 +05302334 u16 optype, int offset)
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002335{
2336 struct be_mcc_wrb *wrb;
Padmanabh Ratnakarbe716442012-10-22 23:02:44 +00002337 struct be_cmd_read_flash_crc *req;
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002338 int status;
2339
2340 spin_lock_bh(&adapter->mcc_lock);
2341
2342 wrb = wrb_from_mccq(adapter);
Sathya Perla713d03942009-11-22 22:02:45 +00002343 if (!wrb) {
2344 status = -EBUSY;
2345 goto err;
2346 }
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002347 req = embedded_payload(wrb);
2348
Somnath Kotur106df1e2011-10-27 07:12:13 +00002349 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Padmanabh Ratnakarbe716442012-10-22 23:02:44 +00002350 OPCODE_COMMON_READ_FLASHROM, sizeof(*req),
2351 wrb, NULL);
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002352
Vasundhara Volam96c9b2e2014-05-30 19:06:25 +05302353 req->params.op_type = cpu_to_le32(optype);
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002354 req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
Ajit Khaparde8b93b712010-03-31 01:57:10 +00002355 req->params.offset = cpu_to_le32(offset);
2356 req->params.data_buf_size = cpu_to_le32(0x4);
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002357
2358 status = be_mcc_notify_wait(adapter);
2359 if (!status)
Padmanabh Ratnakarbe716442012-10-22 23:02:44 +00002360 memcpy(flashed_crc, req->crc, 4);
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002361
Sathya Perla713d03942009-11-22 22:02:45 +00002362err:
Sarveshwar Bandifa9a6fe2009-11-20 14:23:47 -08002363 spin_unlock_bh(&adapter->mcc_lock);
2364 return status;
2365}
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002366
Dan Carpenterc196b022010-05-26 04:47:39 +00002367int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302368 struct be_dma_mem *nonemb_cmd)
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002369{
2370 struct be_mcc_wrb *wrb;
2371 struct be_cmd_req_acpi_wol_magic_config *req;
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002372 int status;
2373
2374 spin_lock_bh(&adapter->mcc_lock);
2375
2376 wrb = wrb_from_mccq(adapter);
2377 if (!wrb) {
2378 status = -EBUSY;
2379 goto err;
2380 }
2381 req = nonemb_cmd->va;
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002382
Somnath Kotur106df1e2011-10-27 07:12:13 +00002383 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302384 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req),
2385 wrb, nonemb_cmd);
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002386 memcpy(req->magic_mac, mac, ETH_ALEN);
2387
Ajit Khaparde71d8d1b2009-12-03 06:16:59 +00002388 status = be_mcc_notify_wait(adapter);
2389
2390err:
2391 spin_unlock_bh(&adapter->mcc_lock);
2392 return status;
2393}
Suresh Rff33a6e2009-12-03 16:15:52 -08002394
Sarveshwar Bandifced9992009-12-23 04:41:44 +00002395int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
2396 u8 loopback_type, u8 enable)
2397{
2398 struct be_mcc_wrb *wrb;
2399 struct be_cmd_req_set_lmode *req;
2400 int status;
2401
2402 spin_lock_bh(&adapter->mcc_lock);
2403
2404 wrb = wrb_from_mccq(adapter);
2405 if (!wrb) {
2406 status = -EBUSY;
2407 goto err;
2408 }
2409
2410 req = embedded_payload(wrb);
2411
Somnath Kotur106df1e2011-10-27 07:12:13 +00002412 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302413 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, sizeof(*req),
2414 wrb, NULL);
Sarveshwar Bandifced9992009-12-23 04:41:44 +00002415
2416 req->src_port = port_num;
2417 req->dest_port = port_num;
2418 req->loopback_type = loopback_type;
2419 req->loopback_state = enable;
2420
2421 status = be_mcc_notify_wait(adapter);
2422err:
2423 spin_unlock_bh(&adapter->mcc_lock);
2424 return status;
2425}
2426
Suresh Rff33a6e2009-12-03 16:15:52 -08002427int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302428 u32 loopback_type, u32 pkt_size, u32 num_pkts,
2429 u64 pattern)
Suresh Rff33a6e2009-12-03 16:15:52 -08002430{
2431 struct be_mcc_wrb *wrb;
2432 struct be_cmd_req_loopback_test *req;
Suresh Reddy5eeff632014-01-06 13:02:24 +05302433 struct be_cmd_resp_loopback_test *resp;
Suresh Rff33a6e2009-12-03 16:15:52 -08002434 int status;
2435
2436 spin_lock_bh(&adapter->mcc_lock);
2437
2438 wrb = wrb_from_mccq(adapter);
2439 if (!wrb) {
2440 status = -EBUSY;
2441 goto err;
2442 }
2443
2444 req = embedded_payload(wrb);
2445
Somnath Kotur106df1e2011-10-27 07:12:13 +00002446 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302447 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req), wrb,
2448 NULL);
Suresh Rff33a6e2009-12-03 16:15:52 -08002449
Suresh Reddy5eeff632014-01-06 13:02:24 +05302450 req->hdr.timeout = cpu_to_le32(15);
Suresh Rff33a6e2009-12-03 16:15:52 -08002451 req->pattern = cpu_to_le64(pattern);
2452 req->src_port = cpu_to_le32(port_num);
2453 req->dest_port = cpu_to_le32(port_num);
2454 req->pkt_size = cpu_to_le32(pkt_size);
2455 req->num_pkts = cpu_to_le32(num_pkts);
2456 req->loopback_type = cpu_to_le32(loopback_type);
2457
Suresh Reddy5eeff632014-01-06 13:02:24 +05302458 be_mcc_notify(adapter);
Suresh Rff33a6e2009-12-03 16:15:52 -08002459
Suresh Reddy5eeff632014-01-06 13:02:24 +05302460 spin_unlock_bh(&adapter->mcc_lock);
2461
2462 wait_for_completion(&adapter->et_cmd_compl);
2463 resp = embedded_payload(wrb);
2464 status = le32_to_cpu(resp->status);
2465
2466 return status;
Suresh Rff33a6e2009-12-03 16:15:52 -08002467err:
2468 spin_unlock_bh(&adapter->mcc_lock);
2469 return status;
2470}
2471
2472int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302473 u32 byte_cnt, struct be_dma_mem *cmd)
Suresh Rff33a6e2009-12-03 16:15:52 -08002474{
2475 struct be_mcc_wrb *wrb;
2476 struct be_cmd_req_ddrdma_test *req;
Suresh Rff33a6e2009-12-03 16:15:52 -08002477 int status;
2478 int i, j = 0;
2479
2480 spin_lock_bh(&adapter->mcc_lock);
2481
2482 wrb = wrb_from_mccq(adapter);
2483 if (!wrb) {
2484 status = -EBUSY;
2485 goto err;
2486 }
2487 req = cmd->va;
Somnath Kotur106df1e2011-10-27 07:12:13 +00002488 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302489 OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size, wrb,
2490 cmd);
Suresh Rff33a6e2009-12-03 16:15:52 -08002491
2492 req->pattern = cpu_to_le64(pattern);
2493 req->byte_count = cpu_to_le32(byte_cnt);
2494 for (i = 0; i < byte_cnt; i++) {
2495 req->snd_buff[i] = (u8)(pattern >> (j*8));
2496 j++;
2497 if (j > 7)
2498 j = 0;
2499 }
2500
2501 status = be_mcc_notify_wait(adapter);
2502
2503 if (!status) {
2504 struct be_cmd_resp_ddrdma_test *resp;
2505 resp = cmd->va;
2506 if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
2507 resp->snd_err) {
2508 status = -1;
2509 }
2510 }
2511
2512err:
2513 spin_unlock_bh(&adapter->mcc_lock);
2514 return status;
2515}
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002516
Dan Carpenterc196b022010-05-26 04:47:39 +00002517int be_cmd_get_seeprom_data(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302518 struct be_dma_mem *nonemb_cmd)
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002519{
2520 struct be_mcc_wrb *wrb;
2521 struct be_cmd_req_seeprom_read *req;
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002522 int status;
2523
2524 spin_lock_bh(&adapter->mcc_lock);
2525
2526 wrb = wrb_from_mccq(adapter);
Ajit Khapardee45ff012011-02-04 17:18:28 +00002527 if (!wrb) {
2528 status = -EBUSY;
2529 goto err;
2530 }
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002531 req = nonemb_cmd->va;
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002532
Somnath Kotur106df1e2011-10-27 07:12:13 +00002533 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302534 OPCODE_COMMON_SEEPROM_READ, sizeof(*req), wrb,
2535 nonemb_cmd);
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002536
2537 status = be_mcc_notify_wait(adapter);
2538
Ajit Khapardee45ff012011-02-04 17:18:28 +00002539err:
Sarveshwar Bandi368c0ca2010-01-08 00:07:27 -08002540 spin_unlock_bh(&adapter->mcc_lock);
2541 return status;
2542}
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002543
Ajit Khaparde42f11cf2012-04-21 18:53:22 +00002544int be_cmd_get_phy_info(struct be_adapter *adapter)
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002545{
2546 struct be_mcc_wrb *wrb;
2547 struct be_cmd_req_get_phy_info *req;
Sathya Perla306f1342011-08-02 19:57:45 +00002548 struct be_dma_mem cmd;
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002549 int status;
2550
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00002551 if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
2552 CMD_SUBSYSTEM_COMMON))
2553 return -EPERM;
2554
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002555 spin_lock_bh(&adapter->mcc_lock);
2556
2557 wrb = wrb_from_mccq(adapter);
2558 if (!wrb) {
2559 status = -EBUSY;
2560 goto err;
2561 }
Sathya Perla306f1342011-08-02 19:57:45 +00002562 cmd.size = sizeof(struct be_cmd_req_get_phy_info);
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302563 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
Sathya Perla306f1342011-08-02 19:57:45 +00002564 if (!cmd.va) {
2565 dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
2566 status = -ENOMEM;
2567 goto err;
2568 }
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002569
Sathya Perla306f1342011-08-02 19:57:45 +00002570 req = cmd.va;
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002571
Somnath Kotur106df1e2011-10-27 07:12:13 +00002572 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302573 OPCODE_COMMON_GET_PHY_DETAILS, sizeof(*req),
2574 wrb, &cmd);
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002575
2576 status = be_mcc_notify_wait(adapter);
Sathya Perla306f1342011-08-02 19:57:45 +00002577 if (!status) {
2578 struct be_phy_info *resp_phy_info =
2579 cmd.va + sizeof(struct be_cmd_req_hdr);
Ajit Khaparde42f11cf2012-04-21 18:53:22 +00002580 adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
2581 adapter->phy.interface_type =
Sathya Perla306f1342011-08-02 19:57:45 +00002582 le16_to_cpu(resp_phy_info->interface_type);
Ajit Khaparde42f11cf2012-04-21 18:53:22 +00002583 adapter->phy.auto_speeds_supported =
2584 le16_to_cpu(resp_phy_info->auto_speeds_supported);
2585 adapter->phy.fixed_speeds_supported =
2586 le16_to_cpu(resp_phy_info->fixed_speeds_supported);
2587 adapter->phy.misc_params =
2588 le32_to_cpu(resp_phy_info->misc_params);
Vasundhara Volam68cb7e42013-08-06 09:27:18 +05302589
2590 if (BE2_chip(adapter)) {
2591 adapter->phy.fixed_speeds_supported =
2592 BE_SUPPORTED_SPEED_10GBPS |
2593 BE_SUPPORTED_SPEED_1GBPS;
2594 }
Sathya Perla306f1342011-08-02 19:57:45 +00002595 }
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302596 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
Ajit Khapardeee3cb622010-07-01 03:51:00 +00002597err:
2598 spin_unlock_bh(&adapter->mcc_lock);
2599 return status;
2600}
Ajit Khapardee1d18732010-07-23 01:52:13 +00002601
2602int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
2603{
2604 struct be_mcc_wrb *wrb;
2605 struct be_cmd_req_set_qos *req;
2606 int status;
2607
2608 spin_lock_bh(&adapter->mcc_lock);
2609
2610 wrb = wrb_from_mccq(adapter);
2611 if (!wrb) {
2612 status = -EBUSY;
2613 goto err;
2614 }
2615
2616 req = embedded_payload(wrb);
2617
Somnath Kotur106df1e2011-10-27 07:12:13 +00002618 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302619 OPCODE_COMMON_SET_QOS, sizeof(*req), wrb, NULL);
Ajit Khapardee1d18732010-07-23 01:52:13 +00002620
2621 req->hdr.domain = domain;
Ajit Khaparde6bff57a2011-02-11 13:33:02 +00002622 req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC);
2623 req->max_bps_nic = cpu_to_le32(bps);
Ajit Khapardee1d18732010-07-23 01:52:13 +00002624
2625 status = be_mcc_notify_wait(adapter);
2626
2627err:
2628 spin_unlock_bh(&adapter->mcc_lock);
2629 return status;
2630}
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002631
2632int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
2633{
2634 struct be_mcc_wrb *wrb;
2635 struct be_cmd_req_cntl_attribs *req;
2636 struct be_cmd_resp_cntl_attribs *resp;
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002637 int status;
2638 int payload_len = max(sizeof(*req), sizeof(*resp));
2639 struct mgmt_controller_attrib *attribs;
2640 struct be_dma_mem attribs_cmd;
2641
Suresh Reddyd98ef502013-04-25 00:56:55 +00002642 if (mutex_lock_interruptible(&adapter->mbox_lock))
2643 return -1;
2644
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002645 memset(&attribs_cmd, 0, sizeof(struct be_dma_mem));
2646 attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs);
2647 attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302648 &attribs_cmd.dma);
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002649 if (!attribs_cmd.va) {
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302650 dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
Suresh Reddyd98ef502013-04-25 00:56:55 +00002651 status = -ENOMEM;
2652 goto err;
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002653 }
2654
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002655 wrb = wrb_from_mbox(adapter);
2656 if (!wrb) {
2657 status = -EBUSY;
2658 goto err;
2659 }
2660 req = attribs_cmd.va;
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002661
Somnath Kotur106df1e2011-10-27 07:12:13 +00002662 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302663 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len,
2664 wrb, &attribs_cmd);
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002665
2666 status = be_mbox_notify_wait(adapter);
2667 if (!status) {
Joe Perches43d620c2011-06-16 19:08:06 +00002668 attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002669 adapter->hba_port_num = attribs->hba_attribs.phy_port;
2670 }
2671
2672err:
2673 mutex_unlock(&adapter->mbox_lock);
Suresh Reddyd98ef502013-04-25 00:56:55 +00002674 if (attribs_cmd.va)
2675 pci_free_consistent(adapter->pdev, attribs_cmd.size,
2676 attribs_cmd.va, attribs_cmd.dma);
Ajit Khaparde9e1453c2011-02-20 11:42:22 +00002677 return status;
2678}
Sathya Perla2e588f82011-03-11 02:49:26 +00002679
2680/* Uses mbox */
Sathya Perla2dc1deb2011-07-19 19:52:33 +00002681int be_cmd_req_native_mode(struct be_adapter *adapter)
Sathya Perla2e588f82011-03-11 02:49:26 +00002682{
2683 struct be_mcc_wrb *wrb;
2684 struct be_cmd_req_set_func_cap *req;
2685 int status;
2686
2687 if (mutex_lock_interruptible(&adapter->mbox_lock))
2688 return -1;
2689
2690 wrb = wrb_from_mbox(adapter);
2691 if (!wrb) {
2692 status = -EBUSY;
2693 goto err;
2694 }
2695
2696 req = embedded_payload(wrb);
2697
Somnath Kotur106df1e2011-10-27 07:12:13 +00002698 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302699 OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP,
2700 sizeof(*req), wrb, NULL);
Sathya Perla2e588f82011-03-11 02:49:26 +00002701
2702 req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS |
2703 CAPABILITY_BE3_NATIVE_ERX_API);
2704 req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API);
2705
2706 status = be_mbox_notify_wait(adapter);
2707 if (!status) {
2708 struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
2709 adapter->be3_native = le32_to_cpu(resp->cap_flags) &
2710 CAPABILITY_BE3_NATIVE_ERX_API;
Sathya Perlad3791422012-09-28 04:39:44 +00002711 if (!adapter->be3_native)
2712 dev_warn(&adapter->pdev->dev,
2713 "adapter not in advanced mode\n");
Sathya Perla2e588f82011-03-11 02:49:26 +00002714 }
2715err:
2716 mutex_unlock(&adapter->mbox_lock);
2717 return status;
2718}
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002719
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00002720/* Get privilege(s) for a function */
2721int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
2722 u32 domain)
2723{
2724 struct be_mcc_wrb *wrb;
2725 struct be_cmd_req_get_fn_privileges *req;
2726 int status;
2727
2728 spin_lock_bh(&adapter->mcc_lock);
2729
2730 wrb = wrb_from_mccq(adapter);
2731 if (!wrb) {
2732 status = -EBUSY;
2733 goto err;
2734 }
2735
2736 req = embedded_payload(wrb);
2737
2738 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2739 OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req),
2740 wrb, NULL);
2741
2742 req->hdr.domain = domain;
2743
2744 status = be_mcc_notify_wait(adapter);
2745 if (!status) {
2746 struct be_cmd_resp_get_fn_privileges *resp =
2747 embedded_payload(wrb);
2748 *privilege = le32_to_cpu(resp->privilege_mask);
Suresh Reddy02308d72014-01-15 13:23:36 +05302749
2750 /* In UMC mode FW does not return right privileges.
2751 * Override with correct privilege equivalent to PF.
2752 */
2753 if (BEx_chip(adapter) && be_is_mc(adapter) &&
2754 be_physfn(adapter))
2755 *privilege = MAX_PRIVILEGES;
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00002756 }
2757
2758err:
2759 spin_unlock_bh(&adapter->mcc_lock);
2760 return status;
2761}
2762
Sathya Perla04a06022013-07-23 15:25:00 +05302763/* Set privilege(s) for a function */
2764int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
2765 u32 domain)
2766{
2767 struct be_mcc_wrb *wrb;
2768 struct be_cmd_req_set_fn_privileges *req;
2769 int status;
2770
2771 spin_lock_bh(&adapter->mcc_lock);
2772
2773 wrb = wrb_from_mccq(adapter);
2774 if (!wrb) {
2775 status = -EBUSY;
2776 goto err;
2777 }
2778
2779 req = embedded_payload(wrb);
2780 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2781 OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req),
2782 wrb, NULL);
2783 req->hdr.domain = domain;
2784 if (lancer_chip(adapter))
2785 req->privileges_lancer = cpu_to_le32(privileges);
2786 else
2787 req->privileges = cpu_to_le32(privileges);
2788
2789 status = be_mcc_notify_wait(adapter);
2790err:
2791 spin_unlock_bh(&adapter->mcc_lock);
2792 return status;
2793}
2794
Sathya Perla5a712c12013-07-23 15:24:59 +05302795/* pmac_id_valid: true => pmac_id is supplied and MAC address is requested.
2796 * pmac_id_valid: false => pmac_id or MAC address is requested.
2797 * If pmac_id is returned, pmac_id_valid is returned as true
2798 */
Padmanabh Ratnakar1578e772012-06-07 04:37:08 +00002799int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
Suresh Reddyb188f092014-01-15 13:23:39 +05302800 bool *pmac_id_valid, u32 *pmac_id, u32 if_handle,
2801 u8 domain)
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002802{
2803 struct be_mcc_wrb *wrb;
2804 struct be_cmd_req_get_mac_list *req;
2805 int status;
2806 int mac_count;
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002807 struct be_dma_mem get_mac_list_cmd;
2808 int i;
2809
2810 memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
2811 get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
2812 get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302813 get_mac_list_cmd.size,
2814 &get_mac_list_cmd.dma);
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002815
2816 if (!get_mac_list_cmd.va) {
2817 dev_err(&adapter->pdev->dev,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302818 "Memory allocation failure during GET_MAC_LIST\n");
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002819 return -ENOMEM;
2820 }
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002821
2822 spin_lock_bh(&adapter->mcc_lock);
2823
2824 wrb = wrb_from_mccq(adapter);
2825 if (!wrb) {
2826 status = -EBUSY;
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002827 goto out;
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002828 }
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002829
2830 req = get_mac_list_cmd.va;
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002831
2832 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlabf591f52013-05-08 02:05:48 +00002833 OPCODE_COMMON_GET_MAC_LIST,
2834 get_mac_list_cmd.size, wrb, &get_mac_list_cmd);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002835 req->hdr.domain = domain;
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002836 req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
Sathya Perla5a712c12013-07-23 15:24:59 +05302837 if (*pmac_id_valid) {
2838 req->mac_id = cpu_to_le32(*pmac_id);
Suresh Reddyb188f092014-01-15 13:23:39 +05302839 req->iface_id = cpu_to_le16(if_handle);
Sathya Perla5a712c12013-07-23 15:24:59 +05302840 req->perm_override = 0;
2841 } else {
2842 req->perm_override = 1;
2843 }
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002844
2845 status = be_mcc_notify_wait(adapter);
2846 if (!status) {
2847 struct be_cmd_resp_get_mac_list *resp =
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002848 get_mac_list_cmd.va;
Sathya Perla5a712c12013-07-23 15:24:59 +05302849
2850 if (*pmac_id_valid) {
2851 memcpy(mac, resp->macid_macaddr.mac_addr_id.macaddr,
2852 ETH_ALEN);
2853 goto out;
2854 }
2855
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002856 mac_count = resp->true_mac_count + resp->pseudo_mac_count;
2857 /* Mac list returned could contain one or more active mac_ids
Padmanabh Ratnakar1578e772012-06-07 04:37:08 +00002858 * or one or more true or pseudo permanant mac addresses.
2859 * If an active mac_id is present, return first active mac_id
2860 * found.
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002861 */
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002862 for (i = 0; i < mac_count; i++) {
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002863 struct get_list_macaddr *mac_entry;
2864 u16 mac_addr_size;
2865 u32 mac_id;
2866
2867 mac_entry = &resp->macaddr_list[i];
2868 mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
2869 /* mac_id is a 32 bit value and mac_addr size
2870 * is 6 bytes
2871 */
2872 if (mac_addr_size == sizeof(u32)) {
Sathya Perla5a712c12013-07-23 15:24:59 +05302873 *pmac_id_valid = true;
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002874 mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
2875 *pmac_id = le32_to_cpu(mac_id);
2876 goto out;
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002877 }
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002878 }
Padmanabh Ratnakar1578e772012-06-07 04:37:08 +00002879 /* If no active mac_id found, return first mac addr */
Sathya Perla5a712c12013-07-23 15:24:59 +05302880 *pmac_id_valid = false;
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002881 memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302882 ETH_ALEN);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002883 }
2884
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002885out:
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002886 spin_unlock_bh(&adapter->mcc_lock);
Padmanabh Ratnakare5e1ee82012-02-03 09:50:17 +00002887 pci_free_consistent(adapter->pdev, get_mac_list_cmd.size,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302888 get_mac_list_cmd.va, get_mac_list_cmd.dma);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002889 return status;
2890}
2891
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302892int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id,
2893 u8 *mac, u32 if_handle, bool active, u32 domain)
Sathya Perla5a712c12013-07-23 15:24:59 +05302894{
Sathya Perla5a712c12013-07-23 15:24:59 +05302895
Suresh Reddyb188f092014-01-15 13:23:39 +05302896 if (!active)
2897 be_cmd_get_mac_from_list(adapter, mac, &active, &curr_pmac_id,
2898 if_handle, domain);
Sathya Perla3175d8c2013-07-23 15:25:03 +05302899 if (BEx_chip(adapter))
Sathya Perla5a712c12013-07-23 15:24:59 +05302900 return be_cmd_mac_addr_query(adapter, mac, false,
Suresh Reddyb188f092014-01-15 13:23:39 +05302901 if_handle, curr_pmac_id);
Sathya Perla3175d8c2013-07-23 15:25:03 +05302902 else
2903 /* Fetch the MAC address using pmac_id */
2904 return be_cmd_get_mac_from_list(adapter, mac, &active,
Suresh Reddyb188f092014-01-15 13:23:39 +05302905 &curr_pmac_id,
2906 if_handle, domain);
Sathya Perla5a712c12013-07-23 15:24:59 +05302907}
2908
Sathya Perla95046b92013-07-23 15:25:02 +05302909int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
2910{
2911 int status;
2912 bool pmac_valid = false;
2913
2914 memset(mac, 0, ETH_ALEN);
2915
Sathya Perla3175d8c2013-07-23 15:25:03 +05302916 if (BEx_chip(adapter)) {
2917 if (be_physfn(adapter))
2918 status = be_cmd_mac_addr_query(adapter, mac, true, 0,
2919 0);
2920 else
2921 status = be_cmd_mac_addr_query(adapter, mac, false,
2922 adapter->if_handle, 0);
2923 } else {
Sathya Perla95046b92013-07-23 15:25:02 +05302924 status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
Suresh Reddyb188f092014-01-15 13:23:39 +05302925 NULL, adapter->if_handle, 0);
Sathya Perla3175d8c2013-07-23 15:25:03 +05302926 }
2927
Sathya Perla95046b92013-07-23 15:25:02 +05302928 return status;
2929}
2930
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002931/* Uses synchronous MCCQ */
2932int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
2933 u8 mac_count, u32 domain)
2934{
2935 struct be_mcc_wrb *wrb;
2936 struct be_cmd_req_set_mac_list *req;
2937 int status;
2938 struct be_dma_mem cmd;
2939
2940 memset(&cmd, 0, sizeof(struct be_dma_mem));
2941 cmd.size = sizeof(struct be_cmd_req_set_mac_list);
2942 cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302943 &cmd.dma, GFP_KERNEL);
Joe Perchesd0320f72013-03-14 13:07:21 +00002944 if (!cmd.va)
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002945 return -ENOMEM;
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002946
2947 spin_lock_bh(&adapter->mcc_lock);
2948
2949 wrb = wrb_from_mccq(adapter);
2950 if (!wrb) {
2951 status = -EBUSY;
2952 goto err;
2953 }
2954
2955 req = cmd.va;
2956 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302957 OPCODE_COMMON_SET_MAC_LIST, sizeof(*req),
2958 wrb, &cmd);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002959
2960 req->hdr.domain = domain;
2961 req->mac_count = mac_count;
2962 if (mac_count)
2963 memcpy(req->mac, mac_array, ETH_ALEN*mac_count);
2964
2965 status = be_mcc_notify_wait(adapter);
2966
2967err:
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05302968 dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
Padmanabh Ratnakar590c3912011-11-25 05:47:26 +00002969 spin_unlock_bh(&adapter->mcc_lock);
2970 return status;
2971}
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00002972
Sathya Perla3175d8c2013-07-23 15:25:03 +05302973/* Wrapper to delete any active MACs and provision the new mac.
2974 * Changes to MAC_LIST are allowed iff none of the MAC addresses in the
2975 * current list are active.
2976 */
2977int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
2978{
2979 bool active_mac = false;
2980 u8 old_mac[ETH_ALEN];
2981 u32 pmac_id;
2982 int status;
2983
2984 status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
Suresh Reddyb188f092014-01-15 13:23:39 +05302985 &pmac_id, if_id, dom);
2986
Sathya Perla3175d8c2013-07-23 15:25:03 +05302987 if (!status && active_mac)
2988 be_cmd_pmac_del(adapter, if_id, pmac_id, dom);
2989
2990 return be_cmd_set_mac_list(adapter, mac, mac ? 1 : 0, dom);
2991}
2992
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00002993int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
Ajit Khapardea77dcb82013-08-30 15:01:16 -05002994 u32 domain, u16 intf_id, u16 hsw_mode)
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00002995{
2996 struct be_mcc_wrb *wrb;
2997 struct be_cmd_req_set_hsw_config *req;
2998 void *ctxt;
2999 int status;
3000
3001 spin_lock_bh(&adapter->mcc_lock);
3002
3003 wrb = wrb_from_mccq(adapter);
3004 if (!wrb) {
3005 status = -EBUSY;
3006 goto err;
3007 }
3008
3009 req = embedded_payload(wrb);
3010 ctxt = &req->context;
3011
3012 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303013 OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb,
3014 NULL);
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003015
3016 req->hdr.domain = domain;
3017 AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
3018 if (pvid) {
3019 AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
3020 AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
3021 }
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003022 if (!BEx_chip(adapter) && hsw_mode) {
3023 AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
3024 ctxt, adapter->hba_port_num);
3025 AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
3026 AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
3027 ctxt, hsw_mode);
3028 }
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003029
3030 be_dws_cpu_to_le(req->context, sizeof(req->context));
3031 status = be_mcc_notify_wait(adapter);
3032
3033err:
3034 spin_unlock_bh(&adapter->mcc_lock);
3035 return status;
3036}
3037
3038/* Get Hyper switch config */
3039int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003040 u32 domain, u16 intf_id, u8 *mode)
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003041{
3042 struct be_mcc_wrb *wrb;
3043 struct be_cmd_req_get_hsw_config *req;
3044 void *ctxt;
3045 int status;
3046 u16 vid;
3047
3048 spin_lock_bh(&adapter->mcc_lock);
3049
3050 wrb = wrb_from_mccq(adapter);
3051 if (!wrb) {
3052 status = -EBUSY;
3053 goto err;
3054 }
3055
3056 req = embedded_payload(wrb);
3057 ctxt = &req->context;
3058
3059 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303060 OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb,
3061 NULL);
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003062
3063 req->hdr.domain = domain;
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003064 AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3065 ctxt, intf_id);
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003066 AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003067
Vasundhara Volam2c07c1d2014-01-15 13:23:32 +05303068 if (!BEx_chip(adapter) && mode) {
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003069 AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
3070 ctxt, adapter->hba_port_num);
3071 AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
3072 }
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003073 be_dws_cpu_to_le(req->context, sizeof(req->context));
3074
3075 status = be_mcc_notify_wait(adapter);
3076 if (!status) {
3077 struct be_cmd_resp_get_hsw_config *resp =
3078 embedded_payload(wrb);
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303079 be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003080 vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303081 pvid, &resp->context);
Ajit Khapardea77dcb82013-08-30 15:01:16 -05003082 if (pvid)
3083 *pvid = le16_to_cpu(vid);
3084 if (mode)
3085 *mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
3086 port_fwd_type, &resp->context);
Ajit Khapardef1f3ee12012-03-18 06:23:41 +00003087 }
3088
3089err:
3090 spin_unlock_bh(&adapter->mcc_lock);
3091 return status;
3092}
3093
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003094int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
3095{
3096 struct be_mcc_wrb *wrb;
3097 struct be_cmd_req_acpi_wol_magic_config_v1 *req;
Suresh Reddy76a9e082014-01-15 13:23:40 +05303098 int status = 0;
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003099 struct be_dma_mem cmd;
3100
Padmanabh Ratnakarf25b1192012-10-20 06:02:52 +00003101 if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
3102 CMD_SUBSYSTEM_ETH))
3103 return -EPERM;
3104
Suresh Reddy76a9e082014-01-15 13:23:40 +05303105 if (be_is_wol_excluded(adapter))
3106 return status;
3107
Suresh Reddyd98ef502013-04-25 00:56:55 +00003108 if (mutex_lock_interruptible(&adapter->mbox_lock))
3109 return -1;
3110
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003111 memset(&cmd, 0, sizeof(struct be_dma_mem));
3112 cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303113 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003114 if (!cmd.va) {
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303115 dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
Suresh Reddyd98ef502013-04-25 00:56:55 +00003116 status = -ENOMEM;
3117 goto err;
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003118 }
3119
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003120 wrb = wrb_from_mbox(adapter);
3121 if (!wrb) {
3122 status = -EBUSY;
3123 goto err;
3124 }
3125
3126 req = cmd.va;
3127
3128 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
3129 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
Suresh Reddy76a9e082014-01-15 13:23:40 +05303130 sizeof(*req), wrb, &cmd);
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003131
3132 req->hdr.version = 1;
3133 req->query_options = BE_GET_WOL_CAP;
3134
3135 status = be_mbox_notify_wait(adapter);
3136 if (!status) {
3137 struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
3138 resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
3139
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003140 adapter->wol_cap = resp->wol_settings;
Suresh Reddy76a9e082014-01-15 13:23:40 +05303141 if (adapter->wol_cap & BE_WOL_CAP)
3142 adapter->wol_en = true;
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003143 }
3144err:
3145 mutex_unlock(&adapter->mbox_lock);
Suresh Reddyd98ef502013-04-25 00:56:55 +00003146 if (cmd.va)
3147 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003148 return status;
Somnath Kotur941a77d2012-05-17 22:59:03 +00003149
3150}
Vasundhara Volambaaa08d2014-01-15 13:23:34 +05303151
3152int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level)
3153{
3154 struct be_dma_mem extfat_cmd;
3155 struct be_fat_conf_params *cfgs;
3156 int status;
3157 int i, j;
3158
3159 memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3160 extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3161 extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
3162 &extfat_cmd.dma);
3163 if (!extfat_cmd.va)
3164 return -ENOMEM;
3165
3166 status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3167 if (status)
3168 goto err;
3169
3170 cfgs = (struct be_fat_conf_params *)
3171 (extfat_cmd.va + sizeof(struct be_cmd_resp_hdr));
3172 for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
3173 u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
3174 for (j = 0; j < num_modes; j++) {
3175 if (cfgs->module[i].trace_lvl[j].mode == MODE_UART)
3176 cfgs->module[i].trace_lvl[j].dbg_lvl =
3177 cpu_to_le32(level);
3178 }
3179 }
3180
3181 status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs);
3182err:
3183 pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
3184 extfat_cmd.dma);
3185 return status;
3186}
3187
3188int be_cmd_get_fw_log_level(struct be_adapter *adapter)
3189{
3190 struct be_dma_mem extfat_cmd;
3191 struct be_fat_conf_params *cfgs;
3192 int status, j;
3193 int level = 0;
3194
3195 memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
3196 extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
3197 extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
3198 &extfat_cmd.dma);
3199
3200 if (!extfat_cmd.va) {
3201 dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
3202 __func__);
3203 goto err;
3204 }
3205
3206 status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
3207 if (!status) {
3208 cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
3209 sizeof(struct be_cmd_resp_hdr));
3210 for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
3211 if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
3212 level = cfgs->module[0].trace_lvl[j].dbg_lvl;
3213 }
3214 }
3215 pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
3216 extfat_cmd.dma);
3217err:
3218 return level;
3219}
3220
Somnath Kotur941a77d2012-05-17 22:59:03 +00003221int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
3222 struct be_dma_mem *cmd)
3223{
3224 struct be_mcc_wrb *wrb;
3225 struct be_cmd_req_get_ext_fat_caps *req;
3226 int status;
3227
3228 if (mutex_lock_interruptible(&adapter->mbox_lock))
3229 return -1;
3230
3231 wrb = wrb_from_mbox(adapter);
3232 if (!wrb) {
3233 status = -EBUSY;
3234 goto err;
3235 }
3236
3237 req = cmd->va;
3238 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3239 OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
3240 cmd->size, wrb, cmd);
3241 req->parameter_type = cpu_to_le32(1);
3242
3243 status = be_mbox_notify_wait(adapter);
3244err:
3245 mutex_unlock(&adapter->mbox_lock);
3246 return status;
3247}
3248
3249int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
3250 struct be_dma_mem *cmd,
3251 struct be_fat_conf_params *configs)
3252{
3253 struct be_mcc_wrb *wrb;
3254 struct be_cmd_req_set_ext_fat_caps *req;
3255 int status;
3256
3257 spin_lock_bh(&adapter->mcc_lock);
3258
3259 wrb = wrb_from_mccq(adapter);
3260 if (!wrb) {
3261 status = -EBUSY;
3262 goto err;
3263 }
3264
3265 req = cmd->va;
3266 memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
3267 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3268 OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
3269 cmd->size, wrb, cmd);
3270
3271 status = be_mcc_notify_wait(adapter);
3272err:
3273 spin_unlock_bh(&adapter->mcc_lock);
3274 return status;
Ajit Khaparde4762f6c2012-03-18 06:23:11 +00003275}
Parav Pandit6a4ab662012-03-26 14:27:12 +00003276
Padmanabh Ratnakarb4e32a72012-07-12 03:57:35 +00003277int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name)
3278{
3279 struct be_mcc_wrb *wrb;
3280 struct be_cmd_req_get_port_name *req;
3281 int status;
3282
3283 if (!lancer_chip(adapter)) {
3284 *port_name = adapter->hba_port_num + '0';
3285 return 0;
3286 }
3287
3288 spin_lock_bh(&adapter->mcc_lock);
3289
3290 wrb = wrb_from_mccq(adapter);
3291 if (!wrb) {
3292 status = -EBUSY;
3293 goto err;
3294 }
3295
3296 req = embedded_payload(wrb);
3297
3298 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3299 OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
3300 NULL);
3301 req->hdr.version = 1;
3302
3303 status = be_mcc_notify_wait(adapter);
3304 if (!status) {
3305 struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
3306 *port_name = resp->port_name[adapter->hba_port_num];
3307 } else {
3308 *port_name = adapter->hba_port_num + '0';
3309 }
3310err:
3311 spin_unlock_bh(&adapter->mcc_lock);
3312 return status;
3313}
3314
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303315static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003316{
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303317 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003318 int i;
3319
3320 for (i = 0; i < desc_count; i++) {
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303321 if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
3322 hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
3323 return (struct be_nic_res_desc *)hdr;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003324
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303325 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3326 hdr = (void *)hdr + hdr->desc_len;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003327 }
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303328 return NULL;
3329}
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003330
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303331static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
3332 u32 desc_count)
3333{
3334 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3335 struct be_pcie_res_desc *pcie;
3336 int i;
3337
3338 for (i = 0; i < desc_count; i++) {
3339 if ((hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V0 ||
3340 hdr->desc_type == PCIE_RESOURCE_DESC_TYPE_V1)) {
3341 pcie = (struct be_pcie_res_desc *)hdr;
3342 if (pcie->pf_num == devfn)
3343 return pcie;
3344 }
3345
3346 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3347 hdr = (void *)hdr + hdr->desc_len;
3348 }
Wei Yang950e2952013-05-22 15:58:22 +00003349 return NULL;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003350}
3351
Vasundhara Volamf93f1602014-02-12 16:09:25 +05303352static struct be_port_res_desc *be_get_port_desc(u8 *buf, u32 desc_count)
3353{
3354 struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
3355 int i;
3356
3357 for (i = 0; i < desc_count; i++) {
3358 if (hdr->desc_type == PORT_RESOURCE_DESC_TYPE_V1)
3359 return (struct be_port_res_desc *)hdr;
3360
3361 hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
3362 hdr = (void *)hdr + hdr->desc_len;
3363 }
3364 return NULL;
3365}
3366
Sathya Perla92bf14a2013-08-27 16:57:32 +05303367static void be_copy_nic_desc(struct be_resources *res,
3368 struct be_nic_res_desc *desc)
3369{
3370 res->max_uc_mac = le16_to_cpu(desc->unicast_mac_count);
3371 res->max_vlans = le16_to_cpu(desc->vlan_count);
3372 res->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
3373 res->max_tx_qs = le16_to_cpu(desc->txq_count);
3374 res->max_rss_qs = le16_to_cpu(desc->rssq_count);
3375 res->max_rx_qs = le16_to_cpu(desc->rq_count);
3376 res->max_evt_qs = le16_to_cpu(desc->eq_count);
3377 /* Clear flags that driver is not interested in */
3378 res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
3379 BE_IF_CAP_FLAGS_WANT;
3380 /* Need 1 RXQ as the default RXQ */
3381 if (res->max_rss_qs && res->max_rss_qs == res->max_rx_qs)
3382 res->max_rss_qs -= 1;
3383}
3384
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003385/* Uses Mbox */
Sathya Perla92bf14a2013-08-27 16:57:32 +05303386int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003387{
3388 struct be_mcc_wrb *wrb;
3389 struct be_cmd_req_get_func_config *req;
3390 int status;
3391 struct be_dma_mem cmd;
3392
Suresh Reddyd98ef502013-04-25 00:56:55 +00003393 if (mutex_lock_interruptible(&adapter->mbox_lock))
3394 return -1;
3395
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003396 memset(&cmd, 0, sizeof(struct be_dma_mem));
3397 cmd.size = sizeof(struct be_cmd_resp_get_func_config);
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303398 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003399 if (!cmd.va) {
3400 dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
Suresh Reddyd98ef502013-04-25 00:56:55 +00003401 status = -ENOMEM;
3402 goto err;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003403 }
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003404
3405 wrb = wrb_from_mbox(adapter);
3406 if (!wrb) {
3407 status = -EBUSY;
3408 goto err;
3409 }
3410
3411 req = cmd.va;
3412
3413 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3414 OPCODE_COMMON_GET_FUNC_CONFIG,
3415 cmd.size, wrb, &cmd);
3416
Kalesh AP28710c52013-04-28 22:21:13 +00003417 if (skyhawk_chip(adapter))
3418 req->hdr.version = 1;
3419
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003420 status = be_mbox_notify_wait(adapter);
3421 if (!status) {
3422 struct be_cmd_resp_get_func_config *resp = cmd.va;
3423 u32 desc_count = le32_to_cpu(resp->desc_count);
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303424 struct be_nic_res_desc *desc;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003425
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303426 desc = be_get_nic_desc(resp->func_param, desc_count);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003427 if (!desc) {
3428 status = -EINVAL;
3429 goto err;
3430 }
3431
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003432 adapter->pf_number = desc->pf_num;
Sathya Perla92bf14a2013-08-27 16:57:32 +05303433 be_copy_nic_desc(res, desc);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003434 }
3435err:
3436 mutex_unlock(&adapter->mbox_lock);
Suresh Reddyd98ef502013-04-25 00:56:55 +00003437 if (cmd.va)
3438 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003439 return status;
3440}
3441
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003442/* Uses mbox */
Jingoo Han4188e7d2013-08-05 18:02:02 +09003443static int be_cmd_get_profile_config_mbox(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303444 u8 domain, struct be_dma_mem *cmd)
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003445{
3446 struct be_mcc_wrb *wrb;
3447 struct be_cmd_req_get_profile_config *req;
3448 int status;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003449
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003450 if (mutex_lock_interruptible(&adapter->mbox_lock))
3451 return -1;
3452 wrb = wrb_from_mbox(adapter);
3453
3454 req = cmd->va;
3455 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3456 OPCODE_COMMON_GET_PROFILE_CONFIG,
3457 cmd->size, wrb, cmd);
3458
3459 req->type = ACTIVE_PROFILE_TYPE;
3460 req->hdr.domain = domain;
3461 if (!lancer_chip(adapter))
3462 req->hdr.version = 1;
3463
3464 status = be_mbox_notify_wait(adapter);
3465
3466 mutex_unlock(&adapter->mbox_lock);
3467 return status;
3468}
3469
3470/* Uses sync mcc */
Jingoo Han4188e7d2013-08-05 18:02:02 +09003471static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303472 u8 domain, struct be_dma_mem *cmd)
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003473{
3474 struct be_mcc_wrb *wrb;
3475 struct be_cmd_req_get_profile_config *req;
3476 int status;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003477
3478 spin_lock_bh(&adapter->mcc_lock);
3479
3480 wrb = wrb_from_mccq(adapter);
3481 if (!wrb) {
3482 status = -EBUSY;
3483 goto err;
3484 }
3485
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003486 req = cmd->va;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003487 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3488 OPCODE_COMMON_GET_PROFILE_CONFIG,
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003489 cmd->size, wrb, cmd);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003490
3491 req->type = ACTIVE_PROFILE_TYPE;
3492 req->hdr.domain = domain;
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003493 if (!lancer_chip(adapter))
3494 req->hdr.version = 1;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003495
3496 status = be_mcc_notify_wait(adapter);
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003497
3498err:
3499 spin_unlock_bh(&adapter->mcc_lock);
3500 return status;
3501}
3502
3503/* Uses sync mcc, if MCCQ is already created otherwise mbox */
Sathya Perla92bf14a2013-08-27 16:57:32 +05303504int be_cmd_get_profile_config(struct be_adapter *adapter,
3505 struct be_resources *res, u8 domain)
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003506{
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303507 struct be_cmd_resp_get_profile_config *resp;
3508 struct be_pcie_res_desc *pcie;
Vasundhara Volamf93f1602014-02-12 16:09:25 +05303509 struct be_port_res_desc *port;
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303510 struct be_nic_res_desc *nic;
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003511 struct be_queue_info *mccq = &adapter->mcc_obj.q;
3512 struct be_dma_mem cmd;
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303513 u32 desc_count;
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003514 int status;
3515
3516 memset(&cmd, 0, sizeof(struct be_dma_mem));
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303517 cmd.size = sizeof(struct be_cmd_resp_get_profile_config);
3518 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
3519 if (!cmd.va)
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003520 return -ENOMEM;
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003521
3522 if (!mccq->created)
3523 status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd);
3524 else
3525 status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd);
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303526 if (status)
3527 goto err;
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003528
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303529 resp = cmd.va;
3530 desc_count = le32_to_cpu(resp->desc_count);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003531
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303532 pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
3533 desc_count);
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303534 if (pcie)
Sathya Perla92bf14a2013-08-27 16:57:32 +05303535 res->max_vfs = le16_to_cpu(pcie->num_vfs);
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303536
Vasundhara Volamf93f1602014-02-12 16:09:25 +05303537 port = be_get_port_desc(resp->func_param, desc_count);
3538 if (port)
3539 adapter->mc_type = port->mc_type;
3540
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303541 nic = be_get_nic_desc(resp->func_param, desc_count);
Sathya Perla92bf14a2013-08-27 16:57:32 +05303542 if (nic)
3543 be_copy_nic_desc(res, nic);
3544
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003545err:
Vasundhara Volama05f99d2013-04-21 23:28:17 +00003546 if (cmd.va)
Vasundhara Volam150d58c2013-08-27 16:57:31 +05303547 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
Padmanabh Ratnakarabb93952012-10-20 06:01:41 +00003548 return status;
3549}
3550
Sathya Perlaa4018012014-03-27 10:46:18 +05303551int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
3552 int size, u8 version, u8 domain)
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003553{
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003554 struct be_cmd_req_set_profile_config *req;
Sathya Perlaa4018012014-03-27 10:46:18 +05303555 struct be_mcc_wrb *wrb;
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003556 int status;
3557
3558 spin_lock_bh(&adapter->mcc_lock);
3559
3560 wrb = wrb_from_mccq(adapter);
3561 if (!wrb) {
3562 status = -EBUSY;
3563 goto err;
3564 }
3565
3566 req = embedded_payload(wrb);
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003567 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3568 OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req),
3569 wrb, NULL);
Sathya Perlaa4018012014-03-27 10:46:18 +05303570 req->hdr.version = version;
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003571 req->hdr.domain = domain;
3572 req->desc_count = cpu_to_le32(1);
Sathya Perlaa4018012014-03-27 10:46:18 +05303573 memcpy(req->desc, desc, size);
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003574
Padmanabh Ratnakard5c18472012-10-20 06:01:53 +00003575 status = be_mcc_notify_wait(adapter);
3576err:
3577 spin_unlock_bh(&adapter->mcc_lock);
3578 return status;
3579}
3580
Sathya Perlaa4018012014-03-27 10:46:18 +05303581/* Mark all fields invalid */
3582void be_reset_nic_desc(struct be_nic_res_desc *nic)
3583{
3584 memset(nic, 0, sizeof(*nic));
3585 nic->unicast_mac_count = 0xFFFF;
3586 nic->mcc_count = 0xFFFF;
3587 nic->vlan_count = 0xFFFF;
3588 nic->mcast_mac_count = 0xFFFF;
3589 nic->txq_count = 0xFFFF;
3590 nic->rq_count = 0xFFFF;
3591 nic->rssq_count = 0xFFFF;
3592 nic->lro_count = 0xFFFF;
3593 nic->cq_count = 0xFFFF;
3594 nic->toe_conn_count = 0xFFFF;
3595 nic->eq_count = 0xFFFF;
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303596 nic->iface_count = 0xFFFF;
Sathya Perlaa4018012014-03-27 10:46:18 +05303597 nic->link_param = 0xFF;
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303598 nic->channel_id_param = cpu_to_le16(0xF000);
Sathya Perlaa4018012014-03-27 10:46:18 +05303599 nic->acpi_params = 0xFF;
3600 nic->wol_param = 0x0F;
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303601 nic->tunnel_iface_count = 0xFFFF;
3602 nic->direct_tenant_iface_count = 0xFFFF;
Sathya Perlaa4018012014-03-27 10:46:18 +05303603 nic->bw_max = 0xFFFFFFFF;
3604}
3605
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303606int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
3607 u8 domain)
Sathya Perlaa4018012014-03-27 10:46:18 +05303608{
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303609 struct be_nic_res_desc nic_desc;
3610 u32 bw_percent;
3611 u16 version = 0;
Sathya Perlaa4018012014-03-27 10:46:18 +05303612
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303613 if (BE3_chip(adapter))
3614 return be_cmd_set_qos(adapter, max_rate / 10, domain);
3615
3616 be_reset_nic_desc(&nic_desc);
3617 nic_desc.pf_num = adapter->pf_number;
3618 nic_desc.vf_num = domain;
3619 if (lancer_chip(adapter)) {
Sathya Perlaa4018012014-03-27 10:46:18 +05303620 nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
3621 nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
3622 nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
3623 (1 << NOSV_SHIFT);
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303624 nic_desc.bw_max = cpu_to_le32(max_rate / 10);
Sathya Perlaa4018012014-03-27 10:46:18 +05303625 } else {
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303626 version = 1;
3627 nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
3628 nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3629 nic_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
3630 bw_percent = max_rate ? (max_rate * 100) / link_speed : 100;
3631 nic_desc.bw_max = cpu_to_le32(bw_percent);
Sathya Perlaa4018012014-03-27 10:46:18 +05303632 }
Ravikumar Nelavelli0f77ba72014-05-30 19:06:24 +05303633
3634 return be_cmd_set_profile_config(adapter, &nic_desc,
3635 nic_desc.hdr.desc_len,
3636 version, domain);
Sathya Perlaa4018012014-03-27 10:46:18 +05303637}
3638
3639int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
3640{
3641 struct be_mcc_wrb *wrb;
3642 struct be_cmd_req_manage_iface_filters *req;
3643 int status;
3644
3645 if (iface == 0xFFFFFFFF)
3646 return -1;
3647
3648 spin_lock_bh(&adapter->mcc_lock);
3649
3650 wrb = wrb_from_mccq(adapter);
3651 if (!wrb) {
3652 status = -EBUSY;
3653 goto err;
3654 }
3655 req = embedded_payload(wrb);
3656
3657 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3658 OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req),
3659 wrb, NULL);
3660 req->op = op;
3661 req->target_iface_id = cpu_to_le32(iface);
3662
3663 status = be_mcc_notify_wait(adapter);
3664err:
3665 spin_unlock_bh(&adapter->mcc_lock);
3666 return status;
3667}
3668
3669int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
3670{
3671 struct be_port_res_desc port_desc;
3672
3673 memset(&port_desc, 0, sizeof(port_desc));
3674 port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1;
3675 port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
3676 port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
3677 port_desc.link_num = adapter->hba_port_num;
3678 if (port) {
3679 port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) |
3680 (1 << RCVID_SHIFT);
3681 port_desc.nv_port = swab16(port);
3682 } else {
3683 port_desc.nv_flags = NV_TYPE_DISABLED;
3684 port_desc.nv_port = 0;
3685 }
3686
3687 return be_cmd_set_profile_config(adapter, &port_desc,
3688 RESOURCE_DESC_SIZE_V1, 1, 0);
3689}
3690
Sathya Perla4c876612013-02-03 20:30:11 +00003691int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
3692 int vf_num)
3693{
3694 struct be_mcc_wrb *wrb;
3695 struct be_cmd_req_get_iface_list *req;
3696 struct be_cmd_resp_get_iface_list *resp;
3697 int status;
3698
3699 spin_lock_bh(&adapter->mcc_lock);
3700
3701 wrb = wrb_from_mccq(adapter);
3702 if (!wrb) {
3703 status = -EBUSY;
3704 goto err;
3705 }
3706 req = embedded_payload(wrb);
3707
3708 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3709 OPCODE_COMMON_GET_IFACE_LIST, sizeof(*resp),
3710 wrb, NULL);
3711 req->hdr.domain = vf_num + 1;
3712
3713 status = be_mcc_notify_wait(adapter);
3714 if (!status) {
3715 resp = (struct be_cmd_resp_get_iface_list *)req;
3716 vf_cfg->if_handle = le32_to_cpu(resp->if_desc.if_id);
3717 }
3718
3719err:
3720 spin_unlock_bh(&adapter->mcc_lock);
3721 return status;
3722}
3723
Somnath Kotur5c510812013-05-30 02:52:23 +00003724static int lancer_wait_idle(struct be_adapter *adapter)
3725{
3726#define SLIPORT_IDLE_TIMEOUT 30
3727 u32 reg_val;
3728 int status = 0, i;
3729
3730 for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
3731 reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
3732 if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
3733 break;
3734
3735 ssleep(1);
3736 }
3737
3738 if (i == SLIPORT_IDLE_TIMEOUT)
3739 status = -1;
3740
3741 return status;
3742}
3743
3744int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
3745{
3746 int status = 0;
3747
3748 status = lancer_wait_idle(adapter);
3749 if (status)
3750 return status;
3751
3752 iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);
3753
3754 return status;
3755}
3756
3757/* Routine to check whether dump image is present or not */
3758bool dump_present(struct be_adapter *adapter)
3759{
3760 u32 sliport_status = 0;
3761
3762 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
3763 return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
3764}
3765
3766int lancer_initiate_dump(struct be_adapter *adapter)
3767{
3768 int status;
3769
3770 /* give firmware reset and diagnostic dump */
3771 status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
3772 PHYSDEV_CONTROL_DD_MASK);
3773 if (status < 0) {
3774 dev_err(&adapter->pdev->dev, "Firmware reset failed\n");
3775 return status;
3776 }
3777
3778 status = lancer_wait_idle(adapter);
3779 if (status)
3780 return status;
3781
3782 if (!dump_present(adapter)) {
3783 dev_err(&adapter->pdev->dev, "Dump image not present\n");
3784 return -1;
3785 }
3786
3787 return 0;
3788}
3789
Padmanabh Ratnakardcf7ebb2012-10-20 06:03:49 +00003790/* Uses sync mcc */
3791int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
3792{
3793 struct be_mcc_wrb *wrb;
3794 struct be_cmd_enable_disable_vf *req;
3795 int status;
3796
Vasundhara Volam05998632013-10-01 15:59:59 +05303797 if (BEx_chip(adapter))
Padmanabh Ratnakardcf7ebb2012-10-20 06:03:49 +00003798 return 0;
3799
3800 spin_lock_bh(&adapter->mcc_lock);
3801
3802 wrb = wrb_from_mccq(adapter);
3803 if (!wrb) {
3804 status = -EBUSY;
3805 goto err;
3806 }
3807
3808 req = embedded_payload(wrb);
3809
3810 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3811 OPCODE_COMMON_ENABLE_DISABLE_VF, sizeof(*req),
3812 wrb, NULL);
3813
3814 req->hdr.domain = domain;
3815 req->enable = 1;
3816 status = be_mcc_notify_wait(adapter);
3817err:
3818 spin_unlock_bh(&adapter->mcc_lock);
3819 return status;
3820}
3821
Somnath Kotur68c45a22013-03-14 02:42:07 +00003822int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
3823{
3824 struct be_mcc_wrb *wrb;
3825 struct be_cmd_req_intr_set *req;
3826 int status;
3827
3828 if (mutex_lock_interruptible(&adapter->mbox_lock))
3829 return -1;
3830
3831 wrb = wrb_from_mbox(adapter);
3832
3833 req = embedded_payload(wrb);
3834
3835 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3836 OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req),
3837 wrb, NULL);
3838
3839 req->intr_enabled = intr_enable;
3840
3841 status = be_mbox_notify_wait(adapter);
3842
3843 mutex_unlock(&adapter->mbox_lock);
3844 return status;
3845}
3846
Vasundhara Volam542963b2014-01-15 13:23:33 +05303847/* Uses MBOX */
3848int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile_id)
3849{
3850 struct be_cmd_req_get_active_profile *req;
3851 struct be_mcc_wrb *wrb;
3852 int status;
3853
3854 if (mutex_lock_interruptible(&adapter->mbox_lock))
3855 return -1;
3856
3857 wrb = wrb_from_mbox(adapter);
3858 if (!wrb) {
3859 status = -EBUSY;
3860 goto err;
3861 }
3862
3863 req = embedded_payload(wrb);
3864
3865 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3866 OPCODE_COMMON_GET_ACTIVE_PROFILE, sizeof(*req),
3867 wrb, NULL);
3868
3869 status = be_mbox_notify_wait(adapter);
3870 if (!status) {
3871 struct be_cmd_resp_get_active_profile *resp =
3872 embedded_payload(wrb);
3873 *profile_id = le16_to_cpu(resp->active_profile_id);
3874 }
3875
3876err:
3877 mutex_unlock(&adapter->mbox_lock);
3878 return status;
3879}
3880
Suresh Reddybdce2ad2014-03-11 18:53:04 +05303881int be_cmd_set_logical_link_config(struct be_adapter *adapter,
3882 int link_state, u8 domain)
3883{
3884 struct be_mcc_wrb *wrb;
3885 struct be_cmd_req_set_ll_link *req;
3886 int status;
3887
3888 if (BEx_chip(adapter) || lancer_chip(adapter))
3889 return 0;
3890
3891 spin_lock_bh(&adapter->mcc_lock);
3892
3893 wrb = wrb_from_mccq(adapter);
3894 if (!wrb) {
3895 status = -EBUSY;
3896 goto err;
3897 }
3898
3899 req = embedded_payload(wrb);
3900
3901 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3902 OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG,
3903 sizeof(*req), wrb, NULL);
3904
3905 req->hdr.version = 1;
3906 req->hdr.domain = domain;
3907
3908 if (link_state == IFLA_VF_LINK_STATE_ENABLE)
3909 req->link_config |= 1;
3910
3911 if (link_state == IFLA_VF_LINK_STATE_AUTO)
3912 req->link_config |= 1 << PLINK_TRACK_SHIFT;
3913
3914 status = be_mcc_notify_wait(adapter);
3915err:
3916 spin_unlock_bh(&adapter->mcc_lock);
3917 return status;
3918}
3919
Parav Pandit6a4ab662012-03-26 14:27:12 +00003920int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
Sathya Perlaa2cc4e02014-05-09 13:29:14 +05303921 int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
Parav Pandit6a4ab662012-03-26 14:27:12 +00003922{
3923 struct be_adapter *adapter = netdev_priv(netdev_handle);
3924 struct be_mcc_wrb *wrb;
3925 struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *) wrb_payload;
3926 struct be_cmd_req_hdr *req;
3927 struct be_cmd_resp_hdr *resp;
3928 int status;
3929
3930 spin_lock_bh(&adapter->mcc_lock);
3931
3932 wrb = wrb_from_mccq(adapter);
3933 if (!wrb) {
3934 status = -EBUSY;
3935 goto err;
3936 }
3937 req = embedded_payload(wrb);
3938 resp = embedded_payload(wrb);
3939
3940 be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
3941 hdr->opcode, wrb_payload_size, wrb, NULL);
3942 memcpy(req, wrb_payload, wrb_payload_size);
3943 be_dws_cpu_to_le(req, wrb_payload_size);
3944
3945 status = be_mcc_notify_wait(adapter);
3946 if (cmd_status)
3947 *cmd_status = (status & 0xffff);
3948 if (ext_status)
3949 *ext_status = 0;
3950 memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
3951 be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
3952err:
3953 spin_unlock_bh(&adapter->mcc_lock);
3954 return status;
3955}
3956EXPORT_SYMBOL(be_roce_mcc_cmd);