blob: 7cb009e0030e951432b37eac904436722401255f [file] [log] [blame]
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301/**
Ketan Mukadamc4f39bd2015-07-04 04:12:33 +05302 * Copyright (C) 2005 - 2015 Emulex
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05303 * 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:
Minh Tran4627de92015-05-14 23:16:17 -070011 * linux-drivers@avagotech.com
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053012 *
Ketan Mukadamc4f39bd2015-07-04 04:12:33 +053013 * Emulex
Jayamohan Kallickal255fa9a2011-03-25 14:23:57 -070014 * 3333 Susan Street
15 * Costa Mesa, CA 92626
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053016 */
17
John Soni Jose21771992012-04-03 23:41:49 -050018#include <scsi/iscsi_proto.h>
19
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -070020#include "be_main.h"
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053021#include "be.h"
22#include "be_mgmt.h"
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053023
Jayamohan Kallickale9b91192010-07-22 04:24:53 +053024int be_chk_reset_complete(struct beiscsi_hba *phba)
25{
26 unsigned int num_loop;
27 u8 *mpu_sem = 0;
28 u32 status;
29
30 num_loop = 1000;
31 mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
32 msleep(5000);
33
34 while (num_loop) {
35 status = readl((void *)mpu_sem);
36
37 if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000)
38 break;
39 msleep(60);
40 num_loop--;
41 }
42
43 if ((status & 0x80000000) || (!num_loop)) {
John Soni Jose99bc5d52012-08-20 23:00:18 +053044 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
45 "BC_%d : Failed in be_chk_reset_complete"
46 "status = 0x%x\n", status);
Jayamohan Kallickale9b91192010-07-22 04:24:53 +053047 return -EIO;
48 }
49
50 return 0;
51}
52
Jitendra Bhivare090e2182016-02-04 15:49:17 +053053struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
54 unsigned int *ref_tag)
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +053055{
Jitendra Bhivare090e2182016-02-04 15:49:17 +053056 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
57 struct be_mcc_wrb *wrb = NULL;
58 unsigned int tag;
59
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +053060 spin_lock(&phba->ctrl.mcc_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +053061 if (mccq->used == mccq->len) {
62 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
63 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
64 "BC_%d : MCC queue full: WRB used %u tag avail %u\n",
65 mccq->used, phba->ctrl.mcc_tag_available);
66 goto alloc_failed;
67 }
68
69 if (!phba->ctrl.mcc_tag_available)
70 goto alloc_failed;
71
72 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
73 if (!tag) {
74 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
75 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
76 "BC_%d : MCC tag 0 allocated: tag avail %u alloc index %u\n",
77 phba->ctrl.mcc_tag_available,
78 phba->ctrl.mcc_alloc_index);
79 goto alloc_failed;
80 }
81
82 /* return this tag for further reference */
83 *ref_tag = tag;
84 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
85 phba->ctrl.mcc_tag_status[tag] = 0;
86 phba->ctrl.ptag_state[tag].tag_state = 0;
Jitendra Bhivare50a4b822016-08-19 15:20:12 +053087 phba->ctrl.ptag_state[tag].cbfn = NULL;
Jitendra Bhivare090e2182016-02-04 15:49:17 +053088 phba->ctrl.mcc_tag_available--;
89 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
90 phba->ctrl.mcc_alloc_index = 0;
91 else
92 phba->ctrl.mcc_alloc_index++;
93
94 wrb = queue_head_node(mccq);
95 memset(wrb, 0, sizeof(*wrb));
96 wrb->tag0 = tag;
97 wrb->tag0 |= (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
98 queue_head_inc(mccq);
99 mccq->used++;
100
101alloc_failed:
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530102 spin_unlock(&phba->ctrl.mcc_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530103 return wrb;
104}
105
106void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag)
107{
108 struct be_queue_info *mccq = &ctrl->mcc_obj.q;
109
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530110 spin_lock(&ctrl->mcc_lock);
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530111 tag = tag & MCC_Q_CMD_TAG_MASK;
112 ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
113 if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
114 ctrl->mcc_free_index = 0;
115 else
116 ctrl->mcc_free_index++;
117 ctrl->mcc_tag_available++;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530118 mccq->used--;
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530119 spin_unlock(&ctrl->mcc_lock);
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530120}
121
122/**
123 * beiscsi_fail_session(): Closing session with appropriate error
124 * @cls_session: ptr to session
125 **/
126void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
127{
128 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
129}
130
John Soni Josee175def2012-10-20 04:45:40 +0530131/*
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530132 * beiscsi_mcc_compl_status - Return the status of MCC completion
133 * @phba: Driver private structure
134 * @tag: Tag for the MBX Command
135 * @wrb: the WRB used for the MBX Command
136 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
137 *
138 * return
139 * Success: 0
140 * Failure: Non-Zero
141 */
142int __beiscsi_mcc_compl_status(struct beiscsi_hba *phba,
143 unsigned int tag,
144 struct be_mcc_wrb **wrb,
145 struct be_dma_mem *mbx_cmd_mem)
146{
147 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
148 uint16_t status = 0, addl_status = 0, wrb_num = 0;
149 struct be_cmd_resp_hdr *mbx_resp_hdr;
150 struct be_cmd_req_hdr *mbx_hdr;
151 struct be_mcc_wrb *temp_wrb;
152 uint32_t mcc_tag_status;
153 int rc = 0;
154
155 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
156 status = (mcc_tag_status & CQE_STATUS_MASK);
157 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
158 CQE_STATUS_ADDL_SHIFT);
159
160 if (mbx_cmd_mem) {
161 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
162 } else {
163 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
164 CQE_STATUS_WRB_SHIFT;
165 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
166 mbx_hdr = embedded_payload(temp_wrb);
167
168 if (wrb)
169 *wrb = temp_wrb;
170 }
171
172 if (status || addl_status) {
173 beiscsi_log(phba, KERN_WARNING,
174 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
175 BEISCSI_LOG_CONFIG,
176 "BC_%d : MBX Cmd Failed for Subsys : %d Opcode : %d with Status : %d and Extd_Status : %d\n",
177 mbx_hdr->subsystem, mbx_hdr->opcode,
178 status, addl_status);
179 rc = -EIO;
180 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
181 mbx_resp_hdr = (struct be_cmd_resp_hdr *)mbx_hdr;
182 beiscsi_log(phba, KERN_WARNING,
183 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
184 BEISCSI_LOG_CONFIG,
185 "BC_%d : Insufficient Buffer Error Resp_Len : %d Actual_Resp_Len : %d\n",
186 mbx_resp_hdr->response_length,
187 mbx_resp_hdr->actual_resp_len);
188 rc = -EAGAIN;
189 }
190 }
191
192 return rc;
193}
194
195/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530196 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
John Soni Josee175def2012-10-20 04:45:40 +0530197 * @phba: Driver private structure
198 * @tag: Tag for the MBX Command
199 * @wrb: the WRB used for the MBX Command
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500200 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
John Soni Josee175def2012-10-20 04:45:40 +0530201 *
202 * Waits for MBX completion with the passed TAG.
203 *
204 * return
205 * Success: 0
206 * Failure: Non-Zero
207 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530208int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530209 unsigned int tag,
210 struct be_mcc_wrb **wrb,
Jitendra Bhivare88840332016-02-04 15:49:12 +0530211 struct be_dma_mem *mbx_cmd_mem)
John Soni Josee175def2012-10-20 04:45:40 +0530212{
213 int rc = 0;
John Soni Josee175def2012-10-20 04:45:40 +0530214
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530215 if (beiscsi_hba_in_error(phba)) {
216 clear_bit(MCC_TAG_STATE_RUNNING,
217 &phba->ctrl.ptag_state[tag].tag_state);
218 return -EIO;
219 }
John Soni Jose7a158002012-10-20 04:45:51 +0530220
John Soni Josee175def2012-10-20 04:45:40 +0530221 /* wait for the mccq completion */
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530222 rc = wait_event_interruptible_timeout(phba->ctrl.mcc_wait[tag],
223 phba->ctrl.mcc_tag_status[tag],
224 msecs_to_jiffies(
225 BEISCSI_HOST_MBX_TIMEOUT));
226
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530227 /**
228 * If MBOX cmd timeout expired, tag and resource allocated
229 * for cmd is not freed until FW returns completion.
230 */
John Soni Josee175def2012-10-20 04:45:40 +0530231 if (rc <= 0) {
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500232 struct be_dma_mem *tag_mem;
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500233
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530234 /**
235 * PCI/DMA memory allocated and posted in non-embedded mode
236 * will have mbx_cmd_mem != NULL.
237 * Save virtual and bus addresses for the command so that it
238 * can be freed later.
239 **/
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500240 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
241 if (mbx_cmd_mem) {
242 tag_mem->size = mbx_cmd_mem->size;
243 tag_mem->va = mbx_cmd_mem->va;
244 tag_mem->dma = mbx_cmd_mem->dma;
245 } else
246 tag_mem->size = 0;
247
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530248 /* first make tag_mem_state visible to all */
249 wmb();
250 set_bit(MCC_TAG_STATE_TIMEOUT,
251 &phba->ctrl.ptag_state[tag].tag_state);
252
John Soni Josee175def2012-10-20 04:45:40 +0530253 beiscsi_log(phba, KERN_ERR,
254 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
255 BEISCSI_LOG_CONFIG,
256 "BC_%d : MBX Cmd Completion timed out\n");
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500257 return -EBUSY;
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500258 }
John Soni Josee175def2012-10-20 04:45:40 +0530259
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530260 rc = __beiscsi_mcc_compl_status(phba, tag, wrb, mbx_cmd_mem);
John Soni Josee175def2012-10-20 04:45:40 +0530261
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530262 free_mcc_wrb(&phba->ctrl, tag);
John Soni Josee175def2012-10-20 04:45:40 +0530263 return rc;
264}
265
John Soni Josee175def2012-10-20 04:45:40 +0530266/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530267 * beiscsi_process_mbox_compl()- Check the MBX completion status
John Soni Josee175def2012-10-20 04:45:40 +0530268 * @ctrl: Function specific MBX data structure
269 * @compl: Completion status of MBX Command
270 *
271 * Check for the MBX completion status when BMBX method used
272 *
273 * return
274 * Success: Zero
275 * Failure: Non-Zero
276 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530277static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
278 struct be_mcc_compl *compl)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530279{
280 u16 compl_status, extd_status;
John Soni Josee175def2012-10-20 04:45:40 +0530281 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530282 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
John Soni Josee175def2012-10-20 04:45:40 +0530283 struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
Jayamohan Kallickala8081e32013-04-05 20:38:22 -0700284 struct be_cmd_resp_hdr *resp_hdr;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530285
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530286 /**
287 * To check if valid bit is set, check the entire word as we don't know
288 * the endianness of the data (old entry is host endian while a new
289 * entry is little endian)
290 */
291 if (!compl->flags) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530292 beiscsi_log(phba, KERN_ERR,
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530293 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
294 "BC_%d : BMBX busy, no completion\n");
295 return -EBUSY;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530296 }
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530297 compl->flags = le32_to_cpu(compl->flags);
298 WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
299
300 /**
301 * Just swap the status to host endian;
302 * mcc tag is opaquely copied from mcc_wrb.
303 */
304 be_dws_le_to_cpu(compl, 4);
305 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
306 CQE_STATUS_COMPL_MASK;
307 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
308 CQE_STATUS_EXTD_MASK;
309 /* Need to reset the entire word that houses the valid bit */
310 compl->flags = 0;
311
312 if (compl_status == MCC_STATUS_SUCCESS)
313 return 0;
314
315 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
316 "BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n",
317 hdr->subsystem, hdr->opcode, compl_status, extd_status);
318
319 if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
320 /* if status is insufficient buffer, check the length */
321 resp_hdr = (struct be_cmd_resp_hdr *) hdr;
322 if (resp_hdr->response_length)
323 return 0;
324 }
325 return -EINVAL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530326}
327
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530328static void beiscsi_process_async_link(struct beiscsi_hba *phba,
329 struct be_mcc_compl *compl)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530330{
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530331 struct be_async_event_link_state *evt;
332
333 evt = (struct be_async_event_link_state *)compl;
334
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530335 phba->port_speed = evt->port_speed;
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530336 /**
337 * Check logical link status in ASYNC event.
338 * This has been newly introduced in SKH-R Firmware 10.0.338.45.
339 **/
340 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530341 set_bit(BEISCSI_HBA_LINK_UP, &phba->state);
342 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
343 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530344 __beiscsi_log(phba, KERN_ERR,
345 "BC_%d : Link Up on Port %d tag 0x%x\n",
346 evt->physical_port, evt->event_tag);
347 } else {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530348 clear_bit(BEISCSI_HBA_LINK_UP, &phba->state);
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530349 __beiscsi_log(phba, KERN_ERR,
350 "BC_%d : Link Down on Port %d tag 0x%x\n",
351 evt->physical_port, evt->event_tag);
352 iscsi_host_for_each_session(phba->shost,
353 beiscsi_fail_session);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530354 }
355}
356
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530357static char *beiscsi_port_misconf_event_msg[] = {
358 "Physical Link is functional.",
359 "Optics faulted/incorrectly installed/not installed - Reseat optics, if issue not resolved, replace.",
360 "Optics of two types installed - Remove one optic or install matching pair of optics.",
361 "Incompatible optics - Replace with compatible optics for card to function.",
362 "Unqualified optics - Replace with Avago optics for Warranty and Technical Support.",
363 "Uncertified optics - Replace with Avago Certified optics to enable link operation."
364};
365
366static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
367 struct be_mcc_compl *compl)
368{
369 struct be_async_event_sli *async_sli;
370 u8 evt_type, state, old_state, le;
371 char *sev = KERN_WARNING;
372 char *msg = NULL;
373
374 evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
375 evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
376
377 /* processing only MISCONFIGURED physical port event */
378 if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
379 return;
380
381 async_sli = (struct be_async_event_sli *)compl;
382 state = async_sli->event_data1 >>
383 (phba->fw_config.phys_port * 8) & 0xff;
384 le = async_sli->event_data2 >>
385 (phba->fw_config.phys_port * 8) & 0xff;
386
387 old_state = phba->optic_state;
388 phba->optic_state = state;
389
390 if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
391 /* fw is reporting a state we don't know, log and return */
392 __beiscsi_log(phba, KERN_ERR,
393 "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
394 phba->port_name, async_sli->event_data1);
395 return;
396 }
397
398 if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
399 /* log link effect for unqualified-4, uncertified-5 optics */
400 if (state > 3)
401 msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
402 " Link is non-operational." :
403 " Link is operational.";
404 /* 1 - info */
405 if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
406 sev = KERN_INFO;
407 /* 2 - error */
408 if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2)
409 sev = KERN_ERR;
410 }
411
412 if (old_state != phba->optic_state)
413 __beiscsi_log(phba, sev, "BC_%d : Port %c: %s%s\n",
414 phba->port_name,
415 beiscsi_port_misconf_event_msg[state],
416 !msg ? "" : msg);
417}
418
419void beiscsi_process_async_event(struct beiscsi_hba *phba,
420 struct be_mcc_compl *compl)
421{
422 char *sev = KERN_INFO;
423 u8 evt_code;
424
425 /* interpret flags as an async trailer */
426 evt_code = compl->flags >> ASYNC_TRAILER_EVENT_CODE_SHIFT;
427 evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
428 switch (evt_code) {
429 case ASYNC_EVENT_CODE_LINK_STATE:
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530430 beiscsi_process_async_link(phba, compl);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530431 break;
432 case ASYNC_EVENT_CODE_ISCSI:
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530433 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
434 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530435 sev = KERN_ERR;
436 break;
437 case ASYNC_EVENT_CODE_SLI:
438 beiscsi_process_async_sli(phba, compl);
439 break;
440 default:
441 /* event not registered */
442 sev = KERN_ERR;
443 }
444
445 beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530446 "BC_%d : ASYNC Event %x: status 0x%08x flags 0x%08x\n",
447 evt_code, compl->status, compl->flags);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530448}
449
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530450int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
451 struct be_mcc_compl *compl)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530452{
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530453 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
454 u16 compl_status, extd_status;
455 struct be_dma_mem *tag_mem;
456 unsigned int tag, wrb_idx;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530457
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530458 be_dws_le_to_cpu(compl, 4);
459 tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
460 wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
461
462 if (!test_bit(MCC_TAG_STATE_RUNNING,
463 &ctrl->ptag_state[tag].tag_state)) {
464 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX |
465 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
466 "BC_%d : MBX cmd completed but not posted\n");
467 return 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530468 }
469
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530470 /* end MCC with this tag */
471 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state);
472
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530473 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) {
474 beiscsi_log(phba, KERN_WARNING,
475 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
476 BEISCSI_LOG_CONFIG,
477 "BC_%d : MBX Completion for timeout Command from FW\n");
478 /**
479 * Check for the size before freeing resource.
480 * Only for non-embedded cmd, PCI resource is allocated.
481 **/
482 tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530483 if (tag_mem->size) {
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530484 pci_free_consistent(ctrl->pdev, tag_mem->size,
485 tag_mem->va, tag_mem->dma);
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530486 tag_mem->size = 0;
487 }
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530488 free_mcc_wrb(ctrl, tag);
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530489 return 0;
490 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530491
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530492 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
493 CQE_STATUS_COMPL_MASK;
494 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
495 CQE_STATUS_EXTD_MASK;
496 /* The ctrl.mcc_tag_status[tag] is filled with
497 * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
498 * [7:0] = compl_status
499 */
500 ctrl->mcc_tag_status[tag] = CQE_VALID_MASK;
501 ctrl->mcc_tag_status[tag] |= (wrb_idx << CQE_STATUS_WRB_SHIFT);
502 ctrl->mcc_tag_status[tag] |= (extd_status << CQE_STATUS_ADDL_SHIFT) &
503 CQE_STATUS_ADDL_MASK;
504 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
505
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530506 if (test_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state)) {
507 if (ctrl->ptag_state[tag].cbfn)
508 ctrl->ptag_state[tag].cbfn(phba, tag);
509 else
510 beiscsi_log(phba, KERN_ERR,
511 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
512 BEISCSI_LOG_CONFIG,
513 "BC_%d : MBX ASYNC command with no callback\n");
514 free_mcc_wrb(ctrl, tag);
515 return 0;
516 }
517
Jitendra Bhivare10bcd472016-08-19 15:20:13 +0530518 if (test_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state)) {
519 /* just check completion status and free wrb */
520 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
521 free_mcc_wrb(ctrl, tag);
522 return 0;
523 }
524
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530525 wake_up_interruptible(&ctrl->mcc_wait[tag]);
526 return 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530527}
528
John Soni Josee175def2012-10-20 04:45:40 +0530529/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530530 * be_mcc_compl_poll()- Wait for MBX completion
John Soni Josee175def2012-10-20 04:45:40 +0530531 * @phba: driver private structure
532 *
533 * Wait till no more pending mcc requests are present
534 *
535 * return
536 * Success: 0
537 * Failure: Non-Zero
538 *
539 **/
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530540int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned int tag)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530541{
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530542 struct be_ctrl_info *ctrl = &phba->ctrl;
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530543 int i;
544
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530545 if (!test_bit(MCC_TAG_STATE_RUNNING,
546 &ctrl->ptag_state[tag].tag_state)) {
547 beiscsi_log(phba, KERN_ERR,
548 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
549 "BC_%d: tag %u state not running\n", tag);
550 return 0;
551 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530552 for (i = 0; i < mcc_timeout; i++) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530553 if (beiscsi_hba_in_error(phba))
John Soni Josee175def2012-10-20 04:45:40 +0530554 return -EIO;
555
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530556 beiscsi_process_mcc_cq(phba);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530557 /* after polling, wrb and tag need to be released */
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530558 if (!test_bit(MCC_TAG_STATE_RUNNING,
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530559 &ctrl->ptag_state[tag].tag_state)) {
560 free_mcc_wrb(ctrl, tag);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530561 break;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530562 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530563 udelay(100);
564 }
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530565
566 if (i < mcc_timeout)
567 return 0;
568
569 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
570 "BC_%d : FW Timed Out\n");
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530571 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530572 beiscsi_ue_detect(phba);
573 return -EBUSY;
574}
575
576void be_mcc_notify(struct beiscsi_hba *phba, unsigned int tag)
577{
578 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
579 u32 val = 0;
580
581 set_bit(MCC_TAG_STATE_RUNNING, &phba->ctrl.ptag_state[tag].tag_state);
582 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
583 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
584 /* make request available for DMA */
585 wmb();
586 iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530587}
588
John Soni Josee175def2012-10-20 04:45:40 +0530589/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530590 * be_mbox_db_ready_poll()- Check ready status
John Soni Josee175def2012-10-20 04:45:40 +0530591 * @ctrl: Function specific MBX data structure
592 *
593 * Check for the ready status of FW to send BMBX
594 * commands to adapter.
595 *
596 * return
597 * Success: 0
598 * Failure: Non-Zero
599 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530600static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530601{
Jitendra Bhivare9ec6f6b2016-01-20 14:10:49 +0530602 /* wait 30s for generic non-flash MBOX operation */
603#define BEISCSI_MBX_RDY_BIT_TIMEOUT 30000
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530604 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
John Soni Josee175def2012-10-20 04:45:40 +0530605 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700606 unsigned long timeout;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530607 u32 ready;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700608
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530609 /*
610 * This BMBX busy wait path is used during init only.
611 * For the commands executed during init, 5s should suffice.
612 */
613 timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530614 do {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530615 if (beiscsi_hba_in_error(phba))
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530616 return -EIO;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530617
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530618 ready = ioread32(db);
619 if (ready == 0xffffffff)
620 return -EIO;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700621
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530622 ready &= MPU_MAILBOX_DB_RDY_MASK;
623 if (ready)
624 return 0;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700625
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530626 if (time_after(jiffies, timeout))
627 break;
Jitendra Bhivare3c9e36a2016-08-19 15:20:00 +0530628 /* 1ms sleep is enough in most cases */
629 schedule_timeout_uninterruptible(msecs_to_jiffies(1));
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530630 } while (!ready);
631
632 beiscsi_log(phba, KERN_ERR,
633 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
634 "BC_%d : FW Timed Out\n");
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530635 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530636 beiscsi_ue_detect(phba);
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530637 return -EBUSY;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530638}
639
John Soni Josee175def2012-10-20 04:45:40 +0530640/*
641 * be_mbox_notify: Notify adapter of new BMBX command
642 * @ctrl: Function specific MBX data structure
643 *
644 * Ring doorbell to inform adapter of a BMBX command
645 * to process
646 *
647 * return
648 * Success: 0
649 * Failure: Non-Zero
650 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530651int be_mbox_notify(struct be_ctrl_info *ctrl)
652{
653 int status;
654 u32 val = 0;
655 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
656 struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
657 struct be_mcc_mailbox *mbox = mbox_mem->va;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530658
Jitendra Bhivare88840332016-02-04 15:49:12 +0530659 status = be_mbox_db_ready_poll(ctrl);
Jayamohan Kallickal1e234bb2013-04-05 20:38:23 -0700660 if (status)
661 return status;
662
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530663 val &= ~MPU_MAILBOX_DB_RDY_MASK;
664 val |= MPU_MAILBOX_DB_HI_MASK;
665 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
666 iowrite32(val, db);
667
Jitendra Bhivare88840332016-02-04 15:49:12 +0530668 status = be_mbox_db_ready_poll(ctrl);
John Soni Josee175def2012-10-20 04:45:40 +0530669 if (status)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530670 return status;
John Soni Josee175def2012-10-20 04:45:40 +0530671
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530672 val = 0;
673 val &= ~MPU_MAILBOX_DB_RDY_MASK;
674 val &= ~MPU_MAILBOX_DB_HI_MASK;
675 val |= (u32) (mbox_mem->dma >> 4) << 2;
676 iowrite32(val, db);
677
Jitendra Bhivare88840332016-02-04 15:49:12 +0530678 status = be_mbox_db_ready_poll(ctrl);
John Soni Josee175def2012-10-20 04:45:40 +0530679 if (status)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530680 return status;
John Soni Josee175def2012-10-20 04:45:40 +0530681
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530682 /* RDY is set; small delay before CQE read. */
683 udelay(1);
684
Jitendra Bhivarea264f5e2016-02-04 15:49:13 +0530685 status = beiscsi_process_mbox_compl(ctrl, &mbox->compl);
686 return status;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530687}
688
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530689void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
690 bool embedded, u8 sge_cnt)
691{
692 if (embedded)
693 wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
694 else
695 wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
696 MCC_WRB_SGE_CNT_SHIFT;
697 wrb->payload_length = payload_len;
698 be_dws_cpu_to_le(wrb, 8);
699}
700
701void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
702 u8 subsystem, u8 opcode, int cmd_len)
703{
704 req_hdr->opcode = opcode;
705 req_hdr->subsystem = subsystem;
706 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
John Soni Josee175def2012-10-20 04:45:40 +0530707 req_hdr->timeout = BEISCSI_FW_MBX_TIMEOUT;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530708}
709
710static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
711 struct be_dma_mem *mem)
712{
713 int i, buf_pages;
714 u64 dma = (u64) mem->dma;
715
716 buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
717 for (i = 0; i < buf_pages; i++) {
718 pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
719 pages[i].hi = cpu_to_le32(upper_32_bits(dma));
720 dma += PAGE_SIZE_4K;
721 }
722}
723
724static u32 eq_delay_to_mult(u32 usec_delay)
725{
726#define MAX_INTR_RATE 651042
727 const u32 round = 10;
728 u32 multiplier;
729
730 if (usec_delay == 0)
731 multiplier = 0;
732 else {
733 u32 interrupt_rate = 1000000 / usec_delay;
734 if (interrupt_rate == 0)
735 multiplier = 1023;
736 else {
737 multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
738 multiplier /= interrupt_rate;
739 multiplier = (multiplier + round / 2) / round;
740 multiplier = min(multiplier, (u32) 1023);
741 }
742 }
743 return multiplier;
744}
745
746struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
747{
748 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
749}
750
751int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
752 struct be_queue_info *eq, int eq_delay)
753{
754 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
755 struct be_cmd_req_eq_create *req = embedded_payload(wrb);
756 struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
757 struct be_dma_mem *q_mem = &eq->dma_mem;
758 int status;
759
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530760 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530761 memset(wrb, 0, sizeof(*wrb));
762
763 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
764
765 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
766 OPCODE_COMMON_EQ_CREATE, sizeof(*req));
767
768 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
769
770 AMAP_SET_BITS(struct amap_eq_context, func, req->context,
771 PCI_FUNC(ctrl->pdev->devfn));
772 AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
773 AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
774 AMAP_SET_BITS(struct amap_eq_context, count, req->context,
775 __ilog2_u32(eq->len / 256));
776 AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
777 eq_delay_to_mult(eq_delay));
778 be_dws_cpu_to_le(req->context, sizeof(req->context));
779
780 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
781
782 status = be_mbox_notify(ctrl);
783 if (!status) {
784 eq->id = le16_to_cpu(resp->eq_id);
785 eq->created = true;
786 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530787 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530788 return status;
789}
790
Jayamohan Kallickal0283fbb2013-04-05 20:38:21 -0700791/**
792 * be_cmd_fw_initialize()- Initialize FW
793 * @ctrl: Pointer to function control structure
794 *
795 * Send FW initialize pattern for the function.
796 *
797 * return
798 * Success: 0
799 * Failure: Non-Zero value
800 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530801int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
802{
803 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530804 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530805 int status;
806 u8 *endian_check;
807
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530808 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530809 memset(wrb, 0, sizeof(*wrb));
810
811 endian_check = (u8 *) wrb;
812 *endian_check++ = 0xFF;
813 *endian_check++ = 0x12;
814 *endian_check++ = 0x34;
815 *endian_check++ = 0xFF;
816 *endian_check++ = 0xFF;
817 *endian_check++ = 0x56;
818 *endian_check++ = 0x78;
819 *endian_check++ = 0xFF;
820 be_dws_cpu_to_le(wrb, sizeof(*wrb));
821
822 status = be_mbox_notify(ctrl);
823 if (status)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530824 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
825 "BC_%d : be_cmd_fw_initialize Failed\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530826
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530827 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530828 return status;
829}
830
Jayamohan Kallickal0283fbb2013-04-05 20:38:21 -0700831/**
832 * be_cmd_fw_uninit()- Uinitialize FW
833 * @ctrl: Pointer to function control structure
834 *
835 * Send FW uninitialize pattern for the function
836 *
837 * return
838 * Success: 0
839 * Failure: Non-Zero value
840 **/
841int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
842{
843 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
844 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
845 int status;
846 u8 *endian_check;
847
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530848 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal0283fbb2013-04-05 20:38:21 -0700849 memset(wrb, 0, sizeof(*wrb));
850
851 endian_check = (u8 *) wrb;
852 *endian_check++ = 0xFF;
853 *endian_check++ = 0xAA;
854 *endian_check++ = 0xBB;
855 *endian_check++ = 0xFF;
856 *endian_check++ = 0xFF;
857 *endian_check++ = 0xCC;
858 *endian_check++ = 0xDD;
859 *endian_check = 0xFF;
860
861 be_dws_cpu_to_le(wrb, sizeof(*wrb));
862
863 status = be_mbox_notify(ctrl);
864 if (status)
865 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
866 "BC_%d : be_cmd_fw_uninit Failed\n");
867
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530868 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal0283fbb2013-04-05 20:38:21 -0700869 return status;
870}
871
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530872int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
873 struct be_queue_info *cq, struct be_queue_info *eq,
874 bool sol_evts, bool no_delay, int coalesce_wm)
875{
876 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
877 struct be_cmd_req_cq_create *req = embedded_payload(wrb);
878 struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530879 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530880 struct be_dma_mem *q_mem = &cq->dma_mem;
881 void *ctxt = &req->context;
882 int status;
883
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530884 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530885 memset(wrb, 0, sizeof(*wrb));
886
887 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
888
889 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
890 OPCODE_COMMON_CQ_CREATE, sizeof(*req));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530891
892 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
Jayamohan Kallickal2c9dfd32013-04-05 20:38:26 -0700893 if (is_chip_be2_be3r(phba)) {
John Soni Joseeaae5262012-10-20 04:43:44 +0530894 AMAP_SET_BITS(struct amap_cq_context, coalescwm,
895 ctxt, coalesce_wm);
896 AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
897 AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
898 __ilog2_u32(cq->len / 256));
899 AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
900 AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
901 AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
902 AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
903 AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
904 AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
905 PCI_FUNC(ctrl->pdev->devfn));
Jayamohan Kallickal2c9dfd32013-04-05 20:38:26 -0700906 } else {
907 req->hdr.version = MBX_CMD_VER2;
908 req->page_size = 1;
909 AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
910 ctxt, coalesce_wm);
911 AMAP_SET_BITS(struct amap_cq_context_v2, nodelay,
912 ctxt, no_delay);
913 AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
914 __ilog2_u32(cq->len / 256));
915 AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
916 AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
917 AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
918 AMAP_SET_BITS(struct amap_cq_context_v2, armed, ctxt, 1);
John Soni Joseeaae5262012-10-20 04:43:44 +0530919 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530920
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530921 be_dws_cpu_to_le(ctxt, sizeof(req->context));
922
923 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
924
925 status = be_mbox_notify(ctrl);
926 if (!status) {
927 cq->id = le16_to_cpu(resp->cq_id);
928 cq->created = true;
929 } else
John Soni Jose99bc5d52012-08-20 23:00:18 +0530930 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
931 "BC_%d : In be_cmd_cq_create, status=ox%08x\n",
932 status);
933
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530934 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530935
936 return status;
937}
938
939static u32 be_encoded_q_len(int q_len)
940{
941 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
942 if (len_encoded == 16)
943 len_encoded = 0;
944 return len_encoded;
945}
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530946
Jayamohan Kallickal35e66012009-10-23 11:53:49 +0530947int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530948 struct be_queue_info *mccq,
949 struct be_queue_info *cq)
950{
951 struct be_mcc_wrb *wrb;
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530952 struct be_cmd_req_mcc_create_ext *req;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530953 struct be_dma_mem *q_mem = &mccq->dma_mem;
954 struct be_ctrl_info *ctrl;
955 void *ctxt;
956 int status;
957
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530958 mutex_lock(&phba->ctrl.mbox_lock);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530959 ctrl = &phba->ctrl;
960 wrb = wrb_from_mbox(&ctrl->mbox_mem);
Jayamohan Kallickal37609762011-10-07 19:31:11 -0500961 memset(wrb, 0, sizeof(*wrb));
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530962 req = embedded_payload(wrb);
963 ctxt = &req->context;
964
965 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
966
967 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530968 OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530969
970 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530971 req->async_evt_bitmap = 1 << ASYNC_EVENT_CODE_LINK_STATE;
972 req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_ISCSI;
973 req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_SLI;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530974
975 AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
976 PCI_FUNC(phba->pcidev->devfn));
977 AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
978 AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
979 be_encoded_q_len(mccq->len));
980 AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
981
982 be_dws_cpu_to_le(ctxt, sizeof(req->context));
983
984 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
985
Jitendra Bhivarea264f5e2016-02-04 15:49:13 +0530986 status = be_mbox_notify(ctrl);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530987 if (!status) {
988 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
989 mccq->id = le16_to_cpu(resp->id);
990 mccq->created = true;
991 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530992 mutex_unlock(&phba->ctrl.mbox_lock);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530993
994 return status;
995}
996
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530997int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
998 int queue_type)
999{
1000 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1001 struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +05301002 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301003 u8 subsys = 0, opcode = 0;
1004 int status;
1005
John Soni Jose99bc5d52012-08-20 23:00:18 +05301006 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1007 "BC_%d : In beiscsi_cmd_q_destroy "
1008 "queue_type : %d\n", queue_type);
1009
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301010 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301011 memset(wrb, 0, sizeof(*wrb));
1012 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1013
1014 switch (queue_type) {
1015 case QTYPE_EQ:
1016 subsys = CMD_SUBSYSTEM_COMMON;
1017 opcode = OPCODE_COMMON_EQ_DESTROY;
1018 break;
1019 case QTYPE_CQ:
1020 subsys = CMD_SUBSYSTEM_COMMON;
1021 opcode = OPCODE_COMMON_CQ_DESTROY;
1022 break;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301023 case QTYPE_MCCQ:
1024 subsys = CMD_SUBSYSTEM_COMMON;
1025 opcode = OPCODE_COMMON_MCC_DESTROY;
1026 break;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301027 case QTYPE_WRBQ:
1028 subsys = CMD_SUBSYSTEM_ISCSI;
1029 opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
1030 break;
1031 case QTYPE_DPDUQ:
1032 subsys = CMD_SUBSYSTEM_ISCSI;
1033 opcode = OPCODE_COMMON_ISCSI_DEFQ_DESTROY;
1034 break;
1035 case QTYPE_SGL:
1036 subsys = CMD_SUBSYSTEM_ISCSI;
1037 opcode = OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES;
1038 break;
1039 default:
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301040 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301041 BUG();
Jayamohan Kallickald3ad2bb2010-07-22 04:16:38 +05301042 return -ENXIO;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301043 }
1044 be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
1045 if (queue_type != QTYPE_SGL)
1046 req->id = cpu_to_le16(q->id);
1047
1048 status = be_mbox_notify(ctrl);
1049
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301050 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301051 return status;
1052}
1053
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001054/**
1055 * be_cmd_create_default_pdu_queue()- Create DEFQ for the adapter
1056 * @ctrl: ptr to ctrl_info
1057 * @cq: Completion Queue
1058 * @dq: Default Queue
1059 * @lenght: ring size
1060 * @entry_size: size of each entry in DEFQ
1061 * @is_header: Header or Data DEFQ
1062 * @ulp_num: Bind to which ULP
1063 *
1064 * Create HDR/Data DEFQ for the passed ULP. Unsol PDU are posted
1065 * on this queue by the FW
1066 *
1067 * return
1068 * Success: 0
1069 * Failure: Non-Zero Value
1070 *
1071 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301072int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
1073 struct be_queue_info *cq,
1074 struct be_queue_info *dq, int length,
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001075 int entry_size, uint8_t is_header,
1076 uint8_t ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301077{
1078 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1079 struct be_defq_create_req *req = embedded_payload(wrb);
1080 struct be_dma_mem *q_mem = &dq->dma_mem;
Jayamohan Kallickalef9e1b92013-04-05 20:38:27 -07001081 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301082 void *ctxt = &req->context;
1083 int status;
1084
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301085 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301086 memset(wrb, 0, sizeof(*wrb));
1087
1088 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1089
1090 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1091 OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));
1092
1093 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001094 if (phba->fw_config.dual_ulp_aware) {
1095 req->ulp_num = ulp_num;
1096 req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
1097 req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
1098 }
Jayamohan Kallickalef9e1b92013-04-05 20:38:27 -07001099
1100 if (is_chip_be2_be3r(phba)) {
1101 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1102 rx_pdid, ctxt, 0);
1103 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1104 rx_pdid_valid, ctxt, 1);
1105 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1106 pci_func_id, ctxt, PCI_FUNC(ctrl->pdev->devfn));
1107 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1108 ring_size, ctxt,
1109 be_encoded_q_len(length /
1110 sizeof(struct phys_addr)));
1111 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1112 default_buffer_size, ctxt, entry_size);
1113 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1114 cq_id_recv, ctxt, cq->id);
1115 } else {
1116 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1117 rx_pdid, ctxt, 0);
1118 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1119 rx_pdid_valid, ctxt, 1);
1120 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1121 ring_size, ctxt,
1122 be_encoded_q_len(length /
1123 sizeof(struct phys_addr)));
1124 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1125 default_buffer_size, ctxt, entry_size);
1126 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1127 cq_id_recv, ctxt, cq->id);
1128 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301129
1130 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1131
1132 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1133
1134 status = be_mbox_notify(ctrl);
1135 if (!status) {
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001136 struct be_ring *defq_ring;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301137 struct be_defq_create_resp *resp = embedded_payload(wrb);
1138
1139 dq->id = le16_to_cpu(resp->id);
1140 dq->created = true;
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001141 if (is_header)
1142 defq_ring = &phba->phwi_ctrlr->default_pdu_hdr[ulp_num];
1143 else
1144 defq_ring = &phba->phwi_ctrlr->
1145 default_pdu_data[ulp_num];
1146
1147 defq_ring->id = dq->id;
1148
1149 if (!phba->fw_config.dual_ulp_aware) {
1150 defq_ring->ulp_num = BEISCSI_ULP0;
1151 defq_ring->doorbell_offset = DB_RXULP0_OFFSET;
1152 } else {
1153 defq_ring->ulp_num = resp->ulp_num;
1154 defq_ring->doorbell_offset = resp->doorbell_offset;
1155 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301156 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301157 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301158
1159 return status;
1160}
1161
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001162/**
1163 * be_cmd_wrbq_create()- Create WRBQ
1164 * @ctrl: ptr to ctrl_info
1165 * @q_mem: memory details for the queue
1166 * @wrbq: queue info
1167 * @pwrb_context: ptr to wrb_context
1168 * @ulp_num: ULP on which the WRBQ is to be created
1169 *
1170 * Create WRBQ on the passed ULP_NUM.
1171 *
1172 **/
1173int be_cmd_wrbq_create(struct be_ctrl_info *ctrl,
1174 struct be_dma_mem *q_mem,
1175 struct be_queue_info *wrbq,
1176 struct hwi_wrb_context *pwrb_context,
1177 uint8_t ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301178{
1179 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1180 struct be_wrbq_create_req *req = embedded_payload(wrb);
1181 struct be_wrbq_create_resp *resp = embedded_payload(wrb);
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001182 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301183 int status;
1184
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301185 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301186 memset(wrb, 0, sizeof(*wrb));
1187
1188 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1189
1190 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1191 OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
1192 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001193
1194 if (phba->fw_config.dual_ulp_aware) {
1195 req->ulp_num = ulp_num;
1196 req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
1197 req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
1198 }
1199
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301200 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1201
1202 status = be_mbox_notify(ctrl);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301203 if (!status) {
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301204 wrbq->id = le16_to_cpu(resp->cid);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301205 wrbq->created = true;
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001206
1207 pwrb_context->cid = wrbq->id;
1208 if (!phba->fw_config.dual_ulp_aware) {
1209 pwrb_context->doorbell_offset = DB_TXULP0_OFFSET;
1210 pwrb_context->ulp_num = BEISCSI_ULP0;
1211 } else {
1212 pwrb_context->ulp_num = resp->ulp_num;
1213 pwrb_context->doorbell_offset = resp->doorbell_offset;
1214 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301215 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301216 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301217 return status;
1218}
1219
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001220int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl,
1221 struct be_dma_mem *q_mem)
1222{
1223 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1224 struct be_post_template_pages_req *req = embedded_payload(wrb);
1225 int status;
1226
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301227 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001228
1229 memset(wrb, 0, sizeof(*wrb));
1230 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1231 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1232 OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS,
1233 sizeof(*req));
1234
1235 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
1236 req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
1237 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1238
1239 status = be_mbox_notify(ctrl);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301240 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001241 return status;
1242}
1243
1244int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl)
1245{
1246 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1247 struct be_remove_template_pages_req *req = embedded_payload(wrb);
1248 int status;
1249
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301250 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001251
1252 memset(wrb, 0, sizeof(*wrb));
1253 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1254 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1255 OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS,
1256 sizeof(*req));
1257
1258 req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
1259
1260 status = be_mbox_notify(ctrl);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301261 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001262 return status;
1263}
1264
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301265int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
1266 struct be_dma_mem *q_mem,
1267 u32 page_offset, u32 num_pages)
1268{
1269 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1270 struct be_post_sgl_pages_req *req = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +05301271 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301272 int status;
1273 unsigned int curr_pages;
1274 u32 internal_page_offset = 0;
1275 u32 temp_num_pages = num_pages;
1276
1277 if (num_pages == 0xff)
1278 num_pages = 1;
1279
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301280 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301281 do {
1282 memset(wrb, 0, sizeof(*wrb));
1283 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1284 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1285 OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES,
1286 sizeof(*req));
1287 curr_pages = BE_NUMBER_OF_FIELD(struct be_post_sgl_pages_req,
1288 pages);
1289 req->num_pages = min(num_pages, curr_pages);
1290 req->page_offset = page_offset;
1291 be_cmd_page_addrs_prepare(req->pages, req->num_pages, q_mem);
1292 q_mem->dma = q_mem->dma + (req->num_pages * PAGE_SIZE);
1293 internal_page_offset += req->num_pages;
1294 page_offset += req->num_pages;
1295 num_pages -= req->num_pages;
1296
1297 if (temp_num_pages == 0xff)
1298 req->num_pages = temp_num_pages;
1299
1300 status = be_mbox_notify(ctrl);
1301 if (status) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301302 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1303 "BC_%d : FW CMD to map iscsi frags failed.\n");
1304
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301305 goto error;
1306 }
1307 } while (num_pages > 0);
1308error:
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301309 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301310 if (status != 0)
1311 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
1312 return status;
1313}
Jayamohan Kallickale5285862011-10-07 19:31:08 -05001314
1315int beiscsi_cmd_reset_function(struct beiscsi_hba *phba)
1316{
1317 struct be_ctrl_info *ctrl = &phba->ctrl;
1318 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1319 struct be_post_sgl_pages_req *req = embedded_payload(wrb);
1320 int status;
1321
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301322 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickale5285862011-10-07 19:31:08 -05001323
1324 req = embedded_payload(wrb);
1325 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1326 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1327 OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
Jitendra Bhivarea264f5e2016-02-04 15:49:13 +05301328 status = be_mbox_notify(ctrl);
Jayamohan Kallickale5285862011-10-07 19:31:08 -05001329
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301330 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickale5285862011-10-07 19:31:08 -05001331 return status;
1332}
John Soni Jose6f722382012-08-20 23:00:43 +05301333
1334/**
1335 * be_cmd_set_vlan()- Configure VLAN paramters on the adapter
1336 * @phba: device priv structure instance
1337 * @vlan_tag: TAG to be set
1338 *
1339 * Set the VLAN_TAG for the adapter or Disable VLAN on adapter
1340 *
1341 * returns
1342 * TAG for the MBX Cmd
1343 * **/
1344int be_cmd_set_vlan(struct beiscsi_hba *phba,
1345 uint16_t vlan_tag)
1346{
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301347 unsigned int tag;
John Soni Jose6f722382012-08-20 23:00:43 +05301348 struct be_mcc_wrb *wrb;
1349 struct be_cmd_set_vlan_req *req;
1350 struct be_ctrl_info *ctrl = &phba->ctrl;
1351
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301352 if (mutex_lock_interruptible(&ctrl->mbox_lock))
1353 return 0;
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301354 wrb = alloc_mcc_wrb(phba, &tag);
1355 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301356 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301357 return 0;
John Soni Jose6f722382012-08-20 23:00:43 +05301358 }
1359
John Soni Jose6f722382012-08-20 23:00:43 +05301360 req = embedded_payload(wrb);
John Soni Jose6f722382012-08-20 23:00:43 +05301361 be_wrb_hdr_prepare(wrb, sizeof(*wrb), true, 0);
1362 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1363 OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
1364 sizeof(*req));
1365
1366 req->interface_hndl = phba->interface_handle;
1367 req->vlan_priority = vlan_tag;
1368
Jitendra Bhivarecdde6682016-01-20 14:10:47 +05301369 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301370 mutex_unlock(&ctrl->mbox_lock);
John Soni Jose6f722382012-08-20 23:00:43 +05301371
1372 return tag;
1373}