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