qlcnic_sysfs.c 35 KB

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