1392e8994f2c1bcfe781281f176db14b33e96a61
[deliverable/linux.git] / drivers / net / netxen / netxen_nic_niu.c
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
31 #include "netxen_nic.h"
32
33 /*
34 * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
35 * mii management interface.
36 *
37 * Note: The MII management interface goes through port 0.
38 * Individual phys are addressed as follows:
39 * @param phy [15:8] phy id
40 * @param reg [7:0] register number
41 *
42 * @returns 0 on success
43 * -1 on error
44 *
45 */
46 int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
47 __u32 * readval)
48 {
49 long timeout = 0;
50 long result = 0;
51 long restore = 0;
52 long phy = adapter->physical_port;
53 __u32 address;
54 __u32 command;
55 __u32 status;
56 __u32 mac_cfg0;
57
58 if (netxen_phy_lock(adapter) != 0)
59 return -1;
60
61 /*
62 * MII mgmt all goes through port 0 MAC interface,
63 * so it cannot be in reset
64 */
65
66 mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
67 if (netxen_gb_get_soft_reset(mac_cfg0)) {
68 __u32 temp;
69 temp = 0;
70 netxen_gb_tx_reset_pb(temp);
71 netxen_gb_rx_reset_pb(temp);
72 netxen_gb_tx_reset_mac(temp);
73 netxen_gb_rx_reset_mac(temp);
74 if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
75 return -EIO;
76 restore = 1;
77 }
78
79 address = 0;
80 netxen_gb_mii_mgmt_reg_addr(address, reg);
81 netxen_gb_mii_mgmt_phy_addr(address, phy);
82 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
83 return -EIO;
84 command = 0; /* turn off any prior activity */
85 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
86 return -EIO;
87 /* send read command */
88 netxen_gb_mii_mgmt_set_read_cycle(command);
89 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
90 return -EIO;
91
92 status = 0;
93 do {
94 status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
95 timeout++;
96 } while ((netxen_get_gb_mii_mgmt_busy(status)
97 || netxen_get_gb_mii_mgmt_notvalid(status))
98 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
99
100 if (timeout < NETXEN_NIU_PHY_WAITMAX) {
101 *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
102 result = 0;
103 } else
104 result = -1;
105
106 if (restore)
107 if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
108 return -EIO;
109 netxen_phy_unlock(adapter);
110 return result;
111 }
112
113 /*
114 * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
115 * mii management interface.
116 *
117 * Note: The MII management interface goes through port 0.
118 * Individual phys are addressed as follows:
119 * @param phy [15:8] phy id
120 * @param reg [7:0] register number
121 *
122 * @returns 0 on success
123 * -1 on error
124 *
125 */
126 int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
127 __u32 val)
128 {
129 long timeout = 0;
130 long result = 0;
131 long restore = 0;
132 long phy = adapter->physical_port;
133 __u32 address;
134 __u32 command;
135 __u32 status;
136 __u32 mac_cfg0;
137
138 /*
139 * MII mgmt all goes through port 0 MAC interface, so it
140 * cannot be in reset
141 */
142
143 mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
144 if (netxen_gb_get_soft_reset(mac_cfg0)) {
145 __u32 temp;
146 temp = 0;
147 netxen_gb_tx_reset_pb(temp);
148 netxen_gb_rx_reset_pb(temp);
149 netxen_gb_tx_reset_mac(temp);
150 netxen_gb_rx_reset_mac(temp);
151
152 if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
153 return -EIO;
154 restore = 1;
155 }
156
157 command = 0; /* turn off any prior activity */
158 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
159 return -EIO;
160
161 address = 0;
162 netxen_gb_mii_mgmt_reg_addr(address, reg);
163 netxen_gb_mii_mgmt_phy_addr(address, phy);
164 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
165 return -EIO;
166
167 if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
168 return -EIO;
169
170 status = 0;
171 do {
172 status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
173 timeout++;
174 } while ((netxen_get_gb_mii_mgmt_busy(status))
175 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
176
177 if (timeout < NETXEN_NIU_PHY_WAITMAX)
178 result = 0;
179 else
180 result = -EIO;
181
182 /* restore the state of port 0 MAC in case we tampered with it */
183 if (restore)
184 if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
185 return -EIO;
186
187 return result;
188 }
189
190 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
191 {
192 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
193 NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
194 NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
195 }
196
197 return 0;
198 }
199
200 /* Disable an XG interface */
201 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
202 {
203 __u32 mac_cfg;
204 u32 port = adapter->physical_port;
205
206 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
207 return 0;
208
209 if (port > NETXEN_NIU_MAX_XG_PORTS)
210 return -EINVAL;
211
212 mac_cfg = 0;
213 if (NXWR32(adapter,
214 NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
215 return -EIO;
216 return 0;
217 }
218
219 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
220 u32 mode)
221 {
222 __u32 reg;
223 u32 port = adapter->physical_port;
224
225 if (port > NETXEN_NIU_MAX_XG_PORTS)
226 return -EINVAL;
227
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
234 if (mode == NETXEN_NIU_ALLMULTI_MODE)
235 reg = (reg | 0x1000UL);
236 else
237 reg = (reg & ~0x1000UL);
238
239 NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
240
241 return 0;
242 }
243
244 int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
245 {
246 u32 mac_hi, mac_lo;
247 u32 reg_hi, reg_lo;
248
249 u8 phy = adapter->physical_port;
250 u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
251 NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
252
253 if (phy >= phy_count)
254 return -EINVAL;
255
256 mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
257 mac_hi = addr[2] | ((u32)addr[3] << 8) |
258 ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
259
260 if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
261 reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
262 reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
263 } else {
264 reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
265 reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
266 }
267
268 /* write twice to flush */
269 if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
270 return -EIO;
271 if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
272 return -EIO;
273
274 return 0;
275 }
This page took 0.035025 seconds and 4 git commands to generate.