qlcnic_sysfs.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. /*
  2. * QLogic qlcnic NIC Driver
  3. * Copyright (c) 2009-2013 QLogic Corporation
  4. *
  5. * See LICENSE.qlcnic for copyright and licensing details.
  6. */
  7. #include <linux/slab.h>
  8. #include <linux/vmalloc.h>
  9. #include <linux/interrupt.h>
  10. #include "qlcnic.h"
  11. #include "qlcnic_hw.h"
  12. #include <linux/swab.h>
  13. #include <linux/dma-mapping.h>
  14. #include <net/ip.h>
  15. #include <linux/ipv6.h>
  16. #include <linux/inetdevice.h>
  17. #include <linux/sysfs.h>
  18. #include <linux/aer.h>
  19. #include <linux/log2.h>
  20. #include <linux/sysfs.h>
  21. #define QLC_STATUS_UNSUPPORTED_CMD -2
  22. int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
  23. {
  24. return -EOPNOTSUPP;
  25. }
  26. int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
  27. {
  28. return -EOPNOTSUPP;
  29. }
  30. static ssize_t qlcnic_store_bridged_mode(struct device *dev,
  31. struct device_attribute *attr,
  32. const char *buf, size_t len)
  33. {
  34. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  35. unsigned long new;
  36. int ret = -EINVAL;
  37. if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
  38. goto err_out;
  39. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
  40. goto err_out;
  41. if (strict_strtoul(buf, 2, &new))
  42. goto err_out;
  43. if (!qlcnic_config_bridged_mode(adapter, !!new))
  44. ret = len;
  45. err_out:
  46. return ret;
  47. }
  48. static ssize_t qlcnic_show_bridged_mode(struct device *dev,
  49. struct device_attribute *attr,
  50. char *buf)
  51. {
  52. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  53. int bridged_mode = 0;
  54. if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
  55. bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
  56. return sprintf(buf, "%d\n", bridged_mode);
  57. }
  58. static ssize_t qlcnic_store_diag_mode(struct device *dev,
  59. struct device_attribute *attr,
  60. const char *buf, size_t len)
  61. {
  62. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  63. unsigned long new;
  64. if (strict_strtoul(buf, 2, &new))
  65. return -EINVAL;
  66. if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
  67. adapter->flags ^= QLCNIC_DIAG_ENABLED;
  68. return len;
  69. }
  70. static ssize_t qlcnic_show_diag_mode(struct device *dev,
  71. struct device_attribute *attr, char *buf)
  72. {
  73. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  74. return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
  75. }
  76. static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
  77. u8 *state, u8 *rate)
  78. {
  79. *rate = LSB(beacon);
  80. *state = MSB(beacon);
  81. QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
  82. if (!*state) {
  83. *rate = __QLCNIC_MAX_LED_RATE;
  84. return 0;
  85. } else if (*state > __QLCNIC_MAX_LED_STATE) {
  86. return -EINVAL;
  87. }
  88. if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
  89. return -EINVAL;
  90. return 0;
  91. }
  92. static ssize_t qlcnic_store_beacon(struct device *dev,
  93. struct device_attribute *attr,
  94. const char *buf, size_t len)
  95. {
  96. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  97. struct qlcnic_hardware_context *ahw = adapter->ahw;
  98. int err, max_sds_rings = adapter->max_sds_rings;
  99. u16 beacon;
  100. u8 b_state, b_rate;
  101. unsigned long h_beacon;
  102. if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
  103. dev_warn(dev,
  104. "LED test not supported in non privileged mode\n");
  105. return -EOPNOTSUPP;
  106. }
  107. if (qlcnic_83xx_check(adapter) &&
  108. !test_bit(__QLCNIC_RESETTING, &adapter->state)) {
  109. if (kstrtoul(buf, 2, &h_beacon))
  110. return -EINVAL;
  111. if (ahw->beacon_state == h_beacon)
  112. return len;
  113. rtnl_lock();
  114. if (!ahw->beacon_state) {
  115. if (test_and_set_bit(__QLCNIC_LED_ENABLE,
  116. &adapter->state)) {
  117. rtnl_unlock();
  118. return -EBUSY;
  119. }
  120. }
  121. if (h_beacon) {
  122. err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
  123. if (err)
  124. goto beacon_err;
  125. } else {
  126. err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
  127. if (err)
  128. goto beacon_err;
  129. }
  130. /* set the current beacon state */
  131. ahw->beacon_state = h_beacon;
  132. beacon_err:
  133. if (!ahw->beacon_state)
  134. clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
  135. rtnl_unlock();
  136. return len;
  137. }
  138. if (len != sizeof(u16))
  139. return QL_STATUS_INVALID_PARAM;
  140. memcpy(&beacon, buf, sizeof(u16));
  141. err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
  142. if (err)
  143. return err;
  144. if (adapter->ahw->beacon_state == b_state)
  145. return len;
  146. rtnl_lock();
  147. if (!adapter->ahw->beacon_state)
  148. if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
  149. rtnl_unlock();
  150. return -EBUSY;
  151. }
  152. if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
  153. err = -EIO;
  154. goto out;
  155. }
  156. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
  157. err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
  158. if (err)
  159. goto out;
  160. set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
  161. }
  162. err = qlcnic_config_led(adapter, b_state, b_rate);
  163. if (!err)
  164. err = len;
  165. else
  166. ahw->beacon_state = b_state;
  167. if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
  168. qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
  169. out:
  170. if (!adapter->ahw->beacon_state)
  171. clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
  172. rtnl_unlock();
  173. return err;
  174. }
  175. static ssize_t qlcnic_show_beacon(struct device *dev,
  176. struct device_attribute *attr, char *buf)
  177. {
  178. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  179. return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
  180. }
  181. static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
  182. loff_t offset, size_t size)
  183. {
  184. size_t crb_size = 4;
  185. if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
  186. return -EIO;
  187. if (offset < QLCNIC_PCI_CRBSPACE) {
  188. if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
  189. QLCNIC_PCI_CAMQM_END))
  190. crb_size = 8;
  191. else
  192. return -EINVAL;
  193. }
  194. if ((size != crb_size) || (offset & (crb_size-1)))
  195. return -EINVAL;
  196. return 0;
  197. }
  198. static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
  199. struct bin_attribute *attr, char *buf,
  200. loff_t offset, size_t size)
  201. {
  202. struct device *dev = container_of(kobj, struct device, kobj);
  203. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  204. int ret;
  205. ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
  206. if (ret != 0)
  207. return ret;
  208. qlcnic_read_crb(adapter, buf, offset, size);
  209. return size;
  210. }
  211. static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
  212. struct bin_attribute *attr, char *buf,
  213. loff_t offset, size_t size)
  214. {
  215. struct device *dev = container_of(kobj, struct device, kobj);
  216. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  217. int ret;
  218. ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
  219. if (ret != 0)
  220. return ret;
  221. qlcnic_write_crb(adapter, buf, offset, size);
  222. return size;
  223. }
  224. static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
  225. loff_t offset, size_t size)
  226. {
  227. if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
  228. return -EIO;
  229. if ((size != 8) || (offset & 0x7))
  230. return -EIO;
  231. return 0;
  232. }
  233. static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
  234. struct bin_attribute *attr, char *buf,
  235. loff_t offset, size_t size)
  236. {
  237. struct device *dev = container_of(kobj, struct device, kobj);
  238. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  239. u64 data;
  240. int ret;
  241. ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
  242. if (ret != 0)
  243. return ret;
  244. if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
  245. return -EIO;
  246. memcpy(buf, &data, size);
  247. return size;
  248. }
  249. static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
  250. struct bin_attribute *attr, char *buf,
  251. loff_t offset, size_t size)
  252. {
  253. struct device *dev = container_of(kobj, struct device, kobj);
  254. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  255. u64 data;
  256. int ret;
  257. ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
  258. if (ret != 0)
  259. return ret;
  260. memcpy(&data, buf, size);
  261. if (qlcnic_pci_mem_write_2M(adapter, offset, data))
  262. return -EIO;
  263. return size;
  264. }
  265. static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
  266. {
  267. int i;
  268. for (i = 0; i < adapter->ahw->act_pci_func; i++) {
  269. if (adapter->npars[i].pci_func == pci_func)
  270. return i;
  271. }
  272. return -1;
  273. }
  274. static int validate_pm_config(struct qlcnic_adapter *adapter,
  275. struct qlcnic_pm_func_cfg *pm_cfg, int count)
  276. {
  277. u8 src_pci_func, s_esw_id, d_esw_id;
  278. u8 dest_pci_func;
  279. int i, src_index, dest_index;
  280. for (i = 0; i < count; i++) {
  281. src_pci_func = pm_cfg[i].pci_func;
  282. dest_pci_func = pm_cfg[i].dest_npar;
  283. src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
  284. if (src_index < 0)
  285. return QL_STATUS_INVALID_PARAM;
  286. dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
  287. if (dest_index < 0)
  288. return QL_STATUS_INVALID_PARAM;
  289. s_esw_id = adapter->npars[src_index].phy_port;
  290. d_esw_id = adapter->npars[dest_index].phy_port;
  291. if (s_esw_id != d_esw_id)
  292. return QL_STATUS_INVALID_PARAM;
  293. }
  294. return 0;
  295. }
  296. static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
  297. struct kobject *kobj,
  298. struct bin_attribute *attr,
  299. char *buf, loff_t offset,
  300. size_t size)
  301. {
  302. struct device *dev = container_of(kobj, struct device, kobj);
  303. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  304. struct qlcnic_pm_func_cfg *pm_cfg;
  305. u32 id, action, pci_func;
  306. int count, rem, i, ret, index;
  307. count = size / sizeof(struct qlcnic_pm_func_cfg);
  308. rem = size % sizeof(struct qlcnic_pm_func_cfg);
  309. if (rem)
  310. return QL_STATUS_INVALID_PARAM;
  311. pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
  312. ret = validate_pm_config(adapter, pm_cfg, count);
  313. if (ret)
  314. return ret;
  315. for (i = 0; i < count; i++) {
  316. pci_func = pm_cfg[i].pci_func;
  317. action = !!pm_cfg[i].action;
  318. index = qlcnic_is_valid_nic_func(adapter, pci_func);
  319. if (index < 0)
  320. return QL_STATUS_INVALID_PARAM;
  321. id = adapter->npars[index].phy_port;
  322. ret = qlcnic_config_port_mirroring(adapter, id,
  323. action, pci_func);
  324. if (ret)
  325. return ret;
  326. }
  327. for (i = 0; i < count; i++) {
  328. pci_func = pm_cfg[i].pci_func;
  329. index = qlcnic_is_valid_nic_func(adapter, pci_func);
  330. id = adapter->npars[index].phy_port;
  331. adapter->npars[index].enable_pm = !!pm_cfg[i].action;
  332. adapter->npars[index].dest_npar = id;
  333. }
  334. return size;
  335. }
  336. static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
  337. struct kobject *kobj,
  338. struct bin_attribute *attr,
  339. char *buf, loff_t offset,
  340. size_t size)
  341. {
  342. struct device *dev = container_of(kobj, struct device, kobj);
  343. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  344. struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC];
  345. int i;
  346. u8 pci_func;
  347. if (size != sizeof(pm_cfg))
  348. return QL_STATUS_INVALID_PARAM;
  349. memset(&pm_cfg, 0,
  350. sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC);
  351. for (i = 0; i < adapter->ahw->act_pci_func; i++) {
  352. pci_func = adapter->npars[i].pci_func;
  353. pm_cfg[pci_func].action = adapter->npars[i].enable_pm;
  354. pm_cfg[pci_func].dest_npar = 0;
  355. pm_cfg[pci_func].pci_func = i;
  356. }
  357. memcpy(buf, &pm_cfg, size);
  358. return size;
  359. }
  360. static int validate_esw_config(struct qlcnic_adapter *adapter,
  361. struct qlcnic_esw_func_cfg *esw_cfg, int count)
  362. {
  363. u32 op_mode;
  364. u8 pci_func;
  365. int i, ret;
  366. if (qlcnic_82xx_check(adapter))
  367. op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
  368. else
  369. op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
  370. for (i = 0; i < count; i++) {
  371. pci_func = esw_cfg[i].pci_func;
  372. if (pci_func >= QLCNIC_MAX_PCI_FUNC)
  373. return QL_STATUS_INVALID_PARAM;
  374. if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
  375. if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
  376. return QL_STATUS_INVALID_PARAM;
  377. switch (esw_cfg[i].op_mode) {
  378. case QLCNIC_PORT_DEFAULTS:
  379. if (qlcnic_82xx_check(adapter)) {
  380. ret = QLC_DEV_GET_DRV(op_mode, pci_func);
  381. } else {
  382. ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
  383. pci_func);
  384. esw_cfg[i].offload_flags = 0;
  385. }
  386. if (ret != QLCNIC_NON_PRIV_FUNC) {
  387. if (esw_cfg[i].mac_anti_spoof != 0)
  388. return QL_STATUS_INVALID_PARAM;
  389. if (esw_cfg[i].mac_override != 1)
  390. return QL_STATUS_INVALID_PARAM;
  391. if (esw_cfg[i].promisc_mode != 1)
  392. return QL_STATUS_INVALID_PARAM;
  393. }
  394. break;
  395. case QLCNIC_ADD_VLAN:
  396. if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
  397. return QL_STATUS_INVALID_PARAM;
  398. if (!esw_cfg[i].op_type)
  399. return QL_STATUS_INVALID_PARAM;
  400. break;
  401. case QLCNIC_DEL_VLAN:
  402. if (!esw_cfg[i].op_type)
  403. return QL_STATUS_INVALID_PARAM;
  404. break;
  405. default:
  406. return QL_STATUS_INVALID_PARAM;
  407. }
  408. }
  409. return 0;
  410. }
  411. static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
  412. struct kobject *kobj,
  413. struct bin_attribute *attr,
  414. char *buf, loff_t offset,
  415. size_t size)
  416. {
  417. struct device *dev = container_of(kobj, struct device, kobj);
  418. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  419. struct qlcnic_esw_func_cfg *esw_cfg;
  420. struct qlcnic_npar_info *npar;
  421. int count, rem, i, ret;
  422. int index;
  423. u8 op_mode = 0, pci_func;
  424. count = size / sizeof(struct qlcnic_esw_func_cfg);
  425. rem = size % sizeof(struct qlcnic_esw_func_cfg);
  426. if (rem)
  427. return QL_STATUS_INVALID_PARAM;
  428. esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
  429. ret = validate_esw_config(adapter, esw_cfg, count);
  430. if (ret)
  431. return ret;
  432. for (i = 0; i < count; i++) {
  433. if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
  434. if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
  435. return QL_STATUS_INVALID_PARAM;
  436. if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
  437. continue;
  438. op_mode = esw_cfg[i].op_mode;
  439. qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
  440. esw_cfg[i].op_mode = op_mode;
  441. esw_cfg[i].pci_func = adapter->ahw->pci_func;
  442. switch (esw_cfg[i].op_mode) {
  443. case QLCNIC_PORT_DEFAULTS:
  444. qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
  445. break;
  446. case QLCNIC_ADD_VLAN:
  447. qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
  448. break;
  449. case QLCNIC_DEL_VLAN:
  450. esw_cfg[i].vlan_id = 0;
  451. qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
  452. break;
  453. }
  454. }
  455. if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
  456. goto out;
  457. for (i = 0; i < count; i++) {
  458. pci_func = esw_cfg[i].pci_func;
  459. index = qlcnic_is_valid_nic_func(adapter, pci_func);
  460. npar = &adapter->npars[index];
  461. switch (esw_cfg[i].op_mode) {
  462. case QLCNIC_PORT_DEFAULTS:
  463. npar->promisc_mode = esw_cfg[i].promisc_mode;
  464. npar->mac_override = esw_cfg[i].mac_override;
  465. npar->offload_flags = esw_cfg[i].offload_flags;
  466. npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
  467. npar->discard_tagged = esw_cfg[i].discard_tagged;
  468. break;
  469. case QLCNIC_ADD_VLAN:
  470. npar->pvid = esw_cfg[i].vlan_id;
  471. break;
  472. case QLCNIC_DEL_VLAN:
  473. npar->pvid = 0;
  474. break;
  475. }
  476. }
  477. out:
  478. return size;
  479. }
  480. static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
  481. struct kobject *kobj,
  482. struct bin_attribute *attr,
  483. char *buf, loff_t offset,
  484. size_t size)
  485. {
  486. struct device *dev = container_of(kobj, struct device, kobj);
  487. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  488. struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
  489. u8 i, pci_func;
  490. if (size != sizeof(esw_cfg))
  491. return QL_STATUS_INVALID_PARAM;
  492. memset(&esw_cfg, 0,
  493. sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC);
  494. for (i = 0; i < adapter->ahw->act_pci_func; i++) {
  495. pci_func = adapter->npars[i].pci_func;
  496. esw_cfg[pci_func].pci_func = pci_func;
  497. if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
  498. return QL_STATUS_INVALID_PARAM;
  499. }
  500. memcpy(buf, &esw_cfg, size);
  501. return size;
  502. }
  503. static int validate_npar_config(struct qlcnic_adapter *adapter,
  504. struct qlcnic_npar_func_cfg *np_cfg,
  505. int count)
  506. {
  507. u8 pci_func, i;
  508. for (i = 0; i < count; i++) {
  509. pci_func = np_cfg[i].pci_func;
  510. if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
  511. return QL_STATUS_INVALID_PARAM;
  512. if (!IS_VALID_BW(np_cfg[i].min_bw) ||
  513. !IS_VALID_BW(np_cfg[i].max_bw))
  514. return QL_STATUS_INVALID_PARAM;
  515. }
  516. return 0;
  517. }
  518. static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
  519. struct kobject *kobj,
  520. struct bin_attribute *attr,
  521. char *buf, loff_t offset,
  522. size_t size)
  523. {
  524. struct device *dev = container_of(kobj, struct device, kobj);
  525. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  526. struct qlcnic_info nic_info;
  527. struct qlcnic_npar_func_cfg *np_cfg;
  528. int i, count, rem, ret, index;
  529. u8 pci_func;
  530. count = size / sizeof(struct qlcnic_npar_func_cfg);
  531. rem = size % sizeof(struct qlcnic_npar_func_cfg);
  532. if (rem)
  533. return QL_STATUS_INVALID_PARAM;
  534. np_cfg = (struct qlcnic_npar_func_cfg *)buf;
  535. ret = validate_npar_config(adapter, np_cfg, count);
  536. if (ret)
  537. return ret;
  538. for (i = 0; i < count; i++) {
  539. pci_func = np_cfg[i].pci_func;
  540. memset(&nic_info, 0, sizeof(struct qlcnic_info));
  541. ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
  542. if (ret)
  543. return ret;
  544. nic_info.pci_func = pci_func;
  545. nic_info.min_tx_bw = np_cfg[i].min_bw;
  546. nic_info.max_tx_bw = np_cfg[i].max_bw;
  547. ret = qlcnic_set_nic_info(adapter, &nic_info);
  548. if (ret)
  549. return ret;
  550. index = qlcnic_is_valid_nic_func(adapter, pci_func);
  551. adapter->npars[index].min_bw = nic_info.min_tx_bw;
  552. adapter->npars[index].max_bw = nic_info.max_tx_bw;
  553. }
  554. return size;
  555. }
  556. static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
  557. struct kobject *kobj,
  558. struct bin_attribute *attr,
  559. char *buf, loff_t offset,
  560. size_t size)
  561. {
  562. struct device *dev = container_of(kobj, struct device, kobj);
  563. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  564. struct qlcnic_info nic_info;
  565. struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC];
  566. int i, ret;
  567. if (size != sizeof(np_cfg))
  568. return QL_STATUS_INVALID_PARAM;
  569. memset(&nic_info, 0, sizeof(struct qlcnic_info));
  570. memset(&np_cfg, 0,
  571. sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC);
  572. for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
  573. if (qlcnic_is_valid_nic_func(adapter, i) < 0)
  574. continue;
  575. ret = qlcnic_get_nic_info(adapter, &nic_info, i);
  576. if (ret)
  577. return ret;
  578. np_cfg[i].pci_func = i;
  579. np_cfg[i].op_mode = (u8)nic_info.op_mode;
  580. np_cfg[i].port_num = nic_info.phys_port;
  581. np_cfg[i].fw_capab = nic_info.capabilities;
  582. np_cfg[i].min_bw = nic_info.min_tx_bw;
  583. np_cfg[i].max_bw = nic_info.max_tx_bw;
  584. np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
  585. np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
  586. }
  587. memcpy(buf, &np_cfg, size);
  588. return size;
  589. }
  590. static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
  591. struct kobject *kobj,
  592. struct bin_attribute *attr,
  593. char *buf, loff_t offset,
  594. size_t size)
  595. {
  596. struct device *dev = container_of(kobj, struct device, kobj);
  597. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  598. struct qlcnic_esw_statistics port_stats;
  599. int ret;
  600. if (qlcnic_83xx_check(adapter))
  601. return QLC_STATUS_UNSUPPORTED_CMD;
  602. if (size != sizeof(struct qlcnic_esw_statistics))
  603. return QL_STATUS_INVALID_PARAM;
  604. if (offset >= QLCNIC_MAX_PCI_FUNC)
  605. return QL_STATUS_INVALID_PARAM;
  606. memset(&port_stats, 0, size);
  607. ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
  608. &port_stats.rx);
  609. if (ret)
  610. return ret;
  611. ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
  612. &port_stats.tx);
  613. if (ret)
  614. return ret;
  615. memcpy(buf, &port_stats, size);
  616. return size;
  617. }
  618. static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
  619. struct kobject *kobj,
  620. struct bin_attribute *attr,
  621. char *buf, loff_t offset,
  622. size_t size)
  623. {
  624. struct device *dev = container_of(kobj, struct device, kobj);
  625. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  626. struct qlcnic_esw_statistics esw_stats;
  627. int ret;
  628. if (qlcnic_83xx_check(adapter))
  629. return QLC_STATUS_UNSUPPORTED_CMD;
  630. if (size != sizeof(struct qlcnic_esw_statistics))
  631. return QL_STATUS_INVALID_PARAM;
  632. if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
  633. return QL_STATUS_INVALID_PARAM;
  634. memset(&esw_stats, 0, size);
  635. ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
  636. &esw_stats.rx);
  637. if (ret)
  638. return ret;
  639. ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
  640. &esw_stats.tx);
  641. if (ret)
  642. return ret;
  643. memcpy(buf, &esw_stats, size);
  644. return size;
  645. }
  646. static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
  647. struct kobject *kobj,
  648. struct bin_attribute *attr,
  649. char *buf, loff_t offset,
  650. size_t size)
  651. {
  652. struct device *dev = container_of(kobj, struct device, kobj);
  653. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  654. int ret;
  655. if (qlcnic_83xx_check(adapter))
  656. return QLC_STATUS_UNSUPPORTED_CMD;
  657. if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
  658. return QL_STATUS_INVALID_PARAM;
  659. ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
  660. QLCNIC_QUERY_RX_COUNTER);
  661. if (ret)
  662. return ret;
  663. ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
  664. QLCNIC_QUERY_TX_COUNTER);
  665. if (ret)
  666. return ret;
  667. return size;
  668. }
  669. static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
  670. struct kobject *kobj,
  671. struct bin_attribute *attr,
  672. char *buf, loff_t offset,
  673. size_t size)
  674. {
  675. struct device *dev = container_of(kobj, struct device, kobj);
  676. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  677. int ret;
  678. if (qlcnic_83xx_check(adapter))
  679. return QLC_STATUS_UNSUPPORTED_CMD;
  680. if (offset >= QLCNIC_MAX_PCI_FUNC)
  681. return QL_STATUS_INVALID_PARAM;
  682. ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
  683. QLCNIC_QUERY_RX_COUNTER);
  684. if (ret)
  685. return ret;
  686. ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
  687. QLCNIC_QUERY_TX_COUNTER);
  688. if (ret)
  689. return ret;
  690. return size;
  691. }
  692. static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
  693. struct kobject *kobj,
  694. struct bin_attribute *attr,
  695. char *buf, loff_t offset,
  696. size_t size)
  697. {
  698. struct device *dev = container_of(kobj, struct device, kobj);
  699. struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
  700. struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC];
  701. struct qlcnic_pci_info *pci_info;
  702. int i, ret;
  703. if (size != sizeof(pci_cfg))
  704. return QL_STATUS_INVALID_PARAM;
  705. pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
  706. if (!pci_info)
  707. return -ENOMEM;
  708. ret = qlcnic_get_pci_info(adapter, pci_info);
  709. if (ret) {
  710. kfree(pci_info);
  711. return ret;
  712. }
  713. memset(&pci_cfg, 0,
  714. sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC);
  715. for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
  716. pci_cfg[i].pci_func = pci_info[i].id;
  717. pci_cfg[i].func_type = pci_info[i].type;
  718. pci_cfg[i].port_num = pci_info[i].default_port;
  719. pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
  720. pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
  721. memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
  722. }
  723. memcpy(buf, &pci_cfg, size);
  724. kfree(pci_info);
  725. return size;
  726. }
  727. static struct device_attribute dev_attr_bridged_mode = {
  728. .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
  729. .show = qlcnic_show_bridged_mode,
  730. .store = qlcnic_store_bridged_mode,
  731. };
  732. static struct device_attribute dev_attr_diag_mode = {
  733. .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
  734. .show = qlcnic_show_diag_mode,
  735. .store = qlcnic_store_diag_mode,
  736. };
  737. static struct device_attribute dev_attr_beacon = {
  738. .attr = {.name = "beacon", .mode = (S_IRUGO | S_IWUSR)},
  739. .show = qlcnic_show_beacon,
  740. .store = qlcnic_store_beacon,
  741. };
  742. static struct bin_attribute bin_attr_crb = {
  743. .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
  744. .size = 0,
  745. .read = qlcnic_sysfs_read_crb,
  746. .write = qlcnic_sysfs_write_crb,
  747. };
  748. static struct bin_attribute bin_attr_mem = {
  749. .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
  750. .size = 0,
  751. .read = qlcnic_sysfs_read_mem,
  752. .write = qlcnic_sysfs_write_mem,
  753. };
  754. static struct bin_attribute bin_attr_npar_config = {
  755. .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
  756. .size = 0,
  757. .read = qlcnic_sysfs_read_npar_config,
  758. .write = qlcnic_sysfs_write_npar_config,
  759. };
  760. static struct bin_attribute bin_attr_pci_config = {
  761. .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
  762. .size = 0,
  763. .read = qlcnic_sysfs_read_pci_config,
  764. .write = NULL,
  765. };
  766. static struct bin_attribute bin_attr_port_stats = {
  767. .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
  768. .size = 0,
  769. .read = qlcnic_sysfs_get_port_stats,
  770. .write = qlcnic_sysfs_clear_port_stats,
  771. };
  772. static struct bin_attribute bin_attr_esw_stats = {
  773. .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
  774. .size = 0,
  775. .read = qlcnic_sysfs_get_esw_stats,
  776. .write = qlcnic_sysfs_clear_esw_stats,
  777. };
  778. static struct bin_attribute bin_attr_esw_config = {
  779. .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
  780. .size = 0,
  781. .read = qlcnic_sysfs_read_esw_config,
  782. .write = qlcnic_sysfs_write_esw_config,
  783. };
  784. static struct bin_attribute bin_attr_pm_config = {
  785. .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
  786. .size = 0,
  787. .read = qlcnic_sysfs_read_pm_config,
  788. .write = qlcnic_sysfs_write_pm_config,
  789. };
  790. void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
  791. {
  792. struct device *dev = &adapter->pdev->dev;
  793. if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
  794. if (device_create_file(dev, &dev_attr_bridged_mode))
  795. dev_warn(dev,
  796. "failed to create bridged_mode sysfs entry\n");
  797. }
  798. void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
  799. {
  800. struct device *dev = &adapter->pdev->dev;
  801. if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
  802. device_remove_file(dev, &dev_attr_bridged_mode);
  803. }
  804. void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
  805. {
  806. struct device *dev = &adapter->pdev->dev;
  807. if (device_create_bin_file(dev, &bin_attr_port_stats))
  808. dev_info(dev, "failed to create port stats sysfs entry");
  809. if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
  810. return;
  811. if (device_create_file(dev, &dev_attr_diag_mode))
  812. dev_info(dev, "failed to create diag_mode sysfs entry\n");
  813. if (device_create_bin_file(dev, &bin_attr_crb))
  814. dev_info(dev, "failed to create crb sysfs entry\n");
  815. if (device_create_bin_file(dev, &bin_attr_mem))
  816. dev_info(dev, "failed to create mem sysfs entry\n");
  817. if (device_create_bin_file(dev, &bin_attr_pci_config))
  818. dev_info(dev, "failed to create pci config sysfs entry");
  819. if (device_create_file(dev, &dev_attr_beacon))
  820. dev_info(dev, "failed to create beacon sysfs entry");
  821. if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
  822. return;
  823. if (device_create_bin_file(dev, &bin_attr_esw_config))
  824. dev_info(dev, "failed to create esw config sysfs entry");
  825. if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
  826. return;
  827. if (device_create_bin_file(dev, &bin_attr_npar_config))
  828. dev_info(dev, "failed to create npar config sysfs entry");
  829. if (device_create_bin_file(dev, &bin_attr_pm_config))
  830. dev_info(dev, "failed to create pm config sysfs entry");
  831. if (device_create_bin_file(dev, &bin_attr_esw_stats))
  832. dev_info(dev, "failed to create eswitch stats sysfs entry");
  833. }
  834. void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
  835. {
  836. struct device *dev = &adapter->pdev->dev;
  837. device_remove_bin_file(dev, &bin_attr_port_stats);
  838. if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
  839. return;
  840. device_remove_file(dev, &dev_attr_diag_mode);
  841. device_remove_bin_file(dev, &bin_attr_crb);
  842. device_remove_bin_file(dev, &bin_attr_mem);
  843. device_remove_bin_file(dev, &bin_attr_pci_config);
  844. device_remove_file(dev, &dev_attr_beacon);
  845. if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
  846. return;
  847. device_remove_bin_file(dev, &bin_attr_esw_config);
  848. if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
  849. return;
  850. device_remove_bin_file(dev, &bin_attr_npar_config);
  851. device_remove_bin_file(dev, &bin_attr_pm_config);
  852. device_remove_bin_file(dev, &bin_attr_esw_stats);
  853. }
  854. void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
  855. {
  856. qlcnic_create_diag_entries(adapter);
  857. }
  858. void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
  859. {
  860. qlcnic_remove_diag_entries(adapter);
  861. }
  862. void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
  863. {
  864. qlcnic_create_diag_entries(adapter);
  865. }
  866. void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
  867. {
  868. qlcnic_remove_diag_entries(adapter);
  869. }