aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skxmac2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2008-01-31 01:04:05 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:23 -0400
commit548c36e983f346621b5cb9ab031e4383e9996576 (patch)
tree7c341c1513a6d84a06c86f5045c885086a7524eb /drivers/net/sk98lin/skxmac2.c
parenta978b30af3bab0dd9af9350eeda25e76123fa28e (diff)
sk98lin: remove obsolete driver
All the hardware supported by this driver is now supported by the skge driver. The last remaining issue was support for ancient dual port SysKonnect fiber boards, and the skge driver now does these correctly (p.s. sk98lin was always broken on these old dual port boards anyway). Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sk98lin/skxmac2.c')
-rw-r--r--drivers/net/sk98lin/skxmac2.c4160
1 files changed, 0 insertions, 4160 deletions
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
deleted file mode 100644
index b4e75022a657..000000000000
--- a/drivers/net/sk98lin/skxmac2.c
+++ /dev/null
@@ -1,4160 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skxmac2.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2003/10/02 16:53:58 $
7 * Purpose: Contains functions to initialize the MACs and PHYs
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* typedefs *******************************************************************/
29
30/* BCOM PHY magic pattern list */
31typedef struct s_PhyHack {
32 int PhyReg; /* Phy register */
33 SK_U16 PhyVal; /* Value to write */
34} BCOM_HACK;
35
36/* local variables ************************************************************/
37
38#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
39static const char SysKonnectFileId[] =
40 "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
41#endif
42
43#ifdef GENESIS
44static BCOM_HACK BcomRegA1Hack[] = {
45 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
46 { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
47 { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
48 { 0, 0 }
49};
50static BCOM_HACK BcomRegC0Hack[] = {
51 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
52 { 0x15, 0x0A04 }, { 0x18, 0x0420 },
53 { 0, 0 }
54};
55#endif
56
57/* function prototypes ********************************************************/
58#ifdef GENESIS
59static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
60static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
61static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
62static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
63#endif /* GENESIS */
64#ifdef YUKON
65static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
66static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
67#endif /* YUKON */
68#ifdef OTHER_PHY
69static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
70static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
71static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
72static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
73#endif /* OTHER_PHY */
74
75
76#ifdef GENESIS
77/******************************************************************************
78 *
79 * SkXmPhyRead() - Read from XMAC PHY register
80 *
81 * Description: reads a 16-bit word from XMAC PHY or ext. PHY
82 *
83 * Returns:
84 * nothing
85 */
86void SkXmPhyRead(
87SK_AC *pAC, /* Adapter Context */
88SK_IOC IoC, /* I/O Context */
89int Port, /* Port Index (MAC_1 + n) */
90int PhyReg, /* Register Address (Offset) */
91SK_U16 SK_FAR *pVal) /* Pointer to Value */
92{
93 SK_U16 Mmu;
94 SK_GEPORT *pPrt;
95
96 pPrt = &pAC->GIni.GP[Port];
97
98 /* write the PHY register's address */
99 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
100
101 /* get the PHY register's value */
102 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
103
104 if (pPrt->PhyType != SK_PHY_XMAC) {
105 do {
106 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
107 /* wait until 'Ready' is set */
108 } while ((Mmu & XM_MMU_PHY_RDY) == 0);
109
110 /* get the PHY register's value */
111 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
112 }
113} /* SkXmPhyRead */
114
115
116/******************************************************************************
117 *
118 * SkXmPhyWrite() - Write to XMAC PHY register
119 *
120 * Description: writes a 16-bit word to XMAC PHY or ext. PHY
121 *
122 * Returns:
123 * nothing
124 */
125void SkXmPhyWrite(
126SK_AC *pAC, /* Adapter Context */
127SK_IOC IoC, /* I/O Context */
128int Port, /* Port Index (MAC_1 + n) */
129int PhyReg, /* Register Address (Offset) */
130SK_U16 Val) /* Value */
131{
132 SK_U16 Mmu;
133 SK_GEPORT *pPrt;
134
135 pPrt = &pAC->GIni.GP[Port];
136
137 if (pPrt->PhyType != SK_PHY_XMAC) {
138 do {
139 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
140 /* wait until 'Busy' is cleared */
141 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
142 }
143
144 /* write the PHY register's address */
145 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
146
147 /* write the PHY register's value */
148 XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
149
150 if (pPrt->PhyType != SK_PHY_XMAC) {
151 do {
152 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
153 /* wait until 'Busy' is cleared */
154 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
155 }
156} /* SkXmPhyWrite */
157#endif /* GENESIS */
158
159
160#ifdef YUKON
161/******************************************************************************
162 *
163 * SkGmPhyRead() - Read from GPHY register
164 *
165 * Description: reads a 16-bit word from GPHY through MDIO
166 *
167 * Returns:
168 * nothing
169 */
170void SkGmPhyRead(
171SK_AC *pAC, /* Adapter Context */
172SK_IOC IoC, /* I/O Context */
173int Port, /* Port Index (MAC_1 + n) */
174int PhyReg, /* Register Address (Offset) */
175SK_U16 SK_FAR *pVal) /* Pointer to Value */
176{
177 SK_U16 Ctrl;
178 SK_GEPORT *pPrt;
179#ifdef VCPU
180 u_long SimCyle;
181 u_long SimLowTime;
182
183 VCPUgetTime(&SimCyle, &SimLowTime);
184 VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
185 PhyReg, SimCyle, SimLowTime);
186#endif /* VCPU */
187
188 pPrt = &pAC->GIni.GP[Port];
189
190 /* set PHY-Register offset and 'Read' OpCode (= 1) */
191 *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
192 GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
193
194 GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
195
196 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
197
198 /* additional check for MDC/MDIO activity */
199 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
200 *pVal = 0;
201 return;
202 }
203
204 *pVal |= GM_SMI_CT_BUSY;
205
206 do {
207#ifdef VCPU
208 VCPUwaitTime(1000);
209#endif /* VCPU */
210
211 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
212
213 /* wait until 'ReadValid' is set */
214 } while (Ctrl == *pVal);
215
216 /* get the PHY register's value */
217 GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
218
219#ifdef VCPU
220 VCPUgetTime(&SimCyle, &SimLowTime);
221 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
222 SimCyle, SimLowTime);
223#endif /* VCPU */
224
225} /* SkGmPhyRead */
226
227
228/******************************************************************************
229 *
230 * SkGmPhyWrite() - Write to GPHY register
231 *
232 * Description: writes a 16-bit word to GPHY through MDIO
233 *
234 * Returns:
235 * nothing
236 */
237void SkGmPhyWrite(
238SK_AC *pAC, /* Adapter Context */
239SK_IOC IoC, /* I/O Context */
240int Port, /* Port Index (MAC_1 + n) */
241int PhyReg, /* Register Address (Offset) */
242SK_U16 Val) /* Value */
243{
244 SK_U16 Ctrl;
245 SK_GEPORT *pPrt;
246#ifdef VCPU
247 SK_U32 DWord;
248 u_long SimCyle;
249 u_long SimLowTime;
250
251 VCPUgetTime(&SimCyle, &SimLowTime);
252 VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
253 PhyReg, Val, SimCyle, SimLowTime);
254#endif /* VCPU */
255
256 pPrt = &pAC->GIni.GP[Port];
257
258 /* write the PHY register's value */
259 GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
260
261 /* set PHY-Register offset and 'Write' OpCode (= 0) */
262 Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
263
264 GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
265
266 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
267
268 /* additional check for MDC/MDIO activity */
269 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
270 return;
271 }
272
273 Val |= GM_SMI_CT_BUSY;
274
275 do {
276#ifdef VCPU
277 /* read Timer value */
278 SK_IN32(IoC, B2_TI_VAL, &DWord);
279
280 VCPUwaitTime(1000);
281#endif /* VCPU */
282
283 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
284
285 /* wait until 'Busy' is cleared */
286 } while (Ctrl == Val);
287
288#ifdef VCPU
289 VCPUgetTime(&SimCyle, &SimLowTime);
290 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
291 SimCyle, SimLowTime);
292#endif /* VCPU */
293
294} /* SkGmPhyWrite */
295#endif /* YUKON */
296
297
298#ifdef SK_DIAG
299/******************************************************************************
300 *
301 * SkGePhyRead() - Read from PHY register
302 *
303 * Description: calls a read PHY routine dep. on board type
304 *
305 * Returns:
306 * nothing
307 */
308void SkGePhyRead(
309SK_AC *pAC, /* Adapter Context */
310SK_IOC IoC, /* I/O Context */
311int Port, /* Port Index (MAC_1 + n) */
312int PhyReg, /* Register Address (Offset) */
313SK_U16 *pVal) /* Pointer to Value */
314{
315 void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
316
317 if (pAC->GIni.GIGenesis) {
318 r_func = SkXmPhyRead;
319 }
320 else {
321 r_func = SkGmPhyRead;
322 }
323
324 r_func(pAC, IoC, Port, PhyReg, pVal);
325} /* SkGePhyRead */
326
327
328/******************************************************************************
329 *
330 * SkGePhyWrite() - Write to PHY register
331 *
332 * Description: calls a write PHY routine dep. on board type
333 *
334 * Returns:
335 * nothing
336 */
337void SkGePhyWrite(
338SK_AC *pAC, /* Adapter Context */
339SK_IOC IoC, /* I/O Context */
340int Port, /* Port Index (MAC_1 + n) */
341int PhyReg, /* Register Address (Offset) */
342SK_U16 Val) /* Value */
343{
344 void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
345
346 if (pAC->GIni.GIGenesis) {
347 w_func = SkXmPhyWrite;
348 }
349 else {
350 w_func = SkGmPhyWrite;
351 }
352
353 w_func(pAC, IoC, Port, PhyReg, Val);
354} /* SkGePhyWrite */
355#endif /* SK_DIAG */
356
357
358/******************************************************************************
359 *
360 * SkMacPromiscMode() - Enable / Disable Promiscuous Mode
361 *
362 * Description:
363 * enables / disables promiscuous mode by setting Mode Register (XMAC) or
364 * Receive Control Register (GMAC) dep. on board type
365 *
366 * Returns:
367 * nothing
368 */
369void SkMacPromiscMode(
370SK_AC *pAC, /* adapter context */
371SK_IOC IoC, /* IO context */
372int Port, /* Port Index (MAC_1 + n) */
373SK_BOOL Enable) /* Enable / Disable */
374{
375#ifdef YUKON
376 SK_U16 RcReg;
377#endif
378#ifdef GENESIS
379 SK_U32 MdReg;
380#endif
381
382#ifdef GENESIS
383 if (pAC->GIni.GIGenesis) {
384
385 XM_IN32(IoC, Port, XM_MODE, &MdReg);
386 /* enable or disable promiscuous mode */
387 if (Enable) {
388 MdReg |= XM_MD_ENA_PROM;
389 }
390 else {
391 MdReg &= ~XM_MD_ENA_PROM;
392 }
393 /* setup Mode Register */
394 XM_OUT32(IoC, Port, XM_MODE, MdReg);
395 }
396#endif /* GENESIS */
397
398#ifdef YUKON
399 if (pAC->GIni.GIYukon) {
400
401 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
402
403 /* enable or disable unicast and multicast filtering */
404 if (Enable) {
405 RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
406 }
407 else {
408 RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
409 }
410 /* setup Receive Control Register */
411 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
412 }
413#endif /* YUKON */
414
415} /* SkMacPromiscMode*/
416
417
418/******************************************************************************
419 *
420 * SkMacHashing() - Enable / Disable Hashing
421 *
422 * Description:
423 * enables / disables hashing by setting Mode Register (XMAC) or
424 * Receive Control Register (GMAC) dep. on board type
425 *
426 * Returns:
427 * nothing
428 */
429void SkMacHashing(
430SK_AC *pAC, /* adapter context */
431SK_IOC IoC, /* IO context */
432int Port, /* Port Index (MAC_1 + n) */
433SK_BOOL Enable) /* Enable / Disable */
434{
435#ifdef YUKON
436 SK_U16 RcReg;
437#endif
438#ifdef GENESIS
439 SK_U32 MdReg;
440#endif
441
442#ifdef GENESIS
443 if (pAC->GIni.GIGenesis) {
444
445 XM_IN32(IoC, Port, XM_MODE, &MdReg);
446 /* enable or disable hashing */
447 if (Enable) {
448 MdReg |= XM_MD_ENA_HASH;
449 }
450 else {
451 MdReg &= ~XM_MD_ENA_HASH;
452 }
453 /* setup Mode Register */
454 XM_OUT32(IoC, Port, XM_MODE, MdReg);
455 }
456#endif /* GENESIS */
457
458#ifdef YUKON
459 if (pAC->GIni.GIYukon) {
460
461 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
462
463 /* enable or disable multicast filtering */
464 if (Enable) {
465 RcReg |= GM_RXCR_MCF_ENA;
466 }
467 else {
468 RcReg &= ~GM_RXCR_MCF_ENA;
469 }
470 /* setup Receive Control Register */
471 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
472 }
473#endif /* YUKON */
474
475} /* SkMacHashing*/
476
477
478#ifdef SK_DIAG
479/******************************************************************************
480 *
481 * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
482 *
483 * Description:
484 * The features
485 * - FCS stripping, SK_STRIP_FCS_ON/OFF
486 * - pad byte stripping, SK_STRIP_PAD_ON/OFF
487 * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF
488 * for inrange length error frames
489 * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF
490 * for frames > 1514 bytes
491 * - enable Rx of own packets SK_SELF_RX_ON/OFF
492 *
493 * for incoming packets may be enabled/disabled by this function.
494 * Additional modes may be added later.
495 * Multiple modes can be enabled/disabled at the same time.
496 * The new configuration is written to the Rx Command register immediately.
497 *
498 * Returns:
499 * nothing
500 */
501static void SkXmSetRxCmd(
502SK_AC *pAC, /* adapter context */
503SK_IOC IoC, /* IO context */
504int Port, /* Port Index (MAC_1 + n) */
505int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
506 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
507{
508 SK_U16 OldRxCmd;
509 SK_U16 RxCmd;
510
511 XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
512
513 RxCmd = OldRxCmd;
514
515 switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
516 case SK_STRIP_FCS_ON:
517 RxCmd |= XM_RX_STRIP_FCS;
518 break;
519 case SK_STRIP_FCS_OFF:
520 RxCmd &= ~XM_RX_STRIP_FCS;
521 break;
522 }
523
524 switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
525 case SK_STRIP_PAD_ON:
526 RxCmd |= XM_RX_STRIP_PAD;
527 break;
528 case SK_STRIP_PAD_OFF:
529 RxCmd &= ~XM_RX_STRIP_PAD;
530 break;
531 }
532
533 switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
534 case SK_LENERR_OK_ON:
535 RxCmd |= XM_RX_LENERR_OK;
536 break;
537 case SK_LENERR_OK_OFF:
538 RxCmd &= ~XM_RX_LENERR_OK;
539 break;
540 }
541
542 switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
543 case SK_BIG_PK_OK_ON:
544 RxCmd |= XM_RX_BIG_PK_OK;
545 break;
546 case SK_BIG_PK_OK_OFF:
547 RxCmd &= ~XM_RX_BIG_PK_OK;
548 break;
549 }
550
551 switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
552 case SK_SELF_RX_ON:
553 RxCmd |= XM_RX_SELF_RX;
554 break;
555 case SK_SELF_RX_OFF:
556 RxCmd &= ~XM_RX_SELF_RX;
557 break;
558 }
559
560 /* Write the new mode to the Rx command register if required */
561 if (OldRxCmd != RxCmd) {
562 XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
563 }
564} /* SkXmSetRxCmd */
565
566
567/******************************************************************************
568 *
569 * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
570 *
571 * Description:
572 * The features
573 * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF
574 * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF
575 * for frames > 1514 bytes
576 * - enable Rx of own packets SK_SELF_RX_ON/OFF
577 *
578 * for incoming packets may be enabled/disabled by this function.
579 * Additional modes may be added later.
580 * Multiple modes can be enabled/disabled at the same time.
581 * The new configuration is written to the Rx Command register immediately.
582 *
583 * Returns:
584 * nothing
585 */
586static void SkGmSetRxCmd(
587SK_AC *pAC, /* adapter context */
588SK_IOC IoC, /* IO context */
589int Port, /* Port Index (MAC_1 + n) */
590int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
591 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
592{
593 SK_U16 OldRxCmd;
594 SK_U16 RxCmd;
595
596 if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
597
598 GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
599
600 RxCmd = OldRxCmd;
601
602 if ((Mode & SK_STRIP_FCS_ON) != 0) {
603 RxCmd |= GM_RXCR_CRC_DIS;
604 }
605 else {
606 RxCmd &= ~GM_RXCR_CRC_DIS;
607 }
608 /* Write the new mode to the Rx control register if required */
609 if (OldRxCmd != RxCmd) {
610 GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
611 }
612 }
613
614 if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
615
616 GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
617
618 RxCmd = OldRxCmd;
619
620 if ((Mode & SK_BIG_PK_OK_ON) != 0) {
621 RxCmd |= GM_SMOD_JUMBO_ENA;
622 }
623 else {
624 RxCmd &= ~GM_SMOD_JUMBO_ENA;
625 }
626 /* Write the new mode to the Rx control register if required */
627 if (OldRxCmd != RxCmd) {
628 GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
629 }
630 }
631} /* SkGmSetRxCmd */
632
633
634/******************************************************************************
635 *
636 * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
637 *
638 * Description: modifies the MAC's Rx Control reg. dep. on board type
639 *
640 * Returns:
641 * nothing
642 */
643void SkMacSetRxCmd(
644SK_AC *pAC, /* adapter context */
645SK_IOC IoC, /* IO context */
646int Port, /* Port Index (MAC_1 + n) */
647int Mode) /* Rx Mode */
648{
649 if (pAC->GIni.GIGenesis) {
650
651 SkXmSetRxCmd(pAC, IoC, Port, Mode);
652 }
653 else {
654
655 SkGmSetRxCmd(pAC, IoC, Port, Mode);
656 }
657
658} /* SkMacSetRxCmd */
659
660
661/******************************************************************************
662 *
663 * SkMacCrcGener() - Enable / Disable CRC Generation
664 *
665 * Description: enables / disables CRC generation dep. on board type
666 *
667 * Returns:
668 * nothing
669 */
670void SkMacCrcGener(
671SK_AC *pAC, /* adapter context */
672SK_IOC IoC, /* IO context */
673int Port, /* Port Index (MAC_1 + n) */
674SK_BOOL Enable) /* Enable / Disable */
675{
676 SK_U16 Word;
677
678 if (pAC->GIni.GIGenesis) {
679
680 XM_IN16(IoC, Port, XM_TX_CMD, &Word);
681
682 if (Enable) {
683 Word &= ~XM_TX_NO_CRC;
684 }
685 else {
686 Word |= XM_TX_NO_CRC;
687 }
688 /* setup Tx Command Register */
689 XM_OUT16(IoC, Port, XM_TX_CMD, Word);
690 }
691 else {
692
693 GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
694
695 if (Enable) {
696 Word &= ~GM_TXCR_CRC_DIS;
697 }
698 else {
699 Word |= GM_TXCR_CRC_DIS;
700 }
701 /* setup Tx Control Register */
702 GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
703 }
704
705} /* SkMacCrcGener*/
706
707#endif /* SK_DIAG */
708
709
710#ifdef GENESIS
711/******************************************************************************
712 *
713 * SkXmClrExactAddr() - Clear Exact Match Address Registers
714 *
715 * Description:
716 * All Exact Match Address registers of the XMAC 'Port' will be
717 * cleared starting with 'StartNum' up to (and including) the
718 * Exact Match address number of 'StopNum'.
719 *
720 * Returns:
721 * nothing
722 */
723void SkXmClrExactAddr(
724SK_AC *pAC, /* adapter context */
725SK_IOC IoC, /* IO context */
726int Port, /* Port Index (MAC_1 + n) */
727int StartNum, /* Begin with this Address Register Index (0..15) */
728int StopNum) /* Stop after finished with this Register Idx (0..15) */
729{
730 int i;
731 SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
732
733 if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
734 StartNum > StopNum) {
735
736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
737 return;
738 }
739
740 for (i = StartNum; i <= StopNum; i++) {
741 XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
742 }
743} /* SkXmClrExactAddr */
744#endif /* GENESIS */
745
746
747/******************************************************************************
748 *
749 * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
750 *
751 * Description:
752 * Flush the transmit FIFO of the MAC specified by the index 'Port'
753 *
754 * Returns:
755 * nothing
756 */
757void SkMacFlushTxFifo(
758SK_AC *pAC, /* adapter context */
759SK_IOC IoC, /* IO context */
760int Port) /* Port Index (MAC_1 + n) */
761{
762#ifdef GENESIS
763 SK_U32 MdReg;
764
765 if (pAC->GIni.GIGenesis) {
766
767 XM_IN32(IoC, Port, XM_MODE, &MdReg);
768
769 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
770 }
771#endif /* GENESIS */
772
773#ifdef YUKON
774 if (pAC->GIni.GIYukon) {
775 /* no way to flush the FIFO we have to issue a reset */
776 /* TBD */
777 }
778#endif /* YUKON */
779
780} /* SkMacFlushTxFifo */
781
782
783/******************************************************************************
784 *
785 * SkMacFlushRxFifo() - Flush the MAC's receive FIFO
786 *
787 * Description:
788 * Flush the receive FIFO of the MAC specified by the index 'Port'
789 *
790 * Returns:
791 * nothing
792 */
793static void SkMacFlushRxFifo(
794SK_AC *pAC, /* adapter context */
795SK_IOC IoC, /* IO context */
796int Port) /* Port Index (MAC_1 + n) */
797{
798#ifdef GENESIS
799 SK_U32 MdReg;
800
801 if (pAC->GIni.GIGenesis) {
802
803 XM_IN32(IoC, Port, XM_MODE, &MdReg);
804
805 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
806 }
807#endif /* GENESIS */
808
809#ifdef YUKON
810 if (pAC->GIni.GIYukon) {
811 /* no way to flush the FIFO we have to issue a reset */
812 /* TBD */
813 }
814#endif /* YUKON */
815
816} /* SkMacFlushRxFifo */
817
818
819#ifdef GENESIS
820/******************************************************************************
821 *
822 * SkXmSoftRst() - Do a XMAC software reset
823 *
824 * Description:
825 * The PHY registers should not be destroyed during this
826 * kind of software reset. Therefore the XMAC Software Reset
827 * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
828 *
829 * The software reset is done by
830 * - disabling the Rx and Tx state machine,
831 * - resetting the statistics module,
832 * - clear all other significant XMAC Mode,
833 * Command, and Control Registers
834 * - clearing the Hash Register and the
835 * Exact Match Address registers, and
836 * - flushing the XMAC's Rx and Tx FIFOs.
837 *
838 * Note:
839 * Another requirement when stopping the XMAC is to
840 * avoid sending corrupted frames on the network.
841 * Disabling the Tx state machine will NOT interrupt
842 * the currently transmitted frame. But we must take care
843 * that the Tx FIFO is cleared AFTER the current frame
844 * is complete sent to the network.
845 *
846 * It takes about 12ns to send a frame with 1538 bytes.
847 * One PCI clock goes at least 15ns (66MHz). Therefore
848 * after reading XM_GP_PORT back, we are sure that the
849 * transmitter is disabled AND idle. And this means
850 * we may flush the transmit FIFO now.
851 *
852 * Returns:
853 * nothing
854 */
855static void SkXmSoftRst(
856SK_AC *pAC, /* adapter context */
857SK_IOC IoC, /* IO context */
858int Port) /* Port Index (MAC_1 + n) */
859{
860 SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
861
862 /* reset the statistics module */
863 XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
864
865 /* disable all XMAC IRQs */
866 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
867
868 XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */
869
870 XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */
871 XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */
872
873 /* disable all PHY IRQs */
874 switch (pAC->GIni.GP[Port].PhyType) {
875 case SK_PHY_BCOM:
876 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
877 break;
878#ifdef OTHER_PHY
879 case SK_PHY_LONE:
880 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
881 break;
882 case SK_PHY_NAT:
883 /* todo: National
884 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
885 break;
886#endif /* OTHER_PHY */
887 }
888
889 /* clear the Hash Register */
890 XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
891
892 /* clear the Exact Match Address registers */
893 SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
894
895 /* clear the Source Check Address registers */
896 XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
897
898} /* SkXmSoftRst */
899
900
901/******************************************************************************
902 *
903 * SkXmHardRst() - Do a XMAC hardware reset
904 *
905 * Description:
906 * The XMAC of the specified 'Port' and all connected devices
907 * (PHY and SERDES) will receive a reset signal on its *Reset pins.
908 * External PHYs must be reset by clearing a bit in the GPIO register
909 * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
910 *
911 * ATTENTION:
912 * It is absolutely necessary to reset the SW_RST Bit first
913 * before calling this function.
914 *
915 * Returns:
916 * nothing
917 */
918static void SkXmHardRst(
919SK_AC *pAC, /* adapter context */
920SK_IOC IoC, /* IO context */
921int Port) /* Port Index (MAC_1 + n) */
922{
923 SK_U32 Reg;
924 int i;
925 int TOut;
926 SK_U16 Word;
927
928 for (i = 0; i < 4; i++) {
929 /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
930 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
931
932 TOut = 0;
933 do {
934 if (TOut++ > 10000) {
935 /*
936 * Adapter seems to be in RESET state.
937 * Registers cannot be written.
938 */
939 return;
940 }
941
942 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
943
944 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
945
946 } while ((Word & MFF_SET_MAC_RST) == 0);
947 }
948
949 /* For external PHYs there must be special handling */
950 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
951
952 SK_IN32(IoC, B2_GP_IO, &Reg);
953
954 if (Port == 0) {
955 Reg |= GP_DIR_0; /* set to output */
956 Reg &= ~GP_IO_0; /* set PHY reset (active low) */
957 }
958 else {
959 Reg |= GP_DIR_2; /* set to output */
960 Reg &= ~GP_IO_2; /* set PHY reset (active low) */
961 }
962 /* reset external PHY */
963 SK_OUT32(IoC, B2_GP_IO, Reg);
964
965 /* short delay */
966 SK_IN32(IoC, B2_GP_IO, &Reg);
967 }
968} /* SkXmHardRst */
969
970
971/******************************************************************************
972 *
973 * SkXmClearRst() - Release the PHY & XMAC reset
974 *
975 * Description:
976 *
977 * Returns:
978 * nothing
979 */
980static void SkXmClearRst(
981SK_AC *pAC, /* adapter context */
982SK_IOC IoC, /* IO context */
983int Port) /* Port Index (MAC_1 + n) */
984{
985 SK_U32 DWord;
986
987 /* clear HW reset */
988 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
989
990 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
991
992 SK_IN32(IoC, B2_GP_IO, &DWord);
993
994 if (Port == 0) {
995 DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
996 }
997 else {
998 DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
999 }
1000 /* Clear PHY reset */
1001 SK_OUT32(IoC, B2_GP_IO, DWord);
1002
1003 /* Enable GMII interface */
1004 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
1005 }
1006} /* SkXmClearRst */
1007#endif /* GENESIS */
1008
1009
1010#ifdef YUKON
1011/******************************************************************************
1012 *
1013 * SkGmSoftRst() - Do a GMAC software reset
1014 *
1015 * Description:
1016 * The GPHY registers should not be destroyed during this
1017 * kind of software reset.
1018 *
1019 * Returns:
1020 * nothing
1021 */
1022static void SkGmSoftRst(
1023SK_AC *pAC, /* adapter context */
1024SK_IOC IoC, /* IO context */
1025int Port) /* Port Index (MAC_1 + n) */
1026{
1027 SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
1028 SK_U16 RxCtrl;
1029
1030 /* reset the statistics module */
1031
1032 /* disable all GMAC IRQs */
1033 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
1034
1035 /* disable all PHY IRQs */
1036 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
1037
1038 /* clear the Hash Register */
1039 GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
1040
1041 /* Enable Unicast and Multicast filtering */
1042 GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
1043
1044 GM_OUT16(IoC, Port, GM_RX_CTRL,
1045 (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
1046
1047} /* SkGmSoftRst */
1048
1049
1050/******************************************************************************
1051 *
1052 * SkGmHardRst() - Do a GMAC hardware reset
1053 *
1054 * Description:
1055 *
1056 * Returns:
1057 * nothing
1058 */
1059static void SkGmHardRst(
1060SK_AC *pAC, /* adapter context */
1061SK_IOC IoC, /* IO context */
1062int Port) /* Port Index (MAC_1 + n) */
1063{
1064 SK_U32 DWord;
1065
1066 /* WA code for COMA mode */
1067 if (pAC->GIni.GIYukonLite &&
1068 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1069
1070 SK_IN32(IoC, B2_GP_IO, &DWord);
1071
1072 DWord |= (GP_DIR_9 | GP_IO_9);
1073
1074 /* set PHY reset */
1075 SK_OUT32(IoC, B2_GP_IO, DWord);
1076 }
1077
1078 /* set GPHY Control reset */
1079 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
1080
1081 /* set GMAC Control reset */
1082 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1083
1084} /* SkGmHardRst */
1085
1086
1087/******************************************************************************
1088 *
1089 * SkGmClearRst() - Release the GPHY & GMAC reset
1090 *
1091 * Description:
1092 *
1093 * Returns:
1094 * nothing
1095 */
1096static void SkGmClearRst(
1097SK_AC *pAC, /* adapter context */
1098SK_IOC IoC, /* IO context */
1099int Port) /* Port Index (MAC_1 + n) */
1100{
1101 SK_U32 DWord;
1102
1103#ifdef XXX
1104 /* clear GMAC Control reset */
1105 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
1106
1107 /* set GMAC Control reset */
1108 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1109#endif /* XXX */
1110
1111 /* WA code for COMA mode */
1112 if (pAC->GIni.GIYukonLite &&
1113 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1114
1115 SK_IN32(IoC, B2_GP_IO, &DWord);
1116
1117 DWord |= GP_DIR_9; /* set to output */
1118 DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
1119
1120 /* clear PHY reset */
1121 SK_OUT32(IoC, B2_GP_IO, DWord);
1122 }
1123
1124 /* set HWCFG_MODE */
1125 DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
1126 GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
1127 (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
1128 GPC_HWCFG_GMII_FIB);
1129
1130 /* set GPHY Control reset */
1131 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
1132
1133 /* release GPHY Control reset */
1134 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
1135
1136#ifdef VCPU
1137 VCpuWait(9000);
1138#endif /* VCPU */
1139
1140 /* clear GMAC Control reset */
1141 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
1142
1143#ifdef VCPU
1144 VCpuWait(2000);
1145
1146 SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
1147
1148 SK_IN32(IoC, B0_ISRC, &DWord);
1149#endif /* VCPU */
1150
1151} /* SkGmClearRst */
1152#endif /* YUKON */
1153
1154
1155/******************************************************************************
1156 *
1157 * SkMacSoftRst() - Do a MAC software reset
1158 *
1159 * Description: calls a MAC software reset routine dep. on board type
1160 *
1161 * Returns:
1162 * nothing
1163 */
1164void SkMacSoftRst(
1165SK_AC *pAC, /* adapter context */
1166SK_IOC IoC, /* IO context */
1167int Port) /* Port Index (MAC_1 + n) */
1168{
1169 SK_GEPORT *pPrt;
1170
1171 pPrt = &pAC->GIni.GP[Port];
1172
1173 /* disable receiver and transmitter */
1174 SkMacRxTxDisable(pAC, IoC, Port);
1175
1176#ifdef GENESIS
1177 if (pAC->GIni.GIGenesis) {
1178
1179 SkXmSoftRst(pAC, IoC, Port);
1180 }
1181#endif /* GENESIS */
1182
1183#ifdef YUKON
1184 if (pAC->GIni.GIYukon) {
1185
1186 SkGmSoftRst(pAC, IoC, Port);
1187 }
1188#endif /* YUKON */
1189
1190 /* flush the MAC's Rx and Tx FIFOs */
1191 SkMacFlushTxFifo(pAC, IoC, Port);
1192
1193 SkMacFlushRxFifo(pAC, IoC, Port);
1194
1195 pPrt->PState = SK_PRT_STOP;
1196
1197} /* SkMacSoftRst */
1198
1199
1200/******************************************************************************
1201 *
1202 * SkMacHardRst() - Do a MAC hardware reset
1203 *
1204 * Description: calls a MAC hardware reset routine dep. on board type
1205 *
1206 * Returns:
1207 * nothing
1208 */
1209void SkMacHardRst(
1210SK_AC *pAC, /* adapter context */
1211SK_IOC IoC, /* IO context */
1212int Port) /* Port Index (MAC_1 + n) */
1213{
1214
1215#ifdef GENESIS
1216 if (pAC->GIni.GIGenesis) {
1217
1218 SkXmHardRst(pAC, IoC, Port);
1219 }
1220#endif /* GENESIS */
1221
1222#ifdef YUKON
1223 if (pAC->GIni.GIYukon) {
1224
1225 SkGmHardRst(pAC, IoC, Port);
1226 }
1227#endif /* YUKON */
1228
1229 pAC->GIni.GP[Port].PState = SK_PRT_RESET;
1230
1231} /* SkMacHardRst */
1232
1233
1234#ifdef GENESIS
1235/******************************************************************************
1236 *
1237 * SkXmInitMac() - Initialize the XMAC II
1238 *
1239 * Description:
1240 * Initialize the XMAC of the specified port.
1241 * The XMAC must be reset or stopped before calling this function.
1242 *
1243 * Note:
1244 * The XMAC's Rx and Tx state machine is still disabled when returning.
1245 *
1246 * Returns:
1247 * nothing
1248 */
1249void SkXmInitMac(
1250SK_AC *pAC, /* adapter context */
1251SK_IOC IoC, /* IO context */
1252int Port) /* Port Index (MAC_1 + n) */
1253{
1254 SK_GEPORT *pPrt;
1255 int i;
1256 SK_U16 SWord;
1257
1258 pPrt = &pAC->GIni.GP[Port];
1259
1260 if (pPrt->PState == SK_PRT_STOP) {
1261 /* Port State: SK_PRT_STOP */
1262 /* Verify that the reset bit is cleared */
1263 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
1264
1265 if ((SWord & MFF_SET_MAC_RST) != 0) {
1266 /* PState does not match HW state */
1267 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1268 /* Correct it */
1269 pPrt->PState = SK_PRT_RESET;
1270 }
1271 }
1272
1273 if (pPrt->PState == SK_PRT_RESET) {
1274
1275 SkXmClearRst(pAC, IoC, Port);
1276
1277 if (pPrt->PhyType != SK_PHY_XMAC) {
1278 /* read Id from external PHY (all have the same address) */
1279 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
1280
1281 /*
1282 * Optimize MDIO transfer by suppressing preamble.
1283 * Must be done AFTER first access to BCOM chip.
1284 */
1285 XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
1286
1287 XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
1288
1289 if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
1290 /*
1291 * Workaround BCOM Errata for the C0 type.
1292 * Write magic patterns to reserved registers.
1293 */
1294 i = 0;
1295 while (BcomRegC0Hack[i].PhyReg != 0) {
1296 SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
1297 BcomRegC0Hack[i].PhyVal);
1298 i++;
1299 }
1300 }
1301 else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
1302 /*
1303 * Workaround BCOM Errata for the A1 type.
1304 * Write magic patterns to reserved registers.
1305 */
1306 i = 0;
1307 while (BcomRegA1Hack[i].PhyReg != 0) {
1308 SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
1309 BcomRegA1Hack[i].PhyVal);
1310 i++;
1311 }
1312 }
1313
1314 /*
1315 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1316 * Disable Power Management after reset.
1317 */
1318 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
1319
1320 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
1321 (SK_U16)(SWord | PHY_B_AC_DIS_PM));
1322
1323 /* PHY LED initialization is done in SkGeXmitLED() */
1324 }
1325
1326 /* Dummy read the Interrupt source register */
1327 XM_IN16(IoC, Port, XM_ISRC, &SWord);
1328
1329 /*
1330 * The auto-negotiation process starts immediately after
1331 * clearing the reset. The auto-negotiation process should be
1332 * started by the SIRQ, therefore stop it here immediately.
1333 */
1334 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
1335
1336#ifdef TEST_ONLY
1337 /* temp. code: enable signal detect */
1338 /* WARNING: do not override GMII setting above */
1339 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
1340#endif
1341 }
1342
1343 /*
1344 * configure the XMACs Station Address
1345 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
1346 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
1347 */
1348 for (i = 0; i < 3; i++) {
1349 /*
1350 * The following 2 statements are together endianess
1351 * independent. Remember this when changing.
1352 */
1353 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1354
1355 XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
1356 }
1357
1358 /* Tx Inter Packet Gap (XM_TX_IPG): use default */
1359 /* Tx High Water Mark (XM_TX_HI_WM): use default */
1360 /* Tx Low Water Mark (XM_TX_LO_WM): use default */
1361 /* Host Request Threshold (XM_HT_THR): use default */
1362 /* Rx Request Threshold (XM_RX_THR): use default */
1363 /* Rx Low Water Mark (XM_RX_LO_WM): use default */
1364
1365 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1366 XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
1367
1368 /* Configure Tx Request Threshold */
1369 SWord = SK_XM_THR_SL; /* for single port */
1370
1371 if (pAC->GIni.GIMacsFound > 1) {
1372 switch (pAC->GIni.GIPortUsage) {
1373 case SK_RED_LINK:
1374 SWord = SK_XM_THR_REDL; /* redundant link */
1375 break;
1376 case SK_MUL_LINK:
1377 SWord = SK_XM_THR_MULL; /* load balancing */
1378 break;
1379 case SK_JUMBO_LINK:
1380 SWord = SK_XM_THR_JUMBO; /* jumbo frames */
1381 break;
1382 default:
1383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
1384 break;
1385 }
1386 }
1387 XM_OUT16(IoC, Port, XM_TX_THR, SWord);
1388
1389 /* setup register defaults for the Tx Command Register */
1390 XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
1391
1392 /* setup register defaults for the Rx Command Register */
1393 SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
1394
1395 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1396 SWord |= XM_RX_BIG_PK_OK;
1397 }
1398
1399 if (pPrt->PLinkMode == SK_LMODE_HALF) {
1400 /*
1401 * If in manual half duplex mode the other side might be in
1402 * full duplex mode, so ignore if a carrier extension is not seen
1403 * on frames received
1404 */
1405 SWord |= XM_RX_DIS_CEXT;
1406 }
1407
1408 XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
1409
1410 /*
1411 * setup register defaults for the Mode Register
1412 * - Don't strip error frames to avoid Store & Forward
1413 * on the Rx side.
1414 * - Enable 'Check Station Address' bit
1415 * - Enable 'Check Address Array' bit
1416 */
1417 XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
1418
1419 /*
1420 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
1421 * - Enable all bits excepting 'Octets Rx OK Low CntOv'
1422 * and 'Octets Rx OK Hi Cnt Ov'.
1423 */
1424 XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
1425
1426 /*
1427 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
1428 * - Enable all bits excepting 'Octets Tx OK Low CntOv'
1429 * and 'Octets Tx OK Hi Cnt Ov'.
1430 */
1431 XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
1432
1433 /*
1434 * Do NOT init XMAC interrupt mask here.
1435 * All interrupts remain disable until link comes up!
1436 */
1437
1438 /*
1439 * Any additional configuration changes may be done now.
1440 * The last action is to enable the Rx and Tx state machine.
1441 * This should be done after the auto-negotiation process
1442 * has been completed successfully.
1443 */
1444} /* SkXmInitMac */
1445#endif /* GENESIS */
1446
1447
1448#ifdef YUKON
1449/******************************************************************************
1450 *
1451 * SkGmInitMac() - Initialize the GMAC
1452 *
1453 * Description:
1454 * Initialize the GMAC of the specified port.
1455 * The GMAC must be reset or stopped before calling this function.
1456 *
1457 * Note:
1458 * The GMAC's Rx and Tx state machine is still disabled when returning.
1459 *
1460 * Returns:
1461 * nothing
1462 */
1463void SkGmInitMac(
1464SK_AC *pAC, /* adapter context */
1465SK_IOC IoC, /* IO context */
1466int Port) /* Port Index (MAC_1 + n) */
1467{
1468 SK_GEPORT *pPrt;
1469 int i;
1470 SK_U16 SWord;
1471 SK_U32 DWord;
1472
1473 pPrt = &pAC->GIni.GP[Port];
1474
1475 if (pPrt->PState == SK_PRT_STOP) {
1476 /* Port State: SK_PRT_STOP */
1477 /* Verify that the reset bit is cleared */
1478 SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
1479
1480 if ((DWord & GMC_RST_SET) != 0) {
1481 /* PState does not match HW state */
1482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1483 /* Correct it */
1484 pPrt->PState = SK_PRT_RESET;
1485 }
1486 }
1487
1488 if (pPrt->PState == SK_PRT_RESET) {
1489
1490 SkGmHardRst(pAC, IoC, Port);
1491
1492 SkGmClearRst(pAC, IoC, Port);
1493
1494 /* Auto-negotiation ? */
1495 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1496 /* Auto-negotiation disabled */
1497
1498 /* get General Purpose Control */
1499 GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
1500
1501 /* disable auto-update for speed, duplex and flow-control */
1502 SWord |= GM_GPCR_AU_ALL_DIS;
1503
1504 /* setup General Purpose Control Register */
1505 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1506
1507 SWord = GM_GPCR_AU_ALL_DIS;
1508 }
1509 else {
1510 SWord = 0;
1511 }
1512
1513 /* speed settings */
1514 switch (pPrt->PLinkSpeed) {
1515 case SK_LSPEED_AUTO:
1516 case SK_LSPEED_1000MBPS:
1517 SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
1518 break;
1519 case SK_LSPEED_100MBPS:
1520 SWord |= GM_GPCR_SPEED_100;
1521 break;
1522 case SK_LSPEED_10MBPS:
1523 break;
1524 }
1525
1526 /* duplex settings */
1527 if (pPrt->PLinkMode != SK_LMODE_HALF) {
1528 /* set full duplex */
1529 SWord |= GM_GPCR_DUP_FULL;
1530 }
1531
1532 /* flow-control settings */
1533 switch (pPrt->PFlowCtrlMode) {
1534 case SK_FLOW_MODE_NONE:
1535 /* set Pause Off */
1536 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
1537 /* disable Tx & Rx flow-control */
1538 SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1539 break;
1540 case SK_FLOW_MODE_LOC_SEND:
1541 /* disable Rx flow-control */
1542 SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1543 break;
1544 case SK_FLOW_MODE_SYMMETRIC:
1545 case SK_FLOW_MODE_SYM_OR_REM:
1546 /* enable Tx & Rx flow-control */
1547 break;
1548 }
1549
1550 /* setup General Purpose Control Register */
1551 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1552
1553 /* dummy read the Interrupt Source Register */
1554 SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
1555
1556#ifndef VCPU
1557 /* read Id from PHY */
1558 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
1559
1560 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
1561#endif /* VCPU */
1562 }
1563
1564 (void)SkGmResetCounter(pAC, IoC, Port);
1565
1566 /* setup Transmit Control Register */
1567 GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
1568
1569 /* setup Receive Control Register */
1570 GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
1571 GM_RXCR_CRC_DIS);
1572
1573 /* setup Transmit Flow Control Register */
1574 GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
1575
1576 /* setup Transmit Parameter Register */
1577#ifdef VCPU
1578 GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
1579#endif /* VCPU */
1580
1581 SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
1582 TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
1583 TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
1584
1585 GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
1586
1587 /* configure the Serial Mode Register */
1588#ifdef VCPU
1589 GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
1590#endif /* VCPU */
1591
1592 SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
1593
1594 if (pPrt->PMacLimit4) {
1595 /* reset of collision counter after 4 consecutive collisions */
1596 SWord |= GM_SMOD_LIMIT_4;
1597 }
1598
1599 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1600 /* enable jumbo mode (Max. Frame Length = 9018) */
1601 SWord |= GM_SMOD_JUMBO_ENA;
1602 }
1603
1604 GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
1605
1606 /*
1607 * configure the GMACs Station Addresses
1608 * in PROM you can find our addresses at:
1609 * B2_MAC_1 = xx xx xx xx xx x0 virtual address
1610 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
1611 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
1612 */
1613
1614 for (i = 0; i < 3; i++) {
1615 /*
1616 * The following 2 statements are together endianess
1617 * independent. Remember this when changing.
1618 */
1619 /* physical address: will be used for pause frames */
1620 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1621
1622#ifdef WA_DEV_16
1623 /* WA for deviation #16 */
1624 if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
1625 /* swap the address bytes */
1626 SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
1627
1628 /* write to register in reversed order */
1629 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
1630 }
1631 else {
1632 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1633 }
1634#else
1635 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1636#endif /* WA_DEV_16 */
1637
1638 /* virtual address: will be used for data */
1639 SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
1640
1641 GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
1642
1643 /* reset Multicast filtering Hash registers 1-3 */
1644 GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
1645 }
1646
1647 /* reset Multicast filtering Hash register 4 */
1648 GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
1649
1650 /* enable interrupt mask for counter overflows */
1651 GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
1652 GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
1653 GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
1654
1655#if defined(SK_DIAG) || defined(DEBUG)
1656 /* read General Purpose Status */
1657 GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
1658
1659 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1660 ("MAC Stat Reg.=0x%04X\n", SWord));
1661#endif /* SK_DIAG || DEBUG */
1662
1663#ifdef SK_DIAG
1664 c_print("MAC Stat Reg=0x%04X\n", SWord);
1665#endif /* SK_DIAG */
1666
1667} /* SkGmInitMac */
1668#endif /* YUKON */
1669
1670
1671#ifdef GENESIS
1672/******************************************************************************
1673 *
1674 * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
1675 *
1676 * Description:
1677 * This function initializes the XMACs Duplex Mode.
1678 * It should be called after successfully finishing
1679 * the Auto-negotiation Process
1680 *
1681 * Returns:
1682 * nothing
1683 */
1684static void SkXmInitDupMd(
1685SK_AC *pAC, /* adapter context */
1686SK_IOC IoC, /* IO context */
1687int Port) /* Port Index (MAC_1 + n) */
1688{
1689 switch (pAC->GIni.GP[Port].PLinkModeStatus) {
1690 case SK_LMODE_STAT_AUTOHALF:
1691 case SK_LMODE_STAT_HALF:
1692 /* Configuration Actions for Half Duplex Mode */
1693 /*
1694 * XM_BURST = default value. We are probable not quick
1695 * enough at the 'XMAC' bus to burst 8kB.
1696 * The XMAC stops bursting if no transmit frames
1697 * are available or the burst limit is exceeded.
1698 */
1699 /* XM_TX_RT_LIM = default value (15) */
1700 /* XM_TX_STIME = default value (0xff = 4096 bit times) */
1701 break;
1702 case SK_LMODE_STAT_AUTOFULL:
1703 case SK_LMODE_STAT_FULL:
1704 /* Configuration Actions for Full Duplex Mode */
1705 /*
1706 * The duplex mode is configured by the PHY,
1707 * therefore it seems to be that there is nothing
1708 * to do here.
1709 */
1710 break;
1711 case SK_LMODE_STAT_UNKNOWN:
1712 default:
1713 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
1714 break;
1715 }
1716} /* SkXmInitDupMd */
1717
1718
1719/******************************************************************************
1720 *
1721 * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
1722 *
1723 * Description:
1724 * This function initializes the Pause Mode which should
1725 * be used for this port.
1726 * It should be called after successfully finishing
1727 * the Auto-negotiation Process
1728 *
1729 * Returns:
1730 * nothing
1731 */
1732static void SkXmInitPauseMd(
1733SK_AC *pAC, /* adapter context */
1734SK_IOC IoC, /* IO context */
1735int Port) /* Port Index (MAC_1 + n) */
1736{
1737 SK_GEPORT *pPrt;
1738 SK_U32 DWord;
1739 SK_U16 Word;
1740
1741 pPrt = &pAC->GIni.GP[Port];
1742
1743 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
1744
1745 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
1746 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1747
1748 /* Disable Pause Frame Reception */
1749 Word |= XM_MMU_IGN_PF;
1750 }
1751 else {
1752 /*
1753 * enabling pause frame reception is required for 1000BT
1754 * because the XMAC is not reset if the link is going down
1755 */
1756 /* Enable Pause Frame Reception */
1757 Word &= ~XM_MMU_IGN_PF;
1758 }
1759
1760 XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
1761
1762 XM_IN32(IoC, Port, XM_MODE, &DWord);
1763
1764 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
1765 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1766
1767 /*
1768 * Configure Pause Frame Generation
1769 * Use internal and external Pause Frame Generation.
1770 * Sending pause frames is edge triggered.
1771 * Send a Pause frame with the maximum pause time if
1772 * internal oder external FIFO full condition occurs.
1773 * Send a zero pause time frame to re-start transmission.
1774 */
1775
1776 /* XM_PAUSE_DA = '010000C28001' (default) */
1777
1778 /* XM_MAC_PTIME = 0xffff (maximum) */
1779 /* remember this value is defined in big endian (!) */
1780 XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
1781
1782 /* Set Pause Mode in Mode Register */
1783 DWord |= XM_PAUSE_MODE;
1784
1785 /* Set Pause Mode in MAC Rx FIFO */
1786 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
1787 }
1788 else {
1789 /*
1790 * disable pause frame generation is required for 1000BT
1791 * because the XMAC is not reset if the link is going down
1792 */
1793 /* Disable Pause Mode in Mode Register */
1794 DWord &= ~XM_PAUSE_MODE;
1795
1796 /* Disable Pause Mode in MAC Rx FIFO */
1797 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
1798 }
1799
1800 XM_OUT32(IoC, Port, XM_MODE, DWord);
1801} /* SkXmInitPauseMd*/
1802
1803
1804/******************************************************************************
1805 *
1806 * SkXmInitPhyXmac() - Initialize the XMAC Phy registers
1807 *
1808 * Description: initializes all the XMACs Phy registers
1809 *
1810 * Note:
1811 *
1812 * Returns:
1813 * nothing
1814 */
1815static void SkXmInitPhyXmac(
1816SK_AC *pAC, /* adapter context */
1817SK_IOC IoC, /* IO context */
1818int Port, /* Port Index (MAC_1 + n) */
1819SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1820{
1821 SK_GEPORT *pPrt;
1822 SK_U16 Ctrl;
1823
1824 pPrt = &pAC->GIni.GP[Port];
1825 Ctrl = 0;
1826
1827 /* Auto-negotiation ? */
1828 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1830 ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
1831 /* Set DuplexMode in Config register */
1832 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1833 Ctrl |= PHY_CT_DUP_MD;
1834 }
1835
1836 /*
1837 * Do NOT enable Auto-negotiation here. This would hold
1838 * the link down because no IDLEs are transmitted
1839 */
1840 }
1841 else {
1842 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1843 ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
1844 /* Set Auto-negotiation advertisement */
1845
1846 /* Set Full/half duplex capabilities */
1847 switch (pPrt->PLinkMode) {
1848 case SK_LMODE_AUTOHALF:
1849 Ctrl |= PHY_X_AN_HD;
1850 break;
1851 case SK_LMODE_AUTOFULL:
1852 Ctrl |= PHY_X_AN_FD;
1853 break;
1854 case SK_LMODE_AUTOBOTH:
1855 Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
1856 break;
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1859 SKERR_HWI_E015MSG);
1860 }
1861
1862 /* Set Flow-control capabilities */
1863 switch (pPrt->PFlowCtrlMode) {
1864 case SK_FLOW_MODE_NONE:
1865 Ctrl |= PHY_X_P_NO_PAUSE;
1866 break;
1867 case SK_FLOW_MODE_LOC_SEND:
1868 Ctrl |= PHY_X_P_ASYM_MD;
1869 break;
1870 case SK_FLOW_MODE_SYMMETRIC:
1871 Ctrl |= PHY_X_P_SYM_MD;
1872 break;
1873 case SK_FLOW_MODE_SYM_OR_REM:
1874 Ctrl |= PHY_X_P_BOTH_MD;
1875 break;
1876 default:
1877 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
1878 SKERR_HWI_E016MSG);
1879 }
1880
1881 /* Write AutoNeg Advertisement Register */
1882 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
1883
1884 /* Restart Auto-negotiation */
1885 Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1886 }
1887
1888 if (DoLoop) {
1889 /* Set the Phy Loopback bit, too */
1890 Ctrl |= PHY_CT_LOOP;
1891 }
1892
1893 /* Write to the Phy control register */
1894 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
1895} /* SkXmInitPhyXmac */
1896
1897
1898/******************************************************************************
1899 *
1900 * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
1901 *
1902 * Description: initializes all the Broadcom Phy registers
1903 *
1904 * Note:
1905 *
1906 * Returns:
1907 * nothing
1908 */
1909static void SkXmInitPhyBcom(
1910SK_AC *pAC, /* adapter context */
1911SK_IOC IoC, /* IO context */
1912int Port, /* Port Index (MAC_1 + n) */
1913SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1914{
1915 SK_GEPORT *pPrt;
1916 SK_U16 Ctrl1;
1917 SK_U16 Ctrl2;
1918 SK_U16 Ctrl3;
1919 SK_U16 Ctrl4;
1920 SK_U16 Ctrl5;
1921
1922 Ctrl1 = PHY_CT_SP1000;
1923 Ctrl2 = 0;
1924 Ctrl3 = PHY_SEL_TYPE;
1925 Ctrl4 = PHY_B_PEC_EN_LTR;
1926 Ctrl5 = PHY_B_AC_TX_TST;
1927
1928 pPrt = &pAC->GIni.GP[Port];
1929
1930 /* manually Master/Slave ? */
1931 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
1932 Ctrl2 |= PHY_B_1000C_MSE;
1933
1934 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
1935 Ctrl2 |= PHY_B_1000C_MSC;
1936 }
1937 }
1938 /* Auto-negotiation ? */
1939 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1940 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1941 ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
1942 /* Set DuplexMode in Config register */
1943 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1944 Ctrl1 |= PHY_CT_DUP_MD;
1945 }
1946
1947 /* Determine Master/Slave manually if not already done */
1948 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
1949 Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
1950 }
1951
1952 /*
1953 * Do NOT enable Auto-negotiation here. This would hold
1954 * the link down because no IDLES are transmitted
1955 */
1956 }
1957 else {
1958 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1959 ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
1960 /* Set Auto-negotiation advertisement */
1961
1962 /*
1963 * Workaround BCOM Errata #1 for the C5 type.
1964 * 1000Base-T Link Acquisition Failure in Slave Mode
1965 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1966 */
1967 Ctrl2 |= PHY_B_1000C_RD;
1968
1969 /* Set Full/half duplex capabilities */
1970 switch (pPrt->PLinkMode) {
1971 case SK_LMODE_AUTOHALF:
1972 Ctrl2 |= PHY_B_1000C_AHD;
1973 break;
1974 case SK_LMODE_AUTOFULL:
1975 Ctrl2 |= PHY_B_1000C_AFD;
1976 break;
1977 case SK_LMODE_AUTOBOTH:
1978 Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
1979 break;
1980 default:
1981 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1982 SKERR_HWI_E015MSG);
1983 }
1984
1985 /* Set Flow-control capabilities */
1986 switch (pPrt->PFlowCtrlMode) {
1987 case SK_FLOW_MODE_NONE:
1988 Ctrl3 |= PHY_B_P_NO_PAUSE;
1989 break;
1990 case SK_FLOW_MODE_LOC_SEND:
1991 Ctrl3 |= PHY_B_P_ASYM_MD;
1992 break;
1993 case SK_FLOW_MODE_SYMMETRIC:
1994 Ctrl3 |= PHY_B_P_SYM_MD;
1995 break;
1996 case SK_FLOW_MODE_SYM_OR_REM:
1997 Ctrl3 |= PHY_B_P_BOTH_MD;
1998 break;
1999 default:
2000 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2001 SKERR_HWI_E016MSG);
2002 }
2003
2004 /* Restart Auto-negotiation */
2005 Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
2006 }
2007
2008 /* Initialize LED register here? */
2009 /* No. Please do it in SkDgXmitLed() (if required) and swap
2010 init order of LEDs and XMAC. (MAl) */
2011
2012 /* Write 1000Base-T Control Register */
2013 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
2014 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2015 ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2016
2017 /* Write AutoNeg Advertisement Register */
2018 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
2019 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2020 ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2021
2022 if (DoLoop) {
2023 /* Set the Phy Loopback bit, too */
2024 Ctrl1 |= PHY_CT_LOOP;
2025 }
2026
2027 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
2028 /* configure FIFO to high latency for transmission of ext. packets */
2029 Ctrl4 |= PHY_B_PEC_HIGH_LA;
2030
2031 /* configure reception of extended packets */
2032 Ctrl5 |= PHY_B_AC_LONG_PACK;
2033
2034 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
2035 }
2036
2037 /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
2038 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
2039
2040 /* Write to the Phy control register */
2041 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
2042 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2043 ("PHY Control Reg=0x%04X\n", Ctrl1));
2044} /* SkXmInitPhyBcom */
2045#endif /* GENESIS */
2046
2047#ifdef YUKON
2048/******************************************************************************
2049 *
2050 * SkGmInitPhyMarv() - Initialize the Marvell Phy registers
2051 *
2052 * Description: initializes all the Marvell Phy registers
2053 *
2054 * Note:
2055 *
2056 * Returns:
2057 * nothing
2058 */
2059static void SkGmInitPhyMarv(
2060SK_AC *pAC, /* adapter context */
2061SK_IOC IoC, /* IO context */
2062int Port, /* Port Index (MAC_1 + n) */
2063SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2064{
2065 SK_GEPORT *pPrt;
2066 SK_U16 PhyCtrl;
2067 SK_U16 C1000BaseT;
2068 SK_U16 AutoNegAdv;
2069 SK_U16 ExtPhyCtrl;
2070 SK_U16 LedCtrl;
2071 SK_BOOL AutoNeg;
2072#if defined(SK_DIAG) || defined(DEBUG)
2073 SK_U16 PhyStat;
2074 SK_U16 PhyStat1;
2075 SK_U16 PhySpecStat;
2076#endif /* SK_DIAG || DEBUG */
2077
2078 pPrt = &pAC->GIni.GP[Port];
2079
2080 /* Auto-negotiation ? */
2081 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2082 AutoNeg = SK_FALSE;
2083 }
2084 else {
2085 AutoNeg = SK_TRUE;
2086 }
2087
2088 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2089 ("InitPhyMarv: Port %d, auto-negotiation %s\n",
2090 Port, AutoNeg ? "ON" : "OFF"));
2091
2092#ifdef VCPU
2093 VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
2094 Port, DoLoop);
2095#else /* VCPU */
2096 if (DoLoop) {
2097 /* Set 'MAC Power up'-bit, set Manual MDI configuration */
2098 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2099 PHY_M_PC_MAC_POW_UP);
2100 }
2101 else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
2102 /* Read Ext. PHY Specific Control */
2103 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2104
2105 ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
2106 PHY_M_EC_MAC_S_MSK);
2107
2108 ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
2109 PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
2110
2111 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
2112 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2113 ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2114 }
2115
2116 /* Read PHY Control */
2117 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2118
2119 if (!AutoNeg) {
2120 /* Disable Auto-negotiation */
2121 PhyCtrl &= ~PHY_CT_ANE;
2122 }
2123
2124 PhyCtrl |= PHY_CT_RESET;
2125 /* Assert software reset */
2126 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2127#endif /* VCPU */
2128
2129 PhyCtrl = 0 /* PHY_CT_COL_TST */;
2130 C1000BaseT = 0;
2131 AutoNegAdv = PHY_SEL_TYPE;
2132
2133 /* manually Master/Slave ? */
2134 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2135 /* enable Manual Master/Slave */
2136 C1000BaseT |= PHY_M_1000C_MSE;
2137
2138 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2139 C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */
2140 }
2141 }
2142
2143 /* Auto-negotiation ? */
2144 if (!AutoNeg) {
2145
2146 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2147 /* Set Full Duplex Mode */
2148 PhyCtrl |= PHY_CT_DUP_MD;
2149 }
2150
2151 /* Set Master/Slave manually if not already done */
2152 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2153 C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */
2154 }
2155
2156 /* Set Speed */
2157 switch (pPrt->PLinkSpeed) {
2158 case SK_LSPEED_AUTO:
2159 case SK_LSPEED_1000MBPS:
2160 PhyCtrl |= PHY_CT_SP1000;
2161 break;
2162 case SK_LSPEED_100MBPS:
2163 PhyCtrl |= PHY_CT_SP100;
2164 break;
2165 case SK_LSPEED_10MBPS:
2166 break;
2167 default:
2168 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2169 SKERR_HWI_E019MSG);
2170 }
2171
2172 if (!DoLoop) {
2173 PhyCtrl |= PHY_CT_RESET;
2174 }
2175 }
2176 else {
2177 /* Set Auto-negotiation advertisement */
2178
2179 if (pAC->GIni.GICopperType) {
2180 /* Set Speed capabilities */
2181 switch (pPrt->PLinkSpeed) {
2182 case SK_LSPEED_AUTO:
2183 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2184 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2185 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2186 break;
2187 case SK_LSPEED_1000MBPS:
2188 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2189 break;
2190 case SK_LSPEED_100MBPS:
2191 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2192 /* advertise 10Base-T also */
2193 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2194 break;
2195 case SK_LSPEED_10MBPS:
2196 AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2197 break;
2198 default:
2199 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2200 SKERR_HWI_E019MSG);
2201 }
2202
2203 /* Set Full/half duplex capabilities */
2204 switch (pPrt->PLinkMode) {
2205 case SK_LMODE_AUTOHALF:
2206 C1000BaseT &= ~PHY_M_1000C_AFD;
2207 AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
2208 break;
2209 case SK_LMODE_AUTOFULL:
2210 C1000BaseT &= ~PHY_M_1000C_AHD;
2211 AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
2212 break;
2213 case SK_LMODE_AUTOBOTH:
2214 break;
2215 default:
2216 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2217 SKERR_HWI_E015MSG);
2218 }
2219
2220 /* Set Flow-control capabilities */
2221 switch (pPrt->PFlowCtrlMode) {
2222 case SK_FLOW_MODE_NONE:
2223 AutoNegAdv |= PHY_B_P_NO_PAUSE;
2224 break;
2225 case SK_FLOW_MODE_LOC_SEND:
2226 AutoNegAdv |= PHY_B_P_ASYM_MD;
2227 break;
2228 case SK_FLOW_MODE_SYMMETRIC:
2229 AutoNegAdv |= PHY_B_P_SYM_MD;
2230 break;
2231 case SK_FLOW_MODE_SYM_OR_REM:
2232 AutoNegAdv |= PHY_B_P_BOTH_MD;
2233 break;
2234 default:
2235 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2236 SKERR_HWI_E016MSG);
2237 }
2238 }
2239 else { /* special defines for FIBER (88E1011S only) */
2240
2241 /* Set Full/half duplex capabilities */
2242 switch (pPrt->PLinkMode) {
2243 case SK_LMODE_AUTOHALF:
2244 AutoNegAdv |= PHY_M_AN_1000X_AHD;
2245 break;
2246 case SK_LMODE_AUTOFULL:
2247 AutoNegAdv |= PHY_M_AN_1000X_AFD;
2248 break;
2249 case SK_LMODE_AUTOBOTH:
2250 AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
2251 break;
2252 default:
2253 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2254 SKERR_HWI_E015MSG);
2255 }
2256
2257 /* Set Flow-control capabilities */
2258 switch (pPrt->PFlowCtrlMode) {
2259 case SK_FLOW_MODE_NONE:
2260 AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
2261 break;
2262 case SK_FLOW_MODE_LOC_SEND:
2263 AutoNegAdv |= PHY_M_P_ASYM_MD_X;
2264 break;
2265 case SK_FLOW_MODE_SYMMETRIC:
2266 AutoNegAdv |= PHY_M_P_SYM_MD_X;
2267 break;
2268 case SK_FLOW_MODE_SYM_OR_REM:
2269 AutoNegAdv |= PHY_M_P_BOTH_MD_X;
2270 break;
2271 default:
2272 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2273 SKERR_HWI_E016MSG);
2274 }
2275 }
2276
2277 if (!DoLoop) {
2278 /* Restart Auto-negotiation */
2279 PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
2280 }
2281 }
2282
2283#ifdef VCPU
2284 /*
2285 * E-mail from Gu Lin (08-03-2002):
2286 */
2287
2288 /* Program PHY register 30 as 16'h0708 for simulation speed up */
2289 SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
2290
2291 VCpuWait(2000);
2292
2293#else /* VCPU */
2294
2295 /* Write 1000Base-T Control Register */
2296 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
2297 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2298 ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
2299
2300 /* Write AutoNeg Advertisement Register */
2301 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
2302 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2303 ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2304#endif /* VCPU */
2305
2306 if (DoLoop) {
2307 /* Set the PHY Loopback bit */
2308 PhyCtrl |= PHY_CT_LOOP;
2309
2310#ifdef XXX
2311 /* Program PHY register 16 as 16'h0400 to force link good */
2312 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
2313#endif /* XXX */
2314
2315#ifndef VCPU
2316 if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
2317 /* Write Ext. PHY Specific Control */
2318 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
2319 (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
2320 }
2321#endif /* VCPU */
2322 }
2323#ifdef TEST_ONLY
2324 else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
2325 /* Write PHY Specific Control */
2326 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2327 PHY_M_PC_EN_DET_MSK);
2328 }
2329#endif
2330
2331 /* Write to the PHY Control register */
2332 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2333 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2334 ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2335
2336#ifdef VCPU
2337 VCpuWait(2000);
2338#else
2339
2340 LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
2341
2342 if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
2343 LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
2344 }
2345
2346 if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
2347 LedCtrl |= PHY_M_LEDC_DP_CTRL;
2348 }
2349
2350 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
2351
2352 if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
2353 /* only in forced 100 Mbps mode */
2354 if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
2355
2356 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
2357 PHY_M_LED_MO_100(MO_LED_ON));
2358 }
2359 }
2360
2361#ifdef SK_DIAG
2362 c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
2363 c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
2364 c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
2365 c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
2366#endif /* SK_DIAG */
2367
2368#if defined(SK_DIAG) || defined(DEBUG)
2369 /* Read PHY Control */
2370 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2371 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2372 ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2373
2374 /* Read 1000Base-T Control Register */
2375 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
2376 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2377 ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
2378
2379 /* Read AutoNeg Advertisement Register */
2380 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
2381 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2382 ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2383
2384 /* Read Ext. PHY Specific Control */
2385 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2386 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2387 ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2388
2389 /* Read PHY Status */
2390 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
2391 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2392 ("PHY Stat Reg.=0x%04X\n", PhyStat));
2393 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
2394 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2395 ("PHY Stat Reg.=0x%04X\n", PhyStat1));
2396
2397 /* Read PHY Specific Status */
2398 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
2399 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2400 ("PHY Spec Stat=0x%04X\n", PhySpecStat));
2401#endif /* SK_DIAG || DEBUG */
2402
2403#ifdef SK_DIAG
2404 c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
2405 c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
2406 c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
2407 c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
2408 c_print("PHY Stat Reg=0x%04X\n", PhyStat);
2409 c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
2410 c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
2411#endif /* SK_DIAG */
2412
2413#endif /* VCPU */
2414
2415} /* SkGmInitPhyMarv */
2416#endif /* YUKON */
2417
2418
2419#ifdef OTHER_PHY
2420/******************************************************************************
2421 *
2422 * SkXmInitPhyLone() - Initialize the Level One Phy registers
2423 *
2424 * Description: initializes all the Level One Phy registers
2425 *
2426 * Note:
2427 *
2428 * Returns:
2429 * nothing
2430 */
2431static void SkXmInitPhyLone(
2432SK_AC *pAC, /* adapter context */
2433SK_IOC IoC, /* IO context */
2434int Port, /* Port Index (MAC_1 + n) */
2435SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2436{
2437 SK_GEPORT *pPrt;
2438 SK_U16 Ctrl1;
2439 SK_U16 Ctrl2;
2440 SK_U16 Ctrl3;
2441
2442 Ctrl1 = PHY_CT_SP1000;
2443 Ctrl2 = 0;
2444 Ctrl3 = PHY_SEL_TYPE;
2445
2446 pPrt = &pAC->GIni.GP[Port];
2447
2448 /* manually Master/Slave ? */
2449 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2450 Ctrl2 |= PHY_L_1000C_MSE;
2451
2452 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2453 Ctrl2 |= PHY_L_1000C_MSC;
2454 }
2455 }
2456 /* Auto-negotiation ? */
2457 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2458 /*
2459 * level one spec say: "1000 Mbps: manual mode not allowed"
2460 * but lets see what happens...
2461 */
2462 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2463 ("InitPhyLone: no auto-negotiation Port %d\n", Port));
2464 /* Set DuplexMode in Config register */
2465 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2466 Ctrl1 |= PHY_CT_DUP_MD;
2467 }
2468
2469 /* Determine Master/Slave manually if not already done */
2470 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2471 Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
2472 }
2473
2474 /*
2475 * Do NOT enable Auto-negotiation here. This would hold
2476 * the link down because no IDLES are transmitted
2477 */
2478 }
2479 else {
2480 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2481 ("InitPhyLone: with auto-negotiation Port %d\n", Port));
2482 /* Set Auto-negotiation advertisement */
2483
2484 /* Set Full/half duplex capabilities */
2485 switch (pPrt->PLinkMode) {
2486 case SK_LMODE_AUTOHALF:
2487 Ctrl2 |= PHY_L_1000C_AHD;
2488 break;
2489 case SK_LMODE_AUTOFULL:
2490 Ctrl2 |= PHY_L_1000C_AFD;
2491 break;
2492 case SK_LMODE_AUTOBOTH:
2493 Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
2494 break;
2495 default:
2496 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2497 SKERR_HWI_E015MSG);
2498 }
2499
2500 /* Set Flow-control capabilities */
2501 switch (pPrt->PFlowCtrlMode) {
2502 case SK_FLOW_MODE_NONE:
2503 Ctrl3 |= PHY_L_P_NO_PAUSE;
2504 break;
2505 case SK_FLOW_MODE_LOC_SEND:
2506 Ctrl3 |= PHY_L_P_ASYM_MD;
2507 break;
2508 case SK_FLOW_MODE_SYMMETRIC:
2509 Ctrl3 |= PHY_L_P_SYM_MD;
2510 break;
2511 case SK_FLOW_MODE_SYM_OR_REM:
2512 Ctrl3 |= PHY_L_P_BOTH_MD;
2513 break;
2514 default:
2515 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2516 SKERR_HWI_E016MSG);
2517 }
2518
2519 /* Restart Auto-negotiation */
2520 Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
2521 }
2522
2523 /* Write 1000Base-T Control Register */
2524 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
2525 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2526 ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2527
2528 /* Write AutoNeg Advertisement Register */
2529 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
2530 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2531 ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2532
2533 if (DoLoop) {
2534 /* Set the Phy Loopback bit, too */
2535 Ctrl1 |= PHY_CT_LOOP;
2536 }
2537
2538 /* Write to the Phy control register */
2539 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
2540 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2541 ("PHY Control Reg=0x%04X\n", Ctrl1));
2542} /* SkXmInitPhyLone */
2543
2544
2545/******************************************************************************
2546 *
2547 * SkXmInitPhyNat() - Initialize the National Phy registers
2548 *
2549 * Description: initializes all the National Phy registers
2550 *
2551 * Note:
2552 *
2553 * Returns:
2554 * nothing
2555 */
2556static void SkXmInitPhyNat(
2557SK_AC *pAC, /* adapter context */
2558SK_IOC IoC, /* IO context */
2559int Port, /* Port Index (MAC_1 + n) */
2560SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2561{
2562/* todo: National */
2563} /* SkXmInitPhyNat */
2564#endif /* OTHER_PHY */
2565
2566
2567/******************************************************************************
2568 *
2569 * SkMacInitPhy() - Initialize the PHY registers
2570 *
2571 * Description: calls the Init PHY routines dep. on board type
2572 *
2573 * Note:
2574 *
2575 * Returns:
2576 * nothing
2577 */
2578void SkMacInitPhy(
2579SK_AC *pAC, /* adapter context */
2580SK_IOC IoC, /* IO context */
2581int Port, /* Port Index (MAC_1 + n) */
2582SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2583{
2584 SK_GEPORT *pPrt;
2585
2586 pPrt = &pAC->GIni.GP[Port];
2587
2588#ifdef GENESIS
2589 if (pAC->GIni.GIGenesis) {
2590
2591 switch (pPrt->PhyType) {
2592 case SK_PHY_XMAC:
2593 SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
2594 break;
2595 case SK_PHY_BCOM:
2596 SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
2597 break;
2598#ifdef OTHER_PHY
2599 case SK_PHY_LONE:
2600 SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
2601 break;
2602 case SK_PHY_NAT:
2603 SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
2604 break;
2605#endif /* OTHER_PHY */
2606 }
2607 }
2608#endif /* GENESIS */
2609
2610#ifdef YUKON
2611 if (pAC->GIni.GIYukon) {
2612
2613 SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
2614 }
2615#endif /* YUKON */
2616
2617} /* SkMacInitPhy */
2618
2619
2620#ifdef GENESIS
2621/******************************************************************************
2622 *
2623 * SkXmAutoNegDoneXmac() - Auto-negotiation handling
2624 *
2625 * Description:
2626 * This function handles the auto-negotiation if the Done bit is set.
2627 *
2628 * Returns:
2629 * SK_AND_OK o.k.
2630 * SK_AND_DUP_CAP Duplex capability error happened
2631 * SK_AND_OTHER Other error happened
2632 */
2633static int SkXmAutoNegDoneXmac(
2634SK_AC *pAC, /* adapter context */
2635SK_IOC IoC, /* IO context */
2636int Port) /* Port Index (MAC_1 + n) */
2637{
2638 SK_GEPORT *pPrt;
2639 SK_U16 ResAb; /* Resolved Ability */
2640 SK_U16 LPAb; /* Link Partner Ability */
2641
2642 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2643 ("AutoNegDoneXmac, Port %d\n", Port));
2644
2645 pPrt = &pAC->GIni.GP[Port];
2646
2647 /* Get PHY parameters */
2648 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
2649 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
2650
2651 if ((LPAb & PHY_X_AN_RFB) != 0) {
2652 /* At least one of the remote fault bit is set */
2653 /* Error */
2654 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2655 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2656 pPrt->PAutoNegFail = SK_TRUE;
2657 return(SK_AND_OTHER);
2658 }
2659
2660 /* Check Duplex mismatch */
2661 if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
2662 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2663 }
2664 else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
2665 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2666 }
2667 else {
2668 /* Error */
2669 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2670 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2671 pPrt->PAutoNegFail = SK_TRUE;
2672 return(SK_AND_DUP_CAP);
2673 }
2674
2675 /* Check PAUSE mismatch */
2676 /* We are NOT using chapter 4.23 of the Xaqti manual */
2677 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2678 if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
2679 pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
2680 (LPAb & PHY_X_P_SYM_MD) != 0) {
2681 /* Symmetric PAUSE */
2682 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2683 }
2684 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
2685 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
2686 /* Enable PAUSE receive, disable PAUSE transmit */
2687 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2688 }
2689 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
2690 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
2691 /* Disable PAUSE receive, enable PAUSE transmit */
2692 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2693 }
2694 else {
2695 /* PAUSE mismatch -> no PAUSE */
2696 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2697 }
2698 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2699
2700 return(SK_AND_OK);
2701} /* SkXmAutoNegDoneXmac */
2702
2703
2704/******************************************************************************
2705 *
2706 * SkXmAutoNegDoneBcom() - Auto-negotiation handling
2707 *
2708 * Description:
2709 * This function handles the auto-negotiation if the Done bit is set.
2710 *
2711 * Returns:
2712 * SK_AND_OK o.k.
2713 * SK_AND_DUP_CAP Duplex capability error happened
2714 * SK_AND_OTHER Other error happened
2715 */
2716static int SkXmAutoNegDoneBcom(
2717SK_AC *pAC, /* adapter context */
2718SK_IOC IoC, /* IO context */
2719int Port) /* Port Index (MAC_1 + n) */
2720{
2721 SK_GEPORT *pPrt;
2722 SK_U16 LPAb; /* Link Partner Ability */
2723 SK_U16 AuxStat; /* Auxiliary Status */
2724
2725#ifdef TEST_ONLY
272601-Sep-2000 RA;:;:
2727 SK_U16 ResAb; /* Resolved Ability */
2728#endif /* 0 */
2729
2730 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2731 ("AutoNegDoneBcom, Port %d\n", Port));
2732 pPrt = &pAC->GIni.GP[Port];
2733
2734 /* Get PHY parameters */
2735 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
2736#ifdef TEST_ONLY
273701-Sep-2000 RA;:;:
2738 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
2739#endif /* 0 */
2740
2741 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
2742
2743 if ((LPAb & PHY_B_AN_RF) != 0) {
2744 /* Remote fault bit is set: Error */
2745 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2746 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2747 pPrt->PAutoNegFail = SK_TRUE;
2748 return(SK_AND_OTHER);
2749 }
2750
2751 /* Check Duplex mismatch */
2752 if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
2753 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2754 }
2755 else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
2756 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2757 }
2758 else {
2759 /* Error */
2760 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2761 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2762 pPrt->PAutoNegFail = SK_TRUE;
2763 return(SK_AND_DUP_CAP);
2764 }
2765
2766#ifdef TEST_ONLY
276701-Sep-2000 RA;:;:
2768 /* Check Master/Slave resolution */
2769 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2770 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2771 ("Master/Slave Fault Port %d\n", Port));
2772 pPrt->PAutoNegFail = SK_TRUE;
2773 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2774 return(SK_AND_OTHER);
2775 }
2776
2777 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2778 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
2779#endif /* 0 */
2780
2781 /* Check PAUSE mismatch ??? */
2782 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2783 if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
2784 /* Symmetric PAUSE */
2785 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2786 }
2787 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
2788 /* Enable PAUSE receive, disable PAUSE transmit */
2789 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2790 }
2791 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
2792 /* Disable PAUSE receive, enable PAUSE transmit */
2793 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2794 }
2795 else {
2796 /* PAUSE mismatch -> no PAUSE */
2797 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2798 }
2799 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2800
2801 return(SK_AND_OK);
2802} /* SkXmAutoNegDoneBcom */
2803#endif /* GENESIS */
2804
2805
2806#ifdef YUKON
2807/******************************************************************************
2808 *
2809 * SkGmAutoNegDoneMarv() - Auto-negotiation handling
2810 *
2811 * Description:
2812 * This function handles the auto-negotiation if the Done bit is set.
2813 *
2814 * Returns:
2815 * SK_AND_OK o.k.
2816 * SK_AND_DUP_CAP Duplex capability error happened
2817 * SK_AND_OTHER Other error happened
2818 */
2819static int SkGmAutoNegDoneMarv(
2820SK_AC *pAC, /* adapter context */
2821SK_IOC IoC, /* IO context */
2822int Port) /* Port Index (MAC_1 + n) */
2823{
2824 SK_GEPORT *pPrt;
2825 SK_U16 LPAb; /* Link Partner Ability */
2826 SK_U16 ResAb; /* Resolved Ability */
2827 SK_U16 AuxStat; /* Auxiliary Status */
2828
2829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2830 ("AutoNegDoneMarv, Port %d\n", Port));
2831 pPrt = &pAC->GIni.GP[Port];
2832
2833 /* Get PHY parameters */
2834 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
2835 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2836 ("Link P.Abil.=0x%04X\n", LPAb));
2837
2838 if ((LPAb & PHY_M_AN_RF) != 0) {
2839 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2840 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2841 pPrt->PAutoNegFail = SK_TRUE;
2842 return(SK_AND_OTHER);
2843 }
2844
2845 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
2846
2847 /* Check Master/Slave resolution */
2848 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2849 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2850 ("Master/Slave Fault Port %d\n", Port));
2851 pPrt->PAutoNegFail = SK_TRUE;
2852 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2853 return(SK_AND_OTHER);
2854 }
2855
2856 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2857 (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
2858
2859 /* Read PHY Specific Status */
2860 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
2861
2862 /* Check Speed & Duplex resolved */
2863 if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
2864 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2865 ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
2866 pPrt->PAutoNegFail = SK_TRUE;
2867 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
2868 return(SK_AND_DUP_CAP);
2869 }
2870
2871 if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
2872 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2873 }
2874 else {
2875 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2876 }
2877
2878 /* Check PAUSE mismatch ??? */
2879 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2880 if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
2881 /* Symmetric PAUSE */
2882 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2883 }
2884 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
2885 /* Enable PAUSE receive, disable PAUSE transmit */
2886 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2887 }
2888 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
2889 /* Disable PAUSE receive, enable PAUSE transmit */
2890 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2891 }
2892 else {
2893 /* PAUSE mismatch -> no PAUSE */
2894 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2895 }
2896
2897 /* set used link speed */
2898 switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
2899 case (unsigned)PHY_M_PS_SPEED_1000:
2900 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2901 break;
2902 case PHY_M_PS_SPEED_100:
2903 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
2904 break;
2905 default:
2906 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
2907 }
2908
2909 return(SK_AND_OK);
2910} /* SkGmAutoNegDoneMarv */
2911#endif /* YUKON */
2912
2913
2914#ifdef OTHER_PHY
2915/******************************************************************************
2916 *
2917 * SkXmAutoNegDoneLone() - Auto-negotiation handling
2918 *
2919 * Description:
2920 * This function handles the auto-negotiation if the Done bit is set.
2921 *
2922 * Returns:
2923 * SK_AND_OK o.k.
2924 * SK_AND_DUP_CAP Duplex capability error happened
2925 * SK_AND_OTHER Other error happened
2926 */
2927static int SkXmAutoNegDoneLone(
2928SK_AC *pAC, /* adapter context */
2929SK_IOC IoC, /* IO context */
2930int Port) /* Port Index (MAC_1 + n) */
2931{
2932 SK_GEPORT *pPrt;
2933 SK_U16 ResAb; /* Resolved Ability */
2934 SK_U16 LPAb; /* Link Partner Ability */
2935 SK_U16 QuickStat; /* Auxiliary Status */
2936
2937 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2938 ("AutoNegDoneLone, Port %d\n", Port));
2939 pPrt = &pAC->GIni.GP[Port];
2940
2941 /* Get PHY parameters */
2942 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
2943 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
2944 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
2945
2946 if ((LPAb & PHY_L_AN_RF) != 0) {
2947 /* Remote fault bit is set */
2948 /* Error */
2949 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2950 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2951 pPrt->PAutoNegFail = SK_TRUE;
2952 return(SK_AND_OTHER);
2953 }
2954
2955 /* Check Duplex mismatch */
2956 if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
2957 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2958 }
2959 else {
2960 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2961 }
2962
2963 /* Check Master/Slave resolution */
2964 if ((ResAb & PHY_L_1000S_MSF) != 0) {
2965 /* Error */
2966 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2967 ("Master/Slave Fault Port %d\n", Port));
2968 pPrt->PAutoNegFail = SK_TRUE;
2969 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2970 return(SK_AND_OTHER);
2971 }
2972 else if (ResAb & PHY_L_1000S_MSR) {
2973 pPrt->PMSStatus = SK_MS_STAT_MASTER;
2974 }
2975 else {
2976 pPrt->PMSStatus = SK_MS_STAT_SLAVE;
2977 }
2978
2979 /* Check PAUSE mismatch */
2980 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2981 /* we must manually resolve the abilities here */
2982 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2983
2984 switch (pPrt->PFlowCtrlMode) {
2985 case SK_FLOW_MODE_NONE:
2986 /* default */
2987 break;
2988 case SK_FLOW_MODE_LOC_SEND:
2989 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
2990 (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
2991 /* Disable PAUSE receive, enable PAUSE transmit */
2992 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2993 }
2994 break;
2995 case SK_FLOW_MODE_SYMMETRIC:
2996 if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
2997 /* Symmetric PAUSE */
2998 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2999 }
3000 break;
3001 case SK_FLOW_MODE_SYM_OR_REM:
3002 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
3003 PHY_L_QS_AS_PAUSE) {
3004 /* Enable PAUSE receive, disable PAUSE transmit */
3005 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3006 }
3007 else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
3008 /* Symmetric PAUSE */
3009 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3010 }
3011 break;
3012 default:
3013 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
3014 SKERR_HWI_E016MSG);
3015 }
3016
3017 return(SK_AND_OK);
3018} /* SkXmAutoNegDoneLone */
3019
3020
3021/******************************************************************************
3022 *
3023 * SkXmAutoNegDoneNat() - Auto-negotiation handling
3024 *
3025 * Description:
3026 * This function handles the auto-negotiation if the Done bit is set.
3027 *
3028 * Returns:
3029 * SK_AND_OK o.k.
3030 * SK_AND_DUP_CAP Duplex capability error happened
3031 * SK_AND_OTHER Other error happened
3032 */
3033static int SkXmAutoNegDoneNat(
3034SK_AC *pAC, /* adapter context */
3035SK_IOC IoC, /* IO context */
3036int Port) /* Port Index (MAC_1 + n) */
3037{
3038/* todo: National */
3039 return(SK_AND_OK);
3040} /* SkXmAutoNegDoneNat */
3041#endif /* OTHER_PHY */
3042
3043
3044/******************************************************************************
3045 *
3046 * SkMacAutoNegDone() - Auto-negotiation handling
3047 *
3048 * Description: calls the auto-negotiation done routines dep. on board type
3049 *
3050 * Returns:
3051 * SK_AND_OK o.k.
3052 * SK_AND_DUP_CAP Duplex capability error happened
3053 * SK_AND_OTHER Other error happened
3054 */
3055int SkMacAutoNegDone(
3056SK_AC *pAC, /* adapter context */
3057SK_IOC IoC, /* IO context */
3058int Port) /* Port Index (MAC_1 + n) */
3059{
3060 SK_GEPORT *pPrt;
3061 int Rtv;
3062
3063 Rtv = SK_AND_OK;
3064
3065 pPrt = &pAC->GIni.GP[Port];
3066
3067#ifdef GENESIS
3068 if (pAC->GIni.GIGenesis) {
3069
3070 switch (pPrt->PhyType) {
3071
3072 case SK_PHY_XMAC:
3073 Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
3074 break;
3075 case SK_PHY_BCOM:
3076 Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
3077 break;
3078#ifdef OTHER_PHY
3079 case SK_PHY_LONE:
3080 Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
3081 break;
3082 case SK_PHY_NAT:
3083 Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
3084 break;
3085#endif /* OTHER_PHY */
3086 default:
3087 return(SK_AND_OTHER);
3088 }
3089 }
3090#endif /* GENESIS */
3091
3092#ifdef YUKON
3093 if (pAC->GIni.GIYukon) {
3094
3095 Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
3096 }
3097#endif /* YUKON */
3098
3099 if (Rtv != SK_AND_OK) {
3100 return(Rtv);
3101 }
3102
3103 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3104 ("AutoNeg done Port %d\n", Port));
3105
3106 /* We checked everything and may now enable the link */
3107 pPrt->PAutoNegFail = SK_FALSE;
3108
3109 SkMacRxTxEnable(pAC, IoC, Port);
3110
3111 return(SK_AND_OK);
3112} /* SkMacAutoNegDone */
3113
3114
3115/******************************************************************************
3116 *
3117 * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
3118 *
3119 * Description: enables Rx/Tx dep. on board type
3120 *
3121 * Returns:
3122 * 0 o.k.
3123 * != 0 Error happened
3124 */
3125int SkMacRxTxEnable(
3126SK_AC *pAC, /* adapter context */
3127SK_IOC IoC, /* IO context */
3128int Port) /* Port Index (MAC_1 + n) */
3129{
3130 SK_GEPORT *pPrt;
3131 SK_U16 Reg; /* 16-bit register value */
3132 SK_U16 IntMask; /* MAC interrupt mask */
3133#ifdef GENESIS
3134 SK_U16 SWord;
3135#endif
3136
3137 pPrt = &pAC->GIni.GP[Port];
3138
3139 if (!pPrt->PHWLinkUp) {
3140 /* The Hardware link is NOT up */
3141 return(0);
3142 }
3143
3144 if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
3145 pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
3146 pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
3147 pPrt->PAutoNegFail) {
3148 /* Auto-negotiation is not done or failed */
3149 return(0);
3150 }
3151
3152#ifdef GENESIS
3153 if (pAC->GIni.GIGenesis) {
3154 /* set Duplex Mode and Pause Mode */
3155 SkXmInitDupMd(pAC, IoC, Port);
3156
3157 SkXmInitPauseMd(pAC, IoC, Port);
3158
3159 /*
3160 * Initialize the Interrupt Mask Register. Default IRQs are...
3161 * - Link Asynchronous Event
3162 * - Link Partner requests config
3163 * - Auto Negotiation Done
3164 * - Rx Counter Event Overflow
3165 * - Tx Counter Event Overflow
3166 * - Transmit FIFO Underrun
3167 */
3168 IntMask = XM_DEF_MSK;
3169
3170#ifdef DEBUG
3171 /* add IRQ for Receive FIFO Overflow */
3172 IntMask &= ~XM_IS_RXF_OV;
3173#endif /* DEBUG */
3174
3175 if (pPrt->PhyType != SK_PHY_XMAC) {
3176 /* disable GP0 interrupt bit */
3177 IntMask |= XM_IS_INP_ASS;
3178 }
3179 XM_OUT16(IoC, Port, XM_IMSK, IntMask);
3180
3181 /* get MMU Command Reg. */
3182 XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
3183
3184 if (pPrt->PhyType != SK_PHY_XMAC &&
3185 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3186 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
3187 /* set to Full Duplex */
3188 Reg |= XM_MMU_GMII_FD;
3189 }
3190
3191 switch (pPrt->PhyType) {
3192 case SK_PHY_BCOM:
3193 /*
3194 * Workaround BCOM Errata (#10523) for all BCom Phys
3195 * Enable Power Management after link up
3196 */
3197 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
3198 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3199 (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
3200 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
3201 (SK_U16)PHY_B_DEF_MSK);
3202 break;
3203#ifdef OTHER_PHY
3204 case SK_PHY_LONE:
3205 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
3206 break;
3207 case SK_PHY_NAT:
3208 /* todo National:
3209 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
3210 /* no interrupts possible from National ??? */
3211 break;
3212#endif /* OTHER_PHY */
3213 }
3214
3215 /* enable Rx/Tx */
3216 XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
3217 }
3218#endif /* GENESIS */
3219
3220#ifdef YUKON
3221 if (pAC->GIni.GIYukon) {
3222 /*
3223 * Initialize the Interrupt Mask Register. Default IRQs are...
3224 * - Rx Counter Event Overflow
3225 * - Tx Counter Event Overflow
3226 * - Transmit FIFO Underrun
3227 */
3228 IntMask = GMAC_DEF_MSK;
3229
3230#ifdef DEBUG
3231 /* add IRQ for Receive FIFO Overrun */
3232 IntMask |= GM_IS_RX_FF_OR;
3233#endif /* DEBUG */
3234
3235 SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
3236
3237 /* get General Purpose Control */
3238 GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
3239
3240 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3241 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
3242 /* set to Full Duplex */
3243 Reg |= GM_GPCR_DUP_FULL;
3244 }
3245
3246 /* enable Rx/Tx */
3247 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
3248 GM_GPCR_TX_ENA));
3249
3250#ifndef VCPU
3251 /* Enable all PHY interrupts */
3252 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
3253 (SK_U16)PHY_M_DEF_MSK);
3254#endif /* VCPU */
3255 }
3256#endif /* YUKON */
3257
3258 return(0);
3259
3260} /* SkMacRxTxEnable */
3261
3262
3263/******************************************************************************
3264 *
3265 * SkMacRxTxDisable() - Disable Receiver and Transmitter
3266 *
3267 * Description: disables Rx/Tx dep. on board type
3268 *
3269 * Returns: N/A
3270 */
3271void SkMacRxTxDisable(
3272SK_AC *pAC, /* Adapter Context */
3273SK_IOC IoC, /* IO context */
3274int Port) /* Port Index (MAC_1 + n) */
3275{
3276 SK_U16 Word;
3277
3278#ifdef GENESIS
3279 if (pAC->GIni.GIGenesis) {
3280
3281 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3282
3283 XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
3284
3285 /* dummy read to ensure writing */
3286 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3287 }
3288#endif /* GENESIS */
3289
3290#ifdef YUKON
3291 if (pAC->GIni.GIYukon) {
3292
3293 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3294
3295 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
3296 GM_GPCR_TX_ENA)));
3297
3298 /* dummy read to ensure writing */
3299 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3300 }
3301#endif /* YUKON */
3302
3303} /* SkMacRxTxDisable */
3304
3305
3306/******************************************************************************
3307 *
3308 * SkMacIrqDisable() - Disable IRQ from MAC
3309 *
3310 * Description: sets the IRQ-mask to disable IRQ dep. on board type
3311 *
3312 * Returns: N/A
3313 */
3314void SkMacIrqDisable(
3315SK_AC *pAC, /* Adapter Context */
3316SK_IOC IoC, /* IO context */
3317int Port) /* Port Index (MAC_1 + n) */
3318{
3319 SK_GEPORT *pPrt;
3320#ifdef GENESIS
3321 SK_U16 Word;
3322#endif
3323
3324 pPrt = &pAC->GIni.GP[Port];
3325
3326#ifdef GENESIS
3327 if (pAC->GIni.GIGenesis) {
3328
3329 /* disable all XMAC IRQs */
3330 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
3331
3332 /* Disable all PHY interrupts */
3333 switch (pPrt->PhyType) {
3334 case SK_PHY_BCOM:
3335 /* Make sure that PHY is initialized */
3336 if (pPrt->PState != SK_PRT_RESET) {
3337 /* NOT allowed if BCOM is in RESET state */
3338 /* Workaround BCOM Errata (#10523) all BCom */
3339 /* Disable Power Management if link is down */
3340 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
3341 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3342 (SK_U16)(Word | PHY_B_AC_DIS_PM));
3343 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
3344 }
3345 break;
3346#ifdef OTHER_PHY
3347 case SK_PHY_LONE:
3348 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
3349 break;
3350 case SK_PHY_NAT:
3351 /* todo: National
3352 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
3353 break;
3354#endif /* OTHER_PHY */
3355 }
3356 }
3357#endif /* GENESIS */
3358
3359#ifdef YUKON
3360 if (pAC->GIni.GIYukon) {
3361 /* disable all GMAC IRQs */
3362 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
3363
3364#ifndef VCPU
3365 /* Disable all PHY interrupts */
3366 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
3367#endif /* VCPU */
3368 }
3369#endif /* YUKON */
3370
3371} /* SkMacIrqDisable */
3372
3373
3374#ifdef SK_DIAG
3375/******************************************************************************
3376 *
3377 * SkXmSendCont() - Enable / Disable Send Continuous Mode
3378 *
3379 * Description: enable / disable Send Continuous Mode on XMAC
3380 *
3381 * Returns:
3382 * nothing
3383 */
3384void SkXmSendCont(
3385SK_AC *pAC, /* adapter context */
3386SK_IOC IoC, /* IO context */
3387int Port, /* Port Index (MAC_1 + n) */
3388SK_BOOL Enable) /* Enable / Disable */
3389{
3390 SK_U32 MdReg;
3391
3392 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3393
3394 if (Enable) {
3395 MdReg |= XM_MD_TX_CONT;
3396 }
3397 else {
3398 MdReg &= ~XM_MD_TX_CONT;
3399 }
3400 /* setup Mode Register */
3401 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3402
3403} /* SkXmSendCont */
3404
3405
3406/******************************************************************************
3407 *
3408 * SkMacTimeStamp() - Enable / Disable Time Stamp
3409 *
3410 * Description: enable / disable Time Stamp generation for Rx packets
3411 *
3412 * Returns:
3413 * nothing
3414 */
3415void SkMacTimeStamp(
3416SK_AC *pAC, /* adapter context */
3417SK_IOC IoC, /* IO context */
3418int Port, /* Port Index (MAC_1 + n) */
3419SK_BOOL Enable) /* Enable / Disable */
3420{
3421 SK_U32 MdReg;
3422 SK_U8 TimeCtrl;
3423
3424 if (pAC->GIni.GIGenesis) {
3425
3426 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3427
3428 if (Enable) {
3429 MdReg |= XM_MD_ATS;
3430 }
3431 else {
3432 MdReg &= ~XM_MD_ATS;
3433 }
3434 /* setup Mode Register */
3435 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3436 }
3437 else {
3438 if (Enable) {
3439 TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
3440 }
3441 else {
3442 TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
3443 }
3444 /* Start/Stop Time Stamp Timer */
3445 SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
3446 }
3447
3448} /* SkMacTimeStamp*/
3449
3450#else /* !SK_DIAG */
3451
3452#ifdef GENESIS
3453/******************************************************************************
3454 *
3455 * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
3456 *
3457 * This function analyses the Interrupt status word. If any of the
3458 * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
3459 * is set true.
3460 */
3461void SkXmAutoNegLipaXmac(
3462SK_AC *pAC, /* adapter context */
3463SK_IOC IoC, /* IO context */
3464int Port, /* Port Index (MAC_1 + n) */
3465SK_U16 IStatus) /* Interrupt Status word to analyse */
3466{
3467 SK_GEPORT *pPrt;
3468
3469 pPrt = &pAC->GIni.GP[Port];
3470
3471 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3472 (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
3473
3474 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3475 ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
3476 Port, IStatus));
3477 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3478 }
3479} /* SkXmAutoNegLipaXmac */
3480#endif /* GENESIS */
3481
3482
3483/******************************************************************************
3484 *
3485 * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
3486 *
3487 * This function analyses the PHY status word.
3488 * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
3489 * is set true.
3490 */
3491void SkMacAutoNegLipaPhy(
3492SK_AC *pAC, /* adapter context */
3493SK_IOC IoC, /* IO context */
3494int Port, /* Port Index (MAC_1 + n) */
3495SK_U16 PhyStat) /* PHY Status word to analyse */
3496{
3497 SK_GEPORT *pPrt;
3498
3499 pPrt = &pAC->GIni.GP[Port];
3500
3501 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3502 (PhyStat & PHY_ST_AN_OVER) != 0) {
3503
3504 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3505 ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
3506 Port, PhyStat));
3507 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3508 }
3509} /* SkMacAutoNegLipaPhy */
3510
3511
3512#ifdef GENESIS
3513/******************************************************************************
3514 *
3515 * SkXmIrq() - Interrupt Service Routine
3516 *
3517 * Description: services an Interrupt Request of the XMAC
3518 *
3519 * Note:
3520 * With an external PHY, some interrupt bits are not meaningfull any more:
3521 * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE
3522 * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
3523 * - Page Received (bit #9) XM_IS_RX_PAGE
3524 * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
3525 * - AutoNegDone (bit #7) XM_IS_AND
3526 * Also probably not valid any more is the GP0 input bit:
3527 * - GPRegisterBit0set XM_IS_INP_ASS
3528 *
3529 * Returns:
3530 * nothing
3531 */
3532static void SkXmIrq(
3533SK_AC *pAC, /* adapter context */
3534SK_IOC IoC, /* IO context */
3535int Port) /* Port Index (MAC_1 + n) */
3536{
3537 SK_GEPORT *pPrt;
3538 SK_EVPARA Para;
3539 SK_U16 IStatus; /* Interrupt status read from the XMAC */
3540 SK_U16 IStatus2;
3541#ifdef SK_SLIM
3542 SK_U64 OverflowStatus;
3543#endif
3544
3545 pPrt = &pAC->GIni.GP[Port];
3546
3547 XM_IN16(IoC, Port, XM_ISRC, &IStatus);
3548
3549 /* LinkPartner Auto-negable? */
3550 if (pPrt->PhyType == SK_PHY_XMAC) {
3551 SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
3552 }
3553 else {
3554 /* mask bits that are not used with ext. PHY */
3555 IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
3556 XM_IS_RX_PAGE | XM_IS_TX_PAGE |
3557 XM_IS_AND | XM_IS_INP_ASS);
3558 }
3559
3560 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3561 ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3562
3563 if (!pPrt->PHWLinkUp) {
3564 /* Spurious XMAC interrupt */
3565 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3566 ("SkXmIrq: spurious interrupt on Port %d\n", Port));
3567 return;
3568 }
3569
3570 if ((IStatus & XM_IS_INP_ASS) != 0) {
3571 /* Reread ISR Register if link is not in sync */
3572 XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
3573
3574 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3575 ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
3576 Port, IStatus, IStatus2));
3577 IStatus &= ~XM_IS_INP_ASS;
3578 IStatus |= IStatus2;
3579 }
3580
3581 if ((IStatus & XM_IS_LNK_AE) != 0) {
3582 /* not used, GP0 is used instead */
3583 }
3584
3585 if ((IStatus & XM_IS_TX_ABORT) != 0) {
3586 /* not used */
3587 }
3588
3589 if ((IStatus & XM_IS_FRC_INT) != 0) {
3590 /* not used, use ASIC IRQ instead if needed */
3591 }
3592
3593 if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
3594 SkHWLinkDown(pAC, IoC, Port);
3595
3596 /* Signal to RLMT */
3597 Para.Para32[0] = (SK_U32)Port;
3598 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
3599
3600 /* Start workaround Errata #2 timer */
3601 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
3602 SKGE_HWAC, SK_HWEV_WATIM, Para);
3603 }
3604
3605 if ((IStatus & XM_IS_RX_PAGE) != 0) {
3606 /* not used */
3607 }
3608
3609 if ((IStatus & XM_IS_TX_PAGE) != 0) {
3610 /* not used */
3611 }
3612
3613 if ((IStatus & XM_IS_AND) != 0) {
3614 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3615 ("SkXmIrq: AND on link that is up Port %d\n", Port));
3616 }
3617
3618 if ((IStatus & XM_IS_TSC_OV) != 0) {
3619 /* not used */
3620 }
3621
3622 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3623 if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
3624#ifdef SK_SLIM
3625 SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3626#else
3627 Para.Para32[0] = (SK_U32)Port;
3628 Para.Para32[1] = (SK_U32)IStatus;
3629 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3630#endif /* SK_SLIM */
3631 }
3632
3633 if ((IStatus & XM_IS_RXF_OV) != 0) {
3634 /* normal situation -> no effect */
3635#ifdef DEBUG
3636 pPrt->PRxOverCnt++;
3637#endif /* DEBUG */
3638 }
3639
3640 if ((IStatus & XM_IS_TXF_UR) != 0) {
3641 /* may NOT happen -> error log */
3642 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3643 }
3644
3645 if ((IStatus & XM_IS_TX_COMP) != 0) {
3646 /* not served here */
3647 }
3648
3649 if ((IStatus & XM_IS_RX_COMP) != 0) {
3650 /* not served here */
3651 }
3652} /* SkXmIrq */
3653#endif /* GENESIS */
3654
3655
3656#ifdef YUKON
3657/******************************************************************************
3658 *
3659 * SkGmIrq() - Interrupt Service Routine
3660 *
3661 * Description: services an Interrupt Request of the GMAC
3662 *
3663 * Note:
3664 *
3665 * Returns:
3666 * nothing
3667 */
3668static void SkGmIrq(
3669SK_AC *pAC, /* adapter context */
3670SK_IOC IoC, /* IO context */
3671int Port) /* Port Index (MAC_1 + n) */
3672{
3673 SK_GEPORT *pPrt;
3674 SK_U8 IStatus; /* Interrupt status */
3675#ifdef SK_SLIM
3676 SK_U64 OverflowStatus;
3677#else
3678 SK_EVPARA Para;
3679#endif
3680
3681 pPrt = &pAC->GIni.GP[Port];
3682
3683 SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
3684
3685#ifdef XXX
3686 /* LinkPartner Auto-negable? */
3687 SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
3688#endif /* XXX */
3689
3690 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3691 ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3692
3693 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3694 if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
3695 /* these IRQs will be cleared by reading GMACs register */
3696#ifdef SK_SLIM
3697 SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3698#else
3699 Para.Para32[0] = (SK_U32)Port;
3700 Para.Para32[1] = (SK_U32)IStatus;
3701 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3702#endif
3703 }
3704
3705 if (IStatus & GM_IS_RX_FF_OR) {
3706 /* clear GMAC Rx FIFO Overrun IRQ */
3707 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
3708#ifdef DEBUG
3709 pPrt->PRxOverCnt++;
3710#endif /* DEBUG */
3711 }
3712
3713 if (IStatus & GM_IS_TX_FF_UR) {
3714 /* clear GMAC Tx FIFO Underrun IRQ */
3715 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
3716 /* may NOT happen -> error log */
3717 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3718 }
3719
3720 if (IStatus & GM_IS_TX_COMPL) {
3721 /* not served here */
3722 }
3723
3724 if (IStatus & GM_IS_RX_COMPL) {
3725 /* not served here */
3726 }
3727} /* SkGmIrq */
3728#endif /* YUKON */
3729
3730
3731/******************************************************************************
3732 *
3733 * SkMacIrq() - Interrupt Service Routine for MAC
3734 *
3735 * Description: calls the Interrupt Service Routine dep. on board type
3736 *
3737 * Returns:
3738 * nothing
3739 */
3740void SkMacIrq(
3741SK_AC *pAC, /* adapter context */
3742SK_IOC IoC, /* IO context */
3743int Port) /* Port Index (MAC_1 + n) */
3744{
3745#ifdef GENESIS
3746 if (pAC->GIni.GIGenesis) {
3747 /* IRQ from XMAC */
3748 SkXmIrq(pAC, IoC, Port);
3749 }
3750#endif /* GENESIS */
3751
3752#ifdef YUKON
3753 if (pAC->GIni.GIYukon) {
3754 /* IRQ from GMAC */
3755 SkGmIrq(pAC, IoC, Port);
3756 }
3757#endif /* YUKON */
3758
3759} /* SkMacIrq */
3760
3761#endif /* !SK_DIAG */
3762
3763#ifdef GENESIS
3764/******************************************************************************
3765 *
3766 * SkXmUpdateStats() - Force the XMAC to output the current statistic
3767 *
3768 * Description:
3769 * The XMAC holds its statistic internally. To obtain the current
3770 * values a command must be sent so that the statistic data will
3771 * be written to a predefined memory area on the adapter.
3772 *
3773 * Returns:
3774 * 0: success
3775 * 1: something went wrong
3776 */
3777int SkXmUpdateStats(
3778SK_AC *pAC, /* adapter context */
3779SK_IOC IoC, /* IO context */
3780unsigned int Port) /* Port Index (MAC_1 + n) */
3781{
3782 SK_GEPORT *pPrt;
3783 SK_U16 StatReg;
3784 int WaitIndex;
3785
3786 pPrt = &pAC->GIni.GP[Port];
3787 WaitIndex = 0;
3788
3789 /* Send an update command to XMAC specified */
3790 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
3791
3792 /*
3793 * It is an auto-clearing register. If the command bits
3794 * went to zero again, the statistics are transferred.
3795 * Normally the command should be executed immediately.
3796 * But just to be sure we execute a loop.
3797 */
3798 do {
3799
3800 XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
3801
3802 if (++WaitIndex > 10) {
3803
3804 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
3805
3806 return(1);
3807 }
3808 } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
3809
3810 return(0);
3811} /* SkXmUpdateStats */
3812
3813
3814/******************************************************************************
3815 *
3816 * SkXmMacStatistic() - Get XMAC counter value
3817 *
3818 * Description:
3819 * Gets the 32bit counter value. Except for the octet counters
3820 * the lower 32bit are counted in hardware and the upper 32bit
3821 * must be counted in software by monitoring counter overflow interrupts.
3822 *
3823 * Returns:
3824 * 0: success
3825 * 1: something went wrong
3826 */
3827int SkXmMacStatistic(
3828SK_AC *pAC, /* adapter context */
3829SK_IOC IoC, /* IO context */
3830unsigned int Port, /* Port Index (MAC_1 + n) */
3831SK_U16 StatAddr, /* MIB counter base address */
3832SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3833{
3834 if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
3835
3836 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3837
3838 return(1);
3839 }
3840
3841 XM_IN32(IoC, Port, StatAddr, pVal);
3842
3843 return(0);
3844} /* SkXmMacStatistic */
3845
3846
3847/******************************************************************************
3848 *
3849 * SkXmResetCounter() - Clear MAC statistic counter
3850 *
3851 * Description:
3852 * Force the XMAC to clear its statistic counter.
3853 *
3854 * Returns:
3855 * 0: success
3856 * 1: something went wrong
3857 */
3858int SkXmResetCounter(
3859SK_AC *pAC, /* adapter context */
3860SK_IOC IoC, /* IO context */
3861unsigned int Port) /* Port Index (MAC_1 + n) */
3862{
3863 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3864 /* Clear two times according to Errata #3 */
3865 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3866
3867 return(0);
3868} /* SkXmResetCounter */
3869
3870
3871/******************************************************************************
3872 *
3873 * SkXmOverflowStatus() - Gets the status of counter overflow interrupt
3874 *
3875 * Description:
3876 * Checks the source causing an counter overflow interrupt. On success the
3877 * resulting counter overflow status is written to <pStatus>, whereas the
3878 * upper dword stores the XMAC ReceiveCounterEvent register and the lower
3879 * dword the XMAC TransmitCounterEvent register.
3880 *
3881 * Note:
3882 * For XMAC the interrupt source is a self-clearing register, so the source
3883 * must be checked only once. SIRQ module does another check to be sure
3884 * that no interrupt get lost during process time.
3885 *
3886 * Returns:
3887 * 0: success
3888 * 1: something went wrong
3889 */
3890int SkXmOverflowStatus(
3891SK_AC *pAC, /* adapter context */
3892SK_IOC IoC, /* IO context */
3893unsigned int Port, /* Port Index (MAC_1 + n) */
3894SK_U16 IStatus, /* Interupt Status from MAC */
3895SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
3896{
3897 SK_U64 Status; /* Overflow status */
3898 SK_U32 RegVal;
3899
3900 Status = 0;
3901
3902 if ((IStatus & XM_IS_RXC_OV) != 0) {
3903
3904 XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
3905 Status |= (SK_U64)RegVal << 32;
3906 }
3907
3908 if ((IStatus & XM_IS_TXC_OV) != 0) {
3909
3910 XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
3911 Status |= (SK_U64)RegVal;
3912 }
3913
3914 *pStatus = Status;
3915
3916 return(0);
3917} /* SkXmOverflowStatus */
3918#endif /* GENESIS */
3919
3920
3921#ifdef YUKON
3922/******************************************************************************
3923 *
3924 * SkGmUpdateStats() - Force the GMAC to output the current statistic
3925 *
3926 * Description:
3927 * Empty function for GMAC. Statistic data is accessible in direct way.
3928 *
3929 * Returns:
3930 * 0: success
3931 * 1: something went wrong
3932 */
3933int SkGmUpdateStats(
3934SK_AC *pAC, /* adapter context */
3935SK_IOC IoC, /* IO context */
3936unsigned int Port) /* Port Index (MAC_1 + n) */
3937{
3938 return(0);
3939}
3940
3941
3942/******************************************************************************
3943 *
3944 * SkGmMacStatistic() - Get GMAC counter value
3945 *
3946 * Description:
3947 * Gets the 32bit counter value. Except for the octet counters
3948 * the lower 32bit are counted in hardware and the upper 32bit
3949 * must be counted in software by monitoring counter overflow interrupts.
3950 *
3951 * Returns:
3952 * 0: success
3953 * 1: something went wrong
3954 */
3955int SkGmMacStatistic(
3956SK_AC *pAC, /* adapter context */
3957SK_IOC IoC, /* IO context */
3958unsigned int Port, /* Port Index (MAC_1 + n) */
3959SK_U16 StatAddr, /* MIB counter base address */
3960SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3961{
3962
3963 if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
3964
3965 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3966
3967 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3968 ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
3969 return(1);
3970 }
3971
3972 GM_IN32(IoC, Port, StatAddr, pVal);
3973
3974 return(0);
3975} /* SkGmMacStatistic */
3976
3977
3978/******************************************************************************
3979 *
3980 * SkGmResetCounter() - Clear MAC statistic counter
3981 *
3982 * Description:
3983 * Force GMAC to clear its statistic counter.
3984 *
3985 * Returns:
3986 * 0: success
3987 * 1: something went wrong
3988 */
3989int SkGmResetCounter(
3990SK_AC *pAC, /* adapter context */
3991SK_IOC IoC, /* IO context */
3992unsigned int Port) /* Port Index (MAC_1 + n) */
3993{
3994 SK_U16 Reg; /* Phy Address Register */
3995 SK_U16 Word;
3996 int i;
3997
3998 GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
3999
4000 /* set MIB Clear Counter Mode */
4001 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
4002
4003 /* read all MIB Counters with Clear Mode set */
4004 for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
4005 /* the reset is performed only when the lower 16 bits are read */
4006 GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
4007 }
4008
4009 /* clear MIB Clear Counter Mode */
4010 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
4011
4012 return(0);
4013} /* SkGmResetCounter */
4014
4015
4016/******************************************************************************
4017 *
4018 * SkGmOverflowStatus() - Gets the status of counter overflow interrupt
4019 *
4020 * Description:
4021 * Checks the source causing an counter overflow interrupt. On success the
4022 * resulting counter overflow status is written to <pStatus>, whereas the
4023 * the following bit coding is used:
4024 * 63:56 - unused
4025 * 55:48 - TxRx interrupt register bit7:0
4026 * 32:47 - Rx interrupt register
4027 * 31:24 - unused
4028 * 23:16 - TxRx interrupt register bit15:8
4029 * 15:0 - Tx interrupt register
4030 *
4031 * Returns:
4032 * 0: success
4033 * 1: something went wrong
4034 */
4035int SkGmOverflowStatus(
4036SK_AC *pAC, /* adapter context */
4037SK_IOC IoC, /* IO context */
4038unsigned int Port, /* Port Index (MAC_1 + n) */
4039SK_U16 IStatus, /* Interupt Status from MAC */
4040SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
4041{
4042 SK_U64 Status; /* Overflow status */
4043 SK_U16 RegVal;
4044
4045 Status = 0;
4046
4047 if ((IStatus & GM_IS_RX_CO_OV) != 0) {
4048 /* this register is self-clearing after read */
4049 GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
4050 Status |= (SK_U64)RegVal << 32;
4051 }
4052
4053 if ((IStatus & GM_IS_TX_CO_OV) != 0) {
4054 /* this register is self-clearing after read */
4055 GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
4056 Status |= (SK_U64)RegVal;
4057 }
4058
4059 /* this register is self-clearing after read */
4060 GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
4061 /* Rx overflow interrupt register bits (LoByte)*/
4062 Status |= (SK_U64)((SK_U8)RegVal) << 48;
4063 /* Tx overflow interrupt register bits (HiByte)*/
4064 Status |= (SK_U64)(RegVal >> 8) << 16;
4065
4066 *pStatus = Status;
4067
4068 return(0);
4069} /* SkGmOverflowStatus */
4070
4071
4072#ifndef SK_SLIM
4073/******************************************************************************
4074 *
4075 * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
4076 *
4077 * Description:
4078 * starts the cable diagnostic test if 'StartTest' is true
4079 * gets the results if 'StartTest' is true
4080 *
4081 * NOTE: this test is meaningful only when link is down
4082 *
4083 * Returns:
4084 * 0: success
4085 * 1: no YUKON copper
4086 * 2: test in progress
4087 */
4088int SkGmCableDiagStatus(
4089SK_AC *pAC, /* adapter context */
4090SK_IOC IoC, /* IO context */
4091int Port, /* Port Index (MAC_1 + n) */
4092SK_BOOL StartTest) /* flag for start / get result */
4093{
4094 int i;
4095 SK_U16 RegVal;
4096 SK_GEPORT *pPrt;
4097
4098 pPrt = &pAC->GIni.GP[Port];
4099
4100 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
4101
4102 return(1);
4103 }
4104
4105 if (StartTest) {
4106 /* only start the cable test */
4107 if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
4108 /* apply TDR workaround from Marvell */
4109 SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
4110
4111 SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
4112 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
4113 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
4114 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
4115 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
4116 }
4117
4118 /* set address to 0 for MDI[0] */
4119 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
4120
4121 /* Read Cable Diagnostic Reg */
4122 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4123
4124 /* start Cable Diagnostic Test */
4125 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
4126 (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
4127
4128 return(0);
4129 }
4130
4131 /* Read Cable Diagnostic Reg */
4132 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4133
4134 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
4135 ("PHY Cable Diag.=0x%04X\n", RegVal));
4136
4137 if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
4138 /* test is running */
4139 return(2);
4140 }
4141
4142 /* get the test results */
4143 for (i = 0; i < 4; i++) {
4144 /* set address to i for MDI[i] */
4145 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
4146
4147 /* get Cable Diagnostic values */
4148 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4149
4150 pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
4151
4152 pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
4153 }
4154
4155 return(0);
4156} /* SkGmCableDiagStatus */
4157#endif /* !SK_SLIM */
4158#endif /* YUKON */
4159
4160/* End of file */