netxen_nic_niu.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (C) 2003 - 2009 NetXen, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  18. * MA 02111-1307, USA.
  19. *
  20. * The full GNU General Public License is included in this distribution
  21. * in the file called LICENSE.
  22. *
  23. * Contact Information:
  24. * info@netxen.com
  25. * NetXen Inc,
  26. * 18922 Forge Drive
  27. * Cupertino, CA 95014-0701
  28. *
  29. */
  30. #include "netxen_nic.h"
  31. static long phy_lock_timeout = 100000000;
  32. static int phy_lock(struct netxen_adapter *adapter)
  33. {
  34. int i;
  35. int done = 0, timeout = 0;
  36. while (!done) {
  37. done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
  38. if (done == 1)
  39. break;
  40. if (timeout >= phy_lock_timeout) {
  41. return -1;
  42. }
  43. timeout++;
  44. if (!in_atomic())
  45. schedule();
  46. else {
  47. for (i = 0; i < 20; i++)
  48. cpu_relax();
  49. }
  50. }
  51. NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
  52. return 0;
  53. }
  54. static int phy_unlock(struct netxen_adapter *adapter)
  55. {
  56. adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
  57. return 0;
  58. }
  59. /*
  60. * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
  61. * mii management interface.
  62. *
  63. * Note: The MII management interface goes through port 0.
  64. * Individual phys are addressed as follows:
  65. * @param phy [15:8] phy id
  66. * @param reg [7:0] register number
  67. *
  68. * @returns 0 on success
  69. * -1 on error
  70. *
  71. */
  72. int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
  73. __u32 * readval)
  74. {
  75. long timeout = 0;
  76. long result = 0;
  77. long restore = 0;
  78. long phy = adapter->physical_port;
  79. __u32 address;
  80. __u32 command;
  81. __u32 status;
  82. __u32 mac_cfg0;
  83. if (phy_lock(adapter) != 0) {
  84. return -1;
  85. }
  86. /*
  87. * MII mgmt all goes through port 0 MAC interface,
  88. * so it cannot be in reset
  89. */
  90. mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
  91. if (netxen_gb_get_soft_reset(mac_cfg0)) {
  92. __u32 temp;
  93. temp = 0;
  94. netxen_gb_tx_reset_pb(temp);
  95. netxen_gb_rx_reset_pb(temp);
  96. netxen_gb_tx_reset_mac(temp);
  97. netxen_gb_rx_reset_mac(temp);
  98. if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
  99. return -EIO;
  100. restore = 1;
  101. }
  102. address = 0;
  103. netxen_gb_mii_mgmt_reg_addr(address, reg);
  104. netxen_gb_mii_mgmt_phy_addr(address, phy);
  105. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
  106. return -EIO;
  107. command = 0; /* turn off any prior activity */
  108. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
  109. return -EIO;
  110. /* send read command */
  111. netxen_gb_mii_mgmt_set_read_cycle(command);
  112. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
  113. return -EIO;
  114. status = 0;
  115. do {
  116. status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
  117. timeout++;
  118. } while ((netxen_get_gb_mii_mgmt_busy(status)
  119. || netxen_get_gb_mii_mgmt_notvalid(status))
  120. && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
  121. if (timeout < NETXEN_NIU_PHY_WAITMAX) {
  122. *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
  123. result = 0;
  124. } else
  125. result = -1;
  126. if (restore)
  127. if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
  128. return -EIO;
  129. phy_unlock(adapter);
  130. return result;
  131. }
  132. /*
  133. * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
  134. * mii management interface.
  135. *
  136. * Note: The MII management interface goes through port 0.
  137. * Individual phys are addressed as follows:
  138. * @param phy [15:8] phy id
  139. * @param reg [7:0] register number
  140. *
  141. * @returns 0 on success
  142. * -1 on error
  143. *
  144. */
  145. int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
  146. __u32 val)
  147. {
  148. long timeout = 0;
  149. long result = 0;
  150. long restore = 0;
  151. long phy = adapter->physical_port;
  152. __u32 address;
  153. __u32 command;
  154. __u32 status;
  155. __u32 mac_cfg0;
  156. /*
  157. * MII mgmt all goes through port 0 MAC interface, so it
  158. * cannot be in reset
  159. */
  160. mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
  161. if (netxen_gb_get_soft_reset(mac_cfg0)) {
  162. __u32 temp;
  163. temp = 0;
  164. netxen_gb_tx_reset_pb(temp);
  165. netxen_gb_rx_reset_pb(temp);
  166. netxen_gb_tx_reset_mac(temp);
  167. netxen_gb_rx_reset_mac(temp);
  168. if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
  169. return -EIO;
  170. restore = 1;
  171. }
  172. command = 0; /* turn off any prior activity */
  173. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
  174. return -EIO;
  175. address = 0;
  176. netxen_gb_mii_mgmt_reg_addr(address, reg);
  177. netxen_gb_mii_mgmt_phy_addr(address, phy);
  178. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
  179. return -EIO;
  180. if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
  181. return -EIO;
  182. status = 0;
  183. do {
  184. status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
  185. timeout++;
  186. } while ((netxen_get_gb_mii_mgmt_busy(status))
  187. && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
  188. if (timeout < NETXEN_NIU_PHY_WAITMAX)
  189. result = 0;
  190. else
  191. result = -EIO;
  192. /* restore the state of port 0 MAC in case we tampered with it */
  193. if (restore)
  194. if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
  195. return -EIO;
  196. return result;
  197. }
  198. int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
  199. {
  200. if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
  201. NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
  202. NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
  203. }
  204. return 0;
  205. }
  206. /* Disable an XG interface */
  207. int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
  208. {
  209. __u32 mac_cfg;
  210. u32 port = adapter->physical_port;
  211. if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
  212. return 0;
  213. if (port > NETXEN_NIU_MAX_XG_PORTS)
  214. return -EINVAL;
  215. mac_cfg = 0;
  216. if (NXWR32(adapter,
  217. NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
  218. return -EIO;
  219. return 0;
  220. }
  221. int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
  222. u32 mode)
  223. {
  224. __u32 reg;
  225. u32 port = adapter->physical_port;
  226. if (port > NETXEN_NIU_MAX_XG_PORTS)
  227. return -EINVAL;
  228. reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
  229. if (mode == NETXEN_NIU_PROMISC_MODE)
  230. reg = (reg | 0x2000UL);
  231. else
  232. reg = (reg & ~0x2000UL);
  233. if (mode == NETXEN_NIU_ALLMULTI_MODE)
  234. reg = (reg | 0x1000UL);
  235. else
  236. reg = (reg & ~0x1000UL);
  237. NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
  238. return 0;
  239. }
  240. int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
  241. {
  242. u32 mac_hi, mac_lo;
  243. u32 reg_hi, reg_lo;
  244. u8 phy = adapter->physical_port;
  245. u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
  246. NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
  247. if (phy >= phy_count)
  248. return -EINVAL;
  249. mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
  250. mac_hi = addr[2] | ((u32)addr[3] << 8) |
  251. ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
  252. if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
  253. reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
  254. reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
  255. } else {
  256. reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
  257. reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
  258. }
  259. /* write twice to flush */
  260. if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
  261. return -EIO;
  262. if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
  263. return -EIO;
  264. return 0;
  265. }