dec21x40End.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:165k
源码类别:

VxWorks

开发平台:

C/C++

  1.             (pDrvCtrl->rxLen < pDrvCtrl->rxMaxLen))
  2.             dec21x40Recv (pDrvCtrl, pRxD);
  3.     if (dec21x40RxDGet (pDrvCtrl) != NULL)
  4.         {
  5.         pDrvCtrl->rxMaxLen = (TCP_MSS * 30); /* get more packets next time */
  6.         netJobAdd ((FUNCPTR)dec21x40RxIntHandle, (int)pDrvCtrl, 0, 0, 0, 0);
  7.         }
  8.     else
  9.         {
  10.         pDrvCtrl->rxMaxLen = RWIN;
  11.         DEC_CSR_UPDATE (CSR7, CSR7_RIM);     /* turn on Rx interrupts */
  12.         pDrvCtrl->rxHandling = FALSE;
  13.         }
  14.     }
  15. /***************************************************************************
  16. *
  17. * dec21x40RxDGet - get a ready receive descriptor
  18. *
  19. * RETURNS: a filled receive descriptor, otherwise NULL.
  20. */
  21. LOCAL DEC_RD * dec21x40RxDGet
  22.     (
  23.     DRV_CTRL *pDrvCtrl
  24.     )
  25.     {
  26.     DEC_RD *pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;
  27.     
  28.     DEC_CACHE_INVALIDATE (pRxD, RD_SIZ);
  29.     /* check if the descriptor is owned by the chip */
  30.     if (pRxD->rDesc0 & PCISWAP (RDESC0_OWN))
  31.         return NULL;
  32.     return pRxD;
  33.     }
  34. /***************************************************************************
  35. *
  36. * dec21x40TxDGet - get an available transmit descriptor
  37. *
  38. * RETURNS: an available transmit descriptor, otherwise NULL.
  39. */
  40. LOCAL DEC_TD * dec21x40TxDGet
  41.     (
  42.     DRV_CTRL *pDrvCtrl
  43.     )
  44.     {
  45.     DEC_TD *pTxD = pDrvCtrl->txRing + pDrvCtrl->txIndex;
  46.     DEC_CACHE_INVALIDATE (pTxD, TD_SIZ);
  47.     /* check if this descriptor is owned by the chip or is out of bounds */
  48.     if ((pTxD->tDesc0 & PCISWAP(TDESC0_OWN)) ||
  49.         (((pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds) == pDrvCtrl->txDiIndex))
  50.         return (NULL);
  51.     return pTxD;
  52.     }
  53. /***************************************************************************
  54. *
  55. * dec21x40TxRingClean - clean up processed tx descriptors
  56. *
  57. * This routine processes the transmit queue, freeing all transmitted
  58. * descriptors.
  59. *
  60. * RETURNS: None
  61. */
  62. LOCAL void dec21x40TxRingClean
  63.     (
  64.     DRV_CTRL *pDrvCtrl
  65.     )
  66.     {
  67.     DEC_TD *pTxD;
  68.     pDrvCtrl->txCleaning = TRUE;
  69.     
  70.     while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)
  71.         {
  72.         pTxD = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;
  73.         DEC_CACHE_INVALIDATE (pTxD, TD_SIZ);
  74.         if (pTxD->tDesc0 & PCISWAP(TDESC0_OWN))
  75.             break;
  76.         DRV_LOG (DRV_DEBUG_TX, "Tc:0x%x ", pDrvCtrl->txDiIndex, 0, 0, 0, 0, 0);
  77.         /* free the buffer */
  78.         if (pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf != NULL)
  79.             {
  80.             NET_BUF_FREE(pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf);
  81.             pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf = NULL;
  82.             }
  83.         
  84.         pDrvCtrl->txDiIndex =  (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->numTds;
  85.         /* clear frame-type of a setup frame and process errors for others */
  86.         if (pTxD->tDesc1 & PCISWAP(TDESC1_SET))
  87.             {
  88.             pTxD->tDesc1 &= PCISWAP(~(TDESC1_SET | TDESC1_FT0));
  89.     CACHE_PIPE_FLUSH();
  90.             }
  91.         else if (pTxD->tDesc0 & PCISWAP(TDESC0_ES))
  92.             {
  93. #ifdef INCLUDE_RFC_1213
  94.             /* Old RFC 1213 mib2 interface */
  95.             END_OBJ     *pEndObj = &pDrvCtrl->endObj;
  96.             END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1);
  97.             END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1);
  98. #else            
  99.             /* New RFC 2233 mib2 interface */
  100.             if (pDrvCtrl->endObj.pMib2Tbl != NULL)
  101.                 {
  102.                 pDrvCtrl->endObj.pMib2Tbl->m2CtrUpdateRtn(pDrvCtrl->endObj.
  103.                                                                     pMib2Tbl,
  104.                                                           M2_ctrId_ifOutErrors,
  105.                                                           1);
  106.                 }
  107. #endif /* INCLUDE_RFC_1213 */
  108.            /*
  109.             * NOTE: NC and LO TxDesc bits not valid in internal
  110.             * loop-back mode (CSR6_OM_IL). 
  111.             */
  112.             
  113.    /* we dont have MII phy on a 21145 */
  114.    if( (pDrvCtrl->usrFlags & DEC_USR_21145) == 0)
  115.        {
  116.        if ( !(DEC_CSR_READ(CSR6) & PCISWAP(CSR6_OM_IL)) &&
  117.     (pTxD->tDesc0 & PCISWAP(TDESC0_NC|TDESC0_LO)) )
  118.    {
  119.    /* check for no carrier */
  120.    if ((pTxD->tDesc0 & PCISWAP(TDESC0_NC)) &&
  121.        !(pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_FD))
  122.        {
  123.        DRV_LOG (DRV_DEBUG_ALL, "%s%d - no carriern",
  124. (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  125.        }
  126.    if ((pTxD->tDesc0 & PCISWAP(TDESC0_LO)) &&
  127.        !(pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_FD))
  128.        {
  129.        DRV_LOG (DRV_DEBUG_ALL, "%s%d - loss of carriern",
  130.         (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  131.        }
  132.    dec21x40MediaChange (pDrvCtrl);
  133.    }
  134.        }
  135.    
  136.    /*
  137.             * check for link failure (LF)
  138.     * NOTE: LF in invalid in HomePNA mode
  139.             */
  140.            if ( !(DEC_CSR_READ(CSR6) & PCISWAP(CSR6_OM_IL)) &&
  141.                (pTxD->tDesc0 & PCISWAP(TDESC0_LF)) )
  142.                 {
  143. if((pDrvCtrl->usrFlags & DEC_USR_21145) == 0)
  144.     {
  145.     DRV_LOG (DRV_DEBUG_ALL, "%s%d - link failn",
  146.              (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  147.     dec21x40MediaChange (pDrvCtrl);
  148.     }
  149. /* we are a 21145, make sure we are not in HomePNA mode */
  150. else if( (DEC_CSR_READ(CSR13) & CSR13_AUI_TP) == 0)
  151.     {
  152.     DRV_LOG (DRV_DEBUG_ALL, "%s%d - link failn",
  153.              (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  154.     dec21x40MediaChange (pDrvCtrl);
  155.     }
  156. else if( pDrvCtrl->usrFlags & DEC_USR_HPNA_PREFER_10BT)
  157.     {
  158.     /*
  159.                      * we are in HOMEPNA mode and usr flags are set to
  160.      * prefer 10BT so we must
  161.      * restart autonegotiation
  162.                      */
  163.             DEC_CSR_WRITE(CSR12, (DEC_CSR_READ(CSR12) & 
  164.   ~CSR12_AN_MASK) | 
  165.   CSR12_AN_TX_DISABLED);
  166.     }
  167.                 }
  168.             /* restart if DMA underflow is detected */
  169.             
  170.             if (pTxD->tDesc0 & PCISWAP(TDESC0_UF))
  171.                 {
  172.                 DRV_LOG (DRV_DEBUG_ALL, "%s%d - fatal DMA underflown",
  173.                            (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  174.                 dec21x40Stop (pDrvCtrl);
  175.                 pDrvCtrl->txCleaning = FALSE;
  176.                 netJobAdd ((FUNCPTR)dec21x40Restart, (int)pDrvCtrl, 0, 0, 0, 0);
  177.                 return;
  178.                 }
  179.             }
  180. #ifdef DRV_DEBUG
  181.     {
  182.     UINT32 debugStat = pTxD->tDesc0 & PCISWAP (0x0000cf87);
  183.     if (debugStat & (PCISWAP(TDESC0_ES | 
  184. TDESC0_LF | TDESC0_DE))) 
  185. {
  186. decDescErrors++;
  187. }
  188.     }
  189. #endif /* DRV_DEBUG */
  190.         pTxD->tDesc0 = 0;                    /* clear errors and stats */
  191. CACHE_PIPE_FLUSH();
  192.         }
  193.     pDrvCtrl->txCleaning = FALSE;
  194.     return;
  195.     }
  196. /***************************************************************************
  197. *
  198. * dec21x40Int - handle device interrupts
  199. *
  200. * This interrupt service routine, reads device interrupt status, acknowledges
  201. * the interrupting events, and schedules receive and transmit processing when
  202. * required.
  203. *
  204. * RETURNS: None
  205. */
  206. LOCAL void dec21x40Int
  207.     (
  208.     DRV_CTRL * pDrvCtrl
  209.     )
  210.     {
  211.     ULONG status;
  212.     CACHE_PIPE_FLUSH();
  213.     /* get the status bits and clear the interrupts */
  214.     status = DEC_CSR_READ (CSR5);
  215.     while (status & (pDrvCtrl->intrMask))
  216. {
  217. DEC_CSR_WRITE (CSR5, status);
  218. DRV_LOG (DRV_DEBUG_INT, "i=0x%x:n", status, 0, 0, 0, 0, 0);
  219. /* Check for autonego/link pass int 21145 */
  220. /* if HPNA_PREFER_10BT is set and */
  221. /*  we are in HOME_PNA mode */
  222. if ((status & CSR5_ANC) &&
  223.     DRV_FLAGS_ISSET(DEC_21145) && 
  224.      (pDrvCtrl->usrFlags & DEC_USR_HPNA_PREFER_10BT) &&
  225.      (DEC_CSR_READ(CSR13) & CSR13_AUI_TP)) 
  226.     {
  227.     DRV_LOG (DRV_DEBUG_INT, "anc_int: %lxn", DEC_CSR_READ(CSR12), 
  228.      0, 0, 0, 0, 0);
  229.     dec21x40Stop (pDrvCtrl);
  230.     netJobAdd ((FUNCPTR)dec21x40Restart, (int)pDrvCtrl, 0, 0, 0, 0);
  231.     }
  232. if ((status & CSR5_21040_LNF) &&
  233.     DRV_FLAGS_ISSET(DEC_21145) && 
  234.      (pDrvCtrl->usrFlags & DEC_USR_HPNA_PREFER_10BT) &&
  235.      ( (DEC_CSR_READ(CSR13) & CSR13_AUI_TP) == 0)) 
  236.     {
  237.     DRV_LOG (DRV_DEBUG_INT, "lnk_fail_int: %lxn", DEC_CSR_READ(CSR12), 
  238.      0, 0, 0, 0, 0);
  239.     dec21x40Stop (pDrvCtrl);
  240.     netJobAdd ((FUNCPTR)dec21x40Restart, (int)pDrvCtrl, 0, 0, 0, 0);
  241.     }
  242. /* return on false interrupt */
  243. if ((status & (CSR5_NIS | CSR5_AIS)) == 0)
  244.     {
  245.     DRV_LOG (DRV_DEBUG_INT, "false intrn", 0, 0, 0, 0, 0, 0);
  246.     return;
  247.     }
  248. /* Check for system error */
  249. if (status & CSR5_SE)
  250.     {
  251.     DRV_LOG (DRV_DEBUG_INT, "E", 0, 0, 0, 0, 0, 0);
  252.     DRV_LOG (DRV_DEBUG_INT, "%s%d - fatal system errorn",
  253.     (int)DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);
  254.     dec21x40Stop (pDrvCtrl);
  255.     netJobAdd ((FUNCPTR) dec21x40Restart, (int)pDrvCtrl, 0, 0, 0, 0);
  256.     return;
  257.     }
  258. /* Handle received packets */
  259. if ((status & CSR5_RI) && (! (status & CSR5_RPS)) &&
  260.     (!pDrvCtrl->rxHandling))
  261.     {
  262.     DRV_LOG (DRV_DEBUG_INT, "r ", 0, 0, 0, 0, 0, 0);
  263.     pDrvCtrl->rxHandling = TRUE;
  264.     netJobAdd ((FUNCPTR)dec21x40RxIntHandle, (int)pDrvCtrl, 0, 0, 0, 0);
  265.     
  266.     /* disable Rx intr; re-enable in dec21x40RxIntHandle() */
  267.     DEC_CSR_RESET (CSR7, CSR7_RIM);
  268.     }
  269. #ifdef DRV_DEBUG
  270. if (status & CSR5_TI)
  271.     decTxInts++;
  272. if (status & CSR5_RI)
  273.     decRxInts++;
  274. if (status & (CSR5_TPS | CSR5_TU | CSR5_TJT | CSR5_UNF))
  275.     decTxErrors++;
  276. if (status & (CSR5_RU | CSR5_RPS | CSR5_RWT))
  277.     decRxErrors++;
  278. if (status & (CSR5_TPS))
  279.     decTxTpsErrors++;
  280. if (status & (CSR5_TU))
  281.     decTxBufErrors++;
  282. if (status & (CSR5_TJT))
  283.     decTxTjtErrors++;
  284. if (status & (CSR5_UNF))
  285.     decTxUnfErrors++;
  286. if (status & (CSR5_RU))
  287.     decRxBufErrors++;
  288. if (status & (CSR5_RPS))
  289.     decRxRpsErrors++;
  290. if (status & (CSR5_RWT))
  291.     decRxWtErrors++;
  292. #endif
  293. /* Cleanup TxRing */
  294. if ((status & CSR5_TI) && (!pDrvCtrl->txCleaning))
  295.     {
  296.     DRV_LOG (DRV_DEBUG_INT, "t ", 0, 0, 0, 0, 0, 0);
  297.     pDrvCtrl->txCleaning = TRUE;
  298.     dec21x40TxRingClean (pDrvCtrl);
  299.     }
  300. if (_func_dec2114xIntAck != NULL)
  301.     {
  302.     /*
  303.      * Call BSP specific interrupt ack. routine, if defined.
  304.      * This must be called after all the interrupt  sources
  305.      * have been cleared
  306.      */
  307.     (* _func_dec2114xIntAck) ();
  308.     }
  309. if (pDrvCtrl->txBlocked)
  310.     {
  311.     pDrvCtrl->txBlocked = FALSE;
  312.     netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0,
  313.        0, 0);
  314.     }
  315. status = DEC_CSR_READ (CSR5); /* Get more interrupt status bits */
  316. }
  317.     return;
  318.     }
  319. /***************************************************************************
  320. *
  321. * dec21x40PollStart - starting polling mode
  322. *
  323. * RETURNS: OK, always.
  324. */
  325. LOCAL STATUS dec21x40PollStart
  326.     (
  327.     DRV_CTRL * pDrvCtrl
  328.     )
  329.     {
  330.     int intLevel;
  331.     DRV_LOG (DRV_DEBUG_POLL, "S ", 0, 0, 0, 0, 0, 0);
  332.     intLevel = intLock();
  333.     DEC_CSR_RESET (CSR7, CSR7_NIM | CSR7_AIM);
  334.     DRV_FLAGS_SET (DEC_POLLING);
  335.     intUnlock (intLevel);
  336.     return (OK);
  337.     }
  338. /***************************************************************************
  339. *
  340. * dec21x40PollStop - stop polling mode
  341. *
  342. * RETURNS: OK, always.
  343. */
  344. LOCAL STATUS dec21x40PollStop
  345.     (
  346.     DRV_CTRL * pDrvCtrl
  347.     )
  348.     {
  349.     int intLevel;
  350.     intLevel = intLock();
  351.     DEC_CSR_UPDATE (CSR7, (CSR7_NIM | CSR7_AIM));
  352.     DRV_FLAGS_CLR (DEC_POLLING);
  353.     intUnlock (intLevel);
  354.     DRV_LOG (DRV_DEBUG_POLL, "s", 0, 0, 0, 0, 0, 0);
  355.     return (OK);
  356.     }
  357. /***************************************************************************
  358. *
  359. * dec21x40PollSend - send a packet in polled mode
  360. *
  361. * RETURNS: OK on success, EAGAIN on failure
  362. */
  363. LOCAL STATUS dec21x40PollSend
  364.     (
  365.     DRV_CTRL * pDrvCtrl,
  366.     M_BLK * pMblk
  367.     )
  368.     {
  369.     DEC_TD *pTxD;
  370.     char * pBuf;
  371.     int len;
  372.     pTxD = dec21x40TxDGet (pDrvCtrl); 
  373.     pBuf = pDrvCtrl->txPollSendBuf;
  374.     /* copy and free the MBLK */
  375.     len = netMblkToBufCopy (pMblk, pBuf, NULL);
  376. #ifndef INCLUDE_RFC_1213
  377.  
  378.     /* New RFC 2233 mib2 interface */
  379.     /* RFC 2233 mib2 counter update for outgoing packet */
  380.     if (pDrvCtrl->endObj.pMib2Tbl != NULL)
  381.         {
  382.         pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.pMib2Tbl,
  383.                                                  M2_PACKET_OUT, pBuf, len);
  384.         }
  385. #endif /* INCLUDE_RFC_1213 */
  386.     pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));
  387.     pTxD->tDesc3 = 0;
  388.     /* Associate the data pointer with the MBLK */
  389.     /* setup descriptor fields for tansmit */
  390.     pTxD->tDesc0 = 0;
  391.     pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);
  392.     pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(len));
  393.     pTxD->tDesc0 = PCISWAP(TDESC0_OWN);      /* ready for transmit */
  394.     CACHE_PIPE_FLUSH();
  395.     /* Advance our management index */
  396.     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;
  397.     if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))
  398.         DEC_CSR_WRITE (CSR1, CSR1_TPD);
  399.     /* The buffer does not belong to us; Spin until it can be freed */
  400.     while (pTxD->tDesc0 & PCISWAP(TDESC0_OWN))
  401.         ;
  402.     /* Try again on transmit errors */
  403.     if (pTxD->tDesc0 & PCISWAP(TDESC0_ES))
  404.         return (EAGAIN);
  405.     return (OK);
  406.     }
  407. /***************************************************************************
  408. *
  409. * dec21x40PollReceive - get a packet in polled mode
  410. *
  411. * RETURNS: OK on success, EAGAIN on failure.
  412. */
  413. LOCAL STATUS dec21x40PollReceive
  414.     (
  415.     DRV_CTRL *pDrvCtrl,
  416.     M_BLK  *pMblk
  417.     )
  418.     {
  419.     DEC_RD *pRxD;
  420.     char *pRxBuf;
  421.     int len;
  422.     BOOL gotOne=FALSE;
  423.     if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)
  424.         return (EAGAIN);
  425.     while (((pRxD = dec21x40RxDGet (pDrvCtrl)) != NULL) && !gotOne)
  426.         {
  427.         /* Check if the packet was received OK */
  428.         if (pRxD->rDesc0 & PCISWAP (RDESC0_ES))
  429.             {
  430.             /* Update the error statistics and discard the packet */
  431. #ifdef INCLUDE_RFC_1213
  432.             /* Old RFC 1213 mib2 interface */
  433.             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  434. #else            
  435.             /* New RFC 2233 mib2 interface */
  436.             if (pDrvCtrl->endObj.pMib2Tbl != NULL)
  437.                 {
  438.                 pDrvCtrl->endObj.pMib2Tbl->m2CtrUpdateRtn(pDrvCtrl->endObj.
  439.                                                                     pMib2Tbl,
  440.                                                           M2_ctrId_ifInErrors,
  441.                                                           1);
  442.                 }
  443. #endif /* INCLUDE_RFC_1213 */
  444.             }
  445.         else
  446.             {
  447.             len = DEC_FRAME_LEN_GET (PCISWAP(pRxD->rDesc0)) - ETH_CRC_LEN;
  448.             if (pMblk->mBlkHdr.mLen >= len)
  449.                 {
  450.                 gotOne = TRUE;
  451. #ifdef INCLUDE_RFC_1213
  452.                 /* Old RFC 1213 mib2 interface */
  453.                 END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  454. #endif /* INCLUDE_RFC_1213 */
  455.                 /* Deal with memory alignment */
  456. if (((int) pMblk->mBlkHdr.mData & 0x3) == 0)
  457.                     pMblk->mBlkHdr.mData += pDrvCtrl->offset;
  458.  
  459. pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
  460. pMblk->mBlkHdr.mLen = len;    /* set the data len */
  461. pMblk->mBlkPktHdr.len = len;    /* set the total len */
  462.                 pRxBuf = (char *) PCISWAP (pRxD->rDesc3); /* virt address */
  463. #ifndef INCLUDE_RFC_1213
  464.                 /* RFC 2233 mib2 counter update for incoming packet */
  465.                 if (pDrvCtrl->endObj.pMib2Tbl != NULL)
  466.                     {
  467.                     pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.
  468.                                                                        pMib2Tbl,
  469.                                                              M2_PACKET_IN,
  470.                                                              pRxBuf, len);
  471.                     }
  472. #endif /* INCLUDE_RFC_1213 */ 
  473.                 DEC_CACHE_INVALIDATE (pRxBuf, len);
  474.                 bcopy (pRxBuf, (char *)pMblk->mBlkHdr.mData, len);
  475.                 }
  476.             }
  477.         pRxD->rDesc0 = PCISWAP (RDESC0_OWN);
  478.         CACHE_PIPE_FLUSH();
  479.         pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;
  480.         }
  481.     return (gotOne ? OK : EAGAIN);
  482.     }
  483. /***************************************************************************
  484. *
  485. * dec21x40CsrRead - read a Command and Status Register
  486. *
  487. * RETURNS: contents of the CSR register.
  488. */
  489. LOCAL ULONG dec21x40CsrRead
  490.     (
  491.     DRV_CTRL * pDrvCtrl,              /* device control */
  492.     int reg                          /* register to read */
  493.     )
  494.     {
  495.     ULONG *csrReg;
  496.     ULONG csrData;
  497.     
  498.     csrReg = (ULONG *)(pDrvCtrl->devAdrs + (reg * DECPCI_REG_OFFSET));
  499.     csrData = *csrReg;
  500.     return REGSWAP(csrData);
  501.     }
  502. /***************************************************************************
  503. *
  504. * dec21x40CsrWrite - write a Command and Status Register
  505. *
  506. * RETURNS: None
  507. */
  508. LOCAL void dec21x40CsrWrite
  509.     (
  510.     DRV_CTRL * pDrvCtrl,              /* device control */
  511.     int reg,
  512.     ULONG value
  513.     )
  514.     {
  515.     ULONG *csrReg;
  516.     csrReg = (ULONG *)(pDrvCtrl->devAdrs + (reg * DECPCI_REG_OFFSET));
  517.     *csrReg = REGSWAP (value);
  518.     return;
  519.     }
  520. /***************************************************************************
  521. *
  522. * dec21040AuiTpInit - initialize either AUI or 10BASE-T connection
  523. *
  524. * This function configures 10BASE-T interface. If the link pass state is 
  525. * not achieved within two seconds then the AUI interface is initialized.
  526. */
  527. LOCAL void dec21040AuiTpInit
  528.     (
  529.     DRV_CTRL * pDrvCtrl
  530.     )
  531.     {
  532.     /* reset the SIA registers */
  533.     DEC_CSR_WRITE (CSR13, 0);
  534.     DEC_CSR_WRITE (CSR14, 0);
  535.     DEC_CSR_WRITE (CSR15, 0);
  536.     /* configure 10BASE-T */
  537.     DEC_CSR_WRITE (CSR13, CSR13_CAC_CSR);    /* 10BT auto configuration */
  538.     taskDelay (sysClkRateGet() * 2);         /* 2 second delay */
  539.     /* configure AUI if 10BASE-T is not connected */
  540.     if (DEC_CSR_READ (CSR12) & (CSR12_21040_LKF | CSR12_21040_NCR))
  541. {
  542.         /* reset SIA registers */
  543. DEC_CSR_WRITE (CSR13, 0);            
  544. DEC_CSR_WRITE (CSR14, 0);
  545. DEC_CSR_WRITE (CSR15, 0);
  546. /* AUI auto configuration */
  547. DEC_CSR_WRITE (CSR13, (CSR13_AUI_TP | CSR13_CAC_CSR));
  548. }
  549.     return;
  550.     }
  551. /***************************************************************************
  552. *
  553. * dec21x40EnetAddrGet - gets the ethernet address
  554. *
  555. * This routine gets the ethernet address by calling the appropriate
  556. * EnetAddrGet() routine.
  557. * RETURNS: OK/ERROR
  558. *
  559. * SEE ALSO: dec20140EnetAddrGet(), dec21140EnetAddrGet(),
  560. * sysDec21x40EnetAddrGet()
  561. */
  562. LOCAL STATUS dec21x40EnetAddrGet
  563.     (
  564.     DRV_CTRL * pDrvCtrl,
  565.     char * enetAdrs
  566.     )
  567.     {
  568.     int retVal=ERROR;
  569.     if (! DRV_FLAGS_ISSET (DEC_BSP_EADRS))
  570.         {
  571.         if (DRV_FLAGS_ISSET (DEC_21040))
  572.             retVal=dec21040EnetAddrGet (pDrvCtrl, enetAdrs);
  573.         else
  574.             retVal=dec21140EnetAddrGet (pDrvCtrl, enetAdrs);
  575.         }
  576.     
  577.     if (retVal == ERROR)
  578.         retVal = sysDec21x40EnetAddrGet (pDrvCtrl->unit, enetAdrs);
  579.     return retVal;
  580.     }
  581. /***************************************************************************
  582. *
  583. * dec21040EnetAddrGet - gets the ethernet address from the ROM register
  584. *
  585. * This routine gets the ethernet address from the ROM register.
  586. * This routine returns the ethernet address into the pointer supplied to it.
  587. * RETURNS: OK/ERROR
  588. */
  589. LOCAL STATUS dec21040EnetAddrGet
  590.     (
  591.     DRV_CTRL * pDrvCtrl,
  592.     char *  enetAdrs /* pointer to the ethernet address */ 
  593.     )
  594.     {
  595.     FAST ULONG csr9Value; /* register to hold CSR9 */
  596.     BOOL eRomReady = FALSE; /* ethernet ROM register state */
  597.     int ix; /* index register */
  598.     int len = EADDR_LEN;
  599.     DEC_CSR_WRITE (CSR9, 0); /* reset rom pointer */
  600.     while (len > 0)
  601. {
  602. for (ix = 0; ix < 10; ix++) /* try at least 10 times */
  603.     {
  604.     if ((csr9Value = DEC_CSR_READ (CSR9)) & CSR9_21040_DNV)
  605. {
  606. eRomReady = FALSE;
  607.      DEC_NSDELAY(125);
  608. }
  609.     else
  610. {
  611. *enetAdrs++ = (UCHAR) csr9Value;
  612. len--;
  613. eRomReady = TRUE;
  614. break;
  615. }
  616.     }
  617.         if (!eRomReady)
  618.             return (ERROR);
  619. }
  620.     return (OK);
  621.     }
  622. /***************************************************************************
  623. *
  624. * dec21140EnetAddrGet - gets the ethernet address from the ROM register 
  625. *
  626. * This routine reads an ethernet address from the serial ROM. It supports
  627. * legacy, ver 1/A, and 3.0 serial ROM formats.
  628. * RETURNS: OK on success, and ERROR if the ethernet address bytes cannot be
  629. * read.
  630. */
  631. LOCAL STATUS dec21140EnetAddrGet
  632.     (
  633.     DRV_CTRL * pDrvCtrl,
  634.     char *  enetAdrs /* pointer to the ethernet address */ 
  635.     )
  636.     {
  637.     USHORT sromData;
  638.     int adrsOffset;
  639.     int len;
  640.     /* Check if SROM is programmed. */
  641.     sromData = dec21140SromWordRead (pDrvCtrl, 0);
  642.     if ( sromData == 0xFFFF ) 
  643. return (ERROR);
  644.     sromData = dec21140SromWordRead (pDrvCtrl, 13);
  645.     /*
  646.      * Set MAC address offset from the ROM format.
  647.      * Legacy ROMs have ethernet address start at offset 0,
  648.      * while the rest (ver 1/A and 3.0) have it at byte offset 20.
  649.      */
  650.     adrsOffset = ((sromData == 0xAA55) ||
  651.   (sromData == 0xFFFF)) ? 0: 10;
  652.     for (len=EADDR_LEN; len; len-=2, adrsOffset++)
  653.         {
  654.         sromData = dec21140SromWordRead (pDrvCtrl, adrsOffset);
  655.         /* byte swap it for little endian */
  656.         sromData = LE_BYTE_SWAP(sromData);
  657.         *enetAdrs++ = MSB(sromData);
  658.         *enetAdrs++ = LSB(sromData);
  659.         }
  660.     return (OK);
  661.     }
  662. /***************************************************************************
  663. *
  664. * dec21140SromWordRead - read two bytes from the serial ROM
  665. *
  666. * This routine returns the two bytes of information that is associated 
  667. * with it the specified ROM line number.  This will later be used by the 
  668. * dec21140GetEthernetAdr function.  It can also be used to 
  669. * review the ROM contents itself.
  670. * The function must first send some initial bit patterns to the CSR9 that 
  671. * contains the Serial ROM Control bits.  Then the line index into the ROM
  672. * is evaluated bit-by-bit to program the ROM.  The 2 bytes of data
  673. * are extracted and processed into a normal pair of bytes. 
  674. * RETURNS: Value from ROM or ERROR.
  675. */
  676. USHORT dec21140SromWordRead
  677.     (
  678.     DRV_CTRL * pDrvCtrl,
  679.     UCHAR lineCnt  /* Serial ROM line Number */ 
  680.     )
  681.     {
  682.     int ix; /* index register */
  683.     int loop;           /* address loop counter */
  684.     ULONG adrsBase;
  685.     USHORT romData;
  686.     /* Is the line offset valid, and if so, how large is it */
  687.     if (lineCnt > DEC21140_SROM_SIZE)
  688.      return (ERROR);
  689.     if (lineCnt < 64)
  690.      {
  691. loop = 6;
  692. lineCnt = lineCnt << 2;  /* Prepare lineCnt for processing */
  693.      }
  694.     else
  695. loop = 8;
  696.     /* Command the Serial ROM to the correct Line */
  697.     /* Preamble */
  698.     DEC_SROM_CMD_WRITE (0x0, 30);           /* Command 1 */
  699.     DEC_SROM_CMD_WRITE (0x1, 50);           /* Command 2 */
  700.     DEC_SROM_CMD_WRITE (0x3, 250);          /* Command 3 */
  701.     DEC_SROM_CMD_WRITE (0x1, 150);          /* Command 4 */
  702.     /* Command Phase */
  703.     DEC_SROM_CMD_WRITE (0x5, 150);          /* Command 5 */
  704.     DEC_SROM_CMD_WRITE (0x7, 250);          /* Command 6 */
  705.     DEC_SROM_CMD_WRITE (0x5, 250);          /* Command 7 */
  706.     DEC_SROM_CMD_WRITE (0x7, 250);          /* Command 8 */
  707.     DEC_SROM_CMD_WRITE (0x5, 100);          /* Command 9 */
  708.     DEC_SROM_CMD_WRITE (0x1, 150);          /* Command 10 */
  709.     DEC_SROM_CMD_WRITE (0x3, 250);          /* Command 11 */
  710.     DEC_SROM_CMD_WRITE (0x1, 100);          /* Command 12 */
  711.     
  712.     /* Address Phase */
  713.     for (ix=0; ix < loop; ix++)
  714.      {
  715. adrsBase = ((lineCnt & 0x80) >> 5); 
  716. /* Write the command */
  717.         DEC_SROM_CMD_WRITE (adrsBase | 0x1, 150);  /* Command 13 */
  718.         DEC_SROM_CMD_WRITE (adrsBase | 0x3, 250);  /* Command 14 */
  719.         DEC_SROM_CMD_WRITE (adrsBase | 0x1, 100);  /* Command 15 */
  720. lineCnt = lineCnt<<1;
  721.      }
  722.     DEC_NSDELAY (150);
  723.     /* Data Phase */
  724.     romData = 0;
  725.     for (ix=15; ix >= 0; ix--)
  726.      {
  727. /* Write the command */
  728.         DEC_SROM_CMD_WRITE (0x3, 100);      /* Command 16 */
  729. /* Extract data */
  730.      romData |= (DEC_SROM_CMD_READ() << ix);
  731.      DEC_NSDELAY (150); /* Command 17 */
  732.         DEC_SROM_CMD_WRITE (0x1, 250);      /* Command 18 */
  733.      }
  734.     /* Finish up command */
  735.     DEC_SROM_CMD_WRITE (0x0, 100);           /* Command 19 */
  736.     return (PCISWAP_SHORT(romData));
  737.     }
  738. /***************************************************************************
  739. *
  740. * dec21x40ChipReset - reset the chip and setup CSR0 register
  741. *
  742. * This routine stops the transmitter and receiver, masks all interrupts, then
  743. * resets the ethernet chip. Once the device comes out of the reset state, it
  744. * initializes CSR0 register.
  745. *
  746. * RETURNS: OK, or ERROR if a new TxD could not be obtained.
  747. */
  748. LOCAL STATUS dec21x40ChipReset
  749.     (
  750.     DRV_CTRL * pDrvCtrl /* pointer to device control structure */
  751.     )
  752.     {
  753.     ULONG usrFlags=pDrvCtrl->usrFlags;
  754.     ULONG csr0Val=0x0;
  755.     DEC_TD * pTxD;
  756.     char * pBuf;
  757.     pTxD = dec21x40TxDGet (pDrvCtrl);
  758.     pBuf = NET_BUF_ALLOC ();
  759.     if ((pTxD == NULL) || (pBuf == NULL))
  760. {
  761. if (pBuf)
  762.     NET_BUF_FREE (pBuf);
  763. return ERROR;
  764. }
  765.     /*
  766.      * "Kick" the dec21143 chip on startup to handle a dec21143
  767.      * known problem.  Note the "kicking" will not hurt the dec21140
  768.      * but seems to hurt the 21145.
  769.      */
  770.     /* setup the transmit buffer pointers */
  771.     pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));
  772.     pTxD->tDesc3 = 0;
  773.     /* setup frame len */
  774.     pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);
  775.     pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(4));
  776.     /* transfer ownership to device */
  777.     pTxD->tDesc0  = PCISWAP(TDESC0_OWN);      
  778.     /* Flush the write pipe */
  779.     CACHE_PIPE_FLUSH();
  780.     /*
  781.      * start xmit dummy packet, this will never go
  782.      * out to the physical bus
  783.      */
  784.     DEC_CSR_WRITE (CSR4, DEC_VIRT_TO_PCI((ULONG)pTxD));
  785.     DEC_CSR_WRITE (CSR7, 0);
  786.     DEC_CSR_WRITE (CSR6, CSR6_21140_MB1 |
  787. CSR6_21140_TTM |
  788. CSR6_21140_SF |
  789. CSR6_21140_PS |
  790. CSR6_ST |
  791. CSR6_OM_IL);
  792.     DEC_CSR_WRITE (CSR1, CSR1_TPD );      /* xmit poll demand */
  793.     CACHE_PIPE_FLUSH ();
  794.     /* We're done "kicking" */
  795.     DEC_NSDELAY (0x2000);
  796.     /*
  797.      * Reset the device while xmitting, it ensures the device will not hang
  798.      * up in its 1st xmit later on
  799.      */
  800.     DEC_CSR_WRITE (CSR0, DEC_CSR_READ (CSR0) | CSR0_SWR);
  801.     CACHE_PIPE_FLUSH ();
  802.     /* Re-claim buffer(s) */
  803.     pTxD->tDesc0 = 0;
  804.     NET_BUF_FREE(pBuf);
  805.     taskDelay (sysClkRateGet() / 2);
  806.     DEC_CSR_WRITE (CSR6, 0);          /* stop rcvr & xmitter */
  807.     DEC_CSR_WRITE (CSR7, 0); /* mask interrupts */
  808.     DEC_CSR_WRITE (CSR0, CSR0_SWR);
  809.     CACHE_PIPE_FLUSH ();
  810.     /* Wait Loop, Loop for at least 50 PCI cycles according to chip spec */
  811.     DEC_NSDELAY (1000);
  812.     /* Decode user setting into CSR0 bits */
  813.     csr0Val |= (usrFlags & DEC_USR_BAR_RX)? 0 : CSR0_BAR;
  814.     csr0Val |= (usrFlags & DEC_USR_BE)? CSR0_BLE : 0;
  815.     csr0Val |= (usrFlags & DEC_USR_TAP_MSK) << DEC_USR_TAP_SHF;
  816.     csr0Val |= (usrFlags & DEC_USR_PBL_MSK) << DEC_USR_PBL_SHF;
  817.     csr0Val |= (usrFlags & DEC_USR_RML)? CSR0_21140_RML : 0;
  818.     if (usrFlags & DEC_USR_CAL_MSK)
  819.         csr0Val |= (usrFlags & DEC_USR_CAL_MSK) << DEC_USR_CAL_SHF;
  820.     else
  821.         {
  822. csr0Val &= ~(CSR0_CAL_MSK | CSR0_PBL_MSK);
  823. csr0Val |= (CSR0_CAL_32 | CSR0_PBL_32);
  824.         }
  825.     
  826.     if (! (usrFlags & DEC_USR_TAP_MSK))
  827.         DRV_FLAGS_SET (DEC_TX_KICKSTART);
  828.     DEC_CSR_WRITE (CSR0, csr0Val);
  829.     CACHE_PIPE_FLUSH ();
  830.     DEC_NSDELAY (1000);
  831.     return (OK);
  832.     }
  833. /***************************************************************************
  834. *
  835. * dec21140MediaInit - Initailize media information
  836. *
  837. */
  838. LOCAL STATUS dec21140MediaInit
  839.     (
  840.     DRV_CTRL * pDrvCtrl,
  841.     UCHAR * pSromData
  842.     )
  843.     {
  844.     USHORT * pSromWord = (USHORT *)pSromData;
  845.     UCHAR * pInfoLeaf0;
  846.     UCHAR ix;
  847.     
  848.     /* read the serial ROM into pSromData */
  849.     for (ix=0; ix<DEC21140_SROM_WORDS; ix++)
  850.         *pSromWord++ = dec21140SromWordRead (pDrvCtrl, ix);
  851.     
  852.     /* Initialize the media summary */
  853.     if (pDrvCtrl->mediaCount == 0xFF)
  854.         {
  855.         /* check version */
  856.         if (SROM_VERSION( pSromData ) < DEC21140_SROM_VERSION_3)
  857.             return (ERROR);
  858.         /* get the leaf offset */
  859.         pInfoLeaf0 = pSromData + SROM_ILEAF0_OFFSET( pSromData );
  860.         pDrvCtrl->gprModeVal = ILEAF_GPR_MODE( pInfoLeaf0 );
  861.         pDrvCtrl->mediaCount = ILEAF_MEDIA_COUNT( pInfoLeaf0 );
  862.         pDrvCtrl->mediaCurrent = 0xFF;
  863.         pDrvCtrl->mediaDefault = 0xFF;
  864.         DRV_LOG (DRV_DEBUG_LOAD,
  865.                  "gpMask=0x%x mediaCount = 0x%dn",
  866.                  pDrvCtrl->gprModeVal, pDrvCtrl->mediaCount, 0, 0, 0, 0);
  867.         }
  868.     return (OK);
  869.     }
  870. /***************************************************************************
  871. * dec21x40MiiRead - read a PHY device register via MII
  872. * RETURNS: the contents of a PHY device register in retVal arg, OK always
  873. */
  874. LOCAL STATUS dec21x40MiiRead
  875.     (
  876.     DRV_CTRL    *pDrvCtrl,
  877.     UINT8       phyAdrs,                     /* PHY address to access */
  878.     UINT8       phyReg,                      /* PHY register to read */
  879.     UINT16 *pRetVal
  880.     )
  881.     {
  882.     /* Write 34-bit preamble */
  883.     DEC_MII_WRITE (MII_PREAMBLE, 32);
  884.     DEC_MII_WRITE (MII_PREAMBLE, 2);
  885.     /* start of frame + op-code nibble */
  886.     DEC_MII_WRITE ((MII_SOF | MII_RD), 4);
  887.     /* device address */
  888.     DEC_MII_WRITE (phyAdrs, 5);
  889.     DEC_MII_WRITE (phyReg, 5);
  890.     /* turn around */
  891.     DEC_MII_RTRISTATE;
  892.     /* read data */
  893.     DEC_MII_READ (pRetVal, 16);
  894.     return OK;
  895.     }
  896. /***************************************************************************
  897. *
  898. * dec21x40MiiWrite - write to a PHY device register via MII
  899. *
  900. * RETURNS: OK, always
  901. */
  902. LOCAL STATUS dec21x40MiiWrite
  903.     (
  904.     DRV_CTRL    *pDrvCtrl,
  905.     UINT8       phyAdrs,                     /* PHY address to access */
  906.     UINT8       phyReg,                      /* PHY register to write */
  907.     UINT16      data                         /* Data to write */
  908.     )
  909.     {
  910.     /* write 34-bit preamble */
  911.     DEC_MII_WRITE (MII_PREAMBLE, 32);
  912.     DEC_MII_WRITE (MII_PREAMBLE, 2);
  913.     /* start of frame + op-code nibble */
  914.     DEC_MII_WRITE (MII_SOF | MII_WR, 4);
  915.     /* device address */
  916.     DEC_MII_WRITE (phyAdrs, 5);
  917.     DEC_MII_WRITE (phyReg, 5);
  918.     /* turn around */
  919.     DEC_MII_WTRISTATE;
  920.     /* write data */
  921.     DEC_MII_WRITE (data, 16);
  922.     return OK;
  923.     }
  924. /***************************************************************************
  925. *
  926. * dec21x40PhyFind - Find the first PHY connected to DEC MII port.
  927. *
  928. * RETURNS: Address of PHY or 0xFF if not found.
  929. */
  930. UINT8 dec21x40PhyFind
  931.     (
  932.     DRV_CTRL *pDrvCtrl
  933.     )
  934.     {
  935.     UINT16  miiData;
  936.     UINT8   phyAddr;
  937.     for (phyAddr = 0; phyAddr < (UINT8)DEC_MAX_PHY; phyAddr++) 
  938.         {
  939.          dec21x40MiiRead(pDrvCtrl, phyAddr, MII_PHY_ID0, &miiData);
  940.         /* Verify PHY address read */
  941.         if ((miiData != 0xFFFF) && (miiData != 0)) /* Found PHY */
  942.             {
  943.     DRV_LOG (DRV_DEBUG_LOAD, "PHY @ %#xn", phyAddr, 0,0,0,0,0);
  944.             return (phyAddr);
  945.             }
  946.         }
  947.     DRV_LOG (DRV_DEBUG_INIT, "No PHY foundn", 0,0,0,0,0,0);
  948.     return (0xFF);
  949.     }
  950. /***************************************************************************
  951. *
  952. * dec21140MediaSelect - select the current media
  953. *
  954. * RETURNS: OK, always
  955. */
  956. LOCAL STATUS dec21140MediaSelect
  957.     (
  958.     DRV_CTRL * pDrvCtrl,
  959.     UINT * pCsr6Val
  960.     )
  961.     {
  962.     UCHAR sromData[128];
  963.     UCHAR * pInfoLeaf0;
  964.     UCHAR * pInfoBlock;
  965.     UINT8 ix;
  966.     if (dec21140MediaInit (pDrvCtrl, sromData) == ERROR)
  967.         return (ERROR);
  968.     /* Get Info Leaf 0 */
  969.     pInfoLeaf0 = sromData + SROM_ILEAF0_OFFSET (sromData);
  970.     /* Get the current media */
  971.     if ((pDrvCtrl->mediaCurrent == 0) ||
  972.         (pDrvCtrl->mediaCurrent >= pDrvCtrl->mediaCount))
  973.         pDrvCtrl->mediaCurrent = pDrvCtrl->mediaCount - 1;
  974.     else
  975.         pDrvCtrl->mediaCurrent --;
  976.     /* Seek to the correct media Info Block */
  977.     pInfoBlock = ILEAF_INFO_BLK0( pInfoLeaf0);
  978.     for (ix=0; ix<pDrvCtrl->mediaCurrent; ix++)
  979.         {
  980.         if (IBLK_IS_COMPACT (pInfoBlock))
  981.             pInfoBlock += IBLK_COMPACT_SIZE;
  982.         else
  983.             pInfoBlock += IBLK_EXT_SIZE (pInfoBlock) + 1;
  984.         }
  985.     /* Convert ext0 into compact */
  986.     if (IBLK_IS_EXT0 (pInfoBlock))
  987.         pInfoBlock = IBLK_EXT0_TO_COMPACT (pInfoBlock);
  988.     /* Setup the GP port */
  989.     DEC_CSR_WRITE (CSR12, CSR12_21140_GPC | pDrvCtrl->gprModeVal);
  990.     DEC_NSDELAY (150);
  991.     
  992.     if (IBLK_IS_COMPACT (pInfoBlock))
  993.         {
  994.         USHORT compactCmd;
  995.         DRV_LOG ( DRV_DEBUG_LOAD,
  996.                   "COMPACT: mediaCode=0x%x gpData=0x%x command=0x%xn",
  997.                   IBLK_COMPACT_MCODE( pInfoBlock ),
  998.                   IBLK_COMPACT_GPDATA( pInfoBlock ),
  999.                   IBLK_COMPACT_CMD( pInfoBlock ), 0, 0, 0);
  1000.         /* Initialize the PHY interface */
  1001.         DEC_CSR_WRITE (CSR12, IBLK_COMPACT_GPDATA(pInfoBlock));
  1002.         DEC_NSDELAY(150);
  1003.         /* Get CSR6 settings */
  1004.         compactCmd = IBLK_COMPACT_CMD( pInfoBlock );
  1005.         if (compactCmd & COMPACT_CMD_SCR)
  1006.             *pCsr6Val |= CSR6_21140_SCR;
  1007.         if (compactCmd & COMPACT_CMD_PCS)
  1008.             *pCsr6Val |= CSR6_21140_PCS;
  1009.         if (compactCmd & COMPACT_CMD_PS)
  1010.             *pCsr6Val |= CSR6_21140_PS;
  1011.         }
  1012.     else
  1013.         {
  1014.         UCHAR * pGpStr;
  1015.         DRV_LOG (DRV_DEBUG_LOAD,
  1016.                  "EXT1: PHY#=0x%x InitLen=0x%x resetLen=0x%x n",
  1017.                  IBLK_EXT1_PHY(pInfoBlock),
  1018.                  IBLK_EXT1_INIT_LEN(pInfoBlock),
  1019.                  IBLK_EXT1_RESET_LEN(pInfoBlock), 0, 0, 0);
  1020.         DRV_LOG (DRV_DEBUG_LOAD,
  1021.                  "mediaCap=0x%x autoAd=0x%x FDMap=0x%x TTMmap=0x%xn",
  1022.                  IBLK_EXT1_MEDIA_CAP(pInfoBlock),
  1023.                  IBLK_EXT1_AUTO_AD(pInfoBlock),
  1024.                  IBLK_EXT1_FD_MAP(pInfoBlock),
  1025.                  IBLK_EXT1_TTM_MAP(pInfoBlock), 0, 0);
  1026.         /* Reset the media */
  1027.         pGpStr = IBLK_EXT1_RESET_STR (pInfoBlock);
  1028.         for (ix=IBLK_EXT1_RESET_LEN(pInfoBlock); ix; ix--, pGpStr++)
  1029.             DEC_CSR_WRITE (CSR12, *pGpStr);
  1030.         DEC_NSDELAY(150);
  1031. /* if there's an MII-compliant PHY */
  1032. if (IBLK_IS_EXT1 (pInfoBlock))
  1033.     {
  1034.     DRV_LOG (DRV_DEBUG_LOAD, "PHY compliant devicen",
  1035.        0,0,0,0,0,0);
  1036.     if (dec21x40MiiInit (pDrvCtrl, pCsr6Val, pInfoBlock) == ERROR)
  1037. return (ERROR);
  1038.     }
  1039.         }
  1040.     
  1041.     return (OK);
  1042.     }
  1043. /***************************************************************************
  1044. *
  1045. * dec21143MediaInit - Initialize media information
  1046. *
  1047. * This routine initializes media information for dec21143 chip.
  1048. *
  1049. * RETURNS: OK or ERROR
  1050. */
  1051.  
  1052. LOCAL STATUS dec21143MediaInit
  1053.     (
  1054.     DRV_CTRL *  pDrvCtrl,
  1055.     UCHAR *     pSromData
  1056.     )
  1057.     {
  1058.     USHORT *    pSromWord = (USHORT *)pSromData;
  1059.     UCHAR *     pInfoLeaf0;
  1060.     UCHAR       ix;
  1061.    
  1062.     /* read the serial ROM into pSromData */
  1063.  
  1064.     for (ix=0; ix < DEC21140_SROM_WORDS; ix++)
  1065.         *pSromWord++ = dec21140SromWordRead (pDrvCtrl, ix);
  1066.     /* Initialize the media summary */
  1067.  
  1068.     if (pDrvCtrl->mediaCount == 0xFF)
  1069.         {
  1070.         /* check version */
  1071.  
  1072.         if (SROM_VERSION( pSromData ) < DEC21140_SROM_VERSION_3)
  1073.     {
  1074.     DRV_LOG (DRV_DEBUG_LOAD,
  1075.  "dec21143MediaInit: incorrect SROM version %d (expected >= %d",
  1076.  SROM_VERSION (pSromData), DEC21140_SROM_VERSION_3, 0,0,0,0);
  1077.             return (ERROR);
  1078.     }
  1079.  
  1080.         /* get the leaf offset */
  1081.  
  1082.         pInfoLeaf0 = pSromData + SROM_ILEAF0_OFFSET(pSromData);
  1083.         pDrvCtrl->mediaCount = ILEAF_21143_MEDIA_COUNT(pInfoLeaf0);
  1084.         pDrvCtrl->mediaCurrent = 0xFF;
  1085.         pDrvCtrl->mediaDefault = 0xFF;
  1086.  
  1087.         DRV_LOG (DRV_DEBUG_LOAD, "mediaCount = %dn", 
  1088.                       pDrvCtrl->mediaCount, 0, 0, 0, 0, 0);
  1089.         }
  1090.     return (OK);
  1091.     }
  1092.  
  1093. /***************************************************************************
  1094. *
  1095. * dec21143MediaSelect - select the current media for dec21143
  1096. *
  1097. * This routine reads and sets up physical media with configuration
  1098. * information from a Version 3 DEC Serial ROM. Any other media configuration
  1099. * can be supported by initializing <_func_dec21x40MediaSelect>.
  1100. *
  1101. * RETURN: OK or ERROR
  1102. */
  1103. LOCAL STATUS dec21143MediaSelect
  1104.     (
  1105.     DRV_CTRL * pDrvCtrl,
  1106.     UINT * pCsr6Val
  1107.     )
  1108.     {
  1109.     UCHAR       sromData[128];
  1110.     UCHAR *     pInfoLeaf0;
  1111.     UCHAR *     pInfoBlock;
  1112.     UINT mediaCmd;
  1113.     UINT8       ix;
  1114.     UINT32 csr15Val;
  1115.     if (dec21143MediaInit (pDrvCtrl, sromData) == ERROR)
  1116.         return (ERROR);
  1117.  
  1118.     /* Get Info Leaf 0 */
  1119.  
  1120.     pInfoLeaf0 = sromData + SROM_ILEAF0_OFFSET (sromData);
  1121.  
  1122.     /* Get the current media */
  1123.  
  1124.     if ((pDrvCtrl->mediaCurrent == 0) ||
  1125.         (pDrvCtrl->mediaCurrent >= pDrvCtrl->mediaCount))
  1126.         pDrvCtrl->mediaCurrent = pDrvCtrl->mediaCount - 1;
  1127.     else
  1128.         pDrvCtrl->mediaCurrent --;
  1129.     DRV_LOG (DRV_DEBUG_LOAD, "dec21143MediaSelect trying %dn",
  1130.      pDrvCtrl->mediaCurrent, 0, 0, 0, 0, 0);
  1131.     /* Seek to the correct media Info Block */
  1132.  
  1133.     pInfoBlock = ILEAF_21143_INFO_BLK0( pInfoLeaf0);
  1134.     for (ix=0; ix < pDrvCtrl->mediaCurrent; ix++)
  1135.         pInfoBlock += IBLK_EXT_SIZE (pInfoBlock) + 1;
  1136.     if (IBLK_IS_EXT(pInfoBlock))
  1137. {
  1138.         switch (IBLK_EXT_TYPE(pInfoBlock))
  1139.             {
  1140.             case IBLK_IS_EXT2 :         /* Extended format block - type 2 */
  1141.         DEC_CSR_WRITE (CSR6, 0);
  1142. DEC_CSR_WRITE (CSR0, CSR0_SWR);
  1143. DEC_NSDELAY(150);
  1144. *pCsr6Val &= ~CSR6_21140_PS;
  1145.                 DRV_LOG ( DRV_DEBUG_LOAD, "EXT2: mediaCode=%#x EXT=%#xn",
  1146.                         IBLK_EXT2_MCODE(pInfoBlock),
  1147.                         IBLK_EXT2_EXT(pInfoBlock), 0, 0, 0, 0);
  1148.                 DRV_LOG ( DRV_DEBUG_LOAD, "GP Ctrl=%#x GP Data=%#xn",
  1149.                         IBLK_EXT2_GPC(pInfoBlock),
  1150.                         IBLK_EXT2_GPD(pInfoBlock), 0, 0, 0, 0);
  1151.                 /* get Media-specific data */
  1152.   
  1153.                 if (IBLK_EXT2_EXT(pInfoBlock))
  1154.                     {
  1155.                     DRV_LOG (DRV_DEBUG_LOAD, 
  1156.                         "CSR13=%#x CSR14=%#x CSR15=%#xn",
  1157.                              IBLK_EXT2_MSD_CSR13(pInfoBlock),
  1158.                              IBLK_EXT2_MSD_CSR14(pInfoBlock),
  1159.                              IBLK_EXT2_MSD_CSR15(pInfoBlock), 0, 0, 0);
  1160.   
  1161.   
  1162.                     DEC_CSR_WRITE (CSR15, (IBLK_EXT2_GPC(pInfoBlock) << 16) |
  1163.   IBLK_EXT2_MSD_CSR15(pInfoBlock));
  1164.                     DEC_CSR_WRITE (CSR15, (IBLK_EXT2_GPD(pInfoBlock) << 16) |
  1165.   IBLK_EXT2_MSD_CSR15(pInfoBlock));
  1166.                     DEC_CSR_WRITE (CSR14, IBLK_EXT2_MSD_CSR14(pInfoBlock));
  1167.                     DEC_CSR_WRITE (CSR13, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  1168.                     }
  1169.         else
  1170.     {
  1171.     /* setup the GP port */
  1172.     csr15Val = 0; /* OR'd into GPC/GPD values */
  1173.     DEC_CSR_WRITE (CSR13, 0);
  1174.     switch (IBLK_EXT2_MCODE(pInfoBlock))
  1175. {
  1176. case EXT2_MEDIA_10TP:
  1177.     DRV_LOG (DRV_DEBUG_LOAD, "EXT2: 10TPn",
  1178.                                        0,0,0,0,0,0);
  1179.                             DEC_CSR_WRITE (CSR14, CSR14_SPP | CSR14_APE |
  1180.                                            CSR14_LTE | CSR14_SQE | CSR14_CLD |
  1181.                                            CSR14_CSQ | CSR14_RSQ |
  1182.                                            CSR14_CPEN_HP |
  1183.                                            CSR14_CPEN_DM | CSR14_LSE |
  1184.                                            CSR14_DREN | CSR14_LBK | CSR14_ECEN);
  1185.                             DEC_CSR_WRITE (CSR13, CSR13_SRL_SIA);
  1186.                             break;
  1187.                         case EXT2_MEDIA_BNC:
  1188.                             DRV_LOG (DRV_DEBUG_LOAD, "EXT2: BNCn",0,0,0,0,0,0);
  1189.                             DEC_CSR_WRITE (CSR14, CSR14_ECEN | CSR14_DREN |
  1190.                                            CSR14_CLD | CSR14_CSQ | CSR14_RSQ);
  1191.                             DEC_CSR_WRITE (CSR13, CSR13_SRL_SIA | CSR13_AUI_TP);
  1192.                             break;
  1193.                         case EXT2_MEDIA_AUI:
  1194.                             DRV_LOG (DRV_DEBUG_LOAD, "EXT2: AUIn",0,0,0,0,0,0);
  1195.                             DEC_CSR_WRITE (CSR14, CSR14_ECEN | CSR14_DREN |
  1196.                                            CSR14_CLD | CSR14_CSQ | CSR14_RSQ);
  1197.                             csr15Val = CSR15_21143_ABM;
  1198.                             DEC_CSR_WRITE (CSR13, CSR13_SRL_SIA | CSR13_AUI_TP);
  1199.                             break;
  1200.                         case EXT2_MEDIA_10FD:
  1201.                             DRV_LOG (DRV_DEBUG_LOAD, "EXT2: 10FDn",
  1202.                                      0,0,0,0,0,0);
  1203.                             DEC_CSR_WRITE (CSR14, CSR14_SPP | CSR14_APE |
  1204.                                            CSR14_LTE | CSR14_SQE | CSR14_CLD |
  1205.                                            CSR14_CSQ | CSR14_RSQ |
  1206.                CSR14_CPEN_NC |
  1207.                                            CSR14_LSE | CSR14_DREN | CSR14_ECEN);
  1208.                             DEC_CSR_WRITE (CSR13, CSR13_SRL_SIA);
  1209.                             break;
  1210.                         default:
  1211.                             DRV_LOG (DRV_DEBUG_LOAD, "EXT2: UNKn",0,0,0,0,0,0);
  1212.                             break;
  1213. }
  1214.     DEC_CSR_WRITE (CSR15, (IBLK_EXT2_GPC(pInfoBlock) << 16) | 
  1215.   csr15Val);
  1216.     DEC_CSR_WRITE (CSR15, (IBLK_EXT2_GPD(pInfoBlock) << 16) |
  1217.   csr15Val);
  1218.     }
  1219. DEC_NSDELAY(150);
  1220.                 break;
  1221.             case IBLK_IS_EXT3 :         /* Extended format block - type 3 */
  1222.                 DRV_LOG (DRV_DEBUG_LOAD,
  1223.                         "EXT3: PHY#=%#x InitLen=%#x resetLen=%#x n",
  1224.                                 IBLK_EXT3_PHY(pInfoBlock),
  1225.                                 IBLK_EXT3_INIT_LEN(pInfoBlock),
  1226.                                 IBLK_EXT3_RESET_LEN(pInfoBlock), 0, 0, 0);
  1227.                 DRV_LOG (DRV_DEBUG_LOAD,
  1228.                         "mediaCap=%#x autoAd=%#x FDMap=%#x"
  1229.                         "TTMmap=%#x MIIci=%#xn",
  1230.                                 IBLK_EXT3_MEDIA_CAP(pInfoBlock),
  1231.                                 IBLK_EXT3_AUTO_AD(pInfoBlock),
  1232.                                 IBLK_EXT3_FD_MAP(pInfoBlock),
  1233.                                 IBLK_EXT3_TTM_MAP(pInfoBlock),
  1234.                                 IBLK_EXT3_MII_CI(pInfoBlock), 0);
  1235.  
  1236.         if (dec21x40MiiInit (pDrvCtrl, pCsr6Val, pInfoBlock) == ERROR)
  1237.     return (ERROR);
  1238.                 break;
  1239.             case IBLK_IS_EXT4 :         /* Extended format block - type 4 */
  1240.                 DRV_LOG ( DRV_DEBUG_LOAD, 
  1241.                         "EXT4: mediaCode=%#x GPCtrl=%#x GPData=%#x Cmd=%#xn",
  1242.                                 IBLK_EXT4_MCODE(pInfoBlock),
  1243.                                 IBLK_EXT4_GPC(pInfoBlock),
  1244.                                 IBLK_EXT4_GPD(pInfoBlock),
  1245.                                 IBLK_EXT4_CMD(pInfoBlock), 0, 0);
  1246.   
  1247.                 /* setup the GP port */
  1248.   
  1249.                 DEC_CSR_WRITE (CSR15, IBLK_EXT4_GPC(pInfoBlock) << 16);
  1250.                 DEC_CSR_WRITE (CSR15, IBLK_EXT4_GPD(pInfoBlock) << 16);
  1251.                 DEC_NSDELAY(150);
  1252.                 /* Get CSR6 settings */
  1253.   
  1254.                 mediaCmd = IBLK_EXT4_CMD(pInfoBlock);
  1255. /* *pCsr6Val = 0; */
  1256.   
  1257.                 if (mediaCmd & IBLK_EXT4_CMD_PS)
  1258.                     *pCsr6Val |= CSR6_21140_PS;
  1259.                 if (mediaCmd & IBLK_EXT4_CMD_TTM)
  1260.                     *pCsr6Val |= CSR6_21140_TTM;
  1261.                 if (mediaCmd & IBLK_EXT4_CMD_PCS)
  1262.                     *pCsr6Val |= CSR6_21140_PCS;
  1263.                 if (mediaCmd & IBLK_EXT4_CMD_SCR)
  1264.                     *pCsr6Val |= CSR6_21140_SCR;
  1265. if (IBLK_EXT4_MCODE(pInfoBlock) == 3)
  1266.     {
  1267.     /* Half duplex, 100BaseTx */
  1268.     *pCsr6Val &= ~(CSR6_FD);
  1269.     }
  1270. else if (IBLK_EXT4_MCODE(pInfoBlock) == 5)
  1271.     {
  1272.     /* Full duplex, 100BaseTx */
  1273.     *pCsr6Val |= CSR6_FD;
  1274.     }
  1275. else
  1276.     {
  1277.     DRV_LOG (DRV_DEBUG_INIT, "Unsupported media coden",
  1278.      0,0,0,0,0,0);
  1279.     }
  1280.                 break;
  1281.   
  1282.             case IBLK_IS_EXT5 :         /* Extended format block - type 5 */
  1283.   
  1284.                 DRV_LOG ( DRV_DEBUG_LOAD, "EXT5: Rst Seq length=%#xn",
  1285.                                 IBLK_EXT5_RESET_LEN(pInfoBlock), 0, 0, 0, 0, 0);
  1286.   
  1287.                 /* Reset the media */
  1288.   
  1289.                 /* not implemented */
  1290.   
  1291.                 break;
  1292.   
  1293.             default :
  1294.                 return (ERROR);
  1295.             }
  1296. }
  1297.     else
  1298. {
  1299.         return (ERROR);
  1300. }
  1301.     DRV_LOG (DRV_DEBUG_LOAD, "CSR6 = %#08xn", *pCsr6Val, 0,0,0,0,0);
  1302.     return (OK);
  1303.     }
  1304. /***************************************************************************
  1305. *
  1306. * dec21145SPIStart - Setup HomePNA SPI port 
  1307. *
  1308. * RETURNS: nothing 
  1309. */
  1310.  
  1311. LOCAL void dec21145SPIStart
  1312.     (
  1313.     DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */
  1314.     )
  1315.     {
  1316.     /* Clear SPI Chip Select to HomePNA Phy, and all other SPI bits */
  1317.     DEC_CSR_RESET (CSR9, CSR9_21145_SPI_MSK); 
  1318.     /* SPI Chip Select the HomePNA PHY, set output to zero */
  1319.     DEC_CSR_UPDATE (CSR9, CSR9_21145_SPI_CS); 
  1320.     }
  1321. /***************************************************************************
  1322. *
  1323. * dec21145SPIStop - Reset HomePNA SPI port 
  1324. *
  1325. * RETURNS: nothing 
  1326. */
  1327.  
  1328. LOCAL void dec21145SPIStop
  1329.     (
  1330.     DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */
  1331.     )
  1332.     {
  1333.     /* Clear SPI Chip Select to HomePNA Phy, and all other SPI bits */
  1334.     DEC_CSR_RESET (CSR9, CSR9_21145_SPI_MSK); 
  1335.     /* SPI Chip Select the HomePNA PHY, set output to zero */
  1336.     DEC_CSR_UPDATE (CSR9, CSR9_21145_SPI_CLK); 
  1337.     }   
  1338. /***************************************************************************
  1339. *
  1340. * dec21145SPIByteTransfer - transfer a byte over the HomePNA SPI port 
  1341. *
  1342. * This routine writes and, as a result also, reads a byte of data to/from
  1343. * the SPI port. This routine is generally used to write/read registers on the 
  1344. * HomePNA PHY. 
  1345. *
  1346. * RETURNS: byte value read from SPI port
  1347. */
  1348.  
  1349. LOCAL UCHAR dec21145SPIByteTransfer
  1350.     (
  1351.     DRV_CTRL *  pDrvCtrl,       /* pointer to DRV_CTRL structure */
  1352.     UCHAR   WriteData
  1353.     )
  1354.     {
  1355.     int i;
  1356.     UCHAR ReadData = 0;
  1357.     for (i=7; i>=0; i--)
  1358. {
  1359.         /* falling edge clock */
  1360. DEC_CSR_RESET (CSR9, CSR9_21145_SPI_CLK); 
  1361.         /* read data coming out of PHY */
  1362. if(DEC_CSR_READ(CSR9) & CSR9_21145_SPI_DO)
  1363.     ReadData |= (0x1<<i);
  1364.         if(WriteData & (0x1<<i))
  1365.     
  1366.             /* set Phy input to a ONE */
  1367.     
  1368.             DEC_CSR_UPDATE(CSR9, CSR9_21145_SPI_DI);
  1369. else
  1370.     
  1371.             /* set Phy input to a ZERO */
  1372.     
  1373.             DEC_CSR_RESET (CSR9, CSR9_21145_SPI_DI); 
  1374.   
  1375.         /* rising edge clock, write the Phy input out */
  1376. DEC_CSR_UPDATE(CSR9, CSR9_21145_SPI_CLK);
  1377. }
  1378.       return ReadData;
  1379.     }
  1380. #ifdef DRV_DEBUG
  1381. /***************************************************************************
  1382. *
  1383. * dec21145SPIReadBack - Read all PHY registers out 
  1384. *
  1385. * RETURNS: nothing 
  1386. */
  1387.  
  1388. void dec21145SPIReadBack
  1389.     (
  1390.     DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */
  1391.     )
  1392.     {
  1393.     int i;
  1394.     /* read back the PHY registers */
  1395.     for(i=0; i<0x20; i++) 
  1396. {
  1397. dec21145SPIStart(pDrvCtrl);
  1398. /* output HomePNA SPI read opcode */
  1399. dec21145SPIByteTransfer(pDrvCtrl, (UCHAR) PNA_SPI_OPCODE_READ);
  1400. /* output HomePNA Phy register index */
  1401. dec21145SPIByteTransfer(pDrvCtrl, i);
  1402. /* read HomePNA Phy register data */ 
  1403. DRV_LOG (DRV_DEBUG_LOAD, "Read PNA Phy Reg %x: %xn",
  1404.  i,dec21145SPIByteTransfer(pDrvCtrl,0x0),0,0,0,0);
  1405. dec21145SPIStop(pDrvCtrl);
  1406.     }
  1407. #endif /* DRV_DEBUG */
  1408. /***************************************************************************
  1409. *
  1410. * dec21145HomePNAInit - initialize the chip and PHY to use the HomePNA interface
  1411. *
  1412. * This routine initializes the chip and PHY to use the HomePNA interface.
  1413. *
  1414. * RETURNS: OK, or ERROR
  1415. */
  1416.  
  1417. LOCAL STATUS dec21145HomePNAInit
  1418.     (
  1419.     DRV_CTRL *  pDrvCtrl,       /* pointer to DRV_CTRL structure */
  1420.     UINT *    pCsr6Val
  1421.     )
  1422.     {
  1423.     int i = 0;
  1424.     int j = 0;
  1425.     int regValue;
  1426.     char  WriteableHRRegisters[]={0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 
  1427.                   0x0A, 0x0B, 0x10, 0x12, 0x13, 
  1428.           0x14, 0x15, 0x19, 0x1A, 0x1C, 0x1D, 
  1429.   0x1E, 0x1F, -1};
  1430.     if(pDrvCtrl->pHomePNAPhyInfo == NULL)
  1431. {
  1432. printf("HomePNAInit: No Ext7 PHY parameters found in SROMn");
  1433. exit(ERROR);
  1434. }
  1435.     else
  1436. {  
  1437. /* Get clocks going to the HomePNA Phy */
  1438. #if 0
  1439. /* hard code analog control values from datasheet */
  1440. DEC_CSR_WRITE(CSR13, (0x708a<<16) | CSR13_AUI_TP
  1441.       | CSR13_SRL_SIA);
  1442. #endif
  1443.         /* use analog control values from srom */
  1444. DEC_CSR_WRITE(CSR13, ((pDrvCtrl->pHomePNAPhyInfo->sp_csr13)<<16) | 
  1445.       CSR13_AUI_TP);
  1446. /* make sure the Phy is not going to be powered down */
  1447. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] &=
  1448.         ~PHA_PHY_CTRL_LOW_PDN;
  1449. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1]= 1;
  1450.         /* force the HomePNA speed if user flags are set */
  1451. if(pDrvCtrl->usrFlags & DEC_USR_HPNA_FORCE_SLOW)
  1452.     {
  1453.     /* force slow speed mode - 0.7 MB/sec */
  1454.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] &=
  1455.  ~PHA_PHY_CTRL_LOW_HS;
  1456.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1]= 1;
  1457.     }
  1458. else if (pDrvCtrl->usrFlags & DEC_USR_HPNA_FORCE_FAST)
  1459.     {
  1460.     /* force high speed mode  - 1 MB/sec */
  1461.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] |=
  1462.    PHA_PHY_CTRL_LOW_HS;
  1463.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1]= 1;
  1464.     }
  1465.         /* force the HomePNA power if user flags are set */
  1466. if(pDrvCtrl->usrFlags & DEC_USR_HPNA_FORCE_LOW_PWR)
  1467.     {
  1468.     /* force low power mode */
  1469.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] &=
  1470. ~PHA_PHY_CTRL_LOW_HP;
  1471.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1]= 1;
  1472.     }
  1473. else if (pDrvCtrl->usrFlags & DEC_USR_HPNA_FORCE_HI_PWR)
  1474.     {
  1475.     /* force high power mode */
  1476.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] |=
  1477.   PHA_PHY_CTRL_LOW_HP;
  1478.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1]= 1;
  1479.     }
  1480.         /* ZERO out CSR9!! This must happen or we wont be able to talk SPI */
  1481.         DEC_CSR_WRITE (CSR9, 0); 
  1482. /* output HomePNA SPI latch write enable opcode */
  1483. dec21145SPIStart(pDrvCtrl);
  1484. dec21145SPIByteTransfer(pDrvCtrl, (UCHAR) PNA_SPI_OPCODE_SET_WE);
  1485. dec21145SPIStop(pDrvCtrl);
  1486. /* initialize the PHY registers */
  1487. for(i=0,j=0; (j != -1) && (j<0x20); j=WriteableHRRegisters[i++] ) 
  1488.     {
  1489.     if(j != -1)
  1490. {
  1491. DRV_LOG(DRV_DEBUG_LOAD, "phy reg %x: %x updated %xrn", 
  1492.         j, pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[j][0],
  1493. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[j][1], 4,5,6); 
  1494.         /* did we need to update it? */
  1495. if( pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[j][1] == 1)
  1496.     {
  1497.     /* output HomePNA SPI write opcode */
  1498.     dec21145SPIStart(pDrvCtrl);
  1499.     dec21145SPIByteTransfer(pDrvCtrl,
  1500.                                             (UCHAR) PNA_SPI_OPCODE_WRITE);
  1501.     /* output HomePNA Phy register index */
  1502.     dec21145SPIByteTransfer(pDrvCtrl, j);
  1503.     /* output HomePNA Phy register data */
  1504.     regValue = pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[j][0];
  1505.     DRV_LOG(DRV_DEBUG_LOAD, "Writing reg %x: %xrn", 
  1506.     j, regValue,3,4,5,6);        
  1507.     dec21145SPIByteTransfer(pDrvCtrl, regValue); 
  1508.     dec21145SPIStop(pDrvCtrl);
  1509.     }
  1510. }
  1511.     } 
  1512. #ifdef DRV_DEBUG
  1513. dec21145SPIReadBack(pDrvCtrl);
  1514. #endif
  1515. /* output HomePNA SPI latch clear write enable opcode */
  1516. dec21145SPIStart(pDrvCtrl);
  1517. dec21145SPIByteTransfer(pDrvCtrl, (UCHAR) PNA_SPI_OPCODE_CLEAR_WE);
  1518. dec21145SPIStop(pDrvCtrl);
  1519. }
  1520.           /* reset the SIA  and wait 5ms */
  1521.   DEC_CSR_WRITE(CSR13, ((pDrvCtrl->pHomePNAPhyInfo->sp_csr13)<<16) | 
  1522. CSR13_SRL_SIA );
  1523.   taskDelay((sysClkRateGet() / 200) + 2); 
  1524.          /* enable collison detect, receive squelch, decoder/encoder */
  1525.   DEC_CSR_WRITE(CSR14, CSR14_CLD | CSR14_RSQ | CSR14_DREN | CSR14_ECEN);
  1526.   /* enable 10-BT autonegotitation when the usr flag is set */
  1527.   if(pDrvCtrl->usrFlags & DEC_USR_HPNA_PREFER_10BT)
  1528.     DEC_CSR_UPDATE(CSR14,  CSR14_21143_TAS | CSR14_SPP | CSR14_APE |
  1529.                            CSR14_LTE | CSR14_21143_ANE | CSR14_CPEN_NC |
  1530.                            CSR14_LSE | CSR14_21143_TH );
  1531.   /* disable receive watchdog, and jabber timer*/
  1532.   DEC_CSR_WRITE(CSR15, CSR15_21143_RWD | CSR15_JBD);
  1533.   DEC_CSR_WRITE(CSR13, ((pDrvCtrl->pHomePNAPhyInfo->sp_csr13)<<16) | 
  1534.  CSR13_AUI_TP | CSR13_SRL_SIA);
  1535.       return (OK);
  1536.     }
  1537. /***************************************************************************
  1538. *
  1539. * dec21145DecodeExt7InfoBlock - Decode and load HomePNA Phy defaults from SROM
  1540. *
  1541. * This routine decodes an EXT7 record from the SROM containing the
  1542. * HomePNA PHY register defaults. This routine load up the pHomePNAPhyInfo
  1543. * structure with the values it finds in the SROM.
  1544. *
  1545. * RETURNS: OK or ERROR if decoding fails
  1546. */
  1547.  
  1548. LOCAL STATUS dec21145DecodeExt7InfoBlock
  1549.     (
  1550.     DRV_CTRL *  pDrvCtrl,
  1551.     UCHAR *     pInfoBlock    /* ptr to infoBlock */
  1552.     )
  1553.     {
  1554.     UCHAR       iy;
  1555.     UCHAR       tmpExt7ExtraIndex;
  1556.     UCHAR       tmpExt7ExtraData;
  1557.     /* assume decode failure */
  1558.     pDrvCtrl->homePNAPhyValuesFound = FALSE;
  1559.     if(IBLK_EXT_TYPE(pInfoBlock) == 0x07)
  1560.         {
  1561. /* get memory for the HomePNAphyInfo structure */
  1562. if ((pDrvCtrl->pHomePNAPhyInfo = 
  1563.      calloc (sizeof (HOMEPNA_PHY_INFO), 1)) == NULL)
  1564.     return(ERROR);
  1565. pDrvCtrl->pHomePNAPhyInfo->sp_csr13 = 
  1566.        IBLK_EXT7_ANALOG_CTRL(pInfoBlock);
  1567. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: analog_ctrl 0x%xn",
  1568.   IBLK_EXT7_ANALOG_CTRL(pInfoBlock),2,3,4,5,6);
  1569. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][0] = 
  1570.        IBLK_EXT7_CTRL_LOW(pInfoBlock);
  1571. /* flag this register for update in the phy init */
  1572. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_LOW][1] = 1; 
  1573. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: ctrl_low 0x%xn",
  1574.   IBLK_EXT7_CTRL_LOW(pInfoBlock),2,3,4,5,6);
  1575. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_HI][0] = 
  1576.   IBLK_EXT7_CTRL_HI(pInfoBlock);
  1577. /* flag this register for update in the phy init */
  1578. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_CTRL_HI][1] =1; 
  1579. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: ctrl_hi 0x%xn",
  1580.   IBLK_EXT7_CTRL_HI(pInfoBlock),2,3,4,5,6);
  1581. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NOISE][0] = 
  1582.   IBLK_EXT7_NOISE(pInfoBlock);
  1583. /* flag this register for update in the phy init */
  1584. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NOISE][1] = 1;
  1585. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: noise 0x%xn",
  1586.   IBLK_EXT7_NOISE(pInfoBlock),2,3,4,5,6);
  1587. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_FLOOR][0] = 
  1588.   IBLK_EXT7_NSE_FLOOR(pInfoBlock);
  1589. /* flag this register for update in the phy init */
  1590. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_FLOOR][1] = 1;
  1591. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: floor 0x%xn",
  1592.   IBLK_EXT7_NSE_FLOOR(pInfoBlock),2,3,4,5,6);
  1593. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_CEILING][0] = 
  1594.   IBLK_EXT7_NSE_CEILING(pInfoBlock);
  1595. /* flag this register for update in the phy init */
  1596. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_CEILING][1] =1; 
  1597. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: ceiling 0x%xn",
  1598.   IBLK_EXT7_NSE_CEILING(pInfoBlock),2,3,4,5,6);
  1599. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_ATTACK][0] = 
  1600.   IBLK_EXT7_NSE_ATTACK(pInfoBlock);
  1601. /* flag this register for update in the phy init */
  1602. pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs[PNA_PHY_NSE_ATTACK][1] =1; 
  1603. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7: attack 0x%xn",
  1604.   IBLK_EXT7_NSE_ATTACK(pInfoBlock),2,3,4,5,6);
  1605. if( IBLK_EXT_SIZE(pInfoBlock) > 11) 
  1606.     /* additional fields */
  1607.     {
  1608.     if((IBLK_EXT_SIZE(pInfoBlock) & 0x1) != 0x1)
  1609.         {
  1610. for(iy=10; iy < IBLK_EXT_SIZE(pInfoBlock); iy += 2)
  1611.     {
  1612.     tmpExt7ExtraIndex = 
  1613.       IBLK_EXT7_EXTRA_INDEX(pInfoBlock + iy); 
  1614.     tmpExt7ExtraData = 
  1615.       IBLK_EXT7_EXTRA_DATA(pInfoBlock + iy); 
  1616.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs [tmpExt7ExtraIndex][0]=
  1617.       tmpExt7ExtraData; 
  1618.     /* flag this register for update in the phy init */
  1619.     pDrvCtrl->pHomePNAPhyInfo->pna_phy_regs [tmpExt7ExtraIndex][1]=1;
  1620.     DRV_LOG ( DRV_DEBUG_LOAD, 
  1621.       "EXT7: Extra index 0x%x data 0x%xn",
  1622.       tmpExt7ExtraIndex, tmpExt7ExtraData,3,4,5,6);
  1623.     }
  1624.         }
  1625.     else
  1626.         {
  1627. DRV_LOG( DRV_DEBUG_LOAD, "Invalid SROM Ext7 formatn",
  1628.  1,2,3,4,5,6);
  1629. return (ERROR);
  1630.         }
  1631.     }
  1632. /* we decoded everything ok! */
  1633. pDrvCtrl->homePNAPhyValuesFound = TRUE;
  1634.         }
  1635.     else
  1636.         {
  1637. /* no EXT7 type found */
  1638. DRV_LOG( DRV_DEBUG_LOAD, "Not an Ext7 Info Blockn",
  1639.  1,2,3,4,5,6);
  1640. return(ERROR);
  1641.         }
  1642.     return (OK);
  1643.     }
  1644.  
  1645. /***************************************************************************
  1646. *
  1647. * dec21145FindHomePNAPhyValues - find HomePNA Phy defaults from SROM
  1648. *
  1649. * This routine searches the SROM for HomePNA defaults.
  1650. * HomePNA PHY register defaults. This routine load up the pHomePNAPhyInfo
  1651. * structure with the values it finds in the SROM.
  1652. *
  1653. * RETURNS: OK or ERROR if decoding fails
  1654. */
  1655.  
  1656. LOCAL STATUS dec21145FindHomePNAPhyValues
  1657.     (
  1658.     DRV_CTRL *  pDrvCtrl,
  1659.     UCHAR *     infoBlockPtrs[]    /* array of ptr to infoBlocks */
  1660.     )
  1661.     {
  1662.     UCHAR       ix;
  1663.     for(ix=0; ix< pDrvCtrl->mediaCount; ix++)
  1664.       {
  1665. if(IBLK_EXT_TYPE(infoBlockPtrs[ix]) == 0x07)
  1666.   {
  1667.     dec21145DecodeExt7InfoBlock(pDrvCtrl, infoBlockPtrs[ix]);
  1668.     /* keep searching until we found some good values */
  1669.     if(pDrvCtrl->homePNAPhyValuesFound == TRUE)
  1670.       return (OK);
  1671.   }
  1672.       }
  1673.     return (ERROR);
  1674.     }
  1675. /***************************************************************************
  1676. *
  1677. * dec21145MediaInit - Initialize media information
  1678. *
  1679. * This routine initializes media information for dec21145 chip.
  1680. *
  1681. * RETURNS: OK or ERROR
  1682. */
  1683.  
  1684. LOCAL STATUS dec21145MediaInit
  1685.     (
  1686.     DRV_CTRL *  pDrvCtrl,
  1687.     UCHAR *     pSromData
  1688.     )
  1689.     {
  1690.     USHORT *    pSromWord = (USHORT *)pSromData;
  1691.     UCHAR *     pInfoLeaf0;
  1692.     UCHAR       ix;
  1693.    
  1694.     DRV_LOG (DRV_DEBUG_LOAD, "dec21145MediaInitn", 
  1695.      pDrvCtrl->mediaCount, 0, 0, 0, 0, 0);
  1696.     /* read the serial ROM into pSromData */
  1697.  
  1698.     for (ix=0; ix < DEC21140_SROM_WORDS; ix++)
  1699.         *pSromWord++ = dec21140SromWordRead (pDrvCtrl, ix);
  1700.     /* Initialize the media summary */
  1701.  
  1702.     if (pDrvCtrl->mediaCount == 0xFF)
  1703.       {
  1704.         /* check version */
  1705.         if (SROM_VERSION( pSromData ) < DEC21140_SROM_VERSION_4)
  1706.   {
  1707.     DRV_LOG (DRV_DEBUG_LOAD, 
  1708.      "dec21145MediaInit: unsupport SROM versionn", 
  1709.      pDrvCtrl->mediaCount, 0, 0, 0, 0, 0);
  1710.             return (ERROR);
  1711.   }
  1712.         /* get the leaf offset */
  1713.         pInfoLeaf0 = pSromData + SROM_ILEAF0_OFFSET(pSromData);
  1714.         pDrvCtrl->mediaCount = ILEAF_21145_MEDIA_COUNT(pInfoLeaf0);
  1715.         pDrvCtrl->mediaCurrent = 0xFF;
  1716.         pDrvCtrl->mediaDefault = 0xFF;
  1717.         DRV_LOG (DRV_DEBUG_LOAD, "mediaCount = %dn", 
  1718.  pDrvCtrl->mediaCount, 0, 0, 0, 0, 0);
  1719.       }
  1720.     return (OK);
  1721.     }
  1722.  
  1723. /***************************************************************************
  1724. *
  1725. * dec21145MediaSelect - select the current media for dec21143
  1726. *
  1727. * This routine reads and sets up physical media with configuration
  1728. * information from a Version 4 Intel/DEC Serial ROM. Any other
  1729. * media configuration can be supported by initializing
  1730. * <_func_dec21x40MediaSelect>.
  1731. *
  1732. * RETURN: OK or ERROR
  1733. */
  1734. LOCAL STATUS dec21145MediaSelect
  1735.     (
  1736.     DRV_CTRL *        pDrvCtrl,
  1737.     UINT *    pCsr6Val
  1738.     )
  1739.     {
  1740.     UCHAR       sromData[128];
  1741.     UCHAR *     pInfoLeaf0;
  1742.     UCHAR *     pInfoBlock;
  1743.     UINT        mediaCmd;
  1744.     UCHAR *     infoBlockPtrs[10];   
  1745.     BOOL        mediaOK;
  1746.     int         ix;
  1747.     pDrvCtrl->pHomePNAPhyInfo = NULL;
  1748.     mediaOK = FALSE;
  1749.     DRV_LOG (DRV_DEBUG_LOAD, " dec21145MediaSelectn", 0, 0, 0, 0, 0, 0);
  1750.     if (dec21145MediaInit (pDrvCtrl, sromData) == ERROR)
  1751.         return (ERROR);
  1752.  
  1753.     /* Get Info Leaf 0 */
  1754.  
  1755.     pInfoLeaf0 = sromData + SROM_ILEAF0_OFFSET (sromData);
  1756.  
  1757.     /* Get the current media */
  1758.  
  1759.     if ((pDrvCtrl->mediaCurrent == 0) ||
  1760.         (pDrvCtrl->mediaCurrent >= pDrvCtrl->mediaCount))
  1761.         pDrvCtrl->mediaCurrent = pDrvCtrl->mediaCount - 1;
  1762.     else
  1763.         pDrvCtrl->mediaCurrent --;
  1764.  
  1765.  
  1766.     pInfoBlock = ILEAF_21145_INFO_BLK0( pInfoLeaf0);
  1767.     infoBlockPtrs[0] = pInfoBlock;
  1768.     for (ix=0; ix < pDrvCtrl->mediaCurrent; ix++)
  1769.       {
  1770.         pInfoBlock += IBLK_EXT_SIZE (pInfoBlock) + 1;
  1771. infoBlockPtrs[ix+1] = pInfoBlock;
  1772.       }
  1773.     /* Media fallback loop */
  1774.     do
  1775.     {
  1776.     DRV_LOG (DRV_DEBUG_LOAD, " dec21145MediaSelect media current %dn", 
  1777.      pDrvCtrl->mediaCurrent, 0, 0, 0, 0, 0);
  1778.     pInfoBlock = infoBlockPtrs[pDrvCtrl->mediaCurrent];
  1779.     if (IBLK_IS_EXT(pInfoBlock))
  1780. {
  1781. DRV_LOG (DRV_DEBUG_LOAD, " dec21145MediaSelect media is EXTn", 
  1782.          0, 0, 0, 0, 0, 0);
  1783. /* Seek to the correct media Info Block */
  1784. switch (IBLK_EXT_TYPE(pInfoBlock))
  1785.     {
  1786.     case IBLK_IS_EXT2 :         /* Extended format block - type 2 */
  1787. DRV_LOG ( DRV_DEBUG_LOAD, "EXT2: mediaCode=%#x EXT=%#xn",
  1788.   IBLK_EXT2_MCODE(pInfoBlock),
  1789.   IBLK_EXT2_EXT(pInfoBlock), 0, 0, 0, 0);
  1790. /* make sure we use 10BASE-T/HomePNA port */
  1791. *pCsr6Val &= ~CSR6_21140_PS;
  1792. /* get Media-specific data */
  1793. if (IBLK_EXT2_EXT(pInfoBlock))
  1794.     {
  1795.     DRV_LOG (DRV_DEBUG_LOAD, 
  1796.      "CSR13=%#x CSR14=%#x CSR15=%#xn",
  1797.      IBLK_EXT2_MSD_CSR13(pInfoBlock),
  1798.      IBLK_EXT2_MSD_CSR13(pInfoBlock),
  1799.      IBLK_EXT2_MSD_CSR13(pInfoBlock), 0, 0, 0);
  1800.             DEC_CSR_WRITE (CSR13, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  1801.     DEC_CSR_WRITE (CSR14, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  1802.     DEC_CSR_WRITE (CSR15, IBLK_EXT2_MSD_CSR13(pInfoBlock));
  1803.     }
  1804. /* setup the GP port */
  1805. DRV_LOG ( DRV_DEBUG_LOAD, "GP Ctrl=%#x GP Data=%#xn",
  1806.   IBLK_EXT2_GPC(pInfoBlock),
  1807.   IBLK_EXT2_GPD(pInfoBlock), 0, 0, 0, 0);
  1808. DEC_CSR_UPDATE(CSR15, IBLK_EXT2_GPC(pInfoBlock) << 8);
  1809. DEC_CSR_UPDATE(CSR15, IBLK_EXT2_GPD(pInfoBlock) << 8);
  1810. DEC_NSDELAY(500);
  1811. /* see if we want to setup for HomePNA */
  1812. switch (IBLK_EXT2_MCODE(pInfoBlock))
  1813.     {
  1814.     case EXT2_MEDIA_10TP:
  1815.         DRV_LOG ( DRV_DEBUG_LOAD, "EXT2: Media 10Base-Tn",
  1816.           1,2,3,4,5,6);   
  1817.         /* enable collison detect, receive squelch, decoder/encoder */
  1818.         DEC_CSR_WRITE(CSR14, CSR14_CLD | CSR14_RSQ |
  1819.                                       CSR14_DREN | CSR14_ECEN);
  1820.         DEC_CSR_UPDATE(CSR14,  CSR14_21143_TAS | CSR14_SPP |
  1821.                                        CSR14_APE | CSR14_LTE | CSR14_SQE |
  1822.                                        CSR14_21143_ANE | CSR14_CPEN_NC |
  1823.                                        CSR14_LSE | CSR14_21143_TH ); 
  1824.         /* disable receive watchdog, and jabber timer*/
  1825.         DEC_CSR_WRITE(CSR15, 0);
  1826.         DEC_CSR_WRITE(CSR13,
  1827.                                       ((pDrvCtrl->pHomePNAPhyInfo->sp_csr13)
  1828.                                         <<16) |
  1829.       CSR13_SRL_SIA);
  1830.         *pCsr6Val &= ~CSR6_FD;
  1831.         mediaOK = TRUE;
  1832.         /* if we fail, go back to the higher priority link */
  1833.         pDrvCtrl->mediaCurrent = 0xff;
  1834.         break;
  1835.     case EXT2_MEDIA_10FD:                  
  1836.         DRV_LOG (DRV_DEBUG_LOAD,
  1837.                                  "EXT2: Media 10Base-T Full Duplexn",
  1838.          1,2,3,4,5,6);         
  1839.         /*
  1840.                          * enable collison detect, receive squelch,
  1841.                          * decoder/encoder
  1842.                          */
  1843.         DEC_CSR_WRITE(CSR14, CSR14_CLD | CSR14_RSQ |
  1844.                                       CSR14_DREN | CSR14_ECEN);
  1845.         DEC_CSR_UPDATE(CSR14,  CSR14_21143_TAS | CSR14_SPP |
  1846.                                        CSR14_APE | CSR14_LTE | CSR14_SQE |
  1847.                                        CSR14_21143_ANE | CSR14_CPEN_NC |
  1848.                                        CSR14_LSE | CSR14_21143_TH ); 
  1849.         /* disable receive watchdog, and jabber timer*/
  1850.         DEC_CSR_WRITE(CSR15, 0);
  1851.         DEC_CSR_WRITE(CSR13,
  1852.                                       ((pDrvCtrl->pHomePNAPhyInfo->sp_csr13)
  1853.                                         <<16) | 
  1854.       CSR13_SRL_SIA);
  1855.         *pCsr6Val |= CSR6_FD;
  1856.         mediaOK = TRUE;
  1857.         /* if we fail, go back to the higher priority link */
  1858.         pDrvCtrl->mediaCurrent = 0xff;
  1859.         break;
  1860.     case EXT2_MEDIA_HOMEPNA:
  1861.         DRV_LOG ( DRV_DEBUG_LOAD, "EXT2: Media HomePNAn",
  1862.           1,2,3,4,5,6);
  1863.         /*
  1864.                          * HomePNA operates at half duplex and
  1865.                          * Heartbeat disabled
  1866.                          */
  1867.         *pCsr6Val &= ~CSR6_FD;
  1868.         *pCsr6Val |= CSR6_21140_HBD;
  1869.         /* set TX treshold */
  1870.         *pCsr6Val |= CSR6_THR_096;
  1871.         /*
  1872.                          * see if we can find PNA PHY values in SROM 
  1873.                          * as type EXT7
  1874.                          */
  1875.         if(pDrvCtrl->homePNAPhyValuesFound == FALSE)
  1876.             {
  1877.     if(dec21145FindHomePNAPhyValues(pDrvCtrl, 
  1878. infoBlockPtrs ) 
  1879.        == ERROR)
  1880.         {
  1881.         DRV_LOG ( DRV_DEBUG_LOAD, 
  1882.          "EXT2: Media HomePNA No Phy Values" 
  1883.                                          "Foundn",
  1884.          1,2,3,4,5,6);
  1885.         /* 
  1886.                                  * attach BSP hook here to provide 
  1887.                                  * PNA PHY defaults
  1888.                                  */
  1889.         return(ERROR);
  1890.         }
  1891.             }
  1892.         if(dec21145HomePNAInit ( pDrvCtrl, pCsr6Val) == ERROR)
  1893.             return (ERROR);
  1894.         /* we have determined this is the media we are using */
  1895.         mediaOK = TRUE;
  1896.         break;
  1897.   }
  1898. break;
  1899.     case IBLK_IS_EXT3 :         /* Extended format block - type 3 */
  1900. DRV_LOG (DRV_DEBUG_LOAD,
  1901.  "EXT3: PHY#=%#x InitLen=%#x resetLen=%#x n",
  1902.  IBLK_EXT3_PHY(pInfoBlock),
  1903.  IBLK_EXT3_INIT_LEN(pInfoBlock),
  1904.  IBLK_EXT3_RESET_LEN(pInfoBlock), 0, 0, 0);
  1905. DRV_LOG (DRV_DEBUG_LOAD,
  1906.  "mediaCap=%#x autoAd=%#x FDMap=%#x"
  1907.                          "TTMmap=%#x MIIci=%#xn",
  1908.  IBLK_EXT3_MEDIA_CAP(pInfoBlock),
  1909.  IBLK_EXT3_AUTO_AD(pInfoBlock),
  1910.  IBLK_EXT3_FD_MAP(pInfoBlock),
  1911.  IBLK_EXT3_TTM_MAP(pInfoBlock),
  1912.  IBLK_EXT3_MII_CI(pInfoBlock), 0);
  1913. if (dec21x40MiiInit (pDrvCtrl, pCsr6Val, pInfoBlock) == ERROR)
  1914.     return (ERROR);
  1915. break;
  1916.     case IBLK_IS_EXT4 :         /* Extended format block - type 4 */
  1917. DRV_LOG (DRV_DEBUG_LOAD, 
  1918.  "EXT4: mediaCode=%#x GPCtrl=%#x GPData=%#x Cmd=%#xn",
  1919.  IBLK_EXT4_MCODE(pInfoBlock),
  1920.  IBLK_EXT4_GPC(pInfoBlock),
  1921.  IBLK_EXT4_GPD(pInfoBlock),
  1922.  IBLK_EXT4_CMD(pInfoBlock), 0, 0);
  1923. /* setup the GP port */
  1924. DEC_CSR_UPDATE (CSR15, IBLK_EXT4_GPC(pInfoBlock) << 8);
  1925. DEC_CSR_UPDATE (CSR15, IBLK_EXT4_GPD(pInfoBlock) << 8);
  1926. DEC_NSDELAY(150);
  1927. /* Get CSR6 settings */
  1928. mediaCmd = IBLK_EXT4_CMD(pInfoBlock);
  1929. if (mediaCmd & IBLK_EXT4_CMD_PS)
  1930.     *pCsr6Val |= CSR6_21140_PS;
  1931. if (mediaCmd & IBLK_EXT4_CMD_TTM)
  1932.     *pCsr6Val |= CSR6_21140_TTM;
  1933. if (mediaCmd & IBLK_EXT4_CMD_PCS)
  1934.     *pCsr6Val |= CSR6_21140_PCS;
  1935. if (mediaCmd & IBLK_EXT4_CMD_SCR)
  1936.     *pCsr6Val |= CSR6_21140_SCR;
  1937. break;
  1938.     case IBLK_IS_EXT5 :         /* Extended format block - type 5 */
  1939. DRV_LOG ( DRV_DEBUG_LOAD, "EXT5: Rst Seq length=%#xn",
  1940.   IBLK_EXT5_RESET_LEN(pInfoBlock), 0, 0, 0, 0, 0);
  1941. /* Reset the media */
  1942. /* not implemented */
  1943. pDrvCtrl->mediaCurrent--;
  1944. break;
  1945.     case IBLK_IS_EXT7 :          /* Extended format block - type 7 */
  1946. DRV_LOG ( DRV_DEBUG_LOAD, "EXT7:n", 0, 0, 0, 0, 0, 0);
  1947. if( dec21145DecodeExt7InfoBlock(pDrvCtrl, pInfoBlock) == ERROR)
  1948.     {
  1949.     DRV_LOG ( DRV_DEBUG_LOAD, 
  1950.       "dec21145DecodeExt7InfoBlock return ERRORn", 
  1951.       0, 0, 0, 0, 0, 0);
  1952.     return (ERROR);
  1953.     }
  1954. pDrvCtrl->mediaCurrent--;
  1955. mediaOK = FALSE;
  1956. break;
  1957.     default :
  1958. DRV_LOG ( DRV_DEBUG_LOAD, "Unknown EXT SROM Type %dn",
  1959.   IBLK_EXT_TYPE(pInfoBlock), 0, 0, 0, 0, 0);
  1960. return (ERROR);
  1961. break;
  1962.     }
  1963.         }
  1964.         else
  1965.     {
  1966.     DRV_LOG ( DRV_DEBUG_LOAD, 
  1967.       "No EXT types found in SROM:n", 0, 0, 0, 0, 0, 0);
  1968.     return (ERROR);
  1969.     }
  1970.         } while (mediaOK == FALSE);
  1971.     return (OK);
  1972.     }
  1973. /***************************************************************************
  1974. *
  1975. * dec21x40MiiInit - initialize the chip to use the MII interface
  1976. *
  1977. * This routine initializes the chip to use the MII interface.
  1978. *
  1979. * RETURNS: OK, or ERROR
  1980. */
  1981.  
  1982. LOCAL STATUS dec21x40MiiInit
  1983.     (
  1984.     DRV_CTRL *  pDrvCtrl,       /* pointer to DRV_CTRL structure */
  1985.     UINT *      pCsr6Val, /* pointer to location for new CSR6 value */
  1986.     UCHAR * pInfoBlock /* SROM info block for this MII leaf */
  1987.     )
  1988.     {
  1989.     /* initialize some fields in the PHY info structure */
  1990.     if (dec21x40PhyPreInit (pDrvCtrl, pInfoBlock) != OK)
  1991. {
  1992. DRV_LOG (DRV_DEBUG_LOAD, ("Failed to pre-initialize PHYn"),
  1993.   0, 0, 0, 0, 0, 0);
  1994. return (ERROR);
  1995. }
  1996.     if (miiPhyInit (pDrvCtrl->pPhyInfo) != OK)
  1997.         {
  1998. DRV_LOG (DRV_DEBUG_LOAD, "Failed to initialise PHYn", 0,0,0,0,0,0);
  1999. return (ERROR);
  2000.         }
  2001.     *pCsr6Val |= (CSR6_21140_HBD | CSR6_21140_PS);
  2002.     /* deal with full duplex mode and speed */
  2003.     if (pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_FD)
  2004. {
  2005. *pCsr6Val |= CSR6_FD;
  2006. DRV_LOG (DRV_DEBUG_LOAD, "In full duplex moden", 0,0,0,0,0,0);
  2007. }
  2008.     else
  2009. {
  2010. DRV_LOG (DRV_DEBUG_LOAD, "In half duplex moden", 0,0,0,0,0,0);
  2011. }
  2012.     if (pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_100)
  2013. {
  2014. *pCsr6Val &= ~CSR6_21140_TTM;
  2015. DRV_LOG (DRV_DEBUG_LOAD, "In 100Mbps moden", 0,0,0,0,0,0);
  2016. }
  2017.     else
  2018. {
  2019. *pCsr6Val |= CSR6_21140_TTM;
  2020. DRV_LOG (DRV_DEBUG_LOAD, "In 10Mbps moden", 0,0,0,0,0,0);
  2021. }
  2022.     return (OK);
  2023.     }
  2024. /***************************************************************************
  2025. *
  2026. * dec21x40PhyPreInit - initialize some fields in the phy info structure
  2027. *
  2028. * This routine initializes some fields in the phy info structure,
  2029. * for use of the phyInit() routine.
  2030. *
  2031. * RETURNS: OK, or ERROR if could not obtain memory.
  2032. */
  2033.  
  2034. LOCAL STATUS dec21x40PhyPreInit
  2035.     (
  2036.     DRV_CTRL *  pDrvCtrl, /* pointer to DRV_CTRL structure */
  2037.     UCHAR * pInfoBlock /* pointer to SROM info block for this leaf */
  2038.     )
  2039.     {
  2040.     PHY_INFO * pPhyInfo = NULL;
  2041.     
  2042.     /* get memory for the phyInfo structure */
  2043.  
  2044.     if ((pDrvCtrl->pPhyInfo = calloc (sizeof (PHY_INFO), 1)) == NULL)
  2045. return (ERROR);
  2046.     pPhyInfo = pDrvCtrl->pPhyInfo;
  2047.     /* set some default values */
  2048.  
  2049.     pDrvCtrl->pPhyInfo->pDrvCtrl = (void *) pDrvCtrl;
  2050.  
  2051.     pDrvCtrl->pPhyInfo->phyAnOrderTbl = pDrvCtrl->pMiiPhyTbl;
  2052.     if (pDrvCtrl->phyAddr == ((UINT8) 0xFF))
  2053. {
  2054. /* Default is to take the value from the SROM */
  2055.         if (IBLK_IS_EXT1 (pInfoBlock))
  2056.     {
  2057.     pDrvCtrl->pPhyInfo->phyAddr = IBLK_EXT1_PHY(pInfoBlock);
  2058.     }
  2059. else
  2060.     {
  2061.     pDrvCtrl->pPhyInfo->phyAddr = IBLK_EXT3_PHY(pInfoBlock);
  2062.     }
  2063. }
  2064.     else
  2065. {
  2066. /*
  2067.  * Take the value specified in the load string assuming the user
  2068.  * knows best...
  2069.  */
  2070. pDrvCtrl->pPhyInfo->phyAddr = pDrvCtrl->phyAddr;
  2071. }
  2072.     /* 
  2073.      * in case of link failure, set a default mode for the PHY 
  2074.      * if we intend to use a different media, this flag should 
  2075.      * be cleared
  2076.      */
  2077.  
  2078.     pDrvCtrl->pPhyInfo->phyFlags |= MII_PHY_DEF_SET;
  2079.  
  2080.     pDrvCtrl->pPhyInfo->phyWriteRtn = (FUNCPTR) dec21x40MiiWrite;
  2081.     pDrvCtrl->pPhyInfo->phyReadRtn = (FUNCPTR) dec21x40MiiRead;
  2082.     pDrvCtrl->pPhyInfo->phyLinkDownRtn = (FUNCPTR) dec21x40MediaChange;
  2083.     pDrvCtrl->pPhyInfo->phyDelayRtn = (FUNCPTR) taskDelay;
  2084.     pDrvCtrl->pPhyInfo->phyMaxDelay = (sysClkRateGet() * 5);
  2085.     pDrvCtrl->pPhyInfo->phyDelayParm = max (1, sysClkRateGet()/60);
  2086.     /* in case the cable is not there, leave the PHY ready to auto-negotiate */
  2087.     pDrvCtrl->pPhyInfo->phyDefMode = PHY_AN_ENABLE;
  2088.  
  2089.     /* handle some user-to-physical flags */
  2090.  
  2091.     if (!(DRV_PHY_FLAGS_ISSET (DEC_USR_MII_NO_AN)))
  2092.         MII_PHY_FLAGS_SET (MII_PHY_AUTO);
  2093.     else
  2094.         MII_PHY_FLAGS_CLEAR (MII_PHY_AUTO);
  2095.  
  2096.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_AN_TBL))
  2097.         MII_PHY_FLAGS_SET (MII_PHY_TBL);
  2098.     else
  2099.         MII_PHY_FLAGS_CLEAR (MII_PHY_TBL);
  2100.  
  2101.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_100MB))
  2102.         MII_PHY_FLAGS_SET (MII_PHY_100);
  2103.     else
  2104.         MII_PHY_FLAGS_CLEAR (MII_PHY_100);
  2105.  
  2106.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_FD))
  2107.         MII_PHY_FLAGS_SET (MII_PHY_FD);
  2108.     else
  2109.         MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
  2110.  
  2111.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_10MB))
  2112.         MII_PHY_FLAGS_SET (MII_PHY_10);
  2113.     else
  2114.         MII_PHY_FLAGS_CLEAR (MII_PHY_10);
  2115.  
  2116.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_HD))
  2117.         MII_PHY_FLAGS_SET (MII_PHY_HD);
  2118.     else
  2119.         MII_PHY_FLAGS_CLEAR (MII_PHY_HD);
  2120.  
  2121.     if (DRV_PHY_FLAGS_ISSET (DEC_USR_MII_BUS_MON))
  2122.         MII_PHY_FLAGS_SET (MII_PHY_MONITOR);
  2123.     else
  2124.         MII_PHY_FLAGS_CLEAR (MII_PHY_MONITOR);
  2125.  
  2126.     /* mark it as pre-initilized */
  2127.  
  2128.     MII_PHY_FLAGS_SET (MII_PHY_PRE_INIT);
  2129.  
  2130.     DRV_LOG (DRV_DEBUG_LOAD, ("dec21x40PhyPreInit pPhyInfo = 0x%x read=0x%x "
  2131.       "write=0x%x tbl=0x%x addr=0x%x "
  2132.       "flags=0x%x n"),
  2133.        (int) pDrvCtrl->pPhyInfo,
  2134.        (int) pDrvCtrl->pPhyInfo->phyReadRtn,
  2135.        (int) pDrvCtrl->pPhyInfo->phyWriteRtn,
  2136.        (int) pDrvCtrl->pPhyInfo->phyAnOrderTbl,
  2137.        (int) pDrvCtrl->pPhyInfo->phyAddr,
  2138.        (int) pDrvCtrl->pPhyInfo->phyFlags);
  2139.  
  2140.     return (OK);
  2141.     }
  2142. #ifdef DRV_DEBUG
  2143. void decPoolShow
  2144.     (
  2145.     int inst /* instance number, starting at 0 */
  2146.     )
  2147.     {
  2148.     DRV_CTRL *pDrvCtrl = (DRV_CTRL *)endFindByName ("dc", inst);
  2149.     netPoolShow (pDrvCtrl->endObj.pNetPool);
  2150.     }
  2151. void decCsrShow
  2152.     (
  2153.     int inst /* instance number, starting at 0 */
  2154.     )
  2155.     {
  2156.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2157.     
  2158.     if (pDrvCtrl != NULL)
  2159. {
  2160. printf ("n");
  2161. printf ("CSR0t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR0));
  2162. printf ("CSR1t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR1));
  2163. printf ("CSR2t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR2));
  2164. printf ("CSR3t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR3));
  2165. printf ("CSR4t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR4));
  2166. printf ("CSR5t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR5));
  2167. printf ("CSR6t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR6));
  2168. printf ("CSR7t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR7));
  2169. printf ("CSR8t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR8));
  2170. printf ("CSR9t 0x%xn", (int) dec21x40CsrRead(pDrvCtrl, CSR9));
  2171. printf ("CSR10t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR10));
  2172. printf ("CSR11t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR11));
  2173. printf ("CSR12t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR12));
  2174. printf ("CSR13t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR13));
  2175. printf ("CSR14t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR14));
  2176. printf ("CSR15t 0x%xn",(int) dec21x40CsrRead(pDrvCtrl, CSR15));
  2177. }
  2178.     }
  2179. void decCsrWrite
  2180.     (
  2181.     UINT inst,
  2182.     UINT csr,
  2183.     UINT value
  2184.     )
  2185.     {
  2186.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2187.     DEC_CSR_WRITE (csr, value);
  2188.     }
  2189. void decTxDShow
  2190.     (
  2191.     int inst,
  2192.     int numTxD
  2193.     )
  2194.     {
  2195.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2196.     DEC_TD *pTxD = &pDrvCtrl->txRing[numTxD];
  2197.     printf ("txd[%d] at 0x%x:n", numTxD, (int)pTxD);
  2198.     printf ("tDesc0=0x%x tDesc1=0x%x tDesc2=0x%x tDesc3=0x%xn",
  2199.             (int) PCISWAP (pTxD->tDesc0), (int) PCISWAP (pTxD->tDesc1),
  2200.             (int) PCISWAP (pTxD->tDesc2), (int) PCISWAP (pTxD->tDesc3));
  2201.     }
  2202. void decRxDShow
  2203.     (
  2204.     int inst,
  2205.     int numRxD
  2206.     )
  2207.     {
  2208.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2209.     DEC_TD *pTxD = &pDrvCtrl->txRing[numRxD];
  2210.     printf ("rxd[%d] at 0x%x:n", numRxD, (int)pTxD);
  2211.     printf ("tDesc0=0x%x tDesc1=0x%x tDesc2=0x%x tDesc3=0x%xn",
  2212.             (int) PCISWAP (pTxD->tDesc0), (int) PCISWAP (pTxD->tDesc1),
  2213.             (int) PCISWAP (pTxD->tDesc2), (int) PCISWAP (pTxD->tDesc3));
  2214.     }
  2215. void decShow
  2216.     (
  2217.     int inst
  2218.     )
  2219.     {
  2220.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2221.     printf ("pDrvCtrl=0x%x txNum=%d txIndex=%d txDiIndex=%dn",
  2222.             (int) pDrvCtrl,
  2223.             pDrvCtrl->numTds,
  2224.             pDrvCtrl->txIndex,
  2225.             pDrvCtrl->txDiIndex);
  2226.     
  2227.     printf ("rxNum=%d rxIndex=%dn",
  2228.             pDrvCtrl->numRds,
  2229.             pDrvCtrl->rxIndex);
  2230.     }
  2231. int eAdrsDisplay
  2232.     (
  2233.     UINT8 *pAddr
  2234.     )
  2235.     {
  2236.     printf ("EtherAddr=%x:%x:%x:%x:%x:%xn",
  2237.             pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);
  2238.     return 0;
  2239.     }
  2240. void mcAdd (int inst, char *eAddr)
  2241.     {
  2242.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2243.     dec21x40MCastAddrAdd (pDrvCtrl, eAddr);
  2244.     }
  2245. void mcDel (int inst, char *eAddr)
  2246.     {
  2247.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2248.     dec21x40MCastAddrDel (pDrvCtrl, eAddr);
  2249.     }
  2250. void mcShow (int inst)
  2251.     {
  2252.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2253.     ETHER_MULTI  *pMCastNode;
  2254.     pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);
  2255.     while (pMCastNode != NULL)
  2256.         {
  2257.         eAdrsDisplay (pMCastNode->addr);
  2258.         pMCastNode = END_MULTI_LST_NEXT (pMCastNode);
  2259.         }
  2260.     }
  2261. char decSerialRom[128];
  2262. void decSerialRomUpload (int inst)
  2263.     {
  2264.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2265.     int  count;
  2266.     USHORT  *pSerialRom = (USHORT *)decSerialRom;
  2267.     bzero (decSerialRom, 128);
  2268.     for (count=0; count<64; count++)
  2269.         *pSerialRom++ = dec21140SromWordRead (pDrvCtrl, count);
  2270.     }
  2271. int decReset(int inst)
  2272.     {
  2273.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2274.     dec21x40Stop (pDrvCtrl);
  2275.     taskDelay (max (2, sysClkRateGet()/30));
  2276.     netJobAdd ((FUNCPTR)dec21x40Restart, (int)pDrvCtrl, 0, 0, 0, 0);
  2277.     return 0;
  2278.     }
  2279. short decMiiRead (int inst, int phyAddr, int reg)
  2280.     {
  2281.     int retStat;
  2282.     short miiData = 0;
  2283.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2284.     retStat = dec21x40MiiRead(pDrvCtrl, phyAddr, reg, &miiData);
  2285.     return (miiData);
  2286.     }
  2287. int decMiiWrite (int inst, int phyAddr, int reg, short miiData)
  2288.     {
  2289.     DRV_CTRL * pDrvCtrl = (DRV_CTRL *) endFindByName ("dc", inst);
  2290.     return (dec21x40MiiWrite (pDrvCtrl, phyAddr, reg, miiData));
  2291.     }
  2292. #endif /* DC_DEBUG */