qlcnic_sysfs.c 33 KB

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