qlcnic_ethtool.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804
  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/types.h>
  8. #include <linux/delay.h>
  9. #include <linux/pci.h>
  10. #include <linux/io.h>
  11. #include <linux/netdevice.h>
  12. #include <linux/ethtool.h>
  13. #include "qlcnic.h"
  14. struct qlcnic_stats {
  15. char stat_string[ETH_GSTRING_LEN];
  16. int sizeof_stat;
  17. int stat_offset;
  18. };
  19. #define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
  20. #define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
  21. static const u32 qlcnic_fw_dump_level[] = {
  22. 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
  23. };
  24. static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
  25. {"xmit_called", QLC_SIZEOF(stats.xmitcalled),
  26. QLC_OFF(stats.xmitcalled)},
  27. {"xmit_finished", QLC_SIZEOF(stats.xmitfinished),
  28. QLC_OFF(stats.xmitfinished)},
  29. {"rx_dropped", QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
  30. {"tx_dropped", QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
  31. {"csummed", QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
  32. {"rx_pkts", QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
  33. {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
  34. {"rx_bytes", QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
  35. {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
  36. {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
  37. {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
  38. {"xmit_on", QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
  39. {"xmit_off", QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
  40. {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
  41. QLC_OFF(stats.skb_alloc_failure)},
  42. {"null rxbuf", QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
  43. {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
  44. QLC_OFF(stats.rx_dma_map_error)},
  45. {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
  46. QLC_OFF(stats.tx_dma_map_error)},
  47. {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
  48. QLC_OFF(stats.mac_filter_limit_overrun)},
  49. {"spurious intr", QLC_SIZEOF(stats.spurious_intr),
  50. QLC_OFF(stats.spurious_intr)},
  51. };
  52. static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
  53. "rx unicast frames",
  54. "rx multicast frames",
  55. "rx broadcast frames",
  56. "rx dropped frames",
  57. "rx errors",
  58. "rx local frames",
  59. "rx numbytes",
  60. "tx unicast frames",
  61. "tx multicast frames",
  62. "tx broadcast frames",
  63. "tx dropped frames",
  64. "tx errors",
  65. "tx local frames",
  66. "tx numbytes",
  67. };
  68. static const char qlcnic_83xx_tx_stats_strings[][ETH_GSTRING_LEN] = {
  69. "ctx_tx_bytes",
  70. "ctx_tx_pkts",
  71. "ctx_tx_errors",
  72. "ctx_tx_dropped_pkts",
  73. "ctx_tx_num_buffers",
  74. };
  75. static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = {
  76. "mac_tx_frames",
  77. "mac_tx_bytes",
  78. "mac_tx_mcast_pkts",
  79. "mac_tx_bcast_pkts",
  80. "mac_tx_pause_cnt",
  81. "mac_tx_ctrl_pkt",
  82. "mac_tx_lt_64b_pkts",
  83. "mac_tx_lt_127b_pkts",
  84. "mac_tx_lt_255b_pkts",
  85. "mac_tx_lt_511b_pkts",
  86. "mac_tx_lt_1023b_pkts",
  87. "mac_tx_lt_1518b_pkts",
  88. "mac_tx_gt_1518b_pkts",
  89. "mac_rx_frames",
  90. "mac_rx_bytes",
  91. "mac_rx_mcast_pkts",
  92. "mac_rx_bcast_pkts",
  93. "mac_rx_pause_cnt",
  94. "mac_rx_ctrl_pkt",
  95. "mac_rx_lt_64b_pkts",
  96. "mac_rx_lt_127b_pkts",
  97. "mac_rx_lt_255b_pkts",
  98. "mac_rx_lt_511b_pkts",
  99. "mac_rx_lt_1023b_pkts",
  100. "mac_rx_lt_1518b_pkts",
  101. "mac_rx_gt_1518b_pkts",
  102. "mac_rx_length_error",
  103. "mac_rx_length_small",
  104. "mac_rx_length_large",
  105. "mac_rx_jabber",
  106. "mac_rx_dropped",
  107. "mac_crc_error",
  108. "mac_align_error",
  109. "eswitch_frames",
  110. "eswitch_bytes",
  111. "eswitch_multicast_frames",
  112. "eswitch_broadcast_frames",
  113. "eswitch_unicast_frames",
  114. "eswitch_error_free_frames",
  115. "eswitch_error_free_bytes",
  116. };
  117. #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
  118. static const char qlcnic_tx_ring_stats_strings[][ETH_GSTRING_LEN] = {
  119. "xmit_on",
  120. "xmit_off",
  121. "xmit_called",
  122. "xmit_finished",
  123. };
  124. static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
  125. "ctx_rx_bytes",
  126. "ctx_rx_pkts",
  127. "ctx_lro_pkt_cnt",
  128. "ctx_ip_csum_error",
  129. "ctx_rx_pkts_wo_ctx",
  130. "ctx_rx_pkts_drop_wo_sds_on_card",
  131. "ctx_rx_pkts_drop_wo_sds_on_host",
  132. "ctx_rx_osized_pkts",
  133. "ctx_rx_pkts_dropped_wo_rds",
  134. "ctx_rx_unexpected_mcast_pkts",
  135. "ctx_invalid_mac_address",
  136. "ctx_rx_rds_ring_prim_attempted",
  137. "ctx_rx_rds_ring_prim_success",
  138. "ctx_num_lro_flows_added",
  139. "ctx_num_lro_flows_removed",
  140. "ctx_num_lro_flows_active",
  141. "ctx_pkts_dropped_unknown",
  142. };
  143. static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
  144. "Register_Test_on_offline",
  145. "Link_Test_on_offline",
  146. "Interrupt_Test_offline",
  147. "Internal_Loopback_offline",
  148. "External_Loopback_offline",
  149. "EEPROM_Test_offline"
  150. };
  151. #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
  152. static inline int qlcnic_82xx_statistics(void)
  153. {
  154. return ARRAY_SIZE(qlcnic_device_gstrings_stats) +
  155. ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
  156. }
  157. static inline int qlcnic_83xx_statistics(void)
  158. {
  159. return ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
  160. ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
  161. ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
  162. }
  163. static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
  164. {
  165. if (qlcnic_82xx_check(adapter))
  166. return qlcnic_82xx_statistics();
  167. else if (qlcnic_83xx_check(adapter))
  168. return qlcnic_83xx_statistics();
  169. else
  170. return -1;
  171. }
  172. #define QLCNIC_RING_REGS_COUNT 20
  173. #define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
  174. #define QLCNIC_MAX_EEPROM_LEN 1024
  175. static const u32 diag_registers[] = {
  176. QLCNIC_CMDPEG_STATE,
  177. QLCNIC_RCVPEG_STATE,
  178. QLCNIC_FW_CAPABILITIES,
  179. QLCNIC_CRB_DRV_ACTIVE,
  180. QLCNIC_CRB_DEV_STATE,
  181. QLCNIC_CRB_DRV_STATE,
  182. QLCNIC_CRB_DRV_SCRATCH,
  183. QLCNIC_CRB_DEV_PARTITION_INFO,
  184. QLCNIC_CRB_DRV_IDC_VER,
  185. QLCNIC_PEG_ALIVE_COUNTER,
  186. QLCNIC_PEG_HALT_STATUS1,
  187. QLCNIC_PEG_HALT_STATUS2,
  188. -1
  189. };
  190. static const u32 ext_diag_registers[] = {
  191. CRB_XG_STATE_P3P,
  192. ISR_INT_STATE_REG,
  193. QLCNIC_CRB_PEG_NET_0+0x3c,
  194. QLCNIC_CRB_PEG_NET_1+0x3c,
  195. QLCNIC_CRB_PEG_NET_2+0x3c,
  196. QLCNIC_CRB_PEG_NET_4+0x3c,
  197. -1
  198. };
  199. #define QLCNIC_MGMT_API_VERSION 2
  200. #define QLCNIC_ETHTOOL_REGS_VER 3
  201. static int qlcnic_get_regs_len(struct net_device *dev)
  202. {
  203. struct qlcnic_adapter *adapter = netdev_priv(dev);
  204. u32 len;
  205. if (qlcnic_83xx_check(adapter))
  206. len = qlcnic_83xx_get_regs_len(adapter);
  207. else
  208. len = sizeof(ext_diag_registers) + sizeof(diag_registers);
  209. return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
  210. }
  211. static int qlcnic_get_eeprom_len(struct net_device *dev)
  212. {
  213. return QLCNIC_FLASH_TOTAL_SIZE;
  214. }
  215. static void
  216. qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
  217. {
  218. struct qlcnic_adapter *adapter = netdev_priv(dev);
  219. u32 fw_major, fw_minor, fw_build;
  220. fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
  221. fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
  222. fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
  223. snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
  224. "%d.%d.%d", fw_major, fw_minor, fw_build);
  225. strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
  226. sizeof(drvinfo->bus_info));
  227. strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
  228. strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
  229. sizeof(drvinfo->version));
  230. }
  231. static int
  232. qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
  233. {
  234. struct qlcnic_adapter *adapter = netdev_priv(dev);
  235. if (qlcnic_82xx_check(adapter))
  236. return qlcnic_82xx_get_settings(adapter, ecmd);
  237. else if (qlcnic_83xx_check(adapter))
  238. return qlcnic_83xx_get_settings(adapter, ecmd);
  239. return -EIO;
  240. }
  241. int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter,
  242. struct ethtool_cmd *ecmd)
  243. {
  244. struct qlcnic_hardware_context *ahw = adapter->ahw;
  245. u32 speed, reg;
  246. int check_sfp_module = 0, err = 0;
  247. u16 pcifn = ahw->pci_func;
  248. /* read which mode */
  249. if (adapter->ahw->port_type == QLCNIC_GBE) {
  250. ecmd->supported = (SUPPORTED_10baseT_Half |
  251. SUPPORTED_10baseT_Full |
  252. SUPPORTED_100baseT_Half |
  253. SUPPORTED_100baseT_Full |
  254. SUPPORTED_1000baseT_Half |
  255. SUPPORTED_1000baseT_Full);
  256. ecmd->advertising = (ADVERTISED_100baseT_Half |
  257. ADVERTISED_100baseT_Full |
  258. ADVERTISED_1000baseT_Half |
  259. ADVERTISED_1000baseT_Full);
  260. ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed);
  261. ecmd->duplex = adapter->ahw->link_duplex;
  262. ecmd->autoneg = adapter->ahw->link_autoneg;
  263. } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
  264. u32 val = 0;
  265. val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
  266. if (val == QLCNIC_PORT_MODE_802_3_AP) {
  267. ecmd->supported = SUPPORTED_1000baseT_Full;
  268. ecmd->advertising = ADVERTISED_1000baseT_Full;
  269. } else {
  270. ecmd->supported = SUPPORTED_10000baseT_Full;
  271. ecmd->advertising = ADVERTISED_10000baseT_Full;
  272. }
  273. if (netif_running(adapter->netdev) && ahw->has_link_events) {
  274. if (ahw->linkup) {
  275. reg = QLCRD32(adapter,
  276. P3P_LINK_SPEED_REG(pcifn), &err);
  277. speed = P3P_LINK_SPEED_VAL(pcifn, reg);
  278. ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
  279. }
  280. ethtool_cmd_speed_set(ecmd, ahw->link_speed);
  281. ecmd->autoneg = ahw->link_autoneg;
  282. ecmd->duplex = ahw->link_duplex;
  283. goto skip;
  284. }
  285. ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
  286. ecmd->duplex = DUPLEX_UNKNOWN;
  287. ecmd->autoneg = AUTONEG_DISABLE;
  288. } else
  289. return -EIO;
  290. skip:
  291. ecmd->phy_address = adapter->ahw->physical_port;
  292. ecmd->transceiver = XCVR_EXTERNAL;
  293. switch (adapter->ahw->board_type) {
  294. case QLCNIC_BRDTYPE_P3P_REF_QG:
  295. case QLCNIC_BRDTYPE_P3P_4_GB:
  296. case QLCNIC_BRDTYPE_P3P_4_GB_MM:
  297. ecmd->supported |= SUPPORTED_Autoneg;
  298. ecmd->advertising |= ADVERTISED_Autoneg;
  299. case QLCNIC_BRDTYPE_P3P_10G_CX4:
  300. case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
  301. case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
  302. ecmd->supported |= SUPPORTED_TP;
  303. ecmd->advertising |= ADVERTISED_TP;
  304. ecmd->port = PORT_TP;
  305. ecmd->autoneg = adapter->ahw->link_autoneg;
  306. break;
  307. case QLCNIC_BRDTYPE_P3P_IMEZ:
  308. case QLCNIC_BRDTYPE_P3P_XG_LOM:
  309. case QLCNIC_BRDTYPE_P3P_HMEZ:
  310. ecmd->supported |= SUPPORTED_MII;
  311. ecmd->advertising |= ADVERTISED_MII;
  312. ecmd->port = PORT_MII;
  313. ecmd->autoneg = AUTONEG_DISABLE;
  314. break;
  315. case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
  316. case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
  317. case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
  318. ecmd->advertising |= ADVERTISED_TP;
  319. ecmd->supported |= SUPPORTED_TP;
  320. check_sfp_module = netif_running(adapter->netdev) &&
  321. ahw->has_link_events;
  322. case QLCNIC_BRDTYPE_P3P_10G_XFP:
  323. ecmd->supported |= SUPPORTED_FIBRE;
  324. ecmd->advertising |= ADVERTISED_FIBRE;
  325. ecmd->port = PORT_FIBRE;
  326. ecmd->autoneg = AUTONEG_DISABLE;
  327. break;
  328. case QLCNIC_BRDTYPE_P3P_10G_TP:
  329. if (adapter->ahw->port_type == QLCNIC_XGBE) {
  330. ecmd->autoneg = AUTONEG_DISABLE;
  331. ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
  332. ecmd->advertising |=
  333. (ADVERTISED_FIBRE | ADVERTISED_TP);
  334. ecmd->port = PORT_FIBRE;
  335. check_sfp_module = netif_running(adapter->netdev) &&
  336. ahw->has_link_events;
  337. } else {
  338. ecmd->autoneg = AUTONEG_ENABLE;
  339. ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
  340. ecmd->advertising |=
  341. (ADVERTISED_TP | ADVERTISED_Autoneg);
  342. ecmd->port = PORT_TP;
  343. }
  344. break;
  345. default:
  346. dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
  347. adapter->ahw->board_type);
  348. return -EIO;
  349. }
  350. if (check_sfp_module) {
  351. switch (adapter->ahw->module_type) {
  352. case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
  353. case LINKEVENT_MODULE_OPTICAL_SRLR:
  354. case LINKEVENT_MODULE_OPTICAL_LRM:
  355. case LINKEVENT_MODULE_OPTICAL_SFP_1G:
  356. ecmd->port = PORT_FIBRE;
  357. break;
  358. case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
  359. case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
  360. case LINKEVENT_MODULE_TWINAX:
  361. ecmd->port = PORT_TP;
  362. break;
  363. default:
  364. ecmd->port = PORT_OTHER;
  365. }
  366. }
  367. return 0;
  368. }
  369. static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
  370. struct ethtool_cmd *ecmd)
  371. {
  372. u32 ret = 0, config = 0;
  373. /* read which mode */
  374. if (ecmd->duplex)
  375. config |= 0x1;
  376. if (ecmd->autoneg)
  377. config |= 0x2;
  378. switch (ethtool_cmd_speed(ecmd)) {
  379. case SPEED_10:
  380. config |= (0 << 8);
  381. break;
  382. case SPEED_100:
  383. config |= (1 << 8);
  384. break;
  385. case SPEED_1000:
  386. config |= (10 << 8);
  387. break;
  388. default:
  389. return -EIO;
  390. }
  391. ret = qlcnic_fw_cmd_set_port(adapter, config);
  392. if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
  393. return -EOPNOTSUPP;
  394. else if (ret)
  395. return -EIO;
  396. return ret;
  397. }
  398. static int qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
  399. {
  400. u32 ret = 0;
  401. struct qlcnic_adapter *adapter = netdev_priv(dev);
  402. if (adapter->ahw->port_type != QLCNIC_GBE)
  403. return -EOPNOTSUPP;
  404. if (qlcnic_83xx_check(adapter))
  405. ret = qlcnic_83xx_set_settings(adapter, ecmd);
  406. else
  407. ret = qlcnic_set_port_config(adapter, ecmd);
  408. if (!ret)
  409. return ret;
  410. adapter->ahw->link_speed = ethtool_cmd_speed(ecmd);
  411. adapter->ahw->link_duplex = ecmd->duplex;
  412. adapter->ahw->link_autoneg = ecmd->autoneg;
  413. if (!netif_running(dev))
  414. return 0;
  415. dev->netdev_ops->ndo_stop(dev);
  416. return dev->netdev_ops->ndo_open(dev);
  417. }
  418. static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
  419. u32 *regs_buff)
  420. {
  421. int i, j = 0, err = 0;
  422. for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
  423. regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
  424. j = 0;
  425. while (ext_diag_registers[j] != -1)
  426. regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
  427. &err);
  428. return i;
  429. }
  430. static void
  431. qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
  432. {
  433. struct qlcnic_adapter *adapter = netdev_priv(dev);
  434. struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
  435. struct qlcnic_host_sds_ring *sds_ring;
  436. u32 *regs_buff = p;
  437. int ring, i = 0;
  438. memset(p, 0, qlcnic_get_regs_len(dev));
  439. regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
  440. (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
  441. regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
  442. regs_buff[1] = QLCNIC_MGMT_API_VERSION;
  443. if (qlcnic_82xx_check(adapter))
  444. i = qlcnic_82xx_get_registers(adapter, regs_buff);
  445. else
  446. i = qlcnic_83xx_get_registers(adapter, regs_buff);
  447. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
  448. return;
  449. regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
  450. regs_buff[i++] = 1; /* No. of tx ring */
  451. regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
  452. regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
  453. regs_buff[i++] = 2; /* No. of rx ring */
  454. regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
  455. regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
  456. regs_buff[i++] = adapter->max_sds_rings;
  457. for (ring = 0; ring < adapter->max_sds_rings; ring++) {
  458. sds_ring = &(recv_ctx->sds_rings[ring]);
  459. regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
  460. }
  461. }
  462. static u32 qlcnic_test_link(struct net_device *dev)
  463. {
  464. struct qlcnic_adapter *adapter = netdev_priv(dev);
  465. int err = 0;
  466. u32 val;
  467. if (qlcnic_83xx_check(adapter)) {
  468. val = qlcnic_83xx_test_link(adapter);
  469. return (val & 1) ? 0 : 1;
  470. }
  471. val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
  472. if (err == -EIO)
  473. return err;
  474. val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
  475. return (val == XG_LINK_UP_P3P) ? 0 : 1;
  476. }
  477. static int
  478. qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
  479. u8 *bytes)
  480. {
  481. struct qlcnic_adapter *adapter = netdev_priv(dev);
  482. int offset;
  483. int ret = -1;
  484. if (qlcnic_83xx_check(adapter))
  485. return 0;
  486. if (eeprom->len == 0)
  487. return -EINVAL;
  488. eeprom->magic = (adapter->pdev)->vendor |
  489. ((adapter->pdev)->device << 16);
  490. offset = eeprom->offset;
  491. if (qlcnic_82xx_check(adapter))
  492. ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
  493. eeprom->len);
  494. if (ret < 0)
  495. return ret;
  496. return 0;
  497. }
  498. static void
  499. qlcnic_get_ringparam(struct net_device *dev,
  500. struct ethtool_ringparam *ring)
  501. {
  502. struct qlcnic_adapter *adapter = netdev_priv(dev);
  503. ring->rx_pending = adapter->num_rxd;
  504. ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
  505. ring->tx_pending = adapter->num_txd;
  506. ring->rx_max_pending = adapter->max_rxd;
  507. ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
  508. ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
  509. }
  510. static u32
  511. qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
  512. {
  513. u32 num_desc;
  514. num_desc = max(val, min);
  515. num_desc = min(num_desc, max);
  516. num_desc = roundup_pow_of_two(num_desc);
  517. if (val != num_desc) {
  518. printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
  519. qlcnic_driver_name, r_name, num_desc, val);
  520. }
  521. return num_desc;
  522. }
  523. static int
  524. qlcnic_set_ringparam(struct net_device *dev,
  525. struct ethtool_ringparam *ring)
  526. {
  527. struct qlcnic_adapter *adapter = netdev_priv(dev);
  528. u16 num_rxd, num_jumbo_rxd, num_txd;
  529. if (ring->rx_mini_pending)
  530. return -EOPNOTSUPP;
  531. num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
  532. MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
  533. num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
  534. MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
  535. "rx jumbo");
  536. num_txd = qlcnic_validate_ringparam(ring->tx_pending,
  537. MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
  538. if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
  539. num_jumbo_rxd == adapter->num_jumbo_rxd)
  540. return 0;
  541. adapter->num_rxd = num_rxd;
  542. adapter->num_jumbo_rxd = num_jumbo_rxd;
  543. adapter->num_txd = num_txd;
  544. return qlcnic_reset_context(adapter);
  545. }
  546. static void qlcnic_get_channels(struct net_device *dev,
  547. struct ethtool_channels *channel)
  548. {
  549. struct qlcnic_adapter *adapter = netdev_priv(dev);
  550. int min;
  551. min = min_t(int, adapter->ahw->max_rx_ques, num_online_cpus());
  552. channel->max_rx = rounddown_pow_of_two(min);
  553. channel->max_tx = min_t(int, QLCNIC_MAX_TX_RINGS, num_online_cpus());
  554. channel->rx_count = adapter->max_sds_rings;
  555. channel->tx_count = adapter->max_drv_tx_rings;
  556. }
  557. static int qlcnic_set_channels(struct net_device *dev,
  558. struct ethtool_channels *channel)
  559. {
  560. struct qlcnic_adapter *adapter = netdev_priv(dev);
  561. int err;
  562. int txq = 0;
  563. if (channel->other_count || channel->combined_count)
  564. return -EINVAL;
  565. if (channel->rx_count) {
  566. err = qlcnic_validate_max_rss(adapter, channel->rx_count);
  567. if (err)
  568. return err;
  569. }
  570. if (qlcnic_82xx_check(adapter) && channel->tx_count) {
  571. err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count);
  572. if (err)
  573. return err;
  574. txq = channel->tx_count;
  575. }
  576. err = qlcnic_set_max_rss(adapter, channel->rx_count, txq);
  577. netdev_info(dev, "allocated 0x%x sds rings and 0x%x tx rings\n",
  578. adapter->max_sds_rings, adapter->max_drv_tx_rings);
  579. return err;
  580. }
  581. static void
  582. qlcnic_get_pauseparam(struct net_device *netdev,
  583. struct ethtool_pauseparam *pause)
  584. {
  585. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  586. int port = adapter->ahw->physical_port;
  587. int err = 0;
  588. __u32 val;
  589. if (qlcnic_83xx_check(adapter)) {
  590. qlcnic_83xx_get_pauseparam(adapter, pause);
  591. return;
  592. }
  593. if (adapter->ahw->port_type == QLCNIC_GBE) {
  594. if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
  595. return;
  596. /* get flow control settings */
  597. val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
  598. if (err == -EIO)
  599. return;
  600. pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
  601. val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
  602. if (err == -EIO)
  603. return;
  604. switch (port) {
  605. case 0:
  606. pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
  607. break;
  608. case 1:
  609. pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
  610. break;
  611. case 2:
  612. pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
  613. break;
  614. case 3:
  615. default:
  616. pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
  617. break;
  618. }
  619. } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
  620. if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
  621. return;
  622. pause->rx_pause = 1;
  623. val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
  624. if (err == -EIO)
  625. return;
  626. if (port == 0)
  627. pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
  628. else
  629. pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
  630. } else {
  631. dev_err(&netdev->dev, "Unknown board type: %x\n",
  632. adapter->ahw->port_type);
  633. }
  634. }
  635. static int
  636. qlcnic_set_pauseparam(struct net_device *netdev,
  637. struct ethtool_pauseparam *pause)
  638. {
  639. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  640. int port = adapter->ahw->physical_port;
  641. int err = 0;
  642. __u32 val;
  643. if (qlcnic_83xx_check(adapter))
  644. return qlcnic_83xx_set_pauseparam(adapter, pause);
  645. /* read mode */
  646. if (adapter->ahw->port_type == QLCNIC_GBE) {
  647. if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
  648. return -EIO;
  649. /* set flow control */
  650. val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
  651. if (err == -EIO)
  652. return err;
  653. if (pause->rx_pause)
  654. qlcnic_gb_rx_flowctl(val);
  655. else
  656. qlcnic_gb_unset_rx_flowctl(val);
  657. QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
  658. val);
  659. QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
  660. /* set autoneg */
  661. val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
  662. if (err == -EIO)
  663. return err;
  664. switch (port) {
  665. case 0:
  666. if (pause->tx_pause)
  667. qlcnic_gb_unset_gb0_mask(val);
  668. else
  669. qlcnic_gb_set_gb0_mask(val);
  670. break;
  671. case 1:
  672. if (pause->tx_pause)
  673. qlcnic_gb_unset_gb1_mask(val);
  674. else
  675. qlcnic_gb_set_gb1_mask(val);
  676. break;
  677. case 2:
  678. if (pause->tx_pause)
  679. qlcnic_gb_unset_gb2_mask(val);
  680. else
  681. qlcnic_gb_set_gb2_mask(val);
  682. break;
  683. case 3:
  684. default:
  685. if (pause->tx_pause)
  686. qlcnic_gb_unset_gb3_mask(val);
  687. else
  688. qlcnic_gb_set_gb3_mask(val);
  689. break;
  690. }
  691. QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
  692. } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
  693. if (!pause->rx_pause || pause->autoneg)
  694. return -EOPNOTSUPP;
  695. if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
  696. return -EIO;
  697. val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
  698. if (err == -EIO)
  699. return err;
  700. if (port == 0) {
  701. if (pause->tx_pause)
  702. qlcnic_xg_unset_xg0_mask(val);
  703. else
  704. qlcnic_xg_set_xg0_mask(val);
  705. } else {
  706. if (pause->tx_pause)
  707. qlcnic_xg_unset_xg1_mask(val);
  708. else
  709. qlcnic_xg_set_xg1_mask(val);
  710. }
  711. QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
  712. } else {
  713. dev_err(&netdev->dev, "Unknown board type: %x\n",
  714. adapter->ahw->port_type);
  715. }
  716. return 0;
  717. }
  718. static int qlcnic_reg_test(struct net_device *dev)
  719. {
  720. struct qlcnic_adapter *adapter = netdev_priv(dev);
  721. u32 data_read;
  722. int err = 0;
  723. if (qlcnic_83xx_check(adapter))
  724. return qlcnic_83xx_reg_test(adapter);
  725. data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
  726. if (err == -EIO)
  727. return err;
  728. if ((data_read & 0xffff) != adapter->pdev->vendor)
  729. return 1;
  730. return 0;
  731. }
  732. static int qlcnic_eeprom_test(struct net_device *dev)
  733. {
  734. struct qlcnic_adapter *adapter = netdev_priv(dev);
  735. if (qlcnic_82xx_check(adapter))
  736. return 0;
  737. return qlcnic_83xx_flash_test(adapter);
  738. }
  739. static int qlcnic_get_sset_count(struct net_device *dev, int sset)
  740. {
  741. int len;
  742. struct qlcnic_adapter *adapter = netdev_priv(dev);
  743. switch (sset) {
  744. case ETH_SS_TEST:
  745. return QLCNIC_TEST_LEN;
  746. case ETH_SS_STATS:
  747. len = qlcnic_dev_statistics_len(adapter) + QLCNIC_STATS_LEN;
  748. if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
  749. qlcnic_83xx_check(adapter))
  750. return len;
  751. return qlcnic_82xx_statistics();
  752. default:
  753. return -EOPNOTSUPP;
  754. }
  755. }
  756. static int qlcnic_irq_test(struct net_device *netdev)
  757. {
  758. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  759. struct qlcnic_hardware_context *ahw = adapter->ahw;
  760. struct qlcnic_cmd_args cmd;
  761. int ret, max_sds_rings = adapter->max_sds_rings;
  762. if (qlcnic_83xx_check(adapter))
  763. return qlcnic_83xx_interrupt_test(netdev);
  764. if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
  765. return -EIO;
  766. ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
  767. if (ret)
  768. goto clear_diag_irq;
  769. ahw->diag_cnt = 0;
  770. ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
  771. if (ret)
  772. goto free_diag_res;
  773. cmd.req.arg[1] = ahw->pci_func;
  774. ret = qlcnic_issue_cmd(adapter, &cmd);
  775. if (ret)
  776. goto done;
  777. usleep_range(1000, 12000);
  778. ret = !ahw->diag_cnt;
  779. done:
  780. qlcnic_free_mbx_args(&cmd);
  781. free_diag_res:
  782. qlcnic_diag_free_res(netdev, max_sds_rings);
  783. clear_diag_irq:
  784. adapter->max_sds_rings = max_sds_rings;
  785. clear_bit(__QLCNIC_RESETTING, &adapter->state);
  786. return ret;
  787. }
  788. #define QLCNIC_ILB_PKT_SIZE 64
  789. #define QLCNIC_NUM_ILB_PKT 16
  790. #define QLCNIC_ILB_MAX_RCV_LOOP 10
  791. #define QLCNIC_LB_PKT_POLL_DELAY_MSEC 1
  792. #define QLCNIC_LB_PKT_POLL_COUNT 20
  793. static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
  794. {
  795. unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
  796. memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
  797. memcpy(data, mac, ETH_ALEN);
  798. memcpy(data + ETH_ALEN, mac, ETH_ALEN);
  799. memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
  800. }
  801. int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
  802. {
  803. unsigned char buff[QLCNIC_ILB_PKT_SIZE];
  804. qlcnic_create_loopback_buff(buff, mac);
  805. return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
  806. }
  807. int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
  808. {
  809. struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
  810. struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
  811. struct sk_buff *skb;
  812. int i, loop, cnt = 0;
  813. for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
  814. skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
  815. qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
  816. skb_put(skb, QLCNIC_ILB_PKT_SIZE);
  817. adapter->ahw->diag_cnt = 0;
  818. qlcnic_xmit_frame(skb, adapter->netdev);
  819. loop = 0;
  820. do {
  821. msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
  822. qlcnic_process_rcv_ring_diag(sds_ring);
  823. if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
  824. break;
  825. } while (!adapter->ahw->diag_cnt);
  826. dev_kfree_skb_any(skb);
  827. if (!adapter->ahw->diag_cnt)
  828. dev_warn(&adapter->pdev->dev,
  829. "LB Test: packet #%d was not received\n",
  830. i + 1);
  831. else
  832. cnt++;
  833. }
  834. if (cnt != i) {
  835. dev_err(&adapter->pdev->dev,
  836. "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
  837. if (mode != QLCNIC_ILB_MODE)
  838. dev_warn(&adapter->pdev->dev,
  839. "WARNING: Please check loopback cable\n");
  840. return -1;
  841. }
  842. return 0;
  843. }
  844. int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
  845. {
  846. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  847. int max_drv_tx_rings = adapter->max_drv_tx_rings;
  848. int max_sds_rings = adapter->max_sds_rings;
  849. struct qlcnic_host_sds_ring *sds_ring;
  850. struct qlcnic_hardware_context *ahw = adapter->ahw;
  851. int loop = 0;
  852. int ret;
  853. if (qlcnic_83xx_check(adapter))
  854. return qlcnic_83xx_loopback_test(netdev, mode);
  855. if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
  856. dev_info(&adapter->pdev->dev,
  857. "Firmware do not support loopback test\n");
  858. return -EOPNOTSUPP;
  859. }
  860. dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
  861. mode == QLCNIC_ILB_MODE ? "internal" : "external");
  862. if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
  863. dev_warn(&adapter->pdev->dev,
  864. "Loopback test not supported in nonprivileged mode\n");
  865. return 0;
  866. }
  867. if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
  868. return -EBUSY;
  869. ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
  870. if (ret)
  871. goto clear_it;
  872. sds_ring = &adapter->recv_ctx->sds_rings[0];
  873. ret = qlcnic_set_lb_mode(adapter, mode);
  874. if (ret)
  875. goto free_res;
  876. ahw->diag_cnt = 0;
  877. do {
  878. msleep(500);
  879. qlcnic_process_rcv_ring_diag(sds_ring);
  880. if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
  881. netdev_info(netdev,
  882. "Firmware didn't sent link up event to loopback request\n");
  883. ret = -ETIMEDOUT;
  884. goto free_res;
  885. } else if (adapter->ahw->diag_cnt) {
  886. ret = adapter->ahw->diag_cnt;
  887. goto free_res;
  888. }
  889. } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
  890. ret = qlcnic_do_lb_test(adapter, mode);
  891. qlcnic_clear_lb_mode(adapter, mode);
  892. free_res:
  893. qlcnic_diag_free_res(netdev, max_sds_rings);
  894. clear_it:
  895. adapter->max_sds_rings = max_sds_rings;
  896. adapter->max_drv_tx_rings = max_drv_tx_rings;
  897. clear_bit(__QLCNIC_RESETTING, &adapter->state);
  898. return ret;
  899. }
  900. static void
  901. qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
  902. u64 *data)
  903. {
  904. memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
  905. data[0] = qlcnic_reg_test(dev);
  906. if (data[0])
  907. eth_test->flags |= ETH_TEST_FL_FAILED;
  908. data[1] = (u64) qlcnic_test_link(dev);
  909. if (data[1])
  910. eth_test->flags |= ETH_TEST_FL_FAILED;
  911. if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
  912. data[2] = qlcnic_irq_test(dev);
  913. if (data[2])
  914. eth_test->flags |= ETH_TEST_FL_FAILED;
  915. data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
  916. if (data[3])
  917. eth_test->flags |= ETH_TEST_FL_FAILED;
  918. if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
  919. data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
  920. if (data[4])
  921. eth_test->flags |= ETH_TEST_FL_FAILED;
  922. eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
  923. }
  924. data[5] = qlcnic_eeprom_test(dev);
  925. if (data[5])
  926. eth_test->flags |= ETH_TEST_FL_FAILED;
  927. }
  928. }
  929. static void
  930. qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
  931. {
  932. struct qlcnic_adapter *adapter = netdev_priv(dev);
  933. int index, i, num_stats;
  934. switch (stringset) {
  935. case ETH_SS_TEST:
  936. memcpy(data, *qlcnic_gstrings_test,
  937. QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
  938. break;
  939. case ETH_SS_STATS:
  940. num_stats = ARRAY_SIZE(qlcnic_tx_ring_stats_strings);
  941. for (i = 0; i < adapter->max_drv_tx_rings; i++) {
  942. for (index = 0; index < num_stats; index++) {
  943. sprintf(data, "tx_ring_%d %s", i,
  944. qlcnic_tx_ring_stats_strings[index]);
  945. data += ETH_GSTRING_LEN;
  946. }
  947. }
  948. for (index = 0; index < QLCNIC_STATS_LEN; index++) {
  949. memcpy(data + index * ETH_GSTRING_LEN,
  950. qlcnic_gstrings_stats[index].stat_string,
  951. ETH_GSTRING_LEN);
  952. }
  953. if (qlcnic_83xx_check(adapter)) {
  954. num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
  955. for (i = 0; i < num_stats; i++, index++)
  956. memcpy(data + index * ETH_GSTRING_LEN,
  957. qlcnic_83xx_tx_stats_strings[i],
  958. ETH_GSTRING_LEN);
  959. num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
  960. for (i = 0; i < num_stats; i++, index++)
  961. memcpy(data + index * ETH_GSTRING_LEN,
  962. qlcnic_83xx_mac_stats_strings[i],
  963. ETH_GSTRING_LEN);
  964. num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
  965. for (i = 0; i < num_stats; i++, index++)
  966. memcpy(data + index * ETH_GSTRING_LEN,
  967. qlcnic_83xx_rx_stats_strings[i],
  968. ETH_GSTRING_LEN);
  969. return;
  970. } else {
  971. num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
  972. for (i = 0; i < num_stats; i++, index++)
  973. memcpy(data + index * ETH_GSTRING_LEN,
  974. qlcnic_83xx_mac_stats_strings[i],
  975. ETH_GSTRING_LEN);
  976. }
  977. if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
  978. return;
  979. num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
  980. for (i = 0; i < num_stats; index++, i++) {
  981. memcpy(data + index * ETH_GSTRING_LEN,
  982. qlcnic_device_gstrings_stats[i],
  983. ETH_GSTRING_LEN);
  984. }
  985. }
  986. }
  987. static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
  988. {
  989. if (type == QLCNIC_MAC_STATS) {
  990. struct qlcnic_mac_statistics *mac_stats =
  991. (struct qlcnic_mac_statistics *)stats;
  992. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
  993. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
  994. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
  995. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
  996. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
  997. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
  998. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
  999. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
  1000. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
  1001. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
  1002. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
  1003. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
  1004. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
  1005. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
  1006. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
  1007. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
  1008. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
  1009. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
  1010. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
  1011. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
  1012. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
  1013. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
  1014. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
  1015. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
  1016. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
  1017. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
  1018. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
  1019. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
  1020. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
  1021. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
  1022. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
  1023. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
  1024. *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
  1025. } else if (type == QLCNIC_ESW_STATS) {
  1026. struct __qlcnic_esw_statistics *esw_stats =
  1027. (struct __qlcnic_esw_statistics *)stats;
  1028. *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
  1029. *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
  1030. *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
  1031. *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
  1032. *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
  1033. *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
  1034. *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
  1035. }
  1036. return data;
  1037. }
  1038. static void qlcnic_get_ethtool_stats(struct net_device *dev,
  1039. struct ethtool_stats *stats, u64 *data)
  1040. {
  1041. struct qlcnic_adapter *adapter = netdev_priv(dev);
  1042. struct qlcnic_host_tx_ring *tx_ring;
  1043. struct qlcnic_esw_statistics port_stats;
  1044. struct qlcnic_mac_statistics mac_stats;
  1045. int index, ret, length, size, ring;
  1046. char *p;
  1047. memset(data, 0, adapter->max_drv_tx_rings * 4 * sizeof(u64));
  1048. for (ring = 0, index = 0; ring < adapter->max_drv_tx_rings; ring++) {
  1049. if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
  1050. tx_ring = &adapter->tx_ring[ring];
  1051. *data++ = tx_ring->xmit_on;
  1052. *data++ = tx_ring->xmit_off;
  1053. *data++ = tx_ring->xmit_called;
  1054. *data++ = tx_ring->xmit_finished;
  1055. }
  1056. }
  1057. memset(data, 0, stats->n_stats * sizeof(u64));
  1058. length = QLCNIC_STATS_LEN;
  1059. for (index = 0; index < length; index++) {
  1060. p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
  1061. size = qlcnic_gstrings_stats[index].sizeof_stat;
  1062. *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
  1063. }
  1064. if (qlcnic_83xx_check(adapter)) {
  1065. if (adapter->ahw->linkup)
  1066. qlcnic_83xx_get_stats(adapter, data);
  1067. return;
  1068. } else {
  1069. /* Retrieve MAC statistics from firmware */
  1070. memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
  1071. qlcnic_get_mac_stats(adapter, &mac_stats);
  1072. data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
  1073. }
  1074. if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
  1075. return;
  1076. memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
  1077. ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
  1078. QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
  1079. if (ret)
  1080. return;
  1081. data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
  1082. ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
  1083. QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
  1084. if (ret)
  1085. return;
  1086. qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
  1087. }
  1088. static int qlcnic_set_led(struct net_device *dev,
  1089. enum ethtool_phys_id_state state)
  1090. {
  1091. struct qlcnic_adapter *adapter = netdev_priv(dev);
  1092. int max_sds_rings = adapter->max_sds_rings;
  1093. int err = -EIO, active = 1;
  1094. if (qlcnic_83xx_check(adapter))
  1095. return qlcnic_83xx_set_led(dev, state);
  1096. if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
  1097. netdev_warn(dev, "LED test not supported for non "
  1098. "privilege function\n");
  1099. return -EOPNOTSUPP;
  1100. }
  1101. switch (state) {
  1102. case ETHTOOL_ID_ACTIVE:
  1103. if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
  1104. return -EBUSY;
  1105. if (test_bit(__QLCNIC_RESETTING, &adapter->state))
  1106. break;
  1107. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
  1108. if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
  1109. break;
  1110. set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
  1111. }
  1112. if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
  1113. err = 0;
  1114. break;
  1115. }
  1116. dev_err(&adapter->pdev->dev,
  1117. "Failed to set LED blink state.\n");
  1118. break;
  1119. case ETHTOOL_ID_INACTIVE:
  1120. active = 0;
  1121. if (test_bit(__QLCNIC_RESETTING, &adapter->state))
  1122. break;
  1123. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
  1124. if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
  1125. break;
  1126. set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
  1127. }
  1128. if (adapter->nic_ops->config_led(adapter, 0, 0xf))
  1129. dev_err(&adapter->pdev->dev,
  1130. "Failed to reset LED blink state.\n");
  1131. break;
  1132. default:
  1133. return -EINVAL;
  1134. }
  1135. if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
  1136. qlcnic_diag_free_res(dev, max_sds_rings);
  1137. if (!active || err)
  1138. clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
  1139. return err;
  1140. }
  1141. static void
  1142. qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
  1143. {
  1144. struct qlcnic_adapter *adapter = netdev_priv(dev);
  1145. u32 wol_cfg;
  1146. int err = 0;
  1147. if (qlcnic_83xx_check(adapter))
  1148. return;
  1149. wol->supported = 0;
  1150. wol->wolopts = 0;
  1151. wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
  1152. if (err == -EIO)
  1153. return;
  1154. if (wol_cfg & (1UL << adapter->portnum))
  1155. wol->supported |= WAKE_MAGIC;
  1156. wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
  1157. if (wol_cfg & (1UL << adapter->portnum))
  1158. wol->wolopts |= WAKE_MAGIC;
  1159. }
  1160. static int
  1161. qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
  1162. {
  1163. struct qlcnic_adapter *adapter = netdev_priv(dev);
  1164. u32 wol_cfg;
  1165. int err = 0;
  1166. if (qlcnic_83xx_check(adapter))
  1167. return -EOPNOTSUPP;
  1168. if (wol->wolopts & ~WAKE_MAGIC)
  1169. return -EINVAL;
  1170. wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
  1171. if (err == -EIO)
  1172. return err;
  1173. if (!(wol_cfg & (1 << adapter->portnum)))
  1174. return -EOPNOTSUPP;
  1175. wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
  1176. if (err == -EIO)
  1177. return err;
  1178. if (wol->wolopts & WAKE_MAGIC)
  1179. wol_cfg |= 1UL << adapter->portnum;
  1180. else
  1181. wol_cfg &= ~(1UL << adapter->portnum);
  1182. QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
  1183. return 0;
  1184. }
  1185. /*
  1186. * Set the coalescing parameters. Currently only normal is supported.
  1187. * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
  1188. * firmware coalescing to default.
  1189. */
  1190. static int qlcnic_set_intr_coalesce(struct net_device *netdev,
  1191. struct ethtool_coalesce *ethcoal)
  1192. {
  1193. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1194. struct qlcnic_nic_intr_coalesce *coal;
  1195. u32 rx_coalesce_usecs, rx_max_frames;
  1196. u32 tx_coalesce_usecs, tx_max_frames;
  1197. if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
  1198. return -EINVAL;
  1199. /*
  1200. * Return Error if unsupported values or
  1201. * unsupported parameters are set.
  1202. */
  1203. if (ethcoal->rx_coalesce_usecs > 0xffff ||
  1204. ethcoal->rx_max_coalesced_frames > 0xffff ||
  1205. ethcoal->tx_coalesce_usecs > 0xffff ||
  1206. ethcoal->tx_max_coalesced_frames > 0xffff ||
  1207. ethcoal->rx_coalesce_usecs_irq ||
  1208. ethcoal->rx_max_coalesced_frames_irq ||
  1209. ethcoal->tx_coalesce_usecs_irq ||
  1210. ethcoal->tx_max_coalesced_frames_irq ||
  1211. ethcoal->stats_block_coalesce_usecs ||
  1212. ethcoal->use_adaptive_rx_coalesce ||
  1213. ethcoal->use_adaptive_tx_coalesce ||
  1214. ethcoal->pkt_rate_low ||
  1215. ethcoal->rx_coalesce_usecs_low ||
  1216. ethcoal->rx_max_coalesced_frames_low ||
  1217. ethcoal->tx_coalesce_usecs_low ||
  1218. ethcoal->tx_max_coalesced_frames_low ||
  1219. ethcoal->pkt_rate_high ||
  1220. ethcoal->rx_coalesce_usecs_high ||
  1221. ethcoal->rx_max_coalesced_frames_high ||
  1222. ethcoal->tx_coalesce_usecs_high ||
  1223. ethcoal->tx_max_coalesced_frames_high)
  1224. return -EINVAL;
  1225. coal = &adapter->ahw->coal;
  1226. if (qlcnic_83xx_check(adapter)) {
  1227. if (!ethcoal->tx_coalesce_usecs ||
  1228. !ethcoal->tx_max_coalesced_frames ||
  1229. !ethcoal->rx_coalesce_usecs ||
  1230. !ethcoal->rx_max_coalesced_frames) {
  1231. coal->flag = QLCNIC_INTR_DEFAULT;
  1232. coal->type = QLCNIC_INTR_COAL_TYPE_RX;
  1233. coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
  1234. coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
  1235. coal->tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
  1236. coal->tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
  1237. } else {
  1238. tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
  1239. tx_max_frames = ethcoal->tx_max_coalesced_frames;
  1240. rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
  1241. rx_max_frames = ethcoal->rx_max_coalesced_frames;
  1242. coal->flag = 0;
  1243. if ((coal->rx_time_us == rx_coalesce_usecs) &&
  1244. (coal->rx_packets == rx_max_frames)) {
  1245. coal->type = QLCNIC_INTR_COAL_TYPE_TX;
  1246. coal->tx_time_us = tx_coalesce_usecs;
  1247. coal->tx_packets = tx_max_frames;
  1248. } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
  1249. (coal->tx_packets == tx_max_frames)) {
  1250. coal->type = QLCNIC_INTR_COAL_TYPE_RX;
  1251. coal->rx_time_us = rx_coalesce_usecs;
  1252. coal->rx_packets = rx_max_frames;
  1253. } else {
  1254. coal->type = QLCNIC_INTR_COAL_TYPE_RX;
  1255. coal->rx_time_us = rx_coalesce_usecs;
  1256. coal->rx_packets = rx_max_frames;
  1257. coal->tx_time_us = tx_coalesce_usecs;
  1258. coal->tx_packets = tx_max_frames;
  1259. }
  1260. }
  1261. } else {
  1262. if (!ethcoal->rx_coalesce_usecs ||
  1263. !ethcoal->rx_max_coalesced_frames) {
  1264. coal->flag = QLCNIC_INTR_DEFAULT;
  1265. coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
  1266. coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
  1267. } else {
  1268. coal->flag = 0;
  1269. coal->rx_time_us = ethcoal->rx_coalesce_usecs;
  1270. coal->rx_packets = ethcoal->rx_max_coalesced_frames;
  1271. }
  1272. }
  1273. qlcnic_config_intr_coalesce(adapter);
  1274. return 0;
  1275. }
  1276. static int qlcnic_get_intr_coalesce(struct net_device *netdev,
  1277. struct ethtool_coalesce *ethcoal)
  1278. {
  1279. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1280. if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
  1281. return -EINVAL;
  1282. ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
  1283. ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
  1284. ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
  1285. ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
  1286. return 0;
  1287. }
  1288. static u32 qlcnic_get_msglevel(struct net_device *netdev)
  1289. {
  1290. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1291. return adapter->ahw->msg_enable;
  1292. }
  1293. static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
  1294. {
  1295. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1296. adapter->ahw->msg_enable = msglvl;
  1297. }
  1298. int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
  1299. {
  1300. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1301. u32 val;
  1302. if (qlcnic_84xx_check(adapter)) {
  1303. if (qlcnic_83xx_lock_driver(adapter))
  1304. return -EBUSY;
  1305. val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
  1306. val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
  1307. QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
  1308. qlcnic_83xx_unlock_driver(adapter);
  1309. } else {
  1310. fw_dump->enable = true;
  1311. }
  1312. dev_info(&adapter->pdev->dev, "FW dump enabled\n");
  1313. return 0;
  1314. }
  1315. static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
  1316. {
  1317. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1318. u32 val;
  1319. if (qlcnic_84xx_check(adapter)) {
  1320. if (qlcnic_83xx_lock_driver(adapter))
  1321. return -EBUSY;
  1322. val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
  1323. val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
  1324. QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
  1325. qlcnic_83xx_unlock_driver(adapter);
  1326. } else {
  1327. fw_dump->enable = false;
  1328. }
  1329. dev_info(&adapter->pdev->dev, "FW dump disabled\n");
  1330. return 0;
  1331. }
  1332. bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
  1333. {
  1334. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1335. bool state;
  1336. u32 val;
  1337. if (qlcnic_84xx_check(adapter)) {
  1338. val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
  1339. state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
  1340. } else {
  1341. state = fw_dump->enable;
  1342. }
  1343. return state;
  1344. }
  1345. static int
  1346. qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
  1347. {
  1348. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1349. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1350. if (!fw_dump->tmpl_hdr) {
  1351. netdev_err(adapter->netdev, "FW Dump not supported\n");
  1352. return -ENOTSUPP;
  1353. }
  1354. if (fw_dump->clr)
  1355. dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
  1356. else
  1357. dump->len = 0;
  1358. if (!qlcnic_check_fw_dump_state(adapter))
  1359. dump->flag = ETH_FW_DUMP_DISABLE;
  1360. else
  1361. dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
  1362. dump->version = adapter->fw_version;
  1363. return 0;
  1364. }
  1365. static int
  1366. qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
  1367. void *buffer)
  1368. {
  1369. int i, copy_sz;
  1370. u32 *hdr_ptr;
  1371. __le32 *data;
  1372. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1373. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1374. if (!fw_dump->tmpl_hdr) {
  1375. netdev_err(netdev, "FW Dump not supported\n");
  1376. return -ENOTSUPP;
  1377. }
  1378. if (!fw_dump->clr) {
  1379. netdev_info(netdev, "Dump not available\n");
  1380. return -EINVAL;
  1381. }
  1382. /* Copy template header first */
  1383. copy_sz = fw_dump->tmpl_hdr->size;
  1384. hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
  1385. data = buffer;
  1386. for (i = 0; i < copy_sz/sizeof(u32); i++)
  1387. *data++ = cpu_to_le32(*hdr_ptr++);
  1388. /* Copy captured dump data */
  1389. memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
  1390. dump->len = copy_sz + fw_dump->size;
  1391. dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
  1392. /* Free dump area once data has been captured */
  1393. vfree(fw_dump->data);
  1394. fw_dump->data = NULL;
  1395. fw_dump->clr = 0;
  1396. netdev_info(netdev, "extracted the FW dump Successfully\n");
  1397. return 0;
  1398. }
  1399. static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
  1400. {
  1401. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1402. struct net_device *netdev = adapter->netdev;
  1403. if (!qlcnic_check_fw_dump_state(adapter)) {
  1404. netdev_info(netdev,
  1405. "Can not change driver mask to 0x%x. FW dump not enabled\n",
  1406. mask);
  1407. return -EOPNOTSUPP;
  1408. }
  1409. fw_dump->tmpl_hdr->drv_cap_mask = mask;
  1410. netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
  1411. return 0;
  1412. }
  1413. static int
  1414. qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
  1415. {
  1416. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  1417. struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
  1418. bool valid_mask = false;
  1419. int i, ret = 0;
  1420. u32 state;
  1421. switch (val->flag) {
  1422. case QLCNIC_FORCE_FW_DUMP_KEY:
  1423. if (!fw_dump->tmpl_hdr) {
  1424. netdev_err(netdev, "FW dump not supported\n");
  1425. ret = -EOPNOTSUPP;
  1426. break;
  1427. }
  1428. if (!qlcnic_check_fw_dump_state(adapter)) {
  1429. netdev_info(netdev, "FW dump not enabled\n");
  1430. ret = -EOPNOTSUPP;
  1431. break;
  1432. }
  1433. if (fw_dump->clr) {
  1434. netdev_info(netdev,
  1435. "Previous dump not cleared, not forcing dump\n");
  1436. break;
  1437. }
  1438. netdev_info(netdev, "Forcing a FW dump\n");
  1439. qlcnic_dev_request_reset(adapter, val->flag);
  1440. break;
  1441. case QLCNIC_DISABLE_FW_DUMP:
  1442. if (!fw_dump->tmpl_hdr) {
  1443. netdev_err(netdev, "FW dump not supported\n");
  1444. ret = -EOPNOTSUPP;
  1445. break;
  1446. }
  1447. ret = qlcnic_disable_fw_dump_state(adapter);
  1448. break;
  1449. case QLCNIC_ENABLE_FW_DUMP:
  1450. if (!fw_dump->tmpl_hdr) {
  1451. netdev_err(netdev, "FW dump not supported\n");
  1452. ret = -EOPNOTSUPP;
  1453. break;
  1454. }
  1455. ret = qlcnic_enable_fw_dump_state(adapter);
  1456. break;
  1457. case QLCNIC_FORCE_FW_RESET:
  1458. netdev_info(netdev, "Forcing a FW reset\n");
  1459. qlcnic_dev_request_reset(adapter, val->flag);
  1460. adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
  1461. break;
  1462. case QLCNIC_SET_QUIESCENT:
  1463. case QLCNIC_RESET_QUIESCENT:
  1464. state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
  1465. if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
  1466. netdev_info(netdev, "Device in FAILED state\n");
  1467. break;
  1468. default:
  1469. if (!fw_dump->tmpl_hdr) {
  1470. netdev_err(netdev, "FW dump not supported\n");
  1471. ret = -EOPNOTSUPP;
  1472. break;
  1473. }
  1474. for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
  1475. if (val->flag == qlcnic_fw_dump_level[i]) {
  1476. valid_mask = true;
  1477. break;
  1478. }
  1479. }
  1480. if (valid_mask) {
  1481. ret = qlcnic_set_dump_mask(adapter, val->flag);
  1482. } else {
  1483. netdev_info(netdev, "Invalid dump level: 0x%x\n",
  1484. val->flag);
  1485. ret = -EINVAL;
  1486. }
  1487. }
  1488. return ret;
  1489. }
  1490. const struct ethtool_ops qlcnic_ethtool_ops = {
  1491. .get_settings = qlcnic_get_settings,
  1492. .set_settings = qlcnic_set_settings,
  1493. .get_drvinfo = qlcnic_get_drvinfo,
  1494. .get_regs_len = qlcnic_get_regs_len,
  1495. .get_regs = qlcnic_get_regs,
  1496. .get_link = ethtool_op_get_link,
  1497. .get_eeprom_len = qlcnic_get_eeprom_len,
  1498. .get_eeprom = qlcnic_get_eeprom,
  1499. .get_ringparam = qlcnic_get_ringparam,
  1500. .set_ringparam = qlcnic_set_ringparam,
  1501. .get_channels = qlcnic_get_channels,
  1502. .set_channels = qlcnic_set_channels,
  1503. .get_pauseparam = qlcnic_get_pauseparam,
  1504. .set_pauseparam = qlcnic_set_pauseparam,
  1505. .get_wol = qlcnic_get_wol,
  1506. .set_wol = qlcnic_set_wol,
  1507. .self_test = qlcnic_diag_test,
  1508. .get_strings = qlcnic_get_strings,
  1509. .get_ethtool_stats = qlcnic_get_ethtool_stats,
  1510. .get_sset_count = qlcnic_get_sset_count,
  1511. .get_coalesce = qlcnic_get_intr_coalesce,
  1512. .set_coalesce = qlcnic_set_intr_coalesce,
  1513. .set_phys_id = qlcnic_set_led,
  1514. .set_msglevel = qlcnic_set_msglevel,
  1515. .get_msglevel = qlcnic_get_msglevel,
  1516. .get_dump_flag = qlcnic_get_dump_flag,
  1517. .get_dump_data = qlcnic_get_dump_data,
  1518. .set_dump = qlcnic_set_dump,
  1519. };
  1520. const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
  1521. .get_settings = qlcnic_get_settings,
  1522. .get_drvinfo = qlcnic_get_drvinfo,
  1523. .get_regs_len = qlcnic_get_regs_len,
  1524. .get_regs = qlcnic_get_regs,
  1525. .get_link = ethtool_op_get_link,
  1526. .get_eeprom_len = qlcnic_get_eeprom_len,
  1527. .get_eeprom = qlcnic_get_eeprom,
  1528. .get_ringparam = qlcnic_get_ringparam,
  1529. .set_ringparam = qlcnic_set_ringparam,
  1530. .get_channels = qlcnic_get_channels,
  1531. .get_pauseparam = qlcnic_get_pauseparam,
  1532. .get_wol = qlcnic_get_wol,
  1533. .get_strings = qlcnic_get_strings,
  1534. .get_ethtool_stats = qlcnic_get_ethtool_stats,
  1535. .get_sset_count = qlcnic_get_sset_count,
  1536. .get_coalesce = qlcnic_get_intr_coalesce,
  1537. .set_coalesce = qlcnic_set_intr_coalesce,
  1538. .set_msglevel = qlcnic_set_msglevel,
  1539. .get_msglevel = qlcnic_get_msglevel,
  1540. };
  1541. const struct ethtool_ops qlcnic_ethtool_failed_ops = {
  1542. .get_settings = qlcnic_get_settings,
  1543. .get_drvinfo = qlcnic_get_drvinfo,
  1544. .set_msglevel = qlcnic_set_msglevel,
  1545. .get_msglevel = qlcnic_get_msglevel,
  1546. .set_dump = qlcnic_set_dump,
  1547. };