Loading...
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 *
19 *
20 * File: mac.c
21 *
22 * Purpose: MAC routines
23 *
24 * Author: Tevin Chen
25 *
26 * Date: May 21, 1996
27 *
28 * Functions:
29 * MACvReadAllRegs - Read All MAC Registers to buffer
30 * MACbIsRegBitsOn - Test if All test Bits On
31 * MACbIsRegBitsOff - Test if All test Bits Off
32 * MACbIsIntDisable - Test if MAC interrupt disable
33 * MACbyReadMultiAddr - Read Multicast Address Mask Pattern
34 * MACvWriteMultiAddr - Write Multicast Address Mask Pattern
35 * MACvSetMultiAddrByHash - Set Multicast Address Mask by Hash value
36 * MACvResetMultiAddrByHash - Clear Multicast Address Mask by Hash value
37 * MACvSetRxThreshold - Set Rx Threshold value
38 * MACvGetRxThreshold - Get Rx Threshold value
39 * MACvSetTxThreshold - Set Tx Threshold value
40 * MACvGetTxThreshold - Get Tx Threshold value
41 * MACvSetDmaLength - Set Dma Length value
42 * MACvGetDmaLength - Get Dma Length value
43 * MACvSetShortRetryLimit - Set 802.11 Short Retry limit
44 * MACvGetShortRetryLimit - Get 802.11 Short Retry limit
45 * MACvSetLongRetryLimit - Set 802.11 Long Retry limit
46 * MACvGetLongRetryLimit - Get 802.11 Long Retry limit
47 * MACvSetLoopbackMode - Set MAC Loopback Mode
48 * MACbIsInLoopbackMode - Test if MAC in Loopback mode
49 * MACvSetPacketFilter - Set MAC Address Filter
50 * MACvSaveContext - Save Context of MAC Registers
51 * MACvRestoreContext - Restore Context of MAC Registers
52 * MACbCompareContext - Compare if values of MAC Registers same as Context
53 * MACbSoftwareReset - Software Reset MAC
54 * MACbSafeRxOff - Turn Off MAC Rx
55 * MACbSafeTxOff - Turn Off MAC Tx
56 * MACbSafeStop - Stop MAC function
57 * MACbShutdown - Shut down MAC
58 * MACvInitialize - Initialize MAC
59 * MACvSetCurrRxDescAddr - Set Rx Descriptors Address
60 * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
61 * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
62 * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
63 *
64 * Revision History:
65 * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53
66 * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& MACvEnableBusSusEn()
67 * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry
68 *
69 */
70
71#include "tmacro.h"
72#include "tether.h"
73#include "mac.h"
74
75unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
76/*--------------------- Static Definitions -------------------------*/
77//static int msglevel =MSG_LEVEL_DEBUG;
78static int msglevel = MSG_LEVEL_INFO;
79/*--------------------- Static Classes ----------------------------*/
80
81/*--------------------- Static Variables --------------------------*/
82
83/*--------------------- Static Functions --------------------------*/
84
85/*--------------------- Export Variables --------------------------*/
86
87/*--------------------- Export Functions --------------------------*/
88
89/*
90 * Description:
91 * Read All MAC Registers to buffer
92 *
93 * Parameters:
94 * In:
95 * dwIoBase - Base Address for MAC
96 * Out:
97 * pbyMacRegs - buffer to read
98 *
99 * Return Value: none
100 *
101 */
102void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs)
103{
104 int ii;
105
106 // read page0 register
107 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
108 VNSvInPortB(dwIoBase + ii, pbyMacRegs);
109 pbyMacRegs++;
110 }
111
112 MACvSelectPage1(dwIoBase);
113
114 // read page1 register
115 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
116 VNSvInPortB(dwIoBase + ii, pbyMacRegs);
117 pbyMacRegs++;
118 }
119
120 MACvSelectPage0(dwIoBase);
121}
122
123/*
124 * Description:
125 * Test if all test bits on
126 *
127 * Parameters:
128 * In:
129 * dwIoBase - Base Address for MAC
130 * byRegOfs - Offset of MAC Register
131 * byTestBits - Test bits
132 * Out:
133 * none
134 *
135 * Return Value: true if all test bits On; otherwise false
136 *
137 */
138bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
139{
140 unsigned char byData;
141
142 VNSvInPortB(dwIoBase + byRegOfs, &byData);
143 return (byData & byTestBits) == byTestBits;
144}
145
146/*
147 * Description:
148 * Test if all test bits off
149 *
150 * Parameters:
151 * In:
152 * dwIoBase - Base Address for MAC
153 * byRegOfs - Offset of MAC Register
154 * byTestBits - Test bits
155 * Out:
156 * none
157 *
158 * Return Value: true if all test bits Off; otherwise false
159 *
160 */
161bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
162{
163 unsigned char byData;
164
165 VNSvInPortB(dwIoBase + byRegOfs, &byData);
166 return !(byData & byTestBits);
167}
168
169/*
170 * Description:
171 * Test if MAC interrupt disable
172 *
173 * Parameters:
174 * In:
175 * dwIoBase - Base Address for MAC
176 * Out:
177 * none
178 *
179 * Return Value: true if interrupt is disable; otherwise false
180 *
181 */
182bool MACbIsIntDisable(unsigned long dwIoBase)
183{
184 unsigned long dwData;
185
186 VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
187 if (dwData != 0)
188 return false;
189
190 return true;
191}
192
193/*
194 * Description:
195 * Read MAC Multicast Address Mask
196 *
197 * Parameters:
198 * In:
199 * dwIoBase - Base Address for MAC
200 * uByteidx - Index of Mask
201 * Out:
202 * none
203 *
204 * Return Value: Mask Value read
205 *
206 */
207unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx)
208{
209 unsigned char byData;
210
211 MACvSelectPage1(dwIoBase);
212 VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData);
213 MACvSelectPage0(dwIoBase);
214 return byData;
215}
216
217/*
218 * Description:
219 * Write MAC Multicast Address Mask
220 *
221 * Parameters:
222 * In:
223 * dwIoBase - Base Address for MAC
224 * uByteidx - Index of Mask
225 * byData - Mask Value to write
226 * Out:
227 * none
228 *
229 * Return Value: none
230 *
231 */
232void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData)
233{
234 MACvSelectPage1(dwIoBase);
235 VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData);
236 MACvSelectPage0(dwIoBase);
237}
238
239/*
240 * Description:
241 * Set this hash index into multicast address register bit
242 *
243 * Parameters:
244 * In:
245 * dwIoBase - Base Address for MAC
246 * byHashIdx - Hash index to set
247 * Out:
248 * none
249 *
250 * Return Value: none
251 *
252 */
253void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
254{
255 unsigned int uByteIdx;
256 unsigned char byBitMask;
257 unsigned char byOrgValue;
258
259 // calculate byte position
260 uByteIdx = byHashIdx / 8;
261 ASSERT(uByteIdx < 8);
262 // calculate bit position
263 byBitMask = 1;
264 byBitMask <<= (byHashIdx % 8);
265 // turn on the bit
266 byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
267 MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask));
268}
269
270/*
271 * Description:
272 * Reset this hash index into multicast address register bit
273 *
274 * Parameters:
275 * In:
276 * dwIoBase - Base Address for MAC
277 * byHashIdx - Hash index to clear
278 * Out:
279 * none
280 *
281 * Return Value: none
282 *
283 */
284void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
285{
286 unsigned int uByteIdx;
287 unsigned char byBitMask;
288 unsigned char byOrgValue;
289
290 // calculate byte position
291 uByteIdx = byHashIdx / 8;
292 ASSERT(uByteIdx < 8);
293 // calculate bit position
294 byBitMask = 1;
295 byBitMask <<= (byHashIdx % 8);
296 // turn off the bit
297 byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
298 MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask)));
299}
300
301/*
302 * Description:
303 * Set Rx Threshold
304 *
305 * Parameters:
306 * In:
307 * dwIoBase - Base Address for MAC
308 * byThreshold - Threshold Value
309 * Out:
310 * none
311 *
312 * Return Value: none
313 *
314 */
315void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
316{
317 unsigned char byOrgValue;
318
319 ASSERT(byThreshold < 4);
320
321 // set FCR0
322 VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
323 byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4);
324 VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
325}
326
327/*
328 * Description:
329 * Get Rx Threshold
330 *
331 * Parameters:
332 * In:
333 * dwIoBase - Base Address for MAC
334 * Out:
335 * pbyThreshold- Threshold Value Get
336 *
337 * Return Value: none
338 *
339 */
340void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
341{
342 // get FCR0
343 VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
344 *pbyThreshold = (*pbyThreshold >> 4) & 0x03;
345}
346
347/*
348 * Description:
349 * Set Tx Threshold
350 *
351 * Parameters:
352 * In:
353 * dwIoBase - Base Address for MAC
354 * byThreshold - Threshold Value
355 * Out:
356 * none
357 *
358 * Return Value: none
359 *
360 */
361void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
362{
363 unsigned char byOrgValue;
364
365 ASSERT(byThreshold < 4);
366
367 // set FCR0
368 VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
369 byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2);
370 VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
371}
372
373/*
374 * Description:
375 * Get Tx Threshold
376 *
377 * Parameters:
378 * In:
379 * dwIoBase - Base Address for MAC
380 * Out:
381 * pbyThreshold- Threshold Value Get
382 *
383 * Return Value: none
384 *
385 */
386void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
387{
388 // get FCR0
389 VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
390 *pbyThreshold = (*pbyThreshold >> 2) & 0x03;
391}
392
393/*
394 * Description:
395 * Set Dma Length
396 *
397 * Parameters:
398 * In:
399 * dwIoBase - Base Address for MAC
400 * byDmaLength - Dma Length Value
401 * Out:
402 * none
403 *
404 * Return Value: none
405 *
406 */
407void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength)
408{
409 unsigned char byOrgValue;
410
411 ASSERT(byDmaLength < 4);
412
413 // set FCR0
414 VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
415 byOrgValue = (byOrgValue & 0xFC) | byDmaLength;
416 VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
417}
418
419/*
420 * Description:
421 * Get Dma Length
422 *
423 * Parameters:
424 * In:
425 * dwIoBase - Base Address for MAC
426 * Out:
427 * pbyDmaLength- Dma Length Value Get
428 *
429 * Return Value: none
430 *
431 */
432void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength)
433{
434 // get FCR0
435 VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength);
436 *pbyDmaLength &= 0x03;
437}
438
439/*
440 * Description:
441 * Set 802.11 Short Retry Limit
442 *
443 * Parameters:
444 * In:
445 * dwIoBase - Base Address for MAC
446 * byRetryLimit- Retry Limit
447 * Out:
448 * none
449 *
450 * Return Value: none
451 *
452 */
453void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
454{
455 // set SRT
456 VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
457}
458
459/*
460 * Description:
461 * Get 802.11 Short Retry Limit
462 *
463 * Parameters:
464 * In:
465 * dwIoBase - Base Address for MAC
466 * Out:
467 * pbyRetryLimit - Retry Limit Get
468 *
469 * Return Value: none
470 *
471 */
472void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
473{
474 // get SRT
475 VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
476}
477
478/*
479 * Description:
480 * Set 802.11 Long Retry Limit
481 *
482 * Parameters:
483 * In:
484 * dwIoBase - Base Address for MAC
485 * byRetryLimit- Retry Limit
486 * Out:
487 * none
488 *
489 * Return Value: none
490 *
491 */
492void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
493{
494 // set LRT
495 VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
496}
497
498/*
499 * Description:
500 * Get 802.11 Long Retry Limit
501 *
502 * Parameters:
503 * In:
504 * dwIoBase - Base Address for MAC
505 * Out:
506 * pbyRetryLimit - Retry Limit Get
507 *
508 * Return Value: none
509 *
510 */
511void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
512{
513 // get LRT
514 VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit);
515}
516
517/*
518 * Description:
519 * Set MAC Loopback mode
520 *
521 * Parameters:
522 * In:
523 * dwIoBase - Base Address for MAC
524 * byLoopbackMode - Loopback Mode
525 * Out:
526 * none
527 *
528 * Return Value: none
529 *
530 */
531void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode)
532{
533 unsigned char byOrgValue;
534
535 ASSERT(byLoopbackMode < 3);
536 byLoopbackMode <<= 6;
537 // set TCR
538 VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
539 byOrgValue = byOrgValue & 0x3F;
540 byOrgValue = byOrgValue | byLoopbackMode;
541 VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue);
542}
543
544/*
545 * Description:
546 * Test if MAC in Loopback mode
547 *
548 * Parameters:
549 * In:
550 * dwIoBase - Base Address for MAC
551 * Out:
552 * none
553 *
554 * Return Value: true if in Loopback mode; otherwise false
555 *
556 */
557bool MACbIsInLoopbackMode(unsigned long dwIoBase)
558{
559 unsigned char byOrgValue;
560
561 VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
562 if (byOrgValue & (TEST_LBINT | TEST_LBEXT))
563 return true;
564 return false;
565}
566
567/*
568 * Description:
569 * Set MAC Address filter
570 *
571 * Parameters:
572 * In:
573 * dwIoBase - Base Address for MAC
574 * wFilterType - Filter Type
575 * Out:
576 * none
577 *
578 * Return Value: none
579 *
580 */
581void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType)
582{
583 unsigned char byOldRCR;
584 unsigned char byNewRCR = 0;
585
586 // if only in DIRECTED mode, multicast-address will set to zero,
587 // but if other mode exist (e.g. PROMISCUOUS), multicast-address
588 // will be open
589 if (wFilterType & PKT_TYPE_DIRECTED) {
590 // set multicast address to accept none
591 MACvSelectPage1(dwIoBase);
592 VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L);
593 VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L);
594 MACvSelectPage0(dwIoBase);
595 }
596
597 if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
598 // set multicast address to accept all
599 MACvSelectPage1(dwIoBase);
600 VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL);
601 VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL);
602 MACvSelectPage0(dwIoBase);
603 }
604
605 if (wFilterType & PKT_TYPE_PROMISCUOUS) {
606 byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST);
607
608 byNewRCR &= ~RCR_BSSID;
609 }
610
611 if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST))
612 byNewRCR |= RCR_MULTICAST;
613
614 if (wFilterType & PKT_TYPE_BROADCAST)
615 byNewRCR |= RCR_BROADCAST;
616
617 if (wFilterType & PKT_TYPE_ERROR_CRC)
618 byNewRCR |= RCR_ERRCRC;
619
620 VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR);
621 if (byNewRCR != byOldRCR) {
622 // Modify the Receive Command Register
623 VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR);
624 }
625}
626
627/*
628 * Description:
629 * Save MAC registers to context buffer
630 *
631 * Parameters:
632 * In:
633 * dwIoBase - Base Address for MAC
634 * Out:
635 * pbyCxtBuf - Context buffer
636 *
637 * Return Value: none
638 *
639 */
640void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
641{
642 int ii;
643
644 // read page0 register
645 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
646 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii));
647 }
648
649 MACvSelectPage1(dwIoBase);
650
651 // read page1 register
652 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
653 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
654 }
655
656 MACvSelectPage0(dwIoBase);
657}
658
659/*
660 * Description:
661 * Restore MAC registers from context buffer
662 *
663 * Parameters:
664 * In:
665 * dwIoBase - Base Address for MAC
666 * pbyCxtBuf - Context buffer
667 * Out:
668 * none
669 *
670 * Return Value: none
671 *
672 */
673void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
674{
675 int ii;
676
677 MACvSelectPage1(dwIoBase);
678 // restore page1
679 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
680 VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
681 }
682 MACvSelectPage0(dwIoBase);
683
684 // restore RCR,TCR,IMR...
685 for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) {
686 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
687 }
688 // restore MAC Config.
689 for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) {
690 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
691 }
692 VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG));
693
694 // restore PS Config.
695 for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) {
696 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
697 }
698
699 // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
700 VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
701 VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
702 VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
703
704 VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
705
706 VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
707}
708
709/*
710 * Description:
711 * Compare if MAC registers same as context buffer
712 *
713 * Parameters:
714 * In:
715 * dwIoBase - Base Address for MAC
716 * pbyCxtBuf - Context buffer
717 * Out:
718 * none
719 *
720 * Return Value: true if all values are the same; otherwise false
721 *
722 */
723bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
724{
725 unsigned long dwData;
726
727 // compare MAC context to determine if this is a power lost init,
728 // return true for power remaining init, return false for power lost init
729
730 // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
731 VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData);
732 if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) {
733 return false;
734 }
735
736 VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData);
737 if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) {
738 return false;
739 }
740
741 VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData);
742 if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) {
743 return false;
744 }
745
746 VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData);
747 if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) {
748 return false;
749 }
750
751 return true;
752}
753
754/*
755 * Description:
756 * Software Reset MAC
757 *
758 * Parameters:
759 * In:
760 * dwIoBase - Base Address for MAC
761 * Out:
762 * none
763 *
764 * Return Value: true if Reset Success; otherwise false
765 *
766 */
767bool MACbSoftwareReset(unsigned long dwIoBase)
768{
769 unsigned char byData;
770 unsigned short ww;
771
772 // turn on HOSTCR_SOFTRST, just write 0x01 to reset
773 //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST);
774 VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01);
775
776 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
777 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
778 if (!(byData & HOSTCR_SOFTRST))
779 break;
780 }
781 if (ww == W_MAX_TIMEOUT)
782 return false;
783 return true;
784}
785
786/*
787 * Description:
788 * save some important register's value, then do reset, then restore register's value
789 *
790 * Parameters:
791 * In:
792 * dwIoBase - Base Address for MAC
793 * Out:
794 * none
795 *
796 * Return Value: true if success; otherwise false
797 *
798 */
799bool MACbSafeSoftwareReset(unsigned long dwIoBase)
800{
801 unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
802 bool bRetVal;
803
804 // PATCH....
805 // save some important register's value, then do
806 // reset, then restore register's value
807
808 // save MAC context
809 MACvSaveContext(dwIoBase, abyTmpRegData);
810 // do reset
811 bRetVal = MACbSoftwareReset(dwIoBase);
812 //BBvSoftwareReset(pDevice->PortOffset);
813 // restore MAC context, except CR0
814 MACvRestoreContext(dwIoBase, abyTmpRegData);
815
816 return bRetVal;
817}
818
819/*
820 * Description:
821 * Trun Off MAC Rx
822 *
823 * Parameters:
824 * In:
825 * dwIoBase - Base Address for MAC
826 * Out:
827 * none
828 *
829 * Return Value: true if success; otherwise false
830 *
831 */
832bool MACbSafeRxOff(unsigned long dwIoBase)
833{
834 unsigned short ww;
835 unsigned long dwData;
836 unsigned char byData;
837
838 // turn off wow temp for turn off Rx safely
839
840 // Clear RX DMA0,1
841 VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN);
842 VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
843 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
844 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
845 if (!(dwData & DMACTL_RUN))
846 break;
847 }
848 if (ww == W_MAX_TIMEOUT) {
849 DBG_PORT80(0x10);
850 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x10)\n");
851 return false;
852 }
853 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
854 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
855 if (!(dwData & DMACTL_RUN))
856 break;
857 }
858 if (ww == W_MAX_TIMEOUT) {
859 DBG_PORT80(0x11);
860 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x11)\n");
861 return false;
862 }
863
864 // try to safe shutdown RX
865 MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);
866 // W_MAX_TIMEOUT is the timeout period
867 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
868 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
869 if (!(byData & HOSTCR_RXONST))
870 break;
871 }
872 if (ww == W_MAX_TIMEOUT) {
873 DBG_PORT80(0x12);
874 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x12)\n");
875 return false;
876 }
877 return true;
878}
879
880/*
881 * Description:
882 * Trun Off MAC Tx
883 *
884 * Parameters:
885 * In:
886 * dwIoBase - Base Address for MAC
887 * Out:
888 * none
889 *
890 * Return Value: true if success; otherwise false
891 *
892 */
893bool MACbSafeTxOff(unsigned long dwIoBase)
894{
895 unsigned short ww;
896 unsigned long dwData;
897 unsigned char byData;
898
899 // Clear TX DMA
900 //Tx0
901 VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN);
902 //AC0
903 VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN);
904
905 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
906 VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
907 if (!(dwData & DMACTL_RUN))
908 break;
909 }
910 if (ww == W_MAX_TIMEOUT) {
911 DBG_PORT80(0x20);
912 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x20)\n");
913 return false;
914 }
915 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
916 VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
917 if (!(dwData & DMACTL_RUN))
918 break;
919 }
920 if (ww == W_MAX_TIMEOUT) {
921 DBG_PORT80(0x21);
922 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x21)\n");
923 return false;
924 }
925
926 // try to safe shutdown TX
927 MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);
928
929 // W_MAX_TIMEOUT is the timeout period
930 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
931 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
932 if (!(byData & HOSTCR_TXONST))
933 break;
934 }
935 if (ww == W_MAX_TIMEOUT) {
936 DBG_PORT80(0x24);
937 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x24)\n");
938 return false;
939 }
940 return true;
941}
942
943/*
944 * Description:
945 * Stop MAC function
946 *
947 * Parameters:
948 * In:
949 * dwIoBase - Base Address for MAC
950 * Out:
951 * none
952 *
953 * Return Value: true if success; otherwise false
954 *
955 */
956bool MACbSafeStop(unsigned long dwIoBase)
957{
958 MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
959
960 if (!MACbSafeRxOff(dwIoBase)) {
961 DBG_PORT80(0xA1);
962 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n");
963 MACbSafeSoftwareReset(dwIoBase);
964 return false;
965 }
966 if (!MACbSafeTxOff(dwIoBase)) {
967 DBG_PORT80(0xA2);
968 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n");
969 MACbSafeSoftwareReset(dwIoBase);
970 return false;
971 }
972
973 MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN);
974
975 return true;
976}
977
978/*
979 * Description:
980 * Shut Down MAC
981 *
982 * Parameters:
983 * In:
984 * dwIoBase - Base Address for MAC
985 * Out:
986 * none
987 *
988 * Return Value: true if success; otherwise false
989 *
990 */
991bool MACbShutdown(unsigned long dwIoBase)
992{
993 // disable MAC IMR
994 MACvIntDisable(dwIoBase);
995 MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL);
996 // stop the adapter
997 if (!MACbSafeStop(dwIoBase)) {
998 MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
999 return false;
1000 }
1001 MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
1002 return true;
1003}
1004
1005/*
1006 * Description:
1007 * Initialize MAC
1008 *
1009 * Parameters:
1010 * In:
1011 * dwIoBase - Base Address for MAC
1012 * Out:
1013 * none
1014 *
1015 * Return Value: none
1016 *
1017 */
1018void MACvInitialize(unsigned long dwIoBase)
1019{
1020 // clear sticky bits
1021 MACvClearStckDS(dwIoBase);
1022 // disable force PME-enable
1023 VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR);
1024 // only 3253 A
1025 /*
1026 MACvPwrEvntDisable(dwIoBase);
1027 // clear power status
1028 VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPSR0, 0x0F0F);
1029 */
1030
1031 // do reset
1032 MACbSoftwareReset(dwIoBase);
1033
1034 // reset TSF counter
1035 VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1036 // enable TSF counter
1037 VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1038
1039 // set packet filter
1040 // receive directed and broadcast address
1041
1042 MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST);
1043}
1044
1045/*
1046 * Description:
1047 * Set the chip with current rx descriptor address
1048 *
1049 * Parameters:
1050 * In:
1051 * dwIoBase - Base Address for MAC
1052 * dwCurrDescAddr - Descriptor Address
1053 * Out:
1054 * none
1055 *
1056 * Return Value: none
1057 *
1058 */
1059void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1060{
1061 unsigned short ww;
1062 unsigned char byData;
1063 unsigned char byOrgDMACtl;
1064
1065 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
1066 if (byOrgDMACtl & DMACTL_RUN) {
1067 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN);
1068 }
1069 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1070 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData);
1071 if (!(byData & DMACTL_RUN))
1072 break;
1073 }
1074 if (ww == W_MAX_TIMEOUT) {
1075 DBG_PORT80(0x13);
1076 }
1077 VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
1078 if (byOrgDMACtl & DMACTL_RUN) {
1079 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
1080 }
1081}
1082
1083/*
1084 * Description:
1085 * Set the chip with current rx descriptor address
1086 *
1087 * Parameters:
1088 * In:
1089 * dwIoBase - Base Address for MAC
1090 * dwCurrDescAddr - Descriptor Address
1091 * Out:
1092 * none
1093 *
1094 * Return Value: none
1095 *
1096 */
1097void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1098{
1099 unsigned short ww;
1100 unsigned char byData;
1101 unsigned char byOrgDMACtl;
1102
1103 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
1104 if (byOrgDMACtl & DMACTL_RUN) {
1105 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
1106 }
1107 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1108 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
1109 if (!(byData & DMACTL_RUN))
1110 break;
1111 }
1112 if (ww == W_MAX_TIMEOUT) {
1113 DBG_PORT80(0x14);
1114 }
1115 VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
1116 if (byOrgDMACtl & DMACTL_RUN) {
1117 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
1118 }
1119}
1120
1121/*
1122 * Description:
1123 * Set the chip with current tx0 descriptor address
1124 *
1125 * Parameters:
1126 * In:
1127 * dwIoBase - Base Address for MAC
1128 * dwCurrDescAddr - Descriptor Address
1129 * Out:
1130 * none
1131 *
1132 * Return Value: none
1133 *
1134 */
1135void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1136{
1137 unsigned short ww;
1138 unsigned char byData;
1139 unsigned char byOrgDMACtl;
1140
1141 VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
1142 if (byOrgDMACtl & DMACTL_RUN) {
1143 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
1144 }
1145 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1146 VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
1147 if (!(byData & DMACTL_RUN))
1148 break;
1149 }
1150 if (ww == W_MAX_TIMEOUT) {
1151 DBG_PORT80(0x25);
1152 }
1153 VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
1154 if (byOrgDMACtl & DMACTL_RUN) {
1155 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
1156 }
1157}
1158
1159/*
1160 * Description:
1161 * Set the chip with current AC0 descriptor address
1162 *
1163 * Parameters:
1164 * In:
1165 * dwIoBase - Base Address for MAC
1166 * dwCurrDescAddr - Descriptor Address
1167 * Out:
1168 * none
1169 *
1170 * Return Value: none
1171 *
1172 */
1173//TxDMA1 = AC0DMA
1174void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1175{
1176 unsigned short ww;
1177 unsigned char byData;
1178 unsigned char byOrgDMACtl;
1179
1180 VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
1181 if (byOrgDMACtl & DMACTL_RUN) {
1182 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
1183 }
1184 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1185 VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
1186 if (!(byData & DMACTL_RUN))
1187 break;
1188 }
1189 if (ww == W_MAX_TIMEOUT) {
1190 DBG_PORT80(0x26);
1191 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x26)\n");
1192 }
1193 VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
1194 if (byOrgDMACtl & DMACTL_RUN) {
1195 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
1196 }
1197}
1198
1199void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1200{
1201 if (iTxType == TYPE_AC0DMA) {
1202 MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
1203 } else if (iTxType == TYPE_TXDMA0) {
1204 MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr);
1205 }
1206}
1207
1208/*
1209 * Description:
1210 * Micro Second Delay via MAC
1211 *
1212 * Parameters:
1213 * In:
1214 * dwIoBase - Base Address for MAC
1215 * uDelay - Delay time (timer resolution is 4 us)
1216 * Out:
1217 * none
1218 *
1219 * Return Value: none
1220 *
1221 */
1222void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay)
1223{
1224 unsigned char byValue;
1225 unsigned int uu, ii;
1226
1227 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1228 VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
1229 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
1230 for (ii = 0; ii < 66; ii++) { // assume max PCI clock is 66Mhz
1231 for (uu = 0; uu < uDelay; uu++) {
1232 VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
1233 if ((byValue == 0) ||
1234 (byValue & TMCTL_TSUSP)) {
1235 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1236 return;
1237 }
1238 }
1239 }
1240 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1241}
1242
1243/*
1244 * Description:
1245 * Micro Second One shot timer via MAC
1246 *
1247 * Parameters:
1248 * In:
1249 * dwIoBase - Base Address for MAC
1250 * uDelay - Delay time
1251 * Out:
1252 * none
1253 *
1254 * Return Value: none
1255 *
1256 */
1257void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
1258{
1259 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1260 VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime);
1261 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
1262}
1263
1264/*
1265 * Description:
1266 * Micro Second One shot timer via MAC
1267 *
1268 * Parameters:
1269 * In:
1270 * dwIoBase - Base Address for MAC
1271 * uDelay - Delay time
1272 * Out:
1273 * none
1274 *
1275 * Return Value: none
1276 *
1277 */
1278void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
1279{
1280 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
1281 VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
1282 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
1283}
1284
1285void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData)
1286{
1287 if (wOffset > 273)
1288 return;
1289 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1290 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1291 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1292}
1293
1294bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx)
1295{
1296 unsigned char byData;
1297 unsigned int ww = 0;
1298
1299 if (idx == TYPE_TXDMA0) {
1300 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
1301 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1302 VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
1303 if (!(byData & DMACTL_RUN))
1304 break;
1305 }
1306 } else if (idx == TYPE_AC0DMA) {
1307 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
1308 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1309 VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
1310 if (!(byData & DMACTL_RUN))
1311 break;
1312 }
1313 }
1314 if (ww == W_MAX_TIMEOUT) {
1315 DBG_PORT80(0x29);
1316 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x29)\n");
1317 return false;
1318 }
1319 return true;
1320}
1321
1322void MACvClearBusSusInd(unsigned long dwIoBase)
1323{
1324 unsigned long dwOrgValue;
1325 unsigned int ww;
1326 // check if BcnSusInd enabled
1327 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1328 if (!(dwOrgValue & EnCFG_BcnSusInd))
1329 return;
1330 //Set BcnSusClr
1331 dwOrgValue = dwOrgValue | EnCFG_BcnSusClr;
1332 VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);
1333 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1334 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1335 if (!(dwOrgValue & EnCFG_BcnSusInd))
1336 break;
1337 }
1338 if (ww == W_MAX_TIMEOUT) {
1339 DBG_PORT80(0x33);
1340 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1341 }
1342}
1343
1344void MACvEnableBusSusEn(unsigned long dwIoBase)
1345{
1346 unsigned char byOrgValue;
1347 unsigned long dwOrgValue;
1348 unsigned int ww;
1349 // check if BcnSusInd enabled
1350 VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue);
1351
1352 //Set BcnSusEn
1353 byOrgValue = byOrgValue | CFG_BCNSUSEN;
1354 VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue);
1355 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1356 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1357 if (dwOrgValue & EnCFG_BcnSusInd)
1358 break;
1359 }
1360 if (ww == W_MAX_TIMEOUT) {
1361 DBG_PORT80(0x34);
1362 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x34)\n");
1363 }
1364}
1365
1366bool MACbFlushSYNCFifo(unsigned long dwIoBase)
1367{
1368 unsigned char byOrgValue;
1369 unsigned int ww;
1370 // Read MACCR
1371 VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
1372
1373 // Set SYNCFLUSH
1374 byOrgValue = byOrgValue | MACCR_SYNCFLUSH;
1375 VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue);
1376
1377 // Check if SyncFlushOK
1378 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1379 VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
1380 if (byOrgValue & MACCR_SYNCFLUSHOK)
1381 break;
1382 }
1383 if (ww == W_MAX_TIMEOUT) {
1384 DBG_PORT80(0x35);
1385 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1386 }
1387 return true;
1388}
1389
1390bool MACbPSWakeup(unsigned long dwIoBase)
1391{
1392 unsigned char byOrgValue;
1393 unsigned int ww;
1394 // Read PSCTL
1395 if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) {
1396 return true;
1397 }
1398 // Disable PS
1399 MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
1400
1401 // Check if SyncFlushOK
1402 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1403 VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue);
1404 if (byOrgValue & PSCTL_WAKEDONE)
1405 break;
1406 }
1407 if (ww == W_MAX_TIMEOUT) {
1408 DBG_PORT80(0x36);
1409 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1410 return false;
1411 }
1412 return true;
1413}
1414
1415/*
1416 * Description:
1417 * Set the Key by MISCFIFO
1418 *
1419 * Parameters:
1420 * In:
1421 * dwIoBase - Base Address for MAC
1422 *
1423 * Out:
1424 * none
1425 *
1426 * Return Value: none
1427 *
1428 */
1429
1430void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
1431 unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID)
1432{
1433 unsigned short wOffset;
1434 u32 dwData;
1435 int ii;
1436
1437 if (byLocalID <= 1)
1438 return;
1439
1440 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n");
1441 wOffset = MISCFIFO_KEYETRY0;
1442 wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1443
1444 dwData = 0;
1445 dwData |= wKeyCtl;
1446 dwData <<= 16;
1447 dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
1448 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %X, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
1449
1450 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1451 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1452 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1453 wOffset++;
1454
1455 dwData = 0;
1456 dwData |= *(pbyAddr+3);
1457 dwData <<= 8;
1458 dwData |= *(pbyAddr+2);
1459 dwData <<= 8;
1460 dwData |= *(pbyAddr+1);
1461 dwData <<= 8;
1462 dwData |= *(pbyAddr+0);
1463 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2. wOffset: %d, Data: %X\n", wOffset, dwData);
1464
1465 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1466 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1467 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1468 wOffset++;
1469
1470 wOffset += (uKeyIdx * 4);
1471 for (ii = 0; ii < 4; ii++) {
1472 // always push 128 bits
1473 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.(%d) wOffset: %d, Data: %X\n", ii, wOffset+ii, *pdwKey);
1474 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1475 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1476 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1477 }
1478}
1479
1480/*
1481 * Description:
1482 * Disable the Key Entry by MISCFIFO
1483 *
1484 * Parameters:
1485 * In:
1486 * dwIoBase - Base Address for MAC
1487 *
1488 * Out:
1489 * none
1490 *
1491 * Return Value: none
1492 *
1493 */
1494void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx)
1495{
1496 unsigned short wOffset;
1497
1498 wOffset = MISCFIFO_KEYETRY0;
1499 wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1500
1501 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1502 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
1503 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1504}
1505
1506/*
1507 * Description:
1508 * Set the default Key (KeyEntry[10]) by MISCFIFO
1509 *
1510 * Parameters:
1511 * In:
1512 * dwIoBase - Base Address for MAC
1513 *
1514 * Out:
1515 * none
1516 *
1517 * Return Value: none
1518 *
1519 */
1520
1521void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
1522 unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
1523{
1524 unsigned short wOffset;
1525 unsigned long dwData;
1526 int ii;
1527
1528 if (byLocalID <= 1)
1529 return;
1530
1531 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultKeyEntry\n");
1532 wOffset = MISCFIFO_KEYETRY0;
1533 wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1534
1535 wOffset++;
1536 wOffset++;
1537 wOffset += (uKeyIdx * 4);
1538 // always push 128 bits
1539 for (ii = 0; ii < 3; ii++) {
1540 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
1541 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1542 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1543 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1544 }
1545 dwData = *pdwKey;
1546 if (uKeyLen == WLAN_WEP104_KEYLEN) {
1547 dwData |= 0x80000000;
1548 }
1549 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3);
1550 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1551 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1552 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End. wOffset: %d, Data: %lX\n", wOffset+3, dwData);
1553}
1554
1555/*
1556 * Description:
1557 * Enable default Key (KeyEntry[10]) by MISCFIFO
1558 *
1559 * Parameters:
1560 * In:
1561 * dwIoBase - Base Address for MAC
1562 *
1563 * Out:
1564 * none
1565 *
1566 * Return Value: none
1567 *
1568 */
1569/*
1570 void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID)
1571 {
1572 unsigned short wOffset;
1573 unsigned long dwData;
1574
1575 if (byLocalID <= 1)
1576 return;
1577
1578 wOffset = MISCFIFO_KEYETRY0;
1579 wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1580
1581 dwData = 0xC0440000;
1582 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1583 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1584 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1585 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
1586
1587 }
1588*/
1589
1590/*
1591 * Description:
1592 * Disable default Key (KeyEntry[10]) by MISCFIFO
1593 *
1594 * Parameters:
1595 * In:
1596 * dwIoBase - Base Address for MAC
1597 *
1598 * Out:
1599 * none
1600 *
1601 * Return Value: none
1602 *
1603 */
1604void MACvDisableDefaultKey(unsigned long dwIoBase)
1605{
1606 unsigned short wOffset;
1607 unsigned long dwData;
1608
1609 wOffset = MISCFIFO_KEYETRY0;
1610 wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1611
1612 dwData = 0x0;
1613 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1614 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1615 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1616 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
1617}
1618
1619/*
1620 * Description:
1621 * Set the default TKIP Group Key (KeyEntry[10]) by MISCFIFO
1622 *
1623 * Parameters:
1624 * In:
1625 * dwIoBase - Base Address for MAC
1626 *
1627 * Out:
1628 * none
1629 *
1630 * Return Value: none
1631 *
1632 */
1633void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
1634 unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
1635{
1636 unsigned short wOffset;
1637 unsigned long dwData;
1638 int ii;
1639
1640 if (byLocalID <= 1)
1641 return;
1642
1643 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultTKIPKeyEntry\n");
1644 wOffset = MISCFIFO_KEYETRY0;
1645 // Kyle test : change offset from 10 -> 0
1646 wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1647
1648 dwData = 0xC0660000;
1649 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1650 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1651 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1652 wOffset++;
1653
1654 dwData = 0;
1655 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1656 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1657 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1658 wOffset++;
1659
1660 wOffset += (uKeyIdx * 4);
1661 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx);
1662 // always push 128 bits
1663 for (ii = 0; ii < 4; ii++) {
1664 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
1665 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1666 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1667 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1668 }
1669}
1670
1671/*
1672 * Description:
1673 * Set the Key Control by MISCFIFO
1674 *
1675 * Parameters:
1676 * In:
1677 * dwIoBase - Base Address for MAC
1678 *
1679 * Out:
1680 * none
1681 *
1682 * Return Value: none
1683 *
1684 */
1685
1686void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID)
1687{
1688 unsigned short wOffset;
1689 unsigned long dwData;
1690
1691 if (byLocalID <= 1)
1692 return;
1693
1694 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n");
1695 wOffset = MISCFIFO_KEYETRY0;
1696 wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1697
1698 dwData = 0;
1699 dwData |= wKeyCtl;
1700 dwData <<= 16;
1701 dwData |= 0xffff;
1702 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
1703
1704 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1705 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1706 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1707}
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4 * All rights reserved.
5 *
6 * Purpose: MAC routines
7 *
8 * Author: Tevin Chen
9 *
10 * Date: May 21, 1996
11 *
12 * Functions:
13 * vt6655_mac_is_reg_bits_off - Test if All test Bits Off
14 * vt6655_mac_set_short_retry_limit - Set 802.11 Short Retry limit
15 * MACvSetLongRetryLimit - Set 802.11 Long Retry limit
16 * vt6655_mac_set_loopback_mode - Set MAC Loopback Mode
17 * vt6655_mac_save_context - Save Context of MAC Registers
18 * vt6655_mac_restore_context - Restore Context of MAC Registers
19 * MACbSoftwareReset - Software Reset MAC
20 * vt6655_mac_safe_rx_off - Turn Off MAC Rx
21 * vt6655_mac_safe_tx_off - Turn Off MAC Tx
22 * vt6655_mac_safe_stop - Stop MAC function
23 * MACbShutdown - Shut down MAC
24 * MACvInitialize - Initialize MAC
25 * MACvSetCurrRxDescAddr - Set Rx Descriptors Address
26 * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
27 * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
28 * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
29 *
30 * Revision History:
31 * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53
32 * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()&
33 * MACvEnableBusSusEn()
34 * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry
35 *
36 */
37
38#include "mac.h"
39
40void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
41{
42 unsigned char reg_value;
43
44 reg_value = ioread8(iobase + reg_offset);
45 iowrite8(reg_value | bit_mask, iobase + reg_offset);
46}
47
48void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
49{
50 unsigned short reg_value;
51
52 reg_value = ioread16(iobase + reg_offset);
53 iowrite16(reg_value | (bit_mask), iobase + reg_offset);
54}
55
56void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
57{
58 unsigned char reg_value;
59
60 reg_value = ioread8(iobase + reg_offset);
61 iowrite8(reg_value & ~(bit_mask), iobase + reg_offset);
62}
63
64void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
65{
66 unsigned short reg_value;
67
68 reg_value = ioread16(iobase + reg_offset);
69 iowrite16(reg_value & ~(bit_mask), iobase + reg_offset);
70}
71
72static void vt6655_mac_clear_stck_ds(void __iomem *iobase)
73{
74 u8 reg_value;
75
76 reg_value = ioread8(iobase + MAC_REG_STICKHW);
77 reg_value = reg_value & 0xFC;
78 iowrite8(reg_value, iobase + MAC_REG_STICKHW);
79}
80
81/*
82 * Description:
83 * Test if all test bits off
84 *
85 * Parameters:
86 * In:
87 * io_base - Base Address for MAC
88 * reg_offset - Offset of MAC Register
89 * mask - Test bits
90 * Out:
91 * none
92 *
93 * Return Value: true if all test bits Off; otherwise false
94 *
95 */
96static bool vt6655_mac_is_reg_bits_off(struct vnt_private *priv,
97 unsigned char reg_offset,
98 unsigned char mask)
99{
100 void __iomem *io_base = priv->port_offset;
101
102 return !(ioread8(io_base + reg_offset) & mask);
103}
104
105/*
106 * Description:
107 * Set 802.11 Short Retry Limit
108 *
109 * Parameters:
110 * In:
111 * io_base - Base Address for MAC
112 * retry_limit - Retry Limit
113 * Out:
114 * none
115 *
116 * Return Value: none
117 *
118 */
119void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit)
120{
121 void __iomem *io_base = priv->port_offset;
122 /* set SRT */
123 iowrite8(retry_limit, io_base + MAC_REG_SRT);
124}
125
126/*
127 * Description:
128 * Set 802.11 Long Retry Limit
129 *
130 * Parameters:
131 * In:
132 * io_base - Base Address for MAC
133 * byRetryLimit- Retry Limit
134 * Out:
135 * none
136 *
137 * Return Value: none
138 *
139 */
140void MACvSetLongRetryLimit(struct vnt_private *priv,
141 unsigned char byRetryLimit)
142{
143 void __iomem *io_base = priv->port_offset;
144 /* set LRT */
145 iowrite8(byRetryLimit, io_base + MAC_REG_LRT);
146}
147
148/*
149 * Description:
150 * Set MAC Loopback mode
151 *
152 * Parameters:
153 * In:
154 * io_base - Base Address for MAC
155 * loopback_mode - Loopback Mode
156 * Out:
157 * none
158 *
159 * Return Value: none
160 *
161 */
162static void vt6655_mac_set_loopback_mode(struct vnt_private *priv, u8 loopback_mode)
163{
164 void __iomem *io_base = priv->port_offset;
165
166 loopback_mode <<= 6;
167 /* set TCR */
168 iowrite8((ioread8(io_base + MAC_REG_TEST) & 0x3f) | loopback_mode, io_base + MAC_REG_TEST);
169}
170
171/*
172 * Description:
173 * Save MAC registers to context buffer
174 *
175 * Parameters:
176 * In:
177 * io_base - Base Address for MAC
178 * Out:
179 * cxt_buf - Context buffer
180 *
181 * Return Value: none
182 *
183 */
184static void vt6655_mac_save_context(struct vnt_private *priv, u8 *cxt_buf)
185{
186 void __iomem *io_base = priv->port_offset;
187
188 /* read page0 register */
189 memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0);
190
191 VT6655_MAC_SELECT_PAGE1(io_base);
192
193 /* read page1 register */
194 memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base,
195 MAC_MAX_CONTEXT_SIZE_PAGE1);
196
197 VT6655_MAC_SELECT_PAGE0(io_base);
198}
199
200/*
201 * Description:
202 * Restore MAC registers from context buffer
203 *
204 * Parameters:
205 * In:
206 * io_base - Base Address for MAC
207 * cxt_buf - Context buffer
208 * Out:
209 * none
210 *
211 * Return Value: none
212 *
213 */
214static void vt6655_mac_restore_context(struct vnt_private *priv, u8 *cxt_buf)
215{
216 void __iomem *io_base = priv->port_offset;
217
218 VT6655_MAC_SELECT_PAGE1(io_base);
219 /* restore page1 */
220 memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0,
221 MAC_MAX_CONTEXT_SIZE_PAGE1);
222
223 VT6655_MAC_SELECT_PAGE0(io_base);
224
225 /* restore RCR,TCR,IMR... */
226 memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR,
227 MAC_REG_ISR - MAC_REG_RCR);
228
229 /* restore MAC Config. */
230 memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT,
231 MAC_REG_PAGE1SEL - MAC_REG_LRT);
232
233 iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG);
234
235 /* restore PS Config. */
236 memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG,
237 MAC_REG_BBREGCTL - MAC_REG_PSCFG);
238
239 /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
240 iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0),
241 io_base + MAC_REG_TXDMAPTR0);
242 iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR),
243 io_base + MAC_REG_AC0DMAPTR);
244 iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR),
245 io_base + MAC_REG_BCNDMAPTR);
246 iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0),
247 io_base + MAC_REG_RXDMAPTR0);
248 iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1),
249 io_base + MAC_REG_RXDMAPTR1);
250}
251
252/*
253 * Description:
254 * Software Reset MAC
255 *
256 * Parameters:
257 * In:
258 * io_base - Base Address for MAC
259 * Out:
260 * none
261 *
262 * Return Value: true if Reset Success; otherwise false
263 *
264 */
265bool MACbSoftwareReset(struct vnt_private *priv)
266{
267 void __iomem *io_base = priv->port_offset;
268 unsigned short ww;
269
270 /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */
271 iowrite8(0x01, io_base + MAC_REG_HOSTCR);
272
273 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
274 if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST))
275 break;
276 }
277 if (ww == W_MAX_TIMEOUT)
278 return false;
279 return true;
280}
281
282/*
283 * Description:
284 * save some important register's value, then do reset, then restore
285 * register's value
286 *
287 * Parameters:
288 * In:
289 * io_base - Base Address for MAC
290 * Out:
291 * none
292 *
293 * Return Value: true if success; otherwise false
294 *
295 */
296static void vt6655_mac_save_soft_reset(struct vnt_private *priv)
297{
298 u8 tmp_reg_data[MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1];
299
300 /* PATCH....
301 * save some important register's value, then do
302 * reset, then restore register's value
303 */
304 /* save MAC context */
305 vt6655_mac_save_context(priv, tmp_reg_data);
306 /* do reset */
307 MACbSoftwareReset(priv);
308 /* restore MAC context, except CR0 */
309 vt6655_mac_restore_context(priv, tmp_reg_data);
310}
311
312/*
313 * Description:
314 * Turn Off MAC Rx
315 *
316 * Parameters:
317 * In:
318 * io_base - Base Address for MAC
319 * Out:
320 * none
321 *
322 * Return Value: true if success; otherwise false
323 *
324 */
325static bool vt6655_mac_safe_rx_off(struct vnt_private *priv)
326{
327 void __iomem *io_base = priv->port_offset;
328 unsigned short ww;
329
330 /* turn off wow temp for turn off Rx safely */
331
332 /* Clear RX DMA0,1 */
333 iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL0);
334 iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL1);
335 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
336 if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
337 break;
338 }
339 if (ww == W_MAX_TIMEOUT) {
340 pr_debug(" DBG_PORT80(0x10)\n");
341 return false;
342 }
343 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
344 if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
345 break;
346 }
347 if (ww == W_MAX_TIMEOUT) {
348 pr_debug(" DBG_PORT80(0x11)\n");
349 return false;
350 }
351
352 /* try to safe shutdown RX */
353 vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_RXON);
354 /* W_MAX_TIMEOUT is the timeout period */
355 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
356 if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST))
357 break;
358 }
359 if (ww == W_MAX_TIMEOUT) {
360 pr_debug(" DBG_PORT80(0x12)\n");
361 return false;
362 }
363 return true;
364}
365
366/*
367 * Description:
368 * Turn Off MAC Tx
369 *
370 * Parameters:
371 * In:
372 * io_base - Base Address for MAC
373 * Out:
374 * none
375 *
376 * Return Value: true if success; otherwise false
377 *
378 */
379static bool vt6655_mac_safe_tx_off(struct vnt_private *priv)
380{
381 void __iomem *io_base = priv->port_offset;
382 unsigned short ww;
383
384 /* Clear TX DMA */
385 /* Tx0 */
386 iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_TXDMACTL0);
387 /* AC0 */
388 iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_AC0DMACTL);
389
390 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
391 if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
392 break;
393 }
394 if (ww == W_MAX_TIMEOUT) {
395 pr_debug(" DBG_PORT80(0x20)\n");
396 return false;
397 }
398 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
399 if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
400 break;
401 }
402 if (ww == W_MAX_TIMEOUT) {
403 pr_debug(" DBG_PORT80(0x21)\n");
404 return false;
405 }
406
407 /* try to safe shutdown TX */
408 vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_TXON);
409
410 /* W_MAX_TIMEOUT is the timeout period */
411 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
412 if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST))
413 break;
414 }
415 if (ww == W_MAX_TIMEOUT) {
416 pr_debug(" DBG_PORT80(0x24)\n");
417 return false;
418 }
419 return true;
420}
421
422/*
423 * Description:
424 * Stop MAC function
425 *
426 * Parameters:
427 * In:
428 * io_base - Base Address for MAC
429 * Out:
430 * none
431 *
432 * Return Value: true if success; otherwise false
433 *
434 */
435static bool vt6655_mac_safe_stop(struct vnt_private *priv)
436{
437 void __iomem *io_base = priv->port_offset;
438
439 vt6655_mac_reg_bits_off(io_base, MAC_REG_TCR, TCR_AUTOBCNTX);
440
441 if (!vt6655_mac_safe_rx_off(priv)) {
442 pr_debug(" vt6655_mac_safe_rx_off == false)\n");
443 vt6655_mac_save_soft_reset(priv);
444 return false;
445 }
446 if (!vt6655_mac_safe_tx_off(priv)) {
447 pr_debug(" vt6655_mac_safe_tx_off == false)\n");
448 vt6655_mac_save_soft_reset(priv);
449 return false;
450 }
451
452 vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN);
453
454 return true;
455}
456
457/*
458 * Description:
459 * Shut Down MAC
460 *
461 * Parameters:
462 * In:
463 * io_base - Base Address for MAC
464 * Out:
465 * none
466 *
467 * Return Value: true if success; otherwise false
468 *
469 */
470bool MACbShutdown(struct vnt_private *priv)
471{
472 void __iomem *io_base = priv->port_offset;
473 /* disable MAC IMR */
474 iowrite32(0, io_base + MAC_REG_IMR);
475 vt6655_mac_set_loopback_mode(priv, MAC_LB_INTERNAL);
476 /* stop the adapter */
477 if (!vt6655_mac_safe_stop(priv)) {
478 vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE);
479 return false;
480 }
481 vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE);
482 return true;
483}
484
485/*
486 * Description:
487 * Initialize MAC
488 *
489 * Parameters:
490 * In:
491 * io_base - Base Address for MAC
492 * Out:
493 * none
494 *
495 * Return Value: none
496 *
497 */
498void MACvInitialize(struct vnt_private *priv)
499{
500 void __iomem *io_base = priv->port_offset;
501 /* clear sticky bits */
502 vt6655_mac_clear_stck_ds(io_base);
503 /* disable force PME-enable */
504 iowrite8(PME_OVR, io_base + MAC_REG_PMC1);
505 /* only 3253 A */
506
507 /* do reset */
508 MACbSoftwareReset(priv);
509
510 /* reset TSF counter */
511 iowrite8(TFTCTL_TSFCNTRST, io_base + MAC_REG_TFTCTL);
512 /* enable TSF counter */
513 iowrite8(TFTCTL_TSFCNTREN, io_base + MAC_REG_TFTCTL);
514}
515
516/*
517 * Description:
518 * Set the chip with current rx descriptor address
519 *
520 * Parameters:
521 * In:
522 * io_base - Base Address for MAC
523 * curr_desc_addr - Descriptor Address
524 * Out:
525 * none
526 *
527 * Return Value: none
528 *
529 */
530void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr)
531{
532 void __iomem *io_base = priv->port_offset;
533 unsigned short ww;
534 unsigned char org_dma_ctl;
535
536 org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL0);
537 if (org_dma_ctl & DMACTL_RUN)
538 iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0 + 2);
539
540 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
541 if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
542 break;
543 }
544
545 iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR0);
546 if (org_dma_ctl & DMACTL_RUN)
547 iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0);
548}
549
550/*
551 * Description:
552 * Set the chip with current rx descriptor address
553 *
554 * Parameters:
555 * In:
556 * io_base - Base Address for MAC
557 * curr_desc_addr - Descriptor Address
558 * Out:
559 * none
560 *
561 * Return Value: none
562 *
563 */
564void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr)
565{
566 void __iomem *io_base = priv->port_offset;
567 unsigned short ww;
568 unsigned char org_dma_ctl;
569
570 org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL1);
571 if (org_dma_ctl & DMACTL_RUN)
572 iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1 + 2);
573
574 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
575 if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
576 break;
577 }
578
579 iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR1);
580 if (org_dma_ctl & DMACTL_RUN)
581 iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1);
582}
583
584/*
585 * Description:
586 * Set the chip with current tx0 descriptor address
587 *
588 * Parameters:
589 * In:
590 * io_base - Base Address for MAC
591 * curr_desc_addr - Descriptor Address
592 * Out:
593 * none
594 *
595 * Return Value: none
596 *
597 */
598static void vt6655_mac_set_curr_tx_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr)
599{
600 void __iomem *io_base = priv->port_offset;
601 unsigned short ww;
602 unsigned char org_dma_ctl;
603
604 org_dma_ctl = ioread8(io_base + MAC_REG_TXDMACTL0);
605 if (org_dma_ctl & DMACTL_RUN)
606 iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0 + 2);
607
608 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
609 if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
610 break;
611 }
612
613 iowrite32(curr_desc_addr, io_base + MAC_REG_TXDMAPTR0);
614 if (org_dma_ctl & DMACTL_RUN)
615 iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0);
616}
617
618/*
619 * Description:
620 * Set the chip with current AC0 descriptor address
621 *
622 * Parameters:
623 * In:
624 * io_base - Base Address for MAC
625 * curr_desc_addr - Descriptor Address
626 * Out:
627 * none
628 *
629 * Return Value: none
630 *
631 */
632/* TxDMA1 = AC0DMA */
633static void vt6655_mac_set_curr_ac_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr)
634{
635 void __iomem *io_base = priv->port_offset;
636 unsigned short ww;
637 unsigned char org_dma_ctl;
638
639 org_dma_ctl = ioread8(io_base + MAC_REG_AC0DMACTL);
640 if (org_dma_ctl & DMACTL_RUN)
641 iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL + 2);
642
643 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
644 if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
645 break;
646 }
647 if (ww == W_MAX_TIMEOUT)
648 pr_debug(" DBG_PORT80(0x26)\n");
649 iowrite32(curr_desc_addr, io_base + MAC_REG_AC0DMAPTR);
650 if (org_dma_ctl & DMACTL_RUN)
651 iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL);
652}
653
654void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr)
655{
656 if (tx_type == TYPE_AC0DMA)
657 vt6655_mac_set_curr_ac_0_desc_addr_ex(priv, curr_desc_addr);
658 else if (tx_type == TYPE_TXDMA0)
659 vt6655_mac_set_curr_tx_0_desc_addr_ex(priv, curr_desc_addr);
660}
661
662/*
663 * Description:
664 * Micro Second Delay via MAC
665 *
666 * Parameters:
667 * In:
668 * io_base - Base Address for MAC
669 * uDelay - Delay time (timer resolution is 4 us)
670 * Out:
671 * none
672 *
673 * Return Value: none
674 *
675 */
676void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay)
677{
678 void __iomem *io_base = priv->port_offset;
679 unsigned char byValue;
680 unsigned int uu, ii;
681
682 iowrite8(0, io_base + MAC_REG_TMCTL0);
683 iowrite32(uDelay, io_base + MAC_REG_TMDATA0);
684 iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL0);
685 for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */
686 for (uu = 0; uu < uDelay; uu++) {
687 byValue = ioread8(io_base + MAC_REG_TMCTL0);
688 if ((byValue == 0) ||
689 (byValue & TMCTL_TSUSP)) {
690 iowrite8(0, io_base + MAC_REG_TMCTL0);
691 return;
692 }
693 }
694 }
695 iowrite8(0, io_base + MAC_REG_TMCTL0);
696}
697
698/*
699 * Description:
700 * Micro Second One shot timer via MAC
701 *
702 * Parameters:
703 * In:
704 * io_base - Base Address for MAC
705 * uDelay - Delay time
706 * Out:
707 * none
708 *
709 * Return Value: none
710 *
711 */
712void MACvOneShotTimer1MicroSec(struct vnt_private *priv,
713 unsigned int uDelayTime)
714{
715 void __iomem *io_base = priv->port_offset;
716
717 iowrite8(0, io_base + MAC_REG_TMCTL1);
718 iowrite32(uDelayTime, io_base + MAC_REG_TMDATA1);
719 iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL1);
720}
721
722void MACvSetMISCFifo(struct vnt_private *priv, unsigned short offset,
723 u32 data)
724{
725 void __iomem *io_base = priv->port_offset;
726
727 if (offset > 273)
728 return;
729 iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
730 iowrite32(data, io_base + MAC_REG_MISCFFDATA);
731 iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
732}
733
734bool MACbPSWakeup(struct vnt_private *priv)
735{
736 void __iomem *io_base = priv->port_offset;
737 unsigned int ww;
738 /* Read PSCTL */
739 if (vt6655_mac_is_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_PS))
740 return true;
741
742 /* Disable PS */
743 vt6655_mac_reg_bits_off(io_base, MAC_REG_PSCTL, PSCTL_PSEN);
744
745 /* Check if SyncFlushOK */
746 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
747 if (ioread8(io_base + MAC_REG_PSCTL) & PSCTL_WAKEDONE)
748 break;
749 }
750 if (ww == W_MAX_TIMEOUT) {
751 pr_debug(" DBG_PORT80(0x33)\n");
752 return false;
753 }
754 return true;
755}
756
757/*
758 * Description:
759 * Set the Key by MISCFIFO
760 *
761 * Parameters:
762 * In:
763 * io_base - Base Address for MAC
764 *
765 * Out:
766 * none
767 *
768 * Return Value: none
769 *
770 */
771
772void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl,
773 unsigned int uEntryIdx, unsigned int uKeyIdx,
774 unsigned char *pbyAddr, u32 *pdwKey,
775 unsigned char local_id)
776{
777 void __iomem *io_base = priv->port_offset;
778 unsigned short offset;
779 u32 data;
780 int ii;
781
782 if (local_id <= 1)
783 return;
784
785 offset = MISCFIFO_KEYETRY0;
786 offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
787
788 data = 0;
789 data |= wKeyCtl;
790 data <<= 16;
791 data |= MAKEWORD(*(pbyAddr + 4), *(pbyAddr + 5));
792 pr_debug("1. offset: %d, Data: %X, KeyCtl:%X\n",
793 offset, data, wKeyCtl);
794
795 iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
796 iowrite32(data, io_base + MAC_REG_MISCFFDATA);
797 iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
798 offset++;
799
800 data = 0;
801 data |= *(pbyAddr + 3);
802 data <<= 8;
803 data |= *(pbyAddr + 2);
804 data <<= 8;
805 data |= *(pbyAddr + 1);
806 data <<= 8;
807 data |= *pbyAddr;
808 pr_debug("2. offset: %d, Data: %X\n", offset, data);
809
810 iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
811 iowrite32(data, io_base + MAC_REG_MISCFFDATA);
812 iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
813 offset++;
814
815 offset += (uKeyIdx * 4);
816 for (ii = 0; ii < 4; ii++) {
817 /* always push 128 bits */
818 pr_debug("3.(%d) offset: %d, Data: %X\n",
819 ii, offset + ii, *pdwKey);
820 iowrite16(offset + ii, io_base + MAC_REG_MISCFFNDEX);
821 iowrite32(*pdwKey++, io_base + MAC_REG_MISCFFDATA);
822 iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
823 }
824}
825
826/*
827 * Description:
828 * Disable the Key Entry by MISCFIFO
829 *
830 * Parameters:
831 * In:
832 * io_base - Base Address for MAC
833 *
834 * Out:
835 * none
836 *
837 * Return Value: none
838 *
839 */
840void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx)
841{
842 void __iomem *io_base = priv->port_offset;
843 unsigned short offset;
844
845 offset = MISCFIFO_KEYETRY0;
846 offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
847
848 iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
849 iowrite32(0, io_base + MAC_REG_MISCFFDATA);
850 iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
851}