x86: arch/x86/mm/init_32.c cleanup
[wrt350n-kernel.git] / drivers / net / sk98lin / skgeinit.c
blob67f1d6a5c15d341f5bcd9c7261a76f74b2eea9ee
1 /******************************************************************************
3 * Name: skgeinit.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.97 $
6 * Date: $Date: 2003/10/02 16:45:31 $
7 * Purpose: Contains functions to initialize the adapter
9 ******************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
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.
21 * The information in this file is provided "AS IS" without warranty.
23 ******************************************************************************/
25 #include "h/skdrv1st.h"
26 #include "h/skdrv2nd.h"
28 /* global variables ***********************************************************/
30 /* local variables ************************************************************/
32 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
33 static const char SysKonnectFileId[] =
34 "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
35 #endif
37 struct s_QOffTab {
38 int RxQOff; /* Receive Queue Address Offset */
39 int XsQOff; /* Sync Tx Queue Address Offset */
40 int XaQOff; /* Async Tx Queue Address Offset */
42 static struct s_QOffTab QOffTab[] = {
43 {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
46 struct s_Config {
47 char ScanString[8];
48 SK_U32 Value;
51 static struct s_Config OemConfig = {
52 {'O','E','M','_','C','o','n','f'},
53 #ifdef SK_OEM_CONFIG
54 OEM_CONFIG_VALUE,
55 #else
57 #endif
60 /******************************************************************************
62 * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
64 * Description:
65 * Enable or disable the descriptor polling of the transmit descriptor
66 * ring(s) (TxD) for port 'Port'.
67 * The new configuration is *not* saved over any SkGeStopPort() and
68 * SkGeInitPort() calls.
70 * Returns:
71 * nothing
73 void SkGePollTxD(
74 SK_AC *pAC, /* adapter context */
75 SK_IOC IoC, /* IO context */
76 int Port, /* Port Index (MAC_1 + n) */
77 SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
79 SK_GEPORT *pPrt;
80 SK_U32 DWord;
82 pPrt = &pAC->GIni.GP[Port];
84 DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
86 if (pPrt->PXSQSize != 0) {
87 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
90 if (pPrt->PXAQSize != 0) {
91 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
93 } /* SkGePollTxD */
96 /******************************************************************************
98 * SkGeYellowLED() - Switch the yellow LED on or off.
100 * Description:
101 * Switch the yellow LED on or off.
103 * Note:
104 * This function may be called any time after SkGeInit(Level 1).
106 * Returns:
107 * nothing
109 void SkGeYellowLED(
110 SK_AC *pAC, /* adapter context */
111 SK_IOC IoC, /* IO context */
112 int State) /* yellow LED state, 0 = OFF, 0 != ON */
114 if (State == 0) {
115 /* Switch yellow LED OFF */
116 SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
118 else {
119 /* Switch yellow LED ON */
120 SK_OUT8(IoC, B0_LED, LED_STAT_ON);
122 } /* SkGeYellowLED */
125 #if (!defined(SK_SLIM) || defined(GENESIS))
126 /******************************************************************************
128 * SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
130 * Description:
131 * The Rx or Tx LED which is specified by 'Led' will be
132 * enabled, disabled or switched on in test mode.
134 * Note:
135 * 'Led' must contain the address offset of the LEDs INI register.
137 * Usage:
138 * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
140 * Returns:
141 * nothing
143 void SkGeXmitLED(
144 SK_AC *pAC, /* adapter context */
145 SK_IOC IoC, /* IO context */
146 int Led, /* offset to the LED Init Value register */
147 int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
149 SK_U32 LedIni;
151 switch (Mode) {
152 case SK_LED_ENA:
153 LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
154 SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
155 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
156 break;
157 case SK_LED_TST:
158 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
159 SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
160 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
161 break;
162 case SK_LED_DIS:
163 default:
165 * Do NOT stop the LED Timer here. The LED might be
166 * in on state. But it needs to go off.
168 SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
169 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
170 break;
174 * 1000BT: The Transmit LED is driven by the PHY.
175 * But the default LED configuration is used for
176 * Level One and Broadcom PHYs.
177 * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
178 * (In this case it has to be added here. But we will see. XXX)
180 } /* SkGeXmitLED */
181 #endif /* !SK_SLIM || GENESIS */
184 /******************************************************************************
186 * DoCalcAddr() - Calculates the start and the end address of a queue.
188 * Description:
189 * This function calculates the start and the end address of a queue.
190 * Afterwards the 'StartVal' is incremented to the next start position.
191 * If the port is already initialized the calculated values
192 * will be checked against the configured values and an
193 * error will be returned, if they are not equal.
194 * If the port is not initialized the values will be written to
195 * *StartAdr and *EndAddr.
197 * Returns:
198 * 0: success
199 * 1: configuration error
201 static int DoCalcAddr(
202 SK_AC *pAC, /* adapter context */
203 SK_GEPORT SK_FAR *pPrt, /* port index */
204 int QuSize, /* size of the queue to configure in kB */
205 SK_U32 SK_FAR *StartVal, /* start value for address calculation */
206 SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */
207 SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */
209 SK_U32 EndVal;
210 SK_U32 NextStart;
211 int Rtv;
213 Rtv = 0;
214 if (QuSize == 0) {
215 EndVal = *StartVal;
216 NextStart = EndVal;
218 else {
219 EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
220 NextStart = EndVal + 1;
223 if (pPrt->PState >= SK_PRT_INIT) {
224 if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
225 Rtv = 1;
228 else {
229 *QuStartAddr = *StartVal;
230 *QuEndAddr = EndVal;
233 *StartVal = NextStart;
234 return(Rtv);
235 } /* DoCalcAddr */
237 /******************************************************************************
239 * SkGeInitAssignRamToQueues() - allocate default queue sizes
241 * Description:
242 * This function assigns the memory to the different queues and ports.
243 * When DualNet is set to SK_TRUE all ports get the same amount of memory.
244 * Otherwise the first port gets most of the memory and all the
245 * other ports just the required minimum.
246 * This function can only be called when pAC->GIni.GIRamSize and
247 * pAC->GIni.GIMacsFound have been initialized, usually this happens
248 * at init level 1
250 * Returns:
251 * 0 - ok
252 * 1 - invalid input values
253 * 2 - not enough memory
256 int SkGeInitAssignRamToQueues(
257 SK_AC *pAC, /* Adapter context */
258 int ActivePort, /* Active Port in RLMT mode */
259 SK_BOOL DualNet) /* adapter context */
261 int i;
262 int UsedKilobytes; /* memory already assigned */
263 int ActivePortKilobytes; /* memory available for active port */
264 SK_GEPORT *pGePort;
266 UsedKilobytes = 0;
268 if (ActivePort >= pAC->GIni.GIMacsFound) {
269 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
270 ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
271 ActivePort));
272 return(1);
274 if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
275 ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
276 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
277 ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
278 pAC->GIni.GIRamSize));
279 return(2);
282 if (DualNet) {
283 /* every port gets the same amount of memory */
284 ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
285 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
287 pGePort = &pAC->GIni.GP[i];
289 /* take away the minimum memory for active queues */
290 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
292 /* receive queue gets the minimum + 80% of the rest */
293 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
294 ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
295 + SK_MIN_RXQ_SIZE;
297 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
299 /* synchronous transmit queue */
300 pGePort->PXSQSize = 0;
302 /* asynchronous transmit queue */
303 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
304 SK_MIN_TXQ_SIZE);
307 else {
308 /* Rlmt Mode or single link adapter */
310 /* Set standby queue size defaults for all standby ports */
311 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
313 if (i != ActivePort) {
314 pGePort = &pAC->GIni.GP[i];
316 pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
317 pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
318 pGePort->PXSQSize = 0;
320 /* Count used RAM */
321 UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
324 /* what's left? */
325 ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
327 /* assign it to the active port */
328 /* first take away the minimum memory */
329 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
330 pGePort = &pAC->GIni.GP[ActivePort];
332 /* receive queue get's the minimum + 80% of the rest */
333 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
334 (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
336 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
338 /* synchronous transmit queue */
339 pGePort->PXSQSize = 0;
341 /* asynchronous transmit queue */
342 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
343 SK_MIN_TXQ_SIZE;
345 #ifdef VCPU
346 VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
347 pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
348 #endif /* VCPU */
350 return(0);
351 } /* SkGeInitAssignRamToQueues */
353 /******************************************************************************
355 * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
357 * Description:
358 * This function verifies the Queue Size Configuration specified
359 * in the variables PRxQSize, PXSQSize, and PXAQSize of all
360 * used ports.
361 * This requirements must be fullfilled to have a valid configuration:
362 * - The size of all queues must not exceed GIRamSize.
363 * - The queue sizes must be specified in units of 8 kB.
364 * - The size of Rx queues of available ports must not be
365 * smaller than 16 kB.
366 * - The size of at least one Tx queue (synch. or asynch.)
367 * of available ports must not be smaller than 16 kB
368 * when Jumbo Frames are used.
369 * - The RAM start and end addresses must not be changed
370 * for ports which are already initialized.
371 * Furthermore SkGeCheckQSize() defines the Start and End Addresses
372 * of all ports and stores them into the HWAC port structure.
374 * Returns:
375 * 0: Queue Size Configuration valid
376 * 1: Queue Size Configuration invalid
378 static int SkGeCheckQSize(
379 SK_AC *pAC, /* adapter context */
380 int Port) /* port index */
382 SK_GEPORT *pPrt;
383 int i;
384 int Rtv;
385 int Rtv2;
386 SK_U32 StartAddr;
387 #ifndef SK_SLIM
388 int UsedMem; /* total memory used (max. found ports) */
389 #endif
391 Rtv = 0;
393 #ifndef SK_SLIM
395 UsedMem = 0;
396 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
397 pPrt = &pAC->GIni.GP[i];
399 if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
400 (pPrt->PXSQSize & QZ_UNITS) != 0 ||
401 (pPrt->PXAQSize & QZ_UNITS) != 0) {
403 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
404 return(1);
407 if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
408 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
409 return(1);
413 * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
414 * if Jumbo Frames are used, this size has to be >= 16 kB.
416 if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
417 (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
418 ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
419 (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
420 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
421 return(1);
424 UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
427 if (UsedMem > pAC->GIni.GIRamSize) {
428 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
429 return(1);
431 #endif /* !SK_SLIM */
433 /* Now start address calculation */
434 StartAddr = pAC->GIni.GIRamOffs;
435 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
436 pPrt = &pAC->GIni.GP[i];
438 /* Calculate/Check values for the receive queue */
439 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
440 &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
441 Rtv |= Rtv2;
443 /* Calculate/Check values for the synchronous Tx queue */
444 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
445 &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
446 Rtv |= Rtv2;
448 /* Calculate/Check values for the asynchronous Tx queue */
449 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
450 &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
451 Rtv |= Rtv2;
453 if (Rtv) {
454 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
455 return(1);
459 return(0);
460 } /* SkGeCheckQSize */
463 #ifdef GENESIS
464 /******************************************************************************
466 * SkGeInitMacArb() - Initialize the MAC Arbiter
468 * Description:
469 * This function initializes the MAC Arbiter.
470 * It must not be called if there is still an
471 * initialized or active port.
473 * Returns:
474 * nothing
476 static void SkGeInitMacArb(
477 SK_AC *pAC, /* adapter context */
478 SK_IOC IoC) /* IO context */
480 /* release local reset */
481 SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
483 /* configure timeout values */
484 SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
485 SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
486 SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
487 SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
489 SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
490 SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
491 SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
492 SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
494 /* recovery values are needed for XMAC II Rev. B2 only */
495 /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
498 * There is no start or enable button to push, therefore
499 * the MAC arbiter is configured and enabled now.
501 } /* SkGeInitMacArb */
504 /******************************************************************************
506 * SkGeInitPktArb() - Initialize the Packet Arbiter
508 * Description:
509 * This function initializes the Packet Arbiter.
510 * It must not be called if there is still an
511 * initialized or active port.
513 * Returns:
514 * nothing
516 static void SkGeInitPktArb(
517 SK_AC *pAC, /* adapter context */
518 SK_IOC IoC) /* IO context */
520 /* release local reset */
521 SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
523 /* configure timeout values */
524 SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
525 SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
526 SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
527 SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
530 * enable timeout timers if jumbo frames not used
531 * NOTE: the packet arbiter timeout interrupt is needed for
532 * half duplex hangup workaround
534 if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
535 if (pAC->GIni.GIMacsFound == 1) {
536 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
538 else {
539 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
542 } /* SkGeInitPktArb */
543 #endif /* GENESIS */
546 /******************************************************************************
548 * SkGeInitMacFifo() - Initialize the MAC FIFOs
550 * Description:
551 * Initialize all MAC FIFOs of the specified port
553 * Returns:
554 * nothing
556 static void SkGeInitMacFifo(
557 SK_AC *pAC, /* adapter context */
558 SK_IOC IoC, /* IO context */
559 int Port) /* Port Index (MAC_1 + n) */
561 SK_U16 Word;
562 #ifdef VCPU
563 SK_U32 DWord;
564 #endif /* VCPU */
566 * For each FIFO:
567 * - release local reset
568 * - use default value for MAC FIFO size
569 * - setup defaults for the control register
570 * - enable the FIFO
573 #ifdef GENESIS
574 if (pAC->GIni.GIGenesis) {
575 /* Configure Rx MAC FIFO */
576 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
577 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
578 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
580 /* Configure Tx MAC FIFO */
581 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
582 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
583 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
585 /* Enable frame flushing if jumbo frames used */
586 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
587 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
590 #endif /* GENESIS */
592 #ifdef YUKON
593 if (pAC->GIni.GIYukon) {
594 /* set Rx GMAC FIFO Flush Mask */
595 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
597 Word = (SK_U16)GMF_RX_CTRL_DEF;
599 /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
600 if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
602 Word &= ~GMF_RX_F_FL_ON;
605 /* Configure Rx MAC FIFO */
606 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
607 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
609 /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
610 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
612 /* Configure Tx MAC FIFO */
613 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
614 SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
616 #ifdef VCPU
617 SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
618 SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
619 #endif /* VCPU */
621 /* set Tx GMAC FIFO Almost Empty Threshold */
622 /* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
624 #endif /* YUKON */
626 } /* SkGeInitMacFifo */
628 #ifdef SK_LNK_SYNC_CNT
629 /******************************************************************************
631 * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
633 * Description:
634 * This function starts the Link Sync Counter of the specified
635 * port and enables the generation of an Link Sync IRQ.
636 * The Link Sync Counter may be used to detect an active link,
637 * if autonegotiation is not used.
639 * Note:
640 * o To ensure receiving the Link Sync Event the LinkSyncCounter
641 * should be initialized BEFORE clearing the XMAC's reset!
642 * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
643 * function.
645 * Returns:
646 * nothing
648 void SkGeLoadLnkSyncCnt(
649 SK_AC *pAC, /* adapter context */
650 SK_IOC IoC, /* IO context */
651 int Port, /* Port Index (MAC_1 + n) */
652 SK_U32 CntVal) /* Counter value */
654 SK_U32 OrgIMsk;
655 SK_U32 NewIMsk;
656 SK_U32 ISrc;
657 SK_BOOL IrqPend;
659 /* stop counter */
660 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
663 * ASIC problem:
664 * Each time starting the Link Sync Counter an IRQ is generated
665 * by the adapter. See problem report entry from 21.07.98
667 * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ
668 * if no IRQ is already pending.
670 IrqPend = SK_FALSE;
671 SK_IN32(IoC, B0_ISRC, &ISrc);
672 SK_IN32(IoC, B0_IMSK, &OrgIMsk);
673 if (Port == MAC_1) {
674 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
675 if ((ISrc & IS_LNK_SYNC_M1) != 0) {
676 IrqPend = SK_TRUE;
679 else {
680 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
681 if ((ISrc & IS_LNK_SYNC_M2) != 0) {
682 IrqPend = SK_TRUE;
685 if (!IrqPend) {
686 SK_OUT32(IoC, B0_IMSK, NewIMsk);
689 /* load counter */
690 SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
692 /* start counter */
693 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
695 if (!IrqPend) {
696 /* clear the unexpected IRQ, and restore the interrupt mask */
697 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
698 SK_OUT32(IoC, B0_IMSK, OrgIMsk);
700 } /* SkGeLoadLnkSyncCnt*/
701 #endif /* SK_LNK_SYNC_CNT */
703 #if defined(SK_DIAG) || defined(SK_CFG_SYNC)
704 /******************************************************************************
706 * SkGeCfgSync() - Configure synchronous bandwidth for this port.
708 * Description:
709 * This function may be used to configure synchronous bandwidth
710 * to the specified port. This may be done any time after
711 * initializing the port. The configuration values are NOT saved
712 * in the HWAC port structure and will be overwritten any
713 * time when stopping and starting the port.
714 * Any values for the synchronous configuration will be ignored
715 * if the size of the synchronous queue is zero!
717 * The default configuration for the synchronous service is
718 * TXA_ENA_FSYNC. This means if the size of
719 * the synchronous queue is unequal zero but no specific
720 * synchronous bandwidth is configured, the synchronous queue
721 * will always have the 'unlimited' transmit priority!
723 * This mode will be restored if the synchronous bandwidth is
724 * deallocated ('IntTime' = 0 and 'LimCount' = 0).
726 * Returns:
727 * 0: success
728 * 1: parameter configuration error
729 * 2: try to configure quality of service although no
730 * synchronous queue is configured
732 int SkGeCfgSync(
733 SK_AC *pAC, /* adapter context */
734 SK_IOC IoC, /* IO context */
735 int Port, /* Port Index (MAC_1 + n) */
736 SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
737 SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
738 int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
740 int Rtv;
742 Rtv = 0;
744 /* check the parameters */
745 if (LimCount > IntTime ||
746 (LimCount == 0 && IntTime != 0) ||
747 (LimCount != 0 && IntTime == 0)) {
749 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
750 return(1);
753 if (pAC->GIni.GP[Port].PXSQSize == 0) {
754 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
755 return(2);
758 /* calculate register values */
759 IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
760 LimCount = LimCount / 8;
762 if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
763 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
764 return(1);
768 * - Enable 'Force Sync' to ensure the synchronous queue
769 * has the priority while configuring the new values.
770 * - Also 'disable alloc' to ensure the settings complies
771 * to the SyncMode parameter.
772 * - Disable 'Rate Control' to configure the new values.
773 * - write IntTime and LimCount
774 * - start 'Rate Control' and disable 'Force Sync'
775 * if Interval Timer or Limit Counter not zero.
777 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
778 TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
780 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
781 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
783 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
784 (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
786 if (IntTime != 0 || LimCount != 0) {
787 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
790 return(0);
791 } /* SkGeCfgSync */
792 #endif /* SK_DIAG || SK_CFG_SYNC*/
795 /******************************************************************************
797 * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
799 * Desccription:
800 * If the queue is used, enable and initialize it.
801 * Make sure the queue is still reset, if it is not used.
803 * Returns:
804 * nothing
806 static void DoInitRamQueue(
807 SK_AC *pAC, /* adapter context */
808 SK_IOC IoC, /* IO context */
809 int QuIoOffs, /* Queue IO Address Offset */
810 SK_U32 QuStartAddr, /* Queue Start Address */
811 SK_U32 QuEndAddr, /* Queue End Address */
812 int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
814 SK_U32 RxUpThresVal;
815 SK_U32 RxLoThresVal;
817 if (QuStartAddr != QuEndAddr) {
818 /* calculate thresholds, assume we have a big Rx queue */
819 RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
820 RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
822 /* build HW address format */
823 QuStartAddr = QuStartAddr / 8;
824 QuEndAddr = QuEndAddr / 8;
826 /* release local reset */
827 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
829 /* configure addresses */
830 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
831 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
832 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
833 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
835 switch (QuType) {
836 case SK_RX_SRAM_Q:
837 /* configure threshold for small Rx Queue */
838 RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
840 /* continue with SK_RX_BRAM_Q */
841 case SK_RX_BRAM_Q:
842 /* write threshold for Rx Queue */
844 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
845 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
847 /* the high priority threshold not used */
848 break;
849 case SK_TX_RAM_Q:
851 * Do NOT use Store & Forward under normal operation due to
852 * performance optimization (GENESIS only).
853 * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
854 * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
855 * we NEED Store & Forward of the RAM buffer.
857 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
858 pAC->GIni.GIYukon) {
859 /* enable Store & Forward Mode for the Tx Side */
860 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
862 break;
865 /* set queue operational */
866 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
868 else {
869 /* ensure the queue is still disabled */
870 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
872 } /* DoInitRamQueue */
875 /******************************************************************************
877 * SkGeInitRamBufs() - Initialize the RAM Buffer Queues
879 * Description:
880 * Initialize all RAM Buffer Queues of the specified port
882 * Returns:
883 * nothing
885 static void SkGeInitRamBufs(
886 SK_AC *pAC, /* adapter context */
887 SK_IOC IoC, /* IO context */
888 int Port) /* Port Index (MAC_1 + n) */
890 SK_GEPORT *pPrt;
891 int RxQType;
893 pPrt = &pAC->GIni.GP[Port];
895 if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
896 RxQType = SK_RX_SRAM_Q; /* small Rx Queue */
898 else {
899 RxQType = SK_RX_BRAM_Q; /* big Rx Queue */
902 DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
903 pPrt->PRxQRamEnd, RxQType);
905 DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
906 pPrt->PXsQRamEnd, SK_TX_RAM_Q);
908 DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
909 pPrt->PXaQRamEnd, SK_TX_RAM_Q);
911 } /* SkGeInitRamBufs */
914 /******************************************************************************
916 * SkGeInitRamIface() - Initialize the RAM Interface
918 * Description:
919 * This function initializes the Adapters RAM Interface.
921 * Note:
922 * This function is used in the diagnostics.
924 * Returns:
925 * nothing
927 static void SkGeInitRamIface(
928 SK_AC *pAC, /* adapter context */
929 SK_IOC IoC) /* IO context */
931 /* release local reset */
932 SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
934 /* configure timeout values */
935 SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
936 SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
937 SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
938 SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
939 SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
940 SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
941 SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
942 SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
943 SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
944 SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
945 SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
946 SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
948 } /* SkGeInitRamIface */
951 /******************************************************************************
953 * SkGeInitBmu() - Initialize the BMU state machines
955 * Description:
956 * Initialize all BMU state machines of the specified port
958 * Returns:
959 * nothing
961 static void SkGeInitBmu(
962 SK_AC *pAC, /* adapter context */
963 SK_IOC IoC, /* IO context */
964 int Port) /* Port Index (MAC_1 + n) */
966 SK_GEPORT *pPrt;
967 SK_U32 RxWm;
968 SK_U32 TxWm;
970 pPrt = &pAC->GIni.GP[Port];
972 RxWm = SK_BMU_RX_WM;
973 TxWm = SK_BMU_TX_WM;
975 if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
976 /* for better performance */
977 RxWm /= 2;
978 TxWm /= 2;
981 /* Rx Queue: Release all local resets and set the watermark */
982 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
983 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
986 * Tx Queue: Release all local resets if the queue is used !
987 * set watermark
989 if (pPrt->PXSQSize != 0) {
990 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
991 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
994 if (pPrt->PXAQSize != 0) {
995 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
996 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
999 * Do NOT enable the descriptor poll timers here, because
1000 * the descriptor addresses are not specified yet.
1002 } /* SkGeInitBmu */
1005 /******************************************************************************
1007 * TestStopBit() - Test the stop bit of the queue
1009 * Description:
1010 * Stopping a queue is not as simple as it seems to be.
1011 * If descriptor polling is enabled, it may happen
1012 * that RX/TX stop is done and SV idle is NOT set.
1013 * In this case we have to issue another stop command.
1015 * Returns:
1016 * The queues control status register
1018 static SK_U32 TestStopBit(
1019 SK_AC *pAC, /* Adapter Context */
1020 SK_IOC IoC, /* IO Context */
1021 int QuIoOffs) /* Queue IO Address Offset */
1023 SK_U32 QuCsr; /* CSR contents */
1025 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1027 if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
1028 /* Stop Descriptor overridden by start command */
1029 SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
1031 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1034 return(QuCsr);
1035 } /* TestStopBit */
1038 /******************************************************************************
1040 * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
1042 * Description:
1043 * After calling this function the descriptor rings and Rx and Tx
1044 * queues of this port may be reconfigured.
1046 * It is possible to stop the receive and transmit path separate or
1047 * both together.
1049 * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC.
1050 * The receive queue is still active and
1051 * the pending Rx frames may be still transferred
1052 * into the RxD.
1053 * SK_STOP_RX Stop the receive path. The tansmit path
1054 * has to be stopped once before.
1055 * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX
1057 * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive.
1058 * SK_HARD_RST Resets the MAC and the PHY.
1060 * Example:
1061 * 1) A Link Down event was signaled for a port. Therefore the activity
1062 * of this port should be stopped and a hardware reset should be issued
1063 * to enable the workaround of XMAC Errata #2. But the received frames
1064 * should not be discarded.
1065 * ...
1066 * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
1067 * (transfer all pending Rx frames)
1068 * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
1069 * ...
1071 * 2) An event was issued which request the driver to switch
1072 * the 'virtual active' link to an other already active port
1073 * as soon as possible. The frames in the receive queue of this
1074 * port may be lost. But the PHY must not be reset during this
1075 * event.
1076 * ...
1077 * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
1078 * ...
1080 * Extended Description:
1081 * If SK_STOP_TX is set,
1082 * o disable the MAC's receive and transmitter to prevent
1083 * from sending incomplete frames
1084 * o stop the port's transmit queues before terminating the
1085 * BMUs to prevent from performing incomplete PCI cycles
1086 * on the PCI bus
1087 * - The network Rx and Tx activity and PCI Tx transfer is
1088 * disabled now.
1089 * o reset the MAC depending on the RstMode
1090 * o Stop Interval Timer and Limit Counter of Tx Arbiter,
1091 * also disable Force Sync bit and Enable Alloc bit.
1092 * o perform a local reset of the port's Tx path
1093 * - reset the PCI FIFO of the async Tx queue
1094 * - reset the PCI FIFO of the sync Tx queue
1095 * - reset the RAM Buffer async Tx queue
1096 * - reset the RAM Buffer sync Tx queue
1097 * - reset the MAC Tx FIFO
1098 * o switch Link and Tx LED off, stop the LED counters
1100 * If SK_STOP_RX is set,
1101 * o stop the port's receive queue
1102 * - The path data transfer activity is fully stopped now.
1103 * o perform a local reset of the port's Rx path
1104 * - reset the PCI FIFO of the Rx queue
1105 * - reset the RAM Buffer receive queue
1106 * - reset the MAC Rx FIFO
1107 * o switch Rx LED off, stop the LED counter
1109 * If all ports are stopped,
1110 * o reset the RAM Interface.
1112 * Notes:
1113 * o This function may be called during the driver states RESET_PORT and
1114 * SWITCH_PORT.
1116 void SkGeStopPort(
1117 SK_AC *pAC, /* adapter context */
1118 SK_IOC IoC, /* I/O context */
1119 int Port, /* port to stop (MAC_1 + n) */
1120 int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
1121 int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
1123 #ifndef SK_DIAG
1124 SK_EVPARA Para;
1125 #endif /* !SK_DIAG */
1126 SK_GEPORT *pPrt;
1127 SK_U32 DWord;
1128 SK_U32 XsCsr;
1129 SK_U32 XaCsr;
1130 SK_U64 ToutStart;
1131 int i;
1132 int ToutCnt;
1134 pPrt = &pAC->GIni.GP[Port];
1136 if ((Dir & SK_STOP_TX) != 0) {
1137 /* disable receiver and transmitter */
1138 SkMacRxTxDisable(pAC, IoC, Port);
1140 /* stop both transmit queues */
1142 * If the BMU is in the reset state CSR_STOP will terminate
1143 * immediately.
1145 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
1146 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
1148 ToutStart = SkOsGetTime(pAC);
1149 ToutCnt = 0;
1150 do {
1152 * Clear packet arbiter timeout to make sure
1153 * this loop will terminate.
1155 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1156 PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
1159 * If the transfer stucks at the MAC the STOP command will not
1160 * terminate if we don't flush the XMAC's transmit FIFO !
1162 SkMacFlushTxFifo(pAC, IoC, Port);
1164 XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
1165 XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
1167 if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
1169 * Timeout of 1/18 second reached.
1170 * This needs to be checked at 1/18 sec only.
1172 ToutCnt++;
1173 if (ToutCnt > 1) {
1174 /* Might be a problem when the driver event handler
1175 * calls StopPort again. XXX.
1178 /* Fatal Error, Loop aborted */
1179 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
1180 SKERR_HWI_E018MSG);
1181 #ifndef SK_DIAG
1182 Para.Para64 = Port;
1183 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
1184 #endif /* !SK_DIAG */
1185 return;
1188 * Cache incoherency workaround: Assume a start command
1189 * has been lost while sending the frame.
1191 ToutStart = SkOsGetTime(pAC);
1193 if ((XsCsr & CSR_STOP) != 0) {
1194 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
1196 if ((XaCsr & CSR_STOP) != 0) {
1197 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
1202 * Because of the ASIC problem report entry from 21.08.1998 it is
1203 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
1205 } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
1206 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1208 /* Reset the MAC depending on the RstMode */
1209 if (RstMode == SK_SOFT_RST) {
1210 SkMacSoftRst(pAC, IoC, Port);
1212 else {
1213 SkMacHardRst(pAC, IoC, Port);
1216 /* Disable Force Sync bit and Enable Alloc bit */
1217 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
1218 TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
1220 /* Stop Interval Timer and Limit Counter of Tx Arbiter */
1221 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
1222 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
1224 /* Perform a local reset of the port's Tx path */
1226 /* Reset the PCI FIFO of the async Tx queue */
1227 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
1228 /* Reset the PCI FIFO of the sync Tx queue */
1229 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
1230 /* Reset the RAM Buffer async Tx queue */
1231 SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
1232 /* Reset the RAM Buffer sync Tx queue */
1233 SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
1235 /* Reset Tx MAC FIFO */
1236 #ifdef GENESIS
1237 if (pAC->GIni.GIGenesis) {
1238 /* Note: MFF_RST_SET does NOT reset the XMAC ! */
1239 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
1241 /* switch Link and Tx LED off, stop the LED counters */
1242 /* Link LED is switched off by the RLMT and the Diag itself */
1243 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
1245 #endif /* GENESIS */
1247 #ifdef YUKON
1248 if (pAC->GIni.GIYukon) {
1249 /* Reset TX MAC FIFO */
1250 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1252 #endif /* YUKON */
1255 if ((Dir & SK_STOP_RX) != 0) {
1257 * The RX Stop Command will not terminate if no buffers
1258 * are queued in the RxD ring. But it will always reach
1259 * the Idle state. Therefore we can use this feature to
1260 * stop the transfer of received packets.
1262 /* stop the port's receive queue */
1263 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
1265 i = 100;
1266 do {
1268 * Clear packet arbiter timeout to make sure
1269 * this loop will terminate
1271 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1272 PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
1274 DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
1276 /* timeout if i==0 (bug fix for #10748) */
1277 if (--i == 0) {
1278 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
1279 SKERR_HWI_E024MSG);
1280 break;
1283 * because of the ASIC problem report entry from 21.08.98
1284 * it is required to wait until CSR_STOP is reset and
1285 * CSR_SV_IDLE is set.
1287 } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1289 /* The path data transfer activity is fully stopped now */
1291 /* Perform a local reset of the port's Rx path */
1293 /* Reset the PCI FIFO of the Rx queue */
1294 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
1295 /* Reset the RAM Buffer receive queue */
1296 SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
1298 /* Reset Rx MAC FIFO */
1299 #ifdef GENESIS
1300 if (pAC->GIni.GIGenesis) {
1302 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
1304 /* switch Rx LED off, stop the LED counter */
1305 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
1307 #endif /* GENESIS */
1309 #ifdef YUKON
1310 if (pAC->GIni.GIYukon) {
1311 /* Reset Rx MAC FIFO */
1312 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1314 #endif /* YUKON */
1316 } /* SkGeStopPort */
1319 /******************************************************************************
1321 * SkGeInit0() - Level 0 Initialization
1323 * Description:
1324 * - Initialize the BMU address offsets
1326 * Returns:
1327 * nothing
1329 static void SkGeInit0(
1330 SK_AC *pAC, /* adapter context */
1331 SK_IOC IoC) /* IO context */
1333 int i;
1334 SK_GEPORT *pPrt;
1336 for (i = 0; i < SK_MAX_MACS; i++) {
1337 pPrt = &pAC->GIni.GP[i];
1339 pPrt->PState = SK_PRT_RESET;
1340 pPrt->PRxQOff = QOffTab[i].RxQOff;
1341 pPrt->PXsQOff = QOffTab[i].XsQOff;
1342 pPrt->PXaQOff = QOffTab[i].XaQOff;
1343 pPrt->PCheckPar = SK_FALSE;
1344 pPrt->PIsave = 0;
1345 pPrt->PPrevShorts = 0;
1346 pPrt->PLinkResCt = 0;
1347 pPrt->PAutoNegTOCt = 0;
1348 pPrt->PPrevRx = 0;
1349 pPrt->PPrevFcs = 0;
1350 pPrt->PRxLim = SK_DEF_RX_WA_LIM;
1351 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
1352 pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
1353 pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
1354 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
1355 pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
1356 pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1357 pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
1358 SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
1359 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
1360 pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1361 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
1362 pPrt->PMSCap = 0;
1363 pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
1364 pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
1365 pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
1366 pPrt->PAutoNegFail = SK_FALSE;
1367 pPrt->PHWLinkUp = SK_FALSE;
1368 pPrt->PLinkBroken = SK_TRUE; /* See WA code */
1369 pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
1370 pPrt->PMacColThres = TX_COL_DEF;
1371 pPrt->PMacJamLen = TX_JAM_LEN_DEF;
1372 pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF;
1373 pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
1374 pPrt->PMacIpgData = IPG_DATA_DEF;
1375 pPrt->PMacLimit4 = SK_FALSE;
1378 pAC->GIni.GIPortUsage = SK_RED_LINK;
1379 pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
1380 pAC->GIni.GIValIrqMask = IS_ALL_MSK;
1382 } /* SkGeInit0*/
1385 /******************************************************************************
1387 * SkGeInit1() - Level 1 Initialization
1389 * Description:
1390 * o Do a software reset.
1391 * o Clear all reset bits.
1392 * o Verify that the detected hardware is present.
1393 * Return an error if not.
1394 * o Get the hardware configuration
1395 * + Read the number of MACs/Ports.
1396 * + Read the RAM size.
1397 * + Read the PCI Revision Id.
1398 * + Find out the adapters host clock speed
1399 * + Read and check the PHY type
1401 * Returns:
1402 * 0: success
1403 * 5: Unexpected PHY type detected
1404 * 6: HW self test failed
1406 static int SkGeInit1(
1407 SK_AC *pAC, /* adapter context */
1408 SK_IOC IoC) /* IO context */
1410 SK_U8 Byte;
1411 SK_U16 Word;
1412 SK_U16 CtrlStat;
1413 SK_U32 DWord;
1414 int RetVal;
1415 int i;
1417 RetVal = 0;
1419 /* save CLK_RUN bits (YUKON-Lite) */
1420 SK_IN16(IoC, B0_CTST, &CtrlStat);
1422 /* do the SW-reset */
1423 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1425 /* release the SW-reset */
1426 SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
1428 /* reset all error bits in the PCI STATUS register */
1430 * Note: PCI Cfg cycles cannot be used, because they are not
1431 * available on some platforms after 'boot time'.
1433 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1435 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1436 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1437 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1439 /* release Master Reset */
1440 SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
1442 #ifdef CLK_RUN
1443 CtrlStat |= CS_CLK_RUN_ENA;
1444 #endif /* CLK_RUN */
1446 /* restore CLK_RUN bits */
1447 SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
1448 (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
1450 /* read Chip Identification Number */
1451 SK_IN8(IoC, B2_CHIP_ID, &Byte);
1452 pAC->GIni.GIChipId = Byte;
1454 /* read number of MACs */
1455 SK_IN8(IoC, B2_MAC_CFG, &Byte);
1456 pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
1458 /* get Chip Revision Number */
1459 pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
1461 /* get diff. PCI parameters */
1462 SK_IN16(IoC, B0_CTST, &CtrlStat);
1464 /* read the adapters RAM size */
1465 SK_IN8(IoC, B2_E_0, &Byte);
1467 pAC->GIni.GIGenesis = SK_FALSE;
1468 pAC->GIni.GIYukon = SK_FALSE;
1469 pAC->GIni.GIYukonLite = SK_FALSE;
1471 #ifdef GENESIS
1472 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
1474 pAC->GIni.GIGenesis = SK_TRUE;
1476 if (Byte == (SK_U8)3) {
1477 /* special case: 4 x 64k x 36, offset = 0x80000 */
1478 pAC->GIni.GIRamSize = 1024;
1479 pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
1481 else {
1482 pAC->GIni.GIRamSize = (int)Byte * 512;
1483 pAC->GIni.GIRamOffs = 0;
1485 /* all GE adapters work with 53.125 MHz host clock */
1486 pAC->GIni.GIHstClkFact = SK_FACT_53;
1488 /* set Descr. Poll Timer Init Value to 250 ms */
1489 pAC->GIni.GIPollTimerVal =
1490 SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1492 #endif /* GENESIS */
1494 #ifdef YUKON
1495 if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
1497 pAC->GIni.GIYukon = SK_TRUE;
1499 pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
1501 pAC->GIni.GIRamOffs = 0;
1503 /* WA for chip Rev. A */
1504 pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
1505 pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
1507 /* get PM Capabilities of PCI config space */
1508 SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
1510 /* check if VAUX is available */
1511 if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
1512 /* check also if PME from D3cold is set */
1513 ((Word & PCI_PME_D3C_SUP) != 0)) {
1514 /* set entry in GE init struct */
1515 pAC->GIni.GIVauxAvail = SK_TRUE;
1518 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
1519 /* this is Rev. A1 */
1520 pAC->GIni.GIYukonLite = SK_TRUE;
1522 else {
1523 /* save Flash-Address Register */
1524 SK_IN32(IoC, B2_FAR, &DWord);
1526 /* test Flash-Address Register */
1527 SK_OUT8(IoC, B2_FAR + 3, 0xff);
1528 SK_IN8(IoC, B2_FAR + 3, &Byte);
1530 if (Byte != 0) {
1531 /* this is Rev. A0 */
1532 pAC->GIni.GIYukonLite = SK_TRUE;
1534 /* restore Flash-Address Register */
1535 SK_OUT32(IoC, B2_FAR, DWord);
1539 /* switch power to VCC (WA for VAUX problem) */
1540 SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
1541 PC_VAUX_OFF | PC_VCC_ON));
1543 /* read the Interrupt source */
1544 SK_IN32(IoC, B0_ISRC, &DWord);
1546 if ((DWord & IS_HW_ERR) != 0) {
1547 /* read the HW Error Interrupt source */
1548 SK_IN32(IoC, B0_HWE_ISRC, &DWord);
1550 if ((DWord & IS_IRQ_SENSOR) != 0) {
1551 /* disable HW Error IRQ */
1552 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
1556 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1557 /* set GMAC Link Control reset */
1558 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
1560 /* clear GMAC Link Control reset */
1561 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
1563 /* all YU chips work with 78.125 MHz host clock */
1564 pAC->GIni.GIHstClkFact = SK_FACT_78;
1566 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */
1568 #endif /* YUKON */
1570 /* check if 64-bit PCI Slot is present */
1571 pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
1573 /* check if 66 MHz PCI Clock is active */
1574 pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
1576 /* read PCI HW Revision Id. */
1577 SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
1578 pAC->GIni.GIPciHwRev = Byte;
1580 /* read the PMD type */
1581 SK_IN8(IoC, B2_PMD_TYP, &Byte);
1582 pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
1584 /* read the PHY type */
1585 SK_IN8(IoC, B2_E_1, &Byte);
1587 Byte &= 0x0f; /* the PHY type is stored in the lower nibble */
1588 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1590 #ifdef GENESIS
1591 if (pAC->GIni.GIGenesis) {
1592 switch (Byte) {
1593 case SK_PHY_XMAC:
1594 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
1595 break;
1596 case SK_PHY_BCOM:
1597 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
1598 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1599 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1600 break;
1601 #ifdef OTHER_PHY
1602 case SK_PHY_LONE:
1603 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
1604 break;
1605 case SK_PHY_NAT:
1606 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
1607 break;
1608 #endif /* OTHER_PHY */
1609 default:
1610 /* ERROR: unexpected PHY type detected */
1611 RetVal = 5;
1612 break;
1615 #endif /* GENESIS */
1617 #ifdef YUKON
1618 if (pAC->GIni.GIYukon) {
1620 if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
1621 /* if this field is not initialized */
1622 Byte = (SK_U8)SK_PHY_MARV_COPPER;
1624 pAC->GIni.GICopperType = SK_TRUE;
1627 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
1629 if (pAC->GIni.GICopperType) {
1631 pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
1632 SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
1633 SK_LSPEED_CAP_1000MBPS);
1635 pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
1637 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1638 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1640 else {
1641 Byte = (SK_U8)SK_PHY_MARV_FIBER;
1644 #endif /* YUKON */
1646 pAC->GIni.GP[i].PhyType = (int)Byte;
1648 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1649 ("PHY type: %d PHY addr: %04x\n", Byte,
1650 pAC->GIni.GP[i].PhyAddr));
1653 /* get MAC Type & set function pointers dependent on */
1654 #ifdef GENESIS
1655 if (pAC->GIni.GIGenesis) {
1657 pAC->GIni.GIMacType = SK_MAC_XMAC;
1659 pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats;
1660 pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic;
1661 pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter;
1662 pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus;
1664 #endif /* GENESIS */
1666 #ifdef YUKON
1667 if (pAC->GIni.GIYukon) {
1669 pAC->GIni.GIMacType = SK_MAC_GMAC;
1671 pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats;
1672 pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic;
1673 pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter;
1674 pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;
1676 #ifdef SPECIAL_HANDLING
1677 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
1678 /* check HW self test result */
1679 SK_IN8(IoC, B2_E_3, &Byte);
1680 if (Byte & B2_E3_RES_MASK) {
1681 RetVal = 6;
1684 #endif
1686 #endif /* YUKON */
1688 return(RetVal);
1689 } /* SkGeInit1 */
1692 /******************************************************************************
1694 * SkGeInit2() - Level 2 Initialization
1696 * Description:
1697 * - start the Blink Source Counter
1698 * - start the Descriptor Poll Timer
1699 * - configure the MAC-Arbiter
1700 * - configure the Packet-Arbiter
1701 * - enable the Tx Arbiters
1702 * - enable the RAM Interface Arbiter
1704 * Returns:
1705 * nothing
1707 static void SkGeInit2(
1708 SK_AC *pAC, /* adapter context */
1709 SK_IOC IoC) /* IO context */
1711 #ifdef GENESIS
1712 SK_U32 DWord;
1713 #endif /* GENESIS */
1714 int i;
1716 /* start the Descriptor Poll Timer */
1717 if (pAC->GIni.GIPollTimerVal != 0) {
1718 if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
1719 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
1721 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
1723 SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
1724 SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
1727 #ifdef GENESIS
1728 if (pAC->GIni.GIGenesis) {
1729 /* start the Blink Source Counter */
1730 DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1732 SK_OUT32(IoC, B2_BSC_INI, DWord);
1733 SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
1736 * Configure the MAC Arbiter and the Packet Arbiter.
1737 * They will be started once and never be stopped.
1739 SkGeInitMacArb(pAC, IoC);
1741 SkGeInitPktArb(pAC, IoC);
1743 #endif /* GENESIS */
1745 #ifdef YUKON
1746 if (pAC->GIni.GIYukon) {
1747 /* start Time Stamp Timer */
1748 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
1750 #endif /* YUKON */
1752 /* enable the Tx Arbiters */
1753 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1754 SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
1757 /* enable the RAM Interface Arbiter */
1758 SkGeInitRamIface(pAC, IoC);
1760 } /* SkGeInit2 */
1762 /******************************************************************************
1764 * SkGeInit() - Initialize the GE Adapter with the specified level.
1766 * Description:
1767 * Level 0: Initialize the Module structures.
1768 * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has
1769 * to be set before calling this level.
1771 * o Do a software reset.
1772 * o Clear all reset bits.
1773 * o Verify that the detected hardware is present.
1774 * Return an error if not.
1775 * o Get the hardware configuration
1776 * + Set GIMacsFound with the number of MACs.
1777 * + Store the RAM size in GIRamSize.
1778 * + Save the PCI Revision ID in GIPciHwRev.
1779 * o return an error
1780 * if Number of MACs > SK_MAX_MACS
1782 * After returning from Level 0 the adapter
1783 * may be accessed with IO operations.
1785 * Level 2: start the Blink Source Counter
1787 * Returns:
1788 * 0: success
1789 * 1: Number of MACs exceeds SK_MAX_MACS (after level 1)
1790 * 2: Adapter not present or not accessible
1791 * 3: Illegal initialization level
1792 * 4: Initialization Level 1 Call missing
1793 * 5: Unexpected PHY type detected
1794 * 6: HW self test failed
1796 int SkGeInit(
1797 SK_AC *pAC, /* adapter context */
1798 SK_IOC IoC, /* IO context */
1799 int Level) /* initialization level */
1801 int RetVal; /* return value */
1802 SK_U32 DWord;
1804 RetVal = 0;
1805 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1806 ("SkGeInit(Level %d)\n", Level));
1808 switch (Level) {
1809 case SK_INIT_DATA:
1810 /* Initialization Level 0 */
1811 SkGeInit0(pAC, IoC);
1812 pAC->GIni.GILevel = SK_INIT_DATA;
1813 break;
1815 case SK_INIT_IO:
1816 /* Initialization Level 1 */
1817 RetVal = SkGeInit1(pAC, IoC);
1818 if (RetVal != 0) {
1819 break;
1822 /* check if the adapter seems to be accessible */
1823 SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
1824 SK_IN32(IoC, B2_IRQM_INI, &DWord);
1825 SK_OUT32(IoC, B2_IRQM_INI, 0L);
1827 if (DWord != SK_TEST_VAL) {
1828 RetVal = 2;
1829 break;
1832 /* check if the number of GIMacsFound matches SK_MAX_MACS */
1833 if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
1834 RetVal = 1;
1835 break;
1838 /* Level 1 successfully passed */
1839 pAC->GIni.GILevel = SK_INIT_IO;
1840 break;
1842 case SK_INIT_RUN:
1843 /* Initialization Level 2 */
1844 if (pAC->GIni.GILevel != SK_INIT_IO) {
1845 #ifndef SK_DIAG
1846 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
1847 #endif /* !SK_DIAG */
1848 RetVal = 4;
1849 break;
1851 SkGeInit2(pAC, IoC);
1853 /* Level 2 successfully passed */
1854 pAC->GIni.GILevel = SK_INIT_RUN;
1855 break;
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
1859 RetVal = 3;
1860 break;
1863 return(RetVal);
1864 } /* SkGeInit */
1867 /******************************************************************************
1869 * SkGeDeInit() - Deinitialize the adapter
1871 * Description:
1872 * All ports of the adapter will be stopped if not already done.
1873 * Do a software reset and switch off all LEDs.
1875 * Returns:
1876 * nothing
1878 void SkGeDeInit(
1879 SK_AC *pAC, /* adapter context */
1880 SK_IOC IoC) /* IO context */
1882 int i;
1883 SK_U16 Word;
1885 #if (!defined(SK_SLIM) && !defined(VCPU))
1886 /* ensure I2C is ready */
1887 SkI2cWaitIrq(pAC, IoC);
1888 #endif
1890 /* stop all current transfer activity */
1891 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1892 if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
1893 pAC->GIni.GP[i].PState != SK_PRT_RESET) {
1895 SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
1899 /* Reset all bits in the PCI STATUS register */
1901 * Note: PCI Cfg cycles cannot be used, because they are not
1902 * available on some platforms after 'boot time'.
1904 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1906 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1907 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1908 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1910 /* do the reset, all LEDs are switched off now */
1911 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1913 pAC->GIni.GILevel = SK_INIT_DATA;
1914 } /* SkGeDeInit */
1917 /******************************************************************************
1919 * SkGeInitPort() Initialize the specified port.
1921 * Description:
1922 * PRxQSize, PXSQSize, and PXAQSize has to be
1923 * configured for the specified port before calling this function.
1924 * The descriptor rings has to be initialized too.
1926 * o (Re)configure queues of the specified port.
1927 * o configure the MAC of the specified port.
1928 * o put ASIC and MAC(s) in operational mode.
1929 * o initialize Rx/Tx and Sync LED
1930 * o initialize RAM Buffers and MAC FIFOs
1932 * The port is ready to connect when returning.
1934 * Note:
1935 * The MAC's Rx and Tx state machine is still disabled when returning.
1937 * Returns:
1938 * 0: success
1939 * 1: Queue size initialization error. The configured values
1940 * for PRxQSize, PXSQSize, or PXAQSize are invalid for one
1941 * or more queues. The specified port was NOT initialized.
1942 * An error log entry was generated.
1943 * 2: The port has to be stopped before it can be initialized again.
1945 int SkGeInitPort(
1946 SK_AC *pAC, /* adapter context */
1947 SK_IOC IoC, /* IO context */
1948 int Port) /* Port to configure */
1950 SK_GEPORT *pPrt;
1952 pPrt = &pAC->GIni.GP[Port];
1954 if (SkGeCheckQSize(pAC, Port) != 0) {
1955 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
1956 return(1);
1959 if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
1960 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
1961 return(2);
1964 /* configuration ok, initialize the Port now */
1966 #ifdef GENESIS
1967 if (pAC->GIni.GIGenesis) {
1968 /* initialize Rx, Tx and Link LED */
1970 * If 1000BT Phy needs LED initialization than swap
1971 * LED and XMAC initialization order
1973 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
1974 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
1975 /* The Link LED is initialized by RLMT or Diagnostics itself */
1977 SkXmInitMac(pAC, IoC, Port);
1979 #endif /* GENESIS */
1981 #ifdef YUKON
1982 if (pAC->GIni.GIYukon) {
1984 SkGmInitMac(pAC, IoC, Port);
1986 #endif /* YUKON */
1988 /* do NOT initialize the Link Sync Counter */
1990 SkGeInitMacFifo(pAC, IoC, Port);
1992 SkGeInitRamBufs(pAC, IoC, Port);
1994 if (pPrt->PXSQSize != 0) {
1995 /* enable Force Sync bit if synchronous queue available */
1996 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
1999 SkGeInitBmu(pAC, IoC, Port);
2001 /* mark port as initialized */
2002 pPrt->PState = SK_PRT_INIT;
2004 return(0);
2005 } /* SkGeInitPort */