]>
Commit | Line | Data |
---|---|---|
5449c685 FB |
1 | /* |
2 | * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but 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 along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | * | |
612822f5 | 19 | * |
5449c685 FB |
20 | * File: mac.c |
21 | * | |
22 | * Purpose: MAC routines | |
23 | * | |
24 | * Author: Tevin Chen | |
25 | * | |
26 | * Date: May 21, 1996 | |
27 | * | |
28 | * Functions: | |
5449c685 FB |
29 | * MACbIsRegBitsOn - Test if All test Bits On |
30 | * MACbIsRegBitsOff - Test if All test Bits Off | |
31 | * MACbIsIntDisable - Test if MAC interrupt disable | |
5449c685 | 32 | * MACvSetShortRetryLimit - Set 802.11 Short Retry limit |
5449c685 | 33 | * MACvSetLongRetryLimit - Set 802.11 Long Retry limit |
5449c685 | 34 | * MACvSetLoopbackMode - Set MAC Loopback Mode |
5449c685 FB |
35 | * MACvSaveContext - Save Context of MAC Registers |
36 | * MACvRestoreContext - Restore Context of MAC Registers | |
5449c685 FB |
37 | * MACbSoftwareReset - Software Reset MAC |
38 | * MACbSafeRxOff - Turn Off MAC Rx | |
39 | * MACbSafeTxOff - Turn Off MAC Tx | |
40 | * MACbSafeStop - Stop MAC function | |
41 | * MACbShutdown - Shut down MAC | |
42 | * MACvInitialize - Initialize MAC | |
789d1aef JM |
43 | * MACvSetCurrRxDescAddr - Set Rx Descriptors Address |
44 | * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address | |
45 | * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address | |
5449c685 FB |
46 | * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC |
47 | * | |
48 | * Revision History: | |
49 | * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53 | |
50 | * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& MACvEnableBusSusEn() | |
51 | * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry | |
52 | * | |
53 | */ | |
54 | ||
5449c685 | 55 | #include "tmacro.h" |
5449c685 | 56 | #include "mac.h" |
5449c685 | 57 | |
5449c685 FB |
58 | /* |
59 | * Description: | |
60 | * Test if all test bits on | |
61 | * | |
62 | * Parameters: | |
63 | * In: | |
c2d845de | 64 | * io_base - Base Address for MAC |
5449c685 FB |
65 | * byRegOfs - Offset of MAC Register |
66 | * byTestBits - Test bits | |
67 | * Out: | |
68 | * none | |
69 | * | |
5a5a2a6a | 70 | * Return Value: true if all test bits On; otherwise false |
5449c685 FB |
71 | * |
72 | */ | |
f9f853af | 73 | bool MACbIsRegBitsOn(struct vnt_private *priv, unsigned char byRegOfs, |
d4855fe1 | 74 | unsigned char byTestBits) |
5449c685 | 75 | { |
c2d845de | 76 | void __iomem *io_base = priv->PortOffset; |
5449c685 | 77 | |
f205e8d1 | 78 | return (ioread8(io_base + byRegOfs) & byTestBits) == byTestBits; |
5449c685 FB |
79 | } |
80 | ||
81 | /* | |
82 | * Description: | |
83 | * Test if all test bits off | |
84 | * | |
85 | * Parameters: | |
86 | * In: | |
c2d845de | 87 | * io_base - Base Address for MAC |
5449c685 FB |
88 | * byRegOfs - Offset of MAC Register |
89 | * byTestBits - Test bits | |
90 | * Out: | |
91 | * none | |
92 | * | |
5a5a2a6a | 93 | * Return Value: true if all test bits Off; otherwise false |
5449c685 FB |
94 | * |
95 | */ | |
f9f853af | 96 | bool MACbIsRegBitsOff(struct vnt_private *priv, unsigned char byRegOfs, |
d4855fe1 | 97 | unsigned char byTestBits) |
5449c685 | 98 | { |
c2d845de | 99 | void __iomem *io_base = priv->PortOffset; |
5449c685 | 100 | |
f205e8d1 | 101 | return !(ioread8(io_base + byRegOfs) & byTestBits); |
5449c685 FB |
102 | } |
103 | ||
104 | /* | |
105 | * Description: | |
106 | * Test if MAC interrupt disable | |
107 | * | |
108 | * Parameters: | |
109 | * In: | |
c2d845de | 110 | * io_base - Base Address for MAC |
5449c685 FB |
111 | * Out: |
112 | * none | |
113 | * | |
5a5a2a6a | 114 | * Return Value: true if interrupt is disable; otherwise false |
5449c685 FB |
115 | * |
116 | */ | |
f9f853af | 117 | bool MACbIsIntDisable(struct vnt_private *priv) |
5449c685 | 118 | { |
c2d845de | 119 | void __iomem *io_base = priv->PortOffset; |
5449c685 | 120 | |
e52ab0ec | 121 | if (ioread32(io_base + MAC_REG_IMR)) |
c3504bfd | 122 | return false; |
5449c685 | 123 | |
c3504bfd | 124 | return true; |
5449c685 FB |
125 | } |
126 | ||
5449c685 FB |
127 | /* |
128 | * Description: | |
129 | * Set 802.11 Short Retry Limit | |
130 | * | |
131 | * Parameters: | |
132 | * In: | |
c2d845de | 133 | * io_base - Base Address for MAC |
5449c685 FB |
134 | * byRetryLimit- Retry Limit |
135 | * Out: | |
136 | * none | |
137 | * | |
138 | * Return Value: none | |
139 | * | |
140 | */ | |
f9f853af | 141 | void MACvSetShortRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit) |
5449c685 | 142 | { |
c2d845de | 143 | void __iomem *io_base = priv->PortOffset; |
9ab81fb7 | 144 | /* set SRT */ |
c2d845de | 145 | VNSvOutPortB(io_base + MAC_REG_SRT, byRetryLimit); |
5449c685 FB |
146 | } |
147 | ||
5449c685 FB |
148 | |
149 | /* | |
150 | * Description: | |
151 | * Set 802.11 Long Retry Limit | |
152 | * | |
153 | * Parameters: | |
154 | * In: | |
c2d845de | 155 | * io_base - Base Address for MAC |
5449c685 FB |
156 | * byRetryLimit- Retry Limit |
157 | * Out: | |
158 | * none | |
159 | * | |
160 | * Return Value: none | |
161 | * | |
162 | */ | |
f9f853af | 163 | void MACvSetLongRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit) |
5449c685 | 164 | { |
c2d845de | 165 | void __iomem *io_base = priv->PortOffset; |
9ab81fb7 | 166 | /* set LRT */ |
c2d845de | 167 | VNSvOutPortB(io_base + MAC_REG_LRT, byRetryLimit); |
5449c685 FB |
168 | } |
169 | ||
5449c685 FB |
170 | /* |
171 | * Description: | |
172 | * Set MAC Loopback mode | |
173 | * | |
174 | * Parameters: | |
175 | * In: | |
c2d845de | 176 | * io_base - Base Address for MAC |
5449c685 FB |
177 | * byLoopbackMode - Loopback Mode |
178 | * Out: | |
179 | * none | |
180 | * | |
181 | * Return Value: none | |
182 | * | |
183 | */ | |
f9f853af | 184 | void MACvSetLoopbackMode(struct vnt_private *priv, unsigned char byLoopbackMode) |
5449c685 | 185 | { |
c2d845de | 186 | void __iomem *io_base = priv->PortOffset; |
c3504bfd JP |
187 | unsigned char byOrgValue; |
188 | ||
c3504bfd | 189 | byLoopbackMode <<= 6; |
9ab81fb7 | 190 | /* set TCR */ |
c2d845de | 191 | VNSvInPortB(io_base + MAC_REG_TEST, &byOrgValue); |
c3504bfd JP |
192 | byOrgValue = byOrgValue & 0x3F; |
193 | byOrgValue = byOrgValue | byLoopbackMode; | |
c2d845de | 194 | VNSvOutPortB(io_base + MAC_REG_TEST, byOrgValue); |
5449c685 FB |
195 | } |
196 | ||
5449c685 FB |
197 | /* |
198 | * Description: | |
199 | * Save MAC registers to context buffer | |
200 | * | |
201 | * Parameters: | |
202 | * In: | |
c2d845de | 203 | * io_base - Base Address for MAC |
5449c685 FB |
204 | * Out: |
205 | * pbyCxtBuf - Context buffer | |
206 | * | |
207 | * Return Value: none | |
208 | * | |
209 | */ | |
f9f853af | 210 | void MACvSaveContext(struct vnt_private *priv, unsigned char *pbyCxtBuf) |
5449c685 | 211 | { |
c2d845de | 212 | void __iomem *io_base = priv->PortOffset; |
5449c685 | 213 | |
9ab81fb7 | 214 | /* read page0 register */ |
7e5120e9 | 215 | memcpy_fromio(pbyCxtBuf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0); |
5449c685 | 216 | |
c2d845de | 217 | MACvSelectPage1(io_base); |
5449c685 | 218 | |
9ab81fb7 | 219 | /* read page1 register */ |
7e5120e9 MP |
220 | memcpy_fromio(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base, |
221 | MAC_MAX_CONTEXT_SIZE_PAGE1); | |
5449c685 | 222 | |
c2d845de | 223 | MACvSelectPage0(io_base); |
5449c685 FB |
224 | } |
225 | ||
226 | /* | |
227 | * Description: | |
228 | * Restore MAC registers from context buffer | |
229 | * | |
230 | * Parameters: | |
231 | * In: | |
c2d845de | 232 | * io_base - Base Address for MAC |
5449c685 FB |
233 | * pbyCxtBuf - Context buffer |
234 | * Out: | |
235 | * none | |
236 | * | |
237 | * Return Value: none | |
238 | * | |
239 | */ | |
f9f853af | 240 | void MACvRestoreContext(struct vnt_private *priv, unsigned char *pbyCxtBuf) |
5449c685 | 241 | { |
c2d845de | 242 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 243 | int ii; |
5449c685 | 244 | |
c2d845de | 245 | MACvSelectPage1(io_base); |
9ab81fb7 | 246 | /* restore page1 */ |
bc5cf656 | 247 | for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) |
c2d845de | 248 | VNSvOutPortB((io_base + ii), |
d4855fe1 | 249 | *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); |
bc5cf656 | 250 | |
c2d845de | 251 | MACvSelectPage0(io_base); |
5449c685 | 252 | |
9ab81fb7 | 253 | /* restore RCR,TCR,IMR... */ |
bc5cf656 | 254 | for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) |
c2d845de | 255 | VNSvOutPortB(io_base + ii, *(pbyCxtBuf + ii)); |
bc5cf656 | 256 | |
9ab81fb7 | 257 | /* restore MAC Config. */ |
bc5cf656 | 258 | for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) |
c2d845de | 259 | VNSvOutPortB(io_base + ii, *(pbyCxtBuf + ii)); |
bc5cf656 | 260 | |
c2d845de | 261 | VNSvOutPortB(io_base + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG)); |
5449c685 | 262 | |
9ab81fb7 | 263 | /* restore PS Config. */ |
bc5cf656 | 264 | for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) |
c2d845de | 265 | VNSvOutPortB(io_base + ii, *(pbyCxtBuf + ii)); |
5449c685 | 266 | |
9ab81fb7 | 267 | /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */ |
c2d845de | 268 | VNSvOutPortD(io_base + MAC_REG_TXDMAPTR0, |
d4855fe1 | 269 | *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)); |
c2d845de | 270 | VNSvOutPortD(io_base + MAC_REG_AC0DMAPTR, |
d4855fe1 | 271 | *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)); |
c2d845de | 272 | VNSvOutPortD(io_base + MAC_REG_BCNDMAPTR, |
d4855fe1 GB |
273 | *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR)); |
274 | ||
c2d845de | 275 | VNSvOutPortD(io_base + MAC_REG_RXDMAPTR0, |
d4855fe1 GB |
276 | *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)); |
277 | ||
c2d845de | 278 | VNSvOutPortD(io_base + MAC_REG_RXDMAPTR1, |
d4855fe1 | 279 | *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)); |
5449c685 FB |
280 | } |
281 | ||
5449c685 FB |
282 | /* |
283 | * Description: | |
284 | * Software Reset MAC | |
285 | * | |
286 | * Parameters: | |
287 | * In: | |
c2d845de | 288 | * io_base - Base Address for MAC |
5449c685 FB |
289 | * Out: |
290 | * none | |
291 | * | |
5a5a2a6a | 292 | * Return Value: true if Reset Success; otherwise false |
5449c685 FB |
293 | * |
294 | */ | |
f9f853af | 295 | bool MACbSoftwareReset(struct vnt_private *priv) |
5449c685 | 296 | { |
c2d845de | 297 | void __iomem *io_base = priv->PortOffset; |
c3504bfd JP |
298 | unsigned short ww; |
299 | ||
9ab81fb7 | 300 | /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */ |
c2d845de | 301 | VNSvOutPortB(io_base + MAC_REG_HOSTCR, 0x01); |
c3504bfd JP |
302 | |
303 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { | |
f205e8d1 | 304 | if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST)) |
c3504bfd JP |
305 | break; |
306 | } | |
307 | if (ww == W_MAX_TIMEOUT) | |
308 | return false; | |
309 | return true; | |
5449c685 FB |
310 | } |
311 | ||
312 | /* | |
313 | * Description: | |
314 | * save some important register's value, then do reset, then restore register's value | |
315 | * | |
316 | * Parameters: | |
317 | * In: | |
c2d845de | 318 | * io_base - Base Address for MAC |
5449c685 FB |
319 | * Out: |
320 | * none | |
321 | * | |
5a5a2a6a | 322 | * Return Value: true if success; otherwise false |
5449c685 FB |
323 | * |
324 | */ | |
f9f853af | 325 | bool MACbSafeSoftwareReset(struct vnt_private *priv) |
5449c685 | 326 | { |
c3504bfd JP |
327 | unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1]; |
328 | bool bRetVal; | |
329 | ||
9ab81fb7 MS |
330 | /* PATCH.... |
331 | * save some important register's value, then do | |
332 | * reset, then restore register's value | |
333 | */ | |
334 | /* save MAC context */ | |
f9f853af | 335 | MACvSaveContext(priv, abyTmpRegData); |
9ab81fb7 | 336 | /* do reset */ |
f9f853af | 337 | bRetVal = MACbSoftwareReset(priv); |
9ab81fb7 | 338 | /* restore MAC context, except CR0 */ |
f9f853af | 339 | MACvRestoreContext(priv, abyTmpRegData); |
c3504bfd JP |
340 | |
341 | return bRetVal; | |
5449c685 FB |
342 | } |
343 | ||
344 | /* | |
345 | * Description: | |
b1797dfd | 346 | * Turn Off MAC Rx |
5449c685 FB |
347 | * |
348 | * Parameters: | |
349 | * In: | |
c2d845de | 350 | * io_base - Base Address for MAC |
5449c685 FB |
351 | * Out: |
352 | * none | |
353 | * | |
5a5a2a6a | 354 | * Return Value: true if success; otherwise false |
5449c685 FB |
355 | * |
356 | */ | |
f9f853af | 357 | bool MACbSafeRxOff(struct vnt_private *priv) |
5449c685 | 358 | { |
c2d845de | 359 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 360 | unsigned short ww; |
c3504bfd | 361 | |
9ab81fb7 | 362 | /* turn off wow temp for turn off Rx safely */ |
c3504bfd | 363 | |
9ab81fb7 | 364 | /* Clear RX DMA0,1 */ |
c2d845de MP |
365 | VNSvOutPortD(io_base + MAC_REG_RXDMACTL0, DMACTL_CLRRUN); |
366 | VNSvOutPortD(io_base + MAC_REG_RXDMACTL1, DMACTL_CLRRUN); | |
c3504bfd | 367 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
e52ab0ec | 368 | if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) |
c3504bfd JP |
369 | break; |
370 | } | |
371 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 372 | pr_debug(" DBG_PORT80(0x10)\n"); |
a4ef27ad | 373 | return false; |
c3504bfd JP |
374 | } |
375 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { | |
e52ab0ec | 376 | if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) |
c3504bfd JP |
377 | break; |
378 | } | |
379 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 380 | pr_debug(" DBG_PORT80(0x11)\n"); |
a4ef27ad | 381 | return false; |
c3504bfd JP |
382 | } |
383 | ||
9ab81fb7 | 384 | /* try to safe shutdown RX */ |
c2d845de | 385 | MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_RXON); |
9ab81fb7 | 386 | /* W_MAX_TIMEOUT is the timeout period */ |
c3504bfd | 387 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 388 | if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST)) |
c3504bfd JP |
389 | break; |
390 | } | |
391 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 392 | pr_debug(" DBG_PORT80(0x12)\n"); |
a4ef27ad | 393 | return false; |
c3504bfd JP |
394 | } |
395 | return true; | |
5449c685 FB |
396 | } |
397 | ||
398 | /* | |
399 | * Description: | |
b1797dfd | 400 | * Turn Off MAC Tx |
5449c685 FB |
401 | * |
402 | * Parameters: | |
403 | * In: | |
c2d845de | 404 | * io_base - Base Address for MAC |
5449c685 FB |
405 | * Out: |
406 | * none | |
407 | * | |
5a5a2a6a | 408 | * Return Value: true if success; otherwise false |
5449c685 FB |
409 | * |
410 | */ | |
f9f853af | 411 | bool MACbSafeTxOff(struct vnt_private *priv) |
5449c685 | 412 | { |
c2d845de | 413 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 414 | unsigned short ww; |
c3504bfd | 415 | |
9ab81fb7 MS |
416 | /* Clear TX DMA */ |
417 | /* Tx0 */ | |
c2d845de | 418 | VNSvOutPortD(io_base + MAC_REG_TXDMACTL0, DMACTL_CLRRUN); |
9ab81fb7 | 419 | /* AC0 */ |
c2d845de | 420 | VNSvOutPortD(io_base + MAC_REG_AC0DMACTL, DMACTL_CLRRUN); |
c3504bfd | 421 | |
c3504bfd | 422 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
e52ab0ec | 423 | if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) |
c3504bfd JP |
424 | break; |
425 | } | |
426 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 427 | pr_debug(" DBG_PORT80(0x20)\n"); |
a4ef27ad | 428 | return false; |
c3504bfd JP |
429 | } |
430 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { | |
e52ab0ec | 431 | if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) |
c3504bfd JP |
432 | break; |
433 | } | |
434 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 435 | pr_debug(" DBG_PORT80(0x21)\n"); |
a4ef27ad | 436 | return false; |
c3504bfd JP |
437 | } |
438 | ||
9ab81fb7 | 439 | /* try to safe shutdown TX */ |
c2d845de | 440 | MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_TXON); |
c3504bfd | 441 | |
9ab81fb7 | 442 | /* W_MAX_TIMEOUT is the timeout period */ |
c3504bfd | 443 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 444 | if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST)) |
c3504bfd JP |
445 | break; |
446 | } | |
447 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 448 | pr_debug(" DBG_PORT80(0x24)\n"); |
a4ef27ad | 449 | return false; |
c3504bfd JP |
450 | } |
451 | return true; | |
5449c685 FB |
452 | } |
453 | ||
454 | /* | |
455 | * Description: | |
456 | * Stop MAC function | |
457 | * | |
458 | * Parameters: | |
459 | * In: | |
c2d845de | 460 | * io_base - Base Address for MAC |
5449c685 FB |
461 | * Out: |
462 | * none | |
463 | * | |
5a5a2a6a | 464 | * Return Value: true if success; otherwise false |
5449c685 FB |
465 | * |
466 | */ | |
f9f853af | 467 | bool MACbSafeStop(struct vnt_private *priv) |
5449c685 | 468 | { |
c2d845de | 469 | void __iomem *io_base = priv->PortOffset; |
e1c484db | 470 | |
c2d845de | 471 | MACvRegBitsOff(io_base, MAC_REG_TCR, TCR_AUTOBCNTX); |
c3504bfd | 472 | |
f9f853af | 473 | if (!MACbSafeRxOff(priv)) { |
48caf5a0 | 474 | pr_debug(" MACbSafeRxOff == false)\n"); |
f9f853af | 475 | MACbSafeSoftwareReset(priv); |
c3504bfd JP |
476 | return false; |
477 | } | |
f9f853af | 478 | if (!MACbSafeTxOff(priv)) { |
48caf5a0 | 479 | pr_debug(" MACbSafeTxOff == false)\n"); |
f9f853af | 480 | MACbSafeSoftwareReset(priv); |
c3504bfd JP |
481 | return false; |
482 | } | |
483 | ||
c2d845de | 484 | MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN); |
c3504bfd JP |
485 | |
486 | return true; | |
5449c685 FB |
487 | } |
488 | ||
489 | /* | |
490 | * Description: | |
491 | * Shut Down MAC | |
492 | * | |
493 | * Parameters: | |
494 | * In: | |
c2d845de | 495 | * io_base - Base Address for MAC |
5449c685 FB |
496 | * Out: |
497 | * none | |
498 | * | |
5a5a2a6a | 499 | * Return Value: true if success; otherwise false |
5449c685 FB |
500 | * |
501 | */ | |
f9f853af | 502 | bool MACbShutdown(struct vnt_private *priv) |
5449c685 | 503 | { |
c2d845de | 504 | void __iomem *io_base = priv->PortOffset; |
9ab81fb7 | 505 | /* disable MAC IMR */ |
c2d845de | 506 | MACvIntDisable(io_base); |
f9f853af | 507 | MACvSetLoopbackMode(priv, MAC_LB_INTERNAL); |
9ab81fb7 | 508 | /* stop the adapter */ |
f9f853af MP |
509 | if (!MACbSafeStop(priv)) { |
510 | MACvSetLoopbackMode(priv, MAC_LB_NONE); | |
c3504bfd JP |
511 | return false; |
512 | } | |
f9f853af | 513 | MACvSetLoopbackMode(priv, MAC_LB_NONE); |
c3504bfd | 514 | return true; |
5449c685 FB |
515 | } |
516 | ||
517 | /* | |
518 | * Description: | |
519 | * Initialize MAC | |
520 | * | |
521 | * Parameters: | |
522 | * In: | |
c2d845de | 523 | * io_base - Base Address for MAC |
5449c685 FB |
524 | * Out: |
525 | * none | |
526 | * | |
527 | * Return Value: none | |
528 | * | |
529 | */ | |
f9f853af | 530 | void MACvInitialize(struct vnt_private *priv) |
5449c685 | 531 | { |
c2d845de | 532 | void __iomem *io_base = priv->PortOffset; |
9ab81fb7 | 533 | /* clear sticky bits */ |
c2d845de | 534 | MACvClearStckDS(io_base); |
9ab81fb7 | 535 | /* disable force PME-enable */ |
c2d845de | 536 | VNSvOutPortB(io_base + MAC_REG_PMC1, PME_OVR); |
9ab81fb7 | 537 | /* only 3253 A */ |
c3504bfd | 538 | |
9ab81fb7 | 539 | /* do reset */ |
f9f853af | 540 | MACbSoftwareReset(priv); |
c3504bfd | 541 | |
9ab81fb7 | 542 | /* reset TSF counter */ |
c2d845de | 543 | VNSvOutPortB(io_base + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); |
9ab81fb7 | 544 | /* enable TSF counter */ |
c2d845de | 545 | VNSvOutPortB(io_base + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); |
5449c685 FB |
546 | } |
547 | ||
548 | /* | |
549 | * Description: | |
550 | * Set the chip with current rx descriptor address | |
551 | * | |
552 | * Parameters: | |
553 | * In: | |
c2d845de | 554 | * io_base - Base Address for MAC |
5449c685 FB |
555 | * dwCurrDescAddr - Descriptor Address |
556 | * Out: | |
557 | * none | |
558 | * | |
559 | * Return Value: none | |
560 | * | |
561 | */ | |
f9f853af | 562 | void MACvSetCurrRx0DescAddr(struct vnt_private *priv, unsigned long dwCurrDescAddr) |
5449c685 | 563 | { |
c2d845de | 564 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 565 | unsigned short ww; |
c3504bfd JP |
566 | unsigned char byOrgDMACtl; |
567 | ||
c2d845de | 568 | VNSvInPortB(io_base + MAC_REG_RXDMACTL0, &byOrgDMACtl); |
bc5cf656 | 569 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 570 | VNSvOutPortB(io_base + MAC_REG_RXDMACTL0+2, DMACTL_RUN); |
bc5cf656 | 571 | |
c3504bfd | 572 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 573 | if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) |
c3504bfd JP |
574 | break; |
575 | } | |
bc5cf656 | 576 | |
c2d845de | 577 | VNSvOutPortD(io_base + MAC_REG_RXDMAPTR0, dwCurrDescAddr); |
bc5cf656 | 578 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 579 | VNSvOutPortB(io_base + MAC_REG_RXDMACTL0, DMACTL_RUN); |
5449c685 FB |
580 | } |
581 | ||
582 | /* | |
583 | * Description: | |
584 | * Set the chip with current rx descriptor address | |
585 | * | |
586 | * Parameters: | |
587 | * In: | |
c2d845de | 588 | * io_base - Base Address for MAC |
5449c685 FB |
589 | * dwCurrDescAddr - Descriptor Address |
590 | * Out: | |
591 | * none | |
592 | * | |
593 | * Return Value: none | |
594 | * | |
595 | */ | |
f9f853af | 596 | void MACvSetCurrRx1DescAddr(struct vnt_private *priv, unsigned long dwCurrDescAddr) |
5449c685 | 597 | { |
c2d845de | 598 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 599 | unsigned short ww; |
c3504bfd JP |
600 | unsigned char byOrgDMACtl; |
601 | ||
c2d845de | 602 | VNSvInPortB(io_base + MAC_REG_RXDMACTL1, &byOrgDMACtl); |
bc5cf656 | 603 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 604 | VNSvOutPortB(io_base + MAC_REG_RXDMACTL1+2, DMACTL_RUN); |
bc5cf656 | 605 | |
c3504bfd | 606 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 607 | if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) |
c3504bfd JP |
608 | break; |
609 | } | |
bc5cf656 | 610 | |
c2d845de | 611 | VNSvOutPortD(io_base + MAC_REG_RXDMAPTR1, dwCurrDescAddr); |
bc5cf656 | 612 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 613 | VNSvOutPortB(io_base + MAC_REG_RXDMACTL1, DMACTL_RUN); |
bc5cf656 | 614 | |
5449c685 FB |
615 | } |
616 | ||
617 | /* | |
618 | * Description: | |
619 | * Set the chip with current tx0 descriptor address | |
620 | * | |
621 | * Parameters: | |
622 | * In: | |
c2d845de | 623 | * io_base - Base Address for MAC |
5449c685 FB |
624 | * dwCurrDescAddr - Descriptor Address |
625 | * Out: | |
626 | * none | |
627 | * | |
628 | * Return Value: none | |
629 | * | |
630 | */ | |
f9f853af | 631 | void MACvSetCurrTx0DescAddrEx(struct vnt_private *priv, |
d4855fe1 | 632 | unsigned long dwCurrDescAddr) |
5449c685 | 633 | { |
c2d845de | 634 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 635 | unsigned short ww; |
c3504bfd JP |
636 | unsigned char byOrgDMACtl; |
637 | ||
c2d845de | 638 | VNSvInPortB(io_base + MAC_REG_TXDMACTL0, &byOrgDMACtl); |
bc5cf656 | 639 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 640 | VNSvOutPortB(io_base + MAC_REG_TXDMACTL0+2, DMACTL_RUN); |
bc5cf656 | 641 | |
c3504bfd | 642 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 643 | if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) |
c3504bfd JP |
644 | break; |
645 | } | |
bc5cf656 | 646 | |
c2d845de | 647 | VNSvOutPortD(io_base + MAC_REG_TXDMAPTR0, dwCurrDescAddr); |
bc5cf656 | 648 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 649 | VNSvOutPortB(io_base + MAC_REG_TXDMACTL0, DMACTL_RUN); |
5449c685 FB |
650 | } |
651 | ||
652 | /* | |
653 | * Description: | |
654 | * Set the chip with current AC0 descriptor address | |
655 | * | |
656 | * Parameters: | |
657 | * In: | |
c2d845de | 658 | * io_base - Base Address for MAC |
5449c685 FB |
659 | * dwCurrDescAddr - Descriptor Address |
660 | * Out: | |
661 | * none | |
662 | * | |
663 | * Return Value: none | |
664 | * | |
665 | */ | |
9ab81fb7 | 666 | /* TxDMA1 = AC0DMA */ |
f9f853af | 667 | void MACvSetCurrAC0DescAddrEx(struct vnt_private *priv, |
d4855fe1 | 668 | unsigned long dwCurrDescAddr) |
5449c685 | 669 | { |
c2d845de | 670 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 671 | unsigned short ww; |
c3504bfd JP |
672 | unsigned char byOrgDMACtl; |
673 | ||
c2d845de | 674 | VNSvInPortB(io_base + MAC_REG_AC0DMACTL, &byOrgDMACtl); |
bc5cf656 | 675 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 676 | VNSvOutPortB(io_base + MAC_REG_AC0DMACTL+2, DMACTL_RUN); |
bc5cf656 | 677 | |
c3504bfd | 678 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
f205e8d1 | 679 | if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) |
c3504bfd JP |
680 | break; |
681 | } | |
4188e586 | 682 | if (ww == W_MAX_TIMEOUT) |
48caf5a0 | 683 | pr_debug(" DBG_PORT80(0x26)\n"); |
c2d845de | 684 | VNSvOutPortD(io_base + MAC_REG_AC0DMAPTR, dwCurrDescAddr); |
bc5cf656 | 685 | if (byOrgDMACtl & DMACTL_RUN) |
c2d845de | 686 | VNSvOutPortB(io_base + MAC_REG_AC0DMACTL, DMACTL_RUN); |
5449c685 FB |
687 | } |
688 | ||
f9f853af | 689 | void MACvSetCurrTXDescAddr(int iTxType, struct vnt_private *priv, |
d4855fe1 | 690 | unsigned long dwCurrDescAddr) |
5449c685 | 691 | { |
bc5cf656 | 692 | if (iTxType == TYPE_AC0DMA) |
f9f853af | 693 | MACvSetCurrAC0DescAddrEx(priv, dwCurrDescAddr); |
bc5cf656 | 694 | else if (iTxType == TYPE_TXDMA0) |
f9f853af | 695 | MACvSetCurrTx0DescAddrEx(priv, dwCurrDescAddr); |
5449c685 FB |
696 | } |
697 | ||
698 | /* | |
699 | * Description: | |
700 | * Micro Second Delay via MAC | |
701 | * | |
702 | * Parameters: | |
703 | * In: | |
c2d845de | 704 | * io_base - Base Address for MAC |
5449c685 FB |
705 | * uDelay - Delay time (timer resolution is 4 us) |
706 | * Out: | |
707 | * none | |
708 | * | |
709 | * Return Value: none | |
710 | * | |
711 | */ | |
f9f853af | 712 | void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay) |
5449c685 | 713 | { |
c2d845de | 714 | void __iomem *io_base = priv->PortOffset; |
c3504bfd JP |
715 | unsigned char byValue; |
716 | unsigned int uu, ii; | |
717 | ||
c2d845de MP |
718 | VNSvOutPortB(io_base + MAC_REG_TMCTL0, 0); |
719 | VNSvOutPortD(io_base + MAC_REG_TMDATA0, uDelay); | |
720 | VNSvOutPortB(io_base + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); | |
9ab81fb7 | 721 | for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */ |
c3504bfd | 722 | for (uu = 0; uu < uDelay; uu++) { |
c2d845de | 723 | VNSvInPortB(io_base + MAC_REG_TMCTL0, &byValue); |
c3504bfd JP |
724 | if ((byValue == 0) || |
725 | (byValue & TMCTL_TSUSP)) { | |
c2d845de | 726 | VNSvOutPortB(io_base + MAC_REG_TMCTL0, 0); |
c3504bfd JP |
727 | return; |
728 | } | |
729 | } | |
730 | } | |
c2d845de | 731 | VNSvOutPortB(io_base + MAC_REG_TMCTL0, 0); |
5449c685 FB |
732 | } |
733 | ||
5449c685 FB |
734 | /* |
735 | * Description: | |
736 | * Micro Second One shot timer via MAC | |
737 | * | |
738 | * Parameters: | |
739 | * In: | |
c2d845de | 740 | * io_base - Base Address for MAC |
5449c685 FB |
741 | * uDelay - Delay time |
742 | * Out: | |
743 | * none | |
744 | * | |
745 | * Return Value: none | |
746 | * | |
747 | */ | |
f9f853af | 748 | void MACvOneShotTimer1MicroSec(struct vnt_private *priv, unsigned int uDelayTime) |
5449c685 | 749 | { |
c2d845de | 750 | void __iomem *io_base = priv->PortOffset; |
f9f853af | 751 | |
c2d845de MP |
752 | VNSvOutPortB(io_base + MAC_REG_TMCTL1, 0); |
753 | VNSvOutPortD(io_base + MAC_REG_TMDATA1, uDelayTime); | |
754 | VNSvOutPortB(io_base + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE)); | |
5449c685 FB |
755 | } |
756 | ||
f9f853af | 757 | void MACvSetMISCFifo(struct vnt_private *priv, unsigned short wOffset, |
d4855fe1 | 758 | unsigned long dwData) |
5449c685 | 759 | { |
c2d845de | 760 | void __iomem *io_base = priv->PortOffset; |
f9f853af | 761 | |
c3504bfd JP |
762 | if (wOffset > 273) |
763 | return; | |
c2d845de MP |
764 | VNSvOutPortW(io_base + MAC_REG_MISCFFNDEX, wOffset); |
765 | VNSvOutPortD(io_base + MAC_REG_MISCFFDATA, dwData); | |
766 | VNSvOutPortW(io_base + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); | |
5449c685 FB |
767 | } |
768 | ||
f9f853af | 769 | bool MACbPSWakeup(struct vnt_private *priv) |
5449c685 | 770 | { |
c2d845de | 771 | void __iomem *io_base = priv->PortOffset; |
c3504bfd JP |
772 | unsigned char byOrgValue; |
773 | unsigned int ww; | |
9ab81fb7 | 774 | /* Read PSCTL */ |
f9f853af | 775 | if (MACbIsRegBitsOff(priv, MAC_REG_PSCTL, PSCTL_PS)) |
c3504bfd | 776 | return true; |
bc5cf656 | 777 | |
9ab81fb7 | 778 | /* Disable PS */ |
c2d845de | 779 | MACvRegBitsOff(io_base, MAC_REG_PSCTL, PSCTL_PSEN); |
c3504bfd | 780 | |
9ab81fb7 | 781 | /* Check if SyncFlushOK */ |
c3504bfd | 782 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
c2d845de | 783 | VNSvInPortB(io_base + MAC_REG_PSCTL, &byOrgValue); |
c3504bfd JP |
784 | if (byOrgValue & PSCTL_WAKEDONE) |
785 | break; | |
786 | } | |
787 | if (ww == W_MAX_TIMEOUT) { | |
48caf5a0 | 788 | pr_debug(" DBG_PORT80(0x33)\n"); |
c3504bfd JP |
789 | return false; |
790 | } | |
791 | return true; | |
5449c685 FB |
792 | } |
793 | ||
794 | /* | |
795 | * Description: | |
796 | * Set the Key by MISCFIFO | |
797 | * | |
798 | * Parameters: | |
799 | * In: | |
c2d845de | 800 | * io_base - Base Address for MAC |
5449c685 FB |
801 | * |
802 | * Out: | |
803 | * none | |
804 | * | |
805 | * Return Value: none | |
806 | * | |
807 | */ | |
808 | ||
f9f853af | 809 | void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, |
d4855fe1 GB |
810 | unsigned int uEntryIdx, unsigned int uKeyIdx, |
811 | unsigned char *pbyAddr, u32 *pdwKey, | |
812 | unsigned char byLocalID) | |
5449c685 | 813 | { |
c2d845de | 814 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 815 | unsigned short wOffset; |
4dbc77c0 | 816 | u32 dwData; |
c3504bfd JP |
817 | int ii; |
818 | ||
819 | if (byLocalID <= 1) | |
820 | return; | |
821 | ||
48caf5a0 | 822 | pr_debug("MACvSetKeyEntry\n"); |
c3504bfd JP |
823 | wOffset = MISCFIFO_KEYETRY0; |
824 | wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); | |
825 | ||
826 | dwData = 0; | |
827 | dwData |= wKeyCtl; | |
828 | dwData <<= 16; | |
829 | dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); | |
48caf5a0 JP |
830 | pr_debug("1. wOffset: %d, Data: %X, KeyCtl:%X\n", |
831 | wOffset, dwData, wKeyCtl); | |
c3504bfd | 832 | |
c2d845de MP |
833 | VNSvOutPortW(io_base + MAC_REG_MISCFFNDEX, wOffset); |
834 | VNSvOutPortD(io_base + MAC_REG_MISCFFDATA, dwData); | |
835 | VNSvOutPortW(io_base + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); | |
c3504bfd JP |
836 | wOffset++; |
837 | ||
838 | dwData = 0; | |
839 | dwData |= *(pbyAddr+3); | |
840 | dwData <<= 8; | |
841 | dwData |= *(pbyAddr+2); | |
842 | dwData <<= 8; | |
843 | dwData |= *(pbyAddr+1); | |
844 | dwData <<= 8; | |
845 | dwData |= *(pbyAddr+0); | |
48caf5a0 | 846 | pr_debug("2. wOffset: %d, Data: %X\n", wOffset, dwData); |
c3504bfd | 847 | |
c2d845de MP |
848 | VNSvOutPortW(io_base + MAC_REG_MISCFFNDEX, wOffset); |
849 | VNSvOutPortD(io_base + MAC_REG_MISCFFDATA, dwData); | |
850 | VNSvOutPortW(io_base + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); | |
c3504bfd JP |
851 | wOffset++; |
852 | ||
853 | wOffset += (uKeyIdx * 4); | |
854 | for (ii = 0; ii < 4; ii++) { | |
9ab81fb7 | 855 | /* always push 128 bits */ |
48caf5a0 JP |
856 | pr_debug("3.(%d) wOffset: %d, Data: %X\n", |
857 | ii, wOffset+ii, *pdwKey); | |
c2d845de MP |
858 | VNSvOutPortW(io_base + MAC_REG_MISCFFNDEX, wOffset+ii); |
859 | VNSvOutPortD(io_base + MAC_REG_MISCFFDATA, *pdwKey++); | |
860 | VNSvOutPortW(io_base + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); | |
c3504bfd | 861 | } |
5449c685 FB |
862 | } |
863 | ||
5449c685 FB |
864 | /* |
865 | * Description: | |
866 | * Disable the Key Entry by MISCFIFO | |
867 | * | |
868 | * Parameters: | |
869 | * In: | |
c2d845de | 870 | * io_base - Base Address for MAC |
5449c685 FB |
871 | * |
872 | * Out: | |
873 | * none | |
874 | * | |
875 | * Return Value: none | |
876 | * | |
877 | */ | |
f9f853af | 878 | void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx) |
5449c685 | 879 | { |
c2d845de | 880 | void __iomem *io_base = priv->PortOffset; |
c3504bfd | 881 | unsigned short wOffset; |
5449c685 | 882 | |
c3504bfd JP |
883 | wOffset = MISCFIFO_KEYETRY0; |
884 | wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); | |
5449c685 | 885 | |
c2d845de MP |
886 | VNSvOutPortW(io_base + MAC_REG_MISCFFNDEX, wOffset); |
887 | VNSvOutPortD(io_base + MAC_REG_MISCFFDATA, 0); | |
888 | VNSvOutPortW(io_base + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); | |
5449c685 | 889 | } |