fcoe_sysfs.c 28 KB

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