hns_dsaf_misc.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * Copyright (c) 2014-2015 Hisilicon Limited.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include "hns_dsaf_misc.h"
  10. #include "hns_dsaf_mac.h"
  11. #include "hns_dsaf_reg.h"
  12. #include "hns_dsaf_ppe.h"
  13. void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
  14. u16 speed, int data)
  15. {
  16. int speed_reg = 0;
  17. u8 value;
  18. if (!mac_cb) {
  19. pr_err("sfp_led_opt mac_dev is null!\n");
  20. return;
  21. }
  22. if (!mac_cb->cpld_vaddr) {
  23. dev_err(mac_cb->dev, "mac_id=%d, cpld_vaddr is null !\n",
  24. mac_cb->mac_id);
  25. return;
  26. }
  27. if (speed == MAC_SPEED_10000)
  28. speed_reg = 1;
  29. value = mac_cb->cpld_led_value;
  30. if (link_status) {
  31. dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
  32. dsaf_set_field(value, DSAF_LED_SPEED_M,
  33. DSAF_LED_SPEED_S, speed_reg);
  34. dsaf_set_bit(value, DSAF_LED_DATA_B, data);
  35. if (value != mac_cb->cpld_led_value) {
  36. dsaf_write_b(mac_cb->cpld_vaddr, value);
  37. mac_cb->cpld_led_value = value;
  38. }
  39. } else {
  40. dsaf_write_b(mac_cb->cpld_vaddr, CPLD_LED_DEFAULT_VALUE);
  41. mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
  42. }
  43. }
  44. void cpld_led_reset(struct hns_mac_cb *mac_cb)
  45. {
  46. if (!mac_cb || !mac_cb->cpld_vaddr)
  47. return;
  48. dsaf_write_b(mac_cb->cpld_vaddr, CPLD_LED_DEFAULT_VALUE);
  49. mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
  50. }
  51. int cpld_set_led_id(struct hns_mac_cb *mac_cb,
  52. enum hnae_led_state status)
  53. {
  54. switch (status) {
  55. case HNAE_LED_ACTIVE:
  56. mac_cb->cpld_led_value = dsaf_read_b(mac_cb->cpld_vaddr);
  57. dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
  58. CPLD_LED_ON_VALUE);
  59. dsaf_write_b(mac_cb->cpld_vaddr, mac_cb->cpld_led_value);
  60. return 2;
  61. case HNAE_LED_INACTIVE:
  62. dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
  63. CPLD_LED_DEFAULT_VALUE);
  64. dsaf_write_b(mac_cb->cpld_vaddr, mac_cb->cpld_led_value);
  65. break;
  66. default:
  67. break;
  68. }
  69. return 0;
  70. }
  71. #define RESET_REQ_OR_DREQ 1
  72. void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val)
  73. {
  74. u32 xbar_reg_addr;
  75. u32 nt_reg_addr;
  76. if (!val) {
  77. xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
  78. nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
  79. } else {
  80. xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
  81. nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
  82. }
  83. dsaf_write_reg(dsaf_dev->sc_base, xbar_reg_addr,
  84. RESET_REQ_OR_DREQ);
  85. dsaf_write_reg(dsaf_dev->sc_base, nt_reg_addr,
  86. RESET_REQ_OR_DREQ);
  87. }
  88. void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
  89. {
  90. u32 reg_val = 0;
  91. u32 reg_addr;
  92. if (port >= DSAF_XGE_NUM)
  93. return;
  94. reg_val |= RESET_REQ_OR_DREQ;
  95. reg_val |= 0x2082082 << port;
  96. if (val == 0)
  97. reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
  98. else
  99. reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
  100. dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val);
  101. }
  102. void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
  103. u32 port, u32 val)
  104. {
  105. u32 reg_val = 0;
  106. u32 reg_addr;
  107. if (port >= DSAF_XGE_NUM)
  108. return;
  109. reg_val |= XGMAC_TRX_CORE_SRST_M << port;
  110. if (val == 0)
  111. reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
  112. else
  113. reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
  114. dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val);
  115. }
  116. void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
  117. {
  118. u32 reg_val_1;
  119. u32 reg_val_2;
  120. if (port >= DSAF_GE_NUM)
  121. return;
  122. if (port < DSAF_SERVICE_NW_NUM) {
  123. reg_val_1 = 0x1 << port;
  124. /* there is difference between V1 and V2 in register.*/
  125. if (AE_IS_VER1(dsaf_dev->dsaf_ver))
  126. reg_val_2 = 0x1041041 << port;
  127. else
  128. reg_val_2 = 0x2082082 << port;
  129. if (val == 0) {
  130. dsaf_write_reg(dsaf_dev->sc_base,
  131. DSAF_SUB_SC_GE_RESET_REQ1_REG,
  132. reg_val_1);
  133. dsaf_write_reg(dsaf_dev->sc_base,
  134. DSAF_SUB_SC_GE_RESET_REQ0_REG,
  135. reg_val_2);
  136. } else {
  137. dsaf_write_reg(dsaf_dev->sc_base,
  138. DSAF_SUB_SC_GE_RESET_DREQ0_REG,
  139. reg_val_2);
  140. dsaf_write_reg(dsaf_dev->sc_base,
  141. DSAF_SUB_SC_GE_RESET_DREQ1_REG,
  142. reg_val_1);
  143. }
  144. } else {
  145. reg_val_1 = 0x15540 << (port - 6);
  146. reg_val_2 = 0x100 << (port - 6);
  147. if (val == 0) {
  148. dsaf_write_reg(dsaf_dev->sc_base,
  149. DSAF_SUB_SC_GE_RESET_REQ1_REG,
  150. reg_val_1);
  151. dsaf_write_reg(dsaf_dev->sc_base,
  152. DSAF_SUB_SC_PPE_RESET_REQ_REG,
  153. reg_val_2);
  154. } else {
  155. dsaf_write_reg(dsaf_dev->sc_base,
  156. DSAF_SUB_SC_GE_RESET_DREQ1_REG,
  157. reg_val_1);
  158. dsaf_write_reg(dsaf_dev->sc_base,
  159. DSAF_SUB_SC_PPE_RESET_DREQ_REG,
  160. reg_val_2);
  161. }
  162. }
  163. }
  164. void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
  165. {
  166. u32 reg_val = 0;
  167. u32 reg_addr;
  168. reg_val |= RESET_REQ_OR_DREQ << port;
  169. if (val == 0)
  170. reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
  171. else
  172. reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
  173. dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val);
  174. }
  175. void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val)
  176. {
  177. int comm_index = ppe_common->comm_index;
  178. struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev;
  179. u32 reg_val;
  180. u32 reg_addr;
  181. if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) {
  182. reg_val = RESET_REQ_OR_DREQ;
  183. if (val == 0)
  184. reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
  185. else
  186. reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
  187. } else {
  188. reg_val = 0x100 << (comm_index - 1);
  189. if (val == 0)
  190. reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
  191. else
  192. reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
  193. }
  194. dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val);
  195. }
  196. /**
  197. * hns_mac_get_sds_mode - get phy ifterface form serdes mode
  198. * @mac_cb: mac control block
  199. * retuen phy interface
  200. */
  201. phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
  202. {
  203. u32 mode;
  204. u32 reg;
  205. u32 shift;
  206. bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
  207. void __iomem *sys_ctl_vaddr = mac_cb->sys_ctl_vaddr;
  208. int mac_id = mac_cb->mac_id;
  209. phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
  210. if (is_ver1 && (mac_id >= 6 && mac_id <= 7)) {
  211. phy_if = PHY_INTERFACE_MODE_SGMII;
  212. } else if (mac_id >= 0 && mac_id <= 3) {
  213. reg = is_ver1 ? HNS_MAC_HILINK4_REG : HNS_MAC_HILINK4V2_REG;
  214. mode = dsaf_read_reg(sys_ctl_vaddr, reg);
  215. /* mac_id 0, 1, 2, 3 ---> hilink4 lane 0, 1, 2, 3 */
  216. shift = is_ver1 ? 0 : mac_id;
  217. if (dsaf_get_bit(mode, shift))
  218. phy_if = PHY_INTERFACE_MODE_XGMII;
  219. else
  220. phy_if = PHY_INTERFACE_MODE_SGMII;
  221. } else if (mac_id >= 4 && mac_id <= 7) {
  222. reg = is_ver1 ? HNS_MAC_HILINK3_REG : HNS_MAC_HILINK3V2_REG;
  223. mode = dsaf_read_reg(sys_ctl_vaddr, reg);
  224. /* mac_id 4, 5, 6, 7 ---> hilink3 lane 2, 3, 0, 1 */
  225. shift = is_ver1 ? 0 : mac_id <= 5 ? mac_id - 2 : mac_id - 6;
  226. if (dsaf_get_bit(mode, shift))
  227. phy_if = PHY_INTERFACE_MODE_XGMII;
  228. else
  229. phy_if = PHY_INTERFACE_MODE_SGMII;
  230. }
  231. return phy_if;
  232. }
  233. /**
  234. * hns_mac_config_sds_loopback - set loop back for serdes
  235. * @mac_cb: mac control block
  236. * retuen 0 == success
  237. */
  238. int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
  239. {
  240. /* port 0-3 hilink4 base is serdes_vaddr + 0x00280000
  241. * port 4-7 hilink3 base is serdes_vaddr + 0x00200000
  242. */
  243. u8 *base_addr = (u8 *)mac_cb->serdes_vaddr +
  244. (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
  245. const u8 lane_id[] = {
  246. 0, /* mac 0 -> lane 0 */
  247. 1, /* mac 1 -> lane 1 */
  248. 2, /* mac 2 -> lane 2 */
  249. 3, /* mac 3 -> lane 3 */
  250. 2, /* mac 4 -> lane 2 */
  251. 3, /* mac 5 -> lane 3 */
  252. 0, /* mac 6 -> lane 0 */
  253. 1 /* mac 7 -> lane 1 */
  254. };
  255. #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
  256. u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
  257. int sfp_prsnt;
  258. int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
  259. if (!mac_cb->phy_node) {
  260. if (ret)
  261. pr_info("please confirm sfp is present or not\n");
  262. else
  263. if (!sfp_prsnt)
  264. pr_info("no sfp in this eth\n");
  265. }
  266. dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en);
  267. return 0;
  268. }