📄 smsc911x.c
字号:
#define LINK_SYMMETRIC_PAUSE (0x10UL)
#define LINK_ASYMMETRIC_PAUSE (0x20UL)
#define LINK_AUTO_NEGOTIATE (0x40UL)
/*
****************************************************************************
****************************************************************************
* MAC Control and Status Register (Indirect Address)
* Offset (through the MAC_CSR CMD and DATA port)
****************************************************************************
****************************************************************************
*
*/
#define MAC_CR (0x01UL)
/* MAC_CR - MAC Control Register */
#define MAC_CR_RXALL_ (0x80000000UL)
#define MAC_CR_HBDIS_ (0x10000000UL)
#define MAC_CR_RCVOWN_ (0x00800000UL)
#define MAC_CR_LOOPBK_ (0x00200000UL)
#define MAC_CR_FDPX_ (0x00100000UL)
#define MAC_CR_MCPAS_ (0x00080000UL)
#define MAC_CR_PRMS_ (0x00040000UL)
#define MAC_CR_INVFILT_ (0x00020000UL)
#define MAC_CR_PASSBAD_ (0x00010000UL)
#define MAC_CR_HFILT_ (0x00008000UL)
#define MAC_CR_HPFILT_ (0x00002000UL)
#define MAC_CR_LCOLL_ (0x00001000UL)
#define MAC_CR_BCAST_ (0x00000800UL)
#define MAC_CR_DISRTY_ (0x00000400UL)
#define MAC_CR_PADSTR_ (0x00000100UL)
#define MAC_CR_BOLMT_MASK_ (0x000000C0UL)
#define MAC_CR_DFCHK_ (0x00000020UL)
#define MAC_CR_TXEN_ (0x00000008UL)
#define MAC_CR_RXEN_ (0x00000004UL)
#define ADDRH (0x02UL)
#define ADDRL (0x03UL)
#define HASHH (0x04UL)
#define HASHL (0x05UL)
#define MII_ACC (0x06UL)
#define MII_ACC_PHY_ADDR_ (0x0000F800UL)
#define MII_ACC_MIIRINDA_ (0x000007C0UL)
#define MII_ACC_MII_WRITE_ (0x00000002UL)
#define MII_ACC_MII_BUSY_ (0x00000001UL)
#define MII_DATA (0x07UL)
#define FLOW (0x08UL)
#define FLOW_FCPT_ (0xFFFF0000UL)
#define FLOW_FCPASS_ (0x00000004UL)
#define FLOW_FCEN_ (0x00000002UL)
#define FLOW_FCBSY_ (0x00000001UL)
#define VLAN1 (0x09UL)
#define VLAN2 (0x0AUL)
#define WUFF (0x0BUL)
#define WUCSR (0x0CUL)
#define WUCSR_GUE_ (0x00000200UL)
#define WUCSR_WUFR_ (0x00000040UL)
#define WUCSR_MPR_ (0x00000020UL)
#define WUCSR_WAKE_EN_ (0x00000004UL)
#define WUCSR_MPEN_ (0x00000002UL)
/*
****************************************************************************
* Chip Specific MII Defines
****************************************************************************
*
* Phy register offsets and bit definitions
*
*/
#define LAN9118_PHY_ID (0x00C0001C)
#define PHY_BCR ((DWORD)0U)
#define PHY_BCR_RESET_ ((WORD)0x8000U)
#define PHY_BCR_SPEED_SELECT_ ((WORD)0x2000U)
#define PHY_BCR_AUTO_NEG_ENABLE_ ((WORD)0x1000U)
#define PHY_BCR_RESTART_AUTO_NEG_ ((WORD)0x0200U)
#define PHY_BCR_DUPLEX_MODE_ ((WORD)0x0100U)
#define PHY_BSR ((DWORD)1U)
#define PHY_BSR_LINK_STATUS_ ((WORD)0x0004U)
#define PHY_BSR_REMOTE_FAULT_ ((WORD)0x0010U)
#define PHY_BSR_AUTO_NEG_COMP_ ((WORD)0x0020U)
#define PHY_ID_1 ((DWORD)2U)
#define PHY_ID_2 ((DWORD)3U)
#define PHY_ANEG_ADV ((DWORD)4U)
#define PHY_ANEG_ADV_PAUSE_ ((WORD)0x0C00)
#define PHY_ANEG_ADV_ASYMP_ ((WORD)0x0800)
#define PHY_ANEG_ADV_SYMP_ ((WORD)0x0400)
#define PHY_ANEG_ADV_10H_ ((WORD)0x020)
#define PHY_ANEG_ADV_10F_ ((WORD)0x040)
#define PHY_ANEG_ADV_100H_ ((WORD)0x080)
#define PHY_ANEG_ADV_100F_ ((WORD)0x100)
#define PHY_ANEG_ADV_SPEED_ ((WORD)0x1E0)
#define PHY_ANEG_LPA ((DWORD)5U)
#define PHY_ANEG_LPA_ASYMP_ ((WORD)0x0800)
#define PHY_ANEG_LPA_SYMP_ ((WORD)0x0400)
#define PHY_ANEG_LPA_100FDX_ ((WORD)0x0100)
#define PHY_ANEG_LPA_100HDX_ ((WORD)0x0080)
#define PHY_ANEG_LPA_10FDX_ ((WORD)0x0040)
#define PHY_ANEG_LPA_10HDX_ ((WORD)0x0020)
#define PHY_MODE_CTRL_STS ((DWORD)17)
#define MODE_CTRL_STS_EDPWRDOWN_ ((WORD)0x2000U)
#define MODE_CTRL_STS_ENERGYON_ ((WORD)0x0002U)
#define PHY_INT_SRC ((DWORD)29)
#define PHY_INT_SRC_ENERGY_ON_ ((WORD)0x0080U)
#define PHY_INT_SRC_ANEG_COMP_ ((WORD)0x0040U)
#define PHY_INT_SRC_REMOTE_FAULT_ ((WORD)0x0020U)
#define PHY_INT_SRC_LINK_DOWN_ ((WORD)0x0010U)
#define PHY_INT_MASK ((DWORD)30)
#define PHY_INT_MASK_ENERGY_ON_ ((WORD)0x0080U)
#define PHY_INT_MASK_ANEG_COMP_ ((WORD)0x0040U)
#define PHY_INT_MASK_REMOTE_FAULT_ ((WORD)0x0020U)
#define PHY_INT_MASK_LINK_DOWN_ ((WORD)0x0010U)
#define PHY_SPECIAL ((DWORD)31)
#define PHY_SPECIAL_SPD_ ((WORD)0x001CU)
#define PHY_SPECIAL_SPD_10HALF_ ((WORD)0x0004U)
#define PHY_SPECIAL_SPD_10FULL_ ((WORD)0x0014U)
#define PHY_SPECIAL_SPD_100HALF_ ((WORD)0x0008U)
#define PHY_SPECIAL_SPD_100FULL_ ((WORD)0x0018U)
#ifdef USE_LED1_WORK_AROUND
extern volatile DWORD g_GpioSetting;
volatile DWORD g_GpioSettingOriginal;
#endif
/*
****************************************************************************
* Chip Specific MII Defines
****************************************************************************
*
* Phy register offsets and bit definitions
*
*/
#define LAN9118_PHY_ID (0x00C0001C)
#define PHY_BCR ((DWORD)0U)
#define PHY_BCR_RESET_ ((WORD)0x8000U)
#define PHY_BCR_SPEED_SELECT_ ((WORD)0x2000U)
#define PHY_BCR_AUTO_NEG_ENABLE_ ((WORD)0x1000U)
#define PHY_BCR_RESTART_AUTO_NEG_ ((WORD)0x0200U)
#define PHY_BCR_DUPLEX_MODE_ ((WORD)0x0100U)
#define PHY_BSR ((DWORD)1U)
#define PHY_BSR_LINK_STATUS_ ((WORD)0x0004U)
#define PHY_BSR_REMOTE_FAULT_ ((WORD)0x0010U)
#define PHY_BSR_AUTO_NEG_COMP_ ((WORD)0x0020U)
#define PHY_ID_1 ((DWORD)2U)
#define PHY_ID_2 ((DWORD)3U)
#define PHY_ANEG_ADV ((DWORD)4U)
#define PHY_ANEG_ADV_PAUSE_ ((WORD)0x0C00)
#define PHY_ANEG_ADV_ASYMP_ ((WORD)0x0800)
#define PHY_ANEG_ADV_SYMP_ ((WORD)0x0400)
#define PHY_ANEG_ADV_10H_ ((WORD)0x020)
#define PHY_ANEG_ADV_10F_ ((WORD)0x040)
#define PHY_ANEG_ADV_100H_ ((WORD)0x080)
#define PHY_ANEG_ADV_100F_ ((WORD)0x100)
#define PHY_ANEG_ADV_SPEED_ ((WORD)0x1E0)
#define PHY_ANEG_LPA ((DWORD)5U)
#define PHY_ANEG_LPA_ASYMP_ ((WORD)0x0800)
#define PHY_ANEG_LPA_SYMP_ ((WORD)0x0400)
#define PHY_ANEG_LPA_100FDX_ ((WORD)0x0100)
#define PHY_ANEG_LPA_100HDX_ ((WORD)0x0080)
#define PHY_ANEG_LPA_10FDX_ ((WORD)0x0040)
#define PHY_ANEG_LPA_10HDX_ ((WORD)0x0020)
#define PHY_MODE_CTRL_STS ((DWORD)17) /* Mode Control/Status Register */
#define MODE_CTRL_STS_EDPWRDOWN_ ((WORD)0x2000U)
#define MODE_CTRL_STS_ENERGYON_ ((WORD)0x0002U)
#define PHY_INT_SRC ((DWORD)29)
#define PHY_INT_SRC_ENERGY_ON_ ((WORD)0x0080U)
#define PHY_INT_SRC_ANEG_COMP_ ((WORD)0x0040U)
#define PHY_INT_SRC_REMOTE_FAULT_ ((WORD)0x0020U)
#define PHY_INT_SRC_LINK_DOWN_ ((WORD)0x0010U)
#define PHY_INT_MASK ((DWORD)30)
#define PHY_INT_MASK_ENERGY_ON_ ((WORD)0x0080U)
#define PHY_INT_MASK_ANEG_COMP_ ((WORD)0x0040U)
#define PHY_INT_MASK_REMOTE_FAULT_ ((WORD)0x0020U)
#define PHY_INT_MASK_LINK_DOWN_ ((WORD)0x0010U)
#define PHY_SPECIAL ((DWORD)31)
#define PHY_SPECIAL_SPD_ ((WORD)0x001CU)
#define PHY_SPECIAL_SPD_10HALF_ ((WORD)0x0004U)
#define PHY_SPECIAL_SPD_10FULL_ ((WORD)0x0014U)
#define PHY_SPECIAL_SPD_100HALF_ ((WORD)0x0008U)
#define PHY_SPECIAL_SPD_100FULL_ ((WORD)0x0018U)
/*
system level functios & macros
*/
#ifndef SYS_ENET_ADDR_GET
#define SYS_ENET_ADDR_GET(pDevice) \
{ \
bcopy ((char *)(&pDevice->CurrentAddress), (char *)(&pDevice->ucStationAddress), 6); \
}
#endif
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
/* A shortcut for getting the hardware address from the MIB II stuff. */
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
#define END_FLAGS_ISSET(pEnd, setBits) \
((pEnd)->flags & (setBits))
/* The definition of the driver control structure */
#define MAC_ADDRESS_SIZE 6
#define LAN911X_MIN_FBUF (1536) /* min first buffer size */
#define ETHER_LENGTH_OF_ADDRESS 6U
#define ETHER_ZLEN 60
#define EH_SIZE (14) /* Header size (bytes */
typedef struct
{
int len;
UCHAR * pData;
} RX_PKT; /* received packet */
typedef struct
{
M_BLK_ID pMblk;
} TX_PKT; /* transmit packet */
#define TX_PACKETS 0x20
#define RX_PACKETS 0x40
#define MAC_ADDRESS_SIZE 6
typedef struct _NETWORK_ADDRESS
{
UCHAR Address[MAC_ADDRESS_SIZE]; /* Network address */
} NETWORK_ADDRESS;
#define NETWORK_ADDRESS_SIZE sizeof(NETWORK_ADDRESS)
#define DEFAULT_MULTICASTLISTMAX 32
/*
data structures
*/
typedef struct _PRIVATE_DATA {
DWORD dwLanBase;
DWORD dwIdRev;
DWORD dwPhyAddress;
#ifdef USE_LED1_WORK_AROUND
DWORD NotUsingExtPhy;
#endif
#ifdef USE_PHY_WORK_AROUND
#define MIN_PACKET_SIZE (64)
DWORD dwTxStartMargen;
BYTE LoopBackTxPacket[MIN_PACKET_SIZE];
DWORD dwTxEndMargen;
DWORD dwRxStartMargen;
BYTE LoopBackRxPacket[MIN_PACKET_SIZE];
DWORD dwRxEndMargen;
DWORD dwResetCount;
#endif
} PRIVATE_DATA, *PPRIVATE_DATA;
typedef struct lan_device
{
END_OBJ endObj; /* The class we inherit from. */
PRIVATE_DATA private_data ;
int unit; /* unit number */
int ivec; /* interrupt vector */
UINT IOBase; /* Base port */
int ilevel; /* interrupt level */
char* memBase; /* memory base */
int offset;
UINT InitConfigVal;
DWORD PhyAddress ; /* 0xFF: internal phy, others: external phy*/
BOOLEAN fRxDMAMode ;
BOOLEAN fTxDMAMode;
UCHAR ucStationAddress[MAC_ADDRESS_SIZE];
DWORD LinkMode;
int numFrames; /* Number of frames to allocate */
CL_POOL_ID pClPoolId;
BOOLEAN rxHandling;
RX_PKT *pRxBase; /* Rx ring buffer base */
RX_PKT *pRxReadIndex;
RX_PKT *pRxWriteIndex;
BOOLEAN txHandling; /* tx task scheduled */
TX_PKT *pTxBase; /* Tx ring buffer base */
TX_PKT *pTxReadIndex;
TX_PKT *pTxWriteIndex;
UCHAR *sendBuf;
DWORD TDFALevel;
USHORT sendDatalen;
DWORD ucNicMulticastRegs[2];
} SMSC911XEND_DEVICE;
/*
* This will only work if there is only a single unit, for multiple
* unit device drivers these should be integrated into the END_DEVICE
* structure.
*/
#define SMSC911X_BUFSIZE (ETHERMTU + ENET_HDR_REAL_SIZ + 6 + 4)
#define SMSC911X_DEV_NAME "ln"
#define SMSC911X_DEV_NAME_LEN 3
M_CL_CONFIG smsc911xMclBlkConfig = /* network mbuf configuration table */
{
/*
no. mBlks no. clBlks memArea memSize
----------- ---------- ------- -------
*/
256, 128, NULL, 0
};
CL_DESC smsc911xClDescTbl [] = /* network cluster pool configuration table */
{
/*
clusterSize num memArea memSize
----------- ---- ------- -------
*/
{SMSC911X_BUFSIZE, 0, NULL, 0}
};
int smsc911xClDescTblNumEnt = (NELEMENTS(smsc911xClDescTbl));
NET_POOL smsc911xCmpNetPool;
#define SMSC911X_MIN_FBUF (1536) /* min first buffer size */
/* Function Prototypes */
void Mac_Initialize(PPRIVATE_DATA privateData);
BOOLEAN MacNotBusy(DWORD dwLanBase);
DWORD Mac_GetRegDW(DWORD dwBase,DWORD dwRegOffset);
void Mac_SetRegDW(DWORD dwBase,DWORD dwRegOffset,DWORD dwVal);
BOOLEAN Phy_Initialize( PPRIVATE_DATA privateData, DWORD dwPhyAddr);
void Phy_SetLink( PPRIVATE_DATA privateData);
WORD Phy_GetRegW( PPRIVATE_DATA privateData, DWORD dwRegIndex);
void Phy_SetRegW( PPRIVATE_DATA privateData, DWORD dwRegIndex, WORD wVal);
void Tx_Initialize( PPRIVATE_DATA privateData);
void Tx_WriteFifo( DWORD dwLanBase, DWORD *pdwBuf, DWORD dwDwordCount);
void Rx_Initialize( PPRIVATE_DATA privateData);
void Rx_ReadFifo( DWORD dwLanBase, DWORD *pdwBuf, DWORD dwDwordCount);
BOOLEAN Lan_Initialize( PPRIVATE_DATA privateData,DWORD dwIntCfg);
END_OBJ* smsc911xLoad( char* initString, void *args );
STATUS smsc911xUnload ( END_OBJ* pEnd );
STATUS smsc911xStart ( END_OBJ * pEnd );
STATUS smsc911xStop ( END_OBJ *pEnd );
STATUS smsc911xRecv ( SMSC911XEND_DEVICE *pDrvCtrl/*, char *, UINT */);
STATUS smsc911xSend(END_OBJ *pEnd,M_BLK_ID pMblk);
STATUS smsc911xIoctl ( END_OBJ * pEnd, int cmd, caddr_t data );
STATUS smsc911xMCastAddrAdd ( END_OBJ *pEnd, char* pAddress );
STATUS smsc911xMCastAddrDel ( END_OBJ *pEnd, char* pAddress );
STATUS smsc911xMCastAddrGet ( END_OBJ *pEnd, MULTI_TABLE* pTable );
STATUS smsc911xPollStop ( SMSC911XEND_DEVICE * pDrvCtrl );
STATUS smsc911xPollStart ( SMSC911XEND_DEVICE * pDrvCtrl );
void smsc911xInt ( SMSC911XEND_DEVICE * pDrvCtrl );
NET_FUNCS smsc911xFuncTable =
{
(FUNCPTR) smsc911xStart, /* Function to start the device. */
(FUNCPTR) smsc911xStop, /* Function to stop the device. */
(FUNCPTR) smsc911xUnload, /* Unloading function for the driver. */
(FUNCPTR) smsc911xIoctl, /* Ioctl function for the driver. */
(FUNCPTR) smsc911xSend, /* Send function for the driver. */
(FUNCPTR) smsc911xMCastAddrAdd, /* Multicast add function for the driver */
(FUNCPTR) smsc911xMCastAddrDel, /* Multicast delete function for the driver */
(FUNCPTR) smsc911xMCastAddrGet, /* Multicast retrieve function for the driver */
(FUNCPTR) smsc911xPollStart, /* Polling send function */
(FUNCPTR) smsc911xPollStop, /* Polling receive function */
endEtherAddressForm, /* put address info into a NET_BUFFER */
endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
endEtherPacketAddrGet /* Get packet addresses. */
};
STATUS smsc911xIdentify( SMSC911XEND_DEVICE * pDrvCtl ) ;
STATUS smsc911xMemInit(SMSC911XEND_DEVICE * pDrvCtrl) ;
void smsc911xSendPackets( SMSC911XEND_DEVICE *pDrvCtrl ) ;
void smsc911xWriteToChip(SMSC911XEND_DEVICE *pDrvCtrl);
void smsc911xSetMulticastAddressList (SMSC911XEND_DEVICE *pDrvCtrl) ;
DWORD smsc911xComputeCrc(UCHAR * pBuffer, UINT uiLength);
void HandlerRxISR(SMSC911XEND_DEVICE * pDrvCtl);
BOOL SyncSetTDFALevel(SMSC911XEND_DEVICE * pDrvCtl);
VOID HandlerTxISR(SMSC911XEND_DEVICE * pDrvCtl);
void HandlerPhyISR(SMSC911XEND_DEVICE * pDrvCtl);
void RxFastForward(SMSC911XEND_DEVICE * pDrvCtl, DWORD dwDWCount);
/*
* Declare our function table. This is static across all driver
* instances.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -