1 // SPDX-License-Identifier: GPL-2.0
2 /**
3  * configfs to configure the PCI endpoint
4  *
5  * Copyright (C) 2017 Texas Instruments
6  * Author: Kishon Vijay Abraham I <kishon@ti.com>
7  */
8 
9 #include <linux/module.h>
10 #include <linux/idr.h>
11 #include <linux/slab.h>
12 
13 #include <linux/pci-epc.h>
14 #include <linux/pci-epf.h>
15 #include <linux/pci-ep-cfs.h>
16 
17 static DEFINE_IDR(functions_idr);
18 static DEFINE_MUTEX(functions_mutex);
19 static struct config_group *functions_group;
20 static struct config_group *controllers_group;
21 
22 struct pci_epf_group {
23 	struct config_group group;
24 	struct pci_epf *epf;
25 	int index;
26 };
27 
28 struct pci_epc_group {
29 	struct config_group group;
30 	struct pci_epc *epc;
31 	bool start;
32 };
33 
34 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
35 {
36 	return container_of(to_config_group(item), struct pci_epf_group, group);
37 }
38 
39 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
40 {
41 	return container_of(to_config_group(item), struct pci_epc_group, group);
42 }
43 
44 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
45 				   size_t len)
46 {
47 	int ret;
48 	bool start;
49 	struct pci_epc *epc;
50 	struct pci_epc_group *epc_group = to_pci_epc_group(item);
51 
52 	epc = epc_group->epc;
53 
54 	ret = kstrtobool(page, &start);
55 	if (ret)
56 		return ret;
57 
58 	if (!start) {
59 		pci_epc_stop(epc);
60 		epc_group->start = 0;
61 		return len;
62 	}
63 
64 	ret = pci_epc_start(epc);
65 	if (ret) {
66 		dev_err(&epc->dev, "failed to start endpoint controller\n");
67 		return -EINVAL;
68 	}
69 
70 	epc_group->start = start;
71 
72 	return len;
73 }
74 
75 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
76 {
77 	return sprintf(page, "%d\n",
78 		       to_pci_epc_group(item)->start);
79 }
80 
81 CONFIGFS_ATTR(pci_epc_, start);
82 
83 static struct configfs_attribute *pci_epc_attrs[] = {
84 	&pci_epc_attr_start,
85 	NULL,
86 };
87 
88 static int pci_epc_epf_link(struct config_item *epc_item,
89 			    struct config_item *epf_item)
90 {
91 	int ret;
92 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
93 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
94 	struct pci_epc *epc = epc_group->epc;
95 	struct pci_epf *epf = epf_group->epf;
96 
97 	ret = pci_epc_add_epf(epc, epf);
98 	if (ret)
99 		return ret;
100 
101 	ret = pci_epf_bind(epf);
102 	if (ret) {
103 		pci_epc_remove_epf(epc, epf);
104 		return ret;
105 	}
106 
107 	return 0;
108 }
109 
110 static void pci_epc_epf_unlink(struct config_item *epc_item,
111 			       struct config_item *epf_item)
112 {
113 	struct pci_epc *epc;
114 	struct pci_epf *epf;
115 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
116 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
117 
118 	WARN_ON_ONCE(epc_group->start);
119 
120 	epc = epc_group->epc;
121 	epf = epf_group->epf;
122 	pci_epf_unbind(epf);
123 	pci_epc_remove_epf(epc, epf);
124 }
125 
126 static struct configfs_item_operations pci_epc_item_ops = {
127 	.allow_link	= pci_epc_epf_link,
128 	.drop_link	= pci_epc_epf_unlink,
129 };
130 
131 static const struct config_item_type pci_epc_type = {
132 	.ct_item_ops	= &pci_epc_item_ops,
133 	.ct_attrs	= pci_epc_attrs,
134 	.ct_owner	= THIS_MODULE,
135 };
136 
137 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
138 {
139 	int ret;
140 	struct pci_epc *epc;
141 	struct config_group *group;
142 	struct pci_epc_group *epc_group;
143 
144 	epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
145 	if (!epc_group) {
146 		ret = -ENOMEM;
147 		goto err;
148 	}
149 
150 	group = &epc_group->group;
151 
152 	config_group_init_type_name(group, name, &pci_epc_type);
153 	ret = configfs_register_group(controllers_group, group);
154 	if (ret) {
155 		pr_err("failed to register configfs group for %s\n", name);
156 		goto err_register_group;
157 	}
158 
159 	epc = pci_epc_get(name);
160 	if (IS_ERR(epc)) {
161 		ret = PTR_ERR(epc);
162 		goto err_epc_get;
163 	}
164 
165 	epc_group->epc = epc;
166 
167 	return group;
168 
169 err_epc_get:
170 	configfs_unregister_group(group);
171 
172 err_register_group:
173 	kfree(epc_group);
174 
175 err:
176 	return ERR_PTR(ret);
177 }
178 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
179 
180 void pci_ep_cfs_remove_epc_group(struct config_group *group)
181 {
182 	struct pci_epc_group *epc_group;
183 
184 	if (!group)
185 		return;
186 
187 	epc_group = container_of(group, struct pci_epc_group, group);
188 	pci_epc_put(epc_group->epc);
189 	configfs_unregister_group(&epc_group->group);
190 	kfree(epc_group);
191 }
192 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
193 
194 #define PCI_EPF_HEADER_R(_name)						       \
195 static ssize_t pci_epf_##_name##_show(struct config_item *item,	char *page)    \
196 {									       \
197 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
198 	if (WARN_ON_ONCE(!epf->header))					       \
199 		return -EINVAL;						       \
200 	return sprintf(page, "0x%04x\n", epf->header->_name);		       \
201 }
202 
203 #define PCI_EPF_HEADER_W_u32(_name)					       \
204 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
205 				       const char *page, size_t len)	       \
206 {									       \
207 	u32 val;							       \
208 	int ret;							       \
209 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
210 	if (WARN_ON_ONCE(!epf->header))					       \
211 		return -EINVAL;						       \
212 	ret = kstrtou32(page, 0, &val);					       \
213 	if (ret)							       \
214 		return ret;						       \
215 	epf->header->_name = val;					       \
216 	return len;							       \
217 }
218 
219 #define PCI_EPF_HEADER_W_u16(_name)					       \
220 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
221 				       const char *page, size_t len)	       \
222 {									       \
223 	u16 val;							       \
224 	int ret;							       \
225 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
226 	if (WARN_ON_ONCE(!epf->header))					       \
227 		return -EINVAL;						       \
228 	ret = kstrtou16(page, 0, &val);					       \
229 	if (ret)							       \
230 		return ret;						       \
231 	epf->header->_name = val;					       \
232 	return len;							       \
233 }
234 
235 #define PCI_EPF_HEADER_W_u8(_name)					       \
236 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
237 				       const char *page, size_t len)	       \
238 {									       \
239 	u8 val;								       \
240 	int ret;							       \
241 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
242 	if (WARN_ON_ONCE(!epf->header))					       \
243 		return -EINVAL;						       \
244 	ret = kstrtou8(page, 0, &val);					       \
245 	if (ret)							       \
246 		return ret;						       \
247 	epf->header->_name = val;					       \
248 	return len;							       \
249 }
250 
251 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
252 					    const char *page, size_t len)
253 {
254 	u8 val;
255 	int ret;
256 
257 	ret = kstrtou8(page, 0, &val);
258 	if (ret)
259 		return ret;
260 
261 	to_pci_epf_group(item)->epf->msi_interrupts = val;
262 
263 	return len;
264 }
265 
266 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
267 					   char *page)
268 {
269 	return sprintf(page, "%d\n",
270 		       to_pci_epf_group(item)->epf->msi_interrupts);
271 }
272 
273 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
274 					     const char *page, size_t len)
275 {
276 	u16 val;
277 	int ret;
278 
279 	ret = kstrtou16(page, 0, &val);
280 	if (ret)
281 		return ret;
282 
283 	to_pci_epf_group(item)->epf->msix_interrupts = val;
284 
285 	return len;
286 }
287 
288 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
289 					    char *page)
290 {
291 	return sprintf(page, "%d\n",
292 		       to_pci_epf_group(item)->epf->msix_interrupts);
293 }
294 
295 PCI_EPF_HEADER_R(vendorid)
296 PCI_EPF_HEADER_W_u16(vendorid)
297 
298 PCI_EPF_HEADER_R(deviceid)
299 PCI_EPF_HEADER_W_u16(deviceid)
300 
301 PCI_EPF_HEADER_R(revid)
302 PCI_EPF_HEADER_W_u8(revid)
303 
304 PCI_EPF_HEADER_R(progif_code)
305 PCI_EPF_HEADER_W_u8(progif_code)
306 
307 PCI_EPF_HEADER_R(subclass_code)
308 PCI_EPF_HEADER_W_u8(subclass_code)
309 
310 PCI_EPF_HEADER_R(baseclass_code)
311 PCI_EPF_HEADER_W_u8(baseclass_code)
312 
313 PCI_EPF_HEADER_R(cache_line_size)
314 PCI_EPF_HEADER_W_u8(cache_line_size)
315 
316 PCI_EPF_HEADER_R(subsys_vendor_id)
317 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
318 
319 PCI_EPF_HEADER_R(subsys_id)
320 PCI_EPF_HEADER_W_u16(subsys_id)
321 
322 PCI_EPF_HEADER_R(interrupt_pin)
323 PCI_EPF_HEADER_W_u8(interrupt_pin)
324 
325 CONFIGFS_ATTR(pci_epf_, vendorid);
326 CONFIGFS_ATTR(pci_epf_, deviceid);
327 CONFIGFS_ATTR(pci_epf_, revid);
328 CONFIGFS_ATTR(pci_epf_, progif_code);
329 CONFIGFS_ATTR(pci_epf_, subclass_code);
330 CONFIGFS_ATTR(pci_epf_, baseclass_code);
331 CONFIGFS_ATTR(pci_epf_, cache_line_size);
332 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
333 CONFIGFS_ATTR(pci_epf_, subsys_id);
334 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
335 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
336 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
337 
338 static struct configfs_attribute *pci_epf_attrs[] = {
339 	&pci_epf_attr_vendorid,
340 	&pci_epf_attr_deviceid,
341 	&pci_epf_attr_revid,
342 	&pci_epf_attr_progif_code,
343 	&pci_epf_attr_subclass_code,
344 	&pci_epf_attr_baseclass_code,
345 	&pci_epf_attr_cache_line_size,
346 	&pci_epf_attr_subsys_vendor_id,
347 	&pci_epf_attr_subsys_id,
348 	&pci_epf_attr_interrupt_pin,
349 	&pci_epf_attr_msi_interrupts,
350 	&pci_epf_attr_msix_interrupts,
351 	NULL,
352 };
353 
354 static void pci_epf_release(struct config_item *item)
355 {
356 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
357 
358 	mutex_lock(&functions_mutex);
359 	idr_remove(&functions_idr, epf_group->index);
360 	mutex_unlock(&functions_mutex);
361 	pci_epf_destroy(epf_group->epf);
362 	kfree(epf_group);
363 }
364 
365 static struct configfs_item_operations pci_epf_ops = {
366 	.release		= pci_epf_release,
367 };
368 
369 static const struct config_item_type pci_epf_type = {
370 	.ct_item_ops	= &pci_epf_ops,
371 	.ct_attrs	= pci_epf_attrs,
372 	.ct_owner	= THIS_MODULE,
373 };
374 
375 static struct config_group *pci_epf_make(struct config_group *group,
376 					 const char *name)
377 {
378 	struct pci_epf_group *epf_group;
379 	struct pci_epf *epf;
380 	char *epf_name;
381 	int index, err;
382 
383 	epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
384 	if (!epf_group)
385 		return ERR_PTR(-ENOMEM);
386 
387 	mutex_lock(&functions_mutex);
388 	index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
389 	mutex_unlock(&functions_mutex);
390 	if (index < 0) {
391 		err = index;
392 		goto free_group;
393 	}
394 
395 	epf_group->index = index;
396 
397 	config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
398 
399 	epf_name = kasprintf(GFP_KERNEL, "%s.%d",
400 			     group->cg_item.ci_name, epf_group->index);
401 	if (!epf_name) {
402 		err = -ENOMEM;
403 		goto remove_idr;
404 	}
405 
406 	epf = pci_epf_create(epf_name);
407 	if (IS_ERR(epf)) {
408 		pr_err("failed to create endpoint function device\n");
409 		err = -EINVAL;
410 		goto free_name;
411 	}
412 
413 	epf_group->epf = epf;
414 
415 	kfree(epf_name);
416 
417 	return &epf_group->group;
418 
419 free_name:
420 	kfree(epf_name);
421 
422 remove_idr:
423 	mutex_lock(&functions_mutex);
424 	idr_remove(&functions_idr, epf_group->index);
425 	mutex_unlock(&functions_mutex);
426 
427 free_group:
428 	kfree(epf_group);
429 
430 	return ERR_PTR(err);
431 }
432 
433 static void pci_epf_drop(struct config_group *group, struct config_item *item)
434 {
435 	config_item_put(item);
436 }
437 
438 static struct configfs_group_operations pci_epf_group_ops = {
439 	.make_group     = &pci_epf_make,
440 	.drop_item      = &pci_epf_drop,
441 };
442 
443 static const struct config_item_type pci_epf_group_type = {
444 	.ct_group_ops	= &pci_epf_group_ops,
445 	.ct_owner	= THIS_MODULE,
446 };
447 
448 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
449 {
450 	struct config_group *group;
451 
452 	group = configfs_register_default_group(functions_group, name,
453 						&pci_epf_group_type);
454 	if (IS_ERR(group))
455 		pr_err("failed to register configfs group for %s function\n",
456 		       name);
457 
458 	return group;
459 }
460 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
461 
462 void pci_ep_cfs_remove_epf_group(struct config_group *group)
463 {
464 	if (IS_ERR_OR_NULL(group))
465 		return;
466 
467 	configfs_unregister_default_group(group);
468 }
469 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
470 
471 static const struct config_item_type pci_functions_type = {
472 	.ct_owner	= THIS_MODULE,
473 };
474 
475 static const struct config_item_type pci_controllers_type = {
476 	.ct_owner	= THIS_MODULE,
477 };
478 
479 static const struct config_item_type pci_ep_type = {
480 	.ct_owner	= THIS_MODULE,
481 };
482 
483 static struct configfs_subsystem pci_ep_cfs_subsys = {
484 	.su_group = {
485 		.cg_item = {
486 			.ci_namebuf = "pci_ep",
487 			.ci_type = &pci_ep_type,
488 		},
489 	},
490 	.su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
491 };
492 
493 static int __init pci_ep_cfs_init(void)
494 {
495 	int ret;
496 	struct config_group *root = &pci_ep_cfs_subsys.su_group;
497 
498 	config_group_init(root);
499 
500 	ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
501 	if (ret) {
502 		pr_err("Error %d while registering subsystem %s\n",
503 		       ret, root->cg_item.ci_namebuf);
504 		goto err;
505 	}
506 
507 	functions_group = configfs_register_default_group(root, "functions",
508 							  &pci_functions_type);
509 	if (IS_ERR(functions_group)) {
510 		ret = PTR_ERR(functions_group);
511 		pr_err("Error %d while registering functions group\n",
512 		       ret);
513 		goto err_functions_group;
514 	}
515 
516 	controllers_group =
517 		configfs_register_default_group(root, "controllers",
518 						&pci_controllers_type);
519 	if (IS_ERR(controllers_group)) {
520 		ret = PTR_ERR(controllers_group);
521 		pr_err("Error %d while registering controllers group\n",
522 		       ret);
523 		goto err_controllers_group;
524 	}
525 
526 	return 0;
527 
528 err_controllers_group:
529 	configfs_unregister_default_group(functions_group);
530 
531 err_functions_group:
532 	configfs_unregister_subsystem(&pci_ep_cfs_subsys);
533 
534 err:
535 	return ret;
536 }
537 module_init(pci_ep_cfs_init);
538 
539 static void __exit pci_ep_cfs_exit(void)
540 {
541 	configfs_unregister_default_group(controllers_group);
542 	configfs_unregister_default_group(functions_group);
543 	configfs_unregister_subsystem(&pci_ep_cfs_subsys);
544 }
545 module_exit(pci_ep_cfs_exit);
546 
547 MODULE_DESCRIPTION("PCI EP CONFIGFS");
548 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
549 MODULE_LICENSE("GPL v2");
550