blob: c10aac4dbc5ee6a9138bff2e885e879af679afda [file] [log] [blame]
Jitendra Bhivare942b7652017-03-24 14:11:48 +05301/*
Jitendra Bhivare0172dc62017-10-10 16:18:19 +05302 * Copyright 2017 Broadcom. All Rights Reserved.
Jitendra Bhivare942b7652017-03-24 14:11:48 +05303 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05304 *
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
Jitendra Bhivare942b7652017-03-24 14:11:48 +05307 * as published by the Free Software Foundation. The full GNU General
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05308 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
Jitendra Bhivare60f36e02016-08-19 15:20:24 +053011 * linux-drivers@broadcom.com
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053012 *
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053013 */
14
John Soni Jose21771992012-04-03 23:41:49 -050015#include <scsi/iscsi_proto.h>
16
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -070017#include "be_main.h"
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053018#include "be.h"
19#include "be_mgmt.h"
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053020
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +053021/* UE Status Low CSR */
22static const char * const desc_ue_status_low[] = {
23 "CEV",
24 "CTX",
25 "DBUF",
26 "ERX",
27 "Host",
28 "MPU",
29 "NDMA",
30 "PTC ",
31 "RDMA ",
32 "RXF ",
33 "RXIPS ",
34 "RXULP0 ",
35 "RXULP1 ",
36 "RXULP2 ",
37 "TIM ",
38 "TPOST ",
39 "TPRE ",
40 "TXIPS ",
41 "TXULP0 ",
42 "TXULP1 ",
43 "UC ",
44 "WDMA ",
45 "TXULP2 ",
46 "HOST1 ",
47 "P0_OB_LINK ",
48 "P1_OB_LINK ",
49 "HOST_GPIO ",
50 "MBOX ",
51 "AXGMAC0",
52 "AXGMAC1",
53 "JTAG",
54 "MPU_INTPEND"
55};
56
57/* UE Status High CSR */
58static const char * const desc_ue_status_hi[] = {
59 "LPCMEMHOST",
60 "MGMT_MAC",
61 "PCS0ONLINE",
62 "MPU_IRAM",
63 "PCS1ONLINE",
64 "PCTL0",
65 "PCTL1",
66 "PMEM",
67 "RR",
68 "TXPB",
69 "RXPP",
70 "XAUI",
71 "TXP",
72 "ARM",
73 "IPC",
74 "HOST2",
75 "HOST3",
76 "HOST4",
77 "HOST5",
78 "HOST6",
79 "HOST7",
80 "HOST8",
81 "HOST9",
82 "NETC",
83 "Unknown",
84 "Unknown",
85 "Unknown",
86 "Unknown",
87 "Unknown",
88 "Unknown",
89 "Unknown",
90 "Unknown"
91};
92
Jitendra Bhivare090e2182016-02-04 15:49:17 +053093struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
94 unsigned int *ref_tag)
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +053095{
Jitendra Bhivare090e2182016-02-04 15:49:17 +053096 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
97 struct be_mcc_wrb *wrb = NULL;
98 unsigned int tag;
99
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530100 spin_lock(&phba->ctrl.mcc_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530101 if (mccq->used == mccq->len) {
102 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
103 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
104 "BC_%d : MCC queue full: WRB used %u tag avail %u\n",
105 mccq->used, phba->ctrl.mcc_tag_available);
106 goto alloc_failed;
107 }
108
109 if (!phba->ctrl.mcc_tag_available)
110 goto alloc_failed;
111
112 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
113 if (!tag) {
114 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
115 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
116 "BC_%d : MCC tag 0 allocated: tag avail %u alloc index %u\n",
117 phba->ctrl.mcc_tag_available,
118 phba->ctrl.mcc_alloc_index);
119 goto alloc_failed;
120 }
121
122 /* return this tag for further reference */
123 *ref_tag = tag;
124 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
125 phba->ctrl.mcc_tag_status[tag] = 0;
126 phba->ctrl.ptag_state[tag].tag_state = 0;
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530127 phba->ctrl.ptag_state[tag].cbfn = NULL;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530128 phba->ctrl.mcc_tag_available--;
129 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
130 phba->ctrl.mcc_alloc_index = 0;
131 else
132 phba->ctrl.mcc_alloc_index++;
133
134 wrb = queue_head_node(mccq);
135 memset(wrb, 0, sizeof(*wrb));
136 wrb->tag0 = tag;
137 wrb->tag0 |= (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
138 queue_head_inc(mccq);
139 mccq->used++;
140
141alloc_failed:
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530142 spin_unlock(&phba->ctrl.mcc_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530143 return wrb;
144}
145
146void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag)
147{
148 struct be_queue_info *mccq = &ctrl->mcc_obj.q;
149
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530150 spin_lock(&ctrl->mcc_lock);
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530151 tag = tag & MCC_Q_CMD_TAG_MASK;
152 ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
153 if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
154 ctrl->mcc_free_index = 0;
155 else
156 ctrl->mcc_free_index++;
157 ctrl->mcc_tag_available++;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530158 mccq->used--;
Jitendra Bhivare96eb8d42016-08-19 15:19:59 +0530159 spin_unlock(&ctrl->mcc_lock);
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530160}
161
John Soni Josee175def2012-10-20 04:45:40 +0530162/*
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530163 * beiscsi_mcc_compl_status - Return the status of MCC completion
164 * @phba: Driver private structure
165 * @tag: Tag for the MBX Command
166 * @wrb: the WRB used for the MBX Command
167 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
168 *
169 * return
170 * Success: 0
171 * Failure: Non-Zero
172 */
173int __beiscsi_mcc_compl_status(struct beiscsi_hba *phba,
174 unsigned int tag,
175 struct be_mcc_wrb **wrb,
176 struct be_dma_mem *mbx_cmd_mem)
177{
178 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
179 uint16_t status = 0, addl_status = 0, wrb_num = 0;
180 struct be_cmd_resp_hdr *mbx_resp_hdr;
181 struct be_cmd_req_hdr *mbx_hdr;
182 struct be_mcc_wrb *temp_wrb;
183 uint32_t mcc_tag_status;
184 int rc = 0;
185
186 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
187 status = (mcc_tag_status & CQE_STATUS_MASK);
188 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
189 CQE_STATUS_ADDL_SHIFT);
190
191 if (mbx_cmd_mem) {
192 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
193 } else {
194 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
195 CQE_STATUS_WRB_SHIFT;
196 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
197 mbx_hdr = embedded_payload(temp_wrb);
198
199 if (wrb)
200 *wrb = temp_wrb;
201 }
202
203 if (status || addl_status) {
204 beiscsi_log(phba, KERN_WARNING,
205 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
206 BEISCSI_LOG_CONFIG,
207 "BC_%d : MBX Cmd Failed for Subsys : %d Opcode : %d with Status : %d and Extd_Status : %d\n",
208 mbx_hdr->subsystem, mbx_hdr->opcode,
209 status, addl_status);
210 rc = -EIO;
211 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
212 mbx_resp_hdr = (struct be_cmd_resp_hdr *)mbx_hdr;
213 beiscsi_log(phba, KERN_WARNING,
214 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
215 BEISCSI_LOG_CONFIG,
216 "BC_%d : Insufficient Buffer Error Resp_Len : %d Actual_Resp_Len : %d\n",
217 mbx_resp_hdr->response_length,
218 mbx_resp_hdr->actual_resp_len);
219 rc = -EAGAIN;
220 }
221 }
222
223 return rc;
224}
225
226/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530227 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
John Soni Josee175def2012-10-20 04:45:40 +0530228 * @phba: Driver private structure
229 * @tag: Tag for the MBX Command
230 * @wrb: the WRB used for the MBX Command
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500231 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
John Soni Josee175def2012-10-20 04:45:40 +0530232 *
233 * Waits for MBX completion with the passed TAG.
234 *
235 * return
236 * Success: 0
237 * Failure: Non-Zero
238 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530239int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530240 unsigned int tag,
241 struct be_mcc_wrb **wrb,
Jitendra Bhivare88840332016-02-04 15:49:12 +0530242 struct be_dma_mem *mbx_cmd_mem)
John Soni Josee175def2012-10-20 04:45:40 +0530243{
244 int rc = 0;
John Soni Josee175def2012-10-20 04:45:40 +0530245
Jitendra Bhivareeb419222017-03-24 14:11:40 +0530246 if (!tag || tag > MAX_MCC_CMD) {
247 __beiscsi_log(phba, KERN_ERR,
248 "BC_%d : invalid tag %u\n", tag);
249 return -EINVAL;
250 }
251
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530252 if (beiscsi_hba_in_error(phba)) {
253 clear_bit(MCC_TAG_STATE_RUNNING,
254 &phba->ctrl.ptag_state[tag].tag_state);
255 return -EIO;
256 }
John Soni Jose7a158002012-10-20 04:45:51 +0530257
John Soni Josee175def2012-10-20 04:45:40 +0530258 /* wait for the mccq completion */
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530259 rc = wait_event_interruptible_timeout(phba->ctrl.mcc_wait[tag],
260 phba->ctrl.mcc_tag_status[tag],
261 msecs_to_jiffies(
262 BEISCSI_HOST_MBX_TIMEOUT));
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +0530263 /**
264 * Return EIO if port is being disabled. Associated DMA memory, if any,
265 * is freed by the caller. When port goes offline, MCCQ is cleaned up
266 * so does WRB.
267 */
268 if (!test_bit(BEISCSI_HBA_ONLINE, &phba->state)) {
269 clear_bit(MCC_TAG_STATE_RUNNING,
270 &phba->ctrl.ptag_state[tag].tag_state);
271 return -EIO;
272 }
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530273
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530274 /**
275 * If MBOX cmd timeout expired, tag and resource allocated
276 * for cmd is not freed until FW returns completion.
277 */
John Soni Josee175def2012-10-20 04:45:40 +0530278 if (rc <= 0) {
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500279 struct be_dma_mem *tag_mem;
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500280
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530281 /**
282 * PCI/DMA memory allocated and posted in non-embedded mode
283 * will have mbx_cmd_mem != NULL.
284 * Save virtual and bus addresses for the command so that it
285 * can be freed later.
286 **/
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500287 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
288 if (mbx_cmd_mem) {
289 tag_mem->size = mbx_cmd_mem->size;
290 tag_mem->va = mbx_cmd_mem->va;
291 tag_mem->dma = mbx_cmd_mem->dma;
292 } else
293 tag_mem->size = 0;
294
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530295 /* first make tag_mem_state visible to all */
296 wmb();
297 set_bit(MCC_TAG_STATE_TIMEOUT,
298 &phba->ctrl.ptag_state[tag].tag_state);
299
John Soni Josee175def2012-10-20 04:45:40 +0530300 beiscsi_log(phba, KERN_ERR,
301 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
302 BEISCSI_LOG_CONFIG,
303 "BC_%d : MBX Cmd Completion timed out\n");
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500304 return -EBUSY;
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500305 }
John Soni Josee175def2012-10-20 04:45:40 +0530306
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530307 rc = __beiscsi_mcc_compl_status(phba, tag, wrb, mbx_cmd_mem);
John Soni Josee175def2012-10-20 04:45:40 +0530308
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530309 free_mcc_wrb(&phba->ctrl, tag);
John Soni Josee175def2012-10-20 04:45:40 +0530310 return rc;
311}
312
John Soni Josee175def2012-10-20 04:45:40 +0530313/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530314 * beiscsi_process_mbox_compl()- Check the MBX completion status
John Soni Josee175def2012-10-20 04:45:40 +0530315 * @ctrl: Function specific MBX data structure
316 * @compl: Completion status of MBX Command
317 *
318 * Check for the MBX completion status when BMBX method used
319 *
320 * return
321 * Success: Zero
322 * Failure: Non-Zero
323 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530324static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
325 struct be_mcc_compl *compl)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530326{
John Soni Josee175def2012-10-20 04:45:40 +0530327 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530328 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
John Soni Josee175def2012-10-20 04:45:40 +0530329 struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
Jitendra Bhivare66940952016-08-19 15:20:14 +0530330 u16 compl_status, extd_status;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530331
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530332 /**
333 * To check if valid bit is set, check the entire word as we don't know
334 * the endianness of the data (old entry is host endian while a new
335 * entry is little endian)
336 */
337 if (!compl->flags) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530338 beiscsi_log(phba, KERN_ERR,
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530339 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
340 "BC_%d : BMBX busy, no completion\n");
341 return -EBUSY;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530342 }
Jitendra Bhivarec4484272016-02-04 15:49:15 +0530343 compl->flags = le32_to_cpu(compl->flags);
344 WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
345
346 /**
347 * Just swap the status to host endian;
348 * mcc tag is opaquely copied from mcc_wrb.
349 */
350 be_dws_le_to_cpu(compl, 4);
351 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
352 CQE_STATUS_COMPL_MASK;
353 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
354 CQE_STATUS_EXTD_MASK;
355 /* Need to reset the entire word that houses the valid bit */
356 compl->flags = 0;
357
358 if (compl_status == MCC_STATUS_SUCCESS)
359 return 0;
360
361 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
362 "BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n",
363 hdr->subsystem, hdr->opcode, compl_status, extd_status);
Jitendra Bhivare66940952016-08-19 15:20:14 +0530364 return compl_status;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530365}
366
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530367static void beiscsi_process_async_link(struct beiscsi_hba *phba,
368 struct be_mcc_compl *compl)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530369{
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530370 struct be_async_event_link_state *evt;
371
372 evt = (struct be_async_event_link_state *)compl;
373
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530374 phba->port_speed = evt->port_speed;
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530375 /**
376 * Check logical link status in ASYNC event.
377 * This has been newly introduced in SKH-R Firmware 10.0.338.45.
378 **/
379 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530380 set_bit(BEISCSI_HBA_LINK_UP, &phba->state);
381 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
382 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530383 __beiscsi_log(phba, KERN_ERR,
384 "BC_%d : Link Up on Port %d tag 0x%x\n",
385 evt->physical_port, evt->event_tag);
386 } else {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530387 clear_bit(BEISCSI_HBA_LINK_UP, &phba->state);
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530388 __beiscsi_log(phba, KERN_ERR,
389 "BC_%d : Link Down on Port %d tag 0x%x\n",
390 evt->physical_port, evt->event_tag);
391 iscsi_host_for_each_session(phba->shost,
Jitendra Bhivare480195c2016-08-19 15:20:15 +0530392 beiscsi_session_fail);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530393 }
394}
395
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530396static char *beiscsi_port_misconf_event_msg[] = {
397 "Physical Link is functional.",
398 "Optics faulted/incorrectly installed/not installed - Reseat optics, if issue not resolved, replace.",
399 "Optics of two types installed - Remove one optic or install matching pair of optics.",
400 "Incompatible optics - Replace with compatible optics for card to function.",
401 "Unqualified optics - Replace with Avago optics for Warranty and Technical Support.",
402 "Uncertified optics - Replace with Avago Certified optics to enable link operation."
403};
404
405static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
406 struct be_mcc_compl *compl)
407{
408 struct be_async_event_sli *async_sli;
409 u8 evt_type, state, old_state, le;
410 char *sev = KERN_WARNING;
411 char *msg = NULL;
412
413 evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
414 evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
415
416 /* processing only MISCONFIGURED physical port event */
417 if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
418 return;
419
420 async_sli = (struct be_async_event_sli *)compl;
421 state = async_sli->event_data1 >>
422 (phba->fw_config.phys_port * 8) & 0xff;
423 le = async_sli->event_data2 >>
424 (phba->fw_config.phys_port * 8) & 0xff;
425
426 old_state = phba->optic_state;
427 phba->optic_state = state;
428
429 if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
430 /* fw is reporting a state we don't know, log and return */
431 __beiscsi_log(phba, KERN_ERR,
432 "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
433 phba->port_name, async_sli->event_data1);
434 return;
435 }
436
437 if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
438 /* log link effect for unqualified-4, uncertified-5 optics */
439 if (state > 3)
440 msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
441 " Link is non-operational." :
442 " Link is operational.";
443 /* 1 - info */
444 if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
445 sev = KERN_INFO;
446 /* 2 - error */
447 if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2)
448 sev = KERN_ERR;
449 }
450
451 if (old_state != phba->optic_state)
452 __beiscsi_log(phba, sev, "BC_%d : Port %c: %s%s\n",
453 phba->port_name,
454 beiscsi_port_misconf_event_msg[state],
455 !msg ? "" : msg);
456}
457
458void beiscsi_process_async_event(struct beiscsi_hba *phba,
459 struct be_mcc_compl *compl)
460{
461 char *sev = KERN_INFO;
462 u8 evt_code;
463
464 /* interpret flags as an async trailer */
465 evt_code = compl->flags >> ASYNC_TRAILER_EVENT_CODE_SHIFT;
466 evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
467 switch (evt_code) {
468 case ASYNC_EVENT_CODE_LINK_STATE:
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530469 beiscsi_process_async_link(phba, compl);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530470 break;
471 case ASYNC_EVENT_CODE_ISCSI:
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530472 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
473 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530474 sev = KERN_ERR;
475 break;
476 case ASYNC_EVENT_CODE_SLI:
477 beiscsi_process_async_sli(phba, compl);
478 break;
479 default:
480 /* event not registered */
481 sev = KERN_ERR;
482 }
483
484 beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
Jitendra Bhivare9c4f8b02016-01-20 14:10:59 +0530485 "BC_%d : ASYNC Event %x: status 0x%08x flags 0x%08x\n",
486 evt_code, compl->status, compl->flags);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530487}
488
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530489int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
490 struct be_mcc_compl *compl)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530491{
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530492 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
493 u16 compl_status, extd_status;
494 struct be_dma_mem *tag_mem;
495 unsigned int tag, wrb_idx;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530496
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530497 be_dws_le_to_cpu(compl, 4);
498 tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
499 wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
500
501 if (!test_bit(MCC_TAG_STATE_RUNNING,
502 &ctrl->ptag_state[tag].tag_state)) {
503 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX |
504 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
505 "BC_%d : MBX cmd completed but not posted\n");
506 return 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530507 }
508
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530509 /* end MCC with this tag */
510 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state);
511
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530512 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) {
513 beiscsi_log(phba, KERN_WARNING,
514 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
515 BEISCSI_LOG_CONFIG,
516 "BC_%d : MBX Completion for timeout Command from FW\n");
517 /**
518 * Check for the size before freeing resource.
519 * Only for non-embedded cmd, PCI resource is allocated.
520 **/
521 tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530522 if (tag_mem->size) {
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530523 pci_free_consistent(ctrl->pdev, tag_mem->size,
524 tag_mem->va, tag_mem->dma);
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530525 tag_mem->size = 0;
526 }
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530527 free_mcc_wrb(ctrl, tag);
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530528 return 0;
529 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530530
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530531 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
532 CQE_STATUS_COMPL_MASK;
533 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
534 CQE_STATUS_EXTD_MASK;
535 /* The ctrl.mcc_tag_status[tag] is filled with
536 * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
537 * [7:0] = compl_status
538 */
539 ctrl->mcc_tag_status[tag] = CQE_VALID_MASK;
540 ctrl->mcc_tag_status[tag] |= (wrb_idx << CQE_STATUS_WRB_SHIFT);
541 ctrl->mcc_tag_status[tag] |= (extd_status << CQE_STATUS_ADDL_SHIFT) &
542 CQE_STATUS_ADDL_MASK;
543 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
544
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530545 if (test_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state)) {
546 if (ctrl->ptag_state[tag].cbfn)
547 ctrl->ptag_state[tag].cbfn(phba, tag);
548 else
Jitendra Bhivare66940952016-08-19 15:20:14 +0530549 __beiscsi_log(phba, KERN_ERR,
550 "BC_%d : MBX ASYNC command with no callback\n");
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530551 free_mcc_wrb(ctrl, tag);
552 return 0;
553 }
554
Jitendra Bhivare10bcd472016-08-19 15:20:13 +0530555 if (test_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state)) {
556 /* just check completion status and free wrb */
557 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
558 free_mcc_wrb(ctrl, tag);
559 return 0;
560 }
561
Jitendra Bhivare2e4e8f62016-02-04 15:49:11 +0530562 wake_up_interruptible(&ctrl->mcc_wait[tag]);
563 return 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530564}
565
Jitendra Bhivare69fd6d72016-02-04 15:49:14 +0530566void be_mcc_notify(struct beiscsi_hba *phba, unsigned int tag)
567{
568 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
569 u32 val = 0;
570
571 set_bit(MCC_TAG_STATE_RUNNING, &phba->ctrl.ptag_state[tag].tag_state);
572 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
573 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
574 /* make request available for DMA */
575 wmb();
576 iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530577}
578
John Soni Josee175def2012-10-20 04:45:40 +0530579/*
Jitendra Bhivare88840332016-02-04 15:49:12 +0530580 * be_mbox_db_ready_poll()- Check ready status
John Soni Josee175def2012-10-20 04:45:40 +0530581 * @ctrl: Function specific MBX data structure
582 *
583 * Check for the ready status of FW to send BMBX
584 * commands to adapter.
585 *
586 * return
587 * Success: 0
588 * Failure: Non-Zero
589 **/
Jitendra Bhivare88840332016-02-04 15:49:12 +0530590static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530591{
Jitendra Bhivare9ec6f6b2016-01-20 14:10:49 +0530592 /* wait 30s for generic non-flash MBOX operation */
593#define BEISCSI_MBX_RDY_BIT_TIMEOUT 30000
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530594 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
John Soni Josee175def2012-10-20 04:45:40 +0530595 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700596 unsigned long timeout;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530597 u32 ready;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700598
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530599 /*
600 * This BMBX busy wait path is used during init only.
601 * For the commands executed during init, 5s should suffice.
602 */
603 timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530604 do {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530605 if (beiscsi_hba_in_error(phba))
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530606 return -EIO;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530607
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530608 ready = ioread32(db);
609 if (ready == 0xffffffff)
610 return -EIO;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700611
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530612 ready &= MPU_MAILBOX_DB_RDY_MASK;
613 if (ready)
614 return 0;
Jayamohan Kallickal92665a62013-09-28 15:35:43 -0700615
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530616 if (time_after(jiffies, timeout))
617 break;
Jitendra Bhivare3c9e36a2016-08-19 15:20:00 +0530618 /* 1ms sleep is enough in most cases */
619 schedule_timeout_uninterruptible(msecs_to_jiffies(1));
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530620 } while (!ready);
621
622 beiscsi_log(phba, KERN_ERR,
623 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
624 "BC_%d : FW Timed Out\n");
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530625 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530626 return -EBUSY;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530627}
628
John Soni Josee175def2012-10-20 04:45:40 +0530629/*
630 * be_mbox_notify: Notify adapter of new BMBX command
631 * @ctrl: Function specific MBX data structure
632 *
633 * Ring doorbell to inform adapter of a BMBX command
634 * to process
635 *
636 * return
637 * Success: 0
638 * Failure: Non-Zero
639 **/
Jitendra Bhivare480195c2016-08-19 15:20:15 +0530640static int be_mbox_notify(struct be_ctrl_info *ctrl)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530641{
642 int status;
643 u32 val = 0;
644 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
645 struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
646 struct be_mcc_mailbox *mbox = mbox_mem->va;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530647
Jitendra Bhivare88840332016-02-04 15:49:12 +0530648 status = be_mbox_db_ready_poll(ctrl);
Jayamohan Kallickal1e234bb2013-04-05 20:38:23 -0700649 if (status)
650 return status;
651
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530652 val &= ~MPU_MAILBOX_DB_RDY_MASK;
653 val |= MPU_MAILBOX_DB_HI_MASK;
654 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
655 iowrite32(val, db);
656
Jitendra Bhivare88840332016-02-04 15:49:12 +0530657 status = be_mbox_db_ready_poll(ctrl);
John Soni Josee175def2012-10-20 04:45:40 +0530658 if (status)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530659 return status;
John Soni Josee175def2012-10-20 04:45:40 +0530660
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530661 val = 0;
662 val &= ~MPU_MAILBOX_DB_RDY_MASK;
663 val &= ~MPU_MAILBOX_DB_HI_MASK;
664 val |= (u32) (mbox_mem->dma >> 4) << 2;
665 iowrite32(val, db);
666
Jitendra Bhivare88840332016-02-04 15:49:12 +0530667 status = be_mbox_db_ready_poll(ctrl);
John Soni Josee175def2012-10-20 04:45:40 +0530668 if (status)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530669 return status;
John Soni Josee175def2012-10-20 04:45:40 +0530670
Jitendra Bhivare6ac999e2016-01-20 14:10:45 +0530671 /* RDY is set; small delay before CQE read. */
672 udelay(1);
673
Jitendra Bhivarea264f5e2016-02-04 15:49:13 +0530674 status = beiscsi_process_mbox_compl(ctrl, &mbox->compl);
675 return status;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530676}
677
Jitendra Bhivarea39e9f72017-10-10 16:18:14 +0530678void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, u32 payload_len,
679 bool embedded, u8 sge_cnt)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530680{
681 if (embedded)
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +0530682 wrb->emb_sgecnt_special |= MCC_WRB_EMBEDDED_MASK;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530683 else
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +0530684 wrb->emb_sgecnt_special |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
685 MCC_WRB_SGE_CNT_SHIFT;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530686 wrb->payload_length = payload_len;
687 be_dws_cpu_to_le(wrb, 8);
688}
689
690void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
Jitendra Bhivarea39e9f72017-10-10 16:18:14 +0530691 u8 subsystem, u8 opcode, u32 cmd_len)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530692{
693 req_hdr->opcode = opcode;
694 req_hdr->subsystem = subsystem;
695 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
John Soni Josee175def2012-10-20 04:45:40 +0530696 req_hdr->timeout = BEISCSI_FW_MBX_TIMEOUT;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530697}
698
699static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
700 struct be_dma_mem *mem)
701{
702 int i, buf_pages;
703 u64 dma = (u64) mem->dma;
704
705 buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
706 for (i = 0; i < buf_pages; i++) {
707 pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
708 pages[i].hi = cpu_to_le32(upper_32_bits(dma));
709 dma += PAGE_SIZE_4K;
710 }
711}
712
713static u32 eq_delay_to_mult(u32 usec_delay)
714{
715#define MAX_INTR_RATE 651042
716 const u32 round = 10;
717 u32 multiplier;
718
719 if (usec_delay == 0)
720 multiplier = 0;
721 else {
722 u32 interrupt_rate = 1000000 / usec_delay;
723 if (interrupt_rate == 0)
724 multiplier = 1023;
725 else {
726 multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
727 multiplier /= interrupt_rate;
728 multiplier = (multiplier + round / 2) / round;
729 multiplier = min(multiplier, (u32) 1023);
730 }
731 }
732 return multiplier;
733}
734
735struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
736{
737 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
738}
739
740int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
741 struct be_queue_info *eq, int eq_delay)
742{
743 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
744 struct be_cmd_req_eq_create *req = embedded_payload(wrb);
745 struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
746 struct be_dma_mem *q_mem = &eq->dma_mem;
747 int status;
748
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530749 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530750 memset(wrb, 0, sizeof(*wrb));
751
752 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
753
754 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
755 OPCODE_COMMON_EQ_CREATE, sizeof(*req));
756
757 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
758
759 AMAP_SET_BITS(struct amap_eq_context, func, req->context,
760 PCI_FUNC(ctrl->pdev->devfn));
761 AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
762 AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
763 AMAP_SET_BITS(struct amap_eq_context, count, req->context,
764 __ilog2_u32(eq->len / 256));
765 AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
766 eq_delay_to_mult(eq_delay));
767 be_dws_cpu_to_le(req->context, sizeof(req->context));
768
769 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
770
771 status = be_mbox_notify(ctrl);
772 if (!status) {
773 eq->id = le16_to_cpu(resp->eq_id);
774 eq->created = true;
775 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530776 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530777 return status;
778}
779
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530780int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
781 struct be_queue_info *cq, struct be_queue_info *eq,
782 bool sol_evts, bool no_delay, int coalesce_wm)
783{
784 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
785 struct be_cmd_req_cq_create *req = embedded_payload(wrb);
786 struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530787 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530788 struct be_dma_mem *q_mem = &cq->dma_mem;
789 void *ctxt = &req->context;
790 int status;
791
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530792 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530793 memset(wrb, 0, sizeof(*wrb));
794
795 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
796
797 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
798 OPCODE_COMMON_CQ_CREATE, sizeof(*req));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530799
800 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
Jayamohan Kallickal2c9dfd32013-04-05 20:38:26 -0700801 if (is_chip_be2_be3r(phba)) {
John Soni Joseeaae5262012-10-20 04:43:44 +0530802 AMAP_SET_BITS(struct amap_cq_context, coalescwm,
803 ctxt, coalesce_wm);
804 AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
805 AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
806 __ilog2_u32(cq->len / 256));
807 AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
808 AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
809 AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
810 AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
811 AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
812 AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
813 PCI_FUNC(ctrl->pdev->devfn));
Jayamohan Kallickal2c9dfd32013-04-05 20:38:26 -0700814 } else {
815 req->hdr.version = MBX_CMD_VER2;
816 req->page_size = 1;
817 AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm,
818 ctxt, coalesce_wm);
819 AMAP_SET_BITS(struct amap_cq_context_v2, nodelay,
820 ctxt, no_delay);
821 AMAP_SET_BITS(struct amap_cq_context_v2, count, ctxt,
822 __ilog2_u32(cq->len / 256));
823 AMAP_SET_BITS(struct amap_cq_context_v2, valid, ctxt, 1);
824 AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1);
825 AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id);
826 AMAP_SET_BITS(struct amap_cq_context_v2, armed, ctxt, 1);
John Soni Joseeaae5262012-10-20 04:43:44 +0530827 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530828
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530829 be_dws_cpu_to_le(ctxt, sizeof(req->context));
830
831 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
832
833 status = be_mbox_notify(ctrl);
834 if (!status) {
835 cq->id = le16_to_cpu(resp->cq_id);
836 cq->created = true;
837 } else
John Soni Jose99bc5d52012-08-20 23:00:18 +0530838 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
839 "BC_%d : In be_cmd_cq_create, status=ox%08x\n",
840 status);
841
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530842 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530843
844 return status;
845}
846
847static u32 be_encoded_q_len(int q_len)
848{
849 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
850 if (len_encoded == 16)
851 len_encoded = 0;
852 return len_encoded;
853}
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530854
Jayamohan Kallickal35e66012009-10-23 11:53:49 +0530855int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530856 struct be_queue_info *mccq,
857 struct be_queue_info *cq)
858{
859 struct be_mcc_wrb *wrb;
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530860 struct be_cmd_req_mcc_create_ext *req;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530861 struct be_dma_mem *q_mem = &mccq->dma_mem;
862 struct be_ctrl_info *ctrl;
863 void *ctxt;
864 int status;
865
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530866 mutex_lock(&phba->ctrl.mbox_lock);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530867 ctrl = &phba->ctrl;
868 wrb = wrb_from_mbox(&ctrl->mbox_mem);
Jayamohan Kallickal37609762011-10-07 19:31:11 -0500869 memset(wrb, 0, sizeof(*wrb));
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530870 req = embedded_payload(wrb);
871 ctxt = &req->context;
872
873 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
874
875 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530876 OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530877
878 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jitendra Bhivare53aefe22016-01-20 14:10:53 +0530879 req->async_evt_bitmap = 1 << ASYNC_EVENT_CODE_LINK_STATE;
880 req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_ISCSI;
881 req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_SLI;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530882
883 AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
884 PCI_FUNC(phba->pcidev->devfn));
885 AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
886 AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
887 be_encoded_q_len(mccq->len));
888 AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
889
890 be_dws_cpu_to_le(ctxt, sizeof(req->context));
891
892 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
893
Jitendra Bhivarea264f5e2016-02-04 15:49:13 +0530894 status = be_mbox_notify(ctrl);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530895 if (!status) {
896 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
897 mccq->id = le16_to_cpu(resp->id);
898 mccq->created = true;
899 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530900 mutex_unlock(&phba->ctrl.mbox_lock);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530901
902 return status;
903}
904
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530905int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
906 int queue_type)
907{
908 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
909 struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530910 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530911 u8 subsys = 0, opcode = 0;
912 int status;
913
John Soni Jose99bc5d52012-08-20 23:00:18 +0530914 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
915 "BC_%d : In beiscsi_cmd_q_destroy "
916 "queue_type : %d\n", queue_type);
917
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530918 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530919 memset(wrb, 0, sizeof(*wrb));
920 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
921
922 switch (queue_type) {
923 case QTYPE_EQ:
924 subsys = CMD_SUBSYSTEM_COMMON;
925 opcode = OPCODE_COMMON_EQ_DESTROY;
926 break;
927 case QTYPE_CQ:
928 subsys = CMD_SUBSYSTEM_COMMON;
929 opcode = OPCODE_COMMON_CQ_DESTROY;
930 break;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530931 case QTYPE_MCCQ:
932 subsys = CMD_SUBSYSTEM_COMMON;
933 opcode = OPCODE_COMMON_MCC_DESTROY;
934 break;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530935 case QTYPE_WRBQ:
936 subsys = CMD_SUBSYSTEM_ISCSI;
937 opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
938 break;
939 case QTYPE_DPDUQ:
940 subsys = CMD_SUBSYSTEM_ISCSI;
941 opcode = OPCODE_COMMON_ISCSI_DEFQ_DESTROY;
942 break;
943 case QTYPE_SGL:
944 subsys = CMD_SUBSYSTEM_ISCSI;
945 opcode = OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES;
946 break;
947 default:
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530948 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530949 BUG();
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530950 }
951 be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
952 if (queue_type != QTYPE_SGL)
953 req->id = cpu_to_le16(q->id);
954
955 status = be_mbox_notify(ctrl);
956
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530957 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530958 return status;
959}
960
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -0700961/**
962 * be_cmd_create_default_pdu_queue()- Create DEFQ for the adapter
963 * @ctrl: ptr to ctrl_info
964 * @cq: Completion Queue
965 * @dq: Default Queue
966 * @lenght: ring size
967 * @entry_size: size of each entry in DEFQ
968 * @is_header: Header or Data DEFQ
969 * @ulp_num: Bind to which ULP
970 *
971 * Create HDR/Data DEFQ for the passed ULP. Unsol PDU are posted
972 * on this queue by the FW
973 *
974 * return
975 * Success: 0
976 * Failure: Non-Zero Value
977 *
978 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530979int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
980 struct be_queue_info *cq,
981 struct be_queue_info *dq, int length,
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -0700982 int entry_size, uint8_t is_header,
983 uint8_t ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530984{
985 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
986 struct be_defq_create_req *req = embedded_payload(wrb);
987 struct be_dma_mem *q_mem = &dq->dma_mem;
Jayamohan Kallickalef9e1b92013-04-05 20:38:27 -0700988 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530989 void *ctxt = &req->context;
990 int status;
991
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530992 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530993 memset(wrb, 0, sizeof(*wrb));
994
995 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
996
997 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
998 OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));
999
1000 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001001 if (phba->fw_config.dual_ulp_aware) {
1002 req->ulp_num = ulp_num;
1003 req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
1004 req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
1005 }
Jayamohan Kallickalef9e1b92013-04-05 20:38:27 -07001006
1007 if (is_chip_be2_be3r(phba)) {
1008 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1009 rx_pdid, ctxt, 0);
1010 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1011 rx_pdid_valid, ctxt, 1);
1012 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1013 pci_func_id, ctxt, PCI_FUNC(ctrl->pdev->devfn));
1014 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1015 ring_size, ctxt,
1016 be_encoded_q_len(length /
1017 sizeof(struct phys_addr)));
1018 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1019 default_buffer_size, ctxt, entry_size);
1020 AMAP_SET_BITS(struct amap_be_default_pdu_context,
1021 cq_id_recv, ctxt, cq->id);
1022 } else {
1023 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1024 rx_pdid, ctxt, 0);
1025 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1026 rx_pdid_valid, ctxt, 1);
1027 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1028 ring_size, ctxt,
1029 be_encoded_q_len(length /
1030 sizeof(struct phys_addr)));
1031 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1032 default_buffer_size, ctxt, entry_size);
1033 AMAP_SET_BITS(struct amap_default_pdu_context_ext,
1034 cq_id_recv, ctxt, cq->id);
1035 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301036
1037 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1038
1039 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1040
1041 status = be_mbox_notify(ctrl);
1042 if (!status) {
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001043 struct be_ring *defq_ring;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301044 struct be_defq_create_resp *resp = embedded_payload(wrb);
1045
1046 dq->id = le16_to_cpu(resp->id);
1047 dq->created = true;
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -07001048 if (is_header)
1049 defq_ring = &phba->phwi_ctrlr->default_pdu_hdr[ulp_num];
1050 else
1051 defq_ring = &phba->phwi_ctrlr->
1052 default_pdu_data[ulp_num];
1053
1054 defq_ring->id = dq->id;
1055
1056 if (!phba->fw_config.dual_ulp_aware) {
1057 defq_ring->ulp_num = BEISCSI_ULP0;
1058 defq_ring->doorbell_offset = DB_RXULP0_OFFSET;
1059 } else {
1060 defq_ring->ulp_num = resp->ulp_num;
1061 defq_ring->doorbell_offset = resp->doorbell_offset;
1062 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301063 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301064 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301065
1066 return status;
1067}
1068
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001069/**
1070 * be_cmd_wrbq_create()- Create WRBQ
1071 * @ctrl: ptr to ctrl_info
1072 * @q_mem: memory details for the queue
1073 * @wrbq: queue info
1074 * @pwrb_context: ptr to wrb_context
1075 * @ulp_num: ULP on which the WRBQ is to be created
1076 *
1077 * Create WRBQ on the passed ULP_NUM.
1078 *
1079 **/
1080int be_cmd_wrbq_create(struct be_ctrl_info *ctrl,
1081 struct be_dma_mem *q_mem,
1082 struct be_queue_info *wrbq,
1083 struct hwi_wrb_context *pwrb_context,
1084 uint8_t ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301085{
1086 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1087 struct be_wrbq_create_req *req = embedded_payload(wrb);
1088 struct be_wrbq_create_resp *resp = embedded_payload(wrb);
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001089 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301090 int status;
1091
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301092 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301093 memset(wrb, 0, sizeof(*wrb));
1094
1095 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1096
1097 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1098 OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
1099 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001100
1101 if (phba->fw_config.dual_ulp_aware) {
1102 req->ulp_num = ulp_num;
1103 req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
1104 req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
1105 }
1106
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301107 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1108
1109 status = be_mbox_notify(ctrl);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301110 if (!status) {
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301111 wrbq->id = le16_to_cpu(resp->cid);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301112 wrbq->created = true;
Jayamohan Kallickal4eea99d2013-09-28 15:35:48 -07001113
1114 pwrb_context->cid = wrbq->id;
1115 if (!phba->fw_config.dual_ulp_aware) {
1116 pwrb_context->doorbell_offset = DB_TXULP0_OFFSET;
1117 pwrb_context->ulp_num = BEISCSI_ULP0;
1118 } else {
1119 pwrb_context->ulp_num = resp->ulp_num;
1120 pwrb_context->doorbell_offset = resp->doorbell_offset;
1121 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301122 }
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301123 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301124 return status;
1125}
1126
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001127int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl,
1128 struct be_dma_mem *q_mem)
1129{
1130 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1131 struct be_post_template_pages_req *req = embedded_payload(wrb);
1132 int status;
1133
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301134 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001135
1136 memset(wrb, 0, sizeof(*wrb));
1137 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1138 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1139 OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS,
1140 sizeof(*req));
1141
1142 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
1143 req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
1144 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
1145
1146 status = be_mbox_notify(ctrl);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301147 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001148 return status;
1149}
1150
1151int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl)
1152{
1153 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1154 struct be_remove_template_pages_req *req = embedded_payload(wrb);
1155 int status;
1156
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301157 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001158
1159 memset(wrb, 0, sizeof(*wrb));
1160 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1161 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1162 OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS,
1163 sizeof(*req));
1164
1165 req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
1166
1167 status = be_mbox_notify(ctrl);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301168 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal15a90fe2013-09-28 15:35:38 -07001169 return status;
1170}
1171
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301172int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
1173 struct be_dma_mem *q_mem,
1174 u32 page_offset, u32 num_pages)
1175{
1176 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1177 struct be_post_sgl_pages_req *req = embedded_payload(wrb);
John Soni Jose99bc5d52012-08-20 23:00:18 +05301178 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301179 int status;
1180 unsigned int curr_pages;
1181 u32 internal_page_offset = 0;
1182 u32 temp_num_pages = num_pages;
1183
1184 if (num_pages == 0xff)
1185 num_pages = 1;
1186
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301187 mutex_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301188 do {
1189 memset(wrb, 0, sizeof(*wrb));
1190 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1191 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1192 OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES,
1193 sizeof(*req));
1194 curr_pages = BE_NUMBER_OF_FIELD(struct be_post_sgl_pages_req,
1195 pages);
1196 req->num_pages = min(num_pages, curr_pages);
1197 req->page_offset = page_offset;
1198 be_cmd_page_addrs_prepare(req->pages, req->num_pages, q_mem);
1199 q_mem->dma = q_mem->dma + (req->num_pages * PAGE_SIZE);
1200 internal_page_offset += req->num_pages;
1201 page_offset += req->num_pages;
1202 num_pages -= req->num_pages;
1203
1204 if (temp_num_pages == 0xff)
1205 req->num_pages = temp_num_pages;
1206
1207 status = be_mbox_notify(ctrl);
1208 if (status) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301209 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1210 "BC_%d : FW CMD to map iscsi frags failed.\n");
1211
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301212 goto error;
1213 }
1214 } while (num_pages > 0);
1215error:
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301216 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301217 if (status != 0)
1218 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
1219 return status;
1220}
Jayamohan Kallickale5285862011-10-07 19:31:08 -05001221
John Soni Jose6f722382012-08-20 23:00:43 +05301222/**
1223 * be_cmd_set_vlan()- Configure VLAN paramters on the adapter
1224 * @phba: device priv structure instance
1225 * @vlan_tag: TAG to be set
1226 *
1227 * Set the VLAN_TAG for the adapter or Disable VLAN on adapter
1228 *
1229 * returns
1230 * TAG for the MBX Cmd
1231 * **/
1232int be_cmd_set_vlan(struct beiscsi_hba *phba,
1233 uint16_t vlan_tag)
1234{
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301235 unsigned int tag;
John Soni Jose6f722382012-08-20 23:00:43 +05301236 struct be_mcc_wrb *wrb;
1237 struct be_cmd_set_vlan_req *req;
1238 struct be_ctrl_info *ctrl = &phba->ctrl;
1239
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301240 if (mutex_lock_interruptible(&ctrl->mbox_lock))
1241 return 0;
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301242 wrb = alloc_mcc_wrb(phba, &tag);
1243 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301244 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +05301245 return 0;
John Soni Jose6f722382012-08-20 23:00:43 +05301246 }
1247
John Soni Jose6f722382012-08-20 23:00:43 +05301248 req = embedded_payload(wrb);
John Soni Jose6f722382012-08-20 23:00:43 +05301249 be_wrb_hdr_prepare(wrb, sizeof(*wrb), true, 0);
1250 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1251 OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
1252 sizeof(*req));
1253
1254 req->interface_hndl = phba->interface_handle;
1255 req->vlan_priority = vlan_tag;
1256
Jitendra Bhivarecdde6682016-01-20 14:10:47 +05301257 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +05301258 mutex_unlock(&ctrl->mbox_lock);
John Soni Jose6f722382012-08-20 23:00:43 +05301259
1260 return tag;
1261}
Jitendra Bhivare66940952016-08-19 15:20:14 +05301262
Jitendra Bhivare480195c2016-08-19 15:20:15 +05301263int beiscsi_check_supported_fw(struct be_ctrl_info *ctrl,
1264 struct beiscsi_hba *phba)
1265{
1266 struct be_dma_mem nonemb_cmd;
1267 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1268 struct be_mgmt_controller_attributes *req;
1269 struct be_sge *sge = nonembedded_sgl(wrb);
1270 int status = 0;
1271
1272 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
1273 sizeof(struct be_mgmt_controller_attributes),
1274 &nonemb_cmd.dma);
1275 if (nonemb_cmd.va == NULL) {
1276 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1277 "BG_%d : pci_alloc_consistent failed in %s\n",
1278 __func__);
1279 return -ENOMEM;
1280 }
1281 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
1282 req = nonemb_cmd.va;
1283 memset(req, 0, sizeof(*req));
1284 mutex_lock(&ctrl->mbox_lock);
1285 memset(wrb, 0, sizeof(*wrb));
1286 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1287 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1288 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
1289 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1290 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
1291 sge->len = cpu_to_le32(nonemb_cmd.size);
1292 status = be_mbox_notify(ctrl);
1293 if (!status) {
1294 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
1295
1296 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1297 "BG_%d : Firmware Version of CMD : %s\n"
1298 "Firmware Version is : %s\n"
1299 "Developer Build, not performing version check...\n",
1300 resp->params.hba_attribs
1301 .flashrom_version_string,
1302 resp->params.hba_attribs.
1303 firmware_version_string);
1304
1305 phba->fw_config.iscsi_features =
1306 resp->params.hba_attribs.iscsi_features;
1307 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1308 "BM_%d : phba->fw_config.iscsi_features = %d\n",
1309 phba->fw_config.iscsi_features);
1310 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
1311 firmware_version_string, BEISCSI_VER_STRLEN);
1312 } else
1313 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1314 "BG_%d : Failed in beiscsi_check_supported_fw\n");
1315 mutex_unlock(&ctrl->mbox_lock);
1316 if (nonemb_cmd.va)
1317 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
1318 nonemb_cmd.va, nonemb_cmd.dma);
1319
1320 return status;
1321}
1322
1323/**
1324 * beiscsi_get_fw_config()- Get the FW config for the function
1325 * @ctrl: ptr to Ctrl Info
1326 * @phba: ptr to the dev priv structure
1327 *
1328 * Get the FW config and resources available for the function.
1329 * The resources are created based on the count received here.
1330 *
1331 * return
1332 * Success: 0
1333 * Failure: Non-Zero Value
1334 **/
1335int beiscsi_get_fw_config(struct be_ctrl_info *ctrl,
1336 struct beiscsi_hba *phba)
1337{
1338 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1339 struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
1340 uint32_t cid_count, icd_count;
1341 int status = -EINVAL;
1342 uint8_t ulp_num = 0;
1343
1344 mutex_lock(&ctrl->mbox_lock);
1345 memset(wrb, 0, sizeof(*wrb));
1346 be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
1347
1348 be_cmd_hdr_prepare(&pfw_cfg->hdr, CMD_SUBSYSTEM_COMMON,
1349 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
1350 EMBED_MBX_MAX_PAYLOAD_SIZE);
1351
1352 if (be_mbox_notify(ctrl)) {
1353 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1354 "BG_%d : Failed in beiscsi_get_fw_config\n");
1355 goto fail_init;
1356 }
1357
1358 /* FW response formats depend on port id */
1359 phba->fw_config.phys_port = pfw_cfg->phys_port;
1360 if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
1361 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1362 "BG_%d : invalid physical port id %d\n",
1363 phba->fw_config.phys_port);
1364 goto fail_init;
1365 }
1366
1367 /* populate and check FW config against min and max values */
1368 if (!is_chip_be2_be3r(phba)) {
1369 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
1370 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
1371 if (phba->fw_config.eqid_count == 0 ||
1372 phba->fw_config.eqid_count > 2048) {
1373 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1374 "BG_%d : invalid EQ count %d\n",
1375 phba->fw_config.eqid_count);
1376 goto fail_init;
1377 }
1378 if (phba->fw_config.cqid_count == 0 ||
1379 phba->fw_config.cqid_count > 4096) {
1380 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1381 "BG_%d : invalid CQ count %d\n",
1382 phba->fw_config.cqid_count);
1383 goto fail_init;
1384 }
1385 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1386 "BG_%d : EQ_Count : %d CQ_Count : %d\n",
1387 phba->fw_config.eqid_count,
1388 phba->fw_config.cqid_count);
1389 }
1390
1391 /**
1392 * Check on which all ULP iSCSI Protocol is loaded.
1393 * Set the Bit for those ULP. This set flag is used
1394 * at all places in the code to check on which ULP
1395 * iSCSi Protocol is loaded
1396 **/
1397 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1398 if (pfw_cfg->ulp[ulp_num].ulp_mode &
1399 BEISCSI_ULP_ISCSI_INI_MODE) {
1400 set_bit(ulp_num, &phba->fw_config.ulp_supported);
1401
1402 /* Get the CID, ICD and Chain count for each ULP */
1403 phba->fw_config.iscsi_cid_start[ulp_num] =
1404 pfw_cfg->ulp[ulp_num].sq_base;
1405 phba->fw_config.iscsi_cid_count[ulp_num] =
1406 pfw_cfg->ulp[ulp_num].sq_count;
1407
1408 phba->fw_config.iscsi_icd_start[ulp_num] =
1409 pfw_cfg->ulp[ulp_num].icd_base;
1410 phba->fw_config.iscsi_icd_count[ulp_num] =
1411 pfw_cfg->ulp[ulp_num].icd_count;
1412
1413 phba->fw_config.iscsi_chain_start[ulp_num] =
1414 pfw_cfg->chain_icd[ulp_num].chain_base;
1415 phba->fw_config.iscsi_chain_count[ulp_num] =
1416 pfw_cfg->chain_icd[ulp_num].chain_count;
1417
1418 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1419 "BG_%d : Function loaded on ULP : %d\n"
1420 "\tiscsi_cid_count : %d\n"
1421 "\tiscsi_cid_start : %d\n"
1422 "\t iscsi_icd_count : %d\n"
1423 "\t iscsi_icd_start : %d\n",
1424 ulp_num,
1425 phba->fw_config.
1426 iscsi_cid_count[ulp_num],
1427 phba->fw_config.
1428 iscsi_cid_start[ulp_num],
1429 phba->fw_config.
1430 iscsi_icd_count[ulp_num],
1431 phba->fw_config.
1432 iscsi_icd_start[ulp_num]);
1433 }
1434 }
1435
1436 if (phba->fw_config.ulp_supported == 0) {
1437 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1438 "BG_%d : iSCSI initiator mode not set: ULP0 %x ULP1 %x\n",
1439 pfw_cfg->ulp[BEISCSI_ULP0].ulp_mode,
1440 pfw_cfg->ulp[BEISCSI_ULP1].ulp_mode);
1441 goto fail_init;
1442 }
1443
1444 /**
1445 * ICD is shared among ULPs. Use icd_count of any one loaded ULP
1446 **/
1447 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
1448 if (test_bit(ulp_num, &phba->fw_config.ulp_supported))
1449 break;
1450 icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
1451 if (icd_count == 0 || icd_count > 65536) {
1452 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1453 "BG_%d: invalid ICD count %d\n", icd_count);
1454 goto fail_init;
1455 }
1456
1457 cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
1458 BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
1459 if (cid_count == 0 || cid_count > 4096) {
1460 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1461 "BG_%d: invalid CID count %d\n", cid_count);
1462 goto fail_init;
1463 }
1464
1465 /**
1466 * Check FW is dual ULP aware i.e. can handle either
1467 * of the protocols.
1468 */
1469 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
1470 BEISCSI_FUNC_DUA_MODE);
1471
1472 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1473 "BG_%d : DUA Mode : 0x%x\n",
1474 phba->fw_config.dual_ulp_aware);
1475
1476 /* all set, continue using this FW config */
1477 status = 0;
1478fail_init:
1479 mutex_unlock(&ctrl->mbox_lock);
1480 return status;
1481}
1482
1483/**
1484 * beiscsi_get_port_name()- Get port name for the function
1485 * @ctrl: ptr to Ctrl Info
1486 * @phba: ptr to the dev priv structure
1487 *
1488 * Get the alphanumeric character for port
1489 *
1490 **/
1491int beiscsi_get_port_name(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba)
1492{
1493 int ret = 0;
1494 struct be_mcc_wrb *wrb;
1495 struct be_cmd_get_port_name *ioctl;
1496
1497 mutex_lock(&ctrl->mbox_lock);
1498 wrb = wrb_from_mbox(&ctrl->mbox_mem);
1499 memset(wrb, 0, sizeof(*wrb));
1500 ioctl = embedded_payload(wrb);
1501
1502 be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
1503 be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
1504 OPCODE_COMMON_GET_PORT_NAME,
1505 EMBED_MBX_MAX_PAYLOAD_SIZE);
1506 ret = be_mbox_notify(ctrl);
1507 phba->port_name = 0;
1508 if (!ret) {
1509 phba->port_name = ioctl->p.resp.port_names >>
1510 (phba->fw_config.phys_port * 8) & 0xff;
1511 } else {
1512 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1513 "BG_%d : GET_PORT_NAME ret 0x%x status 0x%x\n",
1514 ret, ioctl->h.resp_hdr.status);
1515 }
1516
1517 if (phba->port_name == 0)
1518 phba->port_name = '?';
1519
1520 mutex_unlock(&ctrl->mbox_lock);
1521 return ret;
1522}
1523
Jitendra Bhivare1cb3c3f2017-10-10 16:18:17 +05301524int beiscsi_set_host_data(struct beiscsi_hba *phba)
1525{
1526 struct be_ctrl_info *ctrl = &phba->ctrl;
1527 struct be_cmd_set_host_data *ioctl;
1528 struct be_mcc_wrb *wrb;
1529 int ret = 0;
1530
1531 if (is_chip_be2_be3r(phba))
1532 return ret;
1533
1534 mutex_lock(&ctrl->mbox_lock);
1535 wrb = wrb_from_mbox(&ctrl->mbox_mem);
1536 memset(wrb, 0, sizeof(*wrb));
1537 ioctl = embedded_payload(wrb);
1538
1539 be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
1540 be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
1541 OPCODE_COMMON_SET_HOST_DATA,
1542 EMBED_MBX_MAX_PAYLOAD_SIZE);
1543 ioctl->param.req.param_id = BE_CMD_SET_HOST_PARAM_ID;
1544 ioctl->param.req.param_len =
1545 snprintf((char *)ioctl->param.req.param_data,
1546 sizeof(ioctl->param.req.param_data),
1547 "Linux iSCSI v%s", BUILD_STR);
Jitendra Bhivarea81dde72018-06-07 13:54:41 +05301548 ioctl->param.req.param_len = ALIGN(ioctl->param.req.param_len + 1, 4);
Jitendra Bhivare1cb3c3f2017-10-10 16:18:17 +05301549 if (ioctl->param.req.param_len > BE_CMD_MAX_DRV_VERSION)
1550 ioctl->param.req.param_len = BE_CMD_MAX_DRV_VERSION;
1551 ret = be_mbox_notify(ctrl);
1552 if (!ret) {
1553 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1554 "BG_%d : HBA set host driver version\n");
1555 } else {
1556 /**
1557 * Check "MCC_STATUS_INVALID_LENGTH" for SKH.
1558 * Older FW versions return this error.
1559 */
1560 if (ret == MCC_STATUS_ILLEGAL_REQUEST ||
1561 ret == MCC_STATUS_INVALID_LENGTH)
1562 __beiscsi_log(phba, KERN_INFO,
1563 "BG_%d : HBA failed to set host driver version\n");
1564 }
1565
1566 mutex_unlock(&ctrl->mbox_lock);
1567 return ret;
1568}
1569
Jitendra Bhivare66940952016-08-19 15:20:14 +05301570int beiscsi_set_uer_feature(struct beiscsi_hba *phba)
1571{
1572 struct be_ctrl_info *ctrl = &phba->ctrl;
1573 struct be_cmd_set_features *ioctl;
1574 struct be_mcc_wrb *wrb;
1575 int ret = 0;
1576
1577 mutex_lock(&ctrl->mbox_lock);
1578 wrb = wrb_from_mbox(&ctrl->mbox_mem);
1579 memset(wrb, 0, sizeof(*wrb));
1580 ioctl = embedded_payload(wrb);
1581
1582 be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
1583 be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
1584 OPCODE_COMMON_SET_FEATURES,
1585 EMBED_MBX_MAX_PAYLOAD_SIZE);
1586 ioctl->feature = BE_CMD_SET_FEATURE_UER;
1587 ioctl->param_len = sizeof(ioctl->param.req);
1588 ioctl->param.req.uer = BE_CMD_UER_SUPP_BIT;
1589 ret = be_mbox_notify(ctrl);
1590 if (!ret) {
1591 phba->ue2rp = ioctl->param.resp.ue2rp;
1592 set_bit(BEISCSI_HBA_UER_SUPP, &phba->state);
1593 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1594 "BG_%d : HBA error recovery supported\n");
1595 } else {
1596 /**
1597 * Check "MCC_STATUS_INVALID_LENGTH" for SKH.
1598 * Older FW versions return this error.
1599 */
1600 if (ret == MCC_STATUS_ILLEGAL_REQUEST ||
1601 ret == MCC_STATUS_INVALID_LENGTH)
1602 __beiscsi_log(phba, KERN_INFO,
1603 "BG_%d : HBA error recovery not supported\n");
1604 }
1605
1606 mutex_unlock(&ctrl->mbox_lock);
1607 return ret;
1608}
Jitendra Bhivare4d2ee1e2016-08-19 15:20:16 +05301609
1610static u32 beiscsi_get_post_stage(struct beiscsi_hba *phba)
1611{
1612 u32 sem;
1613
1614 if (is_chip_be2_be3r(phba))
1615 sem = ioread32(phba->csr_va + SLIPORT_SEMAPHORE_OFFSET_BEx);
1616 else
1617 pci_read_config_dword(phba->pcidev,
1618 SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
1619 return sem;
1620}
1621
1622int beiscsi_check_fw_rdy(struct beiscsi_hba *phba)
1623{
1624 u32 loop, post, rdy = 0;
1625
1626 loop = 1000;
1627 while (loop--) {
1628 post = beiscsi_get_post_stage(phba);
1629 if (post & POST_ERROR_BIT)
1630 break;
1631 if ((post & POST_STAGE_MASK) == POST_STAGE_ARMFW_RDY) {
1632 rdy = 1;
1633 break;
1634 }
1635 msleep(60);
1636 }
1637
1638 if (!rdy) {
1639 __beiscsi_log(phba, KERN_ERR,
1640 "BC_%d : FW not ready 0x%x\n", post);
1641 }
1642
1643 return rdy;
1644}
1645
Jitendra Bhivare4ee1ec42016-08-19 15:20:20 +05301646int beiscsi_cmd_function_reset(struct beiscsi_hba *phba)
Jitendra Bhivare4d2ee1e2016-08-19 15:20:16 +05301647{
1648 struct be_ctrl_info *ctrl = &phba->ctrl;
1649 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +05301650 struct be_post_sgl_pages_req *req;
Jitendra Bhivare4d2ee1e2016-08-19 15:20:16 +05301651 int status;
1652
1653 mutex_lock(&ctrl->mbox_lock);
1654
1655 req = embedded_payload(wrb);
1656 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1657 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1658 OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
1659 status = be_mbox_notify(ctrl);
1660
1661 mutex_unlock(&ctrl->mbox_lock);
1662 return status;
1663}
1664
1665int beiscsi_cmd_special_wrb(struct be_ctrl_info *ctrl, u32 load)
1666{
1667 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1668 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
1669 u8 *endian_check;
1670 int status;
1671
1672 mutex_lock(&ctrl->mbox_lock);
1673 memset(wrb, 0, sizeof(*wrb));
1674
1675 endian_check = (u8 *) wrb;
1676 if (load) {
1677 /* to start communicating */
1678 *endian_check++ = 0xFF;
1679 *endian_check++ = 0x12;
1680 *endian_check++ = 0x34;
1681 *endian_check++ = 0xFF;
1682 *endian_check++ = 0xFF;
1683 *endian_check++ = 0x56;
1684 *endian_check++ = 0x78;
1685 *endian_check++ = 0xFF;
1686 } else {
1687 /* to stop communicating */
1688 *endian_check++ = 0xFF;
1689 *endian_check++ = 0xAA;
1690 *endian_check++ = 0xBB;
1691 *endian_check++ = 0xFF;
1692 *endian_check++ = 0xFF;
1693 *endian_check++ = 0xCC;
1694 *endian_check++ = 0xDD;
1695 *endian_check = 0xFF;
1696 }
1697 be_dws_cpu_to_le(wrb, sizeof(*wrb));
1698
1699 status = be_mbox_notify(ctrl);
1700 if (status)
1701 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1702 "BC_%d : special WRB message failed\n");
1703 mutex_unlock(&ctrl->mbox_lock);
1704 return status;
1705}
1706
1707int beiscsi_init_sliport(struct beiscsi_hba *phba)
1708{
1709 int status;
1710
1711 /* check POST stage before talking to FW */
1712 status = beiscsi_check_fw_rdy(phba);
1713 if (!status)
1714 return -EIO;
1715
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +05301716 /* clear all error states after checking FW rdy */
1717 phba->state &= ~BEISCSI_HBA_IN_ERR;
1718
1719 /* check again UER support */
1720 phba->state &= ~BEISCSI_HBA_UER_SUPP;
1721
Jitendra Bhivare4d2ee1e2016-08-19 15:20:16 +05301722 /*
1723 * SLI COMMON_FUNCTION_RESET completion is indicated by BMBX RDY bit.
1724 * It should clean up any stale info in FW for this fn.
1725 */
1726 status = beiscsi_cmd_function_reset(phba);
1727 if (status) {
1728 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
1729 "BC_%d : SLI Function Reset failed\n");
1730 return status;
1731 }
1732
1733 /* indicate driver is loading */
1734 return beiscsi_cmd_special_wrb(&phba->ctrl, 1);
1735}
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301736
1737/**
1738 * beiscsi_cmd_iscsi_cleanup()- Inform FW to cleanup EP data structures.
1739 * @phba: pointer to dev priv structure
1740 * @ulp: ULP number.
1741 *
1742 * return
1743 * Success: 0
1744 * Failure: Non-Zero Value
1745 **/
1746int beiscsi_cmd_iscsi_cleanup(struct beiscsi_hba *phba, unsigned short ulp)
1747{
1748 struct be_ctrl_info *ctrl = &phba->ctrl;
1749 struct iscsi_cleanup_req_v1 *req_v1;
1750 struct iscsi_cleanup_req *req;
Jitendra Bhivared7401052016-12-13 15:55:59 +05301751 u16 hdr_ring_id, data_ring_id;
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301752 struct be_mcc_wrb *wrb;
1753 int status;
1754
1755 mutex_lock(&ctrl->mbox_lock);
1756 wrb = wrb_from_mbox(&ctrl->mbox_mem);
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301757
Jitendra Bhivared7401052016-12-13 15:55:59 +05301758 hdr_ring_id = HWI_GET_DEF_HDRQ_ID(phba, ulp);
1759 data_ring_id = HWI_GET_DEF_BUFQ_ID(phba, ulp);
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301760 if (is_chip_be2_be3r(phba)) {
Jitendra Bhivared7401052016-12-13 15:55:59 +05301761 req = embedded_payload(wrb);
1762 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1763 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1764 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301765 req->chute = (1 << ulp);
Jitendra Bhivared7401052016-12-13 15:55:59 +05301766 /* BE2/BE3 FW creates 8-bit ring id */
1767 req->hdr_ring_id = hdr_ring_id;
1768 req->data_ring_id = data_ring_id;
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301769 } else {
Jitendra Bhivared7401052016-12-13 15:55:59 +05301770 req_v1 = embedded_payload(wrb);
1771 be_wrb_hdr_prepare(wrb, sizeof(*req_v1), true, 0);
1772 be_cmd_hdr_prepare(&req_v1->hdr, CMD_SUBSYSTEM_ISCSI,
1773 OPCODE_COMMON_ISCSI_CLEANUP,
1774 sizeof(*req_v1));
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301775 req_v1->hdr.version = 1;
Jitendra Bhivared7401052016-12-13 15:55:59 +05301776 req_v1->chute = (1 << ulp);
1777 req_v1->hdr_ring_id = cpu_to_le16(hdr_ring_id);
1778 req_v1->data_ring_id = cpu_to_le16(data_ring_id);
Jitendra Bhivaref79929d2016-08-19 15:20:17 +05301779 }
1780
1781 status = be_mbox_notify(ctrl);
1782 if (status)
1783 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
1784 "BG_%d : %s failed %d\n", __func__, ulp);
1785 mutex_unlock(&ctrl->mbox_lock);
1786 return status;
1787}
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +05301788
1789/*
1790 * beiscsi_detect_ue()- Detect Unrecoverable Error on adapter
1791 * @phba: Driver priv structure
1792 *
1793 * Read registers linked to UE and check for the UE status
1794 **/
1795int beiscsi_detect_ue(struct beiscsi_hba *phba)
1796{
1797 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
1798 uint32_t ue_hi = 0, ue_lo = 0;
1799 uint8_t i = 0;
1800 int ret = 0;
1801
1802 pci_read_config_dword(phba->pcidev,
1803 PCICFG_UE_STATUS_LOW, &ue_lo);
1804 pci_read_config_dword(phba->pcidev,
1805 PCICFG_UE_STATUS_MASK_LOW,
1806 &ue_mask_lo);
1807 pci_read_config_dword(phba->pcidev,
1808 PCICFG_UE_STATUS_HIGH,
1809 &ue_hi);
1810 pci_read_config_dword(phba->pcidev,
1811 PCICFG_UE_STATUS_MASK_HI,
1812 &ue_mask_hi);
1813
1814 ue_lo = (ue_lo & ~ue_mask_lo);
1815 ue_hi = (ue_hi & ~ue_mask_hi);
1816
1817
1818 if (ue_lo || ue_hi) {
1819 set_bit(BEISCSI_HBA_IN_UE, &phba->state);
1820 __beiscsi_log(phba, KERN_ERR,
1821 "BC_%d : HBA error detected\n");
1822 ret = 1;
1823 }
1824
1825 if (ue_lo) {
1826 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
1827 if (ue_lo & 1)
1828 __beiscsi_log(phba, KERN_ERR,
1829 "BC_%d : UE_LOW %s bit set\n",
1830 desc_ue_status_low[i]);
1831 }
1832 }
1833
1834 if (ue_hi) {
1835 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
1836 if (ue_hi & 1)
1837 __beiscsi_log(phba, KERN_ERR,
1838 "BC_%d : UE_HIGH %s bit set\n",
1839 desc_ue_status_hi[i]);
1840 }
1841 }
1842 return ret;
1843}
1844
1845/*
1846 * beiscsi_detect_tpe()- Detect Transient Parity Error on adapter
1847 * @phba: Driver priv structure
1848 *
1849 * Read SLIPORT SEMAPHORE register to check for UER
1850 *
1851 **/
1852int beiscsi_detect_tpe(struct beiscsi_hba *phba)
1853{
1854 u32 post, status;
1855 int ret = 0;
1856
1857 post = beiscsi_get_post_stage(phba);
1858 status = post & POST_STAGE_MASK;
1859 if ((status & POST_ERR_RECOVERY_CODE_MASK) ==
1860 POST_STAGE_RECOVERABLE_ERR) {
1861 set_bit(BEISCSI_HBA_IN_TPE, &phba->state);
1862 __beiscsi_log(phba, KERN_INFO,
1863 "BC_%d : HBA error recoverable: 0x%x\n", post);
1864 ret = 1;
1865 } else {
1866 __beiscsi_log(phba, KERN_INFO,
1867 "BC_%d : HBA in UE: 0x%x\n", post);
1868 }
1869
1870 return ret;
1871}