1/*
2 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
3 * Host Bus Adapters. Refer to the README file included with this package
4 * for driver version and adapter compatibility.
5 *
6 * Copyright (c) 2018 Broadcom. All Rights Reserved.
7 * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of version 2 of the GNU General Public License as published
11 * by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful. ALL EXPRESS
14 * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
15 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
16 * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
17 * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
18 * See the GNU General Public License for more details, a copy of which
19 * can be found in the file COPYING included with this package.
20 *
21 * Contact Information:
22 * linux-drivers@broadcom.com
23 *
24 */
25
26#include <linux/bsg-lib.h>
27#include <scsi/scsi_transport_iscsi.h>
28#include <scsi/scsi_bsg_iscsi.h>
29#include "be_mgmt.h"
30#include "be_iscsi.h"
31#include "be_main.h"
32
33unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
34					 struct beiscsi_hba *phba,
35					 struct bsg_job *job,
36					 struct be_dma_mem *nonemb_cmd)
37{
38	struct be_mcc_wrb *wrb;
39	struct be_sge *mcc_sge;
40	unsigned int tag = 0;
41	struct iscsi_bsg_request *bsg_req = job->request;
42	struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
43	unsigned short region, sector_size, sector, offset;
44
45	nonemb_cmd->size = job->request_payload.payload_len;
46	memset(nonemb_cmd->va, 0, nonemb_cmd->size);
47	region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
48	sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
49	sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
50	offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
51	req->region = region;
52	req->sector = sector;
53	req->offset = offset;
54
55	if (mutex_lock_interruptible(&ctrl->mbox_lock))
56		return 0;
57	switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
58	case BEISCSI_WRITE_FLASH:
59		offset = sector * sector_size + offset;
60		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
61				   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
62		sg_copy_to_buffer(job->request_payload.sg_list,
63				  job->request_payload.sg_cnt,
64				  nonemb_cmd->va + offset, job->request_len);
65		break;
66	case BEISCSI_READ_FLASH:
67		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
68			   OPCODE_COMMON_READ_FLASH, sizeof(*req));
69		break;
70	default:
71		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
72			    "BG_%d : Unsupported cmd = 0x%x\n\n",
73			    bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
74
75		mutex_unlock(&ctrl->mbox_lock);
76		return -EPERM;
77	}
78
79	wrb = alloc_mcc_wrb(phba, &tag);
80	if (!wrb) {
81		mutex_unlock(&ctrl->mbox_lock);
82		return 0;
83	}
84
85	mcc_sge = nonembedded_sgl(wrb);
86	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
87			   job->request_payload.sg_cnt);
88	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
89	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
90	mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
91
92	be_mcc_notify(phba, tag);
93
94	mutex_unlock(&ctrl->mbox_lock);
95	return tag;
96}
97
98/**
99 * mgmt_open_connection()- Establish a TCP CXN
100 * @phba: driver priv structure
101 * @dst_addr: Destination Address
102 * @beiscsi_ep: ptr to device endpoint struct
103 * @nonemb_cmd: ptr to memory allocated for command
104 *
105 * return
106 *	Success: Tag number of the MBX Command issued
107 *	Failure: Error code
108 **/
109int mgmt_open_connection(struct beiscsi_hba *phba,
110			 struct sockaddr *dst_addr,
111			 struct beiscsi_endpoint *beiscsi_ep,
112			 struct be_dma_mem *nonemb_cmd)
113{
114	struct hwi_controller *phwi_ctrlr;
115	struct hwi_context_memory *phwi_context;
116	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
117	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
118	struct be_ctrl_info *ctrl = &phba->ctrl;
119	struct be_mcc_wrb *wrb;
120	struct tcp_connect_and_offload_in_v1 *req;
121	unsigned short def_hdr_id;
122	unsigned short def_data_id;
123	struct phys_addr template_address = { 0, 0 };
124	struct phys_addr *ptemplate_address;
125	unsigned int tag = 0;
126	unsigned int i, ulp_num;
127	unsigned short cid = beiscsi_ep->ep_cid;
128	struct be_sge *sge;
129
130	if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
131		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
132			    "BG_%d : unknown addr family %d\n",
133			    dst_addr->sa_family);
134		return 0;
135	}
136
137	phwi_ctrlr = phba->phwi_ctrlr;
138	phwi_context = phwi_ctrlr->phwi_ctxt;
139
140	ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
141
142	def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
143	def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
144
145	ptemplate_address = &template_address;
146	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
147	if (mutex_lock_interruptible(&ctrl->mbox_lock))
148		return 0;
149	wrb = alloc_mcc_wrb(phba, &tag);
150	if (!wrb) {
151		mutex_unlock(&ctrl->mbox_lock);
152		return 0;
153	}
154
155	sge = nonembedded_sgl(wrb);
156	req = nonemb_cmd->va;
157	memset(req, 0, sizeof(*req));
158
159	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
160	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
161			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
162			   nonemb_cmd->size);
163	if (dst_addr->sa_family == PF_INET) {
164		__be32 s_addr = daddr_in->sin_addr.s_addr;
165		req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
166		req->ip_address.addr[0] = s_addr & 0x000000ff;
167		req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
168		req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
169		req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
170		req->tcp_port = ntohs(daddr_in->sin_port);
171		beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
172		beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
173		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
174	} else {
175		/* else its PF_INET6 family */
176		req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
177		memcpy(&req->ip_address.addr,
178		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
179		req->tcp_port = ntohs(daddr_in6->sin6_port);
180		beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
181		memcpy(&beiscsi_ep->dst6_addr,
182		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
183		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
184	}
185	req->cid = cid;
186	i = phba->nxt_cqid++;
187	if (phba->nxt_cqid == phba->num_cpus)
188		phba->nxt_cqid = 0;
189	req->cq_id = phwi_context->be_cq[i].id;
190	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
191		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
192	req->defq_id = def_hdr_id;
193	req->hdr_ring_id = def_hdr_id;
194	req->data_ring_id = def_data_id;
195	req->do_offload = 1;
196	req->dataout_template_pa.lo = ptemplate_address->lo;
197	req->dataout_template_pa.hi = ptemplate_address->hi;
198	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
199	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
200	sge->len = cpu_to_le32(nonemb_cmd->size);
201
202	if (!is_chip_be2_be3r(phba)) {
203		req->hdr.version = MBX_CMD_VER1;
204		req->tcp_window_size = 0x8000;
205		req->tcp_window_scale_count = 2;
206	}
207
208	be_mcc_notify(phba, tag);
209	mutex_unlock(&ctrl->mbox_lock);
210	return tag;
211}
212
213/**
214 * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd
215 * @phba: driver priv structure
216 * @nonemb_cmd: DMA address of the MBX command to be issued
217 * @cbfn: callback func on MCC completion
218 * @resp_buf: buffer to copy the MBX cmd response
219 * @resp_buf_len: response length to be copied
220 *
221 **/
222static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
223				 struct be_dma_mem *nonemb_cmd,
224				 void (*cbfn)(struct beiscsi_hba *,
225					      unsigned int),
226				 void *resp_buf, u32 resp_buf_len)
227{
228	struct be_ctrl_info *ctrl = &phba->ctrl;
229	struct be_mcc_wrb *wrb;
230	struct be_sge *sge;
231	unsigned int tag;
232	int rc = 0;
233
234	mutex_lock(&ctrl->mbox_lock);
235	wrb = alloc_mcc_wrb(phba, &tag);
236	if (!wrb) {
237		mutex_unlock(&ctrl->mbox_lock);
238		rc = -ENOMEM;
239		goto free_cmd;
240	}
241
242	sge = nonembedded_sgl(wrb);
243	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
244	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
245	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
246	sge->len = cpu_to_le32(nonemb_cmd->size);
247
248	if (cbfn) {
249		struct be_dma_mem *tag_mem;
250
251		set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
252		ctrl->ptag_state[tag].cbfn = cbfn;
253		tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
254
255		/* store DMA mem to be freed in callback */
256		tag_mem->size = nonemb_cmd->size;
257		tag_mem->va = nonemb_cmd->va;
258		tag_mem->dma = nonemb_cmd->dma;
259	}
260	be_mcc_notify(phba, tag);
261	mutex_unlock(&ctrl->mbox_lock);
262
263	/* with cbfn set, its async cmd, don't wait */
264	if (cbfn)
265		return 0;
266
267	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
268
269	/* copy the response, if any */
270	if (resp_buf)
271		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
272	/**
273	 * This is special case of NTWK_GET_IF_INFO where the size of
274	 * response is not known. beiscsi_if_get_info checks the return
275	 * value to free DMA buffer.
276	 */
277	if (rc == -EAGAIN)
278		return rc;
279
280	/**
281	 * If FW is busy that is driver timed out, DMA buffer is saved with
282	 * the tag, only when the cmd completes this buffer is freed.
283	 */
284	if (rc == -EBUSY)
285		return rc;
286
287free_cmd:
288	dma_free_coherent(&ctrl->pdev->dev, nonemb_cmd->size,
289			    nonemb_cmd->va, nonemb_cmd->dma);
290	return rc;
291}
292
293static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
294				 struct be_dma_mem *cmd,
295				 u8 subsystem, u8 opcode, u32 size)
296{
297	cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, size, &cmd->dma,
298				     GFP_KERNEL);
299	if (!cmd->va) {
300		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
301			    "BG_%d : Failed to allocate memory for if info\n");
302		return -ENOMEM;
303	}
304	cmd->size = size;
305	be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
306	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
307		    "BG_%d : subsystem %u cmd %u size %u\n",
308		    subsystem, opcode, size);
309	return 0;
310}
311
312static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
313{
314	struct be_dma_mem *tag_mem;
315
316	/* status is ignored */
317	__beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
318	tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
319	if (tag_mem->size) {
320		dma_free_coherent(&phba->pcidev->dev, tag_mem->size,
321				    tag_mem->va, tag_mem->dma);
322		tag_mem->size = 0;
323	}
324}
325
326int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
327			    struct be_set_eqd *set_eqd, int num)
328{
329	struct be_cmd_req_modify_eq_delay *req;
330	struct be_dma_mem nonemb_cmd;
331	int i, rc;
332
333	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
334			OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
335	if (rc)
336		return rc;
337
338	req = nonemb_cmd.va;
339	req->num_eq = cpu_to_le32(num);
340	for (i = 0; i < num; i++) {
341		req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
342		req->delay[i].phase = 0;
343		req->delay[i].delay_multiplier =
344				cpu_to_le32(set_eqd[i].delay_multiplier);
345	}
346
347	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd,
348				     __beiscsi_eq_delay_compl, NULL, 0);
349}
350
351/**
352 * beiscsi_get_initiator_name - read initiator name from flash
353 * @phba: device priv structure
354 * @name: buffer pointer
355 * @cfg: fetch user configured
356 *
357 */
358int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
359{
360	struct be_dma_mem nonemb_cmd;
361	struct be_cmd_hba_name resp;
362	struct be_cmd_hba_name *req;
363	int rc;
364
365	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
366			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
367	if (rc)
368		return rc;
369
370	req = nonemb_cmd.va;
371	if (cfg)
372		req->hdr.version = 1;
373	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
374				   &resp, sizeof(resp));
375	if (rc) {
376		beiscsi_log(phba, KERN_ERR,
377			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
378			    "BS_%d : Initiator Name MBX Failed\n");
379		return rc;
380	}
381	rc = sprintf(name, "%s\n", resp.initiator_name);
382	return rc;
383}
384
385unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
386{
387	struct be_ctrl_info *ctrl = &phba->ctrl;
388	struct be_mcc_wrb *wrb;
389	struct be_cmd_get_all_if_id_req *req;
390	struct be_cmd_get_all_if_id_req *pbe_allid;
391	unsigned int tag;
392	int status = 0;
393
394	if (mutex_lock_interruptible(&ctrl->mbox_lock))
395		return -EINTR;
396	wrb = alloc_mcc_wrb(phba, &tag);
397	if (!wrb) {
398		mutex_unlock(&ctrl->mbox_lock);
399		return -ENOMEM;
400	}
401
402	req = embedded_payload(wrb);
403	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
404	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
405			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
406			   sizeof(*req));
407	be_mcc_notify(phba, tag);
408	mutex_unlock(&ctrl->mbox_lock);
409
410	status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
411	if (status) {
412		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
413			    "BG_%d : %s failed: %d\n", __func__, status);
414		return -EBUSY;
415	}
416
417	pbe_allid = embedded_payload(wrb);
418	/* we now support only one interface per function */
419	phba->interface_handle = pbe_allid->if_hndl_list[0];
420
421	return status;
422}
423
424static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
425{
426	u32 len;
427
428	len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
429	while (len && !ip[len - 1])
430		len--;
431	return (len == 0);
432}
433
434static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
435			     u32 action, u32 ip_type, u8 *gw)
436{
437	struct be_cmd_set_def_gateway_req *req;
438	struct be_dma_mem nonemb_cmd;
439	int rt_val;
440
441	rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
442			OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
443			sizeof(*req));
444	if (rt_val)
445		return rt_val;
446
447	req = nonemb_cmd.va;
448	req->action = action;
449	req->ip_addr.ip_type = ip_type;
450	memcpy(req->ip_addr.addr, gw,
451	       (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
452	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
453}
454
455int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
456{
457	struct be_cmd_get_def_gateway_resp gw_resp;
458	int rt_val;
459
460	memset(&gw_resp, 0, sizeof(gw_resp));
461	rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
462	if (rt_val) {
463		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
464			    "BG_%d : Failed to Get Gateway Addr\n");
465		return rt_val;
466	}
467
468	if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
469		rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
470					   gw_resp.ip_addr.addr);
471		if (rt_val) {
472			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
473				    "BG_%d : Failed to clear Gateway Addr Set\n");
474			return rt_val;
475		}
476	}
477
478	rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
479	if (rt_val)
480		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
481			    "BG_%d : Failed to Set Gateway Addr\n");
482
483	return rt_val;
484}
485
486int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
487		      struct be_cmd_get_def_gateway_resp *resp)
488{
489	struct be_cmd_get_def_gateway_req *req;
490	struct be_dma_mem nonemb_cmd;
491	int rc;
492
493	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
494			OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
495			sizeof(*resp));
496	if (rc)
497		return rc;
498
499	req = nonemb_cmd.va;
500	req->ip_type = ip_type;
501
502	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
503				     resp, sizeof(*resp));
504}
505
506static int
507beiscsi_if_clr_ip(struct beiscsi_hba *phba,
508		  struct be_cmd_get_if_info_resp *if_info)
509{
510	struct be_cmd_set_ip_addr_req *req;
511	struct be_dma_mem nonemb_cmd;
512	int rc;
513
514	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
515			OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
516			sizeof(*req));
517	if (rc)
518		return rc;
519
520	req = nonemb_cmd.va;
521	req->ip_params.record_entry_count = 1;
522	req->ip_params.ip_record.action = IP_ACTION_DEL;
523	req->ip_params.ip_record.interface_hndl =
524		phba->interface_handle;
525	req->ip_params.ip_record.ip_addr.size_of_structure =
526		sizeof(struct be_ip_addr_subnet_format);
527	req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
528	memcpy(req->ip_params.ip_record.ip_addr.addr,
529	       if_info->ip_addr.addr,
530	       sizeof(if_info->ip_addr.addr));
531	memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
532	       if_info->ip_addr.subnet_mask,
533	       sizeof(if_info->ip_addr.subnet_mask));
534	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
535	if (rc < 0 || req->ip_params.ip_record.status) {
536		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
537			    "BG_%d : failed to clear IP: rc %d status %d\n",
538			    rc, req->ip_params.ip_record.status);
539	}
540	return rc;
541}
542
543static int
544beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
545		  u8 *subnet, u32 ip_type)
546{
547	struct be_cmd_set_ip_addr_req *req;
548	struct be_dma_mem nonemb_cmd;
549	uint32_t ip_len;
550	int rc;
551
552	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
553			OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
554			sizeof(*req));
555	if (rc)
556		return rc;
557
558	req = nonemb_cmd.va;
559	req->ip_params.record_entry_count = 1;
560	req->ip_params.ip_record.action = IP_ACTION_ADD;
561	req->ip_params.ip_record.interface_hndl =
562		phba->interface_handle;
563	req->ip_params.ip_record.ip_addr.size_of_structure =
564		sizeof(struct be_ip_addr_subnet_format);
565	req->ip_params.ip_record.ip_addr.ip_type = ip_type;
566	ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
567	memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
568	if (subnet)
569		memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
570		       subnet, ip_len);
571
572	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
573	/**
574	 * In some cases, host needs to look into individual record status
575	 * even though FW reported success for that IOCTL.
576	 */
577	if (rc < 0 || req->ip_params.ip_record.status) {
578		__beiscsi_log(phba, KERN_ERR,
579			    "BG_%d : failed to set IP: rc %d status %d\n",
580			    rc, req->ip_params.ip_record.status);
581		if (req->ip_params.ip_record.status)
582			rc = -EINVAL;
583	}
584	return rc;
585}
586
587int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
588			 u8 *ip, u8 *subnet)
589{
590	struct be_cmd_get_if_info_resp *if_info;
591	struct be_cmd_rel_dhcp_req *reldhcp;
592	struct be_dma_mem nonemb_cmd;
593	int rc;
594
595	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
596	if (rc)
597		return rc;
598
599	if (if_info->dhcp_state) {
600		rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
601				CMD_SUBSYSTEM_ISCSI,
602				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
603				sizeof(*reldhcp));
604		if (rc)
605			goto exit;
606
607		reldhcp = nonemb_cmd.va;
608		reldhcp->interface_hndl = phba->interface_handle;
609		reldhcp->ip_type = ip_type;
610		rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
611		if (rc < 0) {
612			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
613				    "BG_%d : failed to release existing DHCP: %d\n",
614				    rc);
615			goto exit;
616		}
617	}
618
619	/* first delete any IP set */
620	if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
621		rc = beiscsi_if_clr_ip(phba, if_info);
622		if (rc)
623			goto exit;
624	}
625
626	/* if ip == NULL then this is called just to release DHCP IP */
627	if (ip)
628		rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
629exit:
630	kfree(if_info);
631	return rc;
632}
633
634int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
635{
636	struct be_cmd_get_def_gateway_resp gw_resp;
637	struct be_cmd_get_if_info_resp *if_info;
638	struct be_cmd_set_dhcp_req *dhcpreq;
639	struct be_dma_mem nonemb_cmd;
640	u8 *gw;
641	int rc;
642
643	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
644	if (rc)
645		return rc;
646
647	if (if_info->dhcp_state) {
648		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
649				"BG_%d : DHCP Already Enabled\n");
650		goto exit;
651	}
652
653	/* first delete any IP set */
654	if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
655		rc = beiscsi_if_clr_ip(phba, if_info);
656		if (rc)
657			goto exit;
658	}
659
660	/* delete gateway settings if mode change is to DHCP */
661	memset(&gw_resp, 0, sizeof(gw_resp));
662	/* use ip_type provided in if_info */
663	rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
664	if (rc) {
665		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
666			    "BG_%d : Failed to Get Gateway Addr\n");
667		goto exit;
668	}
669	gw = (u8 *)&gw_resp.ip_addr.addr;
670	if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
671		rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
672				       if_info->ip_addr.ip_type, gw);
673		if (rc) {
674			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
675				    "BG_%d : Failed to clear Gateway Addr Set\n");
676			goto exit;
677		}
678	}
679
680	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
681			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
682			sizeof(*dhcpreq));
683	if (rc)
684		goto exit;
685
686	dhcpreq = nonemb_cmd.va;
687	dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
688	dhcpreq->retry_count = 1;
689	dhcpreq->interface_hndl = phba->interface_handle;
690	dhcpreq->ip_type = ip_type;
691	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
692
693exit:
694	kfree(if_info);
695	return rc;
696}
697
698/**
699 * beiscsi_if_set_vlan()- Issue and wait for CMD completion
700 * @phba: device private structure instance
701 * @vlan_tag: VLAN tag
702 *
703 * Issue the MBX Cmd and wait for the completion of the
704 * command.
705 *
706 * returns
707 *	Success: 0
708 *	Failure: Non-Xero Value
709 **/
710int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
711{
712	int rc;
713	unsigned int tag;
714
715	tag = be_cmd_set_vlan(phba, vlan_tag);
716	if (!tag) {
717		beiscsi_log(phba, KERN_ERR,
718			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
719			    "BG_%d : VLAN Setting Failed\n");
720		return -EBUSY;
721	}
722
723	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
724	if (rc) {
725		beiscsi_log(phba, KERN_ERR,
726			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
727			    "BS_%d : VLAN MBX Cmd Failed\n");
728		return rc;
729	}
730	return rc;
731}
732
733
734int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
735			struct be_cmd_get_if_info_resp **if_info)
736{
737	struct be_cmd_get_if_info_req *req;
738	struct be_dma_mem nonemb_cmd;
739	uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
740	int rc;
741
742	rc = beiscsi_if_get_handle(phba);
743	if (rc)
744		return rc;
745
746	do {
747		rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
748				CMD_SUBSYSTEM_ISCSI,
749				OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
750				ioctl_size);
751		if (rc)
752			return rc;
753
754		req = nonemb_cmd.va;
755		req->interface_hndl = phba->interface_handle;
756		req->ip_type = ip_type;
757
758		/* Allocate memory for if_info */
759		*if_info = kzalloc(ioctl_size, GFP_KERNEL);
760		if (!*if_info) {
761			beiscsi_log(phba, KERN_ERR,
762				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
763				    "BG_%d : Memory Allocation Failure\n");
764
765				/* Free the DMA memory for the IOCTL issuing */
766				dma_free_coherent(&phba->ctrl.pdev->dev,
767						    nonemb_cmd.size,
768						    nonemb_cmd.va,
769						    nonemb_cmd.dma);
770				return -ENOMEM;
771		}
772
773		rc =  beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
774					    ioctl_size);
775
776		/* Check if the error is because of Insufficent_Buffer */
777		if (rc == -EAGAIN) {
778
779			/* Get the new memory size */
780			ioctl_size = ((struct be_cmd_resp_hdr *)
781				      nonemb_cmd.va)->actual_resp_len;
782			ioctl_size += sizeof(struct be_cmd_req_hdr);
783
784			/* Free the previous allocated DMA memory */
785			dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
786					    nonemb_cmd.va,
787					    nonemb_cmd.dma);
788
789			/* Free the virtual memory */
790			kfree(*if_info);
791		} else
792			break;
793	} while (true);
794	return rc;
795}
796
797int mgmt_get_nic_conf(struct beiscsi_hba *phba,
798		      struct be_cmd_get_nic_conf_resp *nic)
799{
800	struct be_dma_mem nonemb_cmd;
801	int rc;
802
803	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
804			OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
805			sizeof(*nic));
806	if (rc)
807		return rc;
808
809	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
810				     nic, sizeof(*nic));
811}
812
813static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
814				       unsigned int tag)
815{
816	struct be_cmd_get_boot_target_resp *boot_resp;
817	struct be_cmd_resp_logout_fw_sess *logo_resp;
818	struct be_cmd_get_session_resp *sess_resp;
819	struct be_mcc_wrb *wrb;
820	struct boot_struct *bs;
821	int boot_work, status;
822
823	if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
824		__beiscsi_log(phba, KERN_ERR,
825			      "BG_%d : %s no boot work %lx\n",
826			      __func__, phba->state);
827		return;
828	}
829
830	if (phba->boot_struct.tag != tag) {
831		__beiscsi_log(phba, KERN_ERR,
832			      "BG_%d : %s tag mismatch %d:%d\n",
833			      __func__, tag, phba->boot_struct.tag);
834		return;
835	}
836	bs = &phba->boot_struct;
837	boot_work = 1;
838	status = 0;
839	switch (bs->action) {
840	case BEISCSI_BOOT_REOPEN_SESS:
841		status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
842		if (!status)
843			bs->action = BEISCSI_BOOT_GET_SHANDLE;
844		else
845			bs->retry--;
846		break;
847	case BEISCSI_BOOT_GET_SHANDLE:
848		status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
849		if (!status) {
850			boot_resp = embedded_payload(wrb);
851			bs->s_handle = boot_resp->boot_session_handle;
852		}
853		if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
854			bs->action = BEISCSI_BOOT_REOPEN_SESS;
855			bs->retry--;
856		} else {
857			bs->action = BEISCSI_BOOT_GET_SINFO;
858		}
859		break;
860	case BEISCSI_BOOT_GET_SINFO:
861		status = __beiscsi_mcc_compl_status(phba, tag, NULL,
862						    &bs->nonemb_cmd);
863		if (!status) {
864			sess_resp = bs->nonemb_cmd.va;
865			memcpy(&bs->boot_sess, &sess_resp->session_info,
866			       sizeof(struct mgmt_session_info));
867			bs->action = BEISCSI_BOOT_LOGOUT_SESS;
868		} else {
869			__beiscsi_log(phba, KERN_ERR,
870				      "BG_%d : get boot session info error : 0x%x\n",
871				      status);
872			boot_work = 0;
873		}
874		dma_free_coherent(&phba->ctrl.pdev->dev, bs->nonemb_cmd.size,
875				    bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
876		bs->nonemb_cmd.va = NULL;
877		break;
878	case BEISCSI_BOOT_LOGOUT_SESS:
879		status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
880		if (!status) {
881			logo_resp = embedded_payload(wrb);
882			if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
883				__beiscsi_log(phba, KERN_ERR,
884					      "BG_%d : FW boot session logout error : 0x%x\n",
885					      logo_resp->session_status);
886			}
887		}
888		/* continue to create boot_kset even if logout failed? */
889		bs->action = BEISCSI_BOOT_CREATE_KSET;
890		break;
891	default:
892		break;
893	}
894
895	/* clear the tag so no other completion matches this tag */
896	bs->tag = 0;
897	if (!bs->retry) {
898		boot_work = 0;
899		__beiscsi_log(phba, KERN_ERR,
900			      "BG_%d : failed to setup boot target: status %d action %d\n",
901			      status, bs->action);
902	}
903	if (!boot_work) {
904		/* wait for next event to start boot_work */
905		clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
906		return;
907	}
908	schedule_work(&phba->boot_work);
909}
910
911/**
912 * beiscsi_boot_logout_sess()- Logout from boot FW session
913 * @phba: Device priv structure instance
914 *
915 * return
916 *	the TAG used for MBOX Command
917 *
918 */
919unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
920{
921	struct be_ctrl_info *ctrl = &phba->ctrl;
922	struct be_mcc_wrb *wrb;
923	struct be_cmd_req_logout_fw_sess *req;
924	unsigned int tag;
925
926	mutex_lock(&ctrl->mbox_lock);
927	wrb = alloc_mcc_wrb(phba, &tag);
928	if (!wrb) {
929		mutex_unlock(&ctrl->mbox_lock);
930		return 0;
931	}
932
933	req = embedded_payload(wrb);
934	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
935	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
936			   OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
937			   sizeof(struct be_cmd_req_logout_fw_sess));
938	/* Use the session handle copied into boot_sess */
939	req->session_handle = phba->boot_struct.boot_sess.session_handle;
940
941	phba->boot_struct.tag = tag;
942	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
943	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
944
945	be_mcc_notify(phba, tag);
946	mutex_unlock(&ctrl->mbox_lock);
947
948	return tag;
949}
950/**
951 * beiscsi_boot_reopen_sess()- Reopen boot session
952 * @phba: Device priv structure instance
953 *
954 * return
955 *	the TAG used for MBOX Command
956 *
957 **/
958unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
959{
960	struct be_ctrl_info *ctrl = &phba->ctrl;
961	struct be_mcc_wrb *wrb;
962	struct be_cmd_reopen_session_req *req;
963	unsigned int tag;
964
965	mutex_lock(&ctrl->mbox_lock);
966	wrb = alloc_mcc_wrb(phba, &tag);
967	if (!wrb) {
968		mutex_unlock(&ctrl->mbox_lock);
969		return 0;
970	}
971
972	req = embedded_payload(wrb);
973	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
974	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
975			   OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
976			   sizeof(struct be_cmd_reopen_session_resp));
977	req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
978	req->session_handle = BE_BOOT_INVALID_SHANDLE;
979
980	phba->boot_struct.tag = tag;
981	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
982	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
983
984	be_mcc_notify(phba, tag);
985	mutex_unlock(&ctrl->mbox_lock);
986	return tag;
987}
988
989
990/**
991 * beiscsi_boot_get_sinfo()- Get boot session info
992 * @phba: device priv structure instance
993 *
994 * Fetches the boot_struct.s_handle info from FW.
995 * return
996 *	the TAG used for MBOX Command
997 *
998 **/
999unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
1000{
1001	struct be_ctrl_info *ctrl = &phba->ctrl;
1002	struct be_cmd_get_session_req *req;
1003	struct be_dma_mem *nonemb_cmd;
1004	struct be_mcc_wrb *wrb;
1005	struct be_sge *sge;
1006	unsigned int tag;
1007
1008	mutex_lock(&ctrl->mbox_lock);
1009	wrb = alloc_mcc_wrb(phba, &tag);
1010	if (!wrb) {
1011		mutex_unlock(&ctrl->mbox_lock);
1012		return 0;
1013	}
1014
1015	nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1016	nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
1017	nonemb_cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1018					      nonemb_cmd->size,
1019					      &nonemb_cmd->dma,
1020					      GFP_KERNEL);
1021	if (!nonemb_cmd->va) {
1022		mutex_unlock(&ctrl->mbox_lock);
1023		return 0;
1024	}
1025
1026	req = nonemb_cmd->va;
1027	memset(req, 0, sizeof(*req));
1028	sge = nonembedded_sgl(wrb);
1029	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1030	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1031			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1032			   sizeof(struct be_cmd_get_session_resp));
1033	req->session_handle = phba->boot_struct.s_handle;
1034	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1035	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1036	sge->len = cpu_to_le32(nonemb_cmd->size);
1037
1038	phba->boot_struct.tag = tag;
1039	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1040	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1041
1042	be_mcc_notify(phba, tag);
1043	mutex_unlock(&ctrl->mbox_lock);
1044	return tag;
1045}
1046
1047unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1048{
1049	struct be_ctrl_info *ctrl = &phba->ctrl;
1050	struct be_mcc_wrb *wrb;
1051	struct be_cmd_get_boot_target_req *req;
1052	unsigned int tag;
1053
1054	mutex_lock(&ctrl->mbox_lock);
1055	wrb = alloc_mcc_wrb(phba, &tag);
1056	if (!wrb) {
1057		mutex_unlock(&ctrl->mbox_lock);
1058		return 0;
1059	}
1060
1061	req = embedded_payload(wrb);
1062	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1063	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1064			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1065			   sizeof(struct be_cmd_get_boot_target_resp));
1066
1067	if (async) {
1068		phba->boot_struct.tag = tag;
1069		set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1070		ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1071	}
1072
1073	be_mcc_notify(phba, tag);
1074	mutex_unlock(&ctrl->mbox_lock);
1075	return tag;
1076}
1077
1078/**
1079 * beiscsi_boot_get_shandle()- Get boot session handle
1080 * @phba: device priv structure instance
1081 * @s_handle: session handle returned for boot session.
1082 *
1083 * return
1084 *	Success: 1
1085 *	Failure: negative
1086 *
1087 **/
1088int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1089{
1090	struct be_cmd_get_boot_target_resp *boot_resp;
1091	struct be_mcc_wrb *wrb;
1092	unsigned int tag;
1093	int rc;
1094
1095	*s_handle = BE_BOOT_INVALID_SHANDLE;
1096	/* get configured boot session count and handle */
1097	tag = __beiscsi_boot_get_shandle(phba, 0);
1098	if (!tag) {
1099		beiscsi_log(phba, KERN_ERR,
1100			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1101			    "BG_%d : Getting Boot Target Info Failed\n");
1102		return -EAGAIN;
1103	}
1104
1105	rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1106	if (rc) {
1107		beiscsi_log(phba, KERN_ERR,
1108			    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1109			    "BG_%d : MBX CMD get_boot_target Failed\n");
1110		return -EBUSY;
1111	}
1112
1113	boot_resp = embedded_payload(wrb);
1114	/* check if there are any boot targets configured */
1115	if (!boot_resp->boot_session_count) {
1116		__beiscsi_log(phba, KERN_INFO,
1117			      "BG_%d : No boot targets configured\n");
1118		return -ENXIO;
1119	}
1120
1121	/* only if FW has logged in to the boot target, s_handle is valid */
1122	*s_handle = boot_resp->boot_session_handle;
1123	return 1;
1124}
1125
1126/**
1127 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1128 * @dev: ptr to device not used.
1129 * @attr: device attribute, not used.
1130 * @buf: contains formatted text driver name and version
1131 *
1132 * return
1133 * size of the formatted string
1134 **/
1135ssize_t
1136beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1137		       char *buf)
1138{
1139	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1140}
1141
1142/**
1143 * beiscsi_fw_ver_disp()- Display Firmware Version
1144 * @dev: ptr to device not used.
1145 * @attr: device attribute, not used.
1146 * @buf: contains formatted text Firmware version
1147 *
1148 * return
1149 * size of the formatted string
1150 **/
1151ssize_t
1152beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1153		     char *buf)
1154{
1155	struct Scsi_Host *shost = class_to_shost(dev);
1156	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1157
1158	return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1159}
1160
1161/**
1162 * beiscsi_active_session_disp()- Display Sessions Active
1163 * @dev: ptr to device not used.
1164 * @attr: device attribute, not used.
1165 * @buf: contains formatted text Session Count
1166 *
1167 * return
1168 * size of the formatted string
1169 **/
1170ssize_t
1171beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1172			 char *buf)
1173{
1174	struct Scsi_Host *shost = class_to_shost(dev);
1175	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1176	uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1177
1178	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1179		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1180			avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1181			total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1182			len += scnprintf(buf+len, PAGE_SIZE - len,
1183					 "ULP%d : %d\n", ulp_num,
1184					 (total_cids - avlbl_cids));
1185		} else
1186			len += scnprintf(buf+len, PAGE_SIZE - len,
1187					 "ULP%d : %d\n", ulp_num, 0);
1188	}
1189
1190	return len;
1191}
1192
1193/**
1194 * beiscsi_free_session_disp()- Display Avaliable Session
1195 * @dev: ptr to device not used.
1196 * @attr: device attribute, not used.
1197 * @buf: contains formatted text Session Count
1198 *
1199 * return
1200 * size of the formatted string
1201 **/
1202ssize_t
1203beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1204		       char *buf)
1205{
1206	struct Scsi_Host *shost = class_to_shost(dev);
1207	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1208	uint16_t ulp_num, len = 0;
1209
1210	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1211		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1212			len += scnprintf(buf+len, PAGE_SIZE - len,
1213					 "ULP%d : %d\n", ulp_num,
1214					 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1215		else
1216			len += scnprintf(buf+len, PAGE_SIZE - len,
1217					 "ULP%d : %d\n", ulp_num, 0);
1218	}
1219
1220	return len;
1221}
1222
1223/**
1224 * beiscsi_adap_family_disp()- Display adapter family.
1225 * @dev: ptr to device to get priv structure
1226 * @attr: device attribute, not used.
1227 * @buf: contains formatted text driver name and version
1228 *
1229 * return
1230 * size of the formatted string
1231 **/
1232ssize_t
1233beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1234			  char *buf)
1235{
1236	uint16_t dev_id = 0;
1237	struct Scsi_Host *shost = class_to_shost(dev);
1238	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1239
1240	dev_id = phba->pcidev->device;
1241	switch (dev_id) {
1242	case BE_DEVICE_ID1:
1243	case OC_DEVICE_ID1:
1244	case OC_DEVICE_ID2:
1245		return snprintf(buf, PAGE_SIZE,
1246				"Obsolete/Unsupported BE2 Adapter Family\n");
1247		break;
1248	case BE_DEVICE_ID2:
1249	case OC_DEVICE_ID3:
1250		return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1251		break;
1252	case OC_SKH_ID1:
1253		return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1254		break;
1255	default:
1256		return snprintf(buf, PAGE_SIZE,
1257				"Unknown Adapter Family: 0x%x\n", dev_id);
1258		break;
1259	}
1260}
1261
1262/**
1263 * beiscsi_phys_port()- Display Physical Port Identifier
1264 * @dev: ptr to device not used.
1265 * @attr: device attribute, not used.
1266 * @buf: contains formatted text port identifier
1267 *
1268 * return
1269 * size of the formatted string
1270 **/
1271ssize_t
1272beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1273			 char *buf)
1274{
1275	struct Scsi_Host *shost = class_to_shost(dev);
1276	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1277
1278	return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
1279			phba->fw_config.phys_port);
1280}
1281
1282void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1283			     struct wrb_handle *pwrb_handle,
1284			     struct be_mem_descriptor *mem_descr,
1285			     struct hwi_wrb_context *pwrb_context)
1286{
1287	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1288
1289	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1290		      max_send_data_segment_length, pwrb,
1291		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1292		      max_send_data_segment_length) / 32]);
1293	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1294		      BE_TGT_CTX_UPDT_CMD);
1295	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1296		      first_burst_length,
1297		      pwrb,
1298		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1299		      first_burst_length) / 32]);
1300	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1301		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1302		      erl) / 32] & OFFLD_PARAMS_ERL));
1303	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1304		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1305		       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1306	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1307		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1308		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1309	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1310		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1311		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1312	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1313		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1314		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1315	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1316		      pwrb,
1317		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1318		      exp_statsn) / 32] + 1));
1319	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1320		      pwrb, pwrb_handle->wrb_index);
1321
1322	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1323		      max_burst_length, pwrb, params->dw[offsetof
1324		      (struct amap_beiscsi_offload_params,
1325		      max_burst_length) / 32]);
1326
1327	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1328		      pwrb, pwrb_handle->wrb_index);
1329	if (pwrb_context->plast_wrb)
1330		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1331			      ptr2nextwrb,
1332			      pwrb_context->plast_wrb,
1333			      pwrb_handle->wrb_index);
1334	pwrb_context->plast_wrb = pwrb;
1335
1336	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1337		      session_state, pwrb, 0);
1338	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1339		      pwrb, 1);
1340	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1341		      pwrb, 0);
1342	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1343		      0);
1344
1345	mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1346	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1347		      pad_buffer_addr_hi, pwrb,
1348		      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1349	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1350		      pad_buffer_addr_lo, pwrb,
1351		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1352}
1353
1354void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1355			     struct wrb_handle *pwrb_handle,
1356			     struct hwi_wrb_context *pwrb_context)
1357{
1358	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1359
1360	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1361		      max_burst_length, pwrb, params->dw[offsetof
1362		      (struct amap_beiscsi_offload_params,
1363		      max_burst_length) / 32]);
1364	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1365		      type, pwrb,
1366		      BE_TGT_CTX_UPDT_CMD);
1367	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1368		      ptr2nextwrb,
1369		      pwrb, pwrb_handle->wrb_index);
1370	if (pwrb_context->plast_wrb)
1371		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1372			      ptr2nextwrb,
1373			      pwrb_context->plast_wrb,
1374			      pwrb_handle->wrb_index);
1375	pwrb_context->plast_wrb = pwrb;
1376
1377	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1378		      pwrb, pwrb_handle->wrb_index);
1379	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1380		      max_send_data_segment_length, pwrb,
1381		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1382		      max_send_data_segment_length) / 32]);
1383	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1384		      first_burst_length, pwrb,
1385		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1386		      first_burst_length) / 32]);
1387	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1388		      max_recv_dataseg_len, pwrb,
1389		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1390		      max_recv_data_segment_length) / 32]);
1391	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1392		      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1393	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1394		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1395		      erl) / 32] & OFFLD_PARAMS_ERL));
1396	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1397		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1398		      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1399	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1400		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1401		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1402	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1403		      ir2t, pwrb,
1404		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1405		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1406	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1407		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1408		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1409	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1410		      data_seq_inorder,
1411		      pwrb,
1412		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1413		      data_seq_inorder) / 32] &
1414		      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1415	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1416		      pdu_seq_inorder,
1417		      pwrb,
1418		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1419		      pdu_seq_inorder) / 32] &
1420		      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1421	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1422		      pwrb,
1423		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1424		      max_r2t) / 32] &
1425		      OFFLD_PARAMS_MAX_R2T) >> 8);
1426	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1427		      pwrb,
1428		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1429		      exp_statsn) / 32] + 1));
1430}
1431
1432unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
1433				    struct beiscsi_endpoint *beiscsi_ep)
1434{
1435	struct be_invalidate_connection_params_in *req;
1436	struct be_ctrl_info *ctrl = &phba->ctrl;
1437	struct be_mcc_wrb *wrb;
1438	unsigned int tag = 0;
1439
1440	mutex_lock(&ctrl->mbox_lock);
1441	wrb = alloc_mcc_wrb(phba, &tag);
1442	if (!wrb) {
1443		mutex_unlock(&ctrl->mbox_lock);
1444		return 0;
1445	}
1446
1447	req = embedded_payload(wrb);
1448	be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
1449			   true, 0);
1450	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1451			   OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
1452			   sizeof(*req));
1453	req->session_handle = beiscsi_ep->fw_handle;
1454	req->cid = beiscsi_ep->ep_cid;
1455	if (beiscsi_ep->conn)
1456		req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
1457	else
1458		req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
1459	/**
1460	 * 0 - non-persistent targets
1461	 * 1 - save session info on flash
1462	 */
1463	req->save_cfg = 0;
1464	be_mcc_notify(phba, tag);
1465	mutex_unlock(&ctrl->mbox_lock);
1466	return tag;
1467}
1468
1469unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
1470				struct beiscsi_endpoint *beiscsi_ep)
1471{
1472	struct be_ctrl_info *ctrl = &phba->ctrl;
1473	struct be_mcc_wrb *wrb;
1474	struct be_tcp_upload_params_in *req;
1475	unsigned int tag;
1476
1477	mutex_lock(&ctrl->mbox_lock);
1478	wrb = alloc_mcc_wrb(phba, &tag);
1479	if (!wrb) {
1480		mutex_unlock(&ctrl->mbox_lock);
1481		return 0;
1482	}
1483
1484	req = embedded_payload(wrb);
1485	be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
1486	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
1487			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
1488	req->id = beiscsi_ep->ep_cid;
1489	if (beiscsi_ep->conn)
1490		req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
1491	else
1492		req->upload_type = BE_UPLOAD_TYPE_ABORT;
1493	be_mcc_notify(phba, tag);
1494	mutex_unlock(&ctrl->mbox_lock);
1495	return tag;
1496}
1497
1498int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
1499				 struct invldt_cmd_tbl *inv_tbl,
1500				 unsigned int nents)
1501{
1502	struct be_ctrl_info *ctrl = &phba->ctrl;
1503	struct invldt_cmds_params_in *req;
1504	struct be_dma_mem nonemb_cmd;
1505	struct be_mcc_wrb *wrb;
1506	unsigned int i, tag;
1507	struct be_sge *sge;
1508	int rc;
1509
1510	if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
1511		return -EINVAL;
1512
1513	nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1514	nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1515					   nonemb_cmd.size, &nonemb_cmd.dma,
1516					   GFP_KERNEL);
1517	if (!nonemb_cmd.va) {
1518		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
1519			    "BM_%d : invldt_cmds_params alloc failed\n");
1520		return -ENOMEM;
1521	}
1522
1523	mutex_lock(&ctrl->mbox_lock);
1524	wrb = alloc_mcc_wrb(phba, &tag);
1525	if (!wrb) {
1526		mutex_unlock(&ctrl->mbox_lock);
1527		dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1528				    nonemb_cmd.va, nonemb_cmd.dma);
1529		return -ENOMEM;
1530	}
1531
1532	req = nonemb_cmd.va;
1533	be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
1534	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1535			OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
1536			sizeof(*req));
1537	req->ref_handle = 0;
1538	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
1539	for (i = 0; i < nents; i++) {
1540		req->table[i].icd = inv_tbl[i].icd;
1541		req->table[i].cid = inv_tbl[i].cid;
1542		req->icd_count++;
1543	}
1544	sge = nonembedded_sgl(wrb);
1545	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1546	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
1547	sge->len = cpu_to_le32(nonemb_cmd.size);
1548
1549	be_mcc_notify(phba, tag);
1550	mutex_unlock(&ctrl->mbox_lock);
1551
1552	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1553	if (rc != -EBUSY)
1554		dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1555				    nonemb_cmd.va, nonemb_cmd.dma);
1556	return rc;
1557}
1558