Commit | Line | Data |
---|---|---|
3d396eb1 AK |
1 | /* |
2 | * Copyright (C) 2003 - 2006 NetXen, Inc. | |
3 | * All rights reserved. | |
80922fbc | 4 | * |
3d396eb1 AK |
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. | |
cb8011ad | 9 | * |
3d396eb1 AK |
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. | |
cb8011ad | 14 | * |
3d396eb1 AK |
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. | |
80922fbc | 19 | * |
3d396eb1 AK |
20 | * The full GNU General Public License is included in this distribution |
21 | * in the file called LICENSE. | |
80922fbc | 22 | * |
3d396eb1 AK |
23 | * Contact Information: |
24 | * info@netxen.com | |
25 | * NetXen, | |
26 | * 3965 Freedom Circle, Fourth floor, | |
27 | * Santa Clara, CA 95054 | |
28 | * | |
29 | * | |
30 | * Provides access to the Network Interface Unit h/w block. | |
31 | * | |
32 | */ | |
33 | ||
34 | #include "netxen_nic.h" | |
cb8011ad AK |
35 | |
36 | #define NETXEN_GB_MAC_SOFT_RESET 0x80000000 | |
37 | #define NETXEN_GB_MAC_RESET_PROT_BLK 0x000F0000 | |
38 | #define NETXEN_GB_MAC_ENABLE_TX_RX 0x00000005 | |
39 | #define NETXEN_GB_MAC_PAUSED_FRMS 0x00000020 | |
40 | ||
41 | static long phy_lock_timeout = 100000000; | |
42 | ||
993fb90c | 43 | static int phy_lock(struct netxen_adapter *adapter) |
cb8011ad AK |
44 | { |
45 | int i; | |
46 | int done = 0, timeout = 0; | |
47 | ||
48 | while (!done) { | |
3ce06a32 DP |
49 | done = netxen_nic_reg_read(adapter, |
50 | NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); | |
cb8011ad AK |
51 | if (done == 1) |
52 | break; | |
53 | if (timeout >= phy_lock_timeout) { | |
54 | return -1; | |
55 | } | |
56 | timeout++; | |
57 | if (!in_atomic()) | |
58 | schedule(); | |
59 | else { | |
60 | for (i = 0; i < 20; i++) | |
61 | cpu_relax(); | |
62 | } | |
63 | } | |
64 | ||
3ce06a32 DP |
65 | netxen_crb_writelit_adapter(adapter, |
66 | NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER); | |
cb8011ad AK |
67 | return 0; |
68 | } | |
69 | ||
993fb90c | 70 | static int phy_unlock(struct netxen_adapter *adapter) |
cb8011ad | 71 | { |
3ce06a32 | 72 | adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); |
ed25ffa1 | 73 | |
cb8011ad AK |
74 | return 0; |
75 | } | |
3d396eb1 | 76 | |
4790654c | 77 | /* |
3d396eb1 AK |
78 | * netxen_niu_gbe_phy_read - read a register from the GbE PHY via |
79 | * mii management interface. | |
80 | * | |
81 | * Note: The MII management interface goes through port 0. | |
cb8011ad | 82 | * Individual phys are addressed as follows: |
3d396eb1 AK |
83 | * @param phy [15:8] phy id |
84 | * @param reg [7:0] register number | |
85 | * | |
86 | * @returns 0 on success | |
cb8011ad | 87 | * -1 on error |
3d396eb1 AK |
88 | * |
89 | */ | |
4790654c | 90 | int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, |
13ba9c77 | 91 | __u32 * readval) |
3d396eb1 AK |
92 | { |
93 | long timeout = 0; | |
94 | long result = 0; | |
95 | long restore = 0; | |
3276fbad | 96 | long phy = adapter->physical_port; |
a608ab9c AV |
97 | __u32 address; |
98 | __u32 command; | |
99 | __u32 status; | |
100 | __u32 mac_cfg0; | |
3d396eb1 | 101 | |
ed25ffa1 | 102 | if (phy_lock(adapter) != 0) { |
cb8011ad AK |
103 | return -1; |
104 | } | |
105 | ||
106 | /* | |
107 | * MII mgmt all goes through port 0 MAC interface, | |
108 | * so it cannot be in reset | |
109 | */ | |
110 | ||
3ce06a32 | 111 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
3d396eb1 AK |
112 | &mac_cfg0, 4)) |
113 | return -EIO; | |
114 | if (netxen_gb_get_soft_reset(mac_cfg0)) { | |
a608ab9c | 115 | __u32 temp; |
3d396eb1 AK |
116 | temp = 0; |
117 | netxen_gb_tx_reset_pb(temp); | |
118 | netxen_gb_rx_reset_pb(temp); | |
119 | netxen_gb_tx_reset_mac(temp); | |
120 | netxen_gb_rx_reset_mac(temp); | |
3ce06a32 | 121 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
122 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
123 | &temp, 4)) | |
124 | return -EIO; | |
125 | restore = 1; | |
126 | } | |
127 | ||
3d396eb1 AK |
128 | address = 0; |
129 | netxen_gb_mii_mgmt_reg_addr(address, reg); | |
130 | netxen_gb_mii_mgmt_phy_addr(address, phy); | |
3ce06a32 | 131 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), |
3d396eb1 AK |
132 | &address, 4)) |
133 | return -EIO; | |
134 | command = 0; /* turn off any prior activity */ | |
3ce06a32 | 135 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
3d396eb1 AK |
136 | &command, 4)) |
137 | return -EIO; | |
138 | /* send read command */ | |
139 | netxen_gb_mii_mgmt_set_read_cycle(command); | |
3ce06a32 | 140 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
3d396eb1 AK |
141 | &command, 4)) |
142 | return -EIO; | |
143 | ||
144 | status = 0; | |
145 | do { | |
3ce06a32 | 146 | if (adapter->hw_read_wx(adapter, |
3d396eb1 AK |
147 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), |
148 | &status, 4)) | |
149 | return -EIO; | |
150 | timeout++; | |
151 | } while ((netxen_get_gb_mii_mgmt_busy(status) | |
152 | || netxen_get_gb_mii_mgmt_notvalid(status)) | |
153 | && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); | |
154 | ||
155 | if (timeout < NETXEN_NIU_PHY_WAITMAX) { | |
3ce06a32 | 156 | if (adapter->hw_read_wx(adapter, |
3d396eb1 AK |
157 | NETXEN_NIU_GB_MII_MGMT_STATUS(0), |
158 | readval, 4)) | |
159 | return -EIO; | |
160 | result = 0; | |
161 | } else | |
162 | result = -1; | |
163 | ||
164 | if (restore) | |
3ce06a32 | 165 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
166 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
167 | &mac_cfg0, 4)) | |
168 | return -EIO; | |
ed25ffa1 | 169 | phy_unlock(adapter); |
3d396eb1 AK |
170 | return result; |
171 | } | |
172 | ||
4790654c | 173 | /* |
3d396eb1 AK |
174 | * netxen_niu_gbe_phy_write - write a register to the GbE PHY via |
175 | * mii management interface. | |
176 | * | |
177 | * Note: The MII management interface goes through port 0. | |
cb8011ad | 178 | * Individual phys are addressed as follows: |
3d396eb1 AK |
179 | * @param phy [15:8] phy id |
180 | * @param reg [7:0] register number | |
181 | * | |
182 | * @returns 0 on success | |
cb8011ad | 183 | * -1 on error |
3d396eb1 AK |
184 | * |
185 | */ | |
4790654c | 186 | int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, |
13ba9c77 | 187 | __u32 val) |
3d396eb1 AK |
188 | { |
189 | long timeout = 0; | |
190 | long result = 0; | |
191 | long restore = 0; | |
3276fbad | 192 | long phy = adapter->physical_port; |
a608ab9c AV |
193 | __u32 address; |
194 | __u32 command; | |
195 | __u32 status; | |
196 | __u32 mac_cfg0; | |
3d396eb1 | 197 | |
cb8011ad AK |
198 | /* |
199 | * MII mgmt all goes through port 0 MAC interface, so it | |
200 | * cannot be in reset | |
201 | */ | |
202 | ||
3ce06a32 | 203 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), |
3d396eb1 AK |
204 | &mac_cfg0, 4)) |
205 | return -EIO; | |
206 | if (netxen_gb_get_soft_reset(mac_cfg0)) { | |
a608ab9c | 207 | __u32 temp; |
3d396eb1 AK |
208 | temp = 0; |
209 | netxen_gb_tx_reset_pb(temp); | |
210 | netxen_gb_rx_reset_pb(temp); | |
211 | netxen_gb_tx_reset_mac(temp); | |
212 | netxen_gb_rx_reset_mac(temp); | |
213 | ||
3ce06a32 | 214 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
215 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
216 | &temp, 4)) | |
217 | return -EIO; | |
218 | restore = 1; | |
219 | } | |
220 | ||
221 | command = 0; /* turn off any prior activity */ | |
3ce06a32 | 222 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), |
3d396eb1 AK |
223 | &command, 4)) |
224 | return -EIO; | |
225 | ||
226 | address = 0; | |
227 | netxen_gb_mii_mgmt_reg_addr(address, reg); | |
228 | netxen_gb_mii_mgmt_phy_addr(address, phy); | |
3ce06a32 | 229 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), |
3d396eb1 AK |
230 | &address, 4)) |
231 | return -EIO; | |
232 | ||
3ce06a32 | 233 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), |
3d396eb1 AK |
234 | &val, 4)) |
235 | return -EIO; | |
236 | ||
237 | status = 0; | |
238 | do { | |
3ce06a32 | 239 | if (adapter->hw_read_wx(adapter, |
3d396eb1 AK |
240 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), |
241 | &status, 4)) | |
242 | return -EIO; | |
243 | timeout++; | |
244 | } while ((netxen_get_gb_mii_mgmt_busy(status)) | |
245 | && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); | |
246 | ||
247 | if (timeout < NETXEN_NIU_PHY_WAITMAX) | |
248 | result = 0; | |
249 | else | |
250 | result = -EIO; | |
251 | ||
252 | /* restore the state of port 0 MAC in case we tampered with it */ | |
253 | if (restore) | |
3ce06a32 | 254 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
255 | NETXEN_NIU_GB_MAC_CONFIG_0(0), |
256 | &mac_cfg0, 4)) | |
257 | return -EIO; | |
258 | ||
259 | return result; | |
260 | } | |
261 | ||
13ba9c77 | 262 | int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
263 | { |
264 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f); | |
265 | return 0; | |
266 | } | |
267 | ||
13ba9c77 | 268 | int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
269 | { |
270 | int result = 0; | |
a608ab9c | 271 | __u32 enable = 0; |
3d396eb1 AK |
272 | netxen_set_phy_int_link_status_changed(enable); |
273 | netxen_set_phy_int_autoneg_completed(enable); | |
274 | netxen_set_phy_int_speed_changed(enable); | |
275 | ||
276 | if (0 != | |
4790654c | 277 | netxen_niu_gbe_phy_write(adapter, |
3d396eb1 AK |
278 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, |
279 | enable)) | |
280 | result = -EIO; | |
281 | ||
282 | return result; | |
283 | } | |
284 | ||
13ba9c77 | 285 | int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
286 | { |
287 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f); | |
288 | return 0; | |
289 | } | |
290 | ||
13ba9c77 | 291 | int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
292 | { |
293 | int result = 0; | |
294 | if (0 != | |
13ba9c77 | 295 | netxen_niu_gbe_phy_write(adapter, |
3d396eb1 AK |
296 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0)) |
297 | result = -EIO; | |
298 | ||
299 | return result; | |
300 | } | |
301 | ||
993fb90c | 302 | #if 0 |
13ba9c77 | 303 | int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
304 | { |
305 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1); | |
306 | return 0; | |
307 | } | |
993fb90c | 308 | #endif /* 0 */ |
3d396eb1 | 309 | |
993fb90c | 310 | static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) |
3d396eb1 AK |
311 | { |
312 | int result = 0; | |
313 | if (0 != | |
4790654c | 314 | netxen_niu_gbe_phy_write(adapter, |
3d396eb1 AK |
315 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, |
316 | -EIO)) | |
317 | result = -EIO; | |
318 | ||
319 | return result; | |
320 | } | |
321 | ||
4790654c | 322 | /* |
3d396eb1 AK |
323 | * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC |
324 | * | |
325 | */ | |
993fb90c AB |
326 | static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, |
327 | int port, long enable) | |
3d396eb1 AK |
328 | { |
329 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); | |
330 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
331 | 0x80000000); | |
332 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
333 | 0x0000f0025); | |
334 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), | |
335 | 0xf1ff); | |
336 | netxen_crb_writelit_adapter(adapter, | |
337 | NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0); | |
338 | netxen_crb_writelit_adapter(adapter, | |
339 | NETXEN_NIU_GB0_MII_MODE + (port << 3), 1); | |
340 | netxen_crb_writelit_adapter(adapter, | |
341 | (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); | |
342 | netxen_crb_writelit_adapter(adapter, | |
343 | NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); | |
344 | ||
345 | if (enable) { | |
4790654c JG |
346 | /* |
347 | * Do NOT enable flow control until a suitable solution for | |
348 | * shutting down pause frames is found. | |
3d396eb1 AK |
349 | */ |
350 | netxen_crb_writelit_adapter(adapter, | |
351 | NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
352 | 0x5); | |
353 | } | |
354 | ||
13ba9c77 | 355 | if (netxen_niu_gbe_enable_phy_interrupts(adapter)) |
3d396eb1 | 356 | printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); |
13ba9c77 | 357 | if (netxen_niu_gbe_clear_phy_interrupts(adapter)) |
3d396eb1 AK |
358 | printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); |
359 | } | |
360 | ||
4790654c | 361 | /* |
3d396eb1 AK |
362 | * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC |
363 | */ | |
993fb90c AB |
364 | static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, |
365 | int port, long enable) | |
3d396eb1 AK |
366 | { |
367 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); | |
368 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
369 | 0x80000000); | |
370 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
371 | 0x0000f0025); | |
372 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), | |
373 | 0xf2ff); | |
374 | netxen_crb_writelit_adapter(adapter, | |
375 | NETXEN_NIU_GB0_MII_MODE + (port << 3), 0); | |
376 | netxen_crb_writelit_adapter(adapter, | |
377 | NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1); | |
378 | netxen_crb_writelit_adapter(adapter, | |
379 | (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); | |
380 | netxen_crb_writelit_adapter(adapter, | |
381 | NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); | |
382 | ||
383 | if (enable) { | |
4790654c JG |
384 | /* |
385 | * Do NOT enable flow control until a suitable solution for | |
386 | * shutting down pause frames is found. | |
3d396eb1 AK |
387 | */ |
388 | netxen_crb_writelit_adapter(adapter, | |
389 | NETXEN_NIU_GB_MAC_CONFIG_0(port), | |
390 | 0x5); | |
391 | } | |
392 | ||
13ba9c77 | 393 | if (netxen_niu_gbe_enable_phy_interrupts(adapter)) |
3d396eb1 | 394 | printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); |
13ba9c77 | 395 | if (netxen_niu_gbe_clear_phy_interrupts(adapter)) |
3d396eb1 AK |
396 | printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); |
397 | } | |
398 | ||
399 | int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |
400 | { | |
401 | int result = 0; | |
a608ab9c | 402 | __u32 status; |
c9fc891f DP |
403 | |
404 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | |
405 | return 0; | |
406 | ||
80922fbc | 407 | if (adapter->disable_phy_interrupts) |
13ba9c77 | 408 | adapter->disable_phy_interrupts(adapter); |
3d396eb1 AK |
409 | mdelay(2); |
410 | ||
c9fc891f DP |
411 | if (0 == netxen_niu_gbe_phy_read(adapter, |
412 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) { | |
3d396eb1 AK |
413 | if (netxen_get_phy_link(status)) { |
414 | if (netxen_get_phy_speed(status) == 2) { | |
415 | netxen_niu_gbe_set_gmii_mode(adapter, port, 1); | |
416 | } else if ((netxen_get_phy_speed(status) == 1) | |
417 | || (netxen_get_phy_speed(status) == 0)) { | |
418 | netxen_niu_gbe_set_mii_mode(adapter, port, 1); | |
419 | } else { | |
420 | result = -1; | |
421 | } | |
422 | ||
423 | } else { | |
cb8011ad AK |
424 | /* |
425 | * We don't have link. Cable must be unconnected. | |
426 | * Enable phy interrupts so we take action when | |
427 | * plugged in. | |
428 | */ | |
429 | ||
3d396eb1 AK |
430 | netxen_crb_writelit_adapter(adapter, |
431 | NETXEN_NIU_GB_MAC_CONFIG_0 | |
cb8011ad AK |
432 | (port), |
433 | NETXEN_GB_MAC_SOFT_RESET); | |
3d396eb1 AK |
434 | netxen_crb_writelit_adapter(adapter, |
435 | NETXEN_NIU_GB_MAC_CONFIG_0 | |
cb8011ad AK |
436 | (port), |
437 | NETXEN_GB_MAC_RESET_PROT_BLK | |
438 | | NETXEN_GB_MAC_ENABLE_TX_RX | |
439 | | | |
440 | NETXEN_GB_MAC_PAUSED_FRMS); | |
13ba9c77 | 441 | if (netxen_niu_gbe_clear_phy_interrupts(adapter)) |
3d396eb1 AK |
442 | printk(KERN_ERR PFX |
443 | "ERROR clearing PHY interrupts\n"); | |
13ba9c77 | 444 | if (netxen_niu_gbe_enable_phy_interrupts(adapter)) |
3d396eb1 AK |
445 | printk(KERN_ERR PFX |
446 | "ERROR enabling PHY interrupts\n"); | |
13ba9c77 | 447 | if (netxen_niu_gbe_clear_phy_interrupts(adapter)) |
3d396eb1 AK |
448 | printk(KERN_ERR PFX |
449 | "ERROR clearing PHY interrupts\n"); | |
450 | result = -1; | |
451 | } | |
452 | } else { | |
453 | result = -EIO; | |
454 | } | |
455 | return result; | |
456 | } | |
457 | ||
cb8011ad AK |
458 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
459 | { | |
c9fc891f DP |
460 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
461 | netxen_crb_writelit_adapter(adapter, | |
462 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); | |
463 | netxen_crb_writelit_adapter(adapter, | |
464 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5); | |
465 | } | |
cb8011ad | 466 | |
6c80b18d | 467 | return 0; |
cb8011ad AK |
468 | } |
469 | ||
993fb90c | 470 | #if 0 |
4790654c | 471 | /* |
3d396eb1 AK |
472 | * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts |
473 | * @param enable 0 means don't enable the port | |
cb8011ad | 474 | * 1 means enable (or re-enable) the port |
3d396eb1 AK |
475 | */ |
476 | int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, | |
477 | int port, long enable) | |
478 | { | |
479 | int result = 0; | |
a608ab9c | 480 | __u32 int_src; |
3d396eb1 AK |
481 | |
482 | printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" | |
483 | " (device enable = %d)\n", (int)port, (int)enable); | |
484 | ||
cb8011ad AK |
485 | /* |
486 | * The read of the PHY INT status will clear the pending | |
487 | * interrupt status | |
488 | */ | |
13ba9c77 | 489 | if (netxen_niu_gbe_phy_read(adapter, |
3d396eb1 AK |
490 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, |
491 | &int_src) != 0) | |
492 | result = -EINVAL; | |
493 | else { | |
494 | printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src); | |
495 | if (netxen_get_phy_int_jabber(int_src)) | |
496 | printk(KERN_INFO PFX "jabber Interrupt "); | |
497 | if (netxen_get_phy_int_polarity_changed(int_src)) | |
498 | printk(KERN_INFO PFX "polarity changed "); | |
499 | if (netxen_get_phy_int_energy_detect(int_src)) | |
500 | printk(KERN_INFO PFX "energy detect \n"); | |
501 | if (netxen_get_phy_int_downshift(int_src)) | |
502 | printk(KERN_INFO PFX "downshift \n"); | |
503 | if (netxen_get_phy_int_mdi_xover_changed(int_src)) | |
504 | printk(KERN_INFO PFX "mdi_xover_changed "); | |
505 | if (netxen_get_phy_int_fifo_over_underflow(int_src)) | |
506 | printk(KERN_INFO PFX "fifo_over_underflow "); | |
507 | if (netxen_get_phy_int_false_carrier(int_src)) | |
508 | printk(KERN_INFO PFX "false_carrier "); | |
509 | if (netxen_get_phy_int_symbol_error(int_src)) | |
510 | printk(KERN_INFO PFX "symbol_error "); | |
511 | if (netxen_get_phy_int_autoneg_completed(int_src)) | |
512 | printk(KERN_INFO PFX "autoneg_completed "); | |
513 | if (netxen_get_phy_int_page_received(int_src)) | |
514 | printk(KERN_INFO PFX "page_received "); | |
515 | if (netxen_get_phy_int_duplex_changed(int_src)) | |
516 | printk(KERN_INFO PFX "duplex_changed "); | |
517 | if (netxen_get_phy_int_autoneg_error(int_src)) | |
518 | printk(KERN_INFO PFX "autoneg_error "); | |
519 | if ((netxen_get_phy_int_speed_changed(int_src)) | |
520 | || (netxen_get_phy_int_link_status_changed(int_src))) { | |
a608ab9c | 521 | __u32 status; |
3d396eb1 AK |
522 | |
523 | printk(KERN_INFO PFX | |
524 | "speed_changed or link status changed"); | |
525 | if (netxen_niu_gbe_phy_read | |
13ba9c77 | 526 | (adapter, |
3d396eb1 AK |
527 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
528 | &status) == 0) { | |
529 | if (netxen_get_phy_speed(status) == 2) { | |
530 | printk | |
531 | (KERN_INFO PFX "Link speed changed" | |
532 | " to 1000 Mbps\n"); | |
533 | netxen_niu_gbe_set_gmii_mode(adapter, | |
534 | port, | |
535 | enable); | |
536 | } else if (netxen_get_phy_speed(status) == 1) { | |
537 | printk | |
538 | (KERN_INFO PFX "Link speed changed" | |
539 | " to 100 Mbps\n"); | |
540 | netxen_niu_gbe_set_mii_mode(adapter, | |
541 | port, | |
542 | enable); | |
543 | } else if (netxen_get_phy_speed(status) == 0) { | |
544 | printk | |
545 | (KERN_INFO PFX "Link speed changed" | |
546 | " to 10 Mbps\n"); | |
547 | netxen_niu_gbe_set_mii_mode(adapter, | |
548 | port, | |
549 | enable); | |
550 | } else { | |
5bc51424 JP |
551 | printk(KERN_ERR PFX "ERROR reading " |
552 | "PHY status. Invalid speed.\n"); | |
3d396eb1 AK |
553 | result = -1; |
554 | } | |
555 | } else { | |
556 | printk(KERN_ERR PFX | |
557 | "ERROR reading PHY status.\n"); | |
558 | result = -1; | |
559 | } | |
560 | ||
561 | } | |
562 | printk(KERN_INFO "\n"); | |
563 | } | |
564 | return result; | |
565 | } | |
993fb90c | 566 | #endif /* 0 */ |
3d396eb1 AK |
567 | |
568 | /* | |
569 | * Return the current station MAC address. | |
570 | * Note that the passed-in value must already be in network byte order. | |
571 | */ | |
993fb90c AB |
572 | static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, |
573 | netxen_ethernet_macaddr_t * addr) | |
3d396eb1 | 574 | { |
a608ab9c AV |
575 | u32 stationhigh; |
576 | u32 stationlow; | |
3276fbad | 577 | int phy = adapter->physical_port; |
a608ab9c | 578 | u8 val[8]; |
3d396eb1 AK |
579 | |
580 | if (addr == NULL) | |
581 | return -EINVAL; | |
582 | if ((phy < 0) || (phy > 3)) | |
583 | return -EINVAL; | |
584 | ||
3ce06a32 | 585 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), |
3d396eb1 AK |
586 | &stationhigh, 4)) |
587 | return -EIO; | |
3ce06a32 | 588 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), |
3d396eb1 AK |
589 | &stationlow, 4)) |
590 | return -EIO; | |
a608ab9c AV |
591 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); |
592 | ((__le32 *)val)[0] = cpu_to_le32(stationlow); | |
3d396eb1 | 593 | |
a608ab9c | 594 | memcpy(addr, val + 2, 6); |
3d396eb1 AK |
595 | |
596 | return 0; | |
597 | } | |
598 | ||
599 | /* | |
600 | * Set the station MAC address. | |
601 | * Note that the passed-in value must already be in network byte order. | |
602 | */ | |
3176ff3e | 603 | int netxen_niu_macaddr_set(struct netxen_adapter *adapter, |
3d396eb1 AK |
604 | netxen_ethernet_macaddr_t addr) |
605 | { | |
a608ab9c AV |
606 | u8 temp[4]; |
607 | u32 val; | |
3276fbad | 608 | int phy = adapter->physical_port; |
ed25ffa1 | 609 | unsigned char mac_addr[6]; |
cb8011ad | 610 | int i; |
0795af57 | 611 | DECLARE_MAC_BUF(mac); |
cb8011ad | 612 | |
24a7a455 DP |
613 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
614 | return 0; | |
615 | ||
cb8011ad | 616 | for (i = 0; i < 10; i++) { |
a608ab9c AV |
617 | temp[0] = temp[1] = 0; |
618 | memcpy(temp + 2, addr, 2); | |
619 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 DP |
620 | if (adapter->hw_write_wx(adapter, |
621 | NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) | |
cb8011ad | 622 | return -EIO; |
3d396eb1 | 623 | |
a608ab9c AV |
624 | memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); |
625 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 DP |
626 | if (adapter->hw_write_wx(adapter, |
627 | NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) | |
cb8011ad | 628 | return -2; |
3d396eb1 | 629 | |
4790654c | 630 | netxen_niu_macaddr_get(adapter, |
cb8011ad | 631 | (netxen_ethernet_macaddr_t *) mac_addr); |
ed25ffa1 | 632 | if (memcmp(mac_addr, addr, 6) == 0) |
cb8011ad AK |
633 | break; |
634 | } | |
3d396eb1 | 635 | |
cb8011ad AK |
636 | if (i == 10) { |
637 | printk(KERN_ERR "%s: cannot set Mac addr for %s\n", | |
3176ff3e | 638 | netxen_nic_driver_name, adapter->netdev->name); |
0795af57 JP |
639 | printk(KERN_ERR "MAC address set: %s.\n", |
640 | print_mac(mac, addr)); | |
641 | printk(KERN_ERR "MAC address get: %s.\n", | |
642 | print_mac(mac, mac_addr)); | |
cb8011ad | 643 | } |
3d396eb1 AK |
644 | return 0; |
645 | } | |
646 | ||
993fb90c | 647 | #if 0 |
3d396eb1 AK |
648 | /* Enable a GbE interface */ |
649 | int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |
650 | int port, netxen_niu_gbe_ifmode_t mode) | |
651 | { | |
a608ab9c AV |
652 | __u32 mac_cfg0; |
653 | __u32 mac_cfg1; | |
654 | __u32 mii_cfg; | |
3d396eb1 AK |
655 | |
656 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) | |
657 | return -EINVAL; | |
658 | ||
659 | mac_cfg0 = 0; | |
660 | netxen_gb_soft_reset(mac_cfg0); | |
3ce06a32 | 661 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
3d396eb1 AK |
662 | &mac_cfg0, 4)) |
663 | return -EIO; | |
664 | mac_cfg0 = 0; | |
665 | netxen_gb_enable_tx(mac_cfg0); | |
666 | netxen_gb_enable_rx(mac_cfg0); | |
667 | netxen_gb_unset_rx_flowctl(mac_cfg0); | |
668 | netxen_gb_tx_reset_pb(mac_cfg0); | |
669 | netxen_gb_rx_reset_pb(mac_cfg0); | |
670 | netxen_gb_tx_reset_mac(mac_cfg0); | |
671 | netxen_gb_rx_reset_mac(mac_cfg0); | |
672 | ||
3ce06a32 | 673 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
3d396eb1 AK |
674 | &mac_cfg0, 4)) |
675 | return -EIO; | |
676 | mac_cfg1 = 0; | |
677 | netxen_gb_set_preamblelen(mac_cfg1, 0xf); | |
678 | netxen_gb_set_duplex(mac_cfg1); | |
679 | netxen_gb_set_crc_enable(mac_cfg1); | |
680 | netxen_gb_set_padshort(mac_cfg1); | |
681 | netxen_gb_set_checklength(mac_cfg1); | |
682 | netxen_gb_set_hugeframes(mac_cfg1); | |
683 | ||
684 | if (mode == NETXEN_NIU_10_100_MB) { | |
685 | netxen_gb_set_intfmode(mac_cfg1, 1); | |
3ce06a32 | 686 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
687 | NETXEN_NIU_GB_MAC_CONFIG_1(port), |
688 | &mac_cfg1, 4)) | |
689 | return -EIO; | |
690 | ||
691 | /* set mii mode */ | |
692 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + | |
693 | (port << 3), 0); | |
694 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + | |
695 | (port << 3), 1); | |
696 | ||
697 | } else if (mode == NETXEN_NIU_1000_MB) { | |
698 | netxen_gb_set_intfmode(mac_cfg1, 2); | |
3ce06a32 | 699 | if (adapter->hw_write_wx(adapter, |
3d396eb1 AK |
700 | NETXEN_NIU_GB_MAC_CONFIG_1(port), |
701 | &mac_cfg1, 4)) | |
702 | return -EIO; | |
703 | /* set gmii mode */ | |
704 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + | |
705 | (port << 3), 0); | |
706 | netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + | |
707 | (port << 3), 1); | |
708 | } | |
709 | mii_cfg = 0; | |
710 | netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); | |
3ce06a32 | 711 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), |
3d396eb1 AK |
712 | &mii_cfg, 4)) |
713 | return -EIO; | |
714 | mac_cfg0 = 0; | |
715 | netxen_gb_enable_tx(mac_cfg0); | |
716 | netxen_gb_enable_rx(mac_cfg0); | |
717 | netxen_gb_unset_rx_flowctl(mac_cfg0); | |
718 | netxen_gb_unset_tx_flowctl(mac_cfg0); | |
719 | ||
3ce06a32 | 720 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
3d396eb1 AK |
721 | &mac_cfg0, 4)) |
722 | return -EIO; | |
723 | return 0; | |
724 | } | |
993fb90c | 725 | #endif /* 0 */ |
3d396eb1 AK |
726 | |
727 | /* Disable a GbE interface */ | |
3176ff3e | 728 | int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) |
3d396eb1 | 729 | { |
a608ab9c | 730 | __u32 mac_cfg0; |
3276fbad | 731 | u32 port = adapter->physical_port; |
3d396eb1 | 732 | |
24a7a455 DP |
733 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
734 | return 0; | |
735 | ||
287aa83d | 736 | if (port > NETXEN_NIU_MAX_GBE_PORTS) |
6c80b18d | 737 | return -EINVAL; |
3d396eb1 AK |
738 | mac_cfg0 = 0; |
739 | netxen_gb_soft_reset(mac_cfg0); | |
3ce06a32 | 740 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
3d396eb1 AK |
741 | &mac_cfg0, 4)) |
742 | return -EIO; | |
743 | return 0; | |
744 | } | |
745 | ||
746 | /* Disable an XG interface */ | |
3176ff3e | 747 | int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) |
3d396eb1 | 748 | { |
a608ab9c | 749 | __u32 mac_cfg; |
3276fbad | 750 | u32 port = adapter->physical_port; |
3d396eb1 | 751 | |
24a7a455 DP |
752 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
753 | return 0; | |
754 | ||
72b0a7a8 | 755 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
6c80b18d | 756 | return -EINVAL; |
72b0a7a8 | 757 | |
3d396eb1 | 758 | mac_cfg = 0; |
3ce06a32 | 759 | if (adapter->hw_write_wx(adapter, |
72b0a7a8 | 760 | NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) |
3d396eb1 AK |
761 | return -EIO; |
762 | return 0; | |
763 | } | |
764 | ||
765 | /* Set promiscuous mode for a GbE interface */ | |
4790654c | 766 | int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, |
9ad27643 | 767 | u32 mode) |
3d396eb1 | 768 | { |
a608ab9c | 769 | __u32 reg; |
3276fbad | 770 | u32 port = adapter->physical_port; |
3d396eb1 | 771 | |
287aa83d | 772 | if (port > NETXEN_NIU_MAX_GBE_PORTS) |
3d396eb1 AK |
773 | return -EINVAL; |
774 | ||
775 | /* save previous contents */ | |
3ce06a32 | 776 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, |
3d396eb1 AK |
777 | ®, 4)) |
778 | return -EIO; | |
779 | if (mode == NETXEN_NIU_PROMISC_MODE) { | |
780 | switch (port) { | |
781 | case 0: | |
782 | netxen_clear_gb_drop_gb0(reg); | |
783 | break; | |
784 | case 1: | |
785 | netxen_clear_gb_drop_gb1(reg); | |
786 | break; | |
787 | case 2: | |
788 | netxen_clear_gb_drop_gb2(reg); | |
789 | break; | |
790 | case 3: | |
791 | netxen_clear_gb_drop_gb3(reg); | |
792 | break; | |
793 | default: | |
794 | return -EIO; | |
795 | } | |
796 | } else { | |
797 | switch (port) { | |
798 | case 0: | |
799 | netxen_set_gb_drop_gb0(reg); | |
800 | break; | |
801 | case 1: | |
802 | netxen_set_gb_drop_gb1(reg); | |
803 | break; | |
804 | case 2: | |
805 | netxen_set_gb_drop_gb2(reg); | |
806 | break; | |
807 | case 3: | |
808 | netxen_set_gb_drop_gb3(reg); | |
809 | break; | |
810 | default: | |
811 | return -EIO; | |
812 | } | |
813 | } | |
3ce06a32 | 814 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, |
3d396eb1 AK |
815 | ®, 4)) |
816 | return -EIO; | |
817 | return 0; | |
818 | } | |
819 | ||
820 | /* | |
821 | * Set the MAC address for an XG port | |
822 | * Note that the passed-in value must already be in network byte order. | |
823 | */ | |
3176ff3e | 824 | int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, |
3d396eb1 AK |
825 | netxen_ethernet_macaddr_t addr) |
826 | { | |
3276fbad | 827 | int phy = adapter->physical_port; |
a608ab9c AV |
828 | u8 temp[4]; |
829 | u32 val; | |
3d396eb1 | 830 | |
24a7a455 DP |
831 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
832 | return 0; | |
833 | ||
6c80b18d MT |
834 | if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) |
835 | return -EIO; | |
836 | ||
a608ab9c | 837 | temp[0] = temp[1] = 0; |
6c80b18d MT |
838 | switch (phy) { |
839 | case 0: | |
840 | memcpy(temp + 2, addr, 2); | |
841 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 | 842 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, |
6c80b18d | 843 | &val, 4)) |
3d396eb1 AK |
844 | return -EIO; |
845 | ||
6c80b18d MT |
846 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); |
847 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 | 848 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, |
6c80b18d MT |
849 | &val, 4)) |
850 | return -EIO; | |
851 | break; | |
852 | ||
853 | case 1: | |
854 | memcpy(temp + 2, addr, 2); | |
855 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 | 856 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, |
6c80b18d MT |
857 | &val, 4)) |
858 | return -EIO; | |
859 | ||
860 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | |
861 | val = le32_to_cpu(*(__le32 *)temp); | |
3ce06a32 | 862 | if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, |
6c80b18d | 863 | &val, 4)) |
3d396eb1 | 864 | return -EIO; |
6c80b18d MT |
865 | break; |
866 | ||
867 | default: | |
868 | printk(KERN_ERR "Unknown port %d\n", phy); | |
869 | break; | |
870 | } | |
3d396eb1 AK |
871 | |
872 | return 0; | |
873 | } | |
874 | ||
993fb90c | 875 | #if 0 |
3d396eb1 AK |
876 | /* |
877 | * Return the current station MAC address. | |
878 | * Note that the passed-in value must already be in network byte order. | |
879 | */ | |
13ba9c77 | 880 | int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, |
3d396eb1 AK |
881 | netxen_ethernet_macaddr_t * addr) |
882 | { | |
3276fbad | 883 | int phy = adapter->physical_port; |
a608ab9c AV |
884 | u32 stationhigh; |
885 | u32 stationlow; | |
886 | u8 val[8]; | |
3d396eb1 AK |
887 | |
888 | if (addr == NULL) | |
889 | return -EINVAL; | |
890 | if (phy != 0) | |
891 | return -EINVAL; | |
892 | ||
3ce06a32 | 893 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, |
3d396eb1 AK |
894 | &stationhigh, 4)) |
895 | return -EIO; | |
3ce06a32 | 896 | if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, |
3d396eb1 AK |
897 | &stationlow, 4)) |
898 | return -EIO; | |
a608ab9c AV |
899 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); |
900 | ((__le32 *)val)[0] = cpu_to_le32(stationlow); | |
3d396eb1 | 901 | |
a608ab9c | 902 | memcpy(addr, val + 2, 6); |
3d396eb1 AK |
903 | |
904 | return 0; | |
905 | } | |
993fb90c | 906 | #endif /* 0 */ |
3d396eb1 AK |
907 | |
908 | int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | |
9ad27643 | 909 | u32 mode) |
3d396eb1 | 910 | { |
a608ab9c | 911 | __u32 reg; |
3276fbad | 912 | u32 port = adapter->physical_port; |
3d396eb1 | 913 | |
287aa83d | 914 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
3d396eb1 AK |
915 | return -EINVAL; |
916 | ||
3ce06a32 | 917 | if (adapter->hw_read_wx(adapter, |
6c80b18d MT |
918 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) |
919 | return -EIO; | |
3d396eb1 AK |
920 | if (mode == NETXEN_NIU_PROMISC_MODE) |
921 | reg = (reg | 0x2000UL); | |
922 | else | |
923 | reg = (reg & ~0x2000UL); | |
924 | ||
623621b0 DP |
925 | if (mode == NETXEN_NIU_ALLMULTI_MODE) |
926 | reg = (reg | 0x1000UL); | |
927 | else | |
928 | reg = (reg & ~0x1000UL); | |
929 | ||
6c80b18d MT |
930 | netxen_crb_writelit_adapter(adapter, |
931 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | |
3d396eb1 AK |
932 | |
933 | return 0; | |
934 | } |