1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright(c) 2011 - 2012 Intel Corporation. All rights reserved.
4 *
5 * Maintained at www.Open-FCoE.org
6 */
7
8#include <linux/module.h>
9#include <linux/types.h>
10#include <linux/kernel.h>
11#include <linux/etherdevice.h>
12#include <linux/ctype.h>
13
14#include <scsi/fcoe_sysfs.h>
15#include <scsi/libfcoe.h>
16
17/*
18 * OK to include local libfcoe.h for debug_logging, but cannot include
19 * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have
20 * have to include more than fcoe_sysfs.h.
21 */
22#include "libfcoe.h"
23
24static atomic_t ctlr_num;
25static atomic_t fcf_num;
26
27/*
28 * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs
29 * should insulate the loss of a fcf.
30 */
31static unsigned int fcoe_fcf_dev_loss_tmo = 1800;  /* seconds */
32
33module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo,
34		   uint, S_IRUGO|S_IWUSR);
35MODULE_PARM_DESC(fcf_dev_loss_tmo,
36		 "Maximum number of seconds that libfcoe should"
37		 " insulate the loss of a fcf. Once this value is"
38		 " exceeded, the fcf is removed.");
39
40/*
41 * These are used by the fcoe_*_show_function routines, they
42 * are intentionally placed in the .c file as they're not intended
43 * for use throughout the code.
44 */
45#define fcoe_ctlr_id(x)				\
46	((x)->id)
47#define fcoe_ctlr_work_q_name(x)		\
48	((x)->work_q_name)
49#define fcoe_ctlr_work_q(x)			\
50	((x)->work_q)
51#define fcoe_ctlr_devloss_work_q_name(x)	\
52	((x)->devloss_work_q_name)
53#define fcoe_ctlr_devloss_work_q(x)		\
54	((x)->devloss_work_q)
55#define fcoe_ctlr_mode(x)			\
56	((x)->mode)
57#define fcoe_ctlr_fcf_dev_loss_tmo(x)		\
58	((x)->fcf_dev_loss_tmo)
59#define fcoe_ctlr_link_fail(x)			\
60	((x)->lesb.lesb_link_fail)
61#define fcoe_ctlr_vlink_fail(x)			\
62	((x)->lesb.lesb_vlink_fail)
63#define fcoe_ctlr_miss_fka(x)			\
64	((x)->lesb.lesb_miss_fka)
65#define fcoe_ctlr_symb_err(x)			\
66	((x)->lesb.lesb_symb_err)
67#define fcoe_ctlr_err_block(x)			\
68	((x)->lesb.lesb_err_block)
69#define fcoe_ctlr_fcs_error(x)			\
70	((x)->lesb.lesb_fcs_error)
71#define fcoe_ctlr_enabled(x)			\
72	((x)->enabled)
73#define fcoe_fcf_state(x)			\
74	((x)->state)
75#define fcoe_fcf_fabric_name(x)			\
76	((x)->fabric_name)
77#define fcoe_fcf_switch_name(x)			\
78	((x)->switch_name)
79#define fcoe_fcf_fc_map(x)			\
80	((x)->fc_map)
81#define fcoe_fcf_vfid(x)			\
82	((x)->vfid)
83#define fcoe_fcf_mac(x)				\
84	((x)->mac)
85#define fcoe_fcf_priority(x)			\
86	((x)->priority)
87#define fcoe_fcf_fka_period(x)			\
88	((x)->fka_period)
89#define fcoe_fcf_dev_loss_tmo(x)		\
90	((x)->dev_loss_tmo)
91#define fcoe_fcf_selected(x)			\
92	((x)->selected)
93#define fcoe_fcf_vlan_id(x)			\
94	((x)->vlan_id)
95
96/*
97 * dev_loss_tmo attribute
98 */
99static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val)
100{
101	int ret;
102
103	ret = kstrtoul(buf, 0, val);
104	if (ret)
105		return -EINVAL;
106	/*
107	 * Check for overflow; dev_loss_tmo is u32
108	 */
109	if (*val > UINT_MAX)
110		return -EINVAL;
111
112	return 0;
113}
114
115static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf,
116				     unsigned long val)
117{
118	if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) ||
119	    (fcf->state == FCOE_FCF_STATE_DISCONNECTED) ||
120	    (fcf->state == FCOE_FCF_STATE_DELETED))
121		return -EBUSY;
122	/*
123	 * Check for overflow; dev_loss_tmo is u32
124	 */
125	if (val > UINT_MAX)
126		return -EINVAL;
127
128	fcoe_fcf_dev_loss_tmo(fcf) = val;
129	return 0;
130}
131
132#define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store)	\
133struct device_attribute device_attr_fcoe_##_prefix##_##_name =	\
134	__ATTR(_name, _mode, _show, _store)
135
136#define fcoe_ctlr_show_function(field, format_string, sz, cast)	\
137static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \
138					    struct device_attribute *attr, \
139					    char *buf)			\
140{									\
141	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);		\
142	if (ctlr->f->get_fcoe_ctlr_##field)				\
143		ctlr->f->get_fcoe_ctlr_##field(ctlr);			\
144	return snprintf(buf, sz, format_string,				\
145			cast fcoe_ctlr_##field(ctlr));			\
146}
147
148#define fcoe_fcf_show_function(field, format_string, sz, cast)	\
149static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
150					   struct device_attribute *attr, \
151					   char *buf)			\
152{									\
153	struct fcoe_fcf_device *fcf = dev_to_fcf(dev);			\
154	struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);	\
155	if (ctlr->f->get_fcoe_fcf_##field)				\
156		ctlr->f->get_fcoe_fcf_##field(fcf);			\
157	return snprintf(buf, sz, format_string,				\
158			cast fcoe_fcf_##field(fcf));			\
159}
160
161#define fcoe_ctlr_private_show_function(field, format_string, sz, cast)	\
162static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \
163					    struct device_attribute *attr, \
164					    char *buf)			\
165{									\
166	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);		\
167	return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \
168}
169
170#define fcoe_fcf_private_show_function(field, format_string, sz, cast)	\
171static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
172					   struct device_attribute *attr, \
173					   char *buf)			\
174{								\
175	struct fcoe_fcf_device *fcf = dev_to_fcf(dev);			\
176	return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \
177}
178
179#define fcoe_ctlr_private_rd_attr(field, format_string, sz)		\
180	fcoe_ctlr_private_show_function(field, format_string, sz, )	\
181	static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,			\
182				show_fcoe_ctlr_device_##field, NULL)
183
184#define fcoe_ctlr_rd_attr(field, format_string, sz)			\
185	fcoe_ctlr_show_function(field, format_string, sz, )		\
186	static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,			\
187				show_fcoe_ctlr_device_##field, NULL)
188
189#define fcoe_fcf_rd_attr(field, format_string, sz)			\
190	fcoe_fcf_show_function(field, format_string, sz, )		\
191	static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,			\
192				show_fcoe_fcf_device_##field, NULL)
193
194#define fcoe_fcf_private_rd_attr(field, format_string, sz)		\
195	fcoe_fcf_private_show_function(field, format_string, sz, )	\
196	static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,			\
197				show_fcoe_fcf_device_##field, NULL)
198
199#define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast)	\
200	fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \
201	static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,			\
202				show_fcoe_ctlr_device_##field, NULL)
203
204#define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast)	\
205	fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \
206	static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,			\
207				show_fcoe_fcf_device_##field, NULL)
208
209#define fcoe_enum_name_search(title, table_type, table)			\
210static const char *get_fcoe_##title##_name(enum table_type table_key)	\
211{									\
212	if (table_key < 0 || table_key >= ARRAY_SIZE(table))		\
213		return NULL;						\
214	return table[table_key];					\
215}
216
217static char *fip_conn_type_names[] = {
218	[ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
219	[ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
220	[ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
221};
222fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
223
224static enum fip_conn_type fcoe_parse_mode(const char *buf)
225{
226	int i;
227
228	for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) {
229		if (strcasecmp(buf, fip_conn_type_names[i]) == 0)
230			return i;
231	}
232
233	return FIP_CONN_TYPE_UNKNOWN;
234}
235
236static char *fcf_state_names[] = {
237	[ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
238	[ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
239	[ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
240};
241fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
242#define FCOE_FCF_STATE_MAX_NAMELEN 50
243
244static ssize_t show_fcf_state(struct device *dev,
245			      struct device_attribute *attr,
246			      char *buf)
247{
248	struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
249	const char *name;
250	name = get_fcoe_fcf_state_name(fcf->state);
251	if (!name)
252		return -EINVAL;
253	return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name);
254}
255static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
256
257#define FCOE_MAX_MODENAME_LEN 20
258static ssize_t show_ctlr_mode(struct device *dev,
259			      struct device_attribute *attr,
260			      char *buf)
261{
262	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
263	const char *name;
264
265	name = get_fcoe_ctlr_mode_name(ctlr->mode);
266	if (!name)
267		return -EINVAL;
268	return snprintf(buf, FCOE_MAX_MODENAME_LEN,
269			"%s\n", name);
270}
271
272static ssize_t store_ctlr_mode(struct device *dev,
273			       struct device_attribute *attr,
274			       const char *buf, size_t count)
275{
276	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
277	char mode[FCOE_MAX_MODENAME_LEN + 1];
278
279	if (count > FCOE_MAX_MODENAME_LEN)
280		return -EINVAL;
281
282	strncpy(mode, buf, count);
283
284	if (mode[count - 1] == '\n')
285		mode[count - 1] = '\0';
286	else
287		mode[count] = '\0';
288
289	switch (ctlr->enabled) {
290	case FCOE_CTLR_ENABLED:
291		LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.\n");
292		return -EBUSY;
293	case FCOE_CTLR_DISABLED:
294		if (!ctlr->f->set_fcoe_ctlr_mode) {
295			LIBFCOE_SYSFS_DBG(ctlr,
296					  "Mode change not supported by LLD.\n");
297			return -ENOTSUPP;
298		}
299
300		ctlr->mode = fcoe_parse_mode(mode);
301		if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
302			LIBFCOE_SYSFS_DBG(ctlr, "Unknown mode %s provided.\n",
303					  buf);
304			return -EINVAL;
305		}
306
307		ctlr->f->set_fcoe_ctlr_mode(ctlr);
308		LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.\n", buf);
309
310		return count;
311	case FCOE_CTLR_UNUSED:
312	default:
313		LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.\n");
314		return -ENOTSUPP;
315	}
316}
317
318static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR,
319			show_ctlr_mode, store_ctlr_mode);
320
321static ssize_t store_ctlr_enabled(struct device *dev,
322				  struct device_attribute *attr,
323				  const char *buf, size_t count)
324{
325	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
326	bool enabled;
327	int rc;
328
329	if (*buf == '1')
330		enabled = true;
331	else if (*buf == '0')
332		enabled = false;
333	else
334		return -EINVAL;
335
336	switch (ctlr->enabled) {
337	case FCOE_CTLR_ENABLED:
338		if (enabled)
339			return count;
340		ctlr->enabled = FCOE_CTLR_DISABLED;
341		break;
342	case FCOE_CTLR_DISABLED:
343		if (!enabled)
344			return count;
345		ctlr->enabled = FCOE_CTLR_ENABLED;
346		break;
347	case FCOE_CTLR_UNUSED:
348		return -ENOTSUPP;
349	}
350
351	rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr);
352	if (rc)
353		return rc;
354
355	return count;
356}
357
358static char *ctlr_enabled_state_names[] = {
359	[ FCOE_CTLR_ENABLED ]  = "1",
360	[ FCOE_CTLR_DISABLED ] = "0",
361};
362fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state,
363		      ctlr_enabled_state_names)
364#define FCOE_CTLR_ENABLED_MAX_NAMELEN 50
365
366static ssize_t show_ctlr_enabled_state(struct device *dev,
367				       struct device_attribute *attr,
368				       char *buf)
369{
370	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
371	const char *name;
372
373	name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled);
374	if (!name)
375		return -EINVAL;
376	return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN,
377			"%s\n", name);
378}
379
380static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR,
381			show_ctlr_enabled_state,
382			store_ctlr_enabled);
383
384static ssize_t store_ctlr_fip_resp(struct device *dev,
385			      struct device_attribute *attr,
386			      const char *buf, size_t count)
387{
388	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
389	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr);
390
391	mutex_lock(&fip->ctlr_mutex);
392	if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
393		if (buf[0] == '1') {
394			fip->fip_resp = 1;
395			mutex_unlock(&fip->ctlr_mutex);
396			return count;
397		}
398		if (buf[0] == '0') {
399			fip->fip_resp = 0;
400			mutex_unlock(&fip->ctlr_mutex);
401			return count;
402		}
403	}
404	mutex_unlock(&fip->ctlr_mutex);
405	return -EINVAL;
406}
407
408static ssize_t show_ctlr_fip_resp(struct device *dev,
409				  struct device_attribute *attr,
410				  char *buf)
411{
412	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
413	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr);
414
415	return sprintf(buf, "%d\n", fip->fip_resp ? 1 : 0);
416}
417
418static FCOE_DEVICE_ATTR(ctlr, fip_vlan_responder, S_IRUGO | S_IWUSR,
419			show_ctlr_fip_resp,
420			store_ctlr_fip_resp);
421
422static ssize_t
423fcoe_ctlr_var_store(u32 *var, const char *buf, size_t count)
424{
425	int err;
426	unsigned long v;
427
428	err = kstrtoul(buf, 10, &v);
429	if (err || v > UINT_MAX)
430		return -EINVAL;
431
432	*var = v;
433
434	return count;
435}
436
437static ssize_t store_ctlr_r_a_tov(struct device *dev,
438				  struct device_attribute *attr,
439				  const char *buf, size_t count)
440{
441	struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
442	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
443
444	if (ctlr_dev->enabled == FCOE_CTLR_ENABLED)
445		return -EBUSY;
446	if (ctlr_dev->enabled == FCOE_CTLR_DISABLED)
447		return fcoe_ctlr_var_store(&ctlr->lp->r_a_tov, buf, count);
448	return -ENOTSUPP;
449}
450
451static ssize_t show_ctlr_r_a_tov(struct device *dev,
452				 struct device_attribute *attr,
453				 char *buf)
454{
455	struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
456	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
457
458	return sprintf(buf, "%d\n", ctlr->lp->r_a_tov);
459}
460
461static FCOE_DEVICE_ATTR(ctlr, r_a_tov, S_IRUGO | S_IWUSR,
462			show_ctlr_r_a_tov, store_ctlr_r_a_tov);
463
464static ssize_t store_ctlr_e_d_tov(struct device *dev,
465				  struct device_attribute *attr,
466				  const char *buf, size_t count)
467{
468	struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
469	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
470
471	if (ctlr_dev->enabled == FCOE_CTLR_ENABLED)
472		return -EBUSY;
473	if (ctlr_dev->enabled == FCOE_CTLR_DISABLED)
474		return fcoe_ctlr_var_store(&ctlr->lp->e_d_tov, buf, count);
475	return -ENOTSUPP;
476}
477
478static ssize_t show_ctlr_e_d_tov(struct device *dev,
479				 struct device_attribute *attr,
480				 char *buf)
481{
482	struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
483	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
484
485	return sprintf(buf, "%d\n", ctlr->lp->e_d_tov);
486}
487
488static FCOE_DEVICE_ATTR(ctlr, e_d_tov, S_IRUGO | S_IWUSR,
489			show_ctlr_e_d_tov, store_ctlr_e_d_tov);
490
491static ssize_t
492store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev,
493					 struct device_attribute *attr,
494					 const char *buf, size_t count)
495{
496	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
497	struct fcoe_fcf_device *fcf;
498	unsigned long val;
499	int rc;
500
501	rc = fcoe_str_to_dev_loss(buf, &val);
502	if (rc)
503		return rc;
504
505	fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val;
506	mutex_lock(&ctlr->lock);
507	list_for_each_entry(fcf, &ctlr->fcfs, peers)
508		fcoe_fcf_set_dev_loss_tmo(fcf, val);
509	mutex_unlock(&ctlr->lock);
510	return count;
511}
512fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, );
513static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR,
514			show_fcoe_ctlr_device_fcf_dev_loss_tmo,
515			store_private_fcoe_ctlr_fcf_dev_loss_tmo);
516
517/* Link Error Status Block (LESB) */
518fcoe_ctlr_rd_attr(link_fail, "%u\n", 20);
519fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20);
520fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20);
521fcoe_ctlr_rd_attr(symb_err, "%u\n", 20);
522fcoe_ctlr_rd_attr(err_block, "%u\n", 20);
523fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20);
524
525fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
526fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long);
527fcoe_fcf_private_rd_attr(priority, "%u\n", 20);
528fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20);
529fcoe_fcf_private_rd_attr(vfid, "%u\n", 20);
530fcoe_fcf_private_rd_attr(mac, "%pM\n", 20);
531fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20);
532fcoe_fcf_rd_attr(selected, "%u\n", 20);
533fcoe_fcf_rd_attr(vlan_id, "%u\n", 20);
534
535fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, )
536static ssize_t
537store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
538			    const char *buf, size_t count)
539{
540	struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
541	unsigned long val;
542	int rc;
543
544	rc = fcoe_str_to_dev_loss(buf, &val);
545	if (rc)
546		return rc;
547
548	rc = fcoe_fcf_set_dev_loss_tmo(fcf, val);
549	if (rc)
550		return rc;
551	return count;
552}
553static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR,
554			show_fcoe_fcf_device_dev_loss_tmo,
555			store_fcoe_fcf_dev_loss_tmo);
556
557static struct attribute *fcoe_ctlr_lesb_attrs[] = {
558	&device_attr_fcoe_ctlr_link_fail.attr,
559	&device_attr_fcoe_ctlr_vlink_fail.attr,
560	&device_attr_fcoe_ctlr_miss_fka.attr,
561	&device_attr_fcoe_ctlr_symb_err.attr,
562	&device_attr_fcoe_ctlr_err_block.attr,
563	&device_attr_fcoe_ctlr_fcs_error.attr,
564	NULL,
565};
566
567static struct attribute_group fcoe_ctlr_lesb_attr_group = {
568	.name = "lesb",
569	.attrs = fcoe_ctlr_lesb_attrs,
570};
571
572static struct attribute *fcoe_ctlr_attrs[] = {
573	&device_attr_fcoe_ctlr_fip_vlan_responder.attr,
574	&device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr,
575	&device_attr_fcoe_ctlr_r_a_tov.attr,
576	&device_attr_fcoe_ctlr_e_d_tov.attr,
577	&device_attr_fcoe_ctlr_enabled.attr,
578	&device_attr_fcoe_ctlr_mode.attr,
579	NULL,
580};
581
582static struct attribute_group fcoe_ctlr_attr_group = {
583	.attrs = fcoe_ctlr_attrs,
584};
585
586static const struct attribute_group *fcoe_ctlr_attr_groups[] = {
587	&fcoe_ctlr_attr_group,
588	&fcoe_ctlr_lesb_attr_group,
589	NULL,
590};
591
592static struct attribute *fcoe_fcf_attrs[] = {
593	&device_attr_fcoe_fcf_fabric_name.attr,
594	&device_attr_fcoe_fcf_switch_name.attr,
595	&device_attr_fcoe_fcf_dev_loss_tmo.attr,
596	&device_attr_fcoe_fcf_fc_map.attr,
597	&device_attr_fcoe_fcf_vfid.attr,
598	&device_attr_fcoe_fcf_mac.attr,
599	&device_attr_fcoe_fcf_priority.attr,
600	&device_attr_fcoe_fcf_fka_period.attr,
601	&device_attr_fcoe_fcf_state.attr,
602	&device_attr_fcoe_fcf_selected.attr,
603	&device_attr_fcoe_fcf_vlan_id.attr,
604	NULL
605};
606
607static struct attribute_group fcoe_fcf_attr_group = {
608	.attrs = fcoe_fcf_attrs,
609};
610
611static const struct attribute_group *fcoe_fcf_attr_groups[] = {
612	&fcoe_fcf_attr_group,
613	NULL,
614};
615
616static struct bus_type fcoe_bus_type;
617
618static int fcoe_bus_match(struct device *dev,
619			  struct device_driver *drv)
620{
621	if (dev->bus == &fcoe_bus_type)
622		return 1;
623	return 0;
624}
625
626/**
627 * fcoe_ctlr_device_release() - Release the FIP ctlr memory
628 * @dev: Pointer to the FIP ctlr's embedded device
629 *
630 * Called when the last FIP ctlr reference is released.
631 */
632static void fcoe_ctlr_device_release(struct device *dev)
633{
634	struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
635	kfree(ctlr);
636}
637
638/**
639 * fcoe_fcf_device_release() - Release the FIP fcf memory
640 * @dev: Pointer to the fcf's embedded device
641 *
642 * Called when the last FIP fcf reference is released.
643 */
644static void fcoe_fcf_device_release(struct device *dev)
645{
646	struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
647	kfree(fcf);
648}
649
650static const struct device_type fcoe_ctlr_device_type = {
651	.name = "fcoe_ctlr",
652	.groups = fcoe_ctlr_attr_groups,
653	.release = fcoe_ctlr_device_release,
654};
655
656static const struct device_type fcoe_fcf_device_type = {
657	.name = "fcoe_fcf",
658	.groups = fcoe_fcf_attr_groups,
659	.release = fcoe_fcf_device_release,
660};
661
662static ssize_t ctlr_create_store(const struct bus_type *bus, const char *buf,
663				 size_t count)
664{
665	return fcoe_ctlr_create_store(buf, count);
666}
667static BUS_ATTR_WO(ctlr_create);
668
669static ssize_t ctlr_destroy_store(const struct bus_type *bus, const char *buf,
670				  size_t count)
671{
672	return fcoe_ctlr_destroy_store(buf, count);
673}
674static BUS_ATTR_WO(ctlr_destroy);
675
676static struct attribute *fcoe_bus_attrs[] = {
677	&bus_attr_ctlr_create.attr,
678	&bus_attr_ctlr_destroy.attr,
679	NULL,
680};
681ATTRIBUTE_GROUPS(fcoe_bus);
682
683static struct bus_type fcoe_bus_type = {
684	.name = "fcoe",
685	.match = &fcoe_bus_match,
686	.bus_groups = fcoe_bus_groups,
687};
688
689/**
690 * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue
691 * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed
692 */
693static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
694{
695	if (!fcoe_ctlr_work_q(ctlr)) {
696		printk(KERN_ERR
697		       "ERROR: FIP Ctlr '%d' attempted to flush work, "
698		       "when no workqueue created.\n", ctlr->id);
699		dump_stack();
700		return;
701	}
702
703	flush_workqueue(fcoe_ctlr_work_q(ctlr));
704}
705
706/**
707 * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue
708 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue
709 * @work:   Work to queue for execution
710 *
711 * Return value:
712 *	1 on success / 0 already queued / < 0 for error
713 */
714static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
715				       struct work_struct *work)
716{
717	if (unlikely(!fcoe_ctlr_work_q(ctlr))) {
718		printk(KERN_ERR
719		       "ERROR: FIP Ctlr '%d' attempted to queue work, "
720		       "when no workqueue created.\n", ctlr->id);
721		dump_stack();
722
723		return -EINVAL;
724	}
725
726	return queue_work(fcoe_ctlr_work_q(ctlr), work);
727}
728
729/**
730 * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue
731 * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed
732 */
733static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
734{
735	if (!fcoe_ctlr_devloss_work_q(ctlr)) {
736		printk(KERN_ERR
737		       "ERROR: FIP Ctlr '%d' attempted to flush work, "
738		       "when no workqueue created.\n", ctlr->id);
739		dump_stack();
740		return;
741	}
742
743	flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr));
744}
745
746/**
747 * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue
748 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue
749 * @work:   Work to queue for execution
750 * @delay:  jiffies to delay the work queuing
751 *
752 * Return value:
753 *	1 on success / 0 already queued / < 0 for error
754 */
755static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
756					       struct delayed_work *work,
757					       unsigned long delay)
758{
759	if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) {
760		printk(KERN_ERR
761		       "ERROR: FIP Ctlr '%d' attempted to queue work, "
762		       "when no workqueue created.\n", ctlr->id);
763		dump_stack();
764
765		return -EINVAL;
766	}
767
768	return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay);
769}
770
771static int fcoe_fcf_device_match(struct fcoe_fcf_device *new,
772				 struct fcoe_fcf_device *old)
773{
774	if (new->switch_name == old->switch_name &&
775	    new->fabric_name == old->fabric_name &&
776	    new->fc_map == old->fc_map &&
777	    ether_addr_equal(new->mac, old->mac))
778		return 1;
779	return 0;
780}
781
782/**
783 * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs
784 * @parent:    The parent device to which the fcoe_ctlr instance
785 *             should be attached
786 * @f:         The LLD's FCoE sysfs function template pointer
787 * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD
788 *
789 * This routine allocates a FIP ctlr object with some additional memory
790 * for the LLD. The FIP ctlr is initialized, added to sysfs and then
791 * attributes are added to it.
792 */
793struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
794				    struct fcoe_sysfs_function_template *f,
795				    int priv_size)
796{
797	struct fcoe_ctlr_device *ctlr;
798	int error = 0;
799
800	ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size,
801		       GFP_KERNEL);
802	if (!ctlr)
803		goto out;
804
805	ctlr->id = atomic_inc_return(&ctlr_num) - 1;
806	ctlr->f = f;
807	ctlr->mode = FIP_CONN_TYPE_FABRIC;
808	INIT_LIST_HEAD(&ctlr->fcfs);
809	mutex_init(&ctlr->lock);
810	ctlr->dev.parent = parent;
811	ctlr->dev.bus = &fcoe_bus_type;
812	ctlr->dev.type = &fcoe_ctlr_device_type;
813
814	ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo;
815
816	snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name),
817		 "ctlr_wq_%d", ctlr->id);
818	ctlr->work_q = create_singlethread_workqueue(
819		ctlr->work_q_name);
820	if (!ctlr->work_q)
821		goto out_del;
822
823	snprintf(ctlr->devloss_work_q_name,
824		 sizeof(ctlr->devloss_work_q_name),
825		 "ctlr_dl_wq_%d", ctlr->id);
826	ctlr->devloss_work_q = create_singlethread_workqueue(
827		ctlr->devloss_work_q_name);
828	if (!ctlr->devloss_work_q)
829		goto out_del_q;
830
831	dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id);
832	error = device_register(&ctlr->dev);
833	if (error) {
834		destroy_workqueue(ctlr->devloss_work_q);
835		destroy_workqueue(ctlr->work_q);
836		put_device(&ctlr->dev);
837		return NULL;
838	}
839
840	return ctlr;
841
842out_del_q:
843	destroy_workqueue(ctlr->work_q);
844	ctlr->work_q = NULL;
845out_del:
846	kfree(ctlr);
847out:
848	return NULL;
849}
850EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add);
851
852/**
853 * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs
854 * @ctlr: A pointer to the ctlr to be deleted
855 *
856 * Deletes a FIP ctlr and any fcfs attached
857 * to it. Deleting fcfs will cause their childen
858 * to be deleted as well.
859 *
860 * The ctlr is detached from sysfs and it's resources
861 * are freed (work q), but the memory is not freed
862 * until its last reference is released.
863 *
864 * This routine expects no locks to be held before
865 * calling.
866 *
867 * TODO: Currently there are no callbacks to clean up LLD data
868 * for a fcoe_fcf_device. LLDs must keep this in mind as they need
869 * to clean up each of their LLD data for all fcoe_fcf_device before
870 * calling fcoe_ctlr_device_delete.
871 */
872void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr)
873{
874	struct fcoe_fcf_device *fcf, *next;
875	/* Remove any attached fcfs */
876	mutex_lock(&ctlr->lock);
877	list_for_each_entry_safe(fcf, next,
878				 &ctlr->fcfs, peers) {
879		list_del(&fcf->peers);
880		fcf->state = FCOE_FCF_STATE_DELETED;
881		fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work);
882	}
883	mutex_unlock(&ctlr->lock);
884
885	fcoe_ctlr_device_flush_work(ctlr);
886
887	destroy_workqueue(ctlr->devloss_work_q);
888	ctlr->devloss_work_q = NULL;
889	destroy_workqueue(ctlr->work_q);
890	ctlr->work_q = NULL;
891
892	device_unregister(&ctlr->dev);
893}
894EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete);
895
896/**
897 * fcoe_fcf_device_final_delete() - Final delete routine
898 * @work: The FIP fcf's embedded work struct
899 *
900 * It is expected that the fcf has been removed from
901 * the FIP ctlr's list before calling this routine.
902 */
903static void fcoe_fcf_device_final_delete(struct work_struct *work)
904{
905	struct fcoe_fcf_device *fcf =
906		container_of(work, struct fcoe_fcf_device, delete_work);
907	struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
908
909	/*
910	 * Cancel any outstanding timers. These should really exist
911	 * only when rmmod'ing the LLDD and we're asking for
912	 * immediate termination of the rports
913	 */
914	if (!cancel_delayed_work(&fcf->dev_loss_work))
915		fcoe_ctlr_device_flush_devloss(ctlr);
916
917	device_unregister(&fcf->dev);
918}
919
920/**
921 * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires
922 * @work: The FIP fcf's embedded work struct
923 *
924 * Removes the fcf from the FIP ctlr's list of fcfs and
925 * queues the final deletion.
926 */
927static void fip_timeout_deleted_fcf(struct work_struct *work)
928{
929	struct fcoe_fcf_device *fcf =
930		container_of(work, struct fcoe_fcf_device, dev_loss_work.work);
931	struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
932
933	mutex_lock(&ctlr->lock);
934
935	/*
936	 * If the fcf is deleted or reconnected before the timer
937	 * fires the devloss queue will be flushed, but the state will
938	 * either be CONNECTED or DELETED. If that is the case we
939	 * cancel deleting the fcf.
940	 */
941	if (fcf->state != FCOE_FCF_STATE_DISCONNECTED)
942		goto out;
943
944	dev_printk(KERN_ERR, &fcf->dev,
945		   "FIP fcf connection time out: removing fcf\n");
946
947	list_del(&fcf->peers);
948	fcf->state = FCOE_FCF_STATE_DELETED;
949	fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work);
950
951out:
952	mutex_unlock(&ctlr->lock);
953}
954
955/**
956 * fcoe_fcf_device_delete() - Delete a FIP fcf
957 * @fcf: Pointer to the fcf which is to be deleted
958 *
959 * Queues the FIP fcf on the devloss workqueue
960 *
961 * Expects the ctlr_attrs mutex to be held for fcf
962 * state change.
963 */
964void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf)
965{
966	struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
967	int timeout = fcf->dev_loss_tmo;
968
969	if (fcf->state != FCOE_FCF_STATE_CONNECTED)
970		return;
971
972	fcf->state = FCOE_FCF_STATE_DISCONNECTED;
973
974	/*
975	 * FCF will only be re-connected by the LLD calling
976	 * fcoe_fcf_device_add, and it should be setting up
977	 * priv then.
978	 */
979	fcf->priv = NULL;
980
981	fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work,
982					   timeout * HZ);
983}
984EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete);
985
986/**
987 * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system
988 * @ctlr:    The fcoe_ctlr_device that will be the fcoe_fcf_device parent
989 * @new_fcf: A temporary FCF used for lookups on the current list of fcfs
990 *
991 * Expects to be called with the ctlr->lock held
992 */
993struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr,
994					    struct fcoe_fcf_device *new_fcf)
995{
996	struct fcoe_fcf_device *fcf;
997	int error = 0;
998
999	list_for_each_entry(fcf, &ctlr->fcfs, peers) {
1000		if (fcoe_fcf_device_match(new_fcf, fcf)) {
1001			if (fcf->state == FCOE_FCF_STATE_CONNECTED)
1002				return fcf;
1003
1004			fcf->state = FCOE_FCF_STATE_CONNECTED;
1005
1006			if (!cancel_delayed_work(&fcf->dev_loss_work))
1007				fcoe_ctlr_device_flush_devloss(ctlr);
1008
1009			return fcf;
1010		}
1011	}
1012
1013	fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC);
1014	if (unlikely(!fcf))
1015		goto out;
1016
1017	INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete);
1018	INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf);
1019
1020	fcf->dev.parent = &ctlr->dev;
1021	fcf->dev.bus = &fcoe_bus_type;
1022	fcf->dev.type = &fcoe_fcf_device_type;
1023	fcf->id = atomic_inc_return(&fcf_num) - 1;
1024	fcf->state = FCOE_FCF_STATE_UNKNOWN;
1025
1026	fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo;
1027
1028	dev_set_name(&fcf->dev, "fcf_%d", fcf->id);
1029
1030	fcf->fabric_name = new_fcf->fabric_name;
1031	fcf->switch_name = new_fcf->switch_name;
1032	fcf->fc_map = new_fcf->fc_map;
1033	fcf->vfid = new_fcf->vfid;
1034	memcpy(fcf->mac, new_fcf->mac, ETH_ALEN);
1035	fcf->priority = new_fcf->priority;
1036	fcf->fka_period = new_fcf->fka_period;
1037	fcf->selected = new_fcf->selected;
1038
1039	error = device_register(&fcf->dev);
1040	if (error) {
1041		put_device(&fcf->dev);
1042		goto out;
1043	}
1044
1045	fcf->state = FCOE_FCF_STATE_CONNECTED;
1046	list_add_tail(&fcf->peers, &ctlr->fcfs);
1047
1048	return fcf;
1049
1050out:
1051	return NULL;
1052}
1053EXPORT_SYMBOL_GPL(fcoe_fcf_device_add);
1054
1055int __init fcoe_sysfs_setup(void)
1056{
1057	atomic_set(&ctlr_num, 0);
1058	atomic_set(&fcf_num, 0);
1059
1060	return bus_register(&fcoe_bus_type);
1061}
1062
1063void __exit fcoe_sysfs_teardown(void)
1064{
1065	bus_unregister(&fcoe_bus_type);
1066}
1067