1 /*
2  *    driver for Microsemi PQI-based storage controllers
3  *    Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
4  *    Copyright (c) 2016-2018 Microsemi Corporation
5  *    Copyright (c) 2016 PMC-Sierra, Inc.
6  *
7  *    This program is free software; you can redistribute it and/or modify
8  *    it under the terms of the GNU General Public License as published by
9  *    the Free Software Foundation; version 2 of the License.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14  *    NON INFRINGEMENT.  See the GNU General Public License for more details.
15  *
16  *    Questions/Comments/Bugfixes to storagedev@microchip.com
17  *
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/bsg-lib.h>
22 #include <scsi/scsi_host.h>
23 #include <scsi/scsi_cmnd.h>
24 #include <scsi/scsi_transport_sas.h>
25 #include <asm/unaligned.h>
26 #include "smartpqi.h"
27 
28 static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port)
29 {
30 	struct pqi_sas_phy *pqi_sas_phy;
31 	struct sas_phy *phy;
32 
33 	pqi_sas_phy = kzalloc(sizeof(*pqi_sas_phy), GFP_KERNEL);
34 	if (!pqi_sas_phy)
35 		return NULL;
36 
37 	phy = sas_phy_alloc(pqi_sas_port->parent_node->parent_dev,
38 		pqi_sas_port->next_phy_index);
39 	if (!phy) {
40 		kfree(pqi_sas_phy);
41 		return NULL;
42 	}
43 
44 	pqi_sas_port->next_phy_index++;
45 	pqi_sas_phy->phy = phy;
46 	pqi_sas_phy->parent_port = pqi_sas_port;
47 
48 	return pqi_sas_phy;
49 }
50 
51 static void pqi_free_sas_phy(struct pqi_sas_phy *pqi_sas_phy)
52 {
53 	struct sas_phy *phy = pqi_sas_phy->phy;
54 
55 	sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy);
56 	sas_phy_free(phy);
57 	if (pqi_sas_phy->added_to_port)
58 		list_del(&pqi_sas_phy->phy_list_entry);
59 	kfree(pqi_sas_phy);
60 }
61 
62 static int pqi_sas_port_add_phy(struct pqi_sas_phy *pqi_sas_phy)
63 {
64 	int rc;
65 	struct pqi_sas_port *pqi_sas_port;
66 	struct sas_phy *phy;
67 	struct sas_identify *identify;
68 
69 	pqi_sas_port = pqi_sas_phy->parent_port;
70 	phy = pqi_sas_phy->phy;
71 
72 	identify = &phy->identify;
73 	memset(identify, 0, sizeof(*identify));
74 	identify->sas_address = pqi_sas_port->sas_address;
75 	identify->device_type = SAS_END_DEVICE;
76 	identify->initiator_port_protocols = SAS_PROTOCOL_STP;
77 	identify->target_port_protocols = SAS_PROTOCOL_STP;
78 	phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
79 	phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
80 	phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN;
81 	phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN;
82 	phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
83 
84 	rc = sas_phy_add(pqi_sas_phy->phy);
85 	if (rc)
86 		return rc;
87 
88 	sas_port_add_phy(pqi_sas_port->port, pqi_sas_phy->phy);
89 	list_add_tail(&pqi_sas_phy->phy_list_entry,
90 		&pqi_sas_port->phy_list_head);
91 	pqi_sas_phy->added_to_port = true;
92 
93 	return 0;
94 }
95 
96 static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port,
97 	struct sas_rphy *rphy)
98 {
99 	struct sas_identify *identify;
100 
101 	identify = &rphy->identify;
102 	identify->sas_address = pqi_sas_port->sas_address;
103 
104 	if (pqi_sas_port->device &&
105 		pqi_sas_port->device->is_expander_smp_device) {
106 		identify->initiator_port_protocols = SAS_PROTOCOL_SMP;
107 		identify->target_port_protocols = SAS_PROTOCOL_SMP;
108 	} else {
109 		identify->initiator_port_protocols = SAS_PROTOCOL_STP;
110 		identify->target_port_protocols = SAS_PROTOCOL_STP;
111 	}
112 
113 	return sas_rphy_add(rphy);
114 }
115 
116 static struct sas_rphy *pqi_sas_rphy_alloc(struct pqi_sas_port *pqi_sas_port)
117 {
118 	if (pqi_sas_port->device &&
119 		pqi_sas_port->device->is_expander_smp_device)
120 		return sas_expander_alloc(pqi_sas_port->port,
121 				SAS_FANOUT_EXPANDER_DEVICE);
122 
123 	return sas_end_device_alloc(pqi_sas_port->port);
124 }
125 
126 static struct pqi_sas_port *pqi_alloc_sas_port(
127 	struct pqi_sas_node *pqi_sas_node, u64 sas_address,
128 	struct pqi_scsi_dev *device)
129 {
130 	int rc;
131 	struct pqi_sas_port *pqi_sas_port;
132 	struct sas_port *port;
133 
134 	pqi_sas_port = kzalloc(sizeof(*pqi_sas_port), GFP_KERNEL);
135 	if (!pqi_sas_port)
136 		return NULL;
137 
138 	INIT_LIST_HEAD(&pqi_sas_port->phy_list_head);
139 	pqi_sas_port->parent_node = pqi_sas_node;
140 
141 	port = sas_port_alloc_num(pqi_sas_node->parent_dev);
142 	if (!port)
143 		goto free_pqi_port;
144 
145 	rc = sas_port_add(port);
146 	if (rc)
147 		goto free_sas_port;
148 
149 	pqi_sas_port->port = port;
150 	pqi_sas_port->sas_address = sas_address;
151 	pqi_sas_port->device = device;
152 	list_add_tail(&pqi_sas_port->port_list_entry,
153 		&pqi_sas_node->port_list_head);
154 
155 	return pqi_sas_port;
156 
157 free_sas_port:
158 	sas_port_free(port);
159 free_pqi_port:
160 	kfree(pqi_sas_port);
161 
162 	return NULL;
163 }
164 
165 static void pqi_free_sas_port(struct pqi_sas_port *pqi_sas_port)
166 {
167 	struct pqi_sas_phy *pqi_sas_phy;
168 	struct pqi_sas_phy *next;
169 
170 	list_for_each_entry_safe(pqi_sas_phy, next,
171 		&pqi_sas_port->phy_list_head, phy_list_entry)
172 		pqi_free_sas_phy(pqi_sas_phy);
173 
174 	sas_port_delete(pqi_sas_port->port);
175 	list_del(&pqi_sas_port->port_list_entry);
176 	kfree(pqi_sas_port);
177 }
178 
179 static struct pqi_sas_node *pqi_alloc_sas_node(struct device *parent_dev)
180 {
181 	struct pqi_sas_node *pqi_sas_node;
182 
183 	pqi_sas_node = kzalloc(sizeof(*pqi_sas_node), GFP_KERNEL);
184 	if (pqi_sas_node) {
185 		pqi_sas_node->parent_dev = parent_dev;
186 		INIT_LIST_HEAD(&pqi_sas_node->port_list_head);
187 	}
188 
189 	return pqi_sas_node;
190 }
191 
192 static void pqi_free_sas_node(struct pqi_sas_node *pqi_sas_node)
193 {
194 	struct pqi_sas_port *pqi_sas_port;
195 	struct pqi_sas_port *next;
196 
197 	if (!pqi_sas_node)
198 		return;
199 
200 	list_for_each_entry_safe(pqi_sas_port, next,
201 		&pqi_sas_node->port_list_head, port_list_entry)
202 		pqi_free_sas_port(pqi_sas_port);
203 
204 	kfree(pqi_sas_node);
205 }
206 
207 struct pqi_scsi_dev *pqi_find_device_by_sas_rphy(
208 	struct pqi_ctrl_info *ctrl_info, struct sas_rphy *rphy)
209 {
210 	struct pqi_scsi_dev *device;
211 
212 	list_for_each_entry(device, &ctrl_info->scsi_device_list,
213 		scsi_device_list_entry) {
214 		if (!device->sas_port)
215 			continue;
216 		if (device->sas_port->rphy == rphy)
217 			return device;
218 	}
219 
220 	return NULL;
221 }
222 
223 int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info)
224 {
225 	int rc;
226 	struct device *parent_dev;
227 	struct pqi_sas_node *pqi_sas_node;
228 	struct pqi_sas_port *pqi_sas_port;
229 	struct pqi_sas_phy *pqi_sas_phy;
230 
231 	parent_dev = &shost->shost_dev;
232 
233 	pqi_sas_node = pqi_alloc_sas_node(parent_dev);
234 	if (!pqi_sas_node)
235 		return -ENOMEM;
236 
237 	pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
238 		ctrl_info->sas_address, NULL);
239 	if (!pqi_sas_port) {
240 		rc = -ENODEV;
241 		goto free_sas_node;
242 	}
243 
244 	pqi_sas_phy = pqi_alloc_sas_phy(pqi_sas_port);
245 	if (!pqi_sas_phy) {
246 		rc = -ENODEV;
247 		goto free_sas_port;
248 	}
249 
250 	rc = pqi_sas_port_add_phy(pqi_sas_phy);
251 	if (rc)
252 		goto free_sas_phy;
253 
254 	ctrl_info->sas_host = pqi_sas_node;
255 
256 	return 0;
257 
258 free_sas_phy:
259 	pqi_free_sas_phy(pqi_sas_phy);
260 free_sas_port:
261 	pqi_free_sas_port(pqi_sas_port);
262 free_sas_node:
263 	pqi_free_sas_node(pqi_sas_node);
264 
265 	return rc;
266 }
267 
268 void pqi_delete_sas_host(struct pqi_ctrl_info *ctrl_info)
269 {
270 	pqi_free_sas_node(ctrl_info->sas_host);
271 }
272 
273 int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
274 	struct pqi_scsi_dev *device)
275 {
276 	int rc;
277 	struct pqi_sas_port *pqi_sas_port;
278 	struct sas_rphy *rphy;
279 
280 	pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
281 		device->sas_address, device);
282 	if (!pqi_sas_port)
283 		return -ENOMEM;
284 
285 	rphy = pqi_sas_rphy_alloc(pqi_sas_port);
286 	if (!rphy) {
287 		rc = -ENODEV;
288 		goto free_sas_port;
289 	}
290 
291 	pqi_sas_port->rphy = rphy;
292 	device->sas_port = pqi_sas_port;
293 
294 	rc = pqi_sas_port_add_rphy(pqi_sas_port, rphy);
295 	if (rc)
296 		goto free_sas_port;
297 
298 	return 0;
299 
300 free_sas_port:
301 	pqi_free_sas_port(pqi_sas_port);
302 	device->sas_port = NULL;
303 
304 	return rc;
305 }
306 
307 void pqi_remove_sas_device(struct pqi_scsi_dev *device)
308 {
309 	if (device->sas_port) {
310 		pqi_free_sas_port(device->sas_port);
311 		device->sas_port = NULL;
312 	}
313 }
314 
315 static int pqi_sas_get_linkerrors(struct sas_phy *phy)
316 {
317 	return 0;
318 }
319 
320 static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy,
321 	u64 *identifier)
322 {
323 	return 0;
324 }
325 
326 static int pqi_sas_get_bay_identifier(struct sas_rphy *rphy)
327 {
328 	return -ENXIO;
329 }
330 
331 static int pqi_sas_phy_reset(struct sas_phy *phy, int hard_reset)
332 {
333 	return 0;
334 }
335 
336 static int pqi_sas_phy_enable(struct sas_phy *phy, int enable)
337 {
338 	return 0;
339 }
340 
341 static int pqi_sas_phy_setup(struct sas_phy *phy)
342 {
343 	return 0;
344 }
345 
346 static void pqi_sas_phy_release(struct sas_phy *phy)
347 {
348 }
349 
350 static int pqi_sas_phy_speed(struct sas_phy *phy,
351 	struct sas_phy_linkrates *rates)
352 {
353 	return -EINVAL;
354 }
355 
356 #define CSMI_IOCTL_TIMEOUT	60
357 #define SMP_CRC_FIELD_LENGTH	4
358 
359 static struct bmic_csmi_smp_passthru_buffer *
360 pqi_build_csmi_smp_passthru_buffer(struct sas_rphy *rphy,
361 	struct bsg_job *job)
362 {
363 	struct bmic_csmi_smp_passthru_buffer *smp_buf;
364 	struct bmic_csmi_ioctl_header *ioctl_header;
365 	struct bmic_csmi_smp_passthru *parameters;
366 	u32 req_size;
367 	u32 resp_size;
368 
369 	smp_buf = kzalloc(sizeof(*smp_buf), GFP_KERNEL);
370 	if (!smp_buf)
371 		return NULL;
372 
373 	req_size = job->request_payload.payload_len;
374 	resp_size = job->reply_payload.payload_len;
375 
376 	ioctl_header = &smp_buf->ioctl_header;
377 	put_unaligned_le32(sizeof(smp_buf->ioctl_header),
378 		&ioctl_header->header_length);
379 	put_unaligned_le32(CSMI_IOCTL_TIMEOUT, &ioctl_header->timeout);
380 	put_unaligned_le32(CSMI_CC_SAS_SMP_PASSTHRU,
381 		&ioctl_header->control_code);
382 	put_unaligned_le32(sizeof(smp_buf->parameters), &ioctl_header->length);
383 
384 	parameters = &smp_buf->parameters;
385 	parameters->phy_identifier = rphy->identify.phy_identifier;
386 	parameters->port_identifier = 0;
387 	parameters->connection_rate = 0;
388 	put_unaligned_be64(rphy->identify.sas_address,
389 		&parameters->destination_sas_address);
390 
391 	if (req_size > SMP_CRC_FIELD_LENGTH)
392 		req_size -= SMP_CRC_FIELD_LENGTH;
393 
394 	put_unaligned_le32(req_size, &parameters->request_length);
395 
396 	put_unaligned_le32(resp_size, &parameters->response_length);
397 
398 	sg_copy_to_buffer(job->request_payload.sg_list,
399 		job->reply_payload.sg_cnt, &parameters->request,
400 		req_size);
401 
402 	return smp_buf;
403 }
404 
405 static unsigned int pqi_build_sas_smp_handler_reply(
406 	struct bmic_csmi_smp_passthru_buffer *smp_buf, struct bsg_job *job,
407 	struct pqi_raid_error_info *error_info)
408 {
409 	sg_copy_from_buffer(job->reply_payload.sg_list,
410 		job->reply_payload.sg_cnt, &smp_buf->parameters.response,
411 		le32_to_cpu(smp_buf->parameters.response_length));
412 
413 	job->reply_len = le16_to_cpu(error_info->sense_data_length);
414 	memcpy(job->reply, error_info->data,
415 			le16_to_cpu(error_info->sense_data_length));
416 
417 	return job->reply_payload.payload_len -
418 		get_unaligned_le32(&error_info->data_in_transferred);
419 }
420 
421 void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
422 	struct sas_rphy *rphy)
423 {
424 	int rc;
425 	struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost);
426 	struct bmic_csmi_smp_passthru_buffer *smp_buf;
427 	struct pqi_raid_error_info error_info;
428 	unsigned int reslen = 0;
429 
430 	pqi_ctrl_busy(ctrl_info);
431 
432 	if (job->reply_payload.payload_len == 0) {
433 		rc = -ENOMEM;
434 		goto out;
435 	}
436 
437 	if (!rphy) {
438 		rc = -EINVAL;
439 		goto out;
440 	}
441 
442 	if (rphy->identify.device_type != SAS_FANOUT_EXPANDER_DEVICE) {
443 		rc = -EINVAL;
444 		goto out;
445 	}
446 
447 	if (job->request_payload.sg_cnt > 1 || job->reply_payload.sg_cnt > 1) {
448 		rc = -EINVAL;
449 		goto out;
450 	}
451 
452 	if (pqi_ctrl_offline(ctrl_info)) {
453 		rc = -ENXIO;
454 		goto out;
455 	}
456 
457 	if (pqi_ctrl_blocked(ctrl_info)) {
458 		rc = -EBUSY;
459 		goto out;
460 	}
461 
462 	smp_buf = pqi_build_csmi_smp_passthru_buffer(rphy, job);
463 	if (!smp_buf) {
464 		rc = -ENOMEM;
465 		goto out;
466 	}
467 
468 	rc = pqi_csmi_smp_passthru(ctrl_info, smp_buf, sizeof(*smp_buf),
469 		&error_info);
470 	if (rc)
471 		goto out;
472 
473 	reslen = pqi_build_sas_smp_handler_reply(smp_buf, job, &error_info);
474 out:
475 	bsg_job_done(job, rc, reslen);
476 	pqi_ctrl_unbusy(ctrl_info);
477 }
478 struct sas_function_template pqi_sas_transport_functions = {
479 	.get_linkerrors = pqi_sas_get_linkerrors,
480 	.get_enclosure_identifier = pqi_sas_get_enclosure_identifier,
481 	.get_bay_identifier = pqi_sas_get_bay_identifier,
482 	.phy_reset = pqi_sas_phy_reset,
483 	.phy_enable = pqi_sas_phy_enable,
484 	.phy_setup = pqi_sas_phy_setup,
485 	.phy_release = pqi_sas_phy_release,
486 	.set_phy_speed = pqi_sas_phy_speed,
487 	.smp_handler = pqi_sas_smp_handler,
488 };
489