DP8381X-Linux-Ver-1.6/0000755000000000000000000000000010430230127012654 5ustar rootrootDP8381X-Linux-Ver-1.6/Makefile.2.40000444000000000000000000001137110430225716014627 0ustar rootroot#!/usr/bin/make # Makefile for building National Semiconductor MacPhyter2 Drivers # KERNELVER = $(shell uname -r) SEARCHPATH = /usr/src/linux \ /usr/src/linux-$(shell uname -r | awk '{print substr($$1,1,3)}') \ /usr/src/linux-$(shell uname -r | awk -F [-] '{print $$1}') \ /usr/src/linux-$(KERNELVER) \ /lib/modules/$(KERNELVER)/build ifeq (,$(KERNEL_DIR)) FIND_DIR = $(shell [ -e $(dir)/include/linux ] && echo $(dir)) SEARCHPATH := $(foreach dir, $(SEARCHPATH), $(FIND_DIR)) KERNELDIR := $(firstword $(SEARCHPATH)) else KERNELDIR := $(KERNEL_DIR) endif KSOURCEVER := $(shell $(CC) -E -dM $(KERNELDIR)/include/linux/version.h | \ grep UTS_RELEASE | awk '{ print $$3 }' | sed 'y/"/:/' | \ awk -F [:] '{print $$2}') # Pick an appropriate install path ifeq (,$(INSTALL_DIR)) ifeq (,$(wildcard /lib/modules/$(KERNELVER)/kernel)) INSTALLDIR = /lib/modules/$(KERNELVER)/net else INSTALLDIR = /lib/modules/$(KERNELVER)/kernel/drivers/net endif else INSTALLDIR = $(INSTALL_DIR) endif # MPL dirs MPLDIR = Mpl MPLPUB = $(MPLDIR)/Public MPLTASKS = $(MPLDIR)/Tasks #Driver flags - Remove trailing 1 to enable a flag DRVFLAGS = -DNSM_DIAG_MODE1 -DMPL_CHECKED_BUILD1 -DNSM_DEBUG1 -DLINUX_POWER_DEBUG1 #Target and source files CFILES = HFILES = TARGET = macphy.o # NSM files CFILES += \ nsmos.c \ nsmdiag.o \ nsmmpl.c #MPL Src Files CFILES += \ $(MPLTASKS)/mpltaskrxfilter.c \ $(MPLDIR)/mplutil.o \ $(MPLDIR)/mpldebug.c \ $(MPLDIR)/mplintr.c \ $(MPLDIR)/mplmisc.c \ $(MPLDIR)/mplphy.c \ $(MPLDIR)/mpllink.c \ $(MPLDIR)/mplreceive.c \ $(MPLDIR)/mpltransmit.c \ $(MPLDIR)/mplcaps.c \ $(MPLDIR)/mplpwr.c \ $(MPLDIR)/mplinitshutdown.c CC = gcc #Standard Flags CFLAGS = -DLINUX -D__KERNEL__ -O2 -Wall -DMODULE CFLAGS += -I$(KERNELDIR)/include -I$(KERNELDIR)/include/asm -I$(KERNELDIR)/include/asm/mach-default CFLAGS += -I$(PWD)/$(MPLPUB) -I$(PWD)/$(MPLTASKS) -I$(PWD)/$(MPLDIR) -I$(PWD) CFLAGS += $(DRVFLAGS) CFLAGS += -march=i686 -DKBUILD_BASENAME=macphy -DKBUILD_MODNAME=macphy #User Configurable variable for Symmetric Multi Processing Support obtained # by executing shell script. # Check if the SMP is defined in custom shell script # if the custom shell is not run then select the default # based on CONFIG_ flag set in config.h CONFIG_FILE := $(KERNELDIR)/include/linux/config.h ifeq (,$(SMP)) SMP_F := $(shell $(CC) $(CFLAGS) -E -dM $(CONFIG_FILE) | \ grep CONFIG_SMP | awk '{ print $$3 }') ifneq ($(SMP_F),1) SMP_F := 0 endif else ifeq (y,$(SMP)) SMP_F := 1 endif endif # If SMP_F is set then add to CFLAGS ifeq (1,$(SMP_F)) CFLAGS += -D__SMP__ endif #User Configurable variable for Modversion support obtained # by executing shell script. # Check if the MODVER is defined in custom shell script # if the custom shell is not run then select the default # based on CONFIG_ flag set in config.h ifeq (,$(MODVER)) MOD_F := $(shell $(CC) $(CFLAGS) -E -dM $(CONFIG_FILE) | \ grep CONFIG_MODVERSIONS | awk '{ print $$3 }') ifneq ($(MOD_F),1) MOD_F := 0 endif else ifeq (y,$(MODVER)) MOD_F := 1 endif endif # If MOD_F is set then add to CFLAGS ifeq (1,$(MOD_F)) CFLAGS += $(shell [ -f $(KERNELDIR)/include/linux/modversions.h ] && \ echo "-DMODVERSIONS -include $(KERNELDIR)/include/linux/modversions.h") endif # Target/Rules definitions all :: driver custom : @if [ -x ./build.sh ] ; then \ ./build.sh ; \ fi driver : vcheck $(TARGET) vcheck : @if [ "$(KSOURCEVER)" != "$(KERNELVER)" ] ; then \ echo ; \ echo "Warning! Kernel version Mismatch" ; \ echo "Running kernel: $(KERNELVER)" ; \ echo "Kernel-source version: $(KSOURCEVER)" ; \ echo "Driver might not work as required!!" ; \ echo ; \ fi $(TARGET): $(CFILES:.c=.o) $(LD) -r $^ -o $@ @echo @echo "$(TARGET) Built Successfully" @echo -n " SMP is :" @if [ "$(SMP_F)" != "1" ] ; then \ echo " Disabled" ; else echo " Enabled" ; fi @echo -n " MODVER is :" @if [ "$(MOD_F)" != "1" ] ; then \ echo " Disabled" ; else echo " Enabled" ; fi @echo " Kernel Source path is : $(KERNELDIR)" @echo " INSTALL path is : $(INSTALLDIR)" #@echo " To change the above run : make custom" @echo $(CFILES:.c=.o): Makefile install: $(TARGET) @mkdir -p $(INSTALLDIR) @install -m 644 $(TARGET) $(INSTALLDIR) @echo "NSM Macphyter Driver Successfully Installed : $(INSTALLDIR)" uninstall: @if [ -e $(INSTALLDIR)/$(TARGET) ] ; then \ rm -rf $(INSTALLDIR)/$(TARGET) ; \ fi clean: rm -rf $(TARGET) $(CFILES:.c=.o) DP8381X-Linux-Ver-1.6/nsmmpl.c0000444000000000000000000002456710430225716014352 0ustar rootroot//****************************************************************************** // // NSMMPL.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // Interface file between NSM and MPL, implements // 1. OAI APIs // 2. MPL Callbacks // //****************************************************************************** #include #include //+++++ Host DMA Memory Functions //Allocate/free a region in host memory suitable for DMA NS_BOOLEAN OaiAllocDmaRegion( IN NS_VOID *pClientDevHndl, IN NS_UINT size, IN NS_UINT byteAlignment, OUT MPL_MEM_REGION **pRgnHndl ) { dma_addr_t allocPA; NSM_MEM_REGION *pMemNode; // No allocations yet *pRgnHndl = NULL; // Allocate a DMA MEM node pMemNode = (NSM_MEM_REGION *)kmalloc(sizeof(NSM_MEM_REGION), GFP_KERNEL); if (pMemNode == NULL) return NS_FALSE; // Alloc consistent - Should be mapped on 4-byte pMemNode->pAddr = pci_alloc_consistent(((NSM_CONTEXT *)pClientDevHndl)->pdev, size, &allocPA); if (pMemNode->pAddr != NULL) { pMemNode->phyAddr = (NS_ADDR)allocPA; pMemNode->size = size; *pRgnHndl = (MPL_MEM_REGION *)pMemNode; return NS_TRUE; } else { kfree((NS_VOID *)pMemNode); return NS_FALSE; } } NS_VOID OaiFreeDmaRegion( IN NS_VOID *pClientDevHndl, IN MPL_MEM_REGION *pRgnHndl ) { NSM_MEM_REGION *pMemNode = (NSM_MEM_REGION *)pRgnHndl; if (pMemNode && pMemNode->pAddr) { pci_free_consistent(((NSM_CONTEXT *)pClientDevHndl)->pdev, pMemNode->size, pMemNode->pAddr, (dma_addr_t)pMemNode->phyAddr); kfree((NS_VOID *)pMemNode); } return; } //+++++ Timer Functions //Allocate/free/start/cancel periodic timer w/ callback 'pTimerFunction' NS_BOOLEAN OaiCreateTimer( IN MPL_TIMERCALLBACK pTimerFunction, IN NS_VOID *pTimerArg, OUT NS_VOID **pTimerHandle ) { struct timer_list *timer; // Allocate a timer struct timer = (struct timer_list *)kmalloc(sizeof(struct timer_list), GFP_KERNEL); *pTimerHandle = timer; if (timer != NULL) { // Initialize the Timer init_timer(timer); timer->function = (void (*)(unsigned long))pTimerFunction; timer->data = (unsigned long)pTimerArg; return TRUE; } else return FALSE; } NS_VOID OaiDeleteTimer( IN NS_VOID *pTimerHandle ) { if (pTimerHandle) { // To be safe cancel it first del_timer((struct timer_list *)pTimerHandle); // Free the memory kfree((NS_VOID *)pTimerHandle); } return; } NS_VOID OaiStartTimer( IN NS_VOID *pTimerHandle, IN NS_UINT delayInMsec ) { // Note each jiffies is about 10msec (100 ticks per sec) mod_timer((struct timer_list *)pTimerHandle, (jiffies + (delayInMsec / 10))); return; } NS_BOOLEAN OaiCancelTimer( IN NS_VOID *pTimerHandle ) { del_timer_sync((struct timer_list *)pTimerHandle); return NS_TRUE; } //+++++ Resource Synchronization Functions //Initialize/free/acquire/release multiprocessor-safe synchronization lock NS_BOOLEAN OaiCreateLock( OUT NS_VOID **pLockHandle ) { return NS_TRUE; } NS_VOID OaiDestroyLock( IN NS_VOID *pLockHandle ) { return; } NS_VOID OaiAcquireLock( IN NS_VOID *pLockHandle ) { return; } NS_VOID OaiReleaseLock( IN NS_VOID *pLockHandle ) { return; } //+++++ MPL Callbacks into NSM //***************************************************************************** // NsmTransmitDone // Transmit Done Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose completion is being reported. // pTxDone // MPL allocated MPL_TRANSMIT_DONE structure array in which the // NSM packet handles and statuses are returned. // // Return Value // None //***************************************************************************** NS_VOID NsmTransmitDone( IN NS_VOID *pClientDevHndl, IN NS_UINT packetCnt, IN MPL_TRANSMIT_DONE *pTxDone ) { NSM_CONTEXT *adapter = pClientDevHndl; struct sk_buff *skb; NS_UINT i; NS_ADDR physAddr; NI(NsmTransmitDone); #ifdef NSM_DIAG_MODE if (adapter->opMode != MPL_MODE_NORMAL) { // Call the Diag Tx done handler NsmDiagTransmitDone(pClientDevHndl, packetCnt, pTxDone); NO(NsmTransmitDone); return; } #endif //NSM_DIAG_MODE // Unmap and Free done skbs for(i = 0x0; i < packetCnt; i++) { // Get the skb which was noted as NSM private skb = pTxDone[i].pNsmPrivate; if (pTxDone[i].packetStatus == NS_STATUS_SUCCESS) { // Update counters adapter->netStats.tx_packets++; adapter->netStats.tx_bytes += skb->len; } else { // Update counters adapter->netStats.tx_errors++; // Detailed Error analysis - FM: Make call to MPL Stat? if (pTxDone[i].cmdSts & (CS_ERR_TXA | CS_ERR_TX_EC)) { adapter->netStats.tx_aborted_errors++; } if (pTxDone[i].cmdSts & CS_ERR_TFU) { adapter->netStats.tx_fifo_errors++; } if (pTxDone[i].cmdSts & CS_ERR_TX_CRS) { adapter->netStats.tx_carrier_errors++; } if (pTxDone[i].cmdSts & CS_ERR_TX_OWC) { adapter->netStats.tx_window_errors++; } } // Unmap Buffers physAddr = (NS_ADDR)*((NS_UINT *)skb->cb); pci_unmap_single(adapter->pdev, physAddr, skb->len, PCI_DMA_TODEVICE); // If we had requested to stop new Tx to the Net Stack, /// then let it start again if (netif_queue_stopped(adapter->netdev)) { netif_wake_queue(adapter->netdev); } // Free Skb dev_kfree_skb_irq(skb); } NO(NsmTransmitDone); return; } //***************************************************************************** // NsmReceive // Receive Done Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose reception is being reported. // pPkt // MPL allocated MPL_PKT structure array in which // a list of the newly received packets are reported // // Return Value // None //***************************************************************************** NS_VOID NsmReceive( IN NS_VOID *pClientDevHndl, IN NS_UINT packetCnt, IN MPL_PKT *pPkt ) { NSM_CONTEXT *adapter = pClientDevHndl; MPL_PKT_FRAG *pFragTail; struct sk_buff *skb; NS_UINT i, j; NI(NsmReceive); #ifdef NSM_DIAG_MODE if (adapter->opMode != MPL_MODE_NORMAL) { // Call the Diag Tx done handler NsmDiagReceive(pClientDevHndl, packetCnt, pPkt); NO(NsmReceive); return; } #endif //NSM_DIAG_MODE // Process the receive list for(i = 0x0; i < packetCnt; i++) { pFragTail = pPkt[i].pFragHead; // We should have only ONE fragment for Linux - Process it if (pPkt[i].fragCount == 0x01) { // Unmap the Skb pci_unmap_single(adapter->pdev, pFragTail->physAddr, adapter->rxBufferLen, PCI_DMA_FROMDEVICE); if (pPkt[i].packetStatus == NS_STATUS_SUCCESS) { // Decrement the size of CRC pPkt[i].packetSize -= CRC_LENGTH; // Update counters adapter->netStats.rx_packets++; adapter->netStats.rx_bytes += pPkt[i].packetSize; // Report Skb to Net Stack skb = (struct sk_buff *)(pFragTail->pNsmPrivate); skb_put(skb, pPkt[i].packetSize); skb->protocol = eth_type_trans(skb, adapter->netdev); netif_rx(skb); // The Skb associated with this fragment is now history pFragTail->pNsmPrivate = NULL; } else { // Update counters adapter->netStats.rx_errors++; // Detailed Error analysis if (pPkt[i].rxOOB.cmdSts & (CS_RXA | CS_ERR_RXO)) { adapter->netStats.rx_over_errors++; } if (pPkt[i].rxOOB.cmdSts & CS_ERR_RX_CRCE) { adapter->netStats.rx_crc_errors++; } if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_LONG | CS_ERR_RX_RUNT)) { adapter->netStats.rx_length_errors++; } if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_ISE | CS_ERR_RX_FAE)) { adapter->netStats.rx_frame_errors++; } } } else { if (pPkt[i].packetStatus != NS_STATUS_ABORTED) { adapter->netStats.rx_errors++; adapter->netStats.rx_length_errors++; } for (j = 0x0; j < (pPkt[i].fragCount - 1); j++) { pFragTail = pFragTail->pNextFrag; } } // Put the frags back on the cache adapter->rxFragsTail->pNextFrag = pPkt[i].pFragHead; pFragTail->pNextFrag = NULL; adapter->rxFragsTail = pFragTail; } NO(NsmReceive); return; } //***************************************************************************** // NsmLinkStatusChange // Link status change Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // // Return Value // None //***************************************************************************** NS_VOID NsmLinkStatusChange( IN NS_VOID *pClientDevHndl ) { NSM_CONTEXT *adapter = pClientDevHndl; // Start a tasklet to process the Link change and return tasklet_schedule(&adapter->linkMonTask); return; } DP8381X-Linux-Ver-1.6/nsm.h0000444000000000000000000001222710430225716013634 0ustar rootroot //****************************************************************************** // // NSM.H // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // Linux core related defines for MacPhyter // //***************************************************************************** #ifndef _NSM_H_ #define _NSM_H_ #include #include #include #ifdef NSM_DIAG_MODE #include #include #endif //NSM_DIAG_MODE // Our DMA capability mask #define NSM_DMA_MASK (~0x0UL) #define PCIPM 0x44 #define BAR_0 0 #define BAR_1 1 #define ENET_MTU 1500 #define ENET_BUFFER_SIZE 1536 #define ENET_HEADER_SIZE 14 #define CRC_LENGTH 4 // NSM Defaults for User Configurable values #define NSM_DEFAULT_TXD_CNT 64 #define NSM_DEFAULT_TX_Q_CNT 1 #define NSM_DEFAULT_TX_FILL_THOLD 512 #define NSM_DEFAULT_TX_DRAIN_THOLD 64 #define NSM_DEFAULT_TX_MAX_DMA 256 #define NSM_DEFAULT_TX_MAX_INDY 1 #define NSM_DEFAULT_RXD_CNT 64 #define NSM_DEFAULT_RX_Q_CNT 1 #define NSM_DEFAULT_RX_DRAIN_THOLD 128 #define NSM_DEFAULT_RX_MAX_DMA 256 #define NSM_DEFAULT_RX_MAX_INDY 1 #define NSM_DEFAULT_RX_REPL 4 #define NSM_DEFAULT_LINK_MODE MPL_LINK_MODE_AUTO #define NSM_DEFAULT_LINK_SPEED MPL_LINK_SPEED_HUNDREDMBPS #define NSM_DEFAULT_LINK_DUPLEX MPL_LINK_DUPLEX_FULL #define NSM_DEFAULT_LINK_PAUSE MPL_LINK_PAUSE_RECEIVE #define NSM_DEFAULT_LINK_PAUSE_COUNTER 0x0004 #define NSM_DEFAULT_LINK_PAUSE_DALO 0 #define NSM_DEFAULT_LINK_PAUSE_DAHI 0 #define NSM_DEFAULT_LINK_PAUSE_STHI 0 #define NSM_DEFAULT_LINK_PAUSE_STHI 0 #define NSM_DEFAULT_INTR_TIMER_HOLD 100 #define NSM_DEFAULT_INTR_TX_HOLD 2 #define NSM_DEFAULT_INTR_RX_HOLD 2 #define NSM_DEFAULT_MODE MPL_MODE_NORMAL //#define NSM_DEFAULT_MODE MPL_MODE_MONITOR typedef struct NSM_CONTEXT { // Pointer to next and prev context struct _NSM_CONTEXT *next; struct _NSM_CONTEXT *prev; // Count of NSC Nics found so far NS_UINT8 cardIndex; // Driver details NS_UINT verMajor; // Driver version - Major NS_UINT verMinor; // Driver version - Minor MPL_MODE opMode; // Current Operation Mode // Pci stuff struct pci_dev *pdev; NS_UINT8 pciRevId; NS_UINT16 pciSubVendorId; NS_UINT16 pciSubDeviceId; NS_UINT8 pciBusWidth; // Base device Memory IO address NS_VOID *regAddr; // Irq NS_UINT8 irq; // MPL capabilities MPL_CAPS mplCaps; // Receive NS_UINT16 rxBufferLen; NS_UINT16 rxdCnt; NS_UINT8 rxQCnt; NS_UINT rxdEmpty; NS_VOID *rxFrags; MPL_PKT_FRAG *rxFragsHead; MPL_PKT_FRAG *rxFragsTail; spinlock_t rxLock; // Transmit spinlock_t txLock; NS_UINT16 txdCnt; NS_UINT8 txQCnt; NS_UINT16 mtu; // Link MPL_LINK_NEGOTIATION linkMode; MPL_LINK_SPEED linkSpeed; MPL_LINK_DUPLEX linkDuplex; NS_UINT linkPause; MPL_LINK_STATUS linkStatus; struct tasklet_struct linkMonTask; spinlock_t linkLock; // Intr NS_UINT timerHold; NS_UINT txHold; NS_UINT rxHold; // Power NS_UINT wolModes; // Stats struct net_device_stats netStats; // MPL context NS_VOID *mplContext; MPL_DEVICE_ID deviceId; // Net stack context struct net_device *netdev; NS_BOOLEAN netdevReg; // Diag related #ifdef NSM_DIAG_MODE MPL_LIST diagTxDoneList; // Tx done pkt list MPL_LIST diagRxDoneList; // Rx done pkt list MPL_LIST diagFreeList; // Free pkt list NS_VOID *diagPkts; // Diag Transmit NS_UINT16 txBufferLen; NS_VOID *txFrags; MPL_PKT_FRAG *txFragsHead; MPL_PKT_FRAG *txFragsTail; NS_UINT diagStsQueueSize; // Size of status queue DIAG_STATS diagStats; // Stats #endif // NSM_DIAG_MODE } NSM_CONTEXT; // Exported functions NS_SINT NsmProbe(struct pci_dev *pdev, const struct pci_device_id *id); NS_SINT NsmSuspend(struct pci_dev *pdev, NS_UINT state); NS_SINT NsmResume(struct pci_dev *pdev); NS_VOID NsmRemove(struct pci_dev *pdev); NS_SINT NsmOpen(struct net_device *netdev); NS_SINT NsmXmit(struct sk_buff *skb, struct net_device *netdev); NS_VOID NsmSetMulti(struct net_device *netdev); struct net_device_stats * NsmStats(struct net_device *netdev); NS_SINT NsmSetMac(struct net_device *netdev, void *p); NS_SINT NsmIoctl(struct net_device *netdev, struct ifreq *ifr, NS_SINT cmd); NS_SINT NsmChangeMtu(struct net_device *netdev, int new_mtu); #ifdef L26 NS_SINT NsmIsr(NS_SINT irq, void *data, struct pt_regs *regs); #else NS_VOID NsmIsr(NS_SINT irq, void *data, struct pt_regs *regs); #endif NS_SINT NsmClose(struct net_device *netdev); NS_BOOLEAN setupRxFrags(NSM_CONTEXT *adapter); NS_VOID freeRxFrags(NSM_CONTEXT *adapter); NS_VOID replenishTask(unsigned long data); // Exported variables extern char DP_driverVersionMaj; // Major Ver extern char DP_driverVersionMin; // Minor Ver #endif DP8381X-Linux-Ver-1.6/nsmdiag.c0000444000000000000000000014515710430225716014465 0ustar rootroot //****************************************************************************** // // NSMDIAG.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // NSM Adapter Diagostics Interface API // // OpMode Combinations // ========================================================== // | || NORMAL | LOAD_ONLY | MONITOR | // | Op Mode ||(non-Diag) | (Diag Mode) | (Diag Mode) | // ========================================================== // | Operation|| O W N E R | // |---------------------------------------------------------- // | H/w Init || NSM | Diag App | NSM | // --------------------------------------------------------- // | Tx/Rx || NSM | Diag App | Diag App | // ========================================================== // // This file contains the API implementations for // o Adapter Txd and Rxd Setup - Diag Mode // o Packet Tx // o Packet Rx // o Cmd demultiplexer // //****************************************************************************** #include #include #ifdef NSM_DIAG_MODE // Local functions static NS_BOOLEAN setupTxFrags(NSM_CONTEXT *adapter); static NS_VOID freeTxFrags(NSM_CONTEXT *adapter); static NS_BOOLEAN pktSetup(NSM_CONTEXT *adapter); static NS_VOID pktFree(NSM_CONTEXT *adapter); static NS_UINT txPkt( NSM_CONTEXT *adapter, NS_APP_XFER_CMD *txCmd, NS_UINT8 *txData); static NS_BOOLEAN checkAvailTxFrag( NSM_CONTEXT *adapter, NS_UINT reqFrags); static NS_UINT pktStatus( NSM_CONTEXT *adapter, MPL_LIST *pList, MPL_PKT_FRAG **ppTailFrag, spinlock_t *pLock, NS_APP_XFER_CMD *pCmd, NS_UINT8 *pData); static NS_VOID pktValidate(NSM_CONTEXT *adapter, MPL_PKT_FRAG *pHeadFrag); static NS_VOID flushTx(NSM_CONTEXT *adapter); static NS_VOID flushRx(NSM_CONTEXT *adapter); static NS_VOID getDiagStats(NSM_CONTEXT *adapter, NS_APP_STATS_CMD *pCmd); static NS_UINT xferCfgSet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd); static NS_UINT xferCfgGet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd); //***************************************************************************** // NsmDiagInitialize // Diag module initialization // // Parameters // adapter // NSM Context // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_RESOURCES // Failed to allocate required resources //***************************************************************************** NS_UINT NsmDiagInitialize( NSM_CONTEXT *adapter) { NI(NsmDiagInitialize); if (adapter->opMode != MPL_MODE_LOAD_ONLY) { // Setup the free MPL frag list (for Tx) if (setupTxFrags(adapter) != NS_TRUE) { NO(NsmDiagInitialize); return NS_STATUS_RESOURCES; } // Setup the Diag packet list (for both Tx and Rx use) if (pktSetup(adapter) != NS_TRUE) { freeTxFrags(adapter); pktFree(adapter); NO(NsmDiagInitialize); return NS_STATUS_RESOURCES; } } else { // Only initialize the lists - The population of the list // happens when the app calls xferCfg MplListInit(&adapter->diagFreeList, NS_FALSE); MplListInit(&adapter->diagTxDoneList, NS_FALSE); MplListInit(&adapter->diagRxDoneList, NS_FALSE); } NO(NsmDiagInitialize); return NS_STATUS_SUCCESS; } //***************************************************************************** // NsmDiagUnInitialize // Diag module uninitialization // // Parameters // adapter // NSM Context // // Return Value // None //***************************************************************************** NS_VOID NsmDiagUnInitialize( NSM_CONTEXT *adapter) { NI(NsmDiagUnInitialize); // Free the Diag Pkt cache pktFree(adapter); // Free the MPL_FRAGs cache for Tx freeTxFrags(adapter); NO(NsmDiagUnInitialize); return; } //***************************************************************************** // NsmDiagIoctl // Diag Cmd Multiplexer // // Parameters // adapter // NSM Context // userAddr // Pointer to user buffer (Would need OS specific tweaking) // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_INVALID_PARM // An invalid parameter value was detected // NS_STATUS_RESOURCES // Failed to allocate required resources // NS_STATUS_NOT_SUPPORTED // Operation not supported // NS_STATUS_FAILURE // Operation failed //***************************************************************************** NS_UINT NsmDiagIoctl( NSM_CONTEXT *adapter, NS_VOID *useraddr) { NS_UINT ret = NS_STATUS_SUCCESS; NS_APP_REG_CMD regCmd; NS_APP_INTRO_CMD introCmd; NS_APP_XFER_CMD xferCmd; NS_APP_XFER_CFG_CMD cfgCmd; NS_APP_STATS_CMD statCmd; NS_APP_CMD baseCmd; NS_UINT cmd; NI(NsmDiagIoctl); // FM: Make all user access funcations as abstracted APIs if (get_user(cmd, (NS_UINT32 *)useraddr)) { NO(NsmDiagIoctl); return NS_STATUS_FAILURE;; } // Handle basic Reg read/write kind of requests here // This is available in all modes switch (cmd) { case NSM_APP_INTRO: if (copy_from_user(&introCmd, useraddr, sizeof(introCmd))) { ret = NS_STATUS_FAILURE; } else { if (introCmd.app == NS_APP_SIGN) { introCmd.driver = NS_DRIVER_SIGN; introCmd.numPorts = 0x01; introCmd.driverVerMajor = DP_driverVersionMaj; introCmd.driverVerMinor = DP_driverVersionMin; } if (copy_to_user(useraddr, &introCmd, sizeof(introCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_REG_READ: if (copy_from_user(®Cmd, useraddr, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } else { regCmd.data = MplRegRead(adapter->mplContext, regCmd.offset); if (copy_to_user(useraddr, ®Cmd, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_REG_WRITE: if (copy_from_user(®Cmd, useraddr, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } else { MplRegWrite(adapter->mplContext, regCmd.offset, regCmd.data); } break; case NSM_PCI_READ: if (copy_from_user(®Cmd, useraddr, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } else { pci_read_config_dword(adapter->pdev, regCmd.offset, (unsigned int *)®Cmd.data); if (copy_to_user(useraddr, ®Cmd, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_PCI_WRITE: if (copy_from_user(®Cmd, useraddr, sizeof(regCmd))) { ret = NS_STATUS_FAILURE; } else { pci_write_config_dword(adapter->pdev, regCmd.offset, regCmd.data); } break; default : ret = NS_STATUS_NOT_SUPPORTED; } // Check if the request is for a Tx/Rx related operation // Note this is only available when we are in one of the two debug modes if (adapter->opMode != MPL_MODE_NORMAL && ret == NS_STATUS_NOT_SUPPORTED) { ret = NS_STATUS_SUCCESS; switch (cmd) { case NSM_XFER_CFG_SET: if (copy_from_user(&cfgCmd, useraddr, sizeof(cfgCmd))) { ret = NS_STATUS_FAILURE; } else { // Call cfg handler cfgCmd.status = xferCfgSet(adapter, &cfgCmd); // Copy results back if (copy_to_user(useraddr, &cfgCmd, sizeof(cfgCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_XFER_CFG_GET: if (copy_from_user(&cfgCmd, useraddr, sizeof(cfgCmd))) { ret = NS_STATUS_FAILURE; } else { // Call cfg handler cfgCmd.status = xferCfgGet(adapter, &cfgCmd); // Copy results back if (copy_to_user(useraddr, &cfgCmd, sizeof(cfgCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_TRANSMIT: if (copy_from_user(&xferCmd, useraddr, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } else { // Call Tx pkt handler xferCmd.status = txPkt(adapter, &xferCmd, (NS_UINT8 *)useraddr + sizeof(xferCmd)); // Copy results back if (copy_to_user(useraddr, &xferCmd, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_TRANSMIT_STATUS: if (copy_from_user(&xferCmd, useraddr, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } else { // Call pkt handler xferCmd.status = pktStatus(adapter, &adapter->diagTxDoneList, &adapter->txFragsTail, &adapter->txLock, &xferCmd, (NS_UINT8 *)useraddr + sizeof(xferCmd)); // Copy results back if (copy_to_user(useraddr, &xferCmd, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_TRANSMIT_FLUSH: if (copy_from_user(&baseCmd, useraddr, sizeof(baseCmd))) { ret = NS_STATUS_FAILURE; } else { flushTx(adapter); } break; case NSM_RECEIVE: if (copy_from_user(&xferCmd, useraddr, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } else { // Call pkt handler xferCmd.pktHandle = 0x0; xferCmd.status = pktStatus(adapter, &adapter->diagRxDoneList, &adapter->rxFragsTail, &adapter->rxLock, &xferCmd, (NS_UINT8 *)useraddr + sizeof(xferCmd)); // Copy results back if (copy_to_user(useraddr, &xferCmd, sizeof(xferCmd))) { ret = NS_STATUS_FAILURE; } } break; case NSM_RECEIVE_FLUSH: if (copy_from_user(&baseCmd, useraddr, sizeof(baseCmd))) { ret = NS_STATUS_FAILURE; } else { flushRx(adapter); } break; case NSM_STATS: if (copy_from_user(&statCmd, useraddr, sizeof(statCmd))) { ret = NS_STATUS_FAILURE; } else { getDiagStats(adapter, &statCmd); if (copy_to_user(useraddr, &statCmd, sizeof(statCmd))) { ret = NS_STATUS_FAILURE; } } break; default : ret = NS_STATUS_NOT_SUPPORTED; } } NO(NsmDiagIoctl); return ret; } //***************************************************************************** // NsmDiagTransmitDone // Transmit Done Notification (Diag Mode) // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose completion is being reported. // pTxDone // MPL allocated MPL_TRANSMIT_DONE structure array in which the // NSM packet handles and statuses are returned. // // Return Value // None //***************************************************************************** NS_VOID NsmDiagTransmitDone( NS_VOID *pClientDevHndl, NS_UINT packetCnt, MPL_TRANSMIT_DONE *pTxDone ) { NSM_CONTEXT *adapter = pClientDevHndl; NS_UINT i, pktSize, fragCnt; DIAG_PKT *dPkt; MPL_LIST_NODE *node; MPL_PKT_FRAG *pFrag, *pHeadFrag, *pTailFrag; NI(NsmDiagTransmitDone); // Unmap and Free done skbs for(i = 0x0; i < packetCnt; i++) { // Get the head frag which was noted as NSM private pHeadFrag = pTxDone[i].pNsmPrivate; // Unmap Buffers pFrag = pHeadFrag; pTailFrag = NULL; pktSize = 0x0; fragCnt = 0x0; while (pFrag) { pci_unmap_single(adapter->pdev, pFrag->physAddr, pFrag->fragSize, PCI_DMA_TODEVICE); pktSize += pFrag->fragSize; fragCnt++; // Get next frag pTailFrag = pFrag; pFrag = pFrag->pNextFrag; } // Update stats if (pTxDone[i].packetStatus == NS_STATUS_SUCCESS) { // Update counters adapter->diagStats.txPackets++; adapter->diagStats.txBytes += pktSize; } else { // Update counters adapter->diagStats.txErrors++; // Detailed Error analysis if (pTxDone[i].cmdSts & CS_ERR_TXA) { adapter->diagStats.txAbortedErrors++; } if (pTxDone[i].cmdSts & CS_ERR_TX_EC) { adapter->diagStats.txCollErrors++; } if (pTxDone[i].cmdSts & CS_ERR_TFU) { adapter->diagStats.txFifoErrors++; } if (pTxDone[i].cmdSts & CS_ERR_TX_CRS) { adapter->diagStats.txCarrierErrors++; } if (pTxDone[i].cmdSts & CS_ERR_TX_OWC) { adapter->diagStats.txWindowErrors++; } } if (pTxDone[i].packetStatus != NS_STATUS_ABORTED) { // If we are are out of free pkt nodes to note this completion // then force a stale one out of the completed list if (MPL_LIST_GET_SIZE(&adapter->diagFreeList) == 0x0) { // Ask ProcessDone function to do a basic validation before freeing NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE, &adapter->diagTxDoneList, &adapter->txFragsTail); adapter->diagStats.txDropped++; } // Get a free diag pkt node from the head of the free list node = MPL_LIST_GET_HEAD(&adapter->diagFreeList); // Get the Diag Pkt linked to the curr node dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link); // Note pkt details dPkt->pktStatus = pTxDone[i].packetStatus; dPkt->cmdSts = pTxDone[i].cmdSts; dPkt->pktSize = pktSize; dPkt->appPktHandle = (NS_UINT)pHeadFrag->pPacketHndl; dPkt->numDesc = fragCnt; // NSM Diag related dPkt->pFrag = pHeadFrag; // Move this packet from the free list to the done list MplListDel(&adapter->diagFreeList, &dPkt->link); MplListAddTail(&adapter->diagTxDoneList, &dPkt->link); } else { // Add the frags back to the free list adapter->txFragsTail->pNextFrag = pHeadFrag; adapter->txFragsTail = pTailFrag; } } NO(NsmDiagTransmitDone); return; } //***************************************************************************** // NsmDiagReceive // Diag mode Receive Done Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose reception is being reported. // pPkt // MPL allocated MPL_PKT structure array in which // a list of the newly received packets are reported // // Return Value // None //***************************************************************************** NS_VOID NsmDiagReceive( NS_VOID *pClientDevHndl, NS_UINT packetCnt, MPL_PKT *pPkt ) { NSM_CONTEXT *adapter = pClientDevHndl; MPL_PKT_FRAG *pTailFrag, *pHeadFrag; DIAG_PKT *dPkt; MPL_LIST_NODE *node; NS_UINT i, j; NI(NsmDiagReceive); // Process the receive list for(i = 0x0; i < packetCnt; i++) { // Get the head frag ptr pHeadFrag = pPkt[i].pFragHead; if (pPkt[i].packetStatus == NS_STATUS_SUCCESS) { // Update counters adapter->diagStats.rxPackets++; adapter->diagStats.rxBytes += pPkt[i].packetSize; } else { // Update counters adapter->diagStats.rxErrors++; // Detailed Error analysis if (pPkt[i].rxOOB.cmdSts & (CS_RXA | CS_ERR_RXO)) { adapter->diagStats.rxOverErrors++; } if (pPkt[i].rxOOB.cmdSts & CS_ERR_RX_CRCE) { adapter->diagStats.rxCrcErrors++; } if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_LONG | CS_ERR_RX_RUNT)) { adapter->diagStats.rxLengthErrors++; } if (pPkt[i].rxOOB.cmdSts & (CS_ERR_RX_ISE | CS_ERR_RX_FAE)) { adapter->diagStats.rxFrameErrors++; } } if (pPkt[i].packetStatus != NS_STATUS_ABORTED) { // If we are are out of free pkt nodes to note this completion // then force a stale one out of the completed list if (MPL_LIST_GET_SIZE(&adapter->diagFreeList) == 0x0) { // Ask ProcessDone function to do a basic validation before freeing NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE, &adapter->diagRxDoneList, &adapter->rxFragsTail); adapter->diagStats.rxDropped++; } // Get a free diag pkt node from the head of the free list node = MPL_LIST_GET_HEAD(&adapter->diagFreeList); // Get the Diag Pkt linked to the curr node dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link); // Note pkt details dPkt->pktStatus = pPkt[i].packetStatus; dPkt->cmdSts = pPkt[i].rxOOB.cmdSts; dPkt->pktSize = pPkt[i].packetSize; dPkt->appPktHandle = 0x0; // Reference handle for Rx pkts dPkt->numDesc = pPkt[i].fragCount; // NSM Diag related dPkt->pFrag = pHeadFrag; // Move this packet from the free list to the done list MplListDel(&adapter->diagFreeList, &dPkt->link); MplListAddTail(&adapter->diagRxDoneList, &dPkt->link); } else { pTailFrag = pHeadFrag; for (j = 0x0; j < (pPkt[i].fragCount - 1); j++) { pTailFrag = pTailFrag->pNextFrag; } // Add the frags back to the free list adapter->rxFragsTail->pNextFrag = pHeadFrag; pTailFrag->pNextFrag = NULL; adapter->rxFragsTail = pTailFrag; } } NO(NsmDiagReceive); return; } //***************************************************************************** // NsmDiagProcessDoneList // Process one or more packets in the Tx/Rx Done queue // // Parameters // adapter // NSM Context // pktCnt // Number of packets to process. // Set this to 0x0 to process all packets in the completion queue // validate // NS_TRUE : Do a basic validation on the packet before releasing it // NS_FALSE : Just release it // pList // Done List (Tx/Rx) to process // ppTailFrag // Pointer to a frag pointer at which to append the freed frags // Return Value // None //***************************************************************************** NS_VOID NsmDiagProcessDoneList( NSM_CONTEXT *adapter, NS_UINT pktCnt, NS_BOOLEAN validate, MPL_LIST *pList, MPL_PKT_FRAG **ppTailFrag) { DIAG_PKT *dPkt; MPL_LIST_NODE *node; NS_UINT i; MPL_PKT_FRAG *pTail; NI(NsmDiagProcessDoneList); // Check if we need to process all pkts if (pktCnt == 0x0) { pktCnt = MPL_LIST_GET_SIZE(pList); } // Process done list node = MPL_LIST_GET_HEAD(pList); for (i = 0x0; i < pktCnt; i++) { if (MPL_LIST_GET_SIZE(pList) == 0x0) { break; //premature? } // Get the Diag Pkt linked to the curr node dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link); // Get the next node node = MPL_LIST_GET_NEXT(node); if (dPkt->pFrag) { // Check if we need to validate this packet before removing if (validate == NS_TRUE) { pktValidate(adapter, dPkt->pFrag); } // Put the frags back on the free frag list pTail = dPkt->pFrag; while (pTail->pNextFrag) { pTail = pTail->pNextFrag; } // Add the frags back to the free list (*ppTailFrag)->pNextFrag = dPkt->pFrag; *ppTailFrag = pTail; } // Move the diag pkt from done list to free list MplListDel(pList, &dPkt->link); MplListAddTail(&adapter->diagFreeList, &dPkt->link); } NO(NsmDiagProcessDoneList); return; } // Local functions //***************************************************************************** // setupTxFrags // Setup the MPL frags for Tx // // Parameters // adapter // NSM Context // Return Value // NS_TRUE : Setup was successful // NS_FALSE : Setup failed //***************************************************************************** static NS_BOOLEAN setupTxFrags( NSM_CONTEXT *adapter) { NS_UINT allocSize, i, nodes; MPL_PKT_FRAG *pFrag = NULL, *prevFrag; NS_VOID *allocMem; NS_BOOLEAN ret = NS_FALSE; struct sk_buff *skb; NI(setupTxFrags); // Allocate memory for the frags = total ring size + sts queue size nodes = adapter->txdCnt + adapter->diagStsQueueSize; allocSize = sizeof(MPL_PKT_FRAG) * nodes; allocMem = kmalloc(allocSize, GFP_KERNEL); if (allocMem == NULL) { NSM_DBG(DBG_ERR,("Failed to Alloc mem to tx frags \n")); NO(setupTxFrags); return ret; } else { // Zero up the memory memset((void *)(allocMem), 0x0, allocSize); pFrag = (MPL_PKT_FRAG *) allocMem; prevFrag = NULL; // Create linked list and attach a buffer for (i = 0x0; i < nodes; i++) { // Allocate buffer skb = dev_alloc_skb(adapter->txBufferLen); if (skb == NULL) { NSM_DBG(DBG_ERR,("SKB alloc in fragSetupTx Failed! \n")); break; } // Mark as being used by this device. skb->dev = adapter->netdev; // Set the Fragment pFrag->pAddr = skb->data; pFrag->pNsmPrivate = skb; // Set link if (prevFrag) { prevFrag->pNextFrag = pFrag; } prevFrag = pFrag; pFrag++; } // Note Head and Tail of this frag list // Note: If the skb allocation fails above then the Tail will point to // the last fragment with successful allocation adapter->txFrags = allocMem; adapter->txFragsHead = (MPL_PKT_FRAG *)allocMem; adapter->txFragsTail = prevFrag; if (prevFrag) { // Managed to allocate some buffers prevFrag->pNextFrag = NULL; ret = NS_TRUE; } } NO(setupTxFrags); return ret; } //***************************************************************************** // freeTxFrags // Free the MPL frags for Tx // // Parameters // adapter // NSM Context // Return Value // None //***************************************************************************** static NS_VOID freeTxFrags( NSM_CONTEXT *adapter) { struct pci_dev *pdev = adapter->pdev; MPL_PKT_FRAG *pFrag = NULL; struct sk_buff* skb; NI(freeTxFrags); // Free attached buffers pFrag = adapter->txFragsHead; while (pFrag) { skb = (struct sk_buff *)pFrag->pNsmPrivate; if (skb != NULL) { // UnMap and Free the sk buffs pci_unmap_single(pdev, (dma_addr_t)pFrag->physAddr, adapter->txBufferLen, PCI_DMA_TODEVICE); dev_kfree_skb(skb); pFrag->pNsmPrivate = NULL; } // Move to the next fragment pFrag = pFrag->pNextFrag; } // Free Frag memory if (adapter->txFrags) { kfree(adapter->txFrags); adapter->txFrags = NULL; adapter->txFragsHead = NULL; } NO(freeTxFrags); return; } //***************************************************************************** // pktSetup // Setup the Diag Pkts Status Queue for Tx and Rx completion handling // // Parameters // adapter // NSM Context // Return Value // NS_TRUE : Setup was successful // NS_FALSE : Setup failed //***************************************************************************** static NS_BOOLEAN pktSetup( NSM_CONTEXT *adapter) { NS_UINT allocSize, i, nodes; NS_VOID *allocMem; NS_BOOLEAN ret = NS_FALSE; DIAG_PKT *pPkt; NI(pktSetup); // Allocate memory for the pkts = both for tx and rx nodes = adapter->diagStsQueueSize * 2; allocSize = sizeof(DIAG_PKT) * nodes; allocMem = kmalloc(allocSize, GFP_KERNEL); if (allocMem == NULL) { NSM_DBG(DBG_ERR,("Failed to Alloc mem to diag pkts \n")); NO(pktSetup); return ret; } else { // Note mem adapter->diagPkts = allocMem; // Zero up the memory memset((void *)(allocMem), 0x0, allocSize); pPkt = (DIAG_PKT *) allocMem; // Initialize Diag packet free list MplListInit(&adapter->diagFreeList, NS_FALSE); // Add nodes to the list for (i = 0x0; i < nodes; i++) { MplListAddTail(&adapter->diagFreeList, &pPkt->link); pPkt++; //Get the next packet } // Initialize Diag packet done list (for Tx) - Starts with no nodes MplListInit(&adapter->diagTxDoneList, NS_FALSE); // Initialize Diag packet done list (for Rx) - Starts with no nodes MplListInit(&adapter->diagRxDoneList, NS_FALSE); ret = NS_TRUE; } NO(pktSetup); return ret; } //***************************************************************************** // pktFree // Free the diag packets in status queue // // Parameters // adapter // NSM Context // Return Value // None //***************************************************************************** static NS_VOID pktFree( NSM_CONTEXT *adapter) { NI(pktFree); // Clear Tx done list NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE, &adapter->diagTxDoneList, &adapter->txFragsTail); // Clear Rx done list NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE, &adapter->diagRxDoneList, &adapter->rxFragsTail); // UnInitialize Diag packet done list (for Tx) MplListDeInit(&adapter->diagTxDoneList); // UnInitialize Diag packet done list (for Rx) MplListDeInit(&adapter->diagRxDoneList); // UnInitialize Diag packet free list MplListDeInit(&adapter->diagFreeList); // Free Pkt memory if (adapter->diagPkts) { kfree(adapter->diagPkts); adapter->diagPkts = NULL; } NO(pktFree); return; } //***************************************************************************** // txPkt // Diag module tx // // Parameters // adapter // NSM Context // txCmd // Command block describing the Tx // txData // Data block for this Tx // // Return Value // NS_STATUS_SUCCESS // The initialization was successfully done // NS_STATUS_RESOURCES // Failed to allocate required resources // NS_STATUS_FAILURE // Failed to transmit //***************************************************************************** static NS_UINT txPkt( NSM_CONTEXT *adapter, NS_APP_XFER_CMD *txCmd, NS_UINT8 *txData) { MPL_PKT_FRAG *pFrag, *headFrag, *prevFrag, *qFrag; MPL_PKT mplPkt; NS_UINT status, fragsReq, bytesToGo, src, fragCnt, i; NI(txPkt); // Test if the link is up and the diag tx engine is initialized if ((adapter->linkStatus != MPL_LINK_STATUS_UP) || (adapter->txFragsHead == NULL)) { NO(txPkt); return NS_STATUS_FAILURE; } if (txCmd->packetSize == 0x0) { // What? NO(txPkt); return NS_STATUS_INVALID_PARM; } // Compute the number of frags needed fragsReq = (txCmd->packetSize + adapter->txBufferLen - 1) / adapter->txBufferLen; // Make sure we have enough frags to sent this pkt // if not force some from the done list spin_lock_irq(&adapter->txLock); while(checkAvailTxFrag(adapter, fragsReq) != NS_TRUE) { // Force some frags from the Done list NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE, &adapter->diagTxDoneList, &adapter->txFragsTail); } spin_unlock_irq(&adapter->txLock); // Setup the frags headFrag = pFrag = adapter->txFragsHead; headFrag->pPacketHndl = (NS_VOID *)txCmd->pktHandle; // Initialize byte counters bytesToGo = txCmd->packetSize; src = 0x0; prevFrag = NULL; while (bytesToGo) { if (adapter->txBufferLen >= bytesToGo) { // Final MPL Frag pFrag->fragSize = bytesToGo; } else { // More data to go.. Map as much data as allowed and move on pFrag->fragSize = adapter->txBufferLen; } // Set the frag, copy data to frag if (copy_from_user(pFrag->pAddr, &txData[src], pFrag->fragSize)) { return NS_STATUS_FAILURE; } pFrag->physAddr = pci_map_single(adapter->pdev, pFrag->pAddr, pFrag->fragSize, PCI_DMA_TODEVICE); // Reduce bytes to go by the size copied bytesToGo -= pFrag->fragSize; // Note the current frag prevFrag = pFrag; // Update data offset src += pFrag->fragSize; // Get a new frag pFrag = pFrag->pNextFrag; } // Prep the MPL pkt mplPkt.pNextPacket = NULL; mplPkt.fragCount = fragsReq; // Set priority after validating if ((txCmd->pQueue < 0x1) || (txCmd->pQueue > adapter->mplCaps.txCaps.priorityQCnt)) { // Default to queue 1 - This is returned back to App txCmd->pQueue = 0x1; } mplPkt.txOOB.pQueue = txCmd->pQueue; mplPkt.pFragHead = headFrag; mplPkt.packetSize = txCmd->packetSize; mplPkt.pNsmPrivate = headFrag; // Head frag as handle // Send Packet spin_lock_irq(&adapter->txLock); status = MplTransmit(adapter->mplContext, 0x01, &mplPkt); // Check status if (status == NS_STATUS_SUCCESS) { // Prep for returning status of this packet // Partial status is also returned back to the App to handle // cases where the Tx never completes txCmd->numDesc = mplPkt.fragCount; // Copy physical address used for this transfer qFrag = headFrag; fragCnt = (mplPkt.fragCount < NS_APP_MAX_FRAG_INFO) ? mplPkt.fragCount : NS_APP_MAX_FRAG_INFO; for (i = 0x0; i < fragCnt; i++) { txCmd->descPhyAddr[i] = (NS_ADDR)qFrag->pMplPrivate; txCmd->bufPhyAddr[i] = qFrag->physAddr; qFrag = qFrag->pNextFrag; } // Move the headFrag pointer - this update happens only on Tx success adapter->txFragsHead = pFrag; prevFrag->pNextFrag = NULL; // Detach frags for current pkt } // Release lock spin_unlock_irq(&adapter->txLock); NO(txPkt); return status; } //***************************************************************************** // checkAvailTxFrag // Check is the required Tx Frags are available for transmiting this pkt // // Parameters // adapter // NSM Context // reqFrags // Number of frags required // // Return Value // NS_TRUE // Available // NS_FALSE // Not Available //***************************************************************************** static NS_BOOLEAN checkAvailTxFrag( NSM_CONTEXT *adapter, NS_UINT reqFrags) { NS_UINT cnt = 0x0; MPL_PKT_FRAG *pFrag; NI(checkAvailTxFrag); pFrag = adapter->txFragsHead; while (cnt < reqFrags) { if (pFrag == adapter->txFragsTail) { NO(checkAvailTxFrag); return NS_FALSE; } pFrag = pFrag->pNextFrag; cnt++; } NO(checkAvailTxFrag); return NS_TRUE; } //***************************************************************************** // pktStatus // Checks the status of previous Tx pkt // // Parameters // adapter // NSM Context // pList // List to process from // ppTailFrag // Pointer to a frag pointer at which to append the freed frags // pLock // Pointer to the lock controlling access to parent list // pCmd // Command block describing the pkt // pData // Destination location to copy data // // Return Value // NS_STATUS_SUCCESS // The packet was successfully sent // NS_STATUS_INVALID_PARM // The specified packet handle was not found // Note: This could happen when the status queue was oveflowed too // NS_STATUS_FAILURE // The packet completed with a failure // NS_STATUS_RESOURCES // The pkt could not be copied since the buffer is of smaller size //***************************************************************************** static NS_UINT pktStatus( NSM_CONTEXT *adapter, MPL_LIST *pList, MPL_PKT_FRAG **ppTailFrag, spinlock_t *pLock, NS_APP_XFER_CMD *pCmd, NS_UINT8 *pData) { DIAG_PKT *dPkt; MPL_PKT_FRAG *pFrag, *pTail, *pHead = NULL; MPL_LIST_NODE *node; NS_UINT status = NS_STATUS_INVALID_PARM, dst, fragCnt; NI(pktStatus); // Take lock and search for the pkt in the done list spin_lock_irq(pLock); for (node = MPL_LIST_GET_HEAD(pList); MPL_LIST_CHK_END(pList, node) == NS_FALSE; node = MPL_LIST_GET_NEXT(node)) { dPkt = MPL_LIST_GET_ENTRY(node, DIAG_PKT, link); // Match the app pkt handle with what we have if (dPkt->appPktHandle == pCmd->pktHandle) { // Found the requested pkt // Prep response pCmd->numDesc = dPkt->numDesc; pCmd->cmdSts = dPkt->cmdSts; pCmd->packetSize = dPkt->pktSize; status = dPkt->pktStatus; // Note head frag pointer and detach from packet pHead = dPkt->pFrag; dPkt->pFrag = NULL; // Move the Diag pkt node from Rx done to free list MplListDel(pList, &dPkt->link); MplListAddTail(&adapter->diagFreeList, &dPkt->link); // Return count of completed pkts waiting for app pCmd->morePkts = MPL_LIST_GET_SIZE(pList); break; } } spin_unlock_irq(pLock); // If we managed to find the req node then free the frags // since we are done with this packet if (pHead) { pTail = pFrag = pHead; dst = fragCnt = 0x0; // Do the copy of the data etc.. This is done outside of the locks while (pFrag) { if (pCmd->flags & NSM_APP_XFER_COPY) { // Check for overflow if (dst > pCmd->bufSize) { status = NS_STATUS_RESOURCES; } else { // Copy data back if (copy_to_user(&pData[dst], pFrag->pAddr, pFrag->fragSize)) { status = NS_STATUS_FAILURE; } dst += pFrag->fragSize; } } // Copy physical address used for this transfer if (fragCnt < NS_APP_MAX_FRAG_INFO) { pCmd->descPhyAddr[fragCnt] = (NS_ADDR)pFrag->pMplPrivate; pCmd->bufPhyAddr[fragCnt++] = pFrag->physAddr; } // Get next frag pTail = pFrag; pFrag = pFrag->pNextFrag; } // Add the frags back to the free list spin_lock_irq(pLock); (*ppTailFrag)->pNextFrag = pHead; *ppTailFrag = pTail; spin_unlock_irq(pLock); } NO(pktStatus); return status; } //***************************************************************************** // pktValidate // Do some basic validation on the pkt, and update stats // // Parameters // adapter // NSM Context // pHeadFrag // Pointer to the head fragment in the pkt // Return Value // None //***************************************************************************** static NS_VOID pktValidate( NSM_CONTEXT *adapter, MPL_PKT_FRAG *pHeadFrag) { NI(pktValidate); NO(pktValidate); return; } //***************************************************************************** // flushRx // Dump all pkts in done list and puts the frags and Diag Pkts back on // free lists // // Parameters // adapter // NSM Context // Return Value // None //***************************************************************************** static NS_VOID flushRx( NSM_CONTEXT *adapter) { NI(flushRx); spin_lock_irq(&adapter->rxLock); // Force all frags from the Done list NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE, &adapter->diagRxDoneList, &adapter->rxFragsTail); // Clear all stats adapter->diagStats.rxPackets = 0x0; adapter->diagStats.rxBytes = 0x0; adapter->diagStats.rxErrors = 0x0; adapter->diagStats.rxDropped = 0x0; adapter->diagStats.rxLengthErrors = 0x0; adapter->diagStats.rxOverErrors = 0x0; adapter->diagStats.rxCrcErrors = 0x0; adapter->diagStats.rxFrameErrors = 0x0; spin_unlock_irq(&adapter->rxLock); NO(flushRx); return; } //***************************************************************************** // flushTx // Dump all pkts in done list and puts the frags and Diag Pkts back on // free lists // // Parameters // adapter // NSM Context // Return Value // None //***************************************************************************** static NS_VOID flushTx( NSM_CONTEXT *adapter) { NI(flushTx); spin_lock_irq(&adapter->txLock); // Force all frags from the Done list NsmDiagProcessDoneList(adapter, 0x0, NS_FALSE, &adapter->diagTxDoneList, &adapter->txFragsTail); // Clear all stats adapter->diagStats.txPackets = 0x0; adapter->diagStats.txBytes = 0x0; adapter->diagStats.txErrors = 0x0; adapter->diagStats.txDropped = 0x0; adapter->diagStats.txCollErrors = 0x0; adapter->diagStats.txAbortedErrors = 0x0; adapter->diagStats.txCarrierErrors = 0x0; adapter->diagStats.txFifoErrors = 0x0; adapter->diagStats.txWindowErrors = 0x0; spin_unlock_irq(&adapter->txLock); NO(flushTx); return; } //***************************************************************************** // getDiagStats // Diag module check status of previous Tx // // Parameters // adapter // NSM Context // pCmd // Diag Stats command request // // Return Value // None //***************************************************************************** static NS_VOID getDiagStats( NSM_CONTEXT *adapter, NS_APP_STATS_CMD *pCmd) { NI(getDiagStats); // Basic Tx, Rx pCmd->rxPackets = adapter->diagStats.rxPackets; pCmd->txPackets = adapter->diagStats.txPackets; pCmd->rxBytes = adapter->diagStats.rxBytes; pCmd->txBytes = adapter->diagStats.txBytes; pCmd->rxErrors = adapter->diagStats.rxErrors; pCmd->txErrors = adapter->diagStats.txErrors; pCmd->rxDropped = adapter->diagStats.rxDropped; pCmd->txDropped = adapter->diagStats.txDropped; // detailed rx_errors - As seen in descriptor cmdsts pCmd->rxLengthErrors = adapter->diagStats.rxLengthErrors; pCmd->rxOverErrors = adapter->diagStats.rxOverErrors; pCmd->rxCrcErrors = adapter->diagStats.rxCrcErrors; pCmd->rxFrameErrors = adapter->diagStats.rxFrameErrors; // detailed tx_errors - As seen in descriptor cmdsts pCmd->txCollErrors = adapter->diagStats.txCollErrors; pCmd->txAbortedErrors = adapter->diagStats.txAbortedErrors; pCmd->txCarrierErrors = adapter->diagStats.txCarrierErrors; pCmd->txFifoErrors = adapter->diagStats.txFifoErrors; pCmd->txWindowErrors = adapter->diagStats.txWindowErrors; NO(getDiagStats); return; } //***************************************************************************** // xferCfgSet // Configure the Tx/Rx engine // // Parameters // adapter // NSM Context // pCmd // Diag xfer cfg command request // // Return Value // NS_STATUS_SUCCESS // The requested configurations were successfully applied // NS_STATUS_INVALID_PARM // The configuration values are not valid // NS_STATUS_FAILURE // The requested configuration could not be applied on the device // NS_STATUS_RESOURCES // Resources required for this configuration could not be allocated //***************************************************************************** static NS_UINT xferCfgSet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd) { MPL_TRANSMIT_CFG txCfg; MPL_RECEIVE_CFG rxCfg; NS_UINT i; NS_UINT status; NI(xferCfgSet); // Step0: Validate the parameters before doing any work if (pCmd->txpQueueCnt > adapter->mplCaps.txCaps.priorityQCnt) { return NS_STATUS_INVALID_PARM; } // Step1: Reset current configuration // Reset Tx and Rx engines - This gives all buffers frags back to NSM spin_lock_irq(&adapter->txLock); MplTransmitReset(adapter->mplContext); spin_unlock_irq(&adapter->txLock); spin_lock_irq(&adapter->rxLock); MplReceiveReset(adapter->mplContext); spin_unlock_irq(&adapter->rxLock); // Free the Diag pkts - This flushes the pkts in the done list too pktFree(adapter); // Free the fragments, tx and rx freeTxFrags(adapter); freeRxFrags(adapter); // Step2: Set the new values adapter->rxdCnt = pCmd->rxDescCnt; adapter->txdCnt = pCmd->txDescCnt; adapter->diagStsQueueSize = pCmd->stsQueueSize; adapter->rxBufferLen = pCmd->rxBufferLen; adapter->txBufferLen = pCmd->txBufferLen; adapter->txQCnt = pCmd->txpQueueCnt; adapter->rxQCnt = NSM_DEFAULT_RX_Q_CNT; //Force it to one // Step3: Apply the new values txCfg.cfgFlags = MPL_TRANSMIT_CFG_QUEUES; txCfg.maxIndications = NSM_DEFAULT_TX_MAX_INDY; txCfg.priorityQueueCnt = adapter->txQCnt; for (i = 0x0; i < adapter->txQCnt; i++) { txCfg.descCnt[i] = adapter->txdCnt; } // Tell MPL about the new Tx configurations status = MplTransmitCfg(adapter->mplContext, &txCfg); if (status == NS_STATUS_SUCCESS) { rxCfg.cfgFlags = MPL_RECEIVE_CFG_QUEUES; rxCfg.maxIndications = NSM_DEFAULT_RX_MAX_INDY; rxCfg.priorityQueueCnt = adapter->rxQCnt; for (i = 0x0; i < adapter->rxQCnt; i++) { rxCfg.descCnt[i] = adapter->rxdCnt; } // Tell MPL about the new Rx configurations status = MplReceiveCfg(adapter->mplContext, &rxCfg); } // Diag related setup if (status == NS_STATUS_SUCCESS) { // Setup new frags based on the new settings if ((setupTxFrags(adapter) == NS_TRUE) && (setupRxFrags(adapter) == NS_TRUE)) { // Set up status queue Diag packets based on new status Queue size if (pktSetup(adapter) == NS_TRUE) { // Replenish the device's receive engine with new buffers replenishTask((unsigned long)adapter); } else { freeRxFrags(adapter); freeTxFrags(adapter); status = NS_STATUS_RESOURCES; } } else { freeRxFrags(adapter); freeTxFrags(adapter); status = NS_STATUS_RESOURCES; } } NO(xferCfgSet); return status; } //***************************************************************************** // xferCfgGet // Get the Tx/Rx engine configurations // // Parameters // adapter // NSM Context // pCmd // Diag xfer cfg command request // // Return Value // NS_STATUS_SUCCESS // The requested configurations were successfully applied //***************************************************************************** static NS_UINT xferCfgGet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd) { NI(xferCfgGet); pCmd->rxDescCnt = adapter->rxdCnt; pCmd->txDescCnt = adapter->txdCnt; pCmd->stsQueueSize = adapter->diagStsQueueSize; pCmd->rxBufferLen = adapter->rxBufferLen; pCmd->txBufferLen = adapter->txBufferLen; pCmd->txpQueueCnt = adapter->txQCnt; NO(xferCfgGet); return NS_STATUS_SUCCESS; } #endif //NSM_DIAG_MODE DP8381X-Linux-Ver-1.6/Makefile.2.60000444000000000000000000000337410430225716014635 0ustar rootroot# # Makefile for building National Semiconductor MacPhyter2 Drivers ## # Name of my module MODULE_NAME = macphy # MPL dirs MPLDIR = Mpl MPLPUB = $(MPLDIR)/Public MPLTASKS = $(MPLDIR)/Tasks # NSM files $(MODULE_NAME)-objs = \ nsmos.o \ nsmdiag.o \ nsmmpl.o #MPL Src Files $(MODULE_NAME)-objs += \ $(MPLTASKS)/mpltaskrxfilter.o \ $(MPLTASKS)/mpltaskvlan.o \ $(MPLDIR)/mplutil.o \ $(MPLDIR)/mpldebug.o \ $(MPLDIR)/mplintr.o \ $(MPLDIR)/mplmisc.o \ $(MPLDIR)/mplphy.o \ $(MPLDIR)/mpllink.o \ $(MPLDIR)/mplreceive.o \ $(MPLDIR)/mpltransmit.o \ $(MPLDIR)/mplcaps.o \ $(MPLDIR)/mplpwr.o \ $(MPLDIR)/mplinitshutdown.o #Driver flags DRVFLAGS := -DLINUX -D__KERNEL__ -O2 -Wall -DMODULE -DL26 #Driver flags - Remove trailing 1 to enable a flag DRVFLAGS += -DNSM_DIAG_MODE1 -DMPL_CHECKED_BUILD1 -DNSM_DEBUG1 -DLINUX_POWER_DEBUG1 -DNSM_IO_MAP1 DRVFLAGS += -I$(PWD)/$(MPLPUB) -I$(PWD)/$(MPLTASKS) -I$(PWD)/$(MPLDIR) -I$(PWD) #Append driver flags to global CFlags EXTRA_CFLAGS += $(DRVFLAGS) # First pass, kernel Makefile reads module objects ifneq ($(KERNELRELEASE),) obj-m := $(MODULE_NAME).o # Second pass, the actual build. else KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) all: @echo $(DRVFLAGS) @echo $(PWDO) $(MAKE) -C $(KDIR) M=$(PWD) modules @cp $(MODULE_NAME).ko ../bin @echo @echo "NSC Kernel Module" $(MODULE_NAME).ko "Ready" @echo "Run \"make install\" next" @echo clean: $(MAKE) -C $(KDIR) M=$(PWD) clean distclean: clean $(RM) $(OBJS) help: $(MAKE) -C $(KDIR) M=$(PWD) help install: $(MAKE) -C $(KDIR) M=$(PWD) modules_install endif DP8381X-Linux-Ver-1.6/nsmos.c0000666000000000000000000013714510430226432014202 0ustar rootroot //****************************************************************************** // // NSMOS.C // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // NSM Driver for MPL based MacPhyter Devices // //****************************************************************************** #include MODULE_LICENSE("GPL"); MODULE_AUTHOR("NSC"); MODULE_DESCRIPTION("NSC DP8381X 10/100Mbps MacPhyter Ethernet"); // Max NICs supported by this driver #define DP_MAX_NIC 8 // Globals char DP_driverName[] = "DP8381X"; char DP_driverString[]="NSC Macphyter Driver"; char DP_driverVersionMaj = 1; // Major Ver char DP_driverVersionMin = 6; // Minor Ver char DP_driverVersion[] = "n.1.6"; char DP_copyright[] = "Copyright (c) 2005-2007 National Semiconductor"; char DP83815_ID[] = "DP83815 (MacPhyter-I)"; char DP83816_ID[] = "DP83816 (MacPhyter-II)"; char DP83818_ID[] = "DP83818 (MacPhyter-III)"; char UNKNOWN_ID[] = "UNKNOWN"; // Module Params // Initialize all to -1 i.e not configured #define DP_PARAM_INIT { [0 ... (DP_MAX_NIC - 1)] = -1} #define DP_PARAM(PARM, DESC) \ static const int __devinitdata PARM[DP_MAX_NIC] = DP_PARAM_INIT; \ MODULE_PARM(PARM, "1-" __MODULE_STRING(DP_MAX_NIC) "i"); \ MODULE_PARM_DESC(PARM, DESC); // Number of Transmit Descriptors (32bytes each) // Default : 64 DP_PARAM(TxDCnt, "Number Of Transmit Descriptors"); // Number of Transmit Queues to be enabled // Default : 1, Max : 4 (only on DP83818) DP_PARAM(TxQCnt, "Number Of Transmit Queues"); // Number of Receive Descriptors (32bytes each) // Default : 64 DP_PARAM(RxDCnt, "Number Of Receive Descriptors"); // Number of Receive Queues to be enabled // Default : 1, Max : 1 DP_PARAM(RxQCnt, "Number Of Receive Queues"); // Desired Link Setup Mode // 0 : Auto Negotiate (Default) // 1 : Force Speed and Duplex Mode DP_PARAM(LinkMode, "Link Setup Mode"); // Desired Link Speed // Note : If set in AutoNeg mode then this is the Max speed advertized // 0 : 100Mbps (Default) // 1 : 10Mbps DP_PARAM(LinkSpeed, "Link Speed"); // Desired Link Duplex Mode // Note : If set in AutoNeg mode then this is the mode advertized // 0 : Full Duplex (Default) // 1 : Half Duplex DP_PARAM(LinkDuplex, "Link Duplex Mode"); // Desired Link Pause Mode // Note : If set in AutoNeg mode then this is the mode advertized // 0 : Receive Pause Only (Default) // 1 : Transmit Pause Only // 2 : Transmit and Receive Pause (Symmetrical) // 3 : No Pause generation DP_PARAM(LinkPause, "Link Pause Mode"); // Interrupt Holdoff in usec (Micro) // Default : 100 // Max : 25500 (i.e. 25.5 msec) DP_PARAM(IntTimeHold, "Interrupt Holdoff"); // Interrupt Holdoff in Tx pkt count // Default : 2 // Max : 63 DP_PARAM(IntTxHold, "Interrupt Holdoff in Tx Packets"); // Interrupt Holdoff in Rx pkt count // Default : 2 // Max : 63 DP_PARAM(IntRxHold, "Interrupt Holdoff in Rx Packets"); // Driver Operation Mode // 0 : Normal (Default) // 1 : Monitor (National Semiconductor Internal) // 2 : Load Only (National Semiconductor Internal) DP_PARAM(OpMode, "Driver Operational Mode"); // Desired Wol Events (Logical OR) // 0x01 : MPL_WOL_MAGIC - Enable wake on Magic Pattern. // 0x04 : MPL_WOL_BROADCAST - Enable wake on any broadcast packet. // 0x08 : MPL_WOL_MULTICAST - Enable wake on multicast packet. // 0x10 : MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to // the device's address. // 0x20 : MPL_WOL_LINK - Enable wake on link status change. // 0x40 : MPL_WOL_ARP - Enable wake on any ARP packet. DP_PARAM(Wol, "Wake-on-LAN Events"); #ifdef NSM_DIAG_MODE // Number of pkts possible in the status queue // Default : 256 DP_PARAM(DiagStsQueue, "Size of the Diag Status Queue"); #endif //NSM_DIAG_MODE #ifdef NSM_DEBUG // NSM (OS Specific Module) Debug Zones to be enabled DP_PARAM(NsmDebugZones, "Debug Zones For NSM Module"); // MPL (Hardware Abstraction Layer) Debug Zones to be enabled DP_PARAM(MplDebugZones, "Debug Zones For MPL Module"); // Debug Zones for this file NS_UINT NsmDbgSettings = DBG_INFO | DBG_FUNC | DBG_TMP | DBG_ERR; NS_UINT MplPathZones = DZONE_MPL_INIT_DOWN | DZONE_MPL_TRANS | DZONE_MPL_RECV | DZONE_MPL_INTR | DZONE_MPL_LINK | DZONE_MPL_PWR | DZONE_MPL_DIAG | DZONE_MPL_MISC; NS_UINT MplMsgZones = DZONE_MPL_INIT_DOWN | DZONE_MPL_TRANS | DZONE_MPL_RECV | DZONE_MPL_INTR | DZONE_MPL_LINK | DZONE_MPL_PWR | DZONE_MPL_DIAG | DZONE_MPL_MISC; #else NS_UINT NsmDbgSettings = 0x0; NS_UINT MplPathZones = 0x0; NS_UINT MplMsgZones = 0x0; #endif // Adapter count unsigned NsmAdapterCnt = 0x0; /********************************************************************* * PCI device list for NSC MacPhyter adapters * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, * Class, Class Mask, String Index } * Last device should be 0 *********************************************************************/ #define PCI_DEVICE_ID_DP8381X 0x0020 static struct pci_device_id DP_pciTable[] = { { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP8381X, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } }; MODULE_DEVICE_TABLE(pci, DP_pciTable); // PCI driver struct for this driver static struct pci_driver DP_driver = { name: DP_driverName, id_table: DP_pciTable, probe: NsmProbe, remove: NsmRemove, #ifdef CONFIG_PM suspend: NsmSuspend, resume: NsmResume #endif }; // Locals static NS_VOID readPciInfo(NSM_CONTEXT *adapter); static NS_VOID setDataFields(NSM_CONTEXT *adapter); static NS_VOID readUserOptions(NSM_CONTEXT *adapter); static NS_BOOLEAN configMac(NSM_CONTEXT *adapter); static NS_BOOLEAN configLink(NSM_CONTEXT *adapter); static NS_VOID linkTask(unsigned long data); static NS_SINT __init NsmInitModule(void) { NI(NsmInitModule); // Print driver ver printk(KERN_INFO"%s - version %s\n%s\n", DP_driverString, DP_driverVersion, DP_copyright); /* Register to PCI subsystem */ NO(NsmInitModule); return pci_module_init(&DP_driver); } static NS_VOID __exit NsmExitModule(void) { NI(NsmExitModule); // UnRegister from PCI subsystem pci_unregister_driver(&DP_driver); NO(NsmExitModule); return; } // Module entry/exit points module_init(NsmInitModule); module_exit(NsmExitModule); NS_SINT NsmProbe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *netdev = NULL; NSM_CONTEXT *adapter; NS_CHAR *nicId = NULL; NI(NsmProbe); // Make sure we are not exceeding our max card count if (NsmAdapterCnt == DP_MAX_NIC) { NSM_DBG(DBG_ERR,("Card Found exceeds limit \n")); NO(NsmProbe); return -ENODEV; } // Enable this PCI device if(pci_enable_device(pdev) != 0) \ { NSM_DBG(DBG_ERR,("pci_enable_device failed\n")); NO(NsmProbe); return -ENODEV; } // Set the device as Master capable pci_set_master(pdev); // Check to see if our PCI addressing needs are supported if(!pci_dma_supported(pdev, NSM_DMA_MASK)) { NSM_DBG(DBG_ERR,("PCI DMA not supported by the system\n")); NO(NsmProbe); return -ENODEV; } else pdev->dma_mask = NSM_DMA_MASK; // Init the net device, allocate adapter context netdev = alloc_etherdev(sizeof (NSM_CONTEXT)); if(netdev == NULL) { NSM_DBG(DBG_ERR,("Unable to allocate net_device struct\n")); NO(NsmProbe); return -ENOMEM; } // Init adapter context adapter = (NSM_CONTEXT *) netdev->priv; memset(adapter, 0, sizeof(NSM_CONTEXT)); adapter->netdev = netdev; adapter->pdev = pdev; adapter->regAddr = NULL; pci_set_drvdata(pdev, netdev); // Default MTU netdev->mtu = ENET_MTU; if (pci_request_regions(pdev, DP_driverName)) { NSM_DBG(DBG_ERR,("pci_request_region failed\n")); NsmRemove(pdev); NO(NsmProbe); return -ENOMEM; } #ifdef NSM_IO_MAP // We are operating on the IO space netdev->base_addr = pci_resource_start(pdev, BAR_0); adapter->regAddr = (NS_VOID *)netdev->base_addr; netdev->mem_start = pci_resource_start(pdev, BAR_0); netdev->mem_end = netdev->mem_start + pci_resource_len(pdev, BAR_0); #else // We are operating on the Mem space // Remap the IO region adapter->regAddr = ioremap(pci_resource_start(pdev, BAR_1), pci_resource_len(pdev, BAR_1)); if(adapter->regAddr == NULL) { NSM_DBG(DBG_ERR,("ioremap failed\n")); NsmRemove(pdev); NO(NsmProbe); return -ENOMEM; } else { // Let the Net stack know about the IO region netdev->base_addr = pci_resource_start(pdev, BAR_1); netdev->mem_start = pci_resource_start(pdev, BAR_1); netdev->mem_end = netdev->mem_start + pci_resource_len(pdev, BAR_1); } #endif // Read the Pci info readPciInfo(adapter); // Set default values for this adapter struct setDataFields(adapter); // Read module params and note in adapter struct readUserOptions(adapter); // Enable MPL debug levels MplDebEnablePathTracing(MplPathZones); MplDebEnableMsgsAndChecks(MplMsgZones); // MPL Intializations adapter->mplContext = NULL; if (MplInitialize(adapter, adapter->regAddr, adapter->opMode, &adapter->mplContext) != NS_STATUS_SUCCESS) { NsmRemove(pdev); NO(NsmProbe); printk(KERN_INFO"%s - Failed to Initialize Device! \n", DP_driverString); return -ENODEV; } // Set the Netdevice entry points for this adapter netdev->open = &NsmOpen; netdev->stop = &NsmClose; netdev->hard_start_xmit = &NsmXmit; netdev->get_stats = &NsmStats; netdev->set_multicast_list = &NsmSetMulti; netdev->set_mac_address = &NsmSetMac; netdev->do_ioctl = &NsmIoctl; netdev->change_mtu = &NsmChangeMtu; // Register this device to Net Stack SET_MODULE_OWNER(netdev); #ifdef L26 SET_NETDEV_DEV(netdev, &pdev->dev); #endif if (register_netdev(netdev)) { NsmRemove(pdev); NO(NsmProbe); return -ENODEV; } else { adapter->netdevReg = NS_TRUE; } // Hold-off the netdev till we have a link netif_carrier_off(netdev); // Note our irq - The line itself requested after we are open netdev->irq = pdev->irq; // Set Netdevice features - FM: Checksum? netdev->features = NETIF_F_SG; // Note the instance count for this adapter and increment cards found adapter->cardIndex = ++NsmAdapterCnt; nicId = UNKNOWN_ID; if (adapter->opMode != MPL_MODE_LOAD_ONLY) { // Get the current mac addr MplGetMacAddress(adapter->mplContext, NS_FALSE, netdev->dev_addr); // Display device adapter->deviceId = MplGetDeviceId(adapter->mplContext); switch (adapter->deviceId) { case MPL_DEVICE_ID_DP83815 : nicId = DP83815_ID; break; case MPL_DEVICE_ID_DP83816 : nicId = DP83816_ID; break; case MPL_DEVICE_ID_DP83818 : nicId = DP83818_ID; break; default : nicId = UNKNOWN_ID; } } adapter->verMajor = DP_driverVersionMaj; adapter->verMinor = DP_driverVersionMin; printk("%s: v-%d.%d NSC-%s:%x-%x Mem:0x%p IRQ:%d RegAddr:0x%p Mode:%d \n", netdev->name,adapter->verMajor, adapter->verMinor, nicId, adapter->pciSubVendorId, adapter->pciSubDeviceId, (void *)netdev->mem_start, netdev->irq, adapter->regAddr, adapter->opMode); // AOK! NO(NsmProbe); return 0; } #ifdef CONFIG_PM NS_SINT NsmSuspend(struct pci_dev *pdev, NS_UINT state) { struct net_device *netdev = pci_get_drvdata(pdev); NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; MPL_STATUS status; rtnl_lock(); if (netif_running(netdev)) { // We are currently running so, prep for suspend // Disable further Interrupts MplInterruptDisable(adapter->mplContext); // Stop Netstack from sending more pkts netif_stop_queue(netdev); // Reset Receive Engine - To get back pending fragments spin_lock_irq(&adapter->rxLock); MplReceiveReset(adapter->mplContext); spin_unlock_irq(&adapter->rxLock); // Reset Transmit Engine - To get back pending pkt spin_lock_irq(&adapter->txLock); MplTransmitReset(adapter->mplContext); spin_unlock_irq(&adapter->txLock); #ifdef LINUX_POWER_DEBUG MplWolCfg(adapter->mplContext, NS_TRUE, adapter->wolModes); #endif //NSM_DEBUG // Put device in LOW_POWER mode - Ask MPL to set PME for us status = MplPowerSetState(adapter->mplContext, MPL_POWER_STATE_LOW, NS_TRUE); } // Detach our device from active list netif_device_detach(netdev); rtnl_unlock(); return 0; } NS_SINT NsmResume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; MPL_STATUS status; NS_SINT ret; rtnl_lock(); if (netif_device_present(netdev)) { rtnl_unlock(); return 0x0; } if (netif_running(netdev)) { // Enable PCI device ret = pci_enable_device(pdev); // Put device in HIGH_POWER mode status = MplPowerSetState(adapter->mplContext, MPL_POWER_STATE_HIGH, NS_TRUE); // Replenish MPL with Receive Buffers replenishTask((unsigned long)adapter); // Enable Interrupts MplInterruptEnable(adapter->mplContext); // Configure the Link - Done after Ints are enabled configLink(adapter); } // Attach our device to active list netif_device_attach(netdev); rtnl_unlock(); return 0x0; } #endif NS_VOID NsmRemove(struct pci_dev *pdev) { struct net_device *netdev; NSM_CONTEXT *adapter; NI(NsmRemove); netdev = pci_get_drvdata(pdev); // Adapter not found! if(netdev == NULL) { NSM_DBG(DBG_ERR,("Adapter Not Found! \n")); NO(NsmRemove); return; } // Get our private device struct adapter = (NSM_CONTEXT *) netdev->priv; // Unregister this Net device from the OS if (adapter->netdevReg == NS_TRUE) { unregister_netdev(netdev); } // MPL:UnInitialize the adapter if (adapter->mplContext != NULL) { MplUnload(adapter->mplContext); } // Free system resources #ifdef NSM_IO_MAP if(adapter->regAddr != NULL) { adapter->regAddr = NULL; } #else if(adapter->regAddr != NULL) { // First unmap the memory iounmap(adapter->regAddr); adapter->regAddr = NULL; } #endif // Release the PCI address space pci_release_regions(pdev); // Free the Netdev struct and my NSM context struct kfree(netdev); // Decrement cards found NsmAdapterCnt--; NO(NsmRemove); return; } NS_SINT NsmOpen(struct net_device *netdev) { NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; NI(NsmOpen); // Register Interrupt Service Routine if (request_irq(netdev->irq, &NsmIsr, SA_SHIRQ, DP_driverName, adapter)) { NSM_DBG(DBG_ERR,("Failed to Get IRQ \n")); NO(NsmOpen); return -EAGAIN; } // Initialize SpinLocks spin_lock_init(&adapter->txLock); spin_lock_init(&adapter->rxLock); spin_lock_init(&adapter->linkLock); // Get Mpl Capabilities MplGetCaps(adapter->mplContext, &adapter->mplCaps); // Normal and Monitor mode : Cfg Mac, Link, RxFrags // Load only mode : Open only if (adapter->opMode != MPL_MODE_LOAD_ONLY) { // Configure the MAC if (configMac(adapter) == NS_FALSE) { NSM_DBG(DBG_ERR,("Config Mac Failed \n")); free_irq(netdev->irq, adapter); NO(NsmOpen); return -EAGAIN; } // Initialize link monitor tasklet tasklet_init(&adapter->linkMonTask, linkTask, (unsigned long) adapter); //Task Offloads Enables // Rx Filter (Multicast and Unicast Filtering) MplTaskFilterCfg(adapter->mplContext, NS_TRUE); // Allocate and setup MPL_FRAGs to hold Receive Buffers // These are wrapper structures used to post new buffers to MPL rx if (setupRxFrags(adapter) == NS_FALSE) { NSM_DBG(DBG_ERR,("Frag Setup Failed \n")); free_irq(netdev->irq, adapter); NO(NsmOpen); return -ENOMEM; } } #ifdef NSM_DIAG_MODE // Initialize Diag Module if (adapter->opMode != MPL_MODE_NORMAL) { if (NsmDiagInitialize(adapter) != NS_STATUS_SUCCESS) { NSM_DBG(DBG_ERR,("Diag Setup Failed \n")); // Free the MPL Pkt Fragments freeRxFrags(adapter); free_irq(netdev->irq, adapter); NO(NsmOpen); return -ENOMEM; } } #endif //NSM_DIAG_MODE // Open the adapter for operations if (adapter->opMode != MPL_MODE_LOAD_ONLY) { // Replenish MPL with Receive Buffers replenishTask((unsigned long)adapter); // Open the MPL Adapter MplOpen(adapter->mplContext); // Configure the Link - Done after Ints are enabled configLink(adapter); } else { // Open the MPL Adapter - No other setups required here // We just assume the link is up - the diag app would need // to ensure this is the case before doing any tx/rx MplOpen(adapter->mplContext); adapter->linkStatus = MPL_LINK_STATUS_UP; } // If the Link is not UP, notify Net Stack if ((adapter->linkStatus != MPL_LINK_STATUS_UP) || (adapter->opMode != MPL_MODE_NORMAL)) { netif_stop_queue(netdev); } NO(NsmOpen); return 0x0; } NS_SINT NsmXmit(struct sk_buff *skb, struct net_device *netdev) { NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; MPL_PKT mplPkt; MPL_PKT_FRAG mplFrag; MPL_STATUS status; NI(NsmXmit); // Test if the link is down if (adapter->linkStatus != MPL_LINK_STATUS_UP) { NSM_DBG(DBG_ERR,("Link Down \n")); netif_stop_queue(netdev); NO(NsmXmit); return -EAGAIN; } mplPkt.pNextPacket = NULL; mplPkt.fragCount = 0x01; // Set priority - FM: Map to higher level protocol? mplPkt.txOOB.pQueue = 1; // Prep MPL frag mplFrag.pNextFrag = NULL; mplFrag.fragSize = skb->len; mplFrag.physAddr = pci_map_single(adapter->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); mplFrag.pAddr = skb->data; // Store in the physAddr of the skb in the private field *(NS_UINT *)skb->cb = mplFrag.physAddr; // Send Packet mplPkt.pFragHead = &mplFrag; mplPkt.packetSize = skb->len; mplPkt.pNsmPrivate = skb; //Set Skb ptr as NSM private spin_lock_irq(&adapter->txLock); status = MplTransmit(adapter->mplContext, 0x01, &mplPkt); spin_unlock_irq(&adapter->txLock); // Check status if (status != NS_STATUS_SUCCESS) { if (mplPkt.packetStatus == NS_STATUS_RESOURCES) { // Stop the Net Stack netif_stop_queue(netdev); return -ENOMEM; } else { // Drop the pkt - Free the skb pci_unmap_single(adapter->pdev, mplFrag.physAddr, skb->len, PCI_DMA_TODEVICE); dev_kfree_skb(skb); adapter->netStats.tx_dropped++; } } NO(NsmXmit); return 0x0; } void NsmSetMulti(struct net_device *netdev) { NSM_CONTEXT *adapter = netdev->priv; NS_UINT filterFlag, i; struct dev_mc_list *mcAddr; NI(NsmSetMulti); if (adapter->opMode != MPL_MODE_NORMAL) { return; } // Check if we need to go to Promiscuous Mode if (netdev->flags & IFF_PROMISC) { filterFlag = MPL_RECEIVE_FILTER_PROMISCUOUS_MODE; } else { // We always receive directed unicast and broadcast filterFlag = MPL_RECEIVE_FILTER_DIRECTED_UNICAST | MPL_RECEIVE_FILTER_ACCEPTALL_BROADCAST; if (netdev->flags & IFF_ALLMULTI) { // All multicasts filterFlag |= MPL_RECEIVE_FILTER_ACCEPTALL_MCAST; } else { // Accept multicasts directed to our interest list filterFlag |= MPL_RECEIVE_FILTER_DIRECTED_MCAST; // Add multicast list to the device if(netdev->mc_count > 0x0) { // Clear the current MC list MplTaskFilterMcastClearList(adapter->mplContext); // Report the list to MPL mcAddr = netdev->mc_list; for (i = 0x0; i < netdev->mc_count; i++) { if (mcAddr != NULL) { // Add the MC addr MplTaskFilterMcastAddAddr(adapter->mplContext, mcAddr->dmi_addr); // Get the next MC addr mcAddr = mcAddr->next; } } } } } MplReceiveSetFilter(adapter->mplContext, filterFlag); NO(NsmSetMulti); return; } struct net_device_stats * NsmStats(struct net_device *netdev) { NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; // NI(NsmStats); //FM: Update Stats from MPL // NO(NsmStats); return &adapter->netStats; } NS_SINT NsmSetMac(struct net_device *netdev, void *p) { struct sockaddr *mac = p; NSM_CONTEXT *adapter = netdev->priv; NI(NsmSetMac); memcpy(netdev->dev_addr, mac->sa_data, netdev->addr_len); MplSetMacAddress(adapter->mplContext, netdev->dev_addr); NO(NsmSetMac); return 0x0; } NS_SINT NsmIoctl(struct net_device *netdev, struct ifreq *rq, NS_SINT cmd) { NS_SINT ret = 0x0; NSM_CONTEXT *adapter = netdev->priv; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; // NI(NsmIoctl); switch(cmd) { #ifdef NSM_DIAG_MODE // National's Integrity Tool case NS_APP_IOCTL_CODE: { NS_UINT status; // Handle the ioctl status = NsmDiagIoctl(adapter, (NS_VOID *) rq->ifr_data); if (status != NS_STATUS_SUCCESS) { switch (status) { case NS_STATUS_NOT_SUPPORTED: ret = -EOPNOTSUPP; break; case NS_STATUS_INVALID_PARM: ret = -EINVAL; break; case NS_STATUS_RESOURCES: ret = -ENOMEM; break; default : ret = -EFAULT; } } break; } #endif //NSM_DIAG_MODE // Other Linux Community Tools case SIOCETHTOOL : ret = -EOPNOTSUPP; //Soon to be supported break; case SIOCGMIIPHY : // Get the Phy Addr Index data->phy_id = MplPhyGetDeviceAddr(adapter->mplContext); // Fall thru case SIOCGMIIREG : // Read MII register data->val_out = MplPhyMdioRead(adapter->mplContext, data->phy_id & 0x1F, data->reg_num & 0x1F); break; case SIOCSMIIREG : if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; } else { // Write MII register MplPhyMdioWrite(adapter->mplContext, data->phy_id & 0x1F, data->reg_num & 0x1F, data->val_in); } break; default : adapter = NULL; ret = -EPERM; } // NO(NsmIoctl); return ret; } NS_SINT NsmChangeMtu(struct net_device *netdev, int new_mtu) { //FM: Need to validate with MPL CAPS NO(NsmChangeMtu); NO(NsmChangeMtu); return 0x0; } #ifdef L26 NS_SINT #else NS_VOID #endif NsmIsr(NS_SINT irq, void *data, struct pt_regs *regs) { NSM_CONTEXT *adapter = (NSM_CONTEXT *)data; NS_UINT fragsConsumed = 0x0; // Check if there are pending interrupts if (MplInterruptCheck(adapter->mplContext) == NS_STATUS_SUCCESS) { // Check if we have receive events if (MplInterruptCheckReceive(adapter->mplContext) == NS_STATUS_SUCCESS) { // Let MPL process this receive spin_lock(&adapter->rxLock); MplReceive(adapter->mplContext, 0x0, &fragsConsumed); spin_unlock(&adapter->rxLock); adapter->rxdEmpty += fragsConsumed; // We need to continously replenish the Rx engine with // new buffers - Check it is time to do so if (adapter->rxdEmpty >= (adapter->rxdCnt / NSM_DEFAULT_RX_REPL)) { spin_lock(&adapter->rxLock); replenishTask((unsigned long)adapter); spin_unlock(&adapter->rxLock); // Rxds that are empty should be zero now! adapter->rxdEmpty = 0x0; } } // Check if we have transmit events if (MplInterruptCheckTransmit(adapter->mplContext) == NS_STATUS_SUCCESS) { spin_lock(&adapter->txLock); MplTransmitDone(adapter->mplContext, 0x0); spin_unlock(&adapter->txLock); } // Check if we have internal events if (MplInterruptCheckInternal(adapter->mplContext) == NS_STATUS_SUCCESS) { MplInterruptDoneInternal(adapter->mplContext, 0x0); } // Re-Enable Interrupts MplInterruptEnable(adapter->mplContext); #ifdef L26 return IRQ_HANDLED; #else return; #endif } else { #ifdef L26 return IRQ_NONE; #else return; #endif } } NS_SINT NsmClose(struct net_device *netdev) { NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv; NI(NsmClose); // Stop the Net Stack - Just in case netif_carrier_off(netdev); netif_stop_queue(netdev); // Disable Interrupts - Doing this for load-only mode too? MplInterruptDisable(adapter->mplContext); // Stop link monitoring if (adapter->opMode != MPL_MODE_LOAD_ONLY) { // Kill Link Monitoring Tasklet tasklet_kill(&adapter->linkMonTask); } // Reset Transmit Engine - To get back pending fragments spin_lock_irq(&adapter->txLock); MplTransmitReset(adapter->mplContext); spin_unlock_irq(&adapter->txLock); // Reset Receive Engine - To get back pending fragments spin_lock_irq(&adapter->rxLock); MplReceiveReset(adapter->mplContext); spin_unlock_irq(&adapter->rxLock); #ifdef NSM_DIAG_MODE // UnInitialize Diag Module if (adapter->opMode != MPL_MODE_NORMAL) { NsmDiagUnInitialize(adapter); } #endif //NSM_DIAG_MODE // Free the MPL Pkt Fragments freeRxFrags(adapter); // Close MPL MplClose(adapter->mplContext); //Task Offloads Diables // Rx Filter (Multicast and Unicast Filtering) MplTaskFilterCfg(adapter->mplContext, NS_FALSE); // Release Interrupt free_irq(netdev->irq, adapter); NO(NsmClose); return 0x0; } // Local Functions static NS_VOID readPciInfo(NSM_CONTEXT *adapter) { struct pci_dev *pdev = adapter->pdev; NI(readPciInfo); pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->pciRevId); pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &adapter->pciSubVendorId); pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &adapter->pciSubDeviceId); NO(readPciInfo); return; } static NS_VOID setDataFields(NSM_CONTEXT *adapter) { struct net_device *netdev = adapter->netdev; NI(setDataFields); // The rx buffer size if (netdev->mtu <= ENET_MTU) { adapter->rxBufferLen = ENET_BUFFER_SIZE; } else { adapter->rxBufferLen = netdev->mtu + 32; } #ifdef NSM_DIAG_MODE // Make Tx buffer length same as Rx adapter->txBufferLen = adapter->rxBufferLen; #endif // Note the MTU ..include the Eth Hdr size and CRC len also adapter->mtu = netdev->mtu + ENET_HEADER_SIZE + CRC_LENGTH; NO(setDataFields); return; } static NS_VOID readUserOptions(NSM_CONTEXT *adapter) { NI(readUserOptions); // Transmit Descriptor Count if (TxDCnt[NsmAdapterCnt] != -1) { adapter->txdCnt = TxDCnt[NsmAdapterCnt]; } else { adapter->txdCnt = NSM_DEFAULT_TXD_CNT; } // Transmit Priority Queue if (TxQCnt[NsmAdapterCnt] != -1) { adapter->txQCnt = TxQCnt[NsmAdapterCnt]; } else { adapter->txQCnt = NSM_DEFAULT_TX_Q_CNT; } // Receive Descriptor Count if (RxDCnt[NsmAdapterCnt] != -1) { adapter->rxdCnt = RxDCnt[NsmAdapterCnt]; } else { adapter->rxdCnt = NSM_DEFAULT_RXD_CNT; } // Receive Priority Queue if (RxQCnt[NsmAdapterCnt] != -1) { // This currently has to be = 0x01 adapter->rxQCnt = NSM_DEFAULT_RX_Q_CNT; } else { adapter->rxQCnt = NSM_DEFAULT_RX_Q_CNT; } // AutoNeg if (LinkMode[NsmAdapterCnt] != -1) { switch (LinkMode[NsmAdapterCnt]) { case 0x0 : adapter->linkMode = MPL_LINK_MODE_AUTO; break; case 0x1 : adapter->linkMode = MPL_LINK_MODE_FORCED; break; default : adapter->linkMode = NSM_DEFAULT_LINK_MODE; } } else { adapter->linkMode = NSM_DEFAULT_LINK_MODE; } // Speed if (LinkSpeed[NsmAdapterCnt] != -1) { switch (LinkSpeed[NsmAdapterCnt]) { case 0x0 : adapter->linkSpeed = MPL_LINK_SPEED_HUNDREDMBPS; break; case 0x1 : adapter->linkSpeed = MPL_LINK_SPEED_TENMBPS; break; default : adapter->linkSpeed = NSM_DEFAULT_LINK_SPEED; } } else { adapter->linkSpeed = NSM_DEFAULT_LINK_SPEED; } // Duplex if (LinkDuplex[NsmAdapterCnt] != -1) { switch (LinkDuplex[NsmAdapterCnt]) { case 0x0 : adapter->linkDuplex = MPL_LINK_DUPLEX_FULL; break; case 0x1 : adapter->linkDuplex = MPL_LINK_DUPLEX_HALF; break; default : adapter->linkDuplex = NSM_DEFAULT_LINK_DUPLEX; } } else { adapter->linkDuplex = NSM_DEFAULT_LINK_DUPLEX; } // Pause if (LinkPause[NsmAdapterCnt] != -1) { switch (LinkPause[NsmAdapterCnt]) { case 0x0 : adapter->linkPause = MPL_LINK_PAUSE_RECEIVE; break; case 0x1 : adapter->linkPause = MPL_LINK_PAUSE_TRANSMIT; break; case 0x2 : adapter->linkPause = MPL_LINK_PAUSE_SYMMETRICAL; break; case 0x3 : adapter->linkPause = MPL_LINK_PAUSE_NONE; break; default : adapter->linkPause = NSM_DEFAULT_LINK_PAUSE; } } else { adapter->linkPause = NSM_DEFAULT_LINK_PAUSE; } // Intr Holdoff if (IntTimeHold[NsmAdapterCnt] != -1) { adapter->timerHold = IntTimeHold[NsmAdapterCnt]; } else { adapter->timerHold = NSM_DEFAULT_INTR_TIMER_HOLD; } // Intr Holdoff if (IntTxHold[NsmAdapterCnt] != -1) { adapter->txHold = IntTxHold[NsmAdapterCnt]; } else adapter->txHold = NSM_DEFAULT_INTR_TX_HOLD; // Intr Holdoff if (IntRxHold[NsmAdapterCnt] != -1) { adapter->rxHold = IntRxHold[NsmAdapterCnt]; } else adapter->rxHold = NSM_DEFAULT_INTR_RX_HOLD; // Operation Mode if (OpMode[NsmAdapterCnt] != -1) { switch (OpMode[NsmAdapterCnt]) { case 0x0 : adapter->opMode = MPL_MODE_NORMAL; break; case 0x1 : adapter->opMode = MPL_MODE_MONITOR; break; case 0x2 : adapter->opMode = MPL_MODE_LOAD_ONLY; break; default : adapter->opMode = NSM_DEFAULT_MODE; } } else { adapter->opMode = NSM_DEFAULT_MODE; } // WoL Modes if (Wol[NsmAdapterCnt] != -1) { adapter->wolModes = Wol[NsmAdapterCnt]; } #ifdef NSM_DIAG_MODE // Diag Sts Queue length (in terms of packets) if (DiagStsQueue[NsmAdapterCnt] != -1) { adapter->diagStsQueueSize = DiagStsQueue[NsmAdapterCnt]; } else { adapter->diagStsQueueSize = NSM_DIAG_DEFAULT_STS_QUEUE_SIZE; } #else // When NOT in diag mode, force the mode to be Normal adapter->opMode = MPL_MODE_NORMAL; #endif //NSM_DIAG_MODE #ifdef NSM_DEBUG // NSM Debug Zones if (NsmDebugZones[NsmAdapterCnt] != -1) { NsmDbgSettings = NsmDebugZones[NsmAdapterCnt]; } // Mpl Debug Zones if (MplDebugZones[NsmAdapterCnt] != -1) { MplPathZones = MplDebugZones[NsmAdapterCnt]; } #endif //NSM_DEBUG NO(readUserOptions); return; } static NS_BOOLEAN configMac(NSM_CONTEXT *adapter) { MPL_STATUS status = NS_STATUS_SUCCESS; MPL_TRANSMIT_CFG txCfg; MPL_RECEIVE_CFG rxCfg; NS_UINT8 i; NI(configMac); // Transmit Engine Config // Make sure the priority queues requested is within what is supported if (adapter->txQCnt > adapter->mplCaps.txCaps.priorityQCnt) { adapter->txQCnt = NSM_DEFAULT_TX_Q_CNT; } txCfg.priorityQueueCnt = adapter->txQCnt; for (i = 0x0; i < adapter->txQCnt; i++) { txCfg.descCnt[i] = adapter->txdCnt; //FM: Multiple Qs, diff txds? } // Maximum indications on Tx completions txCfg.maxIndications = NSM_DEFAULT_TX_MAX_INDY; if (adapter->opMode == MPL_MODE_NORMAL) { // Transmit Engine - Not End User configurable Value (atleast initially) txCfg.fillThreshold = NSM_DEFAULT_TX_FILL_THOLD; txCfg.drainThreshold = NSM_DEFAULT_TX_DRAIN_THOLD; txCfg.maxDmaBurst = NSM_DEFAULT_TX_MAX_DMA; txCfg.cfgFlags = MPL_TRANSMIT_CFG_FIFO | MPL_TRANSMIT_CFG_QUEUES | MPL_TRANSMIT_CFG_AUTO_PAD; } else { // In diag mode only set the Txd ring - No FIFO setup txCfg.cfgFlags = MPL_TRANSMIT_CFG_QUEUES; } // Let MPL do the setup status = MplTransmitCfg(adapter->mplContext, &txCfg); if (status != NS_STATUS_SUCCESS) { NSM_DBG(DBG_ERR,("Tx Config Failed \n")); NO(configMac); return NS_FALSE; } // Receive Engine - End User (driver load or UI) configurable rxCfg.priorityQueueCnt = adapter->rxQCnt; for (i = 0x0; i < adapter->rxQCnt; i++) { rxCfg.descCnt[i] = adapter->rxdCnt; //FM: Multiple Qs, diff txds? } // Maximum indications on Rx completions rxCfg.maxIndications = NSM_DEFAULT_RX_MAX_INDY; if (adapter->opMode == MPL_MODE_NORMAL) { // Receive Engine - Not End User configurable Value (atleast initially) rxCfg.drainThreshold = NSM_DEFAULT_RX_DRAIN_THOLD; rxCfg.maxDmaBurst = NSM_DEFAULT_RX_MAX_DMA; rxCfg.cfgFlags = MPL_RECEIVE_CFG_FIFO | MPL_RECEIVE_CFG_QUEUES; } else { rxCfg.cfgFlags = MPL_RECEIVE_CFG_QUEUES; } // Let MPL do the setup status = MplReceiveCfg(adapter->mplContext, &rxCfg); if (status != NS_STATUS_SUCCESS) { NSM_DBG(DBG_ERR,("Rx Config Failed \n")); NO(configMac); return NS_FALSE; } // Configure Max MTU status = MplCfgMTU (adapter->mplContext, adapter->mtu); if (status != NS_STATUS_SUCCESS) { NSM_DBG(DBG_ERR,("MTU Config Failed \n")); NO(configMac); return NS_FALSE; } // Interrupt MplInterruptCfg(adapter->mplContext, adapter->timerHold, adapter->txHold, adapter->rxHold); NO(configMac); return NS_TRUE; } static NS_BOOLEAN configLink(NSM_CONTEXT *adapter) { MPL_STATUS status; MPL_LINK_CFG linkCfg; NS_BOOLEAN ret = NS_TRUE; NI(configLink); memset((void *)&linkCfg, 0x0, sizeof(linkCfg)); // MPL Link APIs are non-reentrant spin_lock_irq(&adapter->linkLock); // Report Net stack that the link is down - since it is being set netif_carrier_off(adapter->netdev); // Link linkCfg.mode = adapter->linkMode; linkCfg.speed = adapter->linkSpeed; linkCfg.duplex = adapter->linkDuplex; // Pause configuration linkCfg.pauseType = adapter->linkPause; if (linkCfg.pauseType & MPL_LINK_PAUSE_TRANSMIT) { // For pause transmits specify the threshold linkCfg.pauseCtr = NSM_DEFAULT_LINK_PAUSE_COUNTER; linkCfg.pauseRxDALO = NSM_DEFAULT_LINK_PAUSE_DALO; // Data FIFO Hi linkCfg.pauseRxDAHI = NSM_DEFAULT_LINK_PAUSE_DAHI; // Data FIFO Hi linkCfg.pauseRxSTLO = NSM_DEFAULT_LINK_PAUSE_STHI; // Status FIFO Hi linkCfg.pauseRxSTHI = NSM_DEFAULT_LINK_PAUSE_STHI; // Status FIFO Hi } // Tell MPL to configure the link status = MplLinkCfg(adapter->mplContext, &linkCfg); if (status == NS_STATUS_SUCCESS) { // The existing link matches our needs - Complete the Setup if (MplLinkUpComplete(adapter->mplContext) == NS_STATUS_SUCCESS) { NSM_DBG(DBG_TMP,("Link is UP \n")); adapter->linkStatus = MPL_LINK_STATUS_UP; // Indicate Upper layers to start Tx and Rx for this adapter // If previously reported a Link down - Report AOK now // This is only in normal mode if (adapter->opMode == MPL_MODE_NORMAL) { if (!netif_carrier_ok(adapter->netdev)) { netif_carrier_on(adapter->netdev); netif_start_queue(adapter->netdev); } } } else { NSM_DBG(DBG_ERR,("Link Config Failed \n")); adapter->linkStatus = MPL_LINK_STATUS_DOWN; ret = NS_FALSE; } } else if (status == NS_STATUS_ASYNCH_COMPLETION) { NSM_DBG(DBG_TMP,("Link is being Pursued \n")); adapter->linkStatus = MPL_LINK_STATUS_ACTIVE; } else { adapter->linkStatus = MPL_LINK_STATUS_DOWN; NSM_DBG(DBG_ERR,("Link Config Failed \n")); ret = NS_FALSE; } spin_unlock_irq(&adapter->linkLock); NO(configLink); return ret; } NS_BOOLEAN setupRxFrags(NSM_CONTEXT *adapter) { NS_UINT allocSize, i, nodes; MPL_PKT_FRAG *pFrag = NULL; NS_VOID *allocMem; NI(setupRxFrags); // Allocate memory for the frags // The one additional fragment will ensure no race condition // between the consumer (Replenish Task) and Producer (RxDone) nodes = adapter->rxdCnt + 1; #ifdef NSM_DIAG_MODE // Additional nodes to handle rx completion queuing nodes += adapter->diagStsQueueSize; #endif //NSM_DIAG_MODE allocSize = sizeof(MPL_PKT_FRAG) * nodes; allocMem = kmalloc(allocSize, GFP_KERNEL); if (allocMem == NULL) { NSM_DBG(DBG_ERR,("Failed to Alloc mem to rx frags \n")); NO(setupRxFrags); return NS_FALSE; } else { // Zero up the memory memset((void *)(allocMem), 0x0, allocSize); pFrag = (MPL_PKT_FRAG *) allocMem; // Create linked list for (i = 0x0; i < (nodes - 1); i++) { // Set link pFrag->pNextFrag = (pFrag + 1); pFrag++; } // Last node has next NULL pFrag->pNextFrag = NULL; // Note Head and Tail of this frag list adapter->rxFrags = allocMem; adapter->rxFragsHead = (MPL_PKT_FRAG *)allocMem; adapter->rxFragsTail = pFrag; } NO(setupRxFrags); return NS_TRUE; } NS_VOID freeRxFrags(NSM_CONTEXT *adapter) { struct pci_dev *pdev = adapter->pdev; MPL_PKT_FRAG *pFrag = NULL; struct sk_buff* skb; NI(freeRxFrags); // Free attached buffers pFrag = adapter->rxFragsHead; while (pFrag) { skb = (struct sk_buff *)pFrag->pNsmPrivate; if (skb != NULL) { // UnMap and Free the sk buffs pci_unmap_single(pdev, (dma_addr_t)pFrag->physAddr, adapter->rxBufferLen, PCI_DMA_FROMDEVICE); dev_kfree_skb(skb); pFrag->pNsmPrivate = NULL; } // Move to the next fragment pFrag = pFrag->pNextFrag; } // Free Frag memory if (adapter->rxFrags) { kfree(adapter->rxFrags); adapter->rxFrags = NULL; adapter->rxFragsHead = NULL; } NO(freeRxFrags); return; } NS_VOID replenishTask(unsigned long data) { NSM_CONTEXT *adapter = (NSM_CONTEXT *)data; MPL_PKT_FRAG *pFrag = NULL, *pFragsToMpl = NULL; struct sk_buff* skb; NS_UINT i, rxdsEmpty, bufCnt = 0x0; // Note: This function needs to be called from Intr context // This function is non-reenterant NI(replenishTask); MplReceiveGetEmptyDesc(adapter->mplContext, adapter->rxQCnt , &rxdsEmpty); if (rxdsEmpty == 0x0) { NO(replenishTask); return; } #ifdef NSM_DIAG_MODE // While in diag mode, there is a chance that we might run out of // fragments in the free list, while waiting for the app to come // get the packets from us - If we enter this situation then force // a packet from the Rx done list to free some frags if (adapter->rxFragsHead == adapter->rxFragsTail) { NsmDiagProcessDoneList(adapter, 0x1, NS_TRUE, &adapter->diagRxDoneList, &adapter->rxFragsTail); } #endif //NSM_DIAG_MODE // Allocate the required number of buffers pFrag = adapter->rxFragsHead; for (i = 0x0; i < rxdsEmpty; i++) { #ifdef NSM_DIAG_MODE if ( pFrag == adapter->rxFragsTail) { // Better luck next time break; } #endif //NSM_DIAG_MODE // Check if this frag need a new SKB if (pFrag->pNsmPrivate == NULL) { // Allocate Skb skb = dev_alloc_skb(adapter->rxBufferLen); if (skb == NULL) { NSM_DBG(DBG_ERR,("SKB alloc in Repl Failed! \n")); // Better luck next time break; } else { // Mark as being used by this device. skb->dev = adapter->netdev; } // Map the Skb buffer pFrag->physAddr = pci_map_single(adapter->pdev, skb->tail, adapter->rxBufferLen, PCI_DMA_FROMDEVICE); // Set the Fragment pFrag->pAddr = skb->data; pFrag->pNsmPrivate = skb; } // Set the size of the buffer pFrag->fragSize = adapter->rxBufferLen; // Get the next frag pFrag = pFrag->pNextFrag; bufCnt++; } // Check if we managed to allocate new buffers if (bufCnt != 0x0) { pFragsToMpl = adapter->rxFragsHead; // Report new buffers to MPL MplReceiveReplenish(adapter->mplContext, bufCnt, &pFragsToMpl); // Check if MPL returned back some buffers if (pFragsToMpl != adapter->rxFragsHead) { // Move Head to the returned list adapter->rxFragsHead = pFragsToMpl; } else { // Move Head to the next frag on the cache adapter->rxFragsHead = pFrag; } } NO(replenishTask); return; } static NS_VOID linkTask(unsigned long data) { NSM_CONTEXT *adapter = (NSM_CONTEXT *)data; MPL_LINK_STATUS linkStatus; NI(linkTask); // MPL Link APIs are non-reentrant spin_lock_irq(&adapter->linkLock); // Get the current Link State linkStatus = MplLinkProcessChange(adapter->mplContext); switch (linkStatus) { case MPL_LINK_STATUS_UP: // Let MPL finish up the Linking process if (MplLinkUpComplete(adapter->mplContext) == NS_STATUS_SUCCESS) { NSM_DBG(DBG_TMP,("Link is UP \n")); adapter->linkStatus = MPL_LINK_STATUS_UP; // If previously reported a Link down - Report AOK now // This is only in normal mode if (adapter->opMode == MPL_MODE_NORMAL) { if (!netif_carrier_ok(adapter->netdev)) { netif_carrier_on(adapter->netdev); netif_start_queue(adapter->netdev); } } } break; case MPL_LINK_STATUS_ACTIVE: NSM_DBG(DBG_TMP,("Link is Actively Pursued \n")); adapter->linkStatus = MPL_LINK_STATUS_ACTIVE; // Reschedule this task after a brief delay mdelay(5); //FM: Eval tasklet_schedule(&adapter->linkMonTask); break; case MPL_LINK_STATUS_DOWN: NSM_DBG(DBG_TMP,("Link is Down \n")); adapter->linkStatus = MPL_LINK_STATUS_DOWN; // If previously reported a Link Up- Report down now if (netif_carrier_ok(adapter->netdev)) { netif_carrier_off(adapter->netdev); netif_stop_queue(adapter->netdev); } break; default: break; } spin_unlock_irq(&adapter->linkLock); NO(linkTask); return; } DP8381X-Linux-Ver-1.6/nsmos.h0000444000000000000000000000226010430225716014172 0ustar rootroot//****************************************************************************** // // NSMOS.H // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // Includes for kernel related header files used by oai.h and // the core driver // //***************************************************************************** #ifndef _NSM_OS_H_ #define _NSM_OS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef L26 #include #endif #endif DP8381X-Linux-Ver-1.6/nsmdebug.h0000444000000000000000000000475610430225716014653 0ustar rootroot//****************************************************************************** // // NSMDEBUG.H // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // Linux NSM debug // //***************************************************************************** #ifndef _NSM_DEBUG_H_ #define _NSM_DEBUG_H_ extern unsigned int NsmDbgSettings; // Change this to suit your OS #define dbgprint printk //#define dbgprint #define hexdump DBG_PrintBuf // Debug zones // More zones ? add to the list after decrease of the bit position by one #define DBG_FUNC (1 << 31) #define DBG_ERR (1 << 30) #define DBG_INFO (1 << 29) #define DBG_TMP (1 << 28) extern void DBG_PrintBuf(unsigned char *dataPtr, int dataLen); // Debug printf #define NSM_DBG(flag,format) (((flag) & NsmDbgSettings )? dbgprint format:0) // Debug HexDump #define NSM_HD(flag,parms) (((flag) & NsmDbgSettings )? hexdump parms:0) #define ISPRINT(ch) (((ch) >= ' ') && ((ch) <= '~')) #define PRINTCHAR(ch) (unsigned char)(ISPRINT(ch) ? (ch) : '.') #define DBG_PrintBuf(bufptr, buflen) \ { \ int i, linei; \ dbgprint("\r\n %d bytes @%x:", buflen, bufptr); \ for (i = 0; i+8 <= buflen; i += 8) { \ unsigned char ch0 = bufptr[i+0], \ ch1 = bufptr[i+1], ch2 = bufptr[i+2], \ ch3 = bufptr[i+3], ch4 = bufptr[i+4], \ ch5 = bufptr[i+5], ch6 = bufptr[i+6], \ ch7 = bufptr[i+7]; \ dbgprint("\r\n %02x %02x %02x %02x %02x %02x %02x %02x" " %c %c %c %c %c %c %c %c", ch0, ch1, ch2, ch3, ch4, ch5, ch6, ch7, PRINTCHAR(ch0), PRINTCHAR(ch1), PRINTCHAR(ch2), PRINTCHAR(ch3), PRINTCHAR(ch4), PRINTCHAR(ch5), PRINTCHAR(ch6), PRINTCHAR(ch7)); \ } \ dbgprint("\r\n "); \ for (linei = 0; (linei < 8) && (i < buflen); i++, linei++){ dbgprint(" %02x", (int)(bufptr[i])); } \ dbgprint(" "); \ i -= linei; \ while (linei++ < 8) dbgprint(" "); \ for (linei = 0; (linei < 8) && (i < buflen); i++, linei++){ \ unsigned char ch = bufptr[i]; \ dbgprint(" %c", PRINTCHAR(ch)); } \ dbgprint("\t\t<>\r\n"); \ } // Local helful debug macros #define NI(fn) NSM_DBG(DBG_FUNC, (">>> Enter " #fn"()\n")) #define NO(fn) NSM_DBG(DBG_FUNC, (" <<< Exit " #fn"() Line : %d \n", __LINE__)) #define NOInt(v) NSM_DBG(DBG_TMP, (" "#v": %x \n", v)) #define NP(fmt) NSM_DBG(DBG_TMP, fmt) #endif DP8381X-Linux-Ver-1.6/nsmapp.h0000444000000000000000000001034410430225716014333 0ustar rootroot //****************************************************************************** // // NSMAPP.H // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // Management Apps / IOCTL Related Defines // //***************************************************************************** #ifndef _NSM_APP_H_ #define _NSM_APP_H_ #define NSM_APP_INTRO 0xFFFF #define NSM_REG_READ 0x01 #define NSM_REG_WRITE 0x02 #define NSM_PCI_READ 0x03 #define NSM_PCI_WRITE 0x04 #define NSM_XFER_CFG_SET 0x05 #define NSM_XFER_CFG_GET 0x06 #define NSM_TRANSMIT 0x07 #define NSM_TRANSMIT_STATUS 0x08 #define NSM_TRANSMIT_FLUSH 0x09 #define NSM_RECEIVE 0x0A #define NSM_RECEIVE_FLUSH 0x0B #define NSM_STATS 0x0C #define NS_APP_IOCTL_CODE 0x89FF #define NS_APP_SIGN 0x0510 #define NS_DRIVER_SIGN 0x1228 #define NS_APP_MAX_PKT_SIZE 2046 #define NS_STATUS_QUEUE_LEN 256 // Packets // Basic command - Opcode only typedef struct _NS_APP_CMD{ NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; } NS_APP_CMD; // Register read/write typedef struct _NS_APP_REG_CMD{ NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; NS_UINT offset; NS_UINT data; } NS_APP_REG_CMD; // App to Driver initial handshake typedef struct _NS_APP_INTRO_CMD{ NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; NS_UINT app; NS_UINT driver; NS_UINT numPorts; NS_UINT driverVerMajor; NS_UINT driverVerMinor; } NS_APP_INTRO_CMD; // Register read/write typedef struct _NS_APP_XFER_CFG_CMD{ NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; NS_UINT txDescCnt; NS_UINT txpQueueCnt; NS_UINT txBufferLen; NS_UINT rxDescCnt; NS_UINT rxBufferLen; NS_UINT stsQueueSize; } NS_APP_XFER_CFG_CMD; // Data Transfer Request typedef struct _NS_APP_XFER_CMD{ NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; // Set by App NS_UINT pktHandle; // Same need to be used while querying for status NS_UINT pQueue; // Valid values are 1,2,3 and 4 NS_UINT packetSize;// Actual size of the packet NS_UINT bufSize; // Size of buffer pointed by buf NS_UINT flags; // Various OOB directives #define NSM_APP_XFER_COPY 0x00000001 // Copy the data from driver to app // Set by Driver #define NS_APP_MAX_FRAG_INFO 0x4 NS_UINT numDesc; // Number of descriptors used for this xfer NS_UINT32 cmdSts; // Of the last descriptor NS_ADDR descPhyAddr[NS_APP_MAX_FRAG_INFO]; //Physical addr of desc NS_ADDR bufPhyAddr[NS_APP_MAX_FRAG_INFO]; //Physical addr of buffers NS_UINT morePkts; //Count of pkt completions to follow // Actual data followes last } NS_APP_XFER_CMD; // Driver maintained (Tx/Rx related) stats typedef struct _NS_APP_STATS_CMD { NS_UINT cmd; NS_UINT instance; NS_UINT reserved; NS_UINT status; NS_UINT rxPackets; // total packets received NS_UINT txPackets; // total packets transmitted NS_UINT rxBytes; // total bytes received NS_UINT txBytes; // total bytes transmitted NS_UINT rxErrors; // bad packets received NS_UINT txErrors; // packet transmit problems NS_UINT rxDropped; // no space to note rx completion NS_UINT txDropped; // no space to note tx completion // detailed rx_errors: NS_UINT rxLengthErrors; NS_UINT rxOverErrors; // receiver ring buff overflow NS_UINT rxCrcErrors; // recved pkt with crc error NS_UINT rxFrameErrors; // recv'd frame alignment error // detailed tx_errors NS_UINT txCollErrors; // dropped due to excessive collisions NS_UINT txAbortedErrors; // transmission was aborted NS_UINT txCarrierErrors; // Carrier sense lost during tx NS_UINT txFifoErrors; // FIFO underrun occured NS_UINT txWindowErrors; // Out-of-window collision occured durring tx } NS_APP_STATS_CMD; #endif DP8381X-Linux-Ver-1.6/oai.h0000444000000000000000000002350610430225716013611 0ustar rootroot //***************************************************************************** // // OAI.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This header file contains OS-specific services, data-type definitions, // etc. required by MPL. This file must be customized for each OS/Platform // and re-named OAI.H. A version of this file will typically be created // for each platform and exist in the NSM driver's source directory. // //***************************************************************************** #ifndef _OAI_H_ #define _OAI_H_ // This brings in all the NSM specific definitions #include //******************************** MPL General Options ************************ // Modify the following to set the desire MPL options //***************************************************************************** // On Big endian machines, uncomment the following line or define it via // the compiler command line // NOTE!!! = Read the instructions under the OaiReadIoXX and OaiWriteIoXX too! // #define MPL_BIG_ENDIAN //**************************** END OF MPL General Options ********************* //******************************** MPL Board Options ************************ // Modify the following to set options based on board design //***************************************************************************** // On MacPhyter boards *without* a EEPROM on them disable the below //#define MPL_NO_EEPROM // On MacPhyter boards that use an EXTERNAL Phy disable the below // #define MPL_EXTERNAL_PHY //**************************** END OF MPL Board Options ********************* //******************************** MPL Diag Mode ****************************** // Modify the following to enable MPL Diagnostics Mode //***************************************************************************** #ifdef NSM_DIAG_MODE #define MPL_DIAG_MODE #endif //******************************** MPL Task Offload *************************** // Modify the following to define MPL task offload behavior //***************************************************************************** // Uncomment to enable statistics collection task //#define MPL_TASK_STAT // Uncomment to enable VLAN offload task #define MPL_TASK_VLAN // Uncomment to enable multicast filtering task #define MPL_TASK_RECEIVE_FILTER // Uncomment to enable checksum offload task //#define MPL_TASK_STAT //**************************** END OF MPL Task Offload Options **************** //******************** MPL COMPILER INDEPENDENT DATA TYPES ******************** // Modify the following to define MPL data types in terms of native // compiler data types. //***************************************************************************** // Note: On platforms where the natural integer size is less then 32-bits // in size (eg 16-bit platforms), NS_UINT and NS_SINT must be defined as a // data type no less then 32-bits in size. typedef unsigned int NS_UINT; typedef int NS_SINT; // Fixed width data types/pointers typedef unsigned char NS_CHAR; typedef unsigned char NS_UINT8; typedef char NS_SINT8; typedef unsigned short NS_UINT16; typedef short NS_SINT16; typedef unsigned long NS_UINT32; typedef long NS_SINT32; // Abstract data type for physical address references typedef unsigned int NS_ADDR; //**************** END OF MPL COMPILER INDEPENDENT DATA TYPES ***************** // Defines the maximum number of physical adapters supported by MPL. // Customize this value appropriate to the environment. #define MPL_MAX_ADAPTERS 8 //******************* OAI DATA DECLARATIONS (DO NOT MODIFY) ******************* //********************************************************************** // Function parameter annotation macros. //********************************************************************** #ifndef IN #define IN #endif // IN #ifndef OUT #define OUT #endif // OUT // Void types typedef void NS_VOID; // Boolean data type typedef NS_UINT NS_BOOLEAN; #define NS_TRUE 1 #define NS_FALSE 0 // Handle structure for returning module opaque fields typedef NS_UINT MPL_HANDLE; // timer callback function pointer (see OaixxxTimer functions) typedef NS_VOID (MPL_TIMERCALLBACK)(NS_VOID *pTimerArg); // Mac address typedef NS_UINT8 *MPL_MAC_ADDR; // handle for DMA region (see OaiAlloc/FreeDmaRegion) typedef struct _MPL_MEM_REGION { NS_VOID *pAddr; // aligned (as requested in alloc request) region ptr, logical NS_ADDR phyAddr; // aligned (as requested in alloc request) region ptr, physical } MPL_MEM_REGION; // NSM DMA Mem region descriptor (derived from above) typedef struct _NSM_MEM_REGION { // In line with MPL_MEM_REGION NS_VOID *pAddr; // aligned (as requested in alloc request) region ptr, logical NS_ADDR phyAddr; // aligned (as requested in alloc request) region ptr, physical // All NSM Extensions NS_UINT size; } NSM_MEM_REGION; //************************** OAI FUNCTION PROTOTYPES ************************** // The following are function declarations of OS services required by MPL. // Each function must be implemented in using native OS API's and linked // with MPL //***************************************************************************** #if defined(__cplusplus) extern "C" { #endif //+++++ I/O access Functions // BIG Endian Note!! // In some architectures or specifically the kernel ports have IO APIs // e.g inl, readl, outl or writel etc do the required swaps - Since MPL // does a similar swap too we would end with no swap at all. Hence to // handle such unique kernel ports it is important to swap the data (16/32) // in the functions below - This would result in an additional swap // correcting the data //Read from PCI memory-mapped or IO location 'pAddr'. #ifdef NSM_IO_MAP #define OaiIoRead32(pClientDevHndl, pAddr) \ (NS_UINT32)inl((NS_UINT32)(pAddr)) #define OaiIoRead16(pClientDevHndl, pAddr) \ (NS_UINT16)inw((NS_UINT32)(pAddr)) #define OaiIoRead8(pClientDevHndl, pAddr) \ (NS_UINT8)inb((NS_UINT32)(pAddr)) #else //NSM_IO_MAP #define OaiIoRead32(pClientDevHndl, pAddr) \ (NS_UINT32)readl((pAddr)) #define OaiIoRead16(pClientDevHndl, pAddr) \ (NS_UINT16)readw((pAddr)) #define OaiIoRead8(pClientDevHndl, pAddr) \ (NS_UINT8)readb((pAddr)) #endif //NSM_IO_MAP //Write to PCI memory-mapped or IO location 'pAddr'. #ifdef NSM_IO_MAP #define OaiIoWrite32(pClientDevHndl, pAddr, writeData) \ outl((NS_UINT32)(writeData), (NS_UINT32)(pAddr)) #define OaiIoWrite16(pClientDevHndl, pAddr, writeData) \ outw((NS_UINT16)(writeData), (NS_UINT32)(pAddr)) #define OaiIoWrite8(pClientDevHndl, pAddr, writeData) \ outb((NS_UINT8)(writeData), (NS_UINT32)(pAddr)) #else //NSM_IO_MAP #define OaiIoWrite32(pClientDevHndl, pAddr, writeData) \ writel((NS_UINT32)(writeData), (pAddr)) #define OaiIoWrite16(pClientDevHndl, pAddr, writeData) \ writew((NS_UINT16)(writeData), (pAddr)) #define OaiIoWrite8(pClientDevHndl, pAddr, writeData) \ writeb((NS_UINT8)(writeData), (pAddr)) #endif //NSM_IO_MAP //+++++ Host Memory Functions //Allocate/free a region in host memory suitable for DMA NS_BOOLEAN OaiAllocDmaRegion( IN NS_VOID *pClientDevHndl, IN NS_UINT size, IN NS_UINT byteAlignment, OUT MPL_MEM_REGION **pRgnHndl ); NS_VOID OaiFreeDmaRegion( IN NS_VOID *pClientDevHndl, IN MPL_MEM_REGION *pRgnHndl ); //Allocate/free general purpose host memory #define OaiMalloc(regionSize) \ kmalloc((regionSize), GFP_KERNEL) #define OaiFree(regionSize, startAddrLogical) \ kfree((startAddrLogical)) //Copy/zero host memory #define OaiMemCopy(dest, src, len) \ memcpy((void *)(dest), (void *)(src), (len)) #define OaiZeroMem(pMemRegion, regionSize) \ memset((void *)(pMemRegion), 0x0, (regionSize)) //+++++ Timer Functions //Delay program execution for 'sleepInterval' usec #define OaiSleep(sleepInterval) { \ if ((sleepInterval) > 1000) \ mdelay((sleepInterval)/1000); \ else \ udelay((sleepInterval)); \ } //Return 10ms tick count #define OaiGetTickCount() jiffies //Allocate/free/start/cancel periodic timer w/ callback 'pTimerFunction' NS_BOOLEAN OaiCreateTimer( IN MPL_TIMERCALLBACK pTimerFunction, IN NS_VOID *pTimerArg, OUT NS_VOID **pTimerHandle ); NS_VOID OaiDeleteTimer( IN NS_VOID *pTimerHandle ); NS_VOID OaiStartTimer( IN NS_VOID *pTimerHandle, IN NS_UINT delayInMsec ); NS_BOOLEAN OaiCancelTimer( IN NS_VOID *pTimerHandle ); //+++++ Resource Synchronization Functions //Initialize/free/acquire/release multiprocessor-safe synchronization lock NS_BOOLEAN OaiCreateLock( OUT NS_VOID **pLockHandle ); NS_VOID OaiDestroyLock( IN NS_VOID *pLockHandle ); NS_VOID OaiAcquireLock( IN NS_VOID *pLockHandle ); NS_VOID OaiReleaseLock( IN NS_VOID *pLockHandle ); #if defined(__cplusplus) } #endif //+++++ Debug Output Abstractions - Define appropriate to the environment. // OAI_DEBUG_MSG takes a base string parameter, and zero or more optional // insertion parameters. #define OAI_DEBUG_MSG printk // OAI_DEBUG_BREAK breaks into the debugger. #define OAI_DEBUG_BREAK printk //********************** END OF OAI FUNCTION PROTOTYPES *********************** #endif // _OAI_H_ DP8381X-Linux-Ver-1.6/nsmdiag.h0000444000000000000000000000602510430225716014460 0ustar rootroot //****************************************************************************** // // NSMDIAG.H // // Copyright (c) 2005 National Semiconductor Corporation. // All Rights Reserved // // Diag Interface related defines // //***************************************************************************** #ifndef _NSM_DIAG_H_ #define _NSM_DIAG_H_ // Default sts queue size #define NSM_DIAG_DEFAULT_STS_QUEUE_SIZE 256 typedef struct _DIAG_PKT { // Below are for interacting with the App NS_UINT pktStatus; // Pkt status NS_UINT pktSize; // Pkt size NS_UINT32 cmdSts; // Of last Txd i.e basically for the pkt NS_UINT appPktHandle; // Pkt handle as signalled by the App NS_UINT firstDescIndex; // First descriptor used for this xfer NS_UINT numDesc; // Number of descriptors used for this xfer // NSM Diag related MPL_PKT_FRAG *pFrag; // Pointer to head frag NS_VOID *pNsmPrivate; // Private usage MPL_LIST_NODE link; // Linkage } DIAG_PKT; typedef struct _DIAG_STATS { NS_UINT rxPackets; // total packets received NS_UINT txPackets; // total packets transmitted NS_UINT rxBytes; // total bytes received NS_UINT txBytes; // total bytes transmitted NS_UINT rxErrors; // bad packets received NS_UINT txErrors; // packet transmit problems NS_UINT rxDropped; // no space to note rx completion NS_UINT txDropped; // no space to note tx completion // detailed rx_errors: NS_UINT rxLengthErrors; NS_UINT rxOverErrors; // receiver ring buff overflow NS_UINT rxCrcErrors; // recved pkt with crc error NS_UINT rxFrameErrors; // recv'd frame alignment error // detailed tx_errors NS_UINT txCollErrors; // dropped due to excessive collisions NS_UINT txAbortedErrors; // transmission was aborted NS_UINT txCarrierErrors; // Carrier sense lost during tx NS_UINT txFifoErrors; // FIFO underrun occured NS_UINT txWindowErrors; // Out-of-window collision occured durring tx } DIAG_STATS; //Exported functions struct NSM_CONTEXT; // Handle fwd decl #if defined(__cplusplus) extern "C" { #endif NS_UINT NsmDiagInitialize( struct NSM_CONTEXT *adapter); NS_UINT NsmDiagIoctl( struct NSM_CONTEXT *adapter, NS_VOID *useraddr); NS_VOID NsmDiagTransmitDone( NS_VOID *pClientDevHndl, NS_UINT packetCnt, MPL_TRANSMIT_DONE *pTxDone); NS_VOID NsmDiagReceive( NS_VOID *pClientDevHndl, NS_UINT packetCnt, MPL_PKT *pPkt); NS_VOID NsmDiagProcessDoneList( struct NSM_CONTEXT *adapter, NS_UINT pktCnt, NS_BOOLEAN validate, MPL_LIST *pList, MPL_PKT_FRAG **ppTailFrag); NS_VOID NsmDiagUnInitialize( struct NSM_CONTEXT *adapter); #if defined(__cplusplus) } #endif #endif DP8381X-Linux-Ver-1.6/Launch.sh0000444000000000000000000000615510430225716014437 0ustar rootroot#/bin/bash KVER=$(uname -r | awk -F [.] '{print $$1}') # Make sure the user is root - Otherwise rmmod and insmod will fail if [ $USER != "root" ]; then echo "Need to be root user to continue!!" exit 1 fi # See if older driver versions are loaded OLD1=$(cat /proc/modules | grep macphy | awk '{print $1}') OLD2=$(cat /proc/modules | grep natsemi | awk '{print $1}') if [ "$OLD1" = "macphy" ]; then echo "Older Macphyter driver is loaded... Unloading it " OLDETH=$(cat /var/log/messages | grep DP838 | tail -n 1 | awk '{print substr($$1, match($$1, "eth"), 4)}') echo "Bringdown interface : $OLDETH" ifconfig $OLDETH down rmmod macphy sleep 2 fi if [ "$OLD2" = "natsemi" ]; then echo "Community distributed driver is loaded... Unloading it " OLDETH=$(cat /var/log/messages | grep NatSemi | tail -n 1 | awk '{print substr($$1, match($$1, "eth"), 4)}') echo "Bringdown interface : $OLDETH" ifconfig $OLDETH down rmmod natsemi sleep 2 fi #Check the mode in which to load the driver if [ $1 ]; then OPMODE=$1 else OPMODE=0 fi # Load new driver - depending on the version, after making it (if needed) if [ $KVER != 6 ] ; then echo "Kernel ver detected as 2.4.x" cp -f Makefile.2.4 Makefile make insmod macphy.o OpMode=$OPMODE sleep 1 else echo "Kernel ver detected as 2.6.x" cp -f Makefile.2.6 Makefile make insmod macphy.ko OpMode=$OPMODE sleep 1 fi ETH=$(tail -n 3 /var/log/messages | grep eth | awk '{print substr($$1, match($$1, "eth"), 4)}') echo "MacPhyter device is" : $ETH echo "Bringing up" : $ETH ifconfig $ETH up echo echo To assign an IP address do "ifconfig $ETH Ip.ad.re.ss" echo # Display the mode in which the driver was loaded case "$OPMODE" in 0) echo "Driver was loaded in NORMAL mode!" echo "---------------------------------" echo " [Operation] : [Owner] " echo "---------------------------------" echo " H/w initialiation : Driver " echo " Tx and Rx : OS (Network Stack)" echo " Register access : Driver, Integrity" echo ;; 1) echo "Driver was loaded in MONITOR mode!" echo "---------------------------------" echo " [Operation] : [Owner] " echo "---------------------------------" echo " H/w initialiation : Driver " echo " Tx and Rx : Integrity " echo " Register access : Driver, Integrity" echo ;; 2) echo "Driver was loaded in LOAD-ONLY mode!" echo "---------------------------------" echo " [Operation] : [Owner] " echo "---------------------------------" echo " H/w initialiation : Integrity " echo " Tx and Rx : Integrity " echo " Register access : Integrity " echo esac echo "To load the Driver in a different mode pass the mode-code as shown below to the Launch Script" echo "E.g. Launch 1" echo "---------------------------" echo "[Mode] : [Code] " echo "---------------------------" echo "NORMAL : 0 " echo "MONITOR : 1 " echo "LOAD-ONLY : 2 " echo sleep 1 exit 0 DP8381X-Linux-Ver-1.6/Mpl/0000777000000000000000000000000010430230144013407 5ustar rootrootDP8381X-Linux-Ver-1.6/Mpl/Tasks/0000777000000000000000000000000010430230160014472 5ustar rootrootDP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskrxfilter.c0000444000000000000000000005464710430225772020120 0ustar rootroot //****************************************************************************** // // MPLTASKRXFILTER.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL receive filtering Offload Task Module. // // This file contains the API implementations for // o Filtering of Receive packets based on // - Multicast Address // - Unicast Address // - TBD // //****************************************************************************** #include #ifdef MPL_TASK_RECEIVE_FILTER // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_TASK_RX_FILTER, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_TASK_RX_FILTER, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_TASK_RX_FILTER, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_TASK_RX_FILTER, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_TASK_RX_FILTER, \ (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_TASK_RX_FILTER, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_TASK_RX_FILTER, fmt) // Locals static MPL_STATUS listenAdd(MPL_CONTEXT *pMplCtx,MPL_MAC_ADDR pCurrentAddress, MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS]); static MPL_STATUS listenCheck(MPL_CONTEXT *pMplCtx,MPL_MAC_ADDR pCurrentAddress, MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS]); static MPL_STATUS listenDel(MPL_CONTEXT *pMplCtx,MPL_MAC_ADDR pCurrentAddress, MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS]); static MPL_STATUS listenClear(MPL_CONTEXT *pMplCtx, MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS]); static MPL_STATUS updateHashTable(MPL_CONTEXT *pMplCtx,NS_UINT16 rowIndex, NS_UINT16 colIndex); static NS_VOID getHashIndex(MPL_MAC_ADDR pCurrentAddress, NS_UINT16 *rowIndex, NS_UINT16 *colIndex); //***************************************************************************** // MplTaskFilterCfg // Configure the receive filtering module // (Currently Multicast and Unicast Destination Address Filtering) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // enableFlag // Set to NS_TRUE to enable the reception of multicast frames and // filtering, NS_FALSE to disable. // // Return Value // NS_STATUS_SUCCESS // The task offload was successfully enabled or disabled // NS_STATUS_NOT_SUPPORTED // This offload task or selected configuration option is not // supported by MPL. // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // //***************************************************************************** MPL_STATUS MplTaskFilterCfg( IN NS_VOID *pMplHandle, IN NS_BOOLEAN enableFlag ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterCfg); pMplCtx->taskRxFilter.enable = enableFlag; EXIT(MplTaskFilterCfg); return status; } //***************************************************************************** // MplTaskFilterReload // Reload receive hash filters from previous defined listen list // Useful for if a Mac Reset is done and the listen lists are to be // restored to their previous saved values // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The listen list was successfully reloaded // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterReload( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT16 rowIndex, colIndex; ENTER(MplTaskFilterReload); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } for (rowIndex = 0x0; rowIndex < MAX_FILTER_ROWS; rowIndex++) { for (colIndex = 0x0; colIndex < MAX_FILTER_COLS; colIndex++) { // Update the Hw's hash table if required if (pMplCtx->taskRxFilter.mcTable[rowIndex][colIndex].refCnt || pMplCtx->taskRxFilter.ucTable[rowIndex][colIndex].refCnt) { updateHashTable(pMplCtx, rowIndex, colIndex); } } } EXIT(MplTaskFilterReload); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplTaskFilterMcastAddAddr // Add a new multicast address to the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be added to the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully added // NS_STATUS_RESOURCES // Unable to allocate required resources // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastAddAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterMcastAddAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Add to the listen list status = listenAdd(pMplCtx, pAddr, pMplCtx->taskRxFilter.mcTable); EXIT(MplTaskFilterMcastAddAddr); return status; } //***************************************************************************** // MplTaskFilterMcastDeleteAddr // Delete a multicast address from the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be deleted from the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully deleted // NS_STATUS_FAILURE // Could not find the address to delete or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastDeleteAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterMcastDeleteAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Remove from the listen list status = listenDel(pMplCtx, pAddr, pMplCtx->taskRxFilter.mcTable); EXIT(MplTaskFilterMcastDeleteAddr); return status; } //***************************************************************************** // MplTaskFilterMcastCheckAddr // Check if a multicast address is present in the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be checked in the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was found in the receive accept list // NS_STATUS_FAILURE // Could not find the address or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastCheckAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterMcastCheckAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check in the listen list status = listenCheck(pMplCtx, pAddr, pMplCtx->taskRxFilter.mcTable); EXIT(MplTaskFilterMcastCheckAddr); return status; } //***************************************************************************** // MplTaskFilterMcastClearList // Clear the multicast clear list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The list was successfully cleared // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastClearList( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterMcastClearList); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Clear multicast listen list status = listenClear(pMplCtx, pMplCtx->taskRxFilter.mcTable); EXIT(MplTaskFilterMcastClearList); return status; } //***************************************************************************** // MplTaskFilterUcastAddAddr // Add a new unicast address to the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be added to the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully added // NS_STATUS_RESOURCES // Unable to allocate required resources // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // //***************************************************************************** MPL_STATUS MplTaskFilterUcastAddAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterUcastAddAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Add to the listen list status = listenAdd(pMplCtx, pAddr, pMplCtx->taskRxFilter.ucTable); EXIT(MplTaskFilterUcastAddAddr); return status; } //***************************************************************************** // MplTaskFilterUcastDeleteAddr // Delete a unicast address from the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be deleted from the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully deleted // NS_STATUS_FAILURE // Could not find the address to delete or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastDeleteAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterUcastDeleteAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Remove from the listen list status = listenDel(pMplCtx, pAddr, pMplCtx->taskRxFilter.ucTable); EXIT(MplTaskFilterUcastDeleteAddr); return status; } //***************************************************************************** // MplTaskFilterUcastCheckAddr // Check if a unicast address is present in the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be checked in the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was found in the receive accept list // NS_STATUS_FAILURE // Could not find the address or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastCheckAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterUcastCheckAddr); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check in the listen list status = listenCheck(pMplCtx, pAddr, pMplCtx->taskRxFilter.ucTable); EXIT(MplTaskFilterUcastCheckAddr); return status; } //***************************************************************************** // MplTaskFilterUcastClearList // Clear the unicast clear list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The list was successfully cleared // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastClearList( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplTaskFilterUcastClearList); // Check if this feature is enabled if (pMplCtx->taskRxFilter.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Clear multicast listen list status = listenClear(pMplCtx, pMplCtx->taskRxFilter.ucTable); EXIT(MplTaskFilterUcastClearList); return status; } //***************************************************************************** // listenAdd // Adds a new MAC address to the listen (i.e. accept) list // // Parameters // pMplCtx // Pointer to MPL Context // pCurrentAddress // Pointer to MAC address to be added // pListen // Pointer to the listen list (multicast or unicast) // // Return Value // NS_STATUS_SUCCESS // The MAC address was succefully added to the listen list // //***************************************************************************** static MPL_STATUS listenAdd( IN MPL_CONTEXT *pMplCtx, IN MPL_MAC_ADDR pCurrentAddress, IN MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS] ) { NS_UINT16 rowIndex, colIndex; // Get the Hash Value getHashIndex(pCurrentAddress, &rowIndex, &colIndex); // Increment the reference count pListen[rowIndex][colIndex].refCnt++; // FM: Add to tracking list // Update the Hw's hash table if required if (pListen[rowIndex][colIndex].refCnt == 0x01) { updateHashTable(pMplCtx, rowIndex, colIndex); } return NS_STATUS_SUCCESS; } //***************************************************************************** // listenCheck // Checks if a MAC address is listed in the listen (i.e. accept) list // // Parameters // pMplCtx // Pointer to MPL Context // pCurrentAddress // Pointer to MAC address to be searched // pListen // Pointer to the listen list (multicast or unicast) // // Return Value // NS_STATUS_SUCCESS // The MAC address was found // NS_STATUS_FAILURE // Could not find the address // //***************************************************************************** static MPL_STATUS listenCheck ( IN MPL_CONTEXT *pMplCtx, IN MPL_MAC_ADDR pCurrentAddress, IN MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS] ) { NS_UINT16 rowIndex, colIndex; // Get the Hash Value getHashIndex(pCurrentAddress, &rowIndex, &colIndex); // Update the Hw's hash table if required if (pListen[rowIndex][colIndex].refCnt) { // TBD: Do a perfect match check - In tracking list return NS_STATUS_SUCCESS; } else return NS_STATUS_FAILURE; } //***************************************************************************** // listenDel // Deletes a MAC address from the listen (i.e. accept) list // // Parameters // pMplCtx // Pointer to MPL Context // pCurrentAddress // Pointer to MAC address to be deleted // pListen // Pointer to the listen list (multicast or unicast) // // Return Value // NS_STATUS_SUCCESS // The MAC address was succefully deleted from the listen list // //***************************************************************************** static MPL_STATUS listenDel( IN MPL_CONTEXT *pMplCtx, IN MPL_MAC_ADDR pCurrentAddress, IN MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS] ) { MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 rowIndex, colIndex; // Get the Hash Value getHashIndex(pCurrentAddress, &rowIndex, &colIndex); // Update the Hw's hash table if required if (pListen[rowIndex][colIndex].refCnt != 0x0) { // Decrement the reference count pListen[rowIndex][colIndex].refCnt--; // FM: Del from tracking list // Update the Hw's hash table if required if (pListen[rowIndex][colIndex].refCnt == 0x0) { updateHashTable(pMplCtx, rowIndex, colIndex); } } else { status = NS_STATUS_FAILURE; } return status; } //***************************************************************************** // listenClear // Clears all MAC addresses from the listen (i.e. accept) list // // Parameters // pMplCtx // Pointer to MPL Context // pListen // Pointer to the listen list (multicast or unicast) // // Return Value // NS_STATUS_SUCCESS // The MAC address was succefully deleted from the listen list // //***************************************************************************** static MPL_STATUS listenClear( IN MPL_CONTEXT *pMplCtx, IN MPL_LISTEN_LIST pListen[][MAX_FILTER_COLS] ) { NS_UINT16 rowIndex, colIndex; // Update the Hw's hash table if required for (rowIndex = 0x0; rowIndex < MAX_FILTER_ROWS; rowIndex++) { for (colIndex = 0x0; colIndex < MAX_FILTER_COLS; colIndex++) { // FM: Del from tracking list // Reset the reference count and tell device about it pListen[rowIndex][colIndex].refCnt = 0x0; updateHashTable(pMplCtx, rowIndex, colIndex); } } return NS_STATUS_SUCCESS; } //***************************************************************************** // updateHashTable // Updates the hash table entry on the device to match the one maintained // by this software module // // Parameters // pMplCtx // Pointer to MPL Context // rowIndex // Row index for the hash table to be modified. // colIndex // Col index for the hash table to be modified. // // Return Value // NS_STATUS_SUCCESS // The hardware was successfully notified // //***************************************************************************** static MPL_STATUS updateHashTable( IN MPL_CONTEXT *pMplCtx, IN NS_UINT16 rowIndex, IN NS_UINT16 colIndex ) { NS_UINT32 rfcrVal, hashVal; // Disable Rx filter rfcrVal = MPL_READ32(pMplCtx, RFCR); MPL_WRITE32(pMplCtx, RFCR, rfcrVal & ~RXFLTR_EN); // Set control bits to get to wordIndex MPL_WRITE32(pMplCtx, RFCR, HASH_TABLE_INDEX + (rowIndex * 2)); // Read current hash setting at wordIndex -16bits hashVal = MPL_READ32(pMplCtx, RFDR); // Write the new hashValue if (pMplCtx->taskRxFilter.mcTable[rowIndex][colIndex].refCnt || pMplCtx->taskRxFilter.ucTable[rowIndex][colIndex].refCnt) { // Multicast or Unicast Address needs to be accepted MPL_WRITE32(pMplCtx, RFDR, hashVal | (1 << colIndex)); } else { // Neither Multicast or Unicast Address needs to be accepted MPL_WRITE32(pMplCtx, RFDR, hashVal & ~(1 << colIndex)); } // Reenable Rx filter MPL_WRITE32(pMplCtx, RFCR, rfcrVal); return NS_STATUS_SUCCESS; } //***************************************************************************** // getHashIndex // Gets the row and col index into the hash table based on a given MAC // address // // Parameters // pCurrentAddress // Pointer to MAC address // rowIndex // Pointer to a caller supplier variable where the Row index into the // hash-table is returned // colIndex // Pointer to a caller supplier variable where the column index into the // hash-table is returned // // Return Value // None // //***************************************************************************** static NS_VOID getHashIndex( IN MPL_MAC_ADDR pCurrentAddress, IN NS_UINT16 *rowIndex, IN NS_UINT16 *colIndex ) { NS_UINT32 crc, msb; NS_UINT8 i, j, currByte; // Get the CRC crc = 0xffffffffL; for (i = 0; i < 0x6; i++) { currByte = *pCurrentAddress++; for (j = 0; j < 0x8; j++) { msb = crc >> 31; crc <<= 1; if ( msb ^ ( currByte & 1 ) ) { crc ^= IEEE_802_3_FCS_HASH_FUNC; crc |= 1; } currByte >>= 1; } } // Compute the word and bit indexes // Word(Row) index is bits 31-27 of the crc // Bit(Col) index is bits 26-23 of the crc crc >>= 23; *rowIndex = (NS_UINT16)((crc >> 4) & 0x1fL); *colIndex = (NS_UINT16)(crc & 0xfL); return; } #endif // MPL_TASK_RECEIVE_FILTER DP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskchksum.c0000444000000000000000000000075710430225772017544 0ustar rootroot //****************************************************************************** // // MPLTASKCHKSUM.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL checksum (IP, TCP, UDP) Offload Task Module. // // This file contains the API implementations for // o Configuring the checksum offload task module // o Set/Query of checksum operation // //****************************************************************************** DP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskvlaninternal.h0000444000000000000000000000236610430225772020752 0ustar rootroot //********************************************************************** // // MPLTASKVLANINTERNAL.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This is the internal file with definitions meant for VLAN task // //********************************************************************** #ifndef _MPL_TASK_VLAN_INTERNAL_H #define _MPL_TASK_VLAN_INTERNAL_H // Defines table size - This ensure perfect match (total VLAN-id // bits = 12 #define MAX_VLAN_FILTER_ROWS 512 #define MAX_VLAN_FILTER_COLS 8 #define VLAN_MAX_PRIORITY 7 #define VLAN_MAX_ID 4095 // VTCI Format = (msb) vlanid[7:0], prio[2:0], CFI, vlanid[11:8] (lsb) #define VLAN_MAKE_TAG(pktId, pktPri) \ (((((pktId) & 0xff) << 8) | (((pktId) & 0xf00) >> 8)) | (((pktPri) & 0x7) << 5)); #define VLAN_BREAK_TAG(extSts, ppktId, ppktPri) \ *ppktId = ((((extSts) & 0xff00) >> 8) | (((extSts) & 0x000f) << 8)); \ *ppktPri = (((extSts) & 0xe0) >> 5); typedef struct MPL_TASK_VLAN_CTX { NS_BOOLEAN enable; // Feature enable tracker NS_UINT cfg; // Current config NS_UINT8 filterTable[MAX_FILTER_ROWS][MAX_FILTER_COLS]; } MPL_TASK_VLAN_CTX; #endif //_MPL_TASK_VLAN_INTERNAL_H DP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskrxfilterinternal.h0000444000000000000000000000161610430225772021646 0ustar rootroot //********************************************************************** // // MPLTASKRXFILTERINTERNAL.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This is the internal file with definitions meant for Rx Filter Task // //********************************************************************** #ifndef _MPL_RX_INTERNAL_INTERNAL_H #define _MPL_RX_INTERNAL_INTERNAL_H typedef struct _MPL_LISTEN_LIST{ NS_UINT16 refCnt; // Reference count // FM: Head pointer for perfect match } MPL_LISTEN_LIST; typedef struct MPL_TASK_FILTER { NS_BOOLEAN enable; // Feature enable tracker // Multicast Listen Table MPL_LISTEN_LIST mcTable[MAX_FILTER_ROWS][MAX_FILTER_COLS]; // Unicast Listen Table MPL_LISTEN_LIST ucTable[MAX_FILTER_ROWS][MAX_FILTER_COLS]; } MPL_TASK_FILTER; #endif //_MPL_RX_INTERNAL_INTERNAL_H DP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskstat.c0000444000000000000000000000074510430225772017222 0ustar rootroot //****************************************************************************** // // MPLTASKSTAT.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Statistics Offload Task Module. // // This file contains the API implementations for // o Configuring the statistics offload task module // o Fetching the latest counter values // //****************************************************************************** DP8381X-Linux-Ver-1.6/Mpl/Tasks/mpltaskvlan.c0000444000000000000000000004023610430225772017206 0ustar rootroot//****************************************************************************** // // MPLTASKVLAN.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL VLAN Offload Task Module. // // This file contains the API implementations for // o Configuring the VLAN offload task module // o Adding/Deleting VLAN tags (global, transmit, receive) // o Set/Query of VLAN tags in packets // //****************************************************************************** #include #ifdef MPL_TASK_VLAN // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_TASK_VLAN, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_TASK_VLAN, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_TASK_VLAN, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_TASK_VLAN, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_TASK_VLAN, \ (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_TASK_VLAN, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_TASK_VLAN, fmt) static NS_VOID getHashIndex(NS_UINT16 vlanId, NS_UINT16 *rowIndex, NS_UINT16 *colIndex); //***************************************************************************** // MplTaskVlanCfg // Enable/Disable and configure the VLAN module // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // enableFlag // Set to NS_TRUE to enable the VLAN tag insertion and removal process, // NS_FALSE to disable. // cfg // Bit map of configuration options for the VLAN task offload module. // MPL_TASK_VLAN_DETECT_TAGS - Detect VLAN tags in incoming pkts // and include tag data in OOB field of MPL_PKT // MPL_TASK_VLAN_REMOVE_TAGS - Specifies the MPL should remove VLAN // tags from receive packets indicated to the NSM. // MPL_TASK_VLAN_DISCARD_TAGGED – Enables discard of frames *with* // a VLAN tag. // MPL_TASK_VLAN_DISCARD_UNTAGGED – Enables discard of frames // *without* a VLAN tag. // MPL_TASK_VLAN_FILTER - Enables MPL’s VLAN ID receive filter. // MPL_TASK_VLAN_PERPACKET - Include VLAN tag on a per pkt basis // - For Tx only (See Global insertion in MplTaskVlanAddTxTag) // // Return Value // NS_STATUS_SUCCESS // The task offload was successfully enabled or disabled. // NS_STATUS_NOT_SUPPORTED // This offload task or selected configuration option is not supported // by MPL. // //***************************************************************************** MPL_STATUS MplTaskVlanCfg ( IN NS_VOID *pMplHandle, IN NS_BOOLEAN enableFlag, IN NS_UINT cfg ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT32 regVal; ENTER(MplTaskVlanCfg); // Note enable/disable mode pMplCtx->taskVlan.enable = enableFlag; if (pMplCtx->taskVlan.enable == NS_TRUE) { // Make sure that we support this offload and the required cfg options if ((pMplCtx->caps.taskCaps.vlan.supported == NS_TRUE) && (pMplCtx->caps.taskCaps.vlan.vlanFlags & cfg)) { // Note the cfg request pMplCtx->taskVlan.cfg = cfg; // Enable each Rx config request regVal = MPL_READ32(pMplCtx, VRCR);; if (cfg & MPL_TASK_VLAN_DETECT_TAGS) regVal |= VTDEN; // Enable tag detection if (cfg & MPL_TASK_VLAN_REMOVE_TAGS) regVal |= VTREN; if (cfg & MPL_TASK_VLAN_DISCARD_TAGGED) regVal |= DVTF; if (cfg & MPL_TASK_VLAN_DISCARD_UNTAGGED) regVal |= DUTF; // Notify H/w abt Rx VLAN cfg MPL_WRITE32(pMplCtx, VRCR, regVal); // Enable each Tx config request regVal = MPL_READ32(pMplCtx, VTCR);; if (cfg & MPL_TASK_VLAN_PERPACKET) regVal |= VPPTI; // Notify H/w abt Tx VLAN cfg MPL_WRITE32(pMplCtx, VTCR, regVal); // Need to enable extended status field on descriptors regVal = MPL_READ32(pMplCtx, CFG); MPL_WRITE32(pMplCtx, CFG, regVal | EXTENDEDDESC_EN); } else { pMplCtx->taskVlan.cfg = 0x0; status = NS_STATUS_NOT_SUPPORTED; } } EXIT(MplTaskVlanCfg); return status; } //***************************************************************************** // MplTaskVlanAddTxTag // Add a new VLAN tag to used globally for all Tx pkts // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be inserted globally for all transmits packets. // vlanPriority // VLAN priority to be inserted globally for all transmits packets. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully added. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // //***************************************************************************** MPL_STATUS MplTaskVlanAddTxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId, IN NS_UINT8 vlanPriority ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT32 regVal; NS_UINT16 vlanTag; ENTER(MplTaskVlanAddTxTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check values if ((vlanId > VLAN_MAX_ID) || (vlanPriority > VLAN_MAX_PRIORITY)) { return NS_STATUS_INVALID_PARM; } // Build the VLAN tag regVal = MPL_READ32(pMplCtx, VTCR);; regVal = (regVal & ~VPPTI) | VGTI; // Global tag insertion now vlanTag = VLAN_MAKE_TAG(vlanId, vlanPriority); regVal = (regVal & VTCI_MASK) | (vlanTag << VTCI_SHIFT); // Notify H/w MPL_WRITE32(pMplCtx, VTCR, regVal); EXIT(MplTaskVlanAddTxTag); return status; } //***************************************************************************** // MplTaskVlanAddRxTag // Add a new VLAN tag to the Rx filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be inserted in the receive filter for incoming // receive packets. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully added. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // NS_STATUS_RESOURCES // The maximum filter list size was reached. // //***************************************************************************** MPL_STATUS MplTaskVlanAddRxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 rowIndex, colIndex; ENTER(MplTaskVlanAddRxTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check values if (vlanId > VLAN_MAX_ID) { return NS_STATUS_INVALID_PARM; } // Get the Hash Value getHashIndex(vlanId, &rowIndex, &colIndex); // Update the filter table - Should be a perfect match // so force to absolute 1 and 0s. pMplCtx->taskVlan.filterTable[rowIndex][colIndex] = 0x01; EXIT(MplTaskVlanAddRxTag); return status; } //***************************************************************************** // MplTaskVlanDeleteRxTag // Delete a VLAN tag from the Rx filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be removed from the receive filter list. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully deleted. // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskVlanDeleteRxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 rowIndex, colIndex; ENTER(MplTaskVlanDeleteRxTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Get the Hash Value getHashIndex(vlanId, &rowIndex, &colIndex); // Update the filter table - Should be a perfect match // so force to absolute 1 and 0s. pMplCtx->taskVlan.filterTable[rowIndex][colIndex] = 0x0; EXIT(MplTaskVlanDeleteRxTag); return status; } //***************************************************************************** // MplTaskVlanClearRxTag // Clear the Rx VLAN filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The VLAN tags were successfully cleared. // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskVlanClearRxTag ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 rowIndex, colIndex; ENTER(MplTaskVlanClearRxTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } for (rowIndex = 0x0; rowIndex < MAX_VLAN_FILTER_ROWS; rowIndex++) { for (colIndex = 0x0; colIndex < MAX_VLAN_FILTER_COLS; colIndex++) { // Reset the reference count pMplCtx->taskVlan.filterTable[rowIndex][colIndex] = 0x0; } } EXIT(MplTaskVlanClearRxTag); return status; } //***************************************************************************** // MplTaskVlanCheckRxTag // Check if the VLAN tag is to be filtered out // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // The VLAN id (0 to 4095 inclusive) // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was found // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_NOT_PRESENT // Could not find the VLAN tag // //***************************************************************************** MPL_STATUS MplTaskVlanCheckRxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 rowIndex, colIndex; ENTER(MplTaskVlanCheckRxTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Get the Hash Value getHashIndex(vlanId, &rowIndex, &colIndex); // Check in the filter table if (pMplCtx->taskVlan.filterTable[rowIndex][colIndex]) { return NS_STATUS_SUCCESS; } else return NS_STATUS_NOT_PRESENT; EXIT(MplTaskVlanCheckRxTag); return status; } //***************************************************************************** // MplSetPacketVlanTag // Set a given VLAN tag to the outgoing pkt (per packet mode) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pPacket // Pointer to the MPL_PKT structure that describes the frame to be // transmitted // vlanId // The VLAN id (0 to 4095 inclusive) to be used to transmit this packet // vlanPriority // The VLAN priority (0 to 7 inclusive) to be used to transmit this // packet // // Return Value // NS_STATUS_SUCCESS // The VLAN id was successfully set for the packet. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // //***************************************************************************** MPL_STATUS MplSetPacketVlanTag ( IN NS_VOID *pMplHandle, IN MPL_PKT *pPacket, IN NS_UINT16 vlanId, IN NS_UINT8 vlanPriority ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplSetPacketVlanTag); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check values if ((vlanId > VLAN_MAX_ID) || (vlanPriority > VLAN_MAX_PRIORITY)) { return NS_STATUS_INVALID_PARM; } // Build the VLAN tag pPacket->txOOB.extCtl = ECS_VPKT | VLAN_MAKE_TAG(vlanId, vlanPriority); EXIT(MplSetPacketVlanTag); return status; } //***************************************************************************** // MplQueryPacketVlanTag // Retrieve the VLAN tag in a given Rx packet // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pPacket // Pointer to the MPL_PKT structure that describes the frame just // received // pVlanId // Pointer to a caller provided variable in which the VLAN id (0 to // 4095 inclusive) is returned. // pVlanPriority // Caller allocated variable in which this function returns the VLAN // priority (0 to 7 inclusive) on the received frame. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully retrieved for the packet. // NS_STATUS_INVALID_PARM // The packet is not a VLAN tagged packet. // NS_STATUS_FAILURE // This offload feature is disabled // //**************************************************************************** MPL_STATUS MplQueryPacketVlanId ( IN NS_VOID *pMplHandle, IN MPL_PKT *pPacket, IN NS_UINT16 *pVlanId, IN NS_UINT8 *pVlanPriority ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplQueryPacketVlanId); // Check if this feature is enabled if (pMplCtx->taskVlan.enable != NS_TRUE) { return NS_STATUS_FAILURE; } // Check if this packet has a VLAN tag if (pPacket->rxOOB.extSts & ECS_VPKT) { VLAN_BREAK_TAG(pPacket->rxOOB.extSts, pVlanId, pVlanPriority) } else { return NS_STATUS_INVALID_PARM; } EXIT(MplQueryPacketVlanId); return status; } //***************************************************************************** // getHashIndex // Gets the row and col index into the hash table based on a given VLAN // id // // Parameters // vlanId // vlanId // rowIndex // Pointer to a caller supplier variable where the Row index into the // hash-table is returned // colIndex // Pointer to a caller supplier variable where the column index into the // hash-table is returned // // Return Value // None // //***************************************************************************** static NS_VOID getHashIndex( IN NS_UINT16 vlanId, IN NS_UINT16 *rowIndex, IN NS_UINT16 *colIndex ) { *rowIndex = vlanId >> 3; // Bits 11:3 *colIndex = vlanId & 0x007; // Bits 2:0 return; } #endif DP8381X-Linux-Ver-1.6/Mpl/mpltransmit.c0000444000000000000000000006507510430225754016147 0ustar rootroot //****************************************************************************** // // MPLTRANSMIT.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Transmit Engine. // // This file contains the API implementations for // o MPL transmit engine configuration // o MPL packet transmit and completion handlers // o Transmit engine reset // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_TRANS, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_TRANS, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_TRANS, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_TRANS, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_TRANS, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_TRANS, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_TRANS, fmt) // Locals static NS_VOID setTxCfg(MPL_CONTEXT *pMplCtx,MPL_TRANSMIT_CFG *pCfgTransmit); static MPL_STATUS allocTxdRing(MPL_CONTEXT *pMplCtx); static NS_VOID setupTxdRing(MPL_CONTEXT *pMplCtx); //***************************************************************************** // MplTransmitCfg // Configures the transmit engine on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pCfgTransmit // Pointer to a caller allocated MPL_TRANSMIT_CFG structure with // configuration values for the transmit engine // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_INVALID_PARM // An invalid parameter value was detected // NS_STATUS_RESOURCES // Failed to allocate required resources // //***************************************************************************** MPL_STATUS MplTransmitCfg ( IN NS_VOID *pMplHandle, IN MPL_TRANSMIT_CFG *pCfgTransmit ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT8 i; NS_UINT32 regVal; // FM: Assert for pCfgTransmit == NULL ENTER(MplTransmitCfg); // Configure FIFO and DMA if client desires if (pCfgTransmit->cfgFlags & MPL_TRANSMIT_CFG_FIFO) { // Validate the FIFO thresholds and DMA burst size if ((pCfgTransmit->fillThreshold < pMplCtx->caps.txCaps.minFill) || (pCfgTransmit->drainThreshold < pMplCtx->caps.txCaps.minDrain) || ((pCfgTransmit->fillThreshold + pCfgTransmit->drainThreshold) > pMplCtx->caps.txCaps.fifoSize) || (pCfgTransmit->maxDmaBurst > pMplCtx->caps.txCaps.maxDma) || (pCfgTransmit->maxDmaBurst > pCfgTransmit->fillThreshold)) { EXIT(MplTransmitCfg); return NS_STATUS_INVALID_PARM; } // Notify the hardware about the FIFO thresholds and DMA burst setTxCfg(pMplCtx, pCfgTransmit); } // Configure Tx queues if client desires if (pCfgTransmit->cfgFlags & MPL_TRANSMIT_CFG_QUEUES) { // Validate the priority queue count - should be atleast 1! if (pCfgTransmit->priorityQueueCnt > pMplCtx->caps.txCaps.priorityQCnt) { EXIT(MplTransmitCfg); return NS_STATUS_INVALID_PARM; } // If this is a runtime reconfiguration request, then free the old ring if (pMplCtx->txDescCnt) { freeTxdRing(pMplCtx); } // Get the Txd count - for all enabled queues pMplCtx->txQueueCnt = pCfgTransmit->priorityQueueCnt; for (i = 0x0; i < pMplCtx->txQueueCnt; i++) { pMplCtx->txQueue[i].descCnt = pCfgTransmit->descCnt[i]; //per queue pMplCtx->txDescCnt += pCfgTransmit->descCnt[i]; } // Note max transmit done indications to be passed to NSM in one pass pMplCtx->maxTxDones = pCfgTransmit->maxIndications; // Allocate Txd ring if (allocTxdRing(pMplCtx) != NS_STATUS_SUCCESS) { EXIT(MplTransmitCfg); return NS_STATUS_RESOURCES; } // Setup Txd ring setupTxdRing(pMplCtx); // Enable priority Queuing if more than one Tx queue is requested if (pMplCtx->txQueueCnt > 0x01) { regVal = MPL_READ32(pMplCtx, PQCR);; regVal |= TXPRIOQ_EN; // Check if caller requests round-robin scheme for queue scheduling if (pCfgTransmit->cfgFlags & MPL_TRANSMIT_CFG_QUEUE_RR) regVal |= ROTPRIO_EN; MPL_WRITE32(pMplCtx, PQCR, regVal); } // Notify the device about the head node on the ring MPL_WRITE32(pMplCtx, TXDP, pMplCtx->txQueue[0].ringPA); MPL_WRITE32(pMplCtx, TXDP1, pMplCtx->txQueue[1].ringPA); MPL_WRITE32(pMplCtx, TXDP2, pMplCtx->txQueue[2].ringPA); MPL_WRITE32(pMplCtx, TXDP3, pMplCtx->txQueue[3].ringPA); } EXIT(MplTransmitCfg); return NS_STATUS_SUCCESS; // All done } //***************************************************************************** // MplTransmitGetFreeDesc // Returns the total free transmit descriptors currently available. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pQueue // Queue (1,2...max tx queues) from which the free count is desired // pTxdCnt // Pointer to a caller allocated fields in which the count of free // transmit descriptors is returned // // Return Value // NS_STATUS_SUCCESS // The count was successfully returned. // NS_STATUS_INVALID_PARM // The priority queue count is invalid // //***************************************************************************** MPL_STATUS MplTransmitGetFreeDesc ( IN NS_VOID *pMplHandle, IN NS_UINT8 pQueue, OUT NS_UINT *pTxdCnt ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplTransmitGetFreeDesc); // Validate the pQueue number if (pQueue > pMplCtx->txQueueCnt) { EXIT(MplTransmitGetFreeDesc); return NS_STATUS_INVALID_PARM; } // Get the free Txd count - Note we always hold one for ring termination *pTxdCnt = (pMplCtx->txQueue[pQueue-1].descCnt - 1) - (pMplCtx->txQueue[pQueue-1].curr - pMplCtx->txQueue[pQueue-1].dirty); EXIT(MplTransmitGetFreeDesc); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplTransmit // Queues up one or more packets for transmission by the device. // NOTE: This function is non-reentrant with respect to itself, // MplTransmitReset and MplTransmitDone // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pktCount // The count of packets being queued for transmission // pPacket // Pointer to a list of MPL_PKT structures due for transmission // // Return Value // NS_STATUS_SUCCESS // All packets were successfully queued up for transmission // NS_STATUS_FAILURE // One or more of the packets where unacceptable for transmission // Clients need to check the status of each packet to detemine // which one failed, // // Per packet status (pPacket->packetStatus) is one of // NS_STATUS_INVALID_PARM // The priority queue count is invalid // NS_STATUS_RESOURCES // Failed to allocate the required resources (Txds) // //***************************************************************************** MPL_STATUS MplTransmit ( IN NS_VOID *pMplHandle, IN NS_UINT pktCount, IN MPL_PKT *pPacket ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; MPL_DESC *currTxd, *firstTxd; MPL_PKT_FRAG *pFrag; NS_UINT8 priQSel = 0x0, pQueue; NS_UINT i, entry, fragIndex, cmdSts, csFlag, txdAvail; ENTER(MplTransmit); // Send each packet for (i = 0x0; i < pktCount; i++) { // Get the priority queue number and validate if ((pPacket->txOOB.pQueue > pMplCtx->txQueueCnt) || (pPacket->txOOB.pQueue < 0x1)) { // Invalid Tx Q pPacket->packetStatus = NS_STATUS_INVALID_PARM; status = NS_STATUS_FAILURE; continue; // To Next Pkt } // Set the priority queue select pQueue = pPacket->txOOB.pQueue - 1; // Get available Txd count txdAvail = (pMplCtx->txQueue[pQueue].descCnt - 1) - (pMplCtx->txQueue[pQueue].curr - pMplCtx->txQueue[pQueue].dirty); // Check availability - Each fragment needs a Txd if (txdAvail < pPacket->fragCount) { pPacket->packetStatus = NS_STATUS_RESOURCES; status = NS_STATUS_FAILURE; continue; // To Next Pkt - Maybe it is on a diff Tx-Q } // Set the priority queue select priQSel |= 1 << pQueue; // Get the first Txd for this packet entry = pMplCtx->txQueue[pQueue].curr % pMplCtx->txQueue[pQueue].descCnt; firstTxd = &pMplCtx->txQueue[pQueue].pRing[entry]; // When dealing with multiple Txds per packet, the first Txd will // have its OWN bit set last (to avoid Tx underruns) csFlag = CS_INTR; #ifdef MPL_TASK_VLAN // If we are in VLAN per-pkt tag insertion mode then include the tag if (pMplCtx->taskVlan.cfg & MPL_TASK_VLAN_PERPACKET) { firstTxd->extCtlSts = MPL_HTOL32(pPacket->txOOB.extCtl); } else { firstTxd->extCtlSts = 0x0; // Clear } #endif // Get the frag head pFrag = pPacket->pFragHead; fragIndex = 0x0; // Process each fragment currTxd = firstTxd; while (fragIndex < pPacket->fragCount) { // Check fragSize to be within max allowed if (pFrag->fragSize > CS_MAX_FRAG_SIZE) { pPacket->packetStatus = NS_STATUS_INVALID_PARM; status = NS_STATUS_FAILURE; break; // Go to next packet } // Set the buffer length and buffer phy address currTxd->bufptrPA = MPL_ADDR_HTOL(pFrag->physAddr); cmdSts = pFrag->fragSize; // Swapped later // Copy the physical addr of Txd - for diag mode operations only pFrag->pMplPrivate = (NS_VOID *)(pMplCtx->txQueue[pQueue].ringPA + (entry * sizeof(MPL_DESC))); // Increment the frag count and check if this is the last fragment if (++fragIndex < pPacket->fragCount) { PRINT(("Multi Txd? %d\n", pPacket->fragCount)); // More frags to go // Set MORE on the current Txd currTxd->cmdSts = MPL_HTOL32(cmdSts | csFlag | CS_MORE); // Get the next Txd in the reserved order entry = (entry + 1) % pMplCtx->txQueue[pQueue].descCnt; currTxd = &pMplCtx->txQueue[pQueue].pRing[entry]; // All further fragments will have its OWN bit set // Note: See the OWN bit for first fragment above csFlag = CS_OWN_INTR; // Move on to the next fragment pFrag = pFrag->pNextFrag; } else { // Last frag // Note the Client Handle in this last Txd currTxd->mplPriv = pPacket->pNsmPrivate; // Set OWN, no MORE currTxd->cmdSts = MPL_HTOL32(cmdSts | CS_OWN_INTR); // For cases with MPL_PKT having multiple fragments we need to // hit the OWN bit for the first Txd - See notes above if (currTxd != firstTxd) { firstTxd->cmdSts |= CS_OWN_ES; } // Move free Txd index pMplCtx->txQueue[pQueue].curr += pPacket->fragCount; // Note the status pPacket->packetStatus = NS_STATUS_SUCCESS; } } // Get the next packet pPacket = pPacket->pNextPacket; } // FM: Evaulate if we should hit TXE per packet or a set of packets MPL_WRITE32(pMplCtx, CR, (priQSel << TX_PQUEUE_OFF) | TX_EN); EXIT(MplTransmit); return status; } //***************************************************************************** // MplTransmitDone // Processes transmit engine related events. // NOTE: This function is non-reentrant with respect to itself, // MplTransmitReset and MplTransmit // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum transmit engine related events (e.g. transmit complete) // that MPL should process before returning back to the caller. // // Return Value // NS_STATUS_SUCCESS // The transmit event was successfully handled. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplTransmitDone ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; MPL_DESC *currTxd; NS_UINT8 pQueue, qNum; NS_UINT priQSel, entry, pktCnt = 0x0, evtCnt = 0x0; ENTER(MplTransmitDone); // Get the Priority Queues that have completion events if (pMplCtx->txQueueCnt > 1) { priQSel = (pMplCtx->isrReg & TXDESC_MASK) >> TXDESC_OFF; } else { // Only one queue to process priQSel = 0x01; } // Process each queue - Start with highest priority for (qNum = pMplCtx->txQueueCnt; (qNum > 0x0) && (status == NS_STATUS_SUCCESS); qNum--) { pQueue = qNum - 1; // 0-Indexed // Check if this queue has any completed packets if ((1 << pQueue) & priQSel) { // Process the Txd ring while ((pMplCtx->txQueue[pQueue].curr - pMplCtx->txQueue[pQueue].dirty) > 0x0) { // Get the entry index entry = pMplCtx->txQueue[pQueue].dirty % pMplCtx->txQueue[pQueue].descCnt; currTxd = &pMplCtx->txQueue[pQueue].pRing[entry]; // Check if the hardware is done i.e. OWN is cleared if (currTxd->cmdSts & CS_OWN_ES) { break; } // Check if we reached limit if ((maxEvents != 0x0) && (evtCnt >= maxEvents)) { status = NS_STATUS_ABORTED; break; } // Check if this is the last Txd for this packet if (currTxd->cmdSts & CS_MORE_ES) { // Go to the next Txd pMplCtx->txQueue[pQueue].dirty++; continue; } // FM : Define event.. Is it per pkt or per processed Txd? // Below it is defined as per packet evtCnt++; // FM : Need to add Stat code for collecting Tx errors // Prepare indication event to NSM pMplCtx->txDone[pktCnt].pNsmPrivate = currTxd->mplPriv; pMplCtx->txDone[pktCnt].cmdSts = MPL_LTOH32(currTxd->cmdSts); pMplCtx->txDone[pktCnt++].packetStatus = (currTxd->cmdSts & CS_OK_ES) ? NS_STATUS_SUCCESS : NS_STATUS_FAILURE; // Check if it is time to report to NSM if (pktCnt >= pMplCtx->maxTxDones) { NsmTransmitDone(pMplCtx->pClientHandle, pktCnt, pMplCtx->txDone); pktCnt = 0x0; } // Go to the next Txd pMplCtx->txQueue[pQueue].dirty++; } } } // Report remaining completed packets to NSM if (pktCnt > 0x0) { NsmTransmitDone(pMplCtx->pClientHandle, pktCnt, pMplCtx->txDone); } EXIT(MplTransmitDone); return status; } //***************************************************************************** // MplTransmitReset // Resets the transmit engine on the device and associated resources. // NOTE: This function is non-reentrant with respect to itself, // MplTransmit and MplTransmitDone // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The transmit engine was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error - No reset done notification from Hw // //***************************************************************************** MPL_STATUS MplTransmitReset ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_DESC *currTxd; NS_UINT pQueue, entry, pktCnt = 0x0; ENTER(MplTransmitReset); // Make sure we were initialized to begin with if (pMplCtx->txQueueCnt == 0x0) { EXIT(MplTransmitReset); return NS_STATUS_SUCCESS; } // Tell the hardware to reset its Tx engine MPL_WRITE32(pMplCtx, CR, TXRESET); // Total 4msec - Not waiting for notification OaiSleep(4 * RESETINTERVAL_MAC); // Process each Tx queue for (pQueue = 0x0; pQueue < pMplCtx->txQueueCnt; pQueue++) { // Process the Txd ring - Look for pending packets while ((pMplCtx->txQueue[pQueue].curr - pMplCtx->txQueue[pQueue].dirty) > 0x0) { // Get the entry index and corresponding Txd entry = pMplCtx->txQueue[pQueue].dirty % pMplCtx->txQueue[pQueue].descCnt; currTxd = &pMplCtx->txQueue[pQueue].pRing[entry]; // If the current Txd is the last one in a packet, report its // status as ABORTED to NSM if ((currTxd->cmdSts & CS_MORE_ES) == 0x0) { // Prepare indication event to NSM pMplCtx->txDone[pktCnt].pNsmPrivate = currTxd->mplPriv; pMplCtx->txDone[pktCnt].cmdSts = 0x0; pMplCtx->txDone[pktCnt++].packetStatus = NS_STATUS_ABORTED; // Check if it is time to report to NSM if (pktCnt >= pMplCtx->maxTxDones) { NsmTransmitDone(pMplCtx->pClientHandle, pktCnt, pMplCtx->txDone); pktCnt = 0x0; } } // Clear Txd currTxd->cmdSts = 0x0; currTxd->bufptrPA = 0x0; currTxd->mplPriv = 0x0; // Go to the next Txd pMplCtx->txQueue[pQueue].dirty++; } // Reinit the ring pMplCtx->txQueue[pQueue].curr = 0x0; pMplCtx->txQueue[pQueue].dirty = 0x0; pMplCtx->txQueue[pQueue].ringPA = pMplCtx->txQueue[pQueue].pRgnHndl->phyAddr; pMplCtx->txQueue[pQueue].pRing = (MPL_DESC *)pMplCtx->txQueue[pQueue].pRgnHndl->pAddr; } // Report remaining pkts to NSM if (pktCnt > 0x0) { NsmTransmitDone(pMplCtx->pClientHandle, pktCnt, pMplCtx->txDone); } // Notify the device about the head node on the ring MPL_WRITE32(pMplCtx, TXDP, pMplCtx->txQueue[0].ringPA); MPL_WRITE32(pMplCtx, TXDP1, pMplCtx->txQueue[1].ringPA); MPL_WRITE32(pMplCtx, TXDP2, pMplCtx->txQueue[2].ringPA); MPL_WRITE32(pMplCtx, TXDP3, pMplCtx->txQueue[3].ringPA); EXIT(MplTransmitReset); return NS_STATUS_SUCCESS; } //***************************************************************************** // setTxCfg // Set the FIFO and DMA burst related configurations on the device // // Parameters // pMplCtx // Pointer to MPL Context // pCfgTransmit // Pointer to a caller allocated MPL_TRANSMIT_CFG structure with // configuration values for the transmit engine // // Return Value // None // //***************************************************************************** static NS_VOID setTxCfg( IN MPL_CONTEXT *pMplCtx, IN MPL_TRANSMIT_CFG *pCfgTransmit ) { NS_UINT32 txDma, txCfg, drain , fill; ENTER(setTxCfg); // Get the Tx DMA size txDma = 0x0; if (pCfgTransmit->maxDmaBurst < 8) txDma = MXDMA4; //Min else if (pCfgTransmit->maxDmaBurst < 16) txDma = MXDMA8; else if (pCfgTransmit->maxDmaBurst < 32) txDma = MXDMA16; else if (pCfgTransmit->maxDmaBurst < 64) txDma = MXDMA32; else if (pCfgTransmit->maxDmaBurst < 128) txDma = MXDMA64; else if (pCfgTransmit->maxDmaBurst < 256) txDma = MXDMA128; else if (pCfgTransmit->maxDmaBurst < 512) txDma = MXDMA256; else if (pCfgTransmit->maxDmaBurst < 1024) txDma = MXDMA512; else if (pCfgTransmit->maxDmaBurst < 2048) txDma = (MXDMA256 | TXDMA4); else txDma = (MXDMA512 | TXDMA4); //Max // Read the Txcfg contents txCfg = MPL_READ32(pMplCtx, TXCFG); // Mask the tx settable values txCfg &= ~TXSET_MASK; // Generate the TXCFG contents - The fill and drain are specified in // 32 byte units drain = (pCfgTransmit->drainThreshold / 32) & TXDRAIN_MASK; fill = ((pCfgTransmit->fillThreshold / 32) << TXFILL_SHIFT) & TXFILL_MASK; txCfg |= txDma | fill | drain; // Write TXCFG MPL_WRITE32(pMplCtx, TXCFG, txCfg); EXIT(setTxCfg); return; } //***************************************************************************** // allocTxdRing // Alloc all the Txd rings // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // NS_STATUS_SUCCESS // The rings were correctly setup // NS_STATUS_RESOURCES // Failed to allocate the resources (transmit control blocks) // //***************************************************************************** static MPL_STATUS allocTxdRing( IN MPL_CONTEXT *pMplCtx ) { MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT i, j; ENTER(allocTxdRing); // Allocate resources for the Tx done indications pMplCtx->txDone = (MPL_TRANSMIT_DONE *)OaiMalloc(sizeof(MPL_TRANSMIT_DONE) * pMplCtx->maxTxDones); if (pMplCtx->txDone == NULL) { EXIT(allocTxdRing); return NS_STATUS_RESOURCES; } OaiZeroMem(pMplCtx->txDone, sizeof(MPL_TRANSMIT_DONE) * pMplCtx->maxTxDones); // Allocate memory for the descriptors for (i = 0x0; i < pMplCtx->txQueueCnt; i++) { if (OaiAllocDmaRegion(pMplCtx->pClientHandle, sizeof(MPL_DESC) * pMplCtx->txQueue[i].descCnt, 4, // Aligned on 32-bits &pMplCtx->txQueue[i].pRgnHndl) == NS_FALSE) { // Allocation failed - Free all prev allocations for (j = 0x0; j < i; j++) { OaiFreeDmaRegion(pMplCtx->pClientHandle, pMplCtx->txQueue[j].pRgnHndl); } OaiFree(sizeof(MPL_TRANSMIT_DONE) * pMplCtx->maxTxDones, pMplCtx->txDone); status = NS_STATUS_RESOURCES; break; } else { // Reset mem block OaiZeroMem(pMplCtx->txQueue[i].pRgnHndl->pAddr, sizeof(MPL_DESC) * pMplCtx->txQueue[i].descCnt); } } EXIT(allocTxdRing); return status; } //***************************************************************************** // freeTxdRing // Free the Txd rings // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** NS_VOID freeTxdRing( IN MPL_CONTEXT *pMplCtx ) { NS_UINT i; ENTER(freeTxdRing); // Free resources for the Tx done indications if (pMplCtx->txDone != NULL) { OaiFree(sizeof(MPL_TRANSMIT_DONE) * pMplCtx->maxTxDones, pMplCtx->txDone); pMplCtx->txDone = NULL; } // Free memory for the descriptors for (i = 0x0; i < pMplCtx->txQueueCnt; i++) { if (pMplCtx->txQueue[i].pRgnHndl != NULL) { OaiFreeDmaRegion(pMplCtx->pClientHandle, pMplCtx->txQueue[i].pRgnHndl); pMplCtx->txQueue[i].pRgnHndl = NULL; } } EXIT(freeTxdRing); return; } //***************************************************************************** // setupTxdRing // Setup the Txd Rings // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID setupTxdRing( IN MPL_CONTEXT *pMplCtx ) { NS_UINT i, j; ENTER(setupTxdRing); // Set the Txd rings on each of enabled queue for (i = 0x0; i < pMplCtx->txQueueCnt; i++) { pMplCtx->txQueue[i].curr = 0x0; pMplCtx->txQueue[i].dirty = 0x0; // Note the ring's physical and logical start address pMplCtx->txQueue[i].ringPA = pMplCtx->txQueue[i].pRgnHndl->phyAddr; pMplCtx->txQueue[i].pRing = (MPL_DESC *)pMplCtx->txQueue[i].pRgnHndl->pAddr; for (j = 0x0; j < pMplCtx->txQueue[i].descCnt; j++) { // Link up and form a ring pMplCtx->txQueue[i].pRing[j].linkPA = MPL_ADDR_HTOL(pMplCtx->txQueue[i].ringPA + (sizeof(MPL_DESC) * ((j+1) % (pMplCtx->txQueue[i].descCnt)))); // Clear cmdstatus pMplCtx->txQueue[i].pRing[j].cmdSts = 0x0; } } EXIT(setupTxdRing); return; } DP8381X-Linux-Ver-1.6/Mpl/mplphy.c0000444000000000000000000011013010430225754015065 0ustar rootroot //****************************************************************************** // // MPLPHY.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Phy Interface Module. // // This file contains the API implementations for // o Detection of PHY // o Configuring the PHY // o Reporting PHY status // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_LINK, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_LINK, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_LINK, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_LINK, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_LINK, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_LINK, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_LINK, fmt) // Local functions static NS_VOID mdioIdle(MPL_CONTEXT *pMplCtx); static NS_VOID mdioSync(MPL_CONTEXT *pMplCtx); #ifndef MPL_EXTERNAL_PHY static NS_VOID phyAdjust(MPL_CONTEXT *pMplCtx); static NS_VOID atanPatchUp(MPL_CONTEXT *pMplCtx); static NS_VOID atanPatchDown(MPL_CONTEXT *pMplCtx); #else static NS_VOID mdioWriteReg(MPL_CONTEXT *pMplCtx, NS_UINT phyDevAddr, NS_UINT regIndex,NS_UINT16 regData); static NS_UINT16 mdioReadReg(MPL_CONTEXT *pMplCtx, NS_UINT phyDevAddr, NS_UINT regIndex); #endif // MPL_EXTERNAL_PHY //***************************************************************************** // MplPhyDetect // Detect the presence of a MacPhyter device on the system. // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // A MacPhyter device was successfully probed // NS_STATUS_HARDWARE_FAILURE // Could not find a MacPhyter device // //***************************************************************************** MPL_STATUS MplPhyDetect( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 phyIdr1, phyIdr2; ENTER(MplPhyDetect); // Sync up the MII bus mdioSync(pMplCtx); // Scan for a matching OUI. for (pMplCtx->phyDeviceAddr = 31; pMplCtx->phyDeviceAddr != 0; pMplCtx->phyDeviceAddr--) { // Check bits 3 - 18 of the OUI phyIdr1 = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_PHYIDR1); switch (phyIdr1) { case MP_PHY_ID1 : // NSC PHY Ids phyIdr2 = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_PHYIDR2); switch (phyIdr2 & 0xfff0) { case MP_PHY_REV : case ASPEN_PHY_REV : pMplCtx->phySiliconRev = phyIdr2 & 0xfff0; EXIT(MplPhyDetect); return NS_STATUS_SUCCESS; default : break; } break; #ifdef MPL_EXTERNAL_PHY // Add a case here to match your PHY Ids // EXTERNAL_PHY_HOOK Modify this to suit your specific device needs case DEFINE_PHY_ID : break; #endif } } EXIT(MplPhyDetect); return NS_STATUS_HARDWARE_FAILURE; } //***************************************************************************** // MplPhyReset // Reset the PHY device // // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // A MacPhyter device was successfully probed // NS_STATUS_HARDWARE_FAILURE // Could not find a MacPhyter device // //***************************************************************************** MPL_STATUS MplPhyReset( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT i; ENTER(MplPhyReset); // Hit the reset bit MplPhyMdioWrite(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR, PHY_RESET); // Wait (total 10 msec) for the PHY to come out of reset for (i = 0x0; i < 10; i ++) { OaiSleep(RESETINTERVAL_PHY); if ((MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR) & PHY_RESET) == 0x0) { // Reset done #ifndef MPL_EXTERNAL_PHY // For NSC internal PHYs some more work remains to be done { NS_UINT32 regVal; // Apply Optimization patch phyAdjust(pMplCtx); // Enable Phy Interrupts, after clearing pending ones regVal = MPL_READ32(pMplCtx, MISR); MPL_WRITE32(pMplCtx, MISR, regVal & ~(MSK_LINK | MSK_ANC)); MPL_WRITE32(pMplCtx, MICR, PHY_INT); } #else // Set Interrupts and other init time operations // EXTERNAL_PHY_HOOK Modify this to suit your specific device needs { DEFINE_PHY_INTERRUPTS; } #endif // MPL_EXTERNAL_PHY EXIT(MplPhyReset); return NS_STATUS_SUCCESS; } } EXIT(MplPhyReset); return NS_STATUS_HARDWARE_FAILURE; } //***************************************************************************** // MplPhyLinkSetup // Setup the link on the PHY with the requested settings // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // The link was set on the PHY device // NS_STATUS_INVALID_PARAM // An invalid link configuration was detected // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplPhyLinkSetup ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 bmcrVal, anarVal, bmcrValTmp; ENTER(MplPhyLinkSetup); // Reset the PHY to apply patches before link being set if (MplPhyReset(pMplCtx) != NS_STATUS_SUCCESS) { return NS_STATUS_HARDWARE_FAILURE; } // Setup AutoNeg advertisements if (pMplCtx->linkCfg.mode == MPL_LINK_MODE_AUTO) { #ifndef MPL_EXTERNAL_PHY // Prelink Patch Works - Only for Internal PHYs { // Apply fix for ATAN switch link-up issue atanPatchUp(pMplCtx); } #endif // MPL_EXTERNAL_PHY // Defaults bmcrVal = AUTONEG_ENABLE | AUTONEG_RESTART; anarVal = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_ANAR); anarVal &= ~(ADV_100BASET_FD | ADV_100BASET_HD | ADV_10BASET_FD | ADV_10BASET_HD | ADV_PAUSE | ADV_ASM_DIR); // Using a fall though switch case statement since // in AUTONEG mode the modes must be backwards compatible // When the user selects Half Duplex then he is backwards // compatible only in Half duplex modes and does not enter // any Full Duplex modes, but when in Full Duplex mode he // can get into any backward compatible mode. switch (pMplCtx->linkCfg.speed) { default: case MPL_LINK_SPEED_HUNDREDMBPS: if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL) { anarVal |= ADV_100BASET_FD; } // Half duplex and backward compatible anarVal |= ADV_100BASET_HD; case MPL_LINK_SPEED_TENMBPS: if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL) { anarVal |= ADV_10BASET_FD; } // Half duplex and backward compatible anarVal |= ADV_10BASET_HD; break; } // Setup advertisement of Flow control (Pause) switch (pMplCtx->linkCfg.pauseType) { case MPL_LINK_PAUSE_TRANSMIT: // Transmit of pause requests only anarVal |= ADV_ASM_DIR; break; case MPL_LINK_PAUSE_RECEIVE: // The Auto-Neg spec does not specify a way to adv receive // only of pause requests. So we will adv both asym and // sym pause support - Later after link is setup we can // disable the transmission of pause requests anarVal |= ADV_ASM_DIR | ADV_PAUSE; break; case MPL_LINK_PAUSE_SYMMETRICAL: // Tx and Rx // Both Transmit and Reception of pause requests anarVal |= ADV_ASM_DIR | ADV_PAUSE; break; default: // No pause advertisement break; } // If we need to do/restart AutoNegtiation then we // first check if we are in forced mode, if we are in forced // mode then we clear bit 12 of the BMCR (AUTO_NEG_ENABLE) and // then reset the bit to 1 and then write to register to restart // Auto Negotiation if required. bmcrValTmp = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR); if (!(bmcrValTmp & AUTONEG_ENABLE)) { // We clear the AUTONEGENABLE bit and then reset the bit // before we start a AutoNegotiate process. bmcrValTmp &= ~AUTONEG_ENABLE; MplPhyMdioWrite(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR, bmcrValTmp); bmcrValTmp |= AUTONEG_ENABLE; MplPhyMdioWrite(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR, bmcrValTmp); } } else { // Setup for Forced mode operation // Defaults bmcrVal = 0x0; anarVal = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_ANAR); anarVal &= ~(ADV_100BASET_FD | ADV_100BASET_HD | ADV_10BASET_FD | ADV_10BASET_HD | ADV_PAUSE | ADV_ASM_DIR); // Set the speed on the card individually // based on the user selection and force selection switch (pMplCtx->linkCfg.speed) { default: case MPL_LINK_SPEED_HUNDREDMBPS: if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL) { bmcrVal |= FORCE_MODE_FD; } bmcrVal |= FORCE_SPEED_100; break; case MPL_LINK_SPEED_TENMBPS: if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL) { bmcrVal |= FORCE_MODE_FD; } break; } } // Enable advertized values MplPhyMdioWrite(pMplCtx, pMplCtx->phyDeviceAddr, MII_ANAR, anarVal); // Write the new configuration MplPhyMdioWrite(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMCR, bmcrVal); EXIT(MplPhyLinkSetup); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplPhyGetLinkStatus // Returns the status of the link // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_STATUS_NONE // An unexpected hardware error occurred while processing this request // and the link state was not retrieved. // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up // //***************************************************************************** MPL_LINK_STATUS MplPhyGetLinkStatus ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplPhyGetLinkStatus); // Read the PhySts register to get the current link state // MacPhy requires the read of BMSR twice to correctly note // the link change event regVal = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMSR); regVal = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMSR); // Check the link state if (regVal & LINK_STATUS) { // Link Up // If we are in Auto-Neg mode, make sure that we are completely // ready if (pMplCtx->linkCfg.mode == MPL_LINK_MODE_AUTO) { if (regVal & AUTONEG_COMP) { EXIT(MplPhyGetLinkStatus); return MPL_LINK_STATUS_UP; } // We are in the process of setting up link EXIT(MplPhyGetLinkStatus); return MPL_LINK_STATUS_ACTIVE; } EXIT(MplPhyGetLinkStatus); return MPL_LINK_STATUS_UP; } // All other cases no Link // This is a good time to apply linkup related patches // (to link correctly with (potentially) a new partner) #ifndef MPL_EXTERNAL_PHY if (pMplCtx->linkCfg.mode == MPL_LINK_MODE_AUTO) { // Apply fix for ATAN switch link-up issue atanPatchUp(pMplCtx); } #endif //MPL_EXTERNAL_PHY // Cancel any PHY link timer OaiCancelTimer(pMplCtx->phyTimer); EXIT(MplPhyGetLinkStatus); return MPL_LINK_STATUS_DOWN; } //***************************************************************************** // MplPhyGetLinkSpeed // Returns current link speed. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_SPEED_TENMBPS // The current link speed is 10Mbps // MPL_LINK_SPEED_HUNDREDMBPS // The current link speed is 100Mbps // //***************************************************************************** MPL_LINK_SPEED MplPhyGetLinkSpeed( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplPhyGetLinkSpeed); #ifndef MPL_EXTERNAL_PHY { // Read the PhySts register to get the current link speed regVal = MPL_READ32(pMplCtx, PHYSTS); // Check the link state if (regVal & SPEED_10_STS) { PRINT(("Phy Link SPEED 10Mbps\n")); EXIT(MplPhyGetLinkSpeed); return MPL_LINK_SPEED_TENMBPS; } else { PRINT(("Phy Link SPEED 100Mbps\n")); EXIT(MplPhyGetLinkSpeed); return MPL_LINK_SPEED_HUNDREDMBPS; } } #else // Use internal PHY registers to return current link SPEED // EXTERNAL_PHY_HOOK Modify this to suit your specific device needs { pMplCtx = pMplCtx; regVal = regVal; //To supress warnings return DEFINE_CURRENT_SPEED; //One of MPL_LINK_SPEED_XXX } #endif // MPL_EXTERNAL_PHY } //***************************************************************************** // MplPhyGetLinkDuplex // Returns current link duplex mode. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_DUPLEX_HALF // The current duplex mode is half // MPL_LINK_DUPLEX_FULL // The current duplex mode is full // //***************************************************************************** MPL_LINK_DUPLEX MplPhyGetLinkDuplex( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplPhyGetLinkDuplex); #ifndef MPL_EXTERNAL_PHY { // Read the PhySts register to get the current link mode regVal = MPL_READ32(pMplCtx, PHYSTS); // Check the link state if (regVal & DUPLEX_FULL_STS) { PRINT(("Phy Link Duplex FULL \n")); EXIT(MplPhyGetLinkDuplex); return MPL_LINK_DUPLEX_FULL; } else { PRINT(("Phy Link Duplex HALF \n")); EXIT(MplPhyGetLinkDuplex); return MPL_LINK_DUPLEX_HALF; } } #else // Use internal PHY regs to return current DUPLEX mode // EXTERNAL_PHY_HOOK Modify this to suit your specific device needs { pMplCtx = pMplCtx; regVal = regVal; //To supress warnings return DEFINE_CURRENT_DUPLEX; //One of MPL_LINK_DUPLEX_XXX } #endif // MPL_EXTERNAL_PHY } //***************************************************************************** // MplPhyAutoNegDone // Returns if Auto Neg process is completed. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The link was setup following a Auto-Neg process // NS_FALSE // The link was setup in forced mode // //***************************************************************************** NS_BOOLEAN MplPhyAutoNegDone( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplPhyAutoNegDone); // Read the PhySts register to get the current mode regVal = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_BMSR); // Check the link state if (regVal & AUTONEG_COMP) { PRINT(("Phy Link Auto DONE \n")); EXIT(MplPhyAutoNegDone); return NS_TRUE; } else { PRINT(("Phy Link Auto NOT DONE \n")); EXIT(MplPhyAutoNegDone); return NS_FALSE; } } //***************************************************************************** // MplPhyLinkSetupComplete // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The link was sucessfully setup // NS_FALSE // The link is not up (Assert - should not happen) // // //***************************************************************************** NS_BOOLEAN MplPhyLinkSetupComplete( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 anar, anlPar; ENTER(MplPhyLinkSetupComplete); // Make sure we have a valid link before proceeding if (MplPhyGetLinkStatus(pMplHandle) != MPL_LINK_STATUS_UP) { // FM: Assert - We should never come here!! EXIT(MplPhyLinkSetupComplete); return NS_FALSE; } // Get the Duplex Status if (MplPhyGetLinkDuplex(pMplCtx) == MPL_LINK_DUPLEX_FULL) { // We are in Full duplex mode pMplCtx->linkCfg.duplex = MPL_LINK_DUPLEX_FULL; // Set Pause - Only in AutoNeg'ed Full Duplex mode if (pMplCtx->linkCfg.mode == MPL_LINK_MODE_AUTO) { // Read our adv values and that of our partner anar = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_ANAR); anlPar = MplPhyMdioRead(pMplCtx, pMplCtx->phyDeviceAddr, MII_ANLPAR); /* * Look at the PAUSE and ASM_DIR bits between us and link partner * to determine the pause setting. * The following table, taken out of the IEEE 802.3ab/D6.0 spec * describes final PAUSE resolution * NOTE: DC = Don't Care * * LOCAL DEVICE | LINK PARTNER * PAUSE | ASM_DIR | PAUSE | ASM_DIR | PAUSE Resolution *-------|---------|-------|---------|-------------------- * 0 | 0 | DC | DC | MPL_LINK_PAUSE_NONE * 0 | 1 | 0 | DC | MPL_LINK_PAUSE_NONE * 0 | 1 | 1 | 0 | MPL_LINK_PAUSE_NONE * 0 | 1 | 1 | 1 | MPL_LINK_PAUSE_TRANSMIT * 1 | 0 | 0 | DC | MPL_LINK_PAUSE_NONE * 1 | DC | 1 | DC | MPL_LINK_PAUSE_SYMMETRICAL * 1 | 1 | 0 | 0 | MPL_LINK_PAUSE_NONE * 1 | 1 | 0 | 1 | MPL_LINK_PAUSE_RECEIVE * */ // Test for SYMMETRICAL pause mode if ((anar & ADV_PAUSE) && (anlPar & ADV_PAUSE)) { if (pMplCtx->linkCfg.pauseType == MPL_LINK_PAUSE_SYMMETRICAL) { pMplCtx->pauseType = MPL_LINK_PAUSE_SYMMETRICAL; } else { // Since we had earlier advertised Sym pause for rx-only mode too pMplCtx->pauseType = MPL_LINK_PAUSE_RECEIVE; } } else if (!(anar & ADV_PAUSE) && (anar & ADV_ASM_DIR) && (anlPar & ADV_PAUSE) && (anlPar & ADV_ASM_DIR)) { // TRANSMIT only pause mode pMplCtx->pauseType = MPL_LINK_PAUSE_TRANSMIT; } else if ((anar & ADV_PAUSE) && (anar & ADV_ASM_DIR) && !(anlPar & ADV_PAUSE) && (anlPar & ADV_ASM_DIR)) { // RECEIVE only pause mode pMplCtx->pauseType = MPL_LINK_PAUSE_RECEIVE; } // At this point the IEEE spec says no pause generation // However unless the NSM has specifically asked for // No-Pause or only Tx-Pause, we can enable Rx-Pause safely // since we are only receiveing pause requests and // not generating our own pause requests else if ((pMplCtx->linkCfg.pauseType == MPL_LINK_PAUSE_TRANSMIT) || (pMplCtx->linkCfg.pauseType == MPL_LINK_PAUSE_NONE)) { pMplCtx->pauseType = MPL_LINK_PAUSE_NONE; } else { pMplCtx->pauseType = MPL_LINK_PAUSE_RECEIVE; } } } else { // We are in half duplex mode pMplCtx->linkCfg.duplex = MPL_LINK_DUPLEX_HALF; // Disable Pause pMplCtx->pauseType = MPL_LINK_PAUSE_NONE; } // Get the Speed Status if (MplPhyGetLinkSpeed(pMplCtx) == MPL_LINK_SPEED_HUNDREDMBPS) { // We are in 100Mbps pMplCtx->linkCfg.speed = MPL_LINK_SPEED_HUNDREDMBPS; } else { // We are in 10Mbps pMplCtx->linkCfg.speed = MPL_LINK_SPEED_TENMBPS; } // Postlink Patch Works - Only for Internal PHYs #ifndef MPL_EXTERNAL_PHY { if (pMplCtx->linkCfg.mode == MPL_LINK_MODE_AUTO) { // Since we are linked up remove ATAN patch and go to // full attenuation level atanPatchDown(pMplCtx); } // Start timer to watch coeff 100msec from now - Short Cable patch if ((pMplCtx->linkCfg.speed == MPL_LINK_SPEED_HUNDREDMBPS) && (((pMplCtx->srr & 0xFF00) == 0x0300) || ((pMplCtx->srr & 0xFF00) == 0x0400) || (pMplCtx->srr == 0x0504))) { OaiStartTimer(pMplCtx->phyTimer, 100); } } #endif // MPL_EXTERNAL_PHY EXIT(MplPhyLinkSetupComplete); return NS_TRUE; } //***************************************************************************** // MplPhyRequiresPatch // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The PHY requires patches to be applied // NS_FALSE // No Patch work required // //***************************************************************************** NS_BOOLEAN MplPhyRequiresPatch( IN NS_VOID *pMplHandle ) { NS_BOOLEAN retVal = NS_TRUE; ENTER(MplPhyRequiresPatch); #ifndef MPL_EXTERNAL_PHY { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; switch (pMplCtx->phySiliconRev) { case MP_PHY_REV : retVal = NS_TRUE; break; case ASPEN_PHY_REV : retVal = NS_FALSE; break; //FM: TBD } } #endif // MPL_EXTERNAL_PHY EXIT(MplPhyRequiresPatch); return retVal; } //***************************************************************************** // MplPhyGetDeviceAddr // Return the Phy device address // // Parameters // pMplHandle // MPL device handle // // Return Value // Phy device addr // //***************************************************************************** NS_UINT MplPhyGetDeviceAddr ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplPhyGetDeviceAddr); EXIT(MplPhyGetDeviceAddr); return pMplCtx->phyDeviceAddr; } //***************************************************************************** // MplPhyMdioRead // Read Phy register // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to read (in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // // Return Value // Reg data // //***************************************************************************** NS_UINT32 MplPhyMdioRead( IN NS_VOID *pMplHandle, IN NS_UINT phyDevAddr, IN NS_UINT regIndex ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regData = 0x0; // If we are using the internal PHY then go thru the simple register // API to access the PHY registers, if not do bit-banging on MDIO #ifndef MPL_EXTERNAL_PHY { NS_UINT32 volatile *regAddr; // Using internal PHY regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase + PHY_MII_REG_BASE + (regIndex << 2)); regData = MPL_LTOH32(OaiIoRead32(pMplCtx->pClientHandle, regAddr)); } #else { // Using external PHY - Go thru MDIO regData = mdioReadReg(pMplCtx, phyDevAddr, regIndex); } #endif // MPL_EXTERNAL_PHY return regData; } //***************************************************************************** // MplPhyMdioWrite // Write Phy register // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to write(in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // regData // Data to write // // Return Value // None // //***************************************************************************** NS_VOID MplPhyMdioWrite( IN NS_VOID *pMplHandle, IN NS_UINT phyDevAddr, IN NS_UINT regIndex, IN NS_UINT32 regData ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // If we are using the internal PHY then go thru the simple register // API to access the PHY registers, if not do bit-banging on MDIO #ifndef MPL_EXTERNAL_PHY { NS_UINT32 volatile *regAddr; // Using internal PHY regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase + PHY_MII_REG_BASE + (regIndex << 2)); OaiIoWrite32(pMplCtx->pClientHandle, regAddr, MPL_HTOL32(regData)); } #else { // Use MDIO for external PHY mdioWriteReg(pMplCtx, phyDevAddr, regIndex, (NS_UINT16)regData); } #endif // MPL_EXTERNAL_PHY return; } //***************************************************************************** // phyTimerHandler // Applies short cable patch at the end of 100msec // // Parameters // pMplCtx // MPL device handle // // Return Value // None // //***************************************************************************** NS_VOID phyTimerHandler( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplPhyTimer); MPL_WRITE32(pMplCtx, PAGE, 0x0001); regVal = MPL_READ32(pMplCtx, DSPCFG); regVal &= 0x0FFF; MPL_WRITE32(pMplCtx, DSPCFG, regVal | 0x1000); OaiSleep(100); //100usec regVal = MPL_READ32(pMplCtx, TDATA); regVal &= 0xFF; if (regVal < 0x80 || regVal > 0xd7 ) { MPL_WRITE32(pMplCtx, TDATA, 0x00E8); regVal = MPL_READ32(pMplCtx, DSPCFG); MPL_WRITE32(pMplCtx, DSPCFG, regVal | 0x0020); } MPL_WRITE32(pMplCtx, PAGE, 0x0); EXIT(MplPhyTimer); return; } #ifndef MPL_EXTERNAL_PHY //***************************************************************************** // phyAdjust // Apply optimization patch // // Parameters // pMplCtx // MPL device context // // Return Value // None // //***************************************************************************** static NS_VOID phyAdjust( IN MPL_CONTEXT *pMplCtx ) { NS_UINT32 regVal; if (pMplCtx->srr == 0x0200) { // MacPhy-1 MPL_WRITE32(pMplCtx, PAGE, 0x0001); MPL_WRITE32(pMplCtx, PMDCSR, 0x0802); MPL_WRITE32(pMplCtx, FCOCTL, 0x0010); MPL_WRITE32(pMplCtx, SDCFG, 0x0333); MPL_WRITE32(pMplCtx, PGMCGM, 0x0860); MPL_WRITE32(pMplCtx, TMR, 0x2100); MPL_WRITE32(pMplCtx, CDCT12, 0x4f48); MPL_WRITE32(pMplCtx, PAGE, 0x0); regVal = MPL_READ32(pMplCtx, TENBT); MPL_WRITE32(pMplCtx, TENBT, regVal | 0x04); } else if ((pMplCtx->srr & 0xFF00) == 0x0300) { // MacPhy-1 MPL_WRITE32(pMplCtx, PAGE, 0x0001); MPL_WRITE32(pMplCtx, PMDCSR, 0x189c); MPL_WRITE32(pMplCtx, TDATA, 0x0000); MPL_WRITE32(pMplCtx, DSPCFG, 0x5040); MPL_WRITE32(pMplCtx, SDCFG, 0x008c); MPL_WRITE32(pMplCtx, PAGE, 0x0); } else if (((pMplCtx->srr & 0xFF00) == 0x0400) || ((pMplCtx->srr & 0xFF00) == 0x0500)) { // MacPhy-2 MPL_WRITE32(pMplCtx, PAGE, 0x0001); MPL_WRITE32(pMplCtx, PMDCSR , 0x189C ); MPL_WRITE32(pMplCtx, PAGE, 0x0); } return; } //***************************************************************************** // atanPatchUp // Apply ATAN switch link-up patch // // Parameters // pMplCtx // MPL device context // // Return Value // None // //***************************************************************************** static NS_VOID atanPatchUp( IN MPL_CONTEXT *pMplCtx ) { MPL_WRITE32(pMplCtx, PAGE, 0x0001); MPL_WRITE32(pMplCtx, DSPTST, 0x80b7); MPL_WRITE32(pMplCtx, PAGE, 0x0); return; } //***************************************************************************** // atanPatchDown // Remove ATAN switch link-up patch // // Parameters // pMplCtx // MPL device context // // Return Value // None // //***************************************************************************** static NS_VOID atanPatchDown( IN MPL_CONTEXT *pMplCtx ) { MPL_WRITE32(pMplCtx, PAGE, 0x0001); MPL_WRITE32(pMplCtx, DSPTST, 0x00b7); MPL_WRITE32(pMplCtx, PAGE, 0x0); return; } #endif //MPL_EXTERNAL_PHY //***************************************************************************** // mdioIdle // MDIO clk delay // // Parameters // pMplCtx // MPL device context // // Return Value // None // //***************************************************************************** static NS_VOID mdioIdle( IN MPL_CONTEXT *pMplCtx ) { OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR); OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR | MDCLK); return; } //***************************************************************************** // mdioSync // MDIO bus sync // // Parameters // pMplCtx // MPL device context // // Return Value // None // //***************************************************************************** static NS_VOID mdioSync( IN MPL_CONTEXT *pMplCtx ) { NS_UINT32 i; // Write 32 logic ones for (i = 0x0; i < 32; i++) mdioIdle(pMplCtx); OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR); return; } #ifdef MPL_EXTERNAL_PHY //***************************************************************************** // mdioReadReg // Read a Phy register via MDIO // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to read (in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // // Return Value // Reg data // //***************************************************************************** NS_UINT16 mdioReadReg( IN MPL_CONTEXT *pMplCtx, IN NS_UINT phyDevAddr, IN NS_UINT regIndex ) { NS_UINT32 mdioCmd; NS_UINT32 oData = 0x0, iData, i; // Create the read cmd seq mdioCmd = MII_READ | (phyDevAddr << MII_ADDR_OFF) | (regIndex << MII_REG_OFF); // Sync up the bus mdioSync(pMplCtx); // Send Start + Read Cmd + Phy Addr + Reg Offset for (i = 0x0; i < 15 ; i++) { if (mdioCmd & 0x80000000) { // Write a 1-bit OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDDIR));// Clk Low,Data High OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK | MDDIR));//Clk Hi,Data High } else { // Write a 0-bit OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDDIR);// Clk Low, Data Low OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDCLK | MDDIR));// Clk Hi, Data Low } // Next bit mdioCmd <<= 1; } // Read-in data for (i = 0x0; i < 16; i++) { OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO); // Clock Low, Data High OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK)); // Clock High, Data High iData = MPL_READ32(pMplCtx, MEAR); oData <<= 1; if (iData & MDIO) oData |= 1; } // Write an idle bit mdioIdle(pMplCtx); OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR); return (NS_UINT16)oData; } //***************************************************************************** // mdioWriteReg // Write Phy register // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to write(in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // regData // Data to write // // Return Value // None // //***************************************************************************** NS_VOID mdioWriteReg( IN MPL_CONTEXT *pMplCtx, IN NS_UINT phyDevAddr, IN NS_UINT regIndex, IN NS_UINT16 regData ) { NS_UINT32 mdioCmd, i; // Create the read cmd seq mdioCmd = MII_WRITE | (phyDevAddr << MII_ADDR_OFF) | (regIndex << MII_REG_OFF) | regData; // Sync up the bus mdioSync(pMplCtx); // Send Start + Write Cmd + Phy Addr + Reg Offset + Reg Data for (i = 0x0; i < 32; i++) { if (mdioCmd & 0x80000000) { // Write a 1-bit OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDDIR));// Clk Low,Data High OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDIO | MDCLK | MDDIR));//Clk Hi,Data High } else { // Write a 0-bit OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDDIR);// Clk Low, Data Low OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, (MDCLK | MDDIR));// Clk Hi, Data Low } // Next bit mdioCmd <<= 1; } // Write an idle bit mdioIdle(pMplCtx); OaiSleep(1); MPL_WRITE32(pMplCtx, MEAR, MDIO | MDDIR); return; } #endif // MPL_EXTERNAL_PHY DP8381X-Linux-Ver-1.6/Mpl/mplintr.c0000444000000000000000000002441310430225754015251 0ustar rootroot //****************************************************************************** // // MPLINTR.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Interrupt Processing. // // This file contains the API implementations for // o MPL interrupt configuration // o Enabling and Disabling interrupts // o Processing interrupts // //****************************************************************************** #include //***************************************************************************** // MplInterruptCfg // Configure the interrupt hold-off delay (for interrupt coalescing). // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // delayMSec // Interrupt hold off delay in microseconds // transmitHold // Interrupts hold off based on number of Tx pkts sent // receiveHold // Interrupts hold off based on number of Rx pkts sent // // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully configured // //***************************************************************************** MPL_STATUS MplInterruptCfg ( IN NS_VOID *pMplHandle, IN NS_UINT delayMSec, IN NS_UINT transmitHold, IN NS_UINT receiveHold ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 ihrVal = 0x0; MPL_CENTER(DZONE_MPL_INTR, MplInterruptCfg); // Force values to max supported if (delayMSec > pMplCtx->caps.intrCaps.maxTimerHold) { delayMSec = pMplCtx->caps.intrCaps.maxTimerHold; } if (transmitHold > pMplCtx->caps.intrCaps.maxTransmitHold) { transmitHold = pMplCtx->caps.intrCaps.maxTransmitHold; } if (receiveHold > pMplCtx->caps.intrCaps.maxReceiveHold) { receiveHold = pMplCtx->caps.intrCaps.maxReceiveHold; } // Decide if we need to use the lower resolution clock if (delayMSec >= 100) { // Compute clocks delayMSec = delayMSec / 100; } else { ihrVal |= INTHLDTMR_4US; // Compute clocks delayMSec = delayMSec / 4; } // Write on the device MPL_WRITE32(pMplCtx, IHR, ihrVal | delayMSec | (transmitHold << INTHLDCNCL_TXPKTS_SHIFT) | (receiveHold << INTHLDCNCL_RXPKTS_SHIFT)); MPL_CEXIT(DZONE_MPL_INTR, MplInterruptCfg); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplInterruptEnable // Enable the interrupt line on the network device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully enabled // //***************************************************************************** MPL_STATUS MplInterruptEnable ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Enable Interrupts MPL_WRITE32(pMplCtx, IER, INT_EN); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplInterruptDisable // Disable the interrupt line on the network device. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully disabled // //***************************************************************************** MPL_STATUS MplInterruptDisable ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Disable Interrupts MPL_WRITE32(pMplCtx, IER, 0x0); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplInterruptCheck // Checks for and clears pending interrupt conditions on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // pIrqsPresent // A caller supplied variable in which the current interrupting // conditions are noted. // // Return Value // NS_STATUS_SUCCESS // The current interrupting conditions were successfully read from the // device and pending events do exist. // NS_STATUS_FAILURE // Interrupts are currently disabled, so no interrupt conditions exist. // or the mask bits and status bits don't match // //***************************************************************************** MPL_STATUS MplInterruptCheck ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Make sure interrupts are currently enabled i.e. this is not a // spurious interrupt if (MPL_READ32(pMplCtx, IER) & INT_EN) { //Disable Interrupts FM: Make this version specific MPL_WRITE32(pMplCtx, IER, 0x0); // Read ISR pMplCtx->isrReg = MPL_READ32(pMplCtx, ISR); // Rev A3 (AspenPhy) don't seem to clear int on mere read of ISR MPL_READ32(pMplCtx, MISR); // Make sure this interrupt reason is not masked if (pMplCtx->isrReg & pMplCtx->imrReg) { return NS_STATUS_SUCCESS; } else { // Interrupts will be disabled after reading the ISR // so reenable it MPL_WRITE32(pMplCtx, IER, INT_EN); } } return NS_STATUS_FAILURE; } //***************************************************************************** // MplInterruptCheckTransmit // Checks for the presence of transmit engine related interrupt events. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // Pending transmit related events exist on the device // NS_STATUS_FAILURE // No transmit related events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckTransmit ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Check if any Tx events are triggered if (pMplCtx->isrReg & (TXOK | TXDESC | TXERR | TXIDLE | TXUNDERRUN)) { return NS_STATUS_SUCCESS; } else { return NS_STATUS_FAILURE; } } //***************************************************************************** // MplInterruptCheckReceive // Checks for the presence of receive engine related interrupt events. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // Pending receive related events exist on the device // NS_STATUS_FAILURE // No receive related events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckReceive ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Check if any Rx events are triggered if (pMplCtx->isrReg & (RXOK | RXDESC | RXERR | RXEARLY | RXOVERUN)) { return NS_STATUS_SUCCESS; } else { return NS_STATUS_FAILURE; } } //***************************************************************************** // MplInterruptCheckInternal // Checks for the presence of MAC/PHY internal (non data transfer related) // interrupt events. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // Return Value // NS_STATUS_SUCCESS // Pending internal events exist on the device // NS_STATUS_FAILURE // No internal events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckInternal ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Check if any Tx events are triggered if (pMplCtx->isrReg & (MIBSTATS | SW_INT | WOL_EVENT | PHYSTSCHANGE | RXIDLE| RXSTSFIFO_OVRN | RXRST_COMPLETE | TXRST_COMPLETE)) { return NS_STATUS_SUCCESS; } else { return NS_STATUS_FAILURE; } } //***************************************************************************** // MplInterruptDoneInternal // Processes device’s internal (non data-type) interrupts. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum internal events (e.g. link change) that MPL should // process before returning back to the caller. // Return Value // NS_STATUS_SUCCESS // The internal event was successfully handled. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplInterruptDoneInternal ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; if (pMplCtx->isrReg & RXIDLE) { // Rx-Idle - For Perf tuning purposes } if (pMplCtx->isrReg & MIBSTATS) { // Go read MIB statistics } if (pMplCtx->isrReg & WOL_EVENT) { // Power Management Event, i.e. Wake-On-LAN } if (pMplCtx->isrReg & PHYSTSCHANGE) { // PHY status change: link is up or down MplLinkInterrupt(pMplCtx); } if (pMplCtx->isrReg & SW_INT) { // Software Interrupt, set when SWI bit is set in CR } if (pMplCtx->isrReg & HIORDER_INT) { if (pMplCtx->isrReg & RXSTSFIFO_OVRN) { // Rx FIFO overrun (RXOVR) } } if (pMplCtx->isrReg & RXRST_COMPLETE) { // recv reset complete } if (pMplCtx->isrReg & TXRST_COMPLETE) { // xmit reset complete } return NS_STATUS_SUCCESS; } DP8381X-Linux-Ver-1.6/Mpl/mplreceive.c0000444000000000000000000006474610430225754015734 0ustar rootroot //****************************************************************************** // // MPLRECEIVE.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Receive engine. // // This file contains the API implementations for // o MPL receive engine configuration // o MPL packet reception and completion handlers // o Receive engine filter configuration // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_RECV, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_RECV, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_RECV, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_RECV, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_RECV, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_RECV, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_RECV, fmt) // Locals static NS_VOID setRxCfg(MPL_CONTEXT *pMplCtx, MPL_RECEIVE_CFG *pCfgReceive); static MPL_STATUS allocRxdRing(MPL_CONTEXT *pMplCtx); static NS_VOID setupRxdRing(MPL_CONTEXT *pMplCtx); //***************************************************************************** // MplReceiveCfg // Configures the receive engine on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pCfgReceive // Pointer to a caller allocated MPL_RECEIVE_CFG structure with // configuration values for the receive engine // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_INVALID_PARM // An invalid parameter value was detected // //***************************************************************************** MPL_STATUS MplReceiveCfg ( IN NS_VOID *pMplHandle, IN MPL_RECEIVE_CFG *pCfgReceive ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplReceiveCfg); // FM: Assert for pCfgReceive == NULL // Configure FIFO and DMA if client desires if (pCfgReceive->cfgFlags & MPL_RECEIVE_CFG_FIFO) { // Validate the FIFO thresholds and DMA burst size if ((pCfgReceive->drainThreshold < pMplCtx->caps.rxCaps.minDrain) || (pCfgReceive->maxDmaBurst > pMplCtx->caps.rxCaps.maxDma)) { EXIT(MplReceiveCfg); return NS_STATUS_INVALID_PARM; } // Notify the hardware about the FIFO thresholds and DMA burst setRxCfg(pMplCtx, pCfgReceive); } // Configure Rx queues if client desires if (pCfgReceive->cfgFlags & MPL_RECEIVE_CFG_QUEUES) { // Validate the priority queue count if (pCfgReceive->priorityQueueCnt > pMplCtx->caps.rxCaps.priorityQCnt) { EXIT(MplReceiveCfg); return NS_STATUS_INVALID_PARM; } // If this is a runtime reconfiguration request, then free the old ring if (pMplCtx->rxDescCnt) { freeRxdRing(pMplCtx); } // Get the Rxd count - Only one Rx queue pMplCtx->rxQueue.descCnt = pCfgReceive->descCnt[0x0]; pMplCtx->rxDescCnt = pCfgReceive->descCnt[0x0]; // Note max receive done indications to be passed to NSM in one pass pMplCtx->maxRxDones = pCfgReceive->maxIndications; // Allocate Rxd ring if (allocRxdRing(pMplCtx) != NS_STATUS_SUCCESS) { EXIT(MplReceiveCfg); return NS_STATUS_RESOURCES; } // Setup Rxd ring setupRxdRing(pMplCtx); // Notify the device about the head node on the ring MPL_WRITE32(pMplCtx, RXDP, pMplCtx->rxQueue.ringPA); } EXIT(MplReceiveCfg); return NS_STATUS_SUCCESS; // All done } //***************************************************************************** // MplReceiveSetFilter // MplReceiveSetFilter enables receive filters on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // filterFlag // Bit-map of receiver filter types that need to be enabled on the // device // Note: This function overwrites all previous filter settings and // sets the device's behavior to that of the filterFlag passed to it. // // Return Value // NS_STATUS_SUCCESS // The filter configurations were successfully applied // NS_STATUS_NOT_SUPPORTED // The device did not support one or more filters // //***************************************************************************** MPL_STATUS MplReceiveSetFilter ( IN NS_VOID *pMplHandle, IN NS_UINT filterFlag ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 fltrRegSetting = 0x0, regVal; ENTER(MplReceiveSetFilter); // Check for Promiscuous Mode if (filterFlag & MPL_RECEIVE_FILTER_PROMISCUOUS_MODE) { fltrRegSetting |= (ACCEPT_ALLBCAST | ACCEPT_ALLMCAST | ACCEPT_ALLUNICAST); } else { // Various individual filters if (filterFlag & MPL_RECEIVE_FILTER_ACCEPTALL_BROADCAST) { fltrRegSetting |= ACCEPT_ALLBCAST; } if (filterFlag & MPL_RECEIVE_FILTER_ACCEPTALL_MCAST) { fltrRegSetting |= ACCEPT_ALLMCAST; } if (filterFlag & MPL_RECEIVE_FILTER_ACCEPTALL_UNICAST) { fltrRegSetting |= ACCEPT_ALLUNICAST; } if (filterFlag & MPL_RECEIVE_FILTER_ACCEPTALL_ARP) { fltrRegSetting |= ACCEPT_ALLARP; } if (filterFlag & MPL_RECEIVE_FILTER_DIRECTED_UNICAST) { fltrRegSetting |= ACCEPT_PERFECTMATCH; } if (filterFlag & MPL_RECEIVE_FILTER_DIRECTED_MCAST) { fltrRegSetting |= MCASTHASH_EN; } } // Disable Rx Filter - Before changing it regVal = MPL_READ32(pMplCtx, RFCR); MPL_WRITE32(pMplCtx, RFCR, regVal & ~RXFLTR_EN); regVal &= (~(ACCEPT_ALLBCAST | ACCEPT_ALLMCAST | ACCEPT_ALLUNICAST | ACCEPT_ALLARP | ACCEPT_PERFECTMATCH)); regVal |= (fltrRegSetting | RXFLTR_EN); MPL_WRITE32(pMplCtx, RFCR, regVal); // In Promiscuous or Accept Err mode - Enable acceptance of runts, CRC err, // FAE, in-range-length errors // Acceptance of long packets depends on the MTU size and NSM's ablility to // provide larger buffers etc. - So this function does not deal with it. // NSM can call MplCfgMTU to accept Long packets regVal = MPL_READ32(pMplCtx, RXCFG); if ((filterFlag & MPL_RECEIVE_FILTER_ERROREDPKTS) || (filterFlag & MPL_RECEIVE_FILTER_PROMISCUOUS_MODE)) { regVal |= (ACCEPT_CRCALIGNERR | ACCEPT_RUNTS | ACCEPT_INRNG_LENERR); } else { // Clear all Err acceptance regVal &= (~(ACCEPT_CRCALIGNERR | ACCEPT_RUNTS | ACCEPT_INRNG_LENERR)); } MPL_WRITE32(pMplCtx, RXCFG, regVal); EXIT(MplReceiveSetFilter); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplReceive // Handles the packet reception event and moves the received packet from // the device to the host. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum receive engine related events (e.g. receive complete) // that MPL should process before returning back to the caller. // pBufFragConsumed // A caller supplied pointer variable in which this function returns the // number of buffer fragments that were consumed while processing this // receive pass. // // Return Value // NS_STATUS_SUCCESS // The receive events were successfully processed. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplReceive ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents, OUT NS_UINT *pBufFragConsumed ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT entry, pendRxds, evtCnt = 0x0, pktCnt = 0x0; NS_UINT32 cmdSts = 0x0; MPL_PKT_FRAG *currFrag; MPL_DESC *currRxd; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplReceive); // Get the starting Rxd and number of Rxds to process entry = pMplCtx->rxQueue.curr % pMplCtx->rxQueue.descCnt; currRxd = &pMplCtx->rxQueue.pRing[entry]; pendRxds = pMplCtx->rxQueue.dirty + pMplCtx->rxQueue.descCnt - pMplCtx->rxQueue.curr; *pBufFragConsumed = 0x0; // Process the Rxd ring - We break once all pending Rxds are processed or // the maxEvents are processed while ((currRxd->cmdSts & CS_OWN_ES) && (pendRxds--)) { // The software now owns this Rxd cmdSts = MPL_LTOH32(currRxd->cmdSts); // Check if we reached limit if ((maxEvents != 0x0) && (evtCnt >= maxEvents)) { status = NS_STATUS_ABORTED; break; } // Get the frag ptr currFrag = (MPL_PKT_FRAG *)currRxd->mplPriv; // Copy the physical addr of Rxd - for diag mode operations only currFrag->pMplPrivate = (NS_VOID *)(pMplCtx->rxQueue.ringPA + (entry * sizeof(MPL_DESC))); // Setup reference ptr to handle situations where a packet spans // into multiple Rxds, and we need to link them all up if (pMplCtx->rxQueue.pFragHead == NULL) { pMplCtx->rxQueue.pFragHead = currFrag; // Head frag } else { pMplCtx->rxQueue.pFragTail->pNextFrag = currFrag; // Tail Frag } pMplCtx->rxQueue.fragCnt++; // Accumulate the frag sizes currFrag->fragSize = cmdSts & CS_LEN_MASK; pMplCtx->rxQueue.packetSize += currFrag->fragSize; // Check if this packet has more Rxds coming if (cmdSts & CS_MORE) { PRINT(("Multi Rxd cmdSts = %x \n", (NS_UINT)cmdSts)); // Add to the tail of pending list pMplCtx->rxQueue.pFragTail = currFrag; } else { // We have all Rxd frags for this pkt - Prepare a indication *pBufFragConsumed += pMplCtx->rxQueue.fragCnt; currFrag->pNextFrag = NULL; // End list pMplCtx->rxDone[pktCnt].fragCount = pMplCtx->rxQueue.fragCnt; pMplCtx->rxDone[pktCnt].pFragHead = pMplCtx->rxQueue.pFragHead; pMplCtx->rxDone[pktCnt].rxOOB.cmdSts = cmdSts; pMplCtx->rxDone[pktCnt].packetSize = pMplCtx->rxQueue.packetSize; #ifdef MPL_TASK_VLAN // If VLAN is enabled then get the extended status pMplCtx->rxDone[pktCnt].rxOOB.extSts = MPL_LTOH32(currRxd->extCtlSts); #endif if (cmdSts & CS_OK) { pMplCtx->rxDone[pktCnt].packetStatus = NS_STATUS_SUCCESS; } else { // PacketQry APIs return more details on the error pMplCtx->rxDone[pktCnt].packetStatus = NS_STATUS_FAILURE; } // Increment pkt count pktCnt++; // Check if it is time to report to NSM if (pktCnt >= pMplCtx->maxRxDones) { NsmReceive(pMplCtx->pClientHandle, pktCnt, pMplCtx->rxDone); pktCnt = 0x0; } // Clean up partial tracker pMplCtx->rxQueue.pFragHead = pMplCtx->rxQueue.pFragTail = NULL; pMplCtx->rxQueue.fragCnt = pMplCtx->rxQueue.packetSize = 0x0 ; // FM : Define event.. Is it per pkt or per processed Rxd? // Below it is defined as per packet evtCnt++; } // Get the next Rxd and Read its cmdSts entry = (++pMplCtx->rxQueue.curr) % pMplCtx->rxQueue.descCnt; currRxd = &pMplCtx->rxQueue.pRing[entry]; } // Report remaining completed packets to NSM if (pktCnt > 0x0) { NsmReceive(pMplCtx->pClientHandle, pktCnt, pMplCtx->rxDone); } EXIT(MplReceive); return status; } //***************************************************************************** // MplReceiveReplenish // Restock the MPL receive engine with fresh buffers for packet reception. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // bufFragCount // Number of buffer fragments being replenished. // pFragList // Pointer to a caller supplied variable of type MPL_PKT_FRAG pointing // to the head node of the buffer fragment list being replenished. // If all the buffer fragments were not consumed by MPL then the // pointer to the first unused fragment is returned back to NSM. // // Return Value // NS_STATUS_SUCCESS // The buffers were successfully replenished. // //***************************************************************************** MPL_STATUS MplReceiveReplenish ( IN NS_VOID *pMplHandle, IN NS_UINT bufFragCount, IN OUT MPL_PKT_FRAG **pFragList ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_PKT_FRAG *currFrag; MPL_DESC *currRxd; NS_UINT entry; ENTER(MplReceiveReplenish); // Loop through the Rxd ring filling it up with new buffers currFrag = *pFragList; for (;bufFragCount && (pMplCtx->rxQueue.curr - pMplCtx->rxQueue.dirty > 0x0); pMplCtx->rxQueue.dirty++, bufFragCount--) { entry = pMplCtx->rxQueue.dirty % pMplCtx->rxQueue.descCnt; currRxd = &pMplCtx->rxQueue.pRing[entry]; // FM: Assert Make sure that this Rxd is empty // Set up the Rxd currRxd->cmdSts = MPL_HTOL32(currFrag->fragSize); currRxd->bufptrPA = MPL_ADDR_HTOL(currFrag->physAddr); currRxd->mplPriv = currFrag; // Note the Frag Ptr // Get the next fragment currFrag = currFrag->pNextFrag; } // If we managed to replenish some buffers then re-enable the Rx engine if ((pMplCtx->rxQueue.curr - pMplCtx->rxQueue.dirty) < pMplCtx->rxQueue.descCnt) { MPL_WRITE32(pMplCtx, CR, RX_EN); } // If we have some fragments left over, then return it back to NSM if (bufFragCount) { *pFragList = currFrag; } EXIT(MplReceiveReplenish); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplQueryPacketLength // Returns the size (in bytes) of the data frame within a MPL_PKT structure // // Parameters // pPacket // Pointer to the MPL_PKT structure who data frame length is being // queried. // // Return Value // The total size of the data frame in bytes (could be 0x0 also). // //***************************************************************************** NS_UINT MplQueryPacketLength ( IN MPL_PKT *pPacket ) { ENTER(MplQueryPacketLength); EXIT(MplQueryPacketLength); // Return the packet size return pPacket->packetSize; } //***************************************************************************** // MplReceiveReset // Resets the receive engine on the device and associated software // resources. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The receive engine was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error - No reset done notification from Hw // //***************************************************************************** MPL_STATUS MplReceiveReset ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT entry, pendRxds; MPL_PKT_FRAG *currFrag; MPL_DESC *currRxd; ENTER(MplReceiveReset); // Make sure we were initialized to begin with if (pMplCtx->rxQueue.pRgnHndl == NULL) { EXIT(MplReceiveReset); return NS_STATUS_SUCCESS; } // Tell the hardware to reset its Rx engine MPL_WRITE32(pMplCtx, CR, RXRESET); // Total 4msec - Not waiting for notification OaiSleep(4 * RESETINTERVAL_MAC); // Get the starting Rxd and number of Rxds to process entry = pMplCtx->rxQueue.curr % pMplCtx->rxQueue.descCnt; currRxd = &pMplCtx->rxQueue.pRing[entry]; pendRxds = pMplCtx->rxQueue.dirty + pMplCtx->rxQueue.descCnt - pMplCtx->rxQueue.curr; // Process the Rxd ring - Collect all data buffers in all pending // Rxds and report them in one big blob while (pendRxds) { // Software OWNs them all currRxd->cmdSts = CS_OWN_ES; // Get the frag ptr currFrag = (MPL_PKT_FRAG *)currRxd->mplPriv; currRxd->mplPriv = NULL; // We link all the buffers together if (pMplCtx->rxQueue.pFragHead == NULL) pMplCtx->rxQueue.pFragHead = currFrag; // Head frag else pMplCtx->rxQueue.pFragTail->pNextFrag = currFrag; // Tail Frag pMplCtx->rxQueue.fragCnt++; // Accumulate the frag sizes pMplCtx->rxQueue.packetSize += (MPL_LTOH32(currRxd->cmdSts) & CS_LEN_MASK); // Add to the tail of pending list pMplCtx->rxQueue.pFragTail = currFrag; // Get the next Rxd and Read its cmdSts entry = (++pMplCtx->rxQueue.curr) % pMplCtx->rxQueue.descCnt; currRxd = &pMplCtx->rxQueue.pRing[entry]; pendRxds--; } // If we managed to salvage any buffer fragments, report it in one blob if (pMplCtx->rxQueue.fragCnt) { // We have all Rxd frags for this abort pkt - Prepare a indication pMplCtx->rxDone[0x0].fragCount = pMplCtx->rxQueue.fragCnt; pMplCtx->rxDone[0x0].pFragHead = pMplCtx->rxQueue.pFragHead; pMplCtx->rxDone[0x0].rxOOB.cmdSts = 0x0; pMplCtx->rxDone[0x0].packetSize = pMplCtx->rxQueue.packetSize; pMplCtx->rxDone[0x0].packetStatus = NS_STATUS_ABORTED; NsmReceive(pMplCtx->pClientHandle, 0x1, pMplCtx->rxDone); } // Clean up partial tracker pMplCtx->rxQueue.pFragHead = pMplCtx->rxQueue.pFragTail = NULL; pMplCtx->rxQueue.fragCnt = pMplCtx->rxQueue.packetSize = 0x0 ; // Reset pointers pMplCtx->rxQueue.dirty = 0x0; pMplCtx->rxQueue.curr = pMplCtx->rxQueue.descCnt; pMplCtx->rxQueue.ringPA = pMplCtx->rxQueue.pRgnHndl->phyAddr; pMplCtx->rxQueue.pRing = (MPL_DESC *)pMplCtx->rxQueue.pRgnHndl->pAddr; // Notify the device about the head node on the ring MPL_WRITE32(pMplCtx, RXDP, pMplCtx->rxQueue.ringPA); EXIT(MplReceiveReset); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplReceiveGetEmptyDesc // Returns the count of the Rxds that are empty i.e. no attached buffers // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pQueue // Queue (1,2...max tx queues) from which the empty count is desired // pRxdCnt // Pointer to a caller allocated fields in which the count of empty // receive descriptors is returned // // Return Value // NS_STATUS_SUCCESS // The count was successfully returned. // NS_STATUS_INVALID_PARM // The priority queue count is invalid // //***************************************************************************** MPL_STATUS MplReceiveGetEmptyDesc ( IN NS_VOID *pMplHandle, IN NS_UINT8 pQueue, OUT NS_UINT *pRxdCnt ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplReceiveGetEmptyDesc); // Get the empty Rxd count *pRxdCnt = pMplCtx->rxQueue.curr - pMplCtx->rxQueue.dirty; EXIT(MplReceiveGetEmptyDesc); return NS_STATUS_SUCCESS; } //+++++ Local Functions //##################### //***************************************************************************** // setRxCfg // Set the FIFO and DMA burst related configurations on the device // // Parameters // pMplCtx // Pointer to MPL Context // pCfgReceive // Pointer to a caller allocated MPL_RECEIVE_CFG structure with // configuration values for the receive engine // // Return Value // None // //***************************************************************************** static NS_VOID setRxCfg( IN MPL_CONTEXT *pMplCtx, IN MPL_RECEIVE_CFG *pCfgReceive ) { NS_UINT32 rxDma, rxCfg, drain; ENTER(setRxCfg); // Get the Rx DMA size rxDma = 0x0; if (pCfgReceive->maxDmaBurst < 8) rxDma = MXDMA4; //Min else if (pCfgReceive->maxDmaBurst < 16) rxDma = MXDMA8; else if (pCfgReceive->maxDmaBurst < 32) rxDma = MXDMA16; else if (pCfgReceive->maxDmaBurst < 64) rxDma = MXDMA32; else if (pCfgReceive->maxDmaBurst < 128) rxDma = MXDMA64; else if (pCfgReceive->maxDmaBurst < 256) rxDma = MXDMA128; else if (pCfgReceive->maxDmaBurst < 512) rxDma = MXDMA256; else if (pCfgReceive->maxDmaBurst < 1024) rxDma = MXDMA512; else if (pCfgReceive->maxDmaBurst < 2048) rxDma = (MXDMA256 | RXDMA4); else rxDma = (MXDMA512 | RXDMA4); //Max // Read the Rxcfg contents rxCfg = MPL_READ32(pMplCtx, RXCFG); // Mask the rx settable values rxCfg &= ~RXSET_MASK; // Generate the RXCFG contents - The drain threshold is specified in // 8 byte units drain = ((pCfgReceive->drainThreshold / 8) & 0x1F) << RXDRAIN_SHIFT; rxCfg |= rxDma | drain; // Write RXCFG MPL_WRITE32(pMplCtx, RXCFG, rxCfg); EXIT(setRxCfg); return; } //***************************************************************************** // allocRxdRing // Alloc all the Rxd rings // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // NS_STATUS_SUCCESS // The rings were correctly setup // NS_STATUS_RESOURCES // Failed to allocate the resources (receive control blocks) // //***************************************************************************** static MPL_STATUS allocRxdRing( IN MPL_CONTEXT *pMplCtx ) { MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(allocRxdRing); // Allocate resources for the Rx done indication packets pMplCtx->rxDone = (MPL_PKT *) OaiMalloc(sizeof(MPL_PKT) * pMplCtx->maxRxDones); if (pMplCtx->rxDone == NULL) { return NS_STATUS_RESOURCES; } OaiZeroMem(pMplCtx->rxDone, sizeof(MPL_PKT) * pMplCtx->maxRxDones); // Allocate memory for the descriptors if (OaiAllocDmaRegion(pMplCtx->pClientHandle, sizeof(MPL_DESC) * pMplCtx->rxQueue.descCnt, 4, // Aligned on 32-bits &pMplCtx->rxQueue.pRgnHndl) == NS_FALSE) { // Allocation failed - Free all prev allocations OaiFree(sizeof(MPL_PKT) * pMplCtx->maxRxDones, pMplCtx->rxDone); status = NS_STATUS_RESOURCES; } else { // Reset mem block OaiZeroMem(pMplCtx->rxQueue.pRgnHndl->pAddr, sizeof(MPL_DESC) * pMplCtx->rxQueue.descCnt); } EXIT(allocRxdRing); return status; } //***************************************************************************** // freeRxdRing // Free the Rxd rings // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** NS_VOID freeRxdRing( IN MPL_CONTEXT *pMplCtx ) { ENTER(freeRxdRing); // Free resources for the Rx done indications if (pMplCtx->rxDone != NULL) { OaiFree(sizeof(MPL_PKT) * pMplCtx->maxRxDones, pMplCtx->rxDone); pMplCtx->rxDone = NULL; } // Free memory for the descriptors if (pMplCtx->rxQueue.pRgnHndl != NULL) { OaiFreeDmaRegion(pMplCtx->pClientHandle, pMplCtx->rxQueue.pRgnHndl); pMplCtx->rxQueue.pRgnHndl = NULL; } EXIT(freeRxdRing); return; } //***************************************************************************** // setupRxdRing // Setup the Rxd Ring // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID setupRxdRing( IN MPL_CONTEXT *pMplCtx ) { NS_UINT j; // Dirty % Ring_Size = First empty Rxd (i.e. no buf attached) // Curr % Ring_Size = First full Rxd (i.e. buf attached) // If (Curr == Dirty) => All Rxds have data bufs attached // If ((Curr - Dirty) == Ring_Size) => None of the Rxds have data bufs // attached ENTER(setupRxdRing); pMplCtx->rxQueue.dirty = 0x0; pMplCtx->rxQueue.curr = pMplCtx->rxQueue.descCnt; pMplCtx->rxQueue.ringPA = pMplCtx->rxQueue.pRgnHndl->phyAddr; pMplCtx->rxQueue.pRing = (MPL_DESC *)pMplCtx->rxQueue.pRgnHndl->pAddr; for (j = 0x0; j < pMplCtx->rxQueue.descCnt; j++) { // Link up and form a ring pMplCtx->rxQueue.pRing[j].linkPA = MPL_ADDR_HTOL(pMplCtx->rxQueue.ringPA + (sizeof(MPL_DESC) * ((j+1) % (pMplCtx->rxQueue.descCnt)))); // We OWN the Rxd (Till it is attached with a buffer) pMplCtx->rxQueue.pRing[j].cmdSts = CS_OWN_ES; pMplCtx->rxQueue.pRing[j].bufptrPA = 0x0; } // Link up the Rx Indication packets also for (j = 0x0; j < (pMplCtx->maxRxDones - 1); j++) { pMplCtx->rxDone[j].pNextPacket = &pMplCtx->rxDone[j+1]; } EXIT(setupRxdRing); return; } DP8381X-Linux-Ver-1.6/Mpl/mplpwr.c0000444000000000000000000003737310430225754015116 0ustar rootroot //****************************************************************************** // // MPLPWR.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Power Management Module. // // This file contains the API implementations for // o Configuring the power state on the device // o WoL related configuration and status reporting // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_PWR, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_PWR, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_PWR, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_PWR, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_PWR, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_PWR, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_PWR, fmt) // Locals static NS_VOID cfgWakeEvts (MPL_CONTEXT *pMplCtx); static NS_VOID cfgWakePatterns(MPL_CONTEXT *pMplCtx); #ifdef LINUX_POWER_DEBUG static NS_VOID printWakeReason(MPL_CONTEXT *pMplCtx); #endif //***************************************************************************** // MplPowerSetState // Set a new power state on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // newState // New power state that needs to be set on the device // pmeEnable // When set to NS_TRUE, MPL enables PME on the device // Some OSs do this automatically, some do not // // Return Value // NS_STATUS_SUCCESS // The new state was successfully set // NS_STATUS_FAILURE // The device could not be set to the new state // //***************************************************************************** MPL_STATUS MplPowerSetState( IN NS_VOID *pMplHandle, IN MPL_POWER_STATE newState, IN NS_BOOLEAN pmeEnable ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplPowerSetState); if ((pMplCtx->pwrState == MPL_POWER_STATE_HIGH) && (newState == MPL_POWER_STATE_LOW)) { // Entering Low Power state from a High Power state // This function expects Int to be disabled and Rx Reset Complete // before calling it // Take a register snap-shot setSoftRegs(pMplHandle, MPL_REGS_CURRENT); // Configure Wake events cfgWakeEvts(pMplCtx); // Configure Wake Patterns if any cfgWakePatterns(pMplCtx); // Put the receiver in "Silent Receive" mode MPL_WRITE32(pMplCtx, CR, RX_DIS); MPL_WRITE32(pMplCtx, RXDP, 0x0); MPL_WRITE32(pMplCtx, CR, RX_EN); // Enable PME if NSM wants us to - This depends on the OS, some do // it themselves, for the rest we do it if (pmeEnable == NS_TRUE) { // Using the PME backdoor if (MPL_READ32(pMplCtx, WCSR) & WAKEON_MASK) { // WOL event is enabled - So set PMEEN MPL_WRITE32(pMplCtx, CCSR, pMplCtx->ccsrReg | PMEEN | PMESTS); } else { // Write whatever was there by default // Note PMEEN bit is loaded from EEPROM MPL_WRITE32(pMplCtx, CCSR, pMplCtx->ccsrReg); } } // Set the new state - LOW pMplCtx->pwrState = MPL_POWER_STATE_LOW; } else if ((pMplCtx->pwrState == MPL_POWER_STATE_LOW) && (newState == MPL_POWER_STATE_HIGH)) { // Entering High Power state from a Low Power state #ifdef LINUX_POWER_DEBUG printWakeReason(pMplCtx); #endif // If PME was enabled then clear status if (pmeEnable == NS_TRUE) { // Clear any wake events configured on the device MPL_WRITE32(pMplCtx, CCSR, PMESTS); } // Not doing MAC/PHY Resets // Set registers with last known snap-shot setHardRegs(pMplCtx); // Set the MAC address - to last know value MplSetMacAddress(pMplCtx, pMplCtx->permMacAddr); #ifdef MPL_TASK_RECEIVE_FILTER // Reload Receive hash filter (Multicast and Unicast) MplTaskFilterReload(pMplCtx); #endif // MPL_TASK_RECEIVE_FILTER // Notify the device about the head node on the Rxd ring // Not enabling RX yet, the replenish API will take care of it MPL_WRITE32(pMplCtx, RXDP, pMplCtx->rxQueue.ringPA); // Notify the device about the head node on the Txd ring MPL_WRITE32(pMplCtx, TXDP, pMplCtx->txQueue[0].ringPA); MPL_WRITE32(pMplCtx, TXDP1, pMplCtx->txQueue[1].ringPA); MPL_WRITE32(pMplCtx, TXDP2, pMplCtx->txQueue[2].ringPA); MPL_WRITE32(pMplCtx, TXDP3, pMplCtx->txQueue[3].ringPA); // Set the new state - HIGH pMplCtx->pwrState = MPL_POWER_STATE_HIGH; } EXIT(MplPowerSetState); return status; } //***************************************************************************** // MplWolCfg // Configure the WOL operation on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // wakeEnable // Flag to enable (set to NS_TRUE) or disable (set to NS_FALSE) Wol // wakeType // When WOL is enabled, represents a bit-map of wake-up events that // needs to be enabled. It is a logical OR of, // MPL_WOL_MAGIC - Enable wake on Magic Pattern. // MPL_WOL_PATTERN - Enable wake on pattern match (Patterns needs // to be separately defined). // MPL_WOL_BROADCAST - Enable wake on any broadcast packet. // MPL_WOL_MULTICAST - Enable wake on multicast packet. // MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to // the device's address. // MPL_WOL_LINK - Enable wake on link status change. // MPL_WOL_ARP - Enable wake on any ARP packet. // // Return Value // NS_STATUS_SUCCESS // The WOL events were successfully enabled or disabled (depending // on wakeEnable). // NS_STATUS_INVALID_PARM // The wake event type is not supported on the device. // //***************************************************************************** MPL_STATUS MplWolCfg( IN NS_VOID *pMplHandle, IN NS_BOOLEAN wakeEnable, IN NS_UINT wakeType ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; ENTER(MplWolCfg); pMplCtx->pwrWakeType = 0x0; if (wakeEnable == NS_TRUE) { // Enable WOL - Make sure wake evt is one that we support if (wakeType & ~(MPL_WOL_MAGIC | MPL_WOL_PATTERNS | MPL_WOL_BROADCAST | MPL_WOL_MULTICAST | MPL_WOL_DIRECTED | MPL_WOL_LINK | MPL_WOL_ARP)) { status = NS_STATUS_INVALID_PARM; } else { pMplCtx->pwrWakeType = wakeType; } } EXIT(MplWolCfg); return status; } //***************************************************************************** // MplWolGetCfg // Retrieve the current WOL configuration on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWakeType // Pointer to caller provider variable in which the bit-map of wake-up // events currently enabled is returned. It is a logical OR of, // MPL_WOL_MAGIC - Enable wake on Magic Pattern. // MPL_WOL_PATTERN - Enable wake on pattern match (Patterns needs to // be separately defined). // MPL_WOL_BROADCAST - Enable wake on any broadcast packet. // MPL_WOL_MULTICAST - Enable wake on multicast packet. // MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to // the device's address. // MPL_WOL_LINK - Enable wake on link status change. // MPL_WOL_ARP - Enable wake on any ARP packet. // // Return Value // NS_STATUS_SUCCESS // The WOL configuration was returned successfully // //***************************************************************************** MPL_STATUS MplWolGetCfg( IN NS_VOID *pMplHandle, IN NS_UINT *pWakeType ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplWolGetCfg); *pWakeType = pMplCtx->pwrWakeType; EXIT(MplWolGetCfg); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplWolClearPattern // Clear all WOL wake patterns on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The wake patterns were successfully cleared // //***************************************************************************** MPL_STATUS MplWolClearPattern( IN NS_VOID *pMplHandle ) { // MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplWolClearPattern); EXIT(MplWolClearPattern); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplWolAddPattern // Add a new WOL wake pattern to the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWolPattern // Pointer to a MPL_WOL_PATTERN structure in which the new pattern // and its associated mask is noted // // Return Value // NS_STATUS_SUCCESS // The wake pattern was successfully added. // NS_STATUS_RESOURCES // The wake pattern not added since it exceeds the maximum supported // on this device. // NS_STATUS_INVALID_PARM // The wake pattern buffer is larger than the maximum supported by // the device. // //***************************************************************************** MPL_STATUS MplWolAddPattern( IN NS_VOID *pMplHandle, IN MPL_WOL_PATTERN *pWolPattern ) { // MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplWolAddPattern); EXIT(MplWolAddPattern); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplWolRemovePattern // Remove a WOL wake pattern from the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWolPattern // Pointer to a MPL_WOL_PATTERN structure in which the pattern // and its associated mask is noted // // Return Value // NS_STATUS_SUCCESS // The wake pattern was deleted successfully. // NS_STATUS_INVALID_PARM // The wake pattern was not found in the list // //***************************************************************************** MPL_STATUS MplWolRemovePattern( IN NS_VOID *pMplHandle, IN MPL_WOL_PATTERN *pWolPattern ) { // MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplWolRemovePattern); EXIT(MplWolRemovePattern); return NS_STATUS_SUCCESS; } //***************************************************************************** // cfgWakeEvts // Configures the wakes events on the chip // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID cfgWakeEvts ( IN MPL_CONTEXT *pMplCtx ) { NS_UINT32 wcsrReg = 0x0, rfcrReg = 0x0; // Disable Rx Filter MPL_WRITE32(pMplCtx, RFCR, 0x0); if (pMplCtx->pwrWakeType & MPL_WOL_MAGIC) { // Wake on Magic Packet wcsrReg |= WAKEON_MAGICPKT; rfcrReg |= ACCEPT_ALLBCAST | ACCEPT_PERFECTMATCH; } if (pMplCtx->pwrWakeType & MPL_WOL_BROADCAST) { // Wake on Any Broadcast packet wcsrReg |= WAKEON_BROADCAST; rfcrReg |= ACCEPT_ALLBCAST; } if (pMplCtx->pwrWakeType & MPL_WOL_MULTICAST) { // Wake on Any Multicast packet wcsrReg |= WAKEON_MULTICAST; rfcrReg |= ACCEPT_ALLMCAST; } if (pMplCtx->pwrWakeType & MPL_WOL_DIRECTED) { // Wake on Unicast packet addressed to us wcsrReg |= WAKEON_UNICAST; rfcrReg |= ACCEPT_PERFECTMATCH; } if (pMplCtx->pwrWakeType & MPL_WOL_LINK) { // Wake on Link change wcsrReg |= WAKEON_PHYSTSCHNG; } if (pMplCtx->pwrWakeType & MPL_WOL_ARP) { // Wake on Any ARP packet wcsrReg |= WAKEON_ARPPKT; rfcrReg |= ACCEPT_ALLBCAST | ACCEPT_ALLARP; } // Tell the chip MPL_WRITE32(pMplCtx, RFCR, rfcrReg | RXFLTR_EN); MPL_WRITE32(pMplCtx, WCSR, wcsrReg); return; } //***************************************************************************** // cfgWakePatterns // Configures the wakes patterns on the chip // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID cfgWakePatterns( IN MPL_CONTEXT *pMplCtx ) { // Make sure to update WCSR (do a read and then add pattern codes) // Restore rfcr from pMplCtx->rfcrReg since the original RFCR contents // now hold on their own i.e. no Evt specific RFCR return; } #ifdef LINUX_POWER_DEBUG //***************************************************************************** // printWakeReason // Prints why we woke up // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID printWakeReason( IN MPL_CONTEXT *pMplCtx ) { NS_UINT32 wcsr; // Disable Rx Filter wcsr = MPL_READ32(pMplCtx, WCSR); if (wcsr & WAKEON_MAGICPKT) { // Wake on Magic Packet printk("MPL Woke on Magic Packet \n"); } if (wcsr & WAKEON_BROADCAST) { // Wake on Any Broadcast packet printk("MPL Woke on Broadcast Packet \n"); } if (wcsr & WAKEON_MULTICAST) { // Wake on Any Multicast packet printk("MPL Woke on Multicast Packet \n"); } if (wcsr & WAKEON_UNICAST) { // Wake on Unicast packet addressed to us printk("MPL Woke on Unicast Packet \n"); } if (wcsr & WAKEON_PHYSTSCHNG) { // Wake on Link change printk("MPL Woke on Link Change \n"); } if (wcsr & WAKEON_ARPPKT) { // Wake on Any ARP packet printk("MPL Woke on ARP Packet \n"); } if (wcsr & WAKEON_PATRN0) { // Wake on Pattern Match printk("MPL Woke on Pattern Match-0\n"); } if (wcsr & WAKEON_PATRN1) { // Wake on Pattern Match printk("MPL Woke on Pattern Match-1\n"); } if (wcsr & WAKEON_PATRN2) { // Wake on Pattern Match printk("MPL Woke on Pattern Match-2\n"); } if (wcsr & WAKEON_PATRN3) { // Wake on Pattern Match printk("MPL Woke on Pattern Match-3\n"); } return; } #endif DP8381X-Linux-Ver-1.6/Mpl/mplmisc.c0000444000000000000000000003531010430225754015226 0ustar rootroot //****************************************************************************** // // MPLMISC.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL miscellaneous support APIs // // This file contains the API implementations for // o Set/Get of Mac Address // o Controlling loopback mode // o Set/Clear of packet priority // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_MISC, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_MISC, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_MISC, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_MISC, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_MISC, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_MISC, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_MISC, fmt) //***************************************************************************** // MplSetMacAddress // Set the MAC's address on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pMacAddr // Pointer to caller supplied variable with the new MAC address // // Return Value // NS_STATUS_SUCCESS // The MAC address was sucessfully programmed on the device // //***************************************************************************** MPL_STATUS MplSetMacAddress ( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pMacAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT16 *tmpPtr = (NS_UINT16 *) pMacAddr; NS_UINT32 regVal; NS_UINT8 i; ENTER(MplSetMacAddress); // Disable Rx Filter regVal = MPL_READ32(pMplCtx, RFCR); MPL_WRITE32(pMplCtx, RFCR, regVal & ~RXFLTR_EN); // Enter new Mac addr for (i = 0x0; i < 0x3; i++, tmpPtr++) { // Set control bits MPL_WRITE32(pMplCtx, RFCR, i * 2); // Write actual data-16bits // No Swapping to be done for MAC addr since it should be N/w order // So go direct to OAI API OaiIoWrite32(pMplCtx->pClientHandle, (NS_UINT32 volatile *) &pMplCtx->pRegsBase->RFDR, *tmpPtr); } // Reenable filter MPL_WRITE32(pMplCtx, RFCR, regVal); // Copy the mac address OaiMemCopy(pMplCtx->permMacAddr, pMacAddr, 0x06); return NS_STATUS_SUCCESS; EXIT(MplSetMacAddress); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplGetMacAddress // Get the current MAC's address on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // eeProm // If set to NS_TRUE, the permanent (EEPROM programmed) mac address // for the device is returned back to the caller, else the current // active address is returned. // pMacAddr // Pointer to a caller supplied MPL_MAC_ADDR variable where the current // or default network address is returned. // // Return Value // NS_STATUS_SUCCESS // The mac address was successfully read and is returned. // NS_STATUS_FAILURE // Failed to get the MAC address //***************************************************************************** MPL_STATUS MplGetMacAddress ( IN NS_VOID *pMplHandle, IN NS_BOOLEAN eeProm, OUT MPL_MAC_ADDR pMacAddr ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; NS_UINT16 *tmpPtr = (NS_UINT16 *) pMacAddr; NS_UINT32 regVal; NS_UINT8 i; ENTER(MplGetMacAddress); // Read from the source if (eeProm == NS_TRUE) { #ifndef MPL_NO_EEPROM { // MP3 differs from all other Mac relative to EEPROM layout if (pMplCtx->devId != MPL_DEVICE_ID_DP83818) { NS_UINT16 prevEE, currEE; // Read from EEPROM status = MplEERead(pMplCtx, 6, &prevEE); for (i = 0; (i < 3) && (status == NS_STATUS_SUCCESS); i++) { status = MplEERead(pMplCtx, i + 7, &currEE); pMacAddr[i*2] = (currEE << 1) + (prevEE >> 15); pMacAddr[i*2 + 1] = currEE >> 7; prevEE = currEE; } } else { // FM: Swapping needed? status = MplEERead(pMplCtx, 0xA, tmpPtr); status = MplEERead(pMplCtx, 0xB, ++tmpPtr); status = MplEERead(pMplCtx, 0xC, ++tmpPtr); } } #else status = NS_STATUS_FAILURE; // No EEPROM on this board #endif// MPL_NO_EEPROM } else { // Read from MAC Registers // Disable Rx Filter regVal = MPL_READ32(pMplCtx, RFCR); MPL_WRITE32(pMplCtx, RFCR, regVal & ~RXFLTR_EN); // Read the current Mac Addr (if this function was called following a load // from EEPROM operation then the addr visible will be the permanent addr) for (i = 0x0; i < 0x3; i++, tmpPtr++) { // Set control bits MPL_WRITE32(pMplCtx, RFCR, i * 2); // Read actual data-16bits // No Swapping to be done for MAC addr since it should be N/w order // So go direct to OAI API *tmpPtr = (NS_UINT16)OaiIoRead32(pMplCtx->pClientHandle, (NS_UINT32 volatile *) &pMplCtx->pRegsBase->RFDR); } // Reenable filter MPL_WRITE32(pMplCtx, RFCR, regVal); } EXIT(MplGetMacAddress); return status; } //***************************************************************************** // MplGetDeviceId // Get the device Id to identify the MacPhyter version // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // MPL_DEVICE_ID_DP83815 = Macphyter-I found // MPL_DEVICE_ID_DP83816 = Macphyter-II found // MPL_DEVICE_ID_DP83818 = Macphyter-III found //***************************************************************************** MPL_DEVICE_ID MplGetDeviceId( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplGetDeviceId); // Read the SRR regVal = MPL_READ32(pMplCtx, SRR); pMplCtx->srr = regVal; switch (regVal) { case MPI_C_MAC_ID : case MPI_D_MAC_ID : pMplCtx->devId = MPL_DEVICE_ID_DP83815; break; case MPII_A4_MAC_ID : case MPII_A5_MAC_ID : pMplCtx->devId = MPL_DEVICE_ID_DP83816; break; case MPIII_MAC_ID : pMplCtx->devId = MPL_DEVICE_ID_DP83818; break; default : pMplCtx->devId = MPL_DEVICE_ID_UNKNOWN; } // Get MPL caps MplGetCaps(pMplCtx, &pMplCtx->caps); EXIT(MplGetDeviceId); return pMplCtx->devId; } //***************************************************************************** // MplGetRegs // Get the current operational registers values // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // pRegs // A caller supplied buffer array (atleast 64*4 bytes) // // Return Value // None //***************************************************************************** NS_VOID MplGetRegs( IN NS_VOID *pMplHandle, IN NS_UINT32 *pRegs ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 i; NS_UINT32 volatile *regAddr; ENTER(MplGetRegs); // Get the Page-0 registers for (i = 0x0; i < 64; i++) { regAddr = (NS_UINT32 volatile *)((NS_UINT8 *)pMplCtx->pRegsBase + i*4); pRegs[i] = MPL_LTOH32(OaiIoRead32(pMplCtx->pClientHandle, regAddr)); } EXIT(MplGetRegs); return; } //***************************************************************************** // MplDumpTransmitRing // Dump the Txd ring // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // None //***************************************************************************** NS_VOID MplDumpTransmitRing( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT i, j; ENTER(MplDumpTransmitRing); for (i = 0x0; i < pMplCtx->txQueueCnt; i++) { PRINT(("Dumping Tx Queue: %d \n", i)); PRINT(("Curr: %d Dirty: %d \n", pMplCtx->txQueue[i].curr, pMplCtx->txQueue[i].dirty)); PRINT(("Ring Phy Addr: %x Virtual Addr: %x \n", pMplCtx->txQueue[i].ringPA, (NS_ADDR)pMplCtx->txQueue[i].pRing)); for (j = 0x0; j < pMplCtx->txQueue[i].descCnt; j++) { PRINT(("Txd: %d Next: %x CmdSts: %x BufPtr: %x MplPriv: %x \n", j, pMplCtx->txQueue[i].pRing[j].linkPA, (NS_UINT)pMplCtx->txQueue[i].pRing[j].cmdSts, (NS_ADDR)pMplCtx->txQueue[i].pRing[j].bufptrPA, (NS_ADDR)pMplCtx->txQueue[i].pRing[j].mplPriv)); } } EXIT(MplDumpTransmitRing); return; } //***************************************************************************** // MplDumpReceiveRing // Dump the Rxd ring // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // None //***************************************************************************** NS_VOID MplDumpReceiveRing( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT j; ENTER(MplDumpReceiveRing); PRINT(("Dumping Rx Queue \n")); PRINT(("Curr: %d Dirty: %d \n", pMplCtx->rxQueue.curr, pMplCtx->rxQueue.dirty)); PRINT(("Ring Phy Addr: %x Virtual Addr: %x \n", pMplCtx->rxQueue.ringPA, (NS_ADDR)pMplCtx->rxQueue.pRing)); for (j = 0x0; j < pMplCtx->rxQueue.descCnt; j++) { PRINT(("Rxd: %d Next: %x CmdSts: %x BufPtr: %x MplPriv: %x \n", j, pMplCtx->rxQueue.pRing[j].linkPA, (NS_UINT)pMplCtx->rxQueue.pRing[j].cmdSts, (NS_ADDR)pMplCtx->rxQueue.pRing[j].bufptrPA, (NS_ADDR)pMplCtx->rxQueue.pRing[j].mplPriv)); } EXIT(MplDumpReceiveRing); return; } //***************************************************************************** // MplRegRead // Read a 32-bit register // // Parameters // pMplHandle // MPL device handle // regIndex // Register to read (in terms of absolute offset e.g. CR = 0x0, // TXCFG = 0x24) // // Return Value // Reg data // //***************************************************************************** NS_UINT32 MplRegRead( IN NS_VOID *pMplHandle, IN NS_UINT regIndex ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 volatile *regAddr; regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase + regIndex); return MPL_LTOH32(OaiIoRead32(pMplCtx->pClientHandle, regAddr)); } //***************************************************************************** // MplRegWrite // Write a 32-bit register // // Parameters // pMplHandle // MPL device handle // regIndex // Register to read (in terms of absolute offset e.g. CR = 0x0, // TXCFG = 0x24) // regData // Data to write // // Return Value // None // //***************************************************************************** NS_VOID MplRegWrite( IN NS_VOID *pMplHandle, IN NS_UINT regIndex, IN NS_UINT32 regData ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 volatile *regAddr; regAddr = (NS_UINT32 volatile *) ((NS_UINT8 *)pMplCtx->pRegsBase + regIndex); OaiIoWrite32(pMplCtx->pClientHandle, regAddr, MPL_HTOL32(regData)); return; } #ifndef MPL_NO_EEPROM //***************************************************************************** // MplEERead // Read 16-bit word from a given EEPROM offset // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // index // Offset from where to read EEPROM contents // *pData // Caller provided variable where the 16-bit contents is returned // // Return Value // NS_STATUS_SUCCESS // The EEPROM was successfully read // NS_STATUS_INVALID_PARM // The EEPROM offset is invalid //***************************************************************************** MPL_STATUS MplEERead( IN NS_VOID *pMplHandle, IN NS_UINT index, IN NS_UINT16 *pData ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 cmd, regVal; NS_SINT i; NS_UINT16 data = 0x0; ENTER(MplEERead); // Select EE chip MPL_WRITE32(pMplCtx, MEAR, EEPROM_CS); // Write out the read command, one bit at a time, insuring that each // transition of the clock lasts at least 2 microseconds. cmd = EEPROM_READ | index; for (i = 10; i >= 0; i--) { regVal = (cmd & (1 << i)) ? EEPROM_CS | EEPROM_DI : EEPROM_CS; MPL_WRITE32(pMplCtx, MEAR, regVal); MPL_READ32(pMplCtx, MEAR); //OaiSleep(4); MPL_WRITE32(pMplCtx, MEAR, (regVal | EEPROM_CLK)); MPL_READ32(pMplCtx, MEAR); //OaiSleep(4); } MPL_WRITE32(pMplCtx, MEAR, EEPROM_CS); MPL_READ32(pMplCtx, MEAR); //OaiSleep(4); // Read in the 16 bits of data, one bit at a time, insuring that each // transition of the clock lasts at least 2 microseconds. for (i = 0; i < 16; i++) { MPL_WRITE32(pMplCtx, MEAR, EEPROM_CS | EEPROM_CLK); MPL_READ32(pMplCtx, MEAR); //OaiSleep(4); data |= ((MPL_READ32(pMplCtx, MEAR) & EEPROM_DO) ? 1 << i : 0); MPL_WRITE32(pMplCtx, MEAR, EEPROM_CS); MPL_READ32(pMplCtx, MEAR); //OaiSleep(4); } // Close the EEPROM MPL_WRITE32(pMplCtx, MEAR, EEPROM_CS); MPL_WRITE32(pMplCtx, MEAR, 0x0); *pData = data; EXIT(MplEERead); return NS_STATUS_SUCCESS; } #endif// MPL_NO_EEPROM DP8381X-Linux-Ver-1.6/Mpl/mplcaps.c0000444000000000000000000001626210430225754015226 0ustar rootroot //****************************************************************************** // // MPLCAPS.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Device and Software Capability Reporting. // // This file contains the API implementations for // o Returning the capabilites of MPL // //****************************************************************************** #include static MPL_CAPS deviceCaps[] = { { #define MPL_CAPS_DP83815_INDEX 0 // Below defines MacPhyter-I caps { // MPL_CAPS_TRANSMIT 1, // priorityQCnt 2048, // fifoSize - Bytes 512, // maxDma - Bytes 32, // minDrain - Bytes 32, // minFill - Bytes 2046, // maxPacketSize - Bytes 0x0 // txFlags - None defined yet }, { // MPL_CAPS_RECEIVE 1, // priorityQCnt 2048, // fifoSize - Bytes 512, // maxDma - Bytes 8, // minDrain - Bytes 2046, // maxPacketSize - Bytes 0x0 // rxFlags - None defined yet }, { // MPL_CAPS_INTERRUPT 0x0, // maxTimerHold - usec 0x0, // maxTransmitHold - Pkt count 0x0, // maxReceiveHold - Pkt count 0x0 // intFlags - None defined yet }, { // MPL_CAPS_LINK MPL_LINK_PAUSE_RECEIVE // linkFlags : Can receive pause requests, but not transmit }, { // MPL_CAPS_WOL 0x4, // maxPatterns 128 // maxPatternSize - Bytes }, { // MPL_CAPS_TASK { // Statistics Task NS_FALSE, // supported 0x0 // statFlags - None defined yet }, { // Checksum Task NS_FALSE, // supported 0x0 // checksumFlags - None defined yet }, { // VLAN Task NS_FALSE, // supported 0x0, // maxFilterEntries 0x0 // vlanFlags - None defined yet }, { // Receive Filter Task NS_TRUE, // supported 0xFFFF, // maxFilterEntries- None defined yet MPL_TASK_FILTER_MCAST | MPL_TASK_FILTER_UCAST // filterFlags } } }, { #define MPL_CAPS_DP83816_INDEX 1 // Below defines MacPhyter-II caps { // MPL_CAPS_TRANSMIT 1, // priorityQCnt 2048, // fifoSize - Bytes 512, // maxDma - Bytes 32, // minDrain - Bytes 32, // minFill - Bytes 2046, // maxPacketSize - Bytes 0x0 // txFlags }, { // MPL_CAPS_RECEIVE 1, // priorityQCnt 2048, // fifoSize - Bytes 512, // maxDma - Bytes 8, // minDrain - Bytes 2046, // maxPacketSize - Bytes 0x0 // rxFlags }, { // MPL_CAPS_INTERRUPT 25500, // maxTimerHold - usec 0x0, // maxTransmitHold - Pkt count 0x0, // maxReceiveHold - Pkt count 0x0 // intFlags }, { // MPL_CAPS_LINK MPL_LINK_PAUSE_RECEIVE // linkFlags : Can receive pause requests, but not transmit }, { // MPL_CAPS_WOL 0x4, // maxPatterns 128 // maxPatternSize - bytes }, { // MPL_CAPS_TASK { // Statistics Task NS_FALSE, // supported 0x0 // statFlags }, { // Checksum Task NS_FALSE, // supported 0x0 // checksumFlags }, { // VLAN Task NS_FALSE, // supported 0x0, // maxFilterEntries 0x0 // vlanFlags }, { // Receive Filter Task NS_TRUE, // supported 0xFFFF, // maxFilterEntries MPL_TASK_FILTER_MCAST | MPL_TASK_FILTER_UCAST // filterFlags } } }, { #define MPL_CAPS_DP83818_INDEX 2 // Below defines MacPhyter-III caps { // MPL_CAPS_TRANSMIT 4, // priorityQCnt 2048, // fifoSize - Bytes 2048, // maxDma - Bytes 0, // minDrain - Bytes 32, // minFill - Bytes 2046, // maxPacketSize - Bytes 0x0 // txFlags }, { // MPL_CAPS_RECEIVE 1, // priorityQCnt 4096, // fifoSize - Bytes 2048, // maxDma - Bytes 0, // minDrain - Bytes 2046, // maxPacketSize - Bytes 0x0 // rxFlags }, { // MPL_CAPS_INTERRUPT 25500, // maxTimerHold - in usec 0x1F, // maxTransmitHold - Pkt count 0x1F, // maxReceiveHold - Pkt count 0x0 // intFlags }, { // MPL_CAPS_LINK MPL_LINK_PAUSE_TRANSMIT | MPL_LINK_PAUSE_RECEIVE // linkFlags }, { // MPL_CAPS_WOL 0x8, // maxPatterns 128 // maxPatternSize - bytes }, { // MPL_CAPS_TASK { // Statistics Task NS_FALSE, // supported 0x0 // statFlag; }, { // Checksum Task NS_FALSE, // supported 0x0 // checksumFlags }, { // VLAN Task NS_TRUE, // supported 4096, // maxVlanEntries in filter table MPL_TASK_VLAN_DETECT_TAGS | MPL_TASK_VLAN_REMOVE_TAGS | MPL_TASK_VLAN_DISCARD_TAGGED | MPL_TASK_VLAN_DISCARD_UNTAGGED | MPL_TASK_VLAN_PERPACKET | MPL_TASK_VLAN_FILTER // vlanFlags }, { // Receive Filter Task NS_TRUE, // supported 0xFFFF, // maxFilterEntries MPL_TASK_FILTER_MCAST | MPL_TASK_FILTER_UCAST // filterFlags } } } }; //***************************************************************************** // MplGetCaps // Returns the capabilities of the device and the MPL implementation. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pMplCaps // Pointer to a caller allocated MPL_CAPS structure in which the // capabilities of the device and MPL is returned // // Return Value // NS_STATUS_SUCCESS // The capabilities were successfully returned // NS_STATUS_ERROR // The device Id was unknown // //***************************************************************************** MPL_STATUS MplGetCaps ( IN NS_VOID *pMplHandle, OUT MPL_CAPS *pMplCaps ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status = NS_STATUS_SUCCESS; switch(pMplCtx->devId) { case MPL_DEVICE_ID_DP83815: *pMplCaps = deviceCaps[MPL_CAPS_DP83815_INDEX]; break; case MPL_DEVICE_ID_DP83816: *pMplCaps = deviceCaps[MPL_CAPS_DP83816_INDEX]; break; case MPL_DEVICE_ID_DP83818: *pMplCaps = deviceCaps[MPL_CAPS_DP83818_INDEX]; break; default : status = NS_STATUS_FAILURE; } return status; } DP8381X-Linux-Ver-1.6/Mpl/mplregs.h0000444000000000000000000007763510430225754015260 0ustar rootroot //********************************************************************** // // MPLREGS.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // Defines the device registers (MAC and PHY) // //********************************************************************** #ifndef _MPLREGS_H #define _MPLREGS_H // Reset intervals #define RESETINTERVAL_MAC 1000 // interval from MAC reset (in usec) #define EELOADINTERVAL 1000 // interval from EELOAC (usec) #define RESETINTERVAL_PHY 1000 // interval from MAC reset (in usec) // MacPhy PHY IDs #define MP_PHY_ID1 0x2000 #define MP_PHY_REV 0x5C20 //Prior to MP3 #define ASPEN_PHY_REV 0x5C90 #define PHY_MII_REG_BASE 0x80 // MacPhy MAC IDs #define MPI_C_MAC_ID 0x0302 // Macphyter-I Rev-C #define MPI_D_MAC_ID 0x0403 // Macphyter-I Rev-D #define MPII_A4_MAC_ID 0x0504 // Macphyter-II Rev-A4 #define MPII_A5_MAC_ID 0x0505 // Macphyter-II Rev A5 #define MPIII_MAC_ID 0x0601 // Macphyter-III // All packed on byte boundaries #pragma pack(1) // Operational Register Map for MacPhyter2/3 typedef volatile struct _DP8381xOpRegs { // Basic MAC (0x00 to 0x5C) NS_UINT32 CR; // Command register NS_UINT32 CFG; // Cfg and media status NS_UINT32 MEAR; // Mii, EEprom Access NS_UINT32 MTSCR; // MAC Test Control NS_UINT32 ISR; // Interrupt Status NS_UINT32 IMR; // Interrupt Mask NS_UINT32 IER; // Interrupt enable NS_UINT32 IHR; // Interrupt holdoff NS_UINT32 TXDP; // Tx descriptor ptr, queue 0 NS_UINT32 TXCFG; // Transmit configuration NS_UINT32 pad1; // Reserved NS_UINT32 GPIOR; // General I/O pin control NS_UINT32 RXDP; // Rx descriptor ptr, queue0 NS_UINT32 RXCFG; // Receive configuration NS_UINT32 pad2; // Reserved NS_UINT32 CCSR; // PME backdoor NS_UINT32 WCSR; // Wake-on-LAN command Status NS_UINT32 PCR; // Pause frame control status NS_UINT32 RFCR; // Receive filter control NS_UINT32 RFDR; // Receive filter data NS_UINT32 BRAR; // Boot rom address NS_UINT32 BRDR; // Boot rom data NS_UINT32 SRR; // Silicon revision NS_UINT32 MIBC; // MIB statistics Control // MIB regs (0x60 to 0x7C) NS_UINT32 RXE; // Packets recd with errors NS_UINT32 RXFCS; // Packets recd with frame check seq err NS_UINT32 RXM; // Packets missed due to FIFO overruns NS_UINT32 RXFAE; // Packets recd with frame alignment err NS_UINT32 RXS; // Packets recd with symbol err NS_UINT32 RXF; // Packets recd with len > 1518 NS_UINT32 TXSQE; // Packets with loss of collision during // transmission NS_UINT32 RXIRL; // Packets recd with InRange length errs // Internal PHY (0x80 to 0x9C) NS_UINT32 BMCR; // Basic Mode Control Register NS_UINT32 BMSR; // Basic Mode Status Register NS_UINT32 PHYIDR1; // PHY Id reg1 NS_UINT32 PHYIDR2; // PHY Id reg2 NS_UINT32 ANAR; // Auto-Neg Adv reg NS_UINT32 ANLPAR; // Auto-Neg Link partner reg NS_UINT32 ANER; // Auto-Neg expansion reg NS_UINT32 ANNPTR; // Auto-Neg next page TX // Priority Queuing (0xA0 to 0xAC) NS_UINT32 TXDP1; // Tx descriptor ptr, queue1 NS_UINT32 TXDP2; // Tx descriptor ptr, queue2 NS_UINT32 TXDP3; // Tx descriptor ptr, queue3 NS_UINT32 PQCR; // Prority Queue Control reg // VLAN control (0xB0 to 0xB4) NS_UINT32 VRCR; // VLAN receive control NS_UINT32 VTCR; // VLAN transmit control NS_UINT32 pad3; // Reserved NS_UINT32 pad4; // Reserved // PHY Status (0xC0) NS_UINT32 PHYSTS; // Phy Status Register // PHY MII Regs (0xC4 and 0xC8) NS_UINT32 MICR; // Phy MII Interrupt Control NS_UINT32 MISR; // Phy MII Interrupt Status // PHY Interal Regs NS_UINT32 PAGE; // 0xCC page select union _RegD0 { NS_UINT32 FCSCR; // 0xD0 (Page 0) false carrier sense counter NS_UINT32 FCOCTL; // 0xD0 (Page 1) FCO control } RegD0; #define FCSCR RegD0.FCSCR #define FCOCTL RegD0.FCOCTL union _RegD4 { NS_UINT32 RECR; // 0xD4 (Page 0) receiver error counter NS_UINT32 TMR; // 0xD4 (Page 1) test mode } RegD4; #define RECR RegD4.RECR #define TMR RegD4.TMR union _RegD8 { NS_UINT32 PCS; // 0xD8 (Page 0) PCS sub layer config & status NS_UINT32 BGR; // 0xD8 (Page 1) band gap reference } RegD8; #define PCS RegD8.PCS #define BGR RegD8.BGR union _RegDC { NS_UINT32 RBR; // 0xDC (Page 0) RMII & bypass NS_UINT32 CRM; // 0xDC (Page 1) CRM } RegDC; #define RBR RegDC.RBR #define CRM RegDC.CRM NS_UINT32 CDCT12; // 0xE0 (Page 1) CD test control 2 union _RegE4 { NS_UINT32 PHYCTL; // 0xE4 (Page 0) phy control NS_UINT32 PMDCSR; // 0xE4 (Page 1) PMD control/status } RegE4; #define PHYCTL RegE4.PHYCTL #define PMDCSR RegE4.PMDCSR union _RegE8 { NS_UINT32 TENBT; // 0xE8 (Page 0) 10BaseT status/control NS_UINT32 PGMCGM; // 0xE8 (Page 1) PGM/CGM control } RegE8; #define TENBT RegE8.TENBT #define PGMCGM RegE8.PGMCGM union _RegEC { NS_UINT32 CDCTL1; // 0xEC (Page 0) CD test control 1 NS_UINT32 DSPTST; // 0xEC (Page 1) DSP test } RegEC; #define CDCTL1 RegEC.CDCTL1 #define DSPTST RegEC.DSPTST NS_UINT32 EXTCFG; // 0xF0 (Page 1) extended config NS_UINT32 DSPCFG; // 0xF4 (Page 1) DSP config NS_UINT32 SDCFG; // 0xF8 (Page 1) signal detect config. NS_UINT32 TDATA; // 0xFC (Page 1) test data } DP8381xOpRegs; #pragma pack() // reset back to the default packing // OPERATIONAL REGISTER BIT DEFINITIONS // (R/W = read/write, RO = read only, ROSC = read only, self-clearing, // WR0 = write, read back 0, !825 = DP83825 only) //*************************************************************** // CR - command register bit definitions //*************************************************************** #define TX_EN 0x00000001 // transmitter enable (R/W) #define TX_DIS 0x00000002 // transmitter disable (WR0) #define RX_EN 0x00000004 // receiver enable (R/W) #define RX_DIS 0x00000008 // receiver disable (WR0) #define TXRESET 0x00000010 // transmitter reset (WR0) #define RXRESET 0x00000020 // receiver reset (WR0) // bit 6 (reserved) #define SWINT 0x00000080 // software interrupt #define SOFTRESET 0x00000100 // soft reset (W read 0 when comp) #define TXQUEUE_MASK 0x00001E00 // Tx priority queue mask #define TXQUEUE0_EN 0x00000200 // Tx Priority Queue 0 (R/W) #define TXQUEUE1_EN 0x00000400 // Tx Priority Queue 1 (R/W) #define TXQUEUE2_EN 0x00000800 // Tx Priority Queue 2 (R/W) #define TXQUEUE3_EN 0x00001000 // Tx Priority Queue 3 (R/W) #define TX_PQUEUE_OFF 9 // Bit Offset for Tx Pri Q setting //*************************************************************** // CFG - Configuration and Media Status Register //*************************************************************** #define BIG_ENDIAN 0x00000001 // big endian (DMA only) (R/W) #define TMRTEST 0x00000002 // speeds up 100us internal timer to 4us #define BROM_DIS 0x00000004 // disable Boot ROM I/F (R/W) #define SERR_ON_PAR_ERR 0x00000008 // SERR on PCI parity err (R/W) #define ABORT_ON_EXCESSIVE_DEF 0x00000010 // abrt on excessive deferral (R/W) #define OOWTMR_AT_PRESTRT 0x00000020 // out-of-window at preamble start (R/W) #define SINGLETXBCKOFF 0x00000040 // Single IFG tx Backoff (R/W) #define PCIREQ_WEAK 0x00000080 // conservative PCI bus req algo (R/W) #define EXTENDEDDESC_EN 0x00000100 // Extended descriptor format en (R/W) #define PHY_DIS 0x00000200 // dise phy (deassert mii RXEN) (R/W) #define PHY_RST 0x00000400 // reset phy (assert PHYRST_N) (R/W) #define BEM_REG 0x00000800 // Big endian reg mode (R/W)-DP83818 #define EXT_PHY 0x00001000 // Enable External Phy Support (R/W) // Auto-Neg Select - FM #define PAUSE_ADV 0x00010000 // pause Advertise (R/W) #define PINT_ACEN 0x00020000 // phy int auto clear (R/W) // PHY Configuration - FM #define AUTO_DUP 0x01000000 // Ena Auto Full duplex (R/W) #define ANEG_DN 0x08000000 // Auto Neg done #define POL_10M 0x10000000 // 10M with reverse polarity detected (RO) #define FULLDUP_STS 0x20000000 // full duplex indication from phy (RO) #define LINKSPEED100 0x40000000 // 100 Mbps indication from phy (RO) #define LINKGOOD_STS 0x80000000 // good link indication from phy (RO) //*************************************************************** // MEAR - MII / EEPROM Access Register //*************************************************************** #define EEPROM_DI 0x00000001 // EEPROM data in (ouR data out) (R/W) #define EEPROM_DO 0x00000002 // EEPROM data out (our data in) (RO) #define EEPROM_CLK 0x00000004 // EEPROM clock (R/W) #define EEPROM_CS 0x00000008 // EEPROM chip select (R/W) #define MDIO 0x00000010 // MII management data input/output (R/W) #define MDDIR 0x00000020 // MII management data dir, 1 = out (R/W) #define MDCLK 0x00000040 // MII management data clock (R/W) #define EEPROM_WRITE 0x00000140 // EEPROM Write Command #define EEPROM_READ 0x00000180 // EEPROM Read Command #define EEPROM_ERASE 0x000001C0 // EEPROM Erase Command enum EEPROM_Cmds { EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), }; #define MII_READ 0x6003FFFF #define MII_WRITE 0x50020000 #define MII_ADDR_OFF 23 #define MII_REG_OFF 18 #define MII_CMD_OFF 16 //*************************************************************** // MTSCR - MAC Test Control Register //*************************************************************** #define EEBIST_FAIL 0x00000001 // EE Bist fail indication (RO) #define EEBIST_EN 0x00000002 // Enable EEPROM BIST (R/W) #define EELOAD_EN 0x00000004 // Enable EEPROM Load (R/W) #define RBIST_RXRFAIL 0x00000008 // RX FIlter RAM BIST Fail (RO) #define RBIST_TXFAIL 0x00000010 // TX FIFO Fail (RO) #define RBIST_RXFAIL 0x00000020 // RX FIFO BIST Fail (RO) #define RBIST_DONE 0x00000040 // SRAM BIST Done (RO) #define RBIST_EN 0x00000080 // SRAM BIST Enable (R/W) #define RBIST_MODE 0x00000100 // SRAM BIST Mode - Reserved NSC (R/W) #define RBIST_CLKD 0x00000200 // SRAM BIST Clock - Reserved NSC (R/W) #define RBIST_RST 0x00000400 // SRAM BIST Reset (R/W) #define RBIST_REL 0x00000800 // SRAM BIST Reliablity Mode (R/W) #define FORCE_CRS 0x00001000 // Force CRS (R/W) #define RXFIFO2K 0x00002000 // Select 2KB RX FIFO (R/W) //*************************************************************** // ISR/IMR - Interrupt bit definitions //*************************************************************** #define RXOK 0x00000001 // RX OK interrupt #define RXDESC 0x00000002 // RX descriptor interrupt #define RXERR 0x00000004 // RX packet error #define RXEARLY 0x00000008 // RX Early Threshold #define RXIDLE 0x00000010 // RX Idle #define RXOVERUN 0x00000020 // RX Overrun #define TXOK 0x00000040 // TX OK interrupt #define TXDESC 0x00000080 // TX descriptor interrupt #define TXERR 0x00000100 // TX packet error #define TXIDLE 0x00000200 // TX idle #define TXUNDERRUN 0x00000400 // TX underrun #define MIBSTATS 0x00000800 // MIB statistics service #define SW_INT 0x00001000 // software interrupt #define WOL_EVENT 0x00002000 // Wake-On-LAN power management event #define PHYSTSCHANGE 0x00004000 // phy status change #define HIORDER_INT 0x00008000 // one of the following int's occured #define RXSTSFIFO_OVRN 0x00010000 // rx status fifo overrun #define PCI_TARGABORT 0x00100000 // received PCI target abort #define PCI_MSTRABORT 0x00200000 // generated PCI master abort #define PCI_SERR 0x00400000 // generated PCI system error #define PCI_PARERR 0x00800000 // detected PCI parity error #define RXRST_COMPLETE 0x01000000 // receive reset complete #define TXRST_COMPLETE 0x02000000 // transmit reset complete #define TXDESC0 0x04000000 // Tx Descriptor for priority Q 0 #define TXDESC1 0x08000000 // Tx Descriptor for priority Q 1 #define TXDESC2 0x10000000 // Tx Descriptor for priority Q 2 #define TXDESC3 0x20000000 // Tx Descriptor for priority Q 3 #define TXDESC_MASK 0x3C000000 // Tx Descriptor INTR mask #define TXDESC_OFF 26 // Tx Descriptor INTR offset //************************************************************** // IER - Interrupt Enable Register //*************************************************************** #define INT_EN 0x00000001 // Intr Ena (0 masks all ints) (R/W) #define AUTODISABLEINT_EN 0x00000002 // en auto disable (read of ISR disables // all int's until INT_EN set (R/W) // bits 2-31 (reserved) //************************************************************** // IHR - Interrupt Holdoff Register //*************************************************************** #define INTHLD_VAL_MASK 0x000000FF // mask for interrupt holdoff value (R/W) #define STARTHLDOFFON1INT 0x00000100 // start interrupt holdoff on 1st int // (if clr, hold begins on int en) (R/W) #define INTHLDTMR_4US 0x00000200 // set holdoff tick to 4us (if clear, // tick=100us (R/W) // bits 10-15 (reserved) #define INTHLDCNCL_RXPKTS_SHIFT 16 #define INTHLDCNCL_RXPKTS_MASK 0x001F0000 // # of rcv packets that will // prematurely terminate intr // holdoff (R/W) #define INTHLDCNCL_TXPKTS_SHIFT 21 #define INTHLDCNDL_TXPKTS_MASK 0x03E00000 // # of rcv packets that will // prematurely terminate intr // holdoff (R/W) // bits 26-31 (reserved) #define MAX_HOLD_TIME (0xFF*100) // Max intr hold timeout value // 255*100usec #define HOLD_TIME_MASK 0xFFFFFF00 // Hold time mask //*************************************************************** // TXCFG - Transmit Configuration Register //*************************************************************** #define MXDMA4 0x00100000 // 4 bytes (R/W) #define MXDMA8 0x00200000 // 8 bytes (R/W) #define MXDMA16 0x00300000 // 16 bytes (R/W) #define MXDMA32 0x00400000 // 32 bytes (R/W) #define MXDMA64 0x00500000 // 64 bytes (R/W) #define MXDMA128 0x00600000 // 128 bytes (R/W) #define MXDMA256 0x00700000 // 256 bytes (R/W) #define MXDMA512 0x00000000 // 512 bytes (R/W) #define TXDMA4 0x00020000 // scale MXDMA table value setting by 4 #define BOFF_CONT 0x00040000 // enable backoff continuos #define BLINDTX_EN 0x00080000 // enable blind transmit (R/W) !825 #define EXC_COLN_RETRY 0x00800000 // en excessive collision retry (R/W) #define AUTOTXPAD_EN 0x10000000 // en Automatic Tx Padding (R/W) #define LOOPBACK_EN 0x20000000 // enable MAC loopback mode (R/W) #define SQE_IGNORE 0x40000000 // dis SQE (heart beat) test (R/W) #define CARRIER_IGNORE 0x80000000 // carrier sense ignore (R/W) #define TXDRAIN_MASK 0x0000003F // transmit drain thresh mask #define TXFILL_MASK 0x00003F00 // transmit fill thresh mask #define TXFILL_SHIFT 8 #define TXMXDMA_MASK 0x00700000 // max tx DMA mask #define TXSET_MASK (TXDMA4 | TXDRAIN_MASK | TXFILL_MASK | TXMXDMA_MASK) //*************************************************************** // GPIOR - General Purpose I/O Register //*************************************************************** #define GP1_OUT 0x00000001 // General purpose Pin 1 Output (R/W) #define GP2_OUT 0x00000002 // General purpose Pin 2 Output (R/W) #define GP3_OUT 0x00000004 // General purpose Pin 3 Output (R/W) #define GP4_OUT 0x00000008 // General purpose Pin 4 Output (R/W) #define GP1_OE 0x00000010 // General purpose Pin 1 Output Enable (R/W) #define GP2_OE 0x00000020 // General purpose Pin 2 Output Enable (R/W) #define GP3_OE 0x00000040 // General purpose Pin 3 Output Enable (R/W) #define GP4_OE 0x00000080 // General purpose Pin 4 Output Enable (R/W) #define GP1_IN 0x00000100 // General purpose Pin 1 Input (RO) #define GP2_IN 0x00000200 // General purpose Pin 2 Input (RO) #define GP3_IN 0x00000400 // General purpose Pin 3 Input (RO) #define GP4_IN 0x00000800 // General purpose Pin 4 Input (RO) //************************************************************** // RXCFG - Receive Configuration Register //*************************************************************** #define RXDRAIN_SHIFT 1 #define RXDRAIN_MASK 0x0000003E // rx drain threshold mask #define RXDMA4 0x00040000 // scale MXDMA table value setting by 4 #define DMA_USECACHESIZ_EN 0x00080000 // rx dma multiples of cacheline size // (R/W) #define RXMXDMA_MASK 0x00700000 // max rx DMA mask #define RXSET_MASK (RXDRAIN_MASK | RXMXDMA_MASK | RXDMA4) // max rx DMA burst sizes...use TXCFG MXDMAxxx definitions #define ACCEPT_INRNG_LENERR 0x04000000 // accept in-range-length error'd // pkts (R/W) #define ACCEPT_LONGPKT 0x08000000 // accept long packets (R/W) #define FULLDUPLEX_EN 0x10000000 // en. full duplex (R/W) #define STRIPCRC_EN 0x20000000 // en strip CRC (R/W) #define ACCEPT_RUNTS 0x40000000 // accept runts (R/W) #define ACCEPT_CRCALIGNERR 0x80000000 // accept CRC and alignment err's (R/W) //************************************************************** // CCSR - PME Backdoor Register //*************************************************************** #define PMEEN 0x00000100 // PME Enable (R/W) - // - Mirrored from PMCSR #define PMESTS 0x00008000 // PME (sticky) Status (R/W) // - Mirrored from PMCSR //************************************************************** // WCSR - Wake Command / Status Register. //*************************************************************** #define WAKEON_PHYSTSCHNG 0x00000001 // wake on phy sts change int (R/W) #define WAKEON_UNICAST 0x00000002 // wake on any unicast pkt (R/W) #define WAKEON_MULTICAST 0x00000004 // wake on multicast pkt (R/W) #define WAKEON_BROADCAST 0x00000008 // wake on broadcast pkt (R/W) #define WAKEON_ARPPKT 0x00000010 // wake on TCP/IP ARP (R/W) #define WAKEON_PATRN0 0x00000020 // wake on pattern #0 match (R/W) #define WAKEON_PATRN1 0x00000040 // wake on pattern #1 match (R/W) #define WAKEON_PATRN2 0x00000080 // wake on pattern #2 match (R/W) #define WAKEON_PATRN3 0x00000100 // wake on pattern #3 match (R/W) #define WAKEON_MAGICPKT 0x00000200 // wake on magic pkt (R/W) #define MAGICPKT_SECURE_EN 0x00000400 // en magic pkt secure on (R/W) #define WAKEON_PATRN4 0x00000800 // wake on pattern #4 match (R/W) #define WAKEON_PATRN5 0x00001000 // wake on pattern #5 match (R/W) #define WAKEON_PATRN6 0x00002000 // wake on pattern #6 match (R/W) #define WAKEON_PATRN7 0x00004000 // wake on pattern #7 match (R/W) #define WAKESTS_PATRN4 0x00020000 // pattern4 match wake event (ROSC) #define WAKESTS_PATRN5 0x00040000 // pattern5 match wake event (ROSC) #define WAKESTS_PATRN6 0x00080000 // pattern6 match wake event (ROSC) #define WAKESTS_PATRN7 0x00100000 // pattern7 match wake event (ROSC) #define WAKESTS_SEC_HACK 0x00200000 // magic pkt security hack event (ROSC) #define WAKESTS_PHYSTSCHNG 0x00400000 // phy sts change wake event (ROSC) #define WAKESTS_UNICAST 0x00800000 // unicast pkt wake event (ROSC) #define WAKESTS_MULTICAST 0x01000000 // multicast pkt wake event (ROSC) #define WAKESTS_BROADCAST 0x02000000 // broadcast pkt wake event (ROSC) #define WAKESTS_ARPPKT 0x04000000 // ARP pkt wake event (ROSC) #define WAKESTS_PATRN0 0x08000000 // pattern0 match wake event (ROSC) #define WAKESTS_PATRN1 0x10000000 // pattern1 match wake event (ROSC) #define WAKESTS_PATRN2 0x20000000 // pattern2 match wake event (ROSC) #define WAKESTS_PATRN3 0x40000000 // pattern3 match wake event (ROSC) #define WAKESTS_MAGICPKT 0x80000000 // magic pkt wake event (ROSC) #define WAKEON_MASK 0x0000EFFF // Alll wake-on bits //************************************************************** // PCR - Pause Control / Status Register. //*************************************************************** #define PAUSEVAL_MASK 0x0000FFFF // pause cntr value mask #define PS_TX_DP83818 0x00020000 // Manual pause frame load enable #define PS_TX 0x00010000 // Manual pause frame load enable #define PS_DA 0x20000000 // en pause rcv sent to MAC addr // or any pattern match (R/W) #define PS_MCAST 0x40000000 // en pause pkt rcv sent to IEEE // reserved mcast address (R/W) #define RXPAUSE_EN 0x80000000 // en. pause frame reception (R/W) // pause threshold low values - rx data fifo - DP83818+ #define PTHRESHLO_DFIFO_MASK 0x000C0000 // data fifo thresh low mask (R/W) #define PTHRESHLO_DFIFO_DIS 0x00000000 // low thresh disabled (R/W) #define PTHRESHLO_DFIFO512 0x00040000 // low thresh < 512 bytes (R/W) #define PTHRESHLO_DFIFO1024 0x00080000 // low thresh < 1K bytes (R/W) #define PTHRESHLO_DFIFO1536 0x000C0000 // low thresh < 1536 bytes (R/W) // pause threshold hi values - rx data fifo - DP83818+ #define PTHRESHHI_DFIFO_MASK 0x00300000 // data fifo thresh hi mask (R/W) #define PTHRESHHI_DFIFO_DIS 0x00000000 // hi thresh disabled (R/W) #define PTHRESHHI_DFIFO512 0x00100000 // hi thresh >= 512 bytes (R/W) #define PTHRESHHI_DFIFO1024 0x00200000 // hi thresh >= 1K bytes (R/W) #define PTHRESHHI_DFIFO1536 0x00300000 // hi thresh >= 2K bytes (R/W) // pause threshold low values - rx status fifo - DP83818+ #define PTHRESHLO_SFIFO_MASK 0x00C00000 // stat fifo thresh low mask (R/W) #define PTHRESHLO_SFIFO_DIS 0x00000000 // low thresh disabled (R/W) #define PTHRESHLO_SFIFO2PKTS 0x00400000 // low thresh < 2 pkts (R/W) #define PTHRESHLO_SFIFO4PKTS 0x00800000 // low thresh < 4 pkts (R/W) #define PTHRESHLO_SFIFO8PKTS 0x00C00000 // low thresh < 8 pkts (R/W) // pause threshold hi values - rx status fifo - DP83818+ #define PTHRESHHI_SFIFO_MASK 0x03000000 // stat fifo thresh hi mask (R/W) #define PTHRESHHI_SFIFO_DIS 0x00000000 // hi thresh disabled (R/W) #define PTHRESHHI_SFIFO2PKTS 0x01000000 // hi thresh = 2 or more pkts (R/W) #define PTHRESHHI_SFIFO4PKTS 0x02000000 // hi thresh = 4 or more pkts (R/W) #define PTHRESHHI_SFIFO8PKTS 0x03000000 // hi thresh = 4 or more pkts (R/W) //************************************************************** // RFCR - Receive Filter Control Register. //*************************************************************** #define RXFLTRAM_ADDRMASK 0x000007ff // FM - Need to check #define MAX_FILTER_ROWS 32 #define MAX_FILTER_COLS 16 #define HASH_TABLE_INDEX 0x200 // beginning of the mcast/ucast hash #define RCVPATTERNS_ADDR 0x280 // beginning of the receive pattern // buffers #define ACCEPT_PTRNMATCH4 0x00008000 // en pattern match 0 (R/W) #define ACCEPT_PTRNMATCH5 0x00010000 // en pattern match 1 (R/W) #define ACCEPT_PTRNMATCH6 0x00020000 // en pattern match 2 (R/W) #define ACCEPT_PTRNMATCH7 0x00040000 // en pattern match 3 (R/W) #define IGNORE_ADDR_ULBIT 0x00080000 // ignore U/L bit in dest addr (R/W) #define UNICASTHASH_EN 0x00100000 // en unicast hash table (R/W) #define MCASTHASH_EN 0x00200000 // en multicast hash table (R/W) #define ACCEPT_ALLARP 0x00400000 // en reception of all ARP pkts (R/W) #define PATTRNMATCH_MASK 0x07800000 // pattern match en mask (R/W) #define ACCEPT_PTRNMATCH0 0x00800000 // en pattern match 0 (R/W) #define ACCEPT_PTRNMATCH1 0x01000000 // en pattern match 1 (R/W) #define ACCEPT_PTRNMATCH2 0x02000000 // en pattern match 2 (R/W) #define ACCEPT_PTRNMATCH3 0x04000000 // en pattern match 3 (R/W) #define ACCEPT_PERFECTMATCH 0x08000000 // en perfect match (R/W) #define ACCEPT_ALLUNICAST 0x10000000 // en reception of all unicast (R/W) #define ACCEPT_ALLMCAST 0x20000000 // en reception of all multicast (R/W) #define ACCEPT_ALLBCAST 0x40000000 // en reception of all broadcast (R/W) #define RXFLTR_EN 0x80000000 // ena recevie filtering. // Must be cleared to // set other filter bits. (R/W) //************************************************************** // RFDR - Receive Filter Data Register. //*************************************************************** #define RXFLTRDATA_MASK 0x0000FFFF // Recieve filter data mask (R/W) #define RXFLTRMSKBITS_MASK 0x00030000 // recive filter byte mask bits (R/W) #define RXFLTRMSKBIT_SHIFT 16 // required shift to point to the // mask bits //************************************************************** // MIBC - MIB Control Register //*************************************************************** #define MIBCNTRS_WRN 0x00000001 // Warning Test Indicator (RO) #define MIBCNTRS_FREEZE 0x00000002 // freeze mib counters (WR0) #define MIBCNTRS_CLR 0x00000004 // clear all mib counters (W/R0) #define MIBCNTRS_STRB 0x00000008 // Strobe MIB counter (R/W) - Test Only //************************************************************** // PQCR - Priority Queuing Control Register //*************************************************************** #define TXPRIOQ_EN 0x00000001 // en tx priority queuing (R/W) #define ROTPRIO_EN 0x00000002 // en rotating priority (i.e. 01230) If clear, // fixed priority (3 highest, 0 lowest) (R/W) #define Q0_QUOTA_SHIFT 8 // shift for Q0 quota (when ROTPRIO_EN set) #define Q1_QUOTA_SHIFT 14 // shift for Q1 quota (when ROTPRIO_EN set) #define Q2_QUOTA_SHIFT 20 // shift for Q2 quota (when ROTPRIO_EN set) #define Q3_QUOTA_SHIFT 26 // shift for Q3 quota (when ROTPRIO_EN set) //************************************************************** // VRCR - VLAN Rx Control Reg //*************************************************************** #define VTDEN 0x00000001 // VLAN tag detection enable #define VTREN 0x00000002 // VLAN tag removal enable #define DVTF 0x00000004 // Discard VLAN tagged frame #define DUTF 0x00000008 // Discard untagged frame //************************************************************** // VTCR - VLAN Tx Control Reg //*************************************************************** #define VGTI 0x00000001 // VLAN Global tag insertion #define VPPTI 0x00000002 // VLAN per pkt tag insertion #define VPAD68 0x00000004 // Tag VLAN frames to 68 bytes #define VTCI_MASK 0x0000FFFF // tag mask #define VTCI_SHIFT 16 // shift for tag contol field //************************************************************** // PHY Registers //*************************************************************** // MII Base register offsets #define MII_BMCR 0x00 #define MII_BMSR 0x01 #define MII_PHYIDR1 0x02 #define MII_PHYIDR2 0x03 #define MII_ANAR 0x04 #define MII_ANLPAR 0x05 #define MII_ANER 0x06 #define MII_ANNPTR 0x07 // BMCR - Basic Mode Control Register Definitions #define PHY_RESET 0x8000 // Initiate soft reset of PHY #define PHY_LOOPBACK 0x4000 // Put PHY in loopback mode #define FORCE_SPEED_100 0x2000 // Force mode - 100Mbps #define FORCE_SPEED_10 0x0000 // Force mode - 10Mbps #define AUTONEG_ENABLE 0x1000 // Enable Auto-Neg #define PHY_POWERDOWN 0x0800 // Power down the PHY #define ISOLATE_PORT 0x0400 // Isolate this port from the MII #define AUTONEG_RESTART 0x0200 // Restart Auto-Neg #define FORCE_MODE_FD 0x0100 // Force mode - Full duplex #define FORCE_MODE_HD 0x0000 // Force mode - Half duplex #define COLL_TEST 0x0080 // Start Collision test // BMSR - Basic Mode Status Register Definitions #define AUTONEG_COMP 0x0020 // Auto nego process done #define LINK_STATUS 0x0004 // Link Up #define JABBER_DET 0x0002 // Jabber detected // ANAR Definitions. #define NP 0x8000 // Next Page Indication #define ADV_RF 0x2000 // Advertise remote fault detection #define ADV_ASM_DIR 0x0800 // Advertise Asymmetrical Pause #define ADV_PAUSE 0x0400 // Advertise Symmetrical Pause #define ADV_100BASET4 0x0200 // 100BASE-T4 Support #define ADV_100BASET_FD 0x0100 // 100BASE-TX Full Duplex Support #define ADV_100BASET_HD 0x0080 // 100BASE-TX Half Duplex Support #define ADV_10BASET_FD 0x0040 // 10BASE-TX Full Duplex Support #define ADV_10BASET_HD 0x0020 // 10BASE-TX Half Duplex Support #define PSB 0x0001 // Protocol Selection - 802.3u // PHYSTS Definitions - Some uncommon bits are not populated #define POL_STS 0x1000 // Set when Inverted polarity is detected #define INT_STS 0x0080 // Set when an internal interrupt is pending #define RF_STS 0x0040 // Set when remote fault condition is // detected #define JABBER_STS 0x0020 // Set when Jabber detected on line #define AUTONEG_DONE_STS 0x0010 // Set when Auto-Neg is complete #define LOOPBACK_STS 0x0008 // Set when PHY is in loopback mode #define DUPLEX_FULL_STS 0x0004 // Set for Full duplex, reset for half #define SPEED_10_STS 0x0002 // Set for 10Mbps, reset for 100Mbps #define LINK_STS 0x0001 // Set when valid link is established // MICR Definitions #define PHY_INT 0x0002 // Propagate PHY intr to MAC #define TINT 0x0001 // Indicate PHY to generate test intr // MISR Definitions #define MSK_LINK 0x4000 // Mask Link interrupt #define MSK_ANC 0x0800 // Mask Auto-Neg done interrupt #endif // _MPLREGS_H DP8381X-Linux-Ver-1.6/Mpl/Public/0000777000000000000000000000000010430230150014622 5ustar rootrootDP8381X-Linux-Ver-1.6/Mpl/Public/mpltaskstat.h0000444000000000000000000000101310430225772017345 0ustar rootroot //****************************************************************************** // // MPLTASKSTAT.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Statistics Offload Task Module definitions and exports // // MPL clients should not include this file directly, instead include // mplclient.h //****************************************************************************** // #ifndef _MPLTASKSTAT_H_ #define _MPLTASKSTAT_H_ #endif // _MPLTASKSTAT_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/oai_template.h0000444000000000000000000002031710430225772017451 0ustar rootroot //***************************************************************************** // // OAI.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This header file contains OS-specific services, data-type definitions, // etc. required by MPL. This file must be customized for each OS/Platform // and re-named OAI.H. A version of this file will typically be created // for each platform and exist in the NSM driver's source directory. // //***************************************************************************** #ifndef _OAI_H_ #define _OAI_H_ //******************************** MPL General Options ************************ // Modify the following to set the desire MPL options //***************************************************************************** // On Big endian machines, uncomment the following line or define it via // the compiler command line //#define MPL_BIG_ENDIAN //**************************** END OF MPL General Options ********************* //******************************** MPL Board Options ************************ // Modify the following to set options based on board design //***************************************************************************** // On MacPhyter boards *without* a EEPROM on them disable the below //#define MPL_NO_EEPROM // On MacPhyter boards that use an EXTERNAL Phy disable the below //#define MPL_EXTERNAL_PHY //**************************** END OF MPL Board Options ********************* //******************************** MPL Diag Mode ****************************** // Modify the following to enable MPL Diagnostics Mode //***************************************************************************** // Uncomment to enable Diag mode //#define MPL_DIAG_MODE //******************************** MPL Task Offload *************************** // Modify the following to define MPL task offload behavior //***************************************************************************** // Uncomment to enable statistics collection task //#define MPL_TASK_STAT // Uncomment to enable VLAN offload task //#define MPL_TASK_VLAN // Uncomment to enable multicast filtering task //#define MPL_TASK_MCAST // Uncomment to enable checksum offload task //#define MPL_TASK_STAT //**************************** END OF MPL Task Offload Options **************** //******************** MPL COMPILER INDEPENDENT DATA TYPES ******************** // Modify the following to define MPL data types in terms of native // compiler data types. //***************************************************************************** // Note: On platforms where the natural integer size is less then 32-bits // in size (eg 16-bit platforms), NS_UINT and NS_SINT must be defined as a // data type no less then 32-bits in size. typedef unsigned int NS_UINT; typedef int NS_SINT; // Fixed width data types/pointers typedef unsigned char NS_CHAR; typedef unsigned char NS_UINT8; typedef char NS_SINT8; typedef unsigned short NS_UINT16; typedef short NS_SINT16; typedef unsigned long NS_UINT32; typedef long NS_SINT32; // Abstract data type for physical address references typedef unsigned int NS_ADDR; //**************** END OF MPL COMPILER INDEPENDENT DATA TYPES ***************** // Defines the maximum number of physical adapters supported by MPL. // Customize this value appropriate to the environment. #define MPL_MAX_ADAPTERS 8 //******************* OAI DATA DECLARATIONS (DO NOT MODIFY) ******************* //********************************************************************** // Function parameter annotation macros. //********************************************************************** #ifndef IN #define IN #endif // IN #ifndef OUT #define OUT #endif // OUT // Void types typedef void NS_VOID; // Boolean data type typedef NS_UINT NS_BOOLEAN; #define NS_TRUE 1 #define NS_FALSE 0 // Handle structure for returning module opaque fields typedef NS_UINT MPL_HANDLE; // timer callback function pointer (see OaixxxTimer functions) typedef NS_VOID (MPL_TIMERCALLBACK)(NS_VOID *pTimerArg); // Mac address typedef NS_UINT8 *MPL_MAC_ADDR; // handle for DMA region (see OaiAlloc/FreeDmaRegion) typedef struct _MPL_MEM_REGION { NS_VOID *pAddr; // aligned (as requested in alloc request) region ptr, logical NS_ADDR phyAddr; // aligned (as requested in alloc request) region ptr, physical } MPL_MEM_REGION; //************************** OAI FUNCTION PROTOTYPES ************************** // The following are function declarations of OS services required by MPL. // Each function must be implemented in using native OS API's and linked // with MPL //***************************************************************************** #if defined(__cplusplus) extern "C" { #endif //+++++ PCI Memory Mapped I/O access Functions //Read from PCI memory-mapped IO location 'pAddr'. NS_UINT32 OaiIoRead32( IN NS_VOID *pClientDevHndl, IN NS_UINT32 volatile *pAddr ); NS_UINT16 OaiIoRead16( IN NS_VOID *pClientDevHndl, IN NS_UINT16 volatile *pAddr ); NS_UINT8 OaiIoRead8( IN NS_VOID *pClientDevHndl, IN NS_UINT8 volatile *pAddr ); //Write to PCI memory-mapped IO location 'pAddr'. NS_VOID OaiIoWrite32( IN NS_VOID *pClientDevHndl, IN NS_UINT32 volatile *pAddr, IN NS_UINT32 writeData ); NS_VOID OaiIoWrite16( IN NS_VOID *pClientDevHndl, IN NS_UINT16 volatile *pAddr, IN NS_UINT16 writeData ); NS_VOID OaiIoWrite8( IN NS_VOID *pClientDevHndl, IN NS_UINT8 volatile *pAddr, IN NS_UINT8 writeData ); //+++++ Host Memory Functions //Allocate/free a region in host memory suitable for DMA NS_BOOLEAN OaiAllocDmaRegion( IN NS_VOID *pClientDevHndl, IN NS_UINT size, IN NS_UINT byteAlignment, OUT MPL_MEM_REGION **pRgnHndl ); NS_VOID OaiFreeDmaRegion( IN NS_VOID *pClientDevHndl, IN MPL_MEM_REGION *pRgnHndl ); //Allocate/free general purpose host memory NS_VOID * OaiMalloc( IN NS_UINT regionSize ); NS_VOID OaiFree( IN NS_UINT regionSize, IN NS_VOID *startAddrLogical ); //Copy/zero host memory NS_VOID OaiMemCopy( IN NS_VOID *dest, IN NS_VOID *src, IN NS_UINT len ); NS_VOID OaiZeroMem( IN NS_VOID *pMemRegion, IN NS_UINT regionSize ); //+++++ Timer Functions //Delay program execution for 'sleepInterval' usec NS_VOID OaiSleep( IN NS_UINT sleepInterval ); //Return 10ms tick count NS_UINT32 OaiGetTickCount(NS_VOID); //Allocate/free/start/cancel periodic timer w/ callback 'pTimerFunction' NS_BOOLEAN OaiCreateTimer( IN MPL_TIMERCALLBACK pTimerFunction, IN NS_VOID *pTimerArg, OUT NS_VOID **pTimerHandle ); NS_VOID OaiDeleteTimer( IN NS_VOID *pTimerHandle ); NS_VOID OaiStartTimer( IN NS_VOID *pTimerHandle, IN NS_UINT delayInMsec ); NS_BOOLEAN OaiCancelTimer( IN NS_VOID *pTimerHandle ); //+++++ Resource Synchronization Functions //Initialize/free/acquire/release multiprocessor-safe synchronization lock NS_BOOLEAN OaiCreateLock( OUT NS_VOID **pLockHandle ); NS_VOID OaiDestroyLock( IN NS_VOID *pLockHandle ); NS_VOID OaiAcquireLock( IN NS_VOID *pLockHandle ); NS_VOID OaiReleaseLock( IN NS_VOID *pLockHandle ); #if defined(__cplusplus) } #endif //+++++ Debug Output Abstractions - Define appropriate to the environment. // OAI_DEBUG_MSG takes a base string parameter, and zero or more optional // insertion parameters. #define OAI_DEBUG_MSG define_a_debug_trace_function_here // OAI_DEBUG_BREAK breaks into the debugger. #define OAI_DEBUG_BREAK define_a_debug_break_function_here //********************** END OF OAI FUNCTION PROTOTYPES *********************** #endif // _OAI_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mpldebug.h0000444000000000000000000001506510430225772016611 0ustar rootroot //********************************************************************** // // MPLDEBUG.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Debug related definitions // //********************************************************************** #ifndef _MPLDEBUG_H_ #define _MPLDEBUG_H_ //********************************************************************** // Debug Definitions. //********************************************************************** // Debug Zones - Add more if needed // Enable all zones #define DZONE_ALL 0xFFFFFFFF // Mpl Zones #define DZONE_MPL_INIT_DOWN 0x00000001 #define DZONE_MPL_TRANS 0x00000002 #define DZONE_MPL_RECV 0x00000004 #define DZONE_MPL_INTR 0x00000008 #define DZONE_MPL_LINK 0x00000010 #define DZONE_MPL_PWR 0x00000020 #define DZONE_MPL_DIAG 0x00000040 #define DZONE_MPL_MISC 0x00000080 #define DZONE_MPL_TASK_RX_FILTER 0x00000100 #define DZONE_MPL_TASK_VLAN 0x00000200 // Add more zones here if needed // The default debug zones to be enabled for function path // tracing. #define DZONE_ENABLED_PATH (DZONE_MPL_INIT_DOWN | \ DZONE_MPL_TRANS | \ DZONE_MPL_RECV | \ DZONE_MPL_INTR | \ DZONE_MPL_LINK | \ DZONE_MPL_PWR | \ DZONE_MPL_DIAG | \ DZONE_MPL_MISC | \ DZONE_MPL_TASK_RX_FILTER) // The default debug zones to be enabled for verbose message // display and asserts. #define DZONE_ENABLED_MSG_CHECKS (DZONE_MPL_INIT_DOWN | \ DZONE_MPL_TRANS | \ DZONE_MPL_RECV | \ DZONE_MPL_INTR | \ DZONE_MPL_LINK | \ DZONE_MPL_PWR | \ DZONE_MPL_DIAG | \ DZONE_MPL_MISC | \ DZONE_MPL_TASK_RX_FILTER) //********** MPL_CHECKED_BUILD *********** #ifdef MPL_CHECKED_BUILD extern NS_UINT MplDebugZonePathTracing; extern NS_UINT MplDebugZoneMsgAndChecks; // Debug Macros #define MPL_TRACE(message) { OAI_DEBUG_MSG message; } #define MPL_BREAK() { OAI_DEBUG_BREAK(); } #define MPL_TRACEBREAK( message) \ { \ MPL_TRACE (message); \ MPL_BREAK(); \ } #define MPL_ASSERT( logicalExpression) \ { \ if (!(logicalExpression)) \ { \ MPL_TRACE(("MPL Assert: " #logicalExpression "\nline %d, %s\n",\ (NS_UINT)__LINE__, (NS_PUINT8)__FILE__)); \ MPL_BREAK(); \ } \ } // Conditional trace outs #define MPL_CTRACE( zone, message) \ { \ if ((zone) & MplDebugZoneMsgAndChecks) \ MPL_TRACE(message); \ } // Conditional Function Enter #define MPL_CENTER( zone, functionName) \ { \ if ((zone) & MplDebugZonePathTracing) \ MPL_TRACE((">>> Enter " #functionName "()\n")); \ } // Conditional Function Exit #define MPL_CEXIT( zone, functionName) \ { \ if ((zone) & MplDebugZonePathTracing) \ MPL_TRACE(("<<< Exit " #functionName"() Line : %d \n", \ (NS_UINT)__LINE__)); \ } // Conditional break #define MPL_CBREAK( zone) \ { \ if ((zone) & MplDebugZoneMsgAndChecks) \ MPL_BREAK(); \ } // Conditional trace-break #define MPL_CTRACEBREAK( zone, message) \ { \ if ((zone) & MplDebugZoneMsgAndChecks) \ MPL_TRACEBREAK(message); \ } // Conditional assert #define MPL_CASSERT( zone, logicalExpression) \ { \ if ((zone) & MplDebugZoneMsgAndChecks) \ MPL_ASSERT(logicalExpression); \ } //********** RETAIL BUILD *********** #else // !MPL_CHECKED_BUILD // These do nothing in retail builds. #define MPL_TRACE(message) #define MPL_BREAK() #define MPL_TRACEBREAK(message) #define MPL_ASSERT(logicalExpression) #define MPL_CTRACE( zone, message) #define MPL_CENTER( zone, functionName) #define MPL_CEXIT( zone, functionName) #define MPL_CBREAK( zone) #define MPL_CTRACEBREAK( zone, message) #define MPL_CASSERT( zone, logicalExpression) #endif // MPL_CHECKED_BUILD // Exposed public debug functions. These are defined for retail and checked // builds, however in retail builds they don't do anything. #if defined(__cplusplus) extern "C" { #endif NS_VOID MplDebDumpBuffer( IN NS_UINT8 *buffer, IN NS_UINT length); NS_VOID MplDebDumpWords( IN NS_UINT32 *buffer, IN NS_UINT length); NS_VOID MplDebEnablePathTracing( IN NS_UINT zones); NS_VOID MplDebEnableMsgsAndChecks( IN NS_UINT zones); NS_VOID MplDebDumpAdapterRegisters( IN NS_VOID *pMplContext); #if defined(__cplusplus) } #endif #endif // _MPLDEBUG_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mpltaskrxfilter.h0000444000000000000000000002110510430225772020235 0ustar rootroot //****************************************************************************** // // MPLTASKRXFILTER.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL receive filtering Offload Task Module. // // This file declares the APIs for // o Filtering of Receive packets based on // - Dest. Multicast Address // - Dest. Unicast Address // - TBD // // MPL clients should not include this file directly, instead include // mplclient.h and defining MPL //****************************************************************************** #ifndef _MPLTASKRXFILTER_H_ #define _MPLTASKRXFILTER_H_ #if defined(__cplusplus) extern "C" { #endif //***************************************************************************** // MplTaskFilterCfg // Configure the receive filtering module // (Currently Multicast and Unicast Destination Address Filtering) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // enableFlag // Set to NS_TRUE to enable the reception of multicast frames and // filtering, NS_FALSE to disable. // // Return Value // NS_STATUS_SUCCESS // The task offload was successfully enabled or disabled // NS_STATUS_NOT_SUPPORTED // This offload task or selected configuration option is not // supported by MPL. // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // //***************************************************************************** MPL_STATUS MplTaskFilterCfg( IN NS_VOID *pMplHandle, IN NS_BOOLEAN enableFlag ); //***************************************************************************** // MplTaskFilterReload // Reload receive hash filters from previous defined listen list // Useful for if a Mac Reset is done and the listen lists are to be // restored to their previous saved values // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The listen list was successfully reloaded // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterReload( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplTaskFilterMcastAddAddr // Add a new multicast address to the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be added to the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully added // NS_STATUS_RESOURCES // Unable to allocate required resources // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // //***************************************************************************** MPL_STATUS MplTaskFilterMcastAddAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterMcastDeleteAddr // Delete a multicast address from the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be deleted from the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully deleted // NS_STATUS_FAILURE // Could not find the address to delete or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastDeleteAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterMcastCheckAddr // Check if a multicast address is present in the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Multicast addr to be checked in the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was found in the receive accept list // NS_STATUS_FAILURE // Could not find the address or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastCheckAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterMcastClearList // Clear the multicast clear list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The list was successfully cleared // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterMcastClearList( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplTaskFilterUcastAddAddr // Add a new unicast address to the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be added to the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully added // NS_STATUS_RESOURCES // Unable to allocate required resources // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // An invalid parameter was detected. // //***************************************************************************** MPL_STATUS MplTaskFilterUcastAddAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterUcastDeleteAddr // Delete a unicast address from the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be deleted from the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was successfully deleted // NS_STATUS_FAILURE // Could not find the address to delete or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastDeleteAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterUcastCheckAddr // Check if a unicast address is present in the receive accept list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pAddr // Unicast addr to be checked in the filter list. // // Return Value // NS_STATUS_SUCCESS // The address was found in the receive accept list // NS_STATUS_FAILURE // Could not find the address or feature not enabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastCheckAddr( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pAddr ); //***************************************************************************** // MplTaskFilterUcastClearList // Clear the unicast clear list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The list was successfully cleared // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskFilterUcastClearList( IN NS_VOID *pMplHandle ); #if defined(__cplusplus) } #endif #endif //_MPLTASKRXFILTER_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mplregdefaults.h0000444000000000000000000000556510430225772020034 0ustar rootroot //********************************************************************** // // MPLREGDEFAULTS.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // Defaults for all the configuration related registers // // Note: A NSM module implementor can edit the contents of this file // assuming he/she know what they are doing. MPL will set bring up // the device with the configuration as defined here!! // //********************************************************************** #ifndef _MPLREGDEFAULTS_H_ #define _MPLREGDEFAULTS_H_ // EEPROM_MASK define the bits that are loaded from the EEPROM // Normally these bits are loaded as is and the defaults don't mess // around with these. If you have a need to modify the EEPROM defaults // then change the XXX_EEPROM_MASK bit definitions // CFG Register Defaults - Includes MP1/2/3 #define CFG_EEPROM_MASK 0x03F1E801 #ifndef MPL_EXTERNAL_PHY #define CFG_DEFAULT (ABORT_ON_EXCESSIVE_DEF | PINT_ACEN) #else #define CFG_DEFAULT (ABORT_ON_EXCESSIVE_DEF | PINT_ACEN | EXT_PHY) #endif // MPL_EXTERNAL_PHY // IMR Register Defaults - FM: Evaluate #define IMR_DEFAULT (RXOK | RXERR | RXOVERUN | RXIDLE | \ TXOK | TXERR | TXUNDERRUN | \ MIBSTATS | PHYSTSCHANGE | SW_INT | \ HIORDER_INT | RXSTSFIFO_OVRN | \ PCI_TARGABORT | PCI_MSTRABORT | \ PCI_SERR | PCI_PARERR) // IER Register Defaults #define IER_DEFAULT 0x0 // IHR Register Defaults #define HOLD_TIME 0x0a //In 100us - Default set to 1msec #define IHR_DEFAULT (HOLD_TIME) // TXCFG Register Defaults #define TXFILLTHRESH 16 // 512 Bytes (In 32byte units), never be set to 0x0 #define TXDRAINTHRESH 2 // 64 Bytes (In 32byte units), never be set to 0x0 #define TXCFG_DEFAULT (EXC_COLN_RETRY | AUTOTXPAD_EN | MXDMA256 | \ (TXFILLTHRESH << TXFILL_SHIFT) | TXDRAINTHRESH) // RXCFG Register Defaults #define RXDRAINTHRESH 16 // 128 Bytes (In 8byte units) // FM: Disable? DMA_USECACHESIZ_EN #define RXCFG_DEFAULT (MXDMA256 | ACCEPT_CRCALIGNERR | (RXDRAINTHRESH << RXDRAIN_SHIFT)) // GPIO Register Defaults #define GPIOR_EEPROM_MASK 0x000003FF #define GPIOR_DEFAULT 0x0 // CCSR Register Defaults #define CCSR_EEPROM_MASK 0x00000100 #define CCSR_DEFAULT (PMESTS) //Clears olders status // WCSR Register Defaults #define WCSR_EEPROM_MASK 0x0000061E #define WCSR_DEFAULT 0x0 // RFCR Register Defaults #define RFCR_EEPROM_MASK 0xF8500000 #define RFCR_DEFAULT (ACCEPT_PERFECTMATCH | ACCEPT_ALLBCAST | RXFLTR_EN) // PQCR Register Defaults // Good place to define quota defaults if you need it #define PQCR_DEFAULT 0x0 // VRCR Register Defaults #define VRCR_DEFAULT 0x0 // VTCR Register Defaults #define VTCR_DEFAULT (VPAD68) #endif // _MPLREGDEFAULTS_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mplclient.h0000444000000000000000000016527710430225772017014 0ustar rootroot //********************************************************************** // // MPLCLIENT.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This is the main public include file for MPL client modules (Eg. NSM) // It is NOT meant to be used internally by MPL. // // Note: This file includes all relavent MPL include files. // Therefore clients need only include this one file to obtain // all needed definitions to use the MPL interfaces. // //********************************************************************** #ifndef _MPLCLIENT_H_ #define _MPLCLIENT_H_ // Include platform customized data type definitions. #include // Include common data structures between MPL and clients #include // Include Debug #include // Include MPL diagnostics APIs #ifdef MPL_DIAG_MODE #endif //MPL_DIAG_MODE // Include all task offload related definitions #ifdef MPL_TASK_STAT #include #endif //MPL_TASK_STAT #ifdef MPL_TASK_VLAN #include #endif //MPL_TASK_VLAN #ifdef MPL_TASK_CHKSUM #include #endif //MPL_TASK_CHKSUM #ifdef MPL_TASK_RECEIVE_FILTER #include #endif // MPL_TASK_RECEIVE_FILTER //************************* MPL CORE FUNCTION PROTOTYPES ********************** // MPL basic device operation (initialization, tx/rx, configuration) APIs //***************************************************************************** // MPL Operational Mode typedef enum { MPL_MODE_NORMAL, MPL_MODE_MONITOR, MPL_MODE_LOAD_ONLY } MPL_MODE; // Transmit Capabilities typedef struct _MPL_CAPS_TRANSMIT { NS_UINT8 priorityQCnt; NS_UINT16 fifoSize; NS_UINT16 maxDma; NS_UINT16 minDrain; NS_UINT16 minFill; NS_UINT16 maxPacketSize; NS_UINT txFlags; // None Defined Yet } MPL_CAPS_TRANSMIT; // Receive Capabilities typedef struct _MPL_CAPS_RECEIVE { NS_UINT8 priorityQCnt; NS_UINT16 fifoSize; NS_UINT16 maxDma; NS_UINT16 minDrain; NS_UINT16 maxPacketSize; NS_UINT rxFlags; // None Defined Yet } MPL_CAPS_RECEIVE; // Interrupt Capabilities typedef struct _MPL_CAPS_INTERRUPT { NS_UINT16 maxTimerHold; NS_UINT16 maxTransmitHold; NS_UINT16 maxReceiveHold; NS_UINT intrFlags; // None Defined Yet } MPL_CAPS_INTERRUPT; // Link Capabilities typedef struct _MPL_CAPS_LINK { NS_UINT linkFlags; #define MPL_LINK_PAUSE_RECEIVE 0x00000001 // Can rx pause reqs, but not tx #define MPL_LINK_PAUSE_TRANSMIT 0x00000002 // Can tx pause reqs, but not rx } MPL_CAPS_LINK; // Wol Capabilities typedef struct _MPL_CAPS_WOL { NS_UINT8 maxPatterns; NS_UINT16 maxPatternSize; NS_UINT wolFlags; // None Defined Yet } MPL_CAPS_WOL; // Offload Task Capabilities typedef struct _MPL_CAPS_TASK { // Statistics Task struct { NS_BOOLEAN supported; NS_UINT statFlags; #define MPL_TASK_STAT_ADV 0x00000001 } stat; // Checksum Task struct { NS_BOOLEAN supported; NS_UINT chkSumFlags; #define MPL_TASK_CHKSUM_GLOBAL 0x00000001 #define MPL_TASK_CHKSUM_PERPACKET 0x00000002 #define MPL_TASK_CHKSUM_REJECT_IP 0x00000004 #define MPL_TASK_CHKSUM_REJECT_UDP 0x00000008 #define MPL_TASK_CHKSUM_REJECT_TCP 0x00000010 } chkSum; // VLAN Task struct { NS_BOOLEAN supported; NS_UINT16 maxFilterEntries; NS_UINT vlanFlags; #define MPL_TASK_VLAN_DETECT_TAGS 0x00000001 //Rx Only - Reports Tag data #define MPL_TASK_VLAN_REMOVE_TAGS 0x00000002 #define MPL_TASK_VLAN_DISCARD_TAGGED 0x00000004 #define MPL_TASK_VLAN_DISCARD_UNTAGGED 0x00000008 #define MPL_TASK_VLAN_PERPACKET 0x00000010 //Tx Only #define MPL_TASK_VLAN_FILTER 0x00000020 // Only when maxFilterEntries > 0x0 } vlan; // Receive Filter Task struct { NS_BOOLEAN supported; NS_UINT16 maxFilterEntries; NS_UINT rxFilterFlags; #define MPL_TASK_FILTER_MCAST 0x00000001 // Support Multicast Listen List #define MPL_TASK_FILTER_UCAST 0x00000002 // Support Unicast Listen List #define MPL_TASK_FILTER_PERFECT 0x00000004 // Support Perfect Filtering } rxFilter; } MPL_CAPS_TASK; // Device Capabilities Structure typedef struct _MPL_CAPS { MPL_CAPS_TRANSMIT txCaps; MPL_CAPS_RECEIVE rxCaps; MPL_CAPS_INTERRUPT intrCaps; MPL_CAPS_LINK linkCaps; MPL_CAPS_WOL wolCaps; MPL_CAPS_TASK taskCaps; } MPL_CAPS; // Transmit Engine Configuration Structure typedef struct MPL_TRANSMIT_CFG { NS_UINT8 priorityQueueCnt; #define MPL_TRANSMIT_MAX_PRIORITYQ_CNT 4 NS_UINT descCnt[MPL_TRANSMIT_MAX_PRIORITYQ_CNT]; NS_UINT fillThreshold; NS_UINT drainThreshold; NS_UINT maxDmaBurst; NS_UINT maxIndications; NS_UINT cfgFlags; #define MPL_TRANSMIT_CFG_FIFO 0x00000001 #define MPL_TRANSMIT_CFG_QUEUES 0x00000002 #define MPL_TRANSMIT_CFG_AUTO_PAD 0x00000004 #define MPL_TRANSMIT_CFG_QUEUE_RR 0x00000008 // En round-robin algo btn queues } MPL_TRANSMIT_CFG; // Receive Engine Configuration Structure typedef struct MPL_RECEIVE_CFG { NS_UINT8 priorityQueueCnt; #define MPL_RECEIVE_MAX_PRIORITYQ_CNT 1 NS_UINT descCnt[MPL_RECEIVE_MAX_PRIORITYQ_CNT]; NS_UINT drainThreshold; NS_UINT maxDmaBurst; NS_UINT maxIndications; NS_UINT cfgFlags; #define MPL_RECEIVE_CFG_FIFO 0x00000001 #define MPL_RECEIVE_CFG_QUEUES 0x00000002 } MPL_RECEIVE_CFG; // Link Negotiation Mode typedef enum { MPL_LINK_MODE_AUTO, MPL_LINK_MODE_FORCED } MPL_LINK_NEGOTIATION; // Link Speed typedef enum { MPL_LINK_SPEED_HUNDREDMBPS, MPL_LINK_SPEED_TENMBPS } MPL_LINK_SPEED; // Link Duplex Type typedef enum { MPL_LINK_DUPLEX_FULL, MPL_LINK_DUPLEX_HALF } MPL_LINK_DUPLEX; // Link Configuration Structure typedef struct _MPL_LINK_CFG { MPL_LINK_NEGOTIATION mode; MPL_LINK_SPEED speed; MPL_LINK_DUPLEX duplex; #define MPL_LINK_PAUSE_SYMMETRICAL \ (MPL_LINK_PAUSE_TRANSMIT | MPL_LINK_PAUSE_RECEIVE) #define MPL_LINK_PAUSE_NONE 0x0 NS_UINT pauseType; NS_UINT pauseCtr; NS_UINT pauseRxDALO; NS_UINT pauseRxDAHI; NS_UINT pauseRxSTLO; NS_UINT pauseRxSTHI; } MPL_LINK_CFG; // Link Status Structure typedef enum _MPL_LINK_STATUS { MPL_LINK_STATUS_NONE, MPL_LINK_STATUS_DOWN, MPL_LINK_STATUS_ACTIVE, MPL_LINK_STATUS_UP } MPL_LINK_STATUS; // Device Ids typedef enum { MPL_DEVICE_ID_UNKNOWN, MPL_DEVICE_ID_DP83815, MPL_DEVICE_ID_DP83816, MPL_DEVICE_ID_DP83818 } MPL_DEVICE_ID; // MPL Packet Fragment Descriptor typedef struct _MPL_PKT_FRAG { struct _MPL_PKT_FRAG *pNextFrag; NS_UINT fragSize; NS_ADDR physAddr; NS_UINT8 *pAddr; NS_VOID *pPacketHndl; NS_VOID *pMplPrivate; NS_VOID *pNsmPrivate; } MPL_PKT_FRAG; // MPL Packet Tx Out-Of-Band data - MPL client should not modify this directly, // instead Call MplSetPacketXXX functions typedef struct _MPL_PKT_TRANSMIT_OOB { NS_UINT32 cmdSts; NS_UINT32 extCtl; // Extended Control NS_UINT8 pQueue; } MPL_PKT_TRANSMIT_OOB; // MPL Packet Rx Out-Of-Band data - MPL client should not modify this directly, // instead Call MplQueryPacketXXX functions typedef struct _MPL_PKT_RECEIVE_OOB { NS_UINT32 cmdSts; NS_UINT32 extSts; // Extended Status } MPL_PKT_RECEIVE_OOB; // MPL Packet Descriptor typedef struct _MPL_PKT { struct _MPL_PKT *pNextPacket; NS_UINT fragCount; MPL_PKT_FRAG *pFragHead; union { MPL_PKT_TRANSMIT_OOB tx; MPL_PKT_RECEIVE_OOB rx; } OOB; #define txOOB OOB.tx #define rxOOB OOB.rx MPL_STATUS packetStatus; NS_UINT packetSize; NS_VOID *pMplPrivate; NS_VOID *pNsmPrivate; } MPL_PKT; // Transmit Done Indication (MPL to NSM) typedef struct _MPL_TRANSMIT_DONE { NS_VOID *pNsmPrivate; MPL_STATUS packetStatus; NS_UINT32 cmdSts; } MPL_TRANSMIT_DONE; // Power State typedef enum _MPL_POWER_STATE { MPL_POWER_STATE_LOW, MPL_POWER_STATE_HIGH } MPL_POWER_STATE; // WoL Pattern Container typedef struct _MPL_WOL_PATTERN { NS_UINT patternSize; NS_UINT8 *pPattern; NS_UINT maskSize; NS_UINT8 *pMask; } MPL_WOL_PATTERN; //+++++ Device Initialization and Shutdown APIs //############################################ #if defined(__cplusplus) extern "C" { #endif //***************************************************************************** // MplInitialize // Allocate and initialize a MPL context fot the device. // // Parameters // pNsmHandle // NSM device handle for the device hardware. This handle is retained // by MPL and passed in to subsequent calls to the NSM. // pBaseAddr // The logical base address for the device. // diagEnable // A NS_TRUE notifies MPL to go into a diagnostic mode where MPL lets // the diag application to control the adapter, MPL now handles only // Txd and RXD ring operation. For most production drivers this should // be passed as NS_FALSE. // pMplHandle // MPL handle for the device’s context. The NSM must retain this handle // and pass it for all subsequent MPL calls. // // Return Value // NS_STATUS_SUCCESS // The device was successfully initialized and the MPL context is // returned // NS_STATUS_INVALID_PARAM // An invalid parameter value was detected // NS_STATUS_RESOURCES // Unable to initialize a context (lack of system resources) // NS_STATUS_HARDWARE_FAILURE // Unable to initialize a context (unexpected h/w error) // or failed to detect MacPhyter device // //***************************************************************************** MPL_STATUS MplInitialize ( IN NS_VOID *pNsmHandle, IN NS_VOID *pBaseAddr, IN NS_BOOLEAN diagEnable, OUT NS_VOID **pMplHandle ); //***************************************************************************** // MplOpen // Opens the device for network operation. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // The device was successfully opened and is ready for network operation // NS_STATUS_INVALID_PARM // An invalid parameter value was detected or this function is called // prior to MplInitialize // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplOpen ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplClose // Closes the network device, disabling network transmission/reception and // interrupts. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The device was successfully closed // NS_STATUS_INVALID_PARM // An invalid parameter value was detected or this function is called // prior to MplInitialize or MplOpen // //***************************************************************************** MPL_STATUS MplClose ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplUnload // Shuts down the device hardware and frees all allocated resources claimed // by MplInitialize. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // MPL was successfully unloaded and all resources released. // NS_STATUS_INVALID_PARM // An invalid parameter value was detected or this function is called // prior to MplInitialize // //***************************************************************************** MPL_STATUS MplUnload ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplMacReset // Resets the network device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The network device was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplMacReset ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplGetCaps // Returns the capabilities of the device and the MPL implementation. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pMplCaps // Pointer to a caller allocated MPL_CAPS structure in which the // capabilities of the device and MPL is returned // // Return Value // NS_STATUS_SUCCESS // The capabilities were successfully returned // //***************************************************************************** MPL_STATUS MplGetCaps ( IN NS_VOID *pMplHandle, OUT MPL_CAPS *pMplCaps ); //***************************************************************************** // MplCfgMTU // Configures the maximum packet size supported by MPL // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // mtu // The maximum packet size queued for transmission or reception // // Return Value // NS_STATUS_SUCCESS // The requested MTU was successfully configured on the device. // NS_STATUS_INVALID_PARM // The size is greater than the maximum supported on the device. // //***************************************************************************** MPL_STATUS MplCfgMTU ( IN NS_VOID *pMplHandle, IN NS_UINT mtu ); //+++++ Transmit Engine APIs //########################## //***************************************************************************** // MplTransmitCfg // Configures the transmit engine on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pCfgTransmit // Pointer to a caller allocated MPL_TRANSMIT_CFG structure with // configuration values for the transmit engine // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_INVALID_PARM // An invalid parameter value was detected // NS_STATUS_RESOURCES // Failed to allocate required resources // //***************************************************************************** MPL_STATUS MplTransmitCfg ( IN NS_VOID *pMplHandle, IN MPL_TRANSMIT_CFG *pCfgTransmit ); //***************************************************************************** // MplTransmitGetFreeDesc // Returns the total free transmit descriptors currently available. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pQueue // Queue (1,2...max tx queues) from which the free count is desired // pTxdCnt // Pointer to a caller allocated fields in which the count of free // transmit descriptors is returned // // Return Value // NS_STATUS_SUCCESS // The count was successfully returned. // NS_STATUS_INVALID_PARM // The priority queue count is invalid // //***************************************************************************** MPL_STATUS MplTransmitGetFreeDesc ( IN NS_VOID *pMplHandle, IN NS_UINT8 pQueue, OUT NS_UINT *pTxdCnt ); //***************************************************************************** // MplTransmit // Queues up one or more packets for transmission by the device. // NOTE: This function is non-reentrant with respect to itself, // MplTransmitReset and MplTransmitDone // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pktCount // The count of packets being queued for transmission // pPackets // Pointer to a list of MPL_PKT structures due for transmission // // Return Value // NS_STATUS_SUCCESS // All packets were successfully queued up for transmission // NS_STATUS_FAILURE // One or more of the packets where unacceptable for transmission // Per packet status (pPacket->packetStatus) is one of // NS_STATUS_INVALID_PARM // The priority queue count is invalid // NS_STATUS_RESOURCES // Failed to allocate the required resources (Txds) // //***************************************************************************** MPL_STATUS MplTransmit ( IN NS_VOID *pMplHandle, IN NS_UINT pktCount, IN MPL_PKT *pPackets ); //***************************************************************************** // MplTrasmitDone // Processes transmit engine related events. // NOTE: This function is non-reentrant with respect to itself, // MplTransmitReset and MplTransmit // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum transmit engine related events (e.g. transmit complete) // that MPL should process before returning back to the caller. // // Return Value // NS_STATUS_SUCCESS // The transmit event was successfully handled. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplTransmitDone ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents ); //***************************************************************************** // MplTransmitReset // Resets the transmit engine on the device and associated resources. // NOTE: This function is non-reentrant with respect to itself, // MplTransmit and MplTransmitDone // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The transmit engine was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error - No reset done notification from Hw // //***************************************************************************** MPL_STATUS MplTransmitReset ( IN NS_VOID *pMplHandle ); //+++++ Receive Engine APIs //########################## //***************************************************************************** // MplReceiveCfg // Configures the receive engine on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pCfgReceive // Pointer to a caller allocated MPL_RECEIVE_CFG structure with // configuration values for the receive engine // // Return Value // NS_STATUS_SUCCESS // The configurations were successfully applied // NS_STATUS_INVALID_PARM // An invalid parameter value was detected // //***************************************************************************** MPL_STATUS MplReceiveCfg ( IN NS_VOID *pMplHandle, IN MPL_RECEIVE_CFG *pCfgReceive ); //***************************************************************************** // MplReceiveSetFilter // MplReceiveSetFilter enables receive filters on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // filterFlag // Bit-map of receiver filter types that need to be enabled on the // device // Note: This function overwrites all previous filter settings and // sets the device's behavior to that of the filterFlag passed to it. // // Return Value // NS_STATUS_SUCCESS // The filter configurations were successfully applied // NS_STATUS_NOT_SUPPORTED // The device did not support one or more filters // //***************************************************************************** MPL_STATUS MplReceiveSetFilter ( IN NS_VOID *pMplHandle, IN NS_UINT filterFlag ); // MPL Receive Filter Bits #define MPL_RECEIVE_FILTER_ACCEPTALL_BROADCAST 0x00000001 #define MPL_RECEIVE_FILTER_ACCEPTALL_MCAST 0x00000002 #define MPL_RECEIVE_FILTER_ACCEPTALL_UNICAST 0x00000004 #define MPL_RECEIVE_FILTER_ACCEPTALL_ARP 0x00000008 #define MPL_RECEIVE_FILTER_PROMISCUOUS_MODE 0x00000010 #define MPL_RECEIVE_FILTER_DIRECTED_UNICAST 0x00000020 #define MPL_RECEIVE_FILTER_DIRECTED_MCAST 0x00000040 #define MPL_RECEIVE_FILTER_ERROREDPKTS 0x00000080 //***************************************************************************** // MplReceive // Handles the packet reception event and moves the received packet from // the device to the host. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum receive engine related events (e.g. receive complete) // that MPL should process before returning back to the caller. // pBufFragConsumed // A caller supplied pointer variable in which this function returns the // number of buffer fragments that were consumed while processing this // receive pass. // // Return Value // NS_STATUS_SUCCESS // The receive events were successfully processed. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplReceive ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents, OUT NS_UINT *pBufFragConsumed ); //***************************************************************************** // MplReceiveReplenish // Restock the MPL receive engine with fresh buffers for packet reception. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // bufFragCount // Number of buffer fragments being replenished. // pFragList // Pointer to a caller supplied variable of type MPL_PKT_FRAG pointing // to the head node of the buffer fragment list being replenished. // If all the buffer fragments were not consumed by MPL then the // pointer to the first unused fragment is returned back to NSM. // // Return Value // NS_STATUS_SUCCESS // The buffers were successfully replenished. // //***************************************************************************** MPL_STATUS MplReceiveReplenish ( IN NS_VOID *pMplHandle, IN NS_UINT bufFragCount, IN OUT MPL_PKT_FRAG **pFragList ); //***************************************************************************** // MplQueryPacketLength // Returns the size (in bytes) of the data frame within a MPL_PKT structure // // Parameters // pPacket // Pointer to the MPL_PKT structure who data frame length is being // queried. // // Return Value // The total size of the data frame in bytes (could be 0x0 also). // //***************************************************************************** NS_UINT MplQueryPacketLength ( IN MPL_PKT *pPacket ); //***************************************************************************** // MplReceiveReset // Resets the receive engine on the device and associated software // resources. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The receive engine was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error - No reset done notification from Hw // //***************************************************************************** MPL_STATUS MplReceiveReset ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplReceiveGetEmptyDesc // Returns the count of the Rxds that are empty i.e. no attached buffers // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pQueue // Queue (1,2...max tx queues) from which the empty count is desired // pRxdCnt // Pointer to a caller allocated fields in which the count of empty // receive descriptors is returned // // Return Value // NS_STATUS_SUCCESS // The count was successfully returned. // NS_STATUS_INVALID_PARM // The priority queue count is invalid // //***************************************************************************** MPL_STATUS MplReceiveGetEmptyDesc ( IN NS_VOID *pMplHandle, IN NS_UINT8 pQueue, OUT NS_UINT *pRxdCnt ); //+++++ Interrupt Module APIs //########################### //***************************************************************************** // MplInterruptCfg // Configure the interrupt hold-off delay (for interrupt coalescing). // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // delayMSec // Interrupt hold off delay in microseconds // transmitHold // Interrupts hold off based on number of Tx pkts sent // receiveHold // Interrupts hold off based on number of Rx pkts sent // // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully configured // //***************************************************************************** MPL_STATUS MplInterruptCfg ( IN NS_VOID *pMplHandle, IN NS_UINT delayMSec, IN NS_UINT transmitHold, IN NS_UINT receiveHold ); //***************************************************************************** // MplInterruptEnable // Enable the interrupt line on the network device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully enabled // //***************************************************************************** MPL_STATUS MplInterruptEnable ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptDisable // Disable the interrupt line on the network device. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // Return Value // NS_STATUS_SUCCESS // Interrupts were successfully disabled // //***************************************************************************** MPL_STATUS MplInterruptDisable ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptCheck // Checks for and clears pending interrupt conditions on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // pIrqsPresent // A caller supplied variable in which the current interrupting // conditions are noted. // // Return Value // NS_STATUS_SUCCESS // The current interrupting conditions were successfully read from the // device and pending events do exist. // NS_STATUS_FAILURE // Interrupts are currently disabled, so no interrupt conditions exist. // or the mask bits and status bits don't match // //***************************************************************************** MPL_STATUS MplInterruptCheck ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptCheckTransmit // Checks for the presence of transmit engine related interrupt events. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // Pending transmit related events exist on the device // NS_STATUS_FAILURE // No transmit related events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckTransmit ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptCheckReceive // Checks for the presence of receive engine related interrupt events. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // Pending receive related events exist on the device // NS_STATUS_FAILURE // No receive related events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckReceive ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptCheckInternal // Checks for the presence of MAC/PHY internal (non data transfer related) // interrupt events. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // Return Value // NS_STATUS_SUCCESS // Pending internal events exist on the device // NS_STATUS_FAILURE // No internal events detected. // //***************************************************************************** MPL_STATUS MplInterruptCheckInternal ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplInterruptDoneInternal // Processes device’s internal (non data-type) interrupts. // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // maxEvents // The maximum internal events (e.g. link change) that MPL should // process before returning back to the caller. // Return Value // NS_STATUS_SUCCESS // The internal event was successfully handled. // NS_STATUS_ABORTED // The processing was aborted since the maximum event count specified // was met. // //***************************************************************************** MPL_STATUS MplInterruptDoneInternal ( IN NS_VOID *pMplHandle, IN NS_UINT maxEvents ); //+++++ Link Management APIs //########################### //***************************************************************************** // MplLinkCfg // Configures the network media speed (10/100), duplex (half/full), // negotiation (Auto/Forced) and network PAUSE parameters. // When configuring auto mode, the speed and duplex setting passed should // reflect the best case scenario i.e most desired speed and duplex // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pLinkCfg // Points to a MPL_LINK_CFG structure with the desired link // configuration. // // Return Value // NS_STATUS_SUCCESS // Link configured and the link is UP. // NS_STATUS_ASYNCH_COMPLETION // Link is currently being configured or being negotiated. // NS_STATUS_INVALID_PARM // An invalid parameter was detected in the configuration structure. // NS_STATUS_HARDWARE_FAILURE // An expected failure occured while setting the link config // //***************************************************************************** MPL_STATUS MplLinkCfg ( IN NS_VOID *pMplHandle, IN MPL_LINK_CFG *pLinkCfg ); //***************************************************************************** // MplLinkGetCfg // Returns the current link configuration on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pLinkCfg // Pointer to a caller allocated MPL_LINK_CFG structure in which the // current link configuration is returned. // // Return Value // NS_STATUS_SUCCESS // The link configuration was successfully returned. // NS_STATUS_FAILURE // The link is not configured (yet). // //***************************************************************************** MPL_STATUS MplLinkGetCfg ( IN NS_VOID *pMplHandle, OUT MPL_LINK_CFG *pLinkCfg ); //***************************************************************************** // MplLinkGetStatus // Returns the link status reported on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // MPL_LINK_STATUS_NONE // An unexpected hardware error occurred while processing this request // and the link state was not retrieved. // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up // //***************************************************************************** MPL_LINK_STATUS MplLinkGetStatus ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplLinkProcessChange // Handles the link change event // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // MPL_LINK_STATUS_NONE // An unexpected hardware error occurred while processing this request // and the link state was not retrieved. // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up. // //***************************************************************************** MPL_LINK_STATUS MplLinkProcessChange ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplLinkUpComplete // Completes the configuration of the device following the // auto-negotiation process. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The link configuration is complete. // NS_STATUS_FAILURE // The link state is not UP. // //***************************************************************************** MPL_STATUS MplLinkUpComplete ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplLinkInterrupt // Processes an incoming link related interrupt // At this time this is an MPL internal function (called from // MplIntteruptDoneInternal) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The interrupt was successfully fielded. // //***************************************************************************** MPL_STATUS MplLinkInterrupt( IN NS_VOID *pMplHandle ); //+++++ PHY Management APIs //################################### //***************************************************************************** // MplPhyDetect // Detect the presence of a MacPhyter device on the system. // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // A MacPhyter device was successfully probed // NS_STATUS_HARDWARE_FAILURE // Could not find a MacPhyter device // //***************************************************************************** MPL_STATUS MplPhyDetect( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyReset // Reset the PHY device // // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // A MacPhyter device was successfully probed // NS_STATUS_HARDWARE_FAILURE // Could not find a MacPhyter device // //***************************************************************************** MPL_STATUS MplPhyReset( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyLinkSetup // Setup the link on the PHY with the requested settings // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_STATUS_SUCCESS // The link was set on the PHY device // NS_STATUS_INVALID_PARM // An invalid link configuration was detected // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplPhyLinkSetup ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyGetLinkStatus // Returns the status of the link // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_STATUS_NONE // An unexpected hardware error occurred while processing this request // and the link state was not retrieved. // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up // //***************************************************************************** MPL_LINK_STATUS MplPhyGetLinkStatus ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyGetLinkSpeed // Returns current link speed. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_SPEED_TENMBPS // The current link speed is 10Mbps // MPL_LINK_SPEED_HUNDREDMBPS // The current link speed is 100Mbps // //***************************************************************************** MPL_LINK_SPEED MplPhyGetLinkSpeed( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyGetLinkDuplex // Returns current link duplex mode. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // MPL_LINK_DUPLEX_HALF // The current duplex mode is half // MPL_LINK_DUPLEX_FULL // The current duplex mode is full // //***************************************************************************** MPL_LINK_DUPLEX MplPhyGetLinkDuplex( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyAutoNegDone // Returns if Auto Neg process is completed. // NOTE: SHOULD be called only after determing that the link is UP - // i.e MplPhyGetLinkStatus has returned MPL_LINK_STATUS_UP // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The link was setup following a Auto-Neg process // NS_FALSE // The link was setup in forced mode // //***************************************************************************** NS_BOOLEAN MplPhyAutoNegDone( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyLinkSetupComplete // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The link was sucessfully setup // NS_FALSE // The link is not up (Assert - should not happen) // // //***************************************************************************** NS_BOOLEAN MplPhyLinkSetupComplete( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyRequiresPatch // // Parameters // pMplHandle // MPL device handle // // Return Value // NS_TRUE // The PHY requires patches to be applied // NS_FALSE // No Patch work required // //***************************************************************************** NS_BOOLEAN MplPhyRequiresPatch( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyGetDeviceAddr // Return the Phy device address // // Parameters // pMplHandle // MPL device handle // // Return Value // Phy device addr // //***************************************************************************** NS_UINT MplPhyGetDeviceAddr ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplPhyMdioRead // Read Phy register // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to read (in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // // Return Value // Reg data // //***************************************************************************** NS_UINT32 MplPhyMdioRead( IN NS_VOID *pMplHandle, IN NS_UINT phyDevAddr, IN NS_UINT regIndex ); //***************************************************************************** // MplPhyMdioWrite // Write Phy register // // Parameters // pMplHandle // MPL device handle // phyDevAddr // Device addr of the Phy // regIndex // Register to write(in terms of MII offset e.g. BMCR = 0x0, BMSR = 0x1) // regData // Data to write // // Return Value // None // //***************************************************************************** NS_VOID MplPhyMdioWrite( IN NS_VOID *pMplHandle, IN NS_UINT phyDevAddr, IN NS_UINT regIndex, IN NS_UINT32 regData ); //+++++ Power Management and WoL APIs //################################### //***************************************************************************** // MplPowerSetState // Set a new power state on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // newState // New power state that needs to be set on the device // pmeEnable // When set to NS_TRUE, MPL enables PME on the device // Some OSs do this automatically, some do not // // Return Value // NS_STATUS_SUCCESS // The new state was successfully set // NS_STATUS_FAILURE // The device could not be set to the new state // //***************************************************************************** MPL_STATUS MplPowerSetState( IN NS_VOID *pMplHandle, IN MPL_POWER_STATE newState, IN NS_BOOLEAN pmeEnable ); //***************************************************************************** // MplWolCfg // Configure the WOL operation on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // wakeEnable // Flag to enable (set to NS_TRUE) or disable (set to NS_FALSE) Wol // wakeType // When WOL is enabled, represents a bit-map of wake-up events that // needs to be enabled. It is a logical OR of, // MPL_WOL_MAGIC - Enable wake on Magic Pattern. // MPL_WOL_PATTERN - Enable wake on pattern match (Patterns needs // to be separately defined). // MPL_WOL_BROADCAST - Enable wake on any broadcast packet. // MPL_WOL_MULTICAST - Enable wake on multicast packet. // MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to // the device's address. // MPL_WOL_LINK - Enable wake on link status change. // MPL_WOL_ARP - Enable wake on any ARP packet. // // Return Value // NS_STATUS_SUCCESS // The WOL events were successfully enabled or disabled (depending // on wakeEnable). // NS_STATUS_INVALID_PARM // The wake event type is not supported on the device. // //***************************************************************************** MPL_STATUS MplWolCfg( IN NS_VOID *pMplHandle, IN NS_BOOLEAN wakeEnable, IN NS_UINT wakeType ); // Wol Type Flag bits #define MPL_WOL_MAGIC 0x00000001 #define MPL_WOL_PATTERNS 0x00000002 #define MPL_WOL_BROADCAST 0x00000004 #define MPL_WOL_MULTICAST 0x00000008 #define MPL_WOL_DIRECTED 0x00000010 #define MPL_WOL_LINK 0x00000020 #define MPL_WOL_ARP 0x00000040 //***************************************************************************** // MplWolGetCfg // Retrieve the current WOL configuration on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWakeType // Pointer to caller provider variable in which the bit-map of wake-up // events currently enabled is returned. It is a logical OR of, // MPL_WOL_MAGIC - Enable wake on Magic Pattern. // MPL_WOL_PATTERN - Enable wake on pattern match (Patterns needs to // be separately defined). // MPL_WOL_BROADCAST - Enable wake on any broadcast packet. // MPL_WOL_MULTICAST - Enable wake on multicast packet. // MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to // the device's address. // MPL_WOL_LINK - Enable wake on link status change. // MPL_WOL_ARP - Enable wake on any ARP packet. // // Return Value // NS_STATUS_SUCCESS // The WOL configuration was returned successfully // //***************************************************************************** MPL_STATUS MplWolGetCfg( IN NS_VOID *pMplHandle, IN NS_UINT *pWakeType ); //***************************************************************************** // MplWolClearPattern // Clear all WOL wake patterns on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The wake patterns were successfully cleared // //***************************************************************************** MPL_STATUS MplWolClearPattern( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplWolAddPattern // Add a new WOL wake pattern to the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWolPattern // Pointer to a MPL_WOL_PATTERN structure in which the new pattern // and its associated mask is noted // // Return Value // NS_STATUS_SUCCESS // The wake pattern was successfully added. // NS_STATUS_RESOURCES // The wake pattern not added since it exceeds the maximum supported // on this device. // NS_STATUS_INVALID_PARM // The wake pattern buffer is larger than the maximum supported by // the device. // //***************************************************************************** MPL_STATUS MplWolAddPattern( IN NS_VOID *pMplHandle, IN MPL_WOL_PATTERN *pWolPattern ); //***************************************************************************** // MplWolRemovePattern // Remove a WOL wake pattern from the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pWolPattern // Pointer to a MPL_WOL_PATTERN structure in which the pattern // and its associated mask is noted // // Return Value // NS_STATUS_SUCCESS // The wake pattern was deleted successfully. // NS_STATUS_INVALID_PARM // The wake pattern was not found in the list // //***************************************************************************** MPL_STATUS MplWolRemovePattern( IN NS_VOID *pMplHandle, IN MPL_WOL_PATTERN *pWolPattern ); //+++++ Miscellaneous APIs //################################### //***************************************************************************** // MplSetMacAddress // Set the MAC's address on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pMacAddr // Pointer to caller supplied variable with the new MAC address // // Return Value // NS_STATUS_SUCCESS // The MAC address was sucessfully programmed on the device // //***************************************************************************** MPL_STATUS MplSetMacAddress ( IN NS_VOID *pMplHandle, IN MPL_MAC_ADDR pMacAddr ); //***************************************************************************** // MplGetMacAddress // Get the current MAC's address on the device // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // eeProm // If set to NS_TRUE, the permanent (EEPROM programmed) mac address // for the device is returned back to the caller, else the current // active address is returned. // pMacAddr // Pointer to a caller supplied MPL_MAC_ADDR variable where the current // or default network address is returned. // // Return Value // NS_STATUS_SUCCESS // The mac address was successfully read and is returned. // NS_STATUS_FAILURE // Failed to get the MAC address //***************************************************************************** MPL_STATUS MplGetMacAddress ( IN NS_VOID *pMplHandle, IN NS_BOOLEAN eeProm, OUT MPL_MAC_ADDR pMacAddr ); //***************************************************************************** // MplGetDeviceId // Get the device Id to identify the MacPhyter version // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // MPL_DEVICE_ID_DP83815 = Macphyter-I found // MPL_DEVICE_ID_DP83816 = Macphyter-II found // MPL_DEVICE_ID_DP83818 = Macphyter-III found //***************************************************************************** MPL_DEVICE_ID MplGetDeviceId( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplGetRegs // Get the current operational registers values // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // pRegs // A caller supplied buffer (atleast 255*4 bytes) // // Return Value // None //***************************************************************************** NS_VOID MplGetRegs( IN NS_VOID *pMplHandle, IN NS_UINT32 *pRegs ); //***************************************************************************** // MplRegRead // Read a 32-bit register // // Parameters // pMplHandle // MPL device handle // regIndex // Register to read (in terms of absolute offset e.g. CR = 0x0, // TXCFG = 0x24) // // Return Value // Reg data // //***************************************************************************** NS_UINT32 MplRegRead( IN NS_VOID *pMplHandle, IN NS_UINT regIndex ); //***************************************************************************** // MplRegWrite // Write a 32-bit register // // Parameters // pMplHandle // MPL device handle // regIndex // Register to read (in terms of absolute offset e.g. CR = 0x0, // TXCFG = 0x24) // regData // Data to write // // Return Value // None // //***************************************************************************** NS_VOID MplRegWrite( IN NS_VOID *pMplHandle, IN NS_UINT regIndex, IN NS_UINT32 regData ); //***************************************************************************** // MplDumpTransmitRing // Dump the Txd ring // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // None //***************************************************************************** NS_VOID MplDumpTransmitRing( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplDumpReceiveRing // Dump the Rxd ring // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // None //***************************************************************************** NS_VOID MplDumpReceiveRing( IN NS_VOID *pMplHandle ); #ifndef MPL_NO_EEPROM //***************************************************************************** // MplEERead // Read 16-bit word from a given EEPROM offset // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // index // Offset from where to read EEPROM contents // *pData // Caller provided variable where the 16-bit contents is returned // // Return Value // NS_STATUS_SUCCESS // The EEPROM was successfully read // NS_STATUS_INVALID_PARM // The EEPROM offset is invalid //***************************************************************************** MPL_STATUS MplEERead( IN NS_VOID *pMplHandle, IN NS_UINT index, IN NS_UINT16 *pData ); #endif// MPL_NO_EEPROM //+++++ MPL Callbacks into NSM //***************************************************************************** // NsmTransmitDone // Transmit Done Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose completion is being reported. // pTxDone // MPL allocated MPL_TRANSMIT_DONE structure array in which the // NSM packet handles and statuses are returned. // // Return Value // None //***************************************************************************** NS_VOID NsmTransmitDone( IN NS_VOID *pClientDevHndl, IN NS_UINT packetCnt, IN MPL_TRANSMIT_DONE *pTxDone ); //***************************************************************************** // NsmReceive // Receive Done Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // packetCnt // Count of packets whose reception is being reported. // pPkt // MPL allocated MPL_PKT structure array in which // a list of the newly received packets are reported // // Return Value // None //***************************************************************************** NS_VOID NsmReceive( IN NS_VOID *pClientDevHndl, IN NS_UINT packetCnt, IN MPL_PKT *pPkt ); //***************************************************************************** // NsmLinkStatusChange // Link status change Notification // // Parameters // pClientDevHndl // NSM device handle registered with MPL (during MplInitialize) // // Return Value // None //***************************************************************************** NS_VOID NsmLinkStatusChange( IN NS_VOID *pClientDevHndl ); #if defined(__cplusplus) } #endif #endif // _MPLCLIENT_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mpltaskchksum.h0000444000000000000000000000103610430225772017671 0ustar rootroot //****************************************************************************** // // MPLTASKCHKSUM.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL checksum (IP, TCP, UDP) Offload Task Module definitions and exports // // MPL clients should not include this file directly, instead include // mplclient.h //****************************************************************************** #ifndef _MPLTASKCHKSUM_H_ #define _MPLTASKCHKSUM_H_ #endif // _MPLTASKCHKSUM_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mpltaskvlan.h0000444000000000000000000001776010430225772017352 0ustar rootroot //****************************************************************************** // // MPLTASKVLAN.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL VLAN Offload Task Module definitions and exports // // MPL clients should not include this file directly, instead include // mplclient.h //****************************************************************************** #ifndef _MPLTASKVLAN_H_ #define _MPLTASKVLAN_H_ #if defined(__cplusplus) extern "C" { #endif // Forward refs for compilation struct _MPL_PKT; //***************************************************************************** // MplTaskVlanCfg // Enable/Disable and configure the VLAN module // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // enableFlag // Set to NS_TRUE to enable the VLAN tag insertion and removal process, // NS_FALSE to disable. // cfg // Bit map of configuration options for the VLAN task offload module. // MPL_TASK_VLAN_DETECT_TAGS - Detect VLAN tags in incoming pkts // and include tag data in OOB field of MPL_PKT // MPL_TASK_VLAN_REMOVE_TAGS - Specifies the MPL should remove VLAN // tags from receive packets indicated to the NSM. // MPL_TASK_VLAN_DISCARD_TAGGED – Enables discard of frames *with* // a VLAN tag. // MPL_TASK_VLAN_DISCARD_UNTAGGED – Enables discard of frames // *without* a VLAN tag. // MPL_TASK_VLAN_FILTER - Enables MPL’s VLAN ID receive filter. // MPL_TASK_VLAN_PERPACKET - Include VLAN tag on a per pkt basis // - For Tx only (See Global insertion in MplTaskVlanAddTxTag) // // Return Value // NS_STATUS_SUCCESS // The task offload was successfully enabled or disabled. // NS_STATUS_NOT_SUPPORTED // This offload task or selected configuration option is not supported // by MPL. // //***************************************************************************** MPL_STATUS MplTaskVlanCfg ( IN NS_VOID *pMplHandle, IN NS_BOOLEAN enableFlag, IN NS_UINT cfg ); //***************************************************************************** // MplTaskVlanAddTxTag // Add a new VLAN tag to used globally for all Tx pkts // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be inserted globally for all transmits packets. // vlanPriority // VLAN priority to be inserted globally for all transmits packets. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully added. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // //***************************************************************************** MPL_STATUS MplTaskVlanAddTxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId, IN NS_UINT8 vlanPriority ); //***************************************************************************** // MplTaskVlanAddRxTag // Add a new VLAN tag to the Rx filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be inserted in the receive filter for incoming // receive packets. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully added. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // NS_STATUS_RESOURCES // The maximum filter list size was reached. // //***************************************************************************** MPL_STATUS MplTaskVlanAddRxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId ); //***************************************************************************** // MplTaskVlanDeleteRxTag // Delete a VLAN tag from the Rx filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // vlanId // VLAN identifier to be removed from the receive filter list. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully deleted. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_FAILURE // The VLAN id was not found in the filter list. // //***************************************************************************** MPL_STATUS MplTaskVlanDeleteRxTag ( IN NS_VOID *pMplHandle, IN NS_UINT16 vlanId ); //***************************************************************************** // MplTaskVlanClearRxTag // Clear the Rx VLAN filter list // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The VLAN tags were successfully cleared. // NS_STATUS_FAILURE // This offload feature is disabled // //***************************************************************************** MPL_STATUS MplTaskVlanClearRxTag ( IN NS_VOID *pMplHandle ); //***************************************************************************** // MplSetPacketVlanTag // Set a given VLAN tag to the outgoing pkt (per packet mode) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pPacket // Pointer to the MPL_PKT structure that describes the frame to be // transmitted // vlanId // The VLAN id (0 to 4095 inclusive) to be used to transmit this packet // vlanPriority // The VLAN priority (0 to 7 inclusive) to be used to transmit this // packet // // Return Value // NS_STATUS_SUCCESS // The VLAN id was successfully set for the packet. // NS_STATUS_FAILURE // This offload feature is disabled // NS_STATUS_INVALID_PARM // The VLAN id or priority value was not in the valid range. // //***************************************************************************** MPL_STATUS MplSetPacketVlanTag ( IN NS_VOID *pMplHandle, IN struct _MPL_PKT *pPacket, IN NS_UINT16 vlandId, IN NS_UINT8 vlanPriority ); //***************************************************************************** // MplQueryPacketVlanTag // Retrieve the VLAN tag in a given Rx packet // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pPacket // Pointer to the MPL_PKT structure that describes the frame just // received // pVlanId // Pointer to a caller provided variable in which the VLAN id (0 to // 4095 inclusive) is returned. // pVlanPriority // Caller allocated variable in which this function returns the VLAN // priority (0 to 7 inclusive) on the received frame. // // Return Value // NS_STATUS_SUCCESS // The VLAN tag was successfully retrieved for the packet. // NS_STATUS_INVALID_PARM // The packet is not a VLAN tagged packet. // NS_STATUS_FAILURE // This offload feature is disabled // //**************************************************************************** MPL_STATUS MplQueryPacketVlanId ( IN NS_VOID *pMplHandle, IN struct _MPL_PKT *pPacket, IN NS_UINT16 *pVlandId, IN NS_UINT8 *pVlanPriority ); #if defined(__cplusplus) } #endif #endif // _MPLTASKVLAN_H_ DP8381X-Linux-Ver-1.6/Mpl/Public/mplcommon.h0000444000000000000000000002242510430225772017011 0ustar rootroot//********************************************************************** // // MPLCOMMON.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // Defines data structures that are common between the MPL layer // and any higher layer or NSM. // This is included via mplclient.h - Do not include this directly! // //********************************************************************** #ifndef _MPLCOMMON_H_ #define _MPLCOMMON_H_ //********************************************************************** // MPL Status Return Codes //********************************************************************** // Test typedef unsigned int MPL_STATUS; #define NS_STATUS_SUCCESS 0x00 #define NS_STATUS_FAILURE 0x01 #define NS_STATUS_NOT_PRESENT 0x02 #define NS_STATUS_NO_MORE_ITEMS 0x03 #define NS_STATUS_INVALID_PARM 0x04 #define NS_STATUS_INVALID_PARAMETER NS_STATUS_INVALID_PARM //For Compatibility #define NS_STATUS_RESOURCES 0x05 #define NS_STATUS_NOT_SUPPORTED 0x06 #define NS_STATUS_ABORTED 0x07 #define NS_STATUS_HARDWARE_FAILURE 0x08 #define NS_STATUS_ASYNCH_COMPLETION 0x09 #define NS_STATUS_TIMEOUT 0x0A #define NS_STATUS_OVERFLOW 0x0B //********************************************************************** // Some common data types we use. //********************************************************************** #ifndef NULL #define NULL (void*)0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define MTU_ETHERNET 1518 #define HDR_ETHERNET 14 #define IEEE_802_3_FCS_HASH_FUNC 0x04C11DB6 //********************************************************************** // CMD-STATUS bit definitions for the Transmit and Receive descriptors // Defined here since the MplSetPacketXXX and MplQueryPacketXXX macros // defined in mplclient.h need them //********************************************************************** // Cmdsts bit Definitions #define CS_OWN 0x80000000 #define CS_MORE 0x40000000 #define CS_INTR 0x20000000 #define CS_SUPCRC 0x10000000 #define CS_OK 0x08000000 #define CS_OWN_INTR 0xA0000000 // OWN+INTR #define ECS_VPKT 0x00010000 // Ext Status - VLAN // CmdSts Tx Err bits #define CS_ERR_TXA 0x04000000 #define CS_ERR_TFU 0x02000000 #define CS_ERR_TX_CRS 0x01000000 #define CS_ERR_TX_TD 0x00800000 #define CS_ERR_TX_ED 0x00400000 #define CS_ERR_TX_OWC 0x00200000 #define CS_ERR_TX_EC 0x00100000 // CmdSts Rx Err bits #define CS_RXA 0x04000000 #define CS_ERR_RXO 0x02000000 #define CS_ERR_RX_LONG 0x00400000 #define CS_ERR_RX_RUNT 0x00200000 #define CS_ERR_RX_ISE 0x00100000 #define CS_ERR_RX_CRCE 0x00080000 #define CS_ERR_RX_FAE 0x00040000 #define CS_LBP 0x00020000 #define CS_ERR_RX_COL 0x00010000 #define CS_LEN_MASK 0x00000FFF #define CS_MAX_FRAG_SIZE 0x07FF // Endian Swapped Cmdsts definitions #ifdef MPL_BIG_ENDIAN #define CS_OWN_ES 0x00000080 #define CS_MORE_ES 0x00000040 #define CS_INTR_ES 0x00000020 #define CS_OK_ES 0x00000008 #define CS_LEN_MASK_ES 0xFF0F0000 #else #define CS_OWN_ES CS_OWN #define CS_MORE_ES CS_MORE #define CS_INTR_ES CS_INTR #define CS_OK_ES CS_OK #define CS_LEN_MASK_ES CS_LEN_MASK #endif // MPL_BIG_ENDIAN //********************************************************************** // Data structures and macros for MPL list management library //********************************************************************** typedef struct _MPL_LIST_NODE { struct _MPL_LIST_NODE *next; struct _MPL_LIST_NODE *prev; } MPL_LIST_NODE; typedef struct _MPL_LIST { // These two should be at the start always MPL_LIST_NODE *next; MPL_LIST_NODE *prev; NS_VOID *lock; NS_UINT entries; } MPL_LIST; // List Locking APIs //***************************************************************************** // MPL_LIST_LOCK // // Clients should use this API to lock a list - required for traversal APIs // only. The add/del APIs implicitly lock the list. // // Parameters // list // A pointer to the list // // Return Value // //***************************************************************************** #define MPL_LIST_LOCK(list) \ if ((list)->lock) \ OaiAcquireLock((list)->lock) //***************************************************************************** // MPL_LIST_UNLOCK // // Clients should use this API to lock a list - required for traversal APIs // only. The add/del APIs implicitly lock the list. // // Parameters // list // A pointer to the list // // Return Value // //***************************************************************************** #define MPL_LIST_UNLOCK(list) \ if ((list)->lock) \ OaiReleaseLock((list)->lock) // Traversal APIs //***************************************************************************** // MPL_LIST_GET_HEAD // // Clients should use this API to get the head(first) node in a list // // Parameters // list // A pointer to the list // // Return Value // Pointer to the head node in the list // //***************************************************************************** #define MPL_LIST_GET_HEAD(list) \ (list)->next //***************************************************************************** // MPL_LIST_GET_TAIL // // Clients should use this API to get the tail(last) node in a list // // Parameters // list // A pointer to the list // // Return Value // Pointer to the tail node in the list // //***************************************************************************** #define MPL_LIST_GET_TAIL(list) \ (list)->prev //***************************************************************************** // MPL_LIST_GET_NEXT // // Clients should use this API to get the tail(last) node in a list // Note: Clients should follow this call with MPL_LIST_CHK_END to verify if // the node returned by this API is valid i.e. we have not looped back to the // begining of the list // // Parameters // node // A pointer to the current node // // Return Value // Pointer to the next node // //***************************************************************************** #define MPL_LIST_GET_NEXT(node) \ (node)->next //***************************************************************************** // MPL_LIST_GET_SIZE // // Clients should use this API to get the number of entries in the list // // Parameters // list // A pointer to the list // // Return Value // Count of entries in the list // //***************************************************************************** #define MPL_LIST_GET_SIZE(list) \ (list)->entries //***************************************************************************** // MPL_LIST_CHK_END // // Clients should use this API to check if a node is valid i.e. if the // traversal has looped back. // Note: Client should always check the validity of a node // that they get from MPL_LIST_GET_NEXT by calling this API. // // Parameters // list // A pointer to the list // node // The node that needs to be verified // // Return Value // NS_TRUE : If we looped back and this node is a repeat // NS_FALSE: If the node is valid and we have'nt looped back // //***************************************************************************** #define MPL_LIST_CHK_END(list, node) \ (((node) == (MPL_LIST_NODE *)(list)) ? NS_TRUE : NS_FALSE) //***************************************************************************** // MPL_LIST_GET_ENTRY // // Clients should use this API to get the parent container structure that // holds the MPL_LIST_NODE entry. // // Parameters // node // The MPL_LIST_NODE pointer that in part of the parent container. This // node pointer is used by MPL_LIST library to track the list. // type // The data structure that defines the type for the parent container // structure. For exp. struct xyz, EHI_SOCK_STRUCT etc. This is needed // for since the typeof operator is not supported in all platforms. // member // The name that client uses within the parent container structure // for the MPL_LIST_NODE entry. // // Return Value // A pointer to the parent container structure that hold the MPL_LIST_NODE // //***************************************************************************** #define MPL_LIST_GET_ENTRY(node, type, member) \ ((type *)((NS_ADDR)(node) - (NS_ADDR)(&((type *)0)->member))) #if defined(__cplusplus) extern "C" { #endif MPL_STATUS MplListInit( IN MPL_LIST *list, IN NS_BOOLEAN safe); NS_VOID MplListDeInit( IN MPL_LIST *list); NS_VOID MplListAddHead( IN MPL_LIST *list, IN MPL_LIST_NODE *newNode); NS_VOID MplListAddTail( IN MPL_LIST *list, IN MPL_LIST_NODE *newNode); NS_VOID MplListDel( IN MPL_LIST *list, IN MPL_LIST_NODE *node); #if defined(__cplusplus) } #endif #endif // _MPLCOMMON_H_ DP8381X-Linux-Ver-1.6/Mpl/mplutil.c0000444000000000000000000001477210430225754015261 0ustar rootroot //****************************************************************************** // // MPLUTIL.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // Some utilities functions // // This file contains the API implementations for // o Linked List management // //****************************************************************************** #include // Local functions // List library APIs //***************************************************************************** // MplListInit // // Clients should use this API to initialize a linked list // // Parameters // list // A pointer to the MPL_LIST structure // safe // NS_TRUE : If the list should be protected with locks // The list is implicitly protected only for MplListAddXXX // and MplListDel APIs. The client needs to explicitly protect // using MPL_LIST_LOCK and MPL_LIST_UNLOCK APIs for list // traversal // NS_FALSE : If the list is unprotected // // Return Value // NS_STATUS_SUCCESS : If the init was successful // NS_STATUS_RESOURCES: If the init failed due to mem // //***************************************************************************** MPL_STATUS MplListInit( IN MPL_LIST *list, IN NS_BOOLEAN safe) { MPL_STATUS ret = NS_STATUS_SUCCESS; // Init list->next = list->prev = (MPL_LIST_NODE *)list; list->entries = 0x0; list->lock = NULL; // Allocate lock if required if (safe == NS_TRUE) { if (OaiCreateLock(&list->lock) == NS_FALSE) ret = NS_STATUS_RESOURCES; } return ret; } //***************************************************************************** // MplListInit // // Clients should use this API to de-initialize a linked list // // Parameters // list // A pointer to the MPL_LIST structure // // Return Value // //***************************************************************************** NS_VOID MplListDeInit( IN MPL_LIST *list) { // Destory lock if we had one if (list->lock) OaiDestroyLock(list->lock); list->lock = NULL; } static __inline NS_VOID listAdd( IN MPL_LIST_NODE *newNode, IN MPL_LIST_NODE *prev, IN MPL_LIST_NODE *next) { next->prev = newNode; newNode->next = next; newNode->prev = prev; prev->next = newNode; } //***************************************************************************** // MplListAddHead // // Clients should use this API to add a new node to the head of the list // This is used for stack data-structures // // Parameters // list // Pointer to the MPL_LIST structure // newNode // Pointer to the new node (MPL_LIST_NODE) // // Return Value // //***************************************************************************** NS_VOID MplListAddHead( IN MPL_LIST *list, IN MPL_LIST_NODE *newNode) { MPL_LIST_LOCK(list); listAdd(newNode, (MPL_LIST_NODE *)list, list->next); list->entries++; MPL_LIST_UNLOCK(list); } //***************************************************************************** // MplListAddTail // // Clients should use this API to add a new node to the tail of the list // This is used for queue data-structures // // Parameters // list // Pointer to the MPL_LIST structure // newNode // Pointer to the new node (MPL_LIST_NODE) // // Return Value // //***************************************************************************** NS_VOID MplListAddTail( IN MPL_LIST *list, IN MPL_LIST_NODE *newNode) { MPL_LIST_LOCK(list); listAdd(newNode, list->prev, (MPL_LIST_NODE *)list); list->entries++; MPL_LIST_UNLOCK(list); } static __inline NS_VOID listDel( IN MPL_LIST_NODE *prev, IN MPL_LIST_NODE *next) { next->prev = prev; prev->next = next; } //***************************************************************************** // MplListDel // // Clients should use this API to delete a node from the list // // Parameters // list // Pointer to the MPL_LIST structure // node // Pointer to the node (MPL_LIST_NODE) // // Return Value // //***************************************************************************** NS_VOID MplListDel( IN MPL_LIST *list, IN MPL_LIST_NODE *node) { MPL_LIST_LOCK(list); listDel(node->prev, node->next); list->entries--; node->next = node->prev = NULL; MPL_LIST_UNLOCK(list); } //***************************************************************************** // MplListExample // // Refer to the below code for an example of howto use the MPL list APIs // //***************************************************************************** #if 0 // Client's Overall context data structure // Below is an example only. The only thing needed is a MPL_LIST entry typedef struct _EXP_CONTEXT{ NS_UINT8 x; // Client specific crap NS_UINT y; // Client specific crap MPL_LIST list; // list entry - Required } EXP_CONTEXT; // Node data structure - The list is created of these structures // Below is an example only. The only thing needed is a MPL_LIST_NODE entry typedef struct _EXP_PARENT { NS_UINT8 x; // Client specific crap NS_UINT y; // Client specific crap MPL_LIST_NODE link; // Field for the list library to work on - Required } EXP_PARENT; NS_VOID listExample(EXP_CONTEXT ctx) { EXP_PARENT par, *tmp; MPL_LIST_NODE *node; // Initialize a protected list (for unprotected pass NS_FALSE below) MplListInit(&ctx->list, NS_TRUE); // Add a new node to head - for stack implementation MplListAddHead(&ctx->list, &par->link); // Add a new node to tail - for queue implementation MplListAddTail(&ctx->list, &par->link); // List traversal - take locks for traversal MPL_LIST_LOCK(&ctx->list); for (node = MPL_LIST_GET_HEAD(&ctx->list); MPL_LIST_CHK_END(&ctx->list, node) == NS_FALSE; node = MPL_LIST_GET_NEXT(node)) { //Node, Type , Member in parent data-structure tmp = MPL_LIST_GET_ENTRY(node, EXP_PARENT, link); } MPL_LIST_UNLOCK(&ctx->list); // Delete a node MplListDel(&ctx->list, &par->link); // De-Initialize the list MplListDeInit(&ctx->list); } #endif DP8381X-Linux-Ver-1.6/Mpl/mpldebug.c0000444000000000000000000002005110430225754015355 0ustar rootroot //****************************************************************************** // // MPLDEBUG.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Debug // // This file contains the API implementations for // o MPL Capabilities and MTU reporting // //****************************************************************************** #include // These functions are defined on a retail build but they don't // do anything. #ifndef MPL_CHECKED_BUILD NS_VOID MplDebDumpBuffer( IN NS_UINT8 *buffer, IN NS_UINT length) { return; } NS_VOID MplDebDumpWords( IN NS_UINT32 *buffer, IN NS_UINT length) { return; } NS_VOID MplDebEnablePathTracing( IN NS_UINT zones) { return; } NS_VOID MplDebEnableMsgsAndChecks( IN NS_UINT zones) { return; } NS_VOID MplDebDumpAdapterRegisters( IN NS_VOID *pEplContext) { return; } #endif //!MPL_CHECKED_BUILD // These routines are only included/compiled in a checked build. #ifdef MPL_CHECKED_BUILD // This is a global variable that is used by the MPL_CENTER, MPL_CEXIT // macros that are defined in epldebug.h NS_UINT MplDebugZonePathTracing = DZONE_ENABLED_PATH; // This is a global variable that is used to control whether verbose // messages are displays and whether ASSERTS are enabled. NS_UINT MplDebugZoneMsgAndChecks = DZONE_ENABLED_MSG_CHECKS; static NS_CHAR * MplDebLogAddrToStr( IN NS_VOID *logAddr, IN NS_CHAR *outBuffer); //********************************************************************** // MplDebDumpBuffer // // Displays the contents of the specified memory buffer using // the OAI defined debug trace facility. // // Parameters: // buffer The memory buffer to display // length The number of bytes to display // // Return: // Nothing // //********************************************************************** NS_VOID MplDebDumpBuffer( IN NS_UINT8 *buffer, IN NS_UINT length) { #define DEB_BYTES_PER_LINE 16 NS_UINT x, y, numLines, remainder; NS_UINT8 asciBuf[ DEB_BYTES_PER_LINE+1 ]; NS_CHAR logAddrStr[ NS_LOG_ADDR_BUF_SIZE ]; MPL_TRACE(("Address %s, length %d bytes:\n\n", MplDebLogAddrToStr( buffer, logAddrStr), length)); if ( length == 0) return; numLines = (length-1) / DEB_BYTES_PER_LINE + 1; remainder = (length-1) % DEB_BYTES_PER_LINE + 1; for ( x = 0; x < numLines; x++) { MPL_TRACE(("%08X: ", x * DEB_BYTES_PER_LINE)); for ( y = 0; y < ( (x != (numLines - 1)) ? DEB_BYTES_PER_LINE : remainder); y++, buffer++) { asciBuf[y+0] = (NS_UINT8) ((*buffer >= '!' && *buffer <= '~') ? *buffer : '.'); asciBuf[y+1] = '\0'; MPL_TRACE(( "%02X ", (NS_UINT) *buffer)); if ( y == (DEB_BYTES_PER_LINE-1)) MPL_TRACE(( " ")); } MPL_TRACE(( "%s\n", asciBuf)); } } //********************************************************************** // MplDebDumpWords // // Displays the contents in hexadecimal of the specified memory buffer // using the OAI defined debug trace facility. Output is a list of // 32-bit words. // // Parameters: // buffer The memory buffer to display // length The number of 32-bit words to display // // Return: // Nothing // //********************************************************************** NS_VOID MplDebDumpWords( IN NS_UINT32 *buffer, IN NS_UINT length ) { NS_UINT i; NS_CHAR logAddrStr[ NS_LOG_ADDR_BUF_SIZE ]; MPL_TRACE(("Address %s, length %d words:\n\n", MplDebLogAddrToStr( buffer, logAddrStr), length)); for (i=0;i>= 4; } outBuffer[ 2 * sizeof( NS_VOID *) ] = '\0'; return outBuffer; } //********************************************************************** // MplDebPhysAddrToStr // // Converts a physical address (32-bit or 64-bit) to it string // representation. For example, an address of 0x12345678 would // be converted to the string "12345678". // // physAddr // Physical address to convert. // outBuffer // Caller allocated string buffer of size NS_PHYS_ADDR_BUF_SIZE. // // Returns: // Pointer to outBuffer //********************************************************************** NS_CHAR * MplDebPhysAddrToStr( IN NS_ADDR physAddr, IN NS_CHAR *outBuffer) { NS_UINT i; NS_CHAR val; // Do it a nibble at a time. for ( i = 0; i < (2 * sizeof( NS_ADDR)); i++) { val = (NS_CHAR)(physAddr & 0x0F); outBuffer[ 2 * sizeof( NS_ADDR) - i - 1 ] = (NS_CHAR)((val <= 9) ? val + '0' : val - 10 + 'A'); physAddr >>= 4; } outBuffer[ 2 * sizeof( NS_ADDR) ] = '\0'; return outBuffer; } #endif // MPL_CHECKED_BUILD DP8381X-Linux-Ver-1.6/Mpl/mplinitshutdown.c0000444000000000000000000004723210430225754017040 0ustar rootroot //****************************************************************************** // // MPLINITSHUTDOWN.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Initialization and Shutdown Module. // // This file contains the API implementations for // o MPL Initialization and Unload // o MPL Device Open and Close // o MAC, Transmit and Receive Resets // o MPL Capabilities and MTU reporting // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_INIT_DOWN, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_INIT_DOWN, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_INIT_DOWN, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_INIT_DOWN, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_INIT_DOWN, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_INIT_DOWN, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_INIT_DOWN, fmt) // Locals static NS_VOID disableDevice(IN NS_VOID *pMplHandle); //***************************************************************************** // MplInitialize // Allocate and initialize a MPL context fot the device. // // Parameters // pNsmHandle // NSM device handle for the device hardware. This handle is retained // by MPL and passed in to subsequent calls to the NSM. // pBaseAddr // The logical base address for the device. // opMode // Specifies the operational mode MPL should go into. The coverage in // each mode is shown in the below table, // For most production drivers this should be passed as MPL_MODE_NORMAL. // ========================================================== // | || NORMAL | LOAD_ONLY | MONITOR | // | Op Mode ||(non-Diag) | (Diag Mode) | (Diag Mode) | // ========================================================== // | Operation|| O W N E R | // |---------------------------------------------------------- // | H/w Init || NSM | Diag App | NSM | // --------------------------------------------------------- // | Tx/Rx || NSM | Diag App | Diag App | // ========================================================== // // pMplHandle // MPL handle for the device’s context. The NSM must retain this handle // and pass it for all subsequent MPL calls. // // Return Value // NS_STATUS_SUCCESS // The device was successfully initialized and the MPL context is // returned // NS_STATUS_INVALID_PARAM // An invalid parameter value was detected // NS_STATUS_RESOURCES // Unable to initialize a context (lack of system resources) // NS_STATUS_HARDWARE_FAILURE // Unable to initialize a context (unexpected h/w error) // or failed to detect MacPhyter device // //***************************************************************************** MPL_STATUS MplInitialize ( IN NS_VOID *pNsmHandle, IN NS_VOID *pBaseAddr, IN MPL_MODE opMode, OUT NS_VOID **pMplHandle ) { MPL_CONTEXT *pMplCtx = NULL; ENTER(MplInitialize); // FM: Assert on base addr or nsmhandle being NULL // Allocate MPL context memory pMplCtx = OaiMalloc(sizeof(MPL_CONTEXT)); if (pMplCtx == NULL) { EXIT(MplInitialize); return NS_STATUS_RESOURCES; } // Initialize context OaiZeroMem(pMplCtx, sizeof(MPL_CONTEXT)); pMplCtx->pClientHandle = pNsmHandle; pMplCtx->pRegsBase = pBaseAddr; #ifdef MPL_DIAG_MODE pMplCtx->diag.mode = opMode; if (pMplCtx->diag.mode == MPL_MODE_LOAD_ONLY) { // Nothing else to do // Set the new state of the adapter context pMplCtx->state = MPL_STATE_INIT; // Return MPL handle *pMplHandle = pMplCtx; EXIT(MplInitialize); return NS_STATUS_SUCCESS; } #endif //MPL_DIAG_MODE // Initialize the MAC and the PHY if (MplMacReset(pMplCtx) == NS_STATUS_SUCCESS) { if ((MplPhyDetect(pMplCtx) == NS_STATUS_SUCCESS) && (MplPhyReset(pMplCtx) == NS_STATUS_SUCCESS)) { // Get MAC Id MplGetDeviceId(pMplCtx); // Set defaults on the soft config regs maintained in MPL context setSoftRegs(pMplCtx, MPL_REGS_DEFAULT); // Set defaults on the adapter's config regs setHardRegs(pMplCtx); // Create Timer object to monitor phy patches OaiCreateTimer(phyTimerHandler, pMplCtx, &pMplCtx->phyTimer); // Set the new state of the adapter context pMplCtx->state = MPL_STATE_INIT; // All done *pMplHandle = pMplCtx; EXIT(MplInitialize); return NS_STATUS_SUCCESS; } } // Failed to initialize! OaiFree(sizeof(MPL_CONTEXT), pMplCtx); EXIT(MplInitialize); return NS_STATUS_HARDWARE_FAILURE; } //***************************************************************************** // MplOpen // Opens the device for network operation. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize. // // Return Value // NS_STATUS_SUCCESS // The device was successfully opened and is ready for network operation // NS_STATUS_INVALID_PARAM // An invalid parameter value was detected or this function is called // prior to MplInitialize // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplOpen ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplOpen); // Make sure we entered from the right state if (pMplCtx->state != MPL_STATE_INIT) { EXIT(MplOpen); return NS_STATUS_INVALID_PARM; } // Set new state and full POWER pMplCtx->state = MPL_STATE_OPEN; pMplCtx->pwrState = MPL_POWER_STATE_HIGH; #ifdef MPL_DIAG_MODE if (pMplCtx->diag.mode == MPL_MODE_LOAD_ONLY) { // Nothing more to do EXIT(MplOpen); return NS_STATUS_SUCCESS; } #endif //MPL_DIAG_MODE // Clear all pending events MPL_READ32(pMplCtx, ISR); // Enable RX engine MPL_WRITE32(pMplCtx, CR, RX_EN); // And go! MplInterruptEnable(pMplHandle); EXIT(MplOpen); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplClose // Closes the network device, disabling network transmission/reception and // interrupts. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The device was successfully closed // NS_STATUS_INVALID_PARAM // An invalid parameter value was detected or this function is called // prior to MplInitialize or MplOpen // //***************************************************************************** MPL_STATUS MplClose ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplClose); // Make sure we entered from the right states if (pMplCtx->state != MPL_STATE_OPEN) { EXIT(MplClose); return NS_STATUS_INVALID_PARM; } // Disable the device disableDevice(pMplCtx); // Free Txd ring related mem freeTxdRing(pMplCtx); // Free Rxd ring related mem freeRxdRing(pMplCtx); // Set new state pMplCtx->state = MPL_STATE_INIT; EXIT(MplClose); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplUnload // Shuts down the device hardware and frees all allocated resources claimed // by MplInitialize. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // MPL was successfully unloaded and all resources released. // NS_STATUS_INVALID_PARAM // An invalid parameter value was detected or this function is called // prior to MplInitialize // //***************************************************************************** MPL_STATUS MplUnload ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplUnload); // Make sure we entered from the right state if (pMplCtx->state != MPL_STATE_INIT) { EXIT(MplOpen); return NS_STATUS_INVALID_PARM; } // Disable the adapter disableDevice(pMplCtx); // Free Txd and Rxd Rings freeTxdRing(pMplCtx); freeRxdRing(pMplCtx); // Delete Timer Object OaiDeleteTimer(pMplCtx->phyTimer); // Free the MPL context OaiFree(sizeof(MPL_CONTEXT), pMplCtx); EXIT(MplUnload); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplMacReset // Resets the network device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The network device was successfully reset. // NS_STATUS_HARDWARE_FAILURE // Unexpected hardware error // //***************************************************************************** MPL_STATUS MplMacReset ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 i; ENTER(MplMacReset); // Disable the adapter disableDevice(pMplCtx); // Pull reset, wait (total 10 msec) and check for completion MPL_WRITE32(pMplCtx, CR, SOFTRESET); OaiSleep(RESETINTERVAL_MAC); for (i = 0x0; (i < 10) && (MPL_READ32(pMplCtx, CR) & SOFTRESET); i++) { OaiSleep(RESETINTERVAL_MAC); } if ((MPL_READ32(pMplCtx, CR) & SOFTRESET)) { EXIT(MplMacReset); return NS_STATUS_HARDWARE_FAILURE; // device failed to flag completion } #ifndef MPL_NO_EEPROM // Reload defaults from EEPROM, wait (total 10 msec) and check for completion MPL_WRITE32(pMplCtx, MTSCR, MPL_READ32(pMplCtx, MTSCR) | EELOAD_EN); OaiSleep(EELOADINTERVAL); for (i = 0x0; (i < 10) && (MPL_READ32(pMplCtx, MTSCR) & EELOAD_EN); i++) { OaiSleep(EELOADINTERVAL); } if ((MPL_READ32(pMplCtx, MTSCR) & EELOAD_EN)) { EXIT(MplMacReset); MPL_TRACE(("Warning : EEPROM Load did not complete \n")); // Get the MAC address from the EEPROM and set on MAC manually // This will atleast get us going... MplGetMacAddress(pMplCtx, NS_TRUE, pMplCtx->permMacAddr); MplSetMacAddress(pMplCtx, pMplCtx->permMacAddr); } #endif// MPL_NO_EEPROM // Get the permanent MAC address and store it away MplGetMacAddress(pMplHandle, NS_FALSE, pMplCtx->permMacAddr); EXIT(MplMacReset); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplCfgMTU // Configures the maximum packet size supported by MPL // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // mtu // The maximum packet size queued for transmission or reception // // Return Value // NS_STATUS_SUCCESS // The requested MTU was successfully configured on the device. // NS_STATUS_INVALID_PARAM // The size is greater than the maximum supported on the device. // //***************************************************************************** MPL_STATUS MplCfgMTU ( IN NS_VOID *pMplHandle, IN NS_UINT mtu ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 regVal; ENTER(MplCfgMTU); // Make sure we are within limits if (mtu > pMplCtx->caps.txCaps.maxPacketSize) { EXIT(MplCfgMTU); return NS_STATUS_INVALID_PARM; } // Note the MTU in the context pMplCtx->mtu = mtu; // Enable jumbo if mtu larger than Ethernet MTU if (mtu > MTU_ETHERNET) { regVal = MPL_READ32(pMplCtx, RXCFG); regVal |= ACCEPT_LONGPKT; MPL_WRITE32(pMplCtx, RXCFG, regVal); } EXIT(MplCfgMTU); return NS_STATUS_SUCCESS; } //+++++ Local Functions //##################### //***************************************************************************** // setSoftRegs // Set the software cfg regs (i.e. reg fields maintained in the MPL // context area) with either the default values or the current value // (by reading from the hardware cfg regs). // // Parameters // pMplHandle // MPL device handle // valType // Type of value of be written (MPL_REGS_DEFAULT or MPL_REGS_CURRENT) // // Return Value // None // //***************************************************************************** NS_VOID setSoftRegs( IN NS_VOID *pMplHandle, IN MPL_REGS_TYPE valType ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(setSoftRegs); // Set the soft register to default or to the current values on the device if (valType == MPL_REGS_DEFAULT) { // CFG Register Defaults - Respect EEPROM loaded bits and retain them pMplCtx->cfgReg = MPL_READ32(pMplCtx, CFG) & CFG_EEPROM_MASK; pMplCtx->cfgReg |= CFG_DEFAULT; // IMR Register Defaults pMplCtx->imrReg = IMR_DEFAULT; // IER Register Defaults pMplCtx->ierReg = IER_DEFAULT; // IHR Register Defaults pMplCtx->ihrReg = IHR_DEFAULT; // TXCFG Register Defaults pMplCtx->txCfgReg = TXCFG_DEFAULT; // RXCFG Register Defaults pMplCtx->rxCfgReg = RXCFG_DEFAULT; // GPIO Register Defaults- Respect EEPROM loaded bits and retain them pMplCtx->gpioReg = MPL_READ32(pMplCtx, GPIOR) & GPIOR_EEPROM_MASK; pMplCtx->gpioReg |= GPIOR_DEFAULT; // CCSR Register Defaults - Respect EEPROM loaded bits and retain them pMplCtx->ccsrReg = MPL_READ32(pMplCtx, CCSR) & CCSR_EEPROM_MASK; pMplCtx->ccsrReg |= CCSR_DEFAULT; // WCSR Register Defaults - Respect EEPROM loaded bits and retain them pMplCtx->wcsrReg = MPL_READ32(pMplCtx, WCSR) & WCSR_EEPROM_MASK; pMplCtx->wcsrReg |= WCSR_DEFAULT; // RFCR Register Defaults - Respect EEPROM loaded bits and retain them pMplCtx->rfcrReg = MPL_READ32(pMplCtx, RFCR) & RFCR_EEPROM_MASK; pMplCtx->rfcrReg |= RFCR_DEFAULT; // VRCR Register Defaults pMplCtx->vrcrReg = VRCR_DEFAULT; // VIPTCR Register Defaults pMplCtx->vtcrReg = VTCR_DEFAULT; // PQCR Register Defaults pMplCtx->pqcrReg = PQCR_DEFAULT; } else { // CFG Register Contents pMplCtx->cfgReg = MPL_READ32(pMplCtx, CFG); // IMR Register Contents pMplCtx->imrReg = MPL_READ32(pMplCtx, IMR); // IER Register Contents pMplCtx->ierReg= MPL_READ32(pMplCtx, IER); // IHR Register Contents pMplCtx->ihrReg = MPL_READ32(pMplCtx, IHR); // TXCFG Register Contents pMplCtx->txCfgReg = MPL_READ32(pMplCtx, TXCFG); // RXCFG Register Contents pMplCtx->rxCfgReg = MPL_READ32(pMplCtx, RXCFG); // GPIO Register Contents pMplCtx->gpioReg = MPL_READ32(pMplCtx, GPIOR); // CCSR Register Contents pMplCtx->ccsrReg = MPL_READ32(pMplCtx, CCSR); // WCSR Register Contents pMplCtx->wcsrReg = MPL_READ32(pMplCtx, WCSR); // RFCR Register Contents pMplCtx->rfcrReg = MPL_READ32(pMplCtx, RFCR) & ~RXFLTRAM_ADDRMASK; // PQCR Register Contents pMplCtx->pqcrReg = MPL_READ32(pMplCtx, PQCR);; // VIPRCR Register Contents pMplCtx->vrcrReg = MPL_READ32(pMplCtx, VRCR); // VIPTCR Register Contents pMplCtx->vtcrReg = MPL_READ32(pMplCtx, VTCR); // BootROM Register Contents - Somehow seems to be altered on resume pMplCtx->brarReg = MPL_READ32(pMplCtx, BRAR); } EXIT(setSoftRegs); return; } //***************************************************************************** // setHardRegs // Write hardware cfg registers with current values stored in the MPL // context (i.e from the soft registers) // // Parameters // pMplHandle // MPL device handle // // Return Value // None // //***************************************************************************** NS_VOID setHardRegs( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(setHardRegs); // CFG Register Contents MPL_WRITE32(pMplCtx, CFG, pMplCtx->cfgReg); // IMR Register Contents MPL_WRITE32(pMplCtx, IMR, pMplCtx->imrReg); // IER Register Contents MPL_WRITE32(pMplCtx, IER, pMplCtx->ierReg); // IHR Register Contents MPL_WRITE32(pMplCtx, IHR, pMplCtx->ihrReg); // TXCFG Register Contents MPL_WRITE32(pMplCtx, TXCFG, pMplCtx->txCfgReg); // RXCFG Register Contents MPL_WRITE32(pMplCtx, RXCFG, pMplCtx->rxCfgReg); // GPIO Register Contents MPL_WRITE32(pMplCtx, GPIOR, pMplCtx->gpioReg); // CCSR Register Contents // The chip could be used as a LOM device or a standalone PCI device // In either case the PME bit could be enabled in the EEPROM, which // would case incoming packets to be scanned only, not passed to the host // So disable PME in normal mode and set it only while WOL is being set MPL_WRITE32(pMplCtx, CCSR, (pMplCtx->ccsrReg & ~PMEEN)); // WCSR Register Contents MPL_WRITE32(pMplCtx, WCSR, pMplCtx->wcsrReg); // PQCR Register Contents MPL_WRITE32(pMplCtx, PQCR, pMplCtx->pqcrReg); // VIPRCR Register Contents MPL_WRITE32(pMplCtx, VRCR, pMplCtx->vrcrReg); // VIPTCR Register Contents MPL_WRITE32(pMplCtx, VTCR, pMplCtx->vtcrReg); // BRAR Register Contents #if 0 // Writing to BRAR and following it with a RFCR read does not work on MP-1/2 // So for now disable this // Now to start-off we should not even be saving this reg - But on Linux // it apprears that a suspend-resume causes this to be altered MPL_WRITE32(pMplCtx, BRAR, pMplCtx->brarReg); #endif // RFCR Register Contents - Disable before writing MPL_WRITE32(pMplCtx, RFCR, 0x0); MPL_WRITE32(pMplCtx, RFCR, pMplCtx->rfcrReg); EXIT(setHardRegs); return; } //***************************************************************************** // disableDevice // Disable the device // // Parameters // pMplHandle // MPL device handle // // Return Value // None // //***************************************************************************** static NS_VOID disableDevice( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(disableDevice); #ifdef MPL_DIAG_MODE if (pMplCtx->diag.mode == MPL_MODE_LOAD_ONLY) { // Nothing to do EXIT(disableDevice); return; } #endif //MPL_DIAG_MODE // Disable adapter interrupts MplInterruptDisable(pMplHandle); // Disable all transmit and receive engines MPL_WRITE32(pMplCtx, CR, TX_DIS | RX_DIS); EXIT(disableDevice); return; } DP8381X-Linux-Ver-1.6/Mpl/mplinternal.h0000444000000000000000000002742310430225754016122 0ustar rootroot //********************************************************************** // // MPLINTERNAL.H // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // This is the internal file with definitions meant for MPL private // //********************************************************************** #ifndef _MPLINTERNAL_H #define _MPLINTERNAL_H #include // Public #include // Private #include // Public #include // Shared #include // Public #include // Public // Task Offload #ifdef MPL_TASK_RECEIVE_FILTER #include // Private #include // Public #endif // MPL_TASK_RECEIVE_FILTER #ifdef MPL_TASK_VLAN #include // Private #include // Public #endif // MPL_TASK_VLAN //********************************************************************** // Byte Ordering Macros // // MPL_SWAP16, MPL_SWAP32 - Swapper Macros // MPL_HTOL16, MPL_HTOL32, MPL_ADDR_HTOL - Host to Little Endian // MPL_HTOB16, MPL_HTOB32, MPL_ADDR_HTOB - Host to Big Endian // MPL_LTOH16, MPL_LTOH32, MPL_ADDR_LTOH - Little Endian to Host // MPL_BTOH16, MPL_BTOH32, MPL_ADDR_BTOH - Big Endian to Host //********************************************************************** #define MPL_SWAP16(value) ((value) >> 8 | (value) << 8) #define MPL_SWAP32(value) \ (((value) >> 24 | ((value) & 0x00FF0000) >> 8 | \ ((value) & 0x0000FF00) << 8 | (value) << 24)) #ifdef MPL_BIG_ENDIAN #define MPL_HTOL16(val) ((NS_UINT16)(MPL_SWAP16((NS_UINT16)(val)))) #define MPL_LTOH16(val) ((NS_UINT16)(MPL_SWAP16((NS_UINT16)(val)))) #define MPL_HTOL32(val) ((NS_UINT32)(MPL_SWAP32((NS_UINT32)(val)))) #define MPL_LTOH32(val) ((NS_UINT32)(MPL_SWAP32((NS_UINT32)(val)))) #define MPL_HTOB16(val) ((NS_UINT16)(val)) #define MPL_BTOH16(val) ((NS_UINT16)(val)) #define MPL_HTOB32(val) ((NS_UINT32)(val)) #define MPL_BTOH32(val) ((NS_UINT32)(val)) #define MPL_ADDR_HTOB(val) (val) #define MPL_ADDR_BTOH(val) (val) #define MPL_ADDR_HTOL(val) MPL_SWAP32(val) #define MPL_ADDR_LTOH(val) MPL_SWAP32(val) #else // !MPL_BIG_ENDIAN #define MPL_HTOL16(val) ((NS_UINT16)(val)) #define MPL_LTOH16(val) ((NS_UINT16)(val)) #define MPL_HTOL32(val) ((NS_UINT32)(val)) #define MPL_LTOH32(val) ((NS_UINT32)(val)) #define MPL_ADDR_HTOL(val) (val) #define MPL_ADDR_LTOH(val) (val) #define EPL_ADDR_HTOB(val) MPL_SWAP32(val) #define EPL_ADDR_BTOH(val) MPL_SWAP32(val) #define MPL_HTOB16(val) ((NS_UINT16)(MPL_SWAP16((NS_UINT16)(val)))) #define MPL_BTOH16(val) ((NS_UINT16)(MPL_SWAP16((NS_UINT16)(val)))) #define MPL_HTOB32(val) ((NS_UINT32)(MPL_SWAP32((NS_UINT32)(val)))) #define MPL_BTOH32(val) ((NS_UINT32)(MPL_SWAP32((NS_UINT32)(val)))) #endif // MPL_BIG_ENDIAN //********************************************************************** // Internal TOE Mode Register Access Macros // // MPL should use these macros whenever possible instead of using // the OaiRead/Write?? functions directly. // // Prototypes: // // NS_UINT8/16/32 // MPL_READ8/16/32( // MPL_CONTEXT *pMplCtx, // nameOfRegister) // // NS_VOID // MPL_WRITE8/16/32( // MPL_CONTEXT *pMplCtx, // nameOfRegister, // NS_UINT8/16/32 valueToWrite) // //********************************************************************** #define MPL_READ8( pMplCtx, regName) \ OaiIoRead8( pMplCtx->pClientHandle, \ (NS_UINT8 volatile *) \ &pMplCtx->pRegsBase->regName) #define MPL_READ16( pMplCtx, regName) \ MPL_LTOH16( OaiIoRead16( pMplCtx->pClientHandle, \ (NS_UINT16 volatile *) \ &pMplCtx->pRegsBase->regName)) #define MPL_READ32( pMplCtx, regName) \ MPL_LTOH32( OaiIoRead32( pMplCtx->pClientHandle, \ (NS_UINT32 volatile *) \ &pMplCtx->pRegsBase->regName)) #define MPL_WRITE8( pMplCtx, regName, value) \ OaiIoWrite8( pMplCtx->pClientHandle, \ (NS_UINT8 volatile *) \ &pMplCtx->pRegsBase->regName, (value)) #define MPL_WRITE16( pMplCtx, regName, value) \ OaiIoWrite16( pMplCtx->pClientHandle, \ (NS_UINT16 volatile *) \ &pMplCtx->pRegsBase->regName, \ MPL_HTOL16((value))) #define MPL_WRITE32( pMplCtx, regName, value) \ OaiIoWrite32( pMplCtx->pClientHandle, \ (NS_UINT32 volatile *) \ &pMplCtx->pRegsBase->regName, \ MPL_HTOL32((value))) // MPL States typedef enum _MPL_STATES { MPL_STATE_INIT, MPL_STATE_OPEN } MPL_STATES; // Register value type typedef enum _MPL_REGS_TYPE{ MPL_REGS_DEFAULT, MPL_REGS_CURRENT } MPL_REGS_TYPE; // Device Descriptor (same for Tx and Rx - Hw Spec Defined) typedef struct _MPL_DESC { NS_ADDR linkPA; // Link for the next descriptor NS_UINT32 cmdSts; // Cmd status NS_ADDR bufptrPA; // Address of the data buffer #ifdef MPL_TASK_VLAN NS_UINT32 extCtlSts; // Cmd status NS_UINT32 pad1; // Cmd status NS_UINT32 pad2; // Cmd status NS_UINT32 pad3; // Cmd status #endif NS_VOID *mplPriv; // Private use of MPL } MPL_DESC; // Receive Queue typedef struct _MPL_RECEIVE_QUEUE { MPL_DESC *pRing; // Device Descriptor Ring NS_UINT curr; // First Rxd with unused buffer, // i.e. ready for hardware. NS_UINT dirty; // First Rxd with used buffer // i.e. needs replenishing. NS_UINT descCnt; // Count of descriptors in the Ring NS_ADDR ringPA; // Physical address of the Ring head MPL_MEM_REGION *pRgnHndl; // DMA region handle // Below are for tracking partial frames in descriptors MPL_PKT_FRAG *pFragHead; // Head frag of the partial packet MPL_PKT_FRAG *pFragTail; // Tail frag of the partial packet NS_UINT fragCnt; // Number of frags collected so far NS_UINT packetSize; // Total size of the packet } MPL_RECEIVE_QUEUE; // Transmit Queue typedef struct _MPL_TRANSMIT_QUEUE { MPL_DESC *pRing; // Device Descriptor Ring NS_UINT curr; // First Free Txd in Ring NS_UINT dirty; // First Used/Full Txd in Ring NS_UINT descCnt; // Count of descriptors in the Ring NS_ADDR ringPA; // Physical address of the Ring head MPL_MEM_REGION *pRgnHndl; // DMA region handle } MPL_TRANSMIT_QUEUE; #ifdef MPL_DIAG_MODE // Diag Mode Context typedef struct _MPL_DIAG { MPL_MODE mode; // Current Operation Mode } MPL_DIAG; #endif //MPL_DIAG_MODE // MPL Context typedef struct _MPL_CONTEXT { NS_VOID *pClientHandle; // MPL Client handle MPL_STATES state; // Current MPL State DP8381xOpRegs *pRegsBase; // Register base MPL_DEVICE_ID devId; // MAC Device Id NS_UINT32 srr; // Silicon Version NS_UINT8 permMacAddr[6]; // Permanent (EEPROM) mac address NS_UINT16 mtu; // Current MTU MPL_CAPS caps; // Capabilities of device and MPL NS_UINT32 cfgReg; // CFG reg snapshot NS_UINT32 imrReg; // IMR reg snapshot NS_UINT32 ierReg; // IER reg snapshot NS_UINT32 ihrReg; // IHR reg snapshot NS_UINT32 isrReg; // ISR reg snapshot NS_UINT32 txCfgReg; // TXCFG reg snapshot NS_UINT32 rxCfgReg; // RXCFG reg snapshot NS_UINT32 gpioReg; // GPIO reg snapshot NS_UINT32 wcsrReg; // WCSR reg snapshot NS_UINT32 ccsrReg; // WCSR reg snapshot NS_UINT32 rfcrReg; // RFCR reg snapshot NS_UINT32 pqcrReg; // PQCR reg snapshot NS_UINT32 vrcrReg; // VRCR reg snapshot NS_UINT32 vtcrReg; // VTCR reg snapshot NS_UINT32 brarReg; // BRAR reg snapshot NS_UINT8 txQueueCnt; // Enabled Transmit Queues NS_UINT txDescCnt; // Total Txd count NS_UINT maxTxDones; // Max indications in one // transmit done notification to NSM MPL_TRANSMIT_DONE *txDone; // Transmit done indication container MPL_TRANSMIT_QUEUE txQueue[MPL_TRANSMIT_MAX_PRIORITYQ_CNT]; // Queues NS_UINT rxDescCnt; // Total Rxd count NS_UINT maxRxDones; // Max indications in one // receive done notification to NSM MPL_PKT *rxDone; // Receive done indication pkts MPL_RECEIVE_QUEUE rxQueue; // Just one Rxd Queue NS_UINT phyDeviceAddr; // Address of PHY on MII bus NS_UINT phySiliconRev; // Silicon version of PHY NS_VOID *phyTimer; // Timer to monitor phy patches MPL_LINK_CFG linkCfg; // Link configuration MPL_LINK_STATUS linkStatus; // Current link status NS_UINT pauseType; // Current link status MPL_POWER_STATE pwrState; // Current power state NS_UINT pwrWakeType; // Current wake types #ifdef MPL_DIAG_MODE MPL_DIAG diag; // Diag mode context #endif //MPL_DIAG_MODE #ifdef MPL_TASK_RECEIVE_FILTER MPL_TASK_FILTER taskRxFilter; // Rx Filter Task Context #endif // MPL_TASK_RECEIVE_FILTER #ifdef MPL_TASK_VLAN MPL_TASK_VLAN_CTX taskVlan; // VLAN Task Context #endif // MPL_TASK_VLAN } MPL_CONTEXT; // Checked build internal definitions. #ifdef MPL_CHECKED_BUILD #define NS_PHYS_ADDR_BUF_SIZE (2 * sizeof( NS_ADDR) + 1) #define NS_LOG_ADDR_BUF_SIZE (2 * sizeof( NS_VOID *) + 1) #endif //MPL_CHECKED_BUILD // MPL Internally Shared APIs #if defined(__cplusplus) extern "C" { #endif NS_VOID freeTxdRing( IN MPL_CONTEXT *pMplCtx ); NS_VOID freeRxdRing( IN MPL_CONTEXT *pMplCtx ); NS_VOID setSoftRegs( IN NS_VOID *pMplHandle, IN MPL_REGS_TYPE valType ); NS_VOID setHardRegs( IN NS_VOID *pMplHandle ); NS_VOID phyTimerHandler( IN NS_VOID *pMplHandle ); #if defined(__cplusplus) } #endif #endif // _MPLINTERNAL_H DP8381X-Linux-Ver-1.6/Mpl/mpllink.c0000444000000000000000000003604610430225754015237 0ustar rootroot //****************************************************************************** // // MPLLINK.C // // Copyright (c) 2004 National Semiconductor Corporation. // All Rights Reserved // // MPL Link Processing. // // This file contains the API implementations for // o MPL link configuration // o Processing link change events // o Reporting link status // //****************************************************************************** #include // Local helful debug macros #undef ENTER #undef EXIT #undef ASSERT #undef PRINT #undef PRINTI #undef PRINTS #undef TBREAK #define ENTER(fn) MPL_CENTER(DZONE_MPL_LINK, fn) #define EXIT(fn) MPL_CEXIT(DZONE_MPL_LINK, fn) #define ASSERT(le) MPL_CASSERT(DZONE_MPL_LINK, le) #define PRINT(fmt) MPL_CTRACE(DZONE_MPL_LINK, fmt) #define PRINTI(v) MPL_CTRACE(DZONE_MPL_LINK, (" "#v": %x \n",(NS_UINT)(v))) #define PRINTS(v) MPL_CTRACE(DZONE_MPL_LINK, (" "#v": %s \n", v)) #define TBREAK(fmt) MPL_CTRACEBREAK(DZONE_MPL_LINK, fmt) // Locals static NS_BOOLEAN linkCompare(MPL_CONTEXT *pMplCtx, MPL_LINK_CFG *pLinkCfg); static NS_VOID setPause(MPL_CONTEXT *pMplCtx); //***************************************************************************** // MplLinkCfg // Configures the network media speed (10/100), duplex (half/full), // negotiation (Auto/Forced) and network PAUSE parameters. // When configuring auto mode, the speed and duplex setting passed should // reflect the best case scenario i.e most desired speed and duplex // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pLinkCfg // Points to a MPL_LINK_CFG structure with the desired link // configuration. // // Return Value // NS_STATUS_SUCCESS // Link configured and the link is UP. // NS_STATUS_ASYNCH_COMPLETION // Link is currently being configured or being negotiated. // NS_STATUS_INVALID_PARM // An invalid parameter was detected in the configuration structure. // NS_STATUS_HARDWARE_FAILURE // An expected failure occured while setting the link config // //***************************************************************************** MPL_STATUS MplLinkCfg ( IN NS_VOID *pMplHandle, IN MPL_LINK_CFG *pLinkCfg ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; MPL_STATUS status; ENTER(MplLinkCfg); // FM: Assert for pLinkCfg == NULL // We start with no link pMplCtx->linkStatus = MPL_LINK_STATUS_NONE; // Make a copy of the requested configuration. OaiMemCopy(&pMplCtx->linkCfg, pLinkCfg, sizeof(MPL_LINK_CFG)); // If the current link matches what's requested then don't bother setting it. if (linkCompare(pMplCtx, pLinkCfg) == NS_TRUE) { pMplCtx->linkStatus = MPL_LINK_STATUS_UP; EXIT(MplLinkCfg); return NS_STATUS_SUCCESS; } // Make sure we support the requested pause type if ((pLinkCfg->pauseType) && (pMplCtx->caps.linkCaps.linkFlags != MPL_LINK_PAUSE_SYMMETRICAL)) { // If the Mac does not support symmetric pause then make sure the // requested direction matches the one supported if (pLinkCfg->pauseType != pMplCtx->caps.linkCaps.linkFlags) { EXIT(MplLinkCfg); return NS_STATUS_INVALID_PARM; } } // Link is now down - Start the link setup process pMplCtx->linkStatus = MPL_LINK_STATUS_DOWN; // Setup the link on the Phy status = MplPhyLinkSetup(pMplHandle); // Check for Status if (status != NS_STATUS_SUCCESS) { EXIT(MplLinkCfg); return NS_STATUS_HARDWARE_FAILURE; } else { EXIT(MplLinkCfg); return NS_STATUS_ASYNCH_COMPLETION; } } //***************************************************************************** // MplLinkGetCfg // Returns the current link configuration on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // pLinkCfg // Pointer to a caller allocated MPL_LINK_CFG structure in which the // current link configuration is returned. // // Return Value // NS_STATUS_SUCCESS // The link configuration was successfully returned. // NS_STATUS_FAILURE // The link is not configured (yet). // //***************************************************************************** MPL_STATUS MplLinkGetCfg ( IN NS_VOID *pMplHandle, OUT MPL_LINK_CFG *pLinkCfg ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplLinkGetCfg); // Make sure the link has been configured if (pMplCtx->linkStatus == MPL_LINK_STATUS_NONE) { EXIT(MplLinkGetCfg); return NS_STATUS_FAILURE; } // Copy our current configuration and return OaiMemCopy(pLinkCfg, &pMplCtx->linkCfg, sizeof(MPL_LINK_CFG)); EXIT(MplLinkGetCfg); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplLinkGetStatus // Returns the link status reported on the device. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // MPL_LINK_STATUS_NONE // An unexpected hardware error occurred while processing this request // and the link state was not retrieved. // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up // //***************************************************************************** MPL_LINK_STATUS MplLinkGetStatus ( IN NS_VOID *pMplHandle ) { ENTER(MplLinkGetStatus); EXIT(MplLinkGetStatus); // Query the hardware and return the status return MplPhyGetLinkStatus(pMplHandle); } //***************************************************************************** // MplLinkProcessChange // Handles the link change event // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // MPL_LINK_STATUS_DOWN // The link is down. // MPL_LINK_STATUS_ACTIVE // The link is currently being configured or negotiated. // MPL_LINK_STATUS_UP // The link is up. // //***************************************************************************** MPL_LINK_STATUS MplLinkProcessChange ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; ENTER(MplLinkProcessChange); // Query the hardware on the latest status switch (MplPhyGetLinkStatus(pMplHandle)) { case MPL_LINK_STATUS_UP : // Link Up // FM : Bounce logic needed? pMplCtx->linkStatus = MPL_LINK_STATUS_UP; break; case MPL_LINK_STATUS_ACTIVE : // Link is Up, but AutoNeg still on pMplCtx->linkStatus = MPL_LINK_STATUS_ACTIVE; break; case MPL_LINK_STATUS_DOWN : // Link Down default : pMplCtx->linkStatus = MPL_LINK_STATUS_DOWN; break; } EXIT(MplLinkProcessChange); return pMplCtx->linkStatus; } //***************************************************************************** // MplLinkUpComplete // Completes the configuration of the device following the // auto-negotiation process. // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The link configuration is complete. // NS_STATUS_FAILURE // The link state is not UP. // //***************************************************************************** MPL_STATUS MplLinkUpComplete ( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; NS_UINT32 txCfgVal, rxCfgVal; ENTER(MplLinkUpComplete); // Check if the link is really up if (pMplCtx->linkStatus != MPL_LINK_STATUS_UP) { EXIT(MplLinkUpComplete); return NS_STATUS_FAILURE; } // Finish PHY link setup if (MplPhyLinkSetupComplete(pMplHandle) == NS_FALSE) { EXIT(MplLinkUpComplete); return NS_STATUS_FAILURE; } // Setup MAC operations txCfgVal = MPL_READ32(pMplCtx, TXCFG); rxCfgVal = MPL_READ32(pMplCtx, RXCFG); if (pMplCtx->linkCfg.duplex == MPL_LINK_DUPLEX_FULL) { // Set MAC to full duplex operation // Tx Engine - Ignore : Carrier Sense and Heartbeat MPL_WRITE32(pMplCtx, TXCFG, txCfgVal | CARRIER_IGNORE | SQE_IGNORE); // Rx Engine - Enable : FD operation MPL_WRITE32(pMplCtx, RXCFG, rxCfgVal | FULLDUPLEX_EN); } else { // Set MAC to half duplex operation // Tx Engine - Enable : Carrier Sense and Heartbeat MPL_WRITE32(pMplCtx, TXCFG, (txCfgVal & ~(CARRIER_IGNORE | SQE_IGNORE))); // Rx Engine - Disable : FD operation MPL_WRITE32(pMplCtx, RXCFG, (rxCfgVal & ~(FULLDUPLEX_EN))); } // Set Pause configuration on the MAC setPause(pMplCtx); EXIT(MplLinkUpComplete); return NS_STATUS_SUCCESS; } //***************************************************************************** // MplLinkInterrupt // Processes an incoming link related interrupt // At this time this is an MPL internal function (called from // MplIntteruptDoneInternal) // // Parameters // pMplHandle // MPL device handle returned following a call to MplInitialize // // Return Value // NS_STATUS_SUCCESS // The interrupt was successfully fielded. // //***************************************************************************** MPL_STATUS MplLinkInterrupt( IN NS_VOID *pMplHandle ) { MPL_CONTEXT *pMplCtx = (MPL_CONTEXT *)pMplHandle; // Notify NSM, it will ensure further processing after // taking care of synchronization issues NsmLinkStatusChange(pMplCtx->pClientHandle); return NS_STATUS_SUCCESS; } //***************************************************************************** // // linkCompare // Check if the requested link configuration matches the one on the // device // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // NS_TRUE // The requested link configuration matches the one on the device // NS_FALSE // The requested link configuration does NOT match the one on the device // //***************************************************************************** static NS_BOOLEAN linkCompare( IN MPL_CONTEXT *pMplCtx, IN MPL_LINK_CFG *pLinkCfg ) { NS_BOOLEAN autoDone; ENTER(linkCompare); // FM: Check if this version of the PHY would need some patch work // If so, then we need to reestablish link if (MplPhyRequiresPatch(pMplCtx) == NS_TRUE) { EXIT(linkCompare); return NS_FALSE; } // Check if link is up, if not no match if (MplPhyGetLinkStatus(pMplCtx) != MPL_LINK_STATUS_UP) { EXIT(linkCompare); return NS_FALSE; } // Check if speed matches if (MplPhyGetLinkSpeed(pMplCtx) != pLinkCfg->speed) { EXIT(linkCompare); return NS_FALSE; } // Check if duplex matches if (MplPhyGetLinkDuplex(pMplCtx) != pLinkCfg->duplex) { EXIT(linkCompare); return NS_FALSE; } // Check if current pause matches if (pMplCtx->pauseType != pLinkCfg->pauseType) { EXIT(linkCompare); return NS_FALSE; } // Check if Auto-Neg is requested, but prev setup was in forced mode autoDone = MplPhyAutoNegDone(pMplCtx); if ((pLinkCfg->mode == MPL_LINK_MODE_AUTO) && (autoDone == NS_FALSE)) { EXIT(linkCompare); return NS_FALSE; } // Check if forced mode is requested, but prev setup was in Auto-Neg mode if ((pLinkCfg->mode == MPL_LINK_MODE_FORCED) && (autoDone == NS_TRUE)) { EXIT(linkCompare); return NS_FALSE; } // All OK, link cfg matches return NS_TRUE; } //***************************************************************************** // // setPause // Set the pause configurations on the MAC // // Parameters // pMplCtx // Pointer to MPL Context // // Return Value // None // //***************************************************************************** static NS_VOID setPause( IN MPL_CONTEXT *pMplCtx ) { NS_UINT32 pcrVal = 0x0; MPL_LINK_CFG *pLinkCfg = &pMplCtx->linkCfg; ENTER(setPause); // Check if pause frame reception is enabled if (pMplCtx->pauseType & MPL_LINK_PAUSE_RECEIVE) { pcrVal |= RXPAUSE_EN | PS_MCAST | PS_DA; } // Check if pause frame transmission is enabled if (pMplCtx->pauseType & MPL_LINK_PAUSE_TRANSMIT) { // Status FIFO - Lower Threshold if (pLinkCfg->pauseRxSTLO == 0x0) pcrVal |= PTHRESHLO_SFIFO_DIS; else if (pLinkCfg->pauseRxSTLO < 2) pcrVal |= PTHRESHLO_SFIFO2PKTS; else if (pLinkCfg->pauseRxSTLO < 4) pcrVal |= PTHRESHLO_SFIFO4PKTS; else pcrVal |= PTHRESHLO_SFIFO8PKTS; // Status FIFO - Higher Threshold if (pLinkCfg->pauseRxSTHI < pLinkCfg->pauseRxSTLO) pLinkCfg->pauseRxSTHI = pLinkCfg->pauseRxSTLO; if (pLinkCfg->pauseRxSTHI == 0x0) pcrVal |= PTHRESHHI_SFIFO_DIS; else if (pLinkCfg->pauseRxSTHI >= 4) pcrVal |= PTHRESHHI_SFIFO8PKTS; else if (pLinkCfg->pauseRxSTHI >= 2) pcrVal |= PTHRESHHI_SFIFO4PKTS; else pcrVal |= PTHRESHHI_SFIFO2PKTS; // Data FIFO - Lower Threshold if (pLinkCfg->pauseRxDALO == 0x0) pcrVal |= PTHRESHLO_DFIFO_DIS; else if (pLinkCfg->pauseRxDALO < 512) pcrVal |= PTHRESHLO_DFIFO512; else if (pLinkCfg->pauseRxDALO < 1024) pcrVal |= PTHRESHLO_DFIFO1024; else pcrVal |= PTHRESHLO_DFIFO1536; // Data FIFO - Higher Threshold if (pLinkCfg->pauseRxDAHI < pLinkCfg->pauseRxDALO) pLinkCfg->pauseRxDAHI = pLinkCfg->pauseRxDALO; if (pLinkCfg->pauseRxDAHI == 0x0) pcrVal |= PTHRESHHI_DFIFO_DIS; else if (pLinkCfg->pauseRxDAHI >= 1024) pcrVal |= PTHRESHHI_DFIFO1536; else if (pLinkCfg->pauseRxDAHI >= 512) pcrVal |= PTHRESHHI_DFIFO1024; else pcrVal |= PTHRESHHI_DFIFO512; // Set pause counter pcrVal |= pLinkCfg->pauseCtr; } MPL_WRITE32(pMplCtx, PCR, pcrVal); EXIT(setPause); return; } DP8381X-Linux-Ver-1.6/README.txt0000444000000000000000000000361410430227312014356 0ustar rootrootDP8381X - 10/100Mbps PCI Ethernet Controllers Linux Driver Version - 1.6 Tested on Linux 2.6.X (Fedora 2/3/4) Tested on Linux 2.4.X MPL Version: 1.5 Mar-9, 2006 ----------------------------------------------------------------------------- Quick Installation Notes [Refer to release-notes.txt under DP8381X for detailed instructions] ----------------------------------------------------------------------------- BUILD ====== 1. Untar the driver files - "tar -xvzf DP8381X-Linux-Ver-X.Y.tgz" 2. Change directory to the DP8381X folder 3. Select the right make file (Makefile.2.x) depending on the kernel you are running (selects between 2.4.X and 2.6.X kernels) and rename it as Makefile 4. Run the "make" command [This produces a loadable kernel module called macphy.ko for 2.6.x and macphy.o for 2.4.x] /* Note: oai.h has numerous setting like disabling EEPROM, Big-endian mode operation etc. Please refer to the release-notes.txt and oai.h to alter behavior of the driver to suit your specific environment */ INSTALL ======= The driver can be dynamically loaded (insmod) and unloaded (rmmod) from a running kernel using insmod/rmmod (for various load options refer to release-notes.txt). # insmod macphy.ko [for 2.6.x kernel] # insmod macphy.o [for 2.4.x kernel] # rmmod macphy CONFIGURATION ============= 1. Driver/device configuration can be made by passing load options while loading the driver. Refer to the file release-notes.txt in DP8381X folder to get the complete list of options (link, descriptor count etc.) 2. IP Configuration is done using the ifconfig command. Refer to man pages of ipconfig for detailed information. 3. Mac address can be set by calling the "ip" function directly too. ip link set ethX address AA:BB:CC:DD:EE:FF /* Note: change ethX to match your device and Mac address to match your desired setting */ DP8381X-Linux-Ver-1.6/release-notes.txt0000444000000000000000000001746610430227176016211 0ustar rootrootDP8381X - Linux driver Release Notes Driver Version - 1.6 Tested on Linux 2.6.X Tested on Linux 2.4.X MPL Version (Hardware abstration layer) : 1.5 May-9, 2006 NOTE!!!!: See Design Instructions below if you will be modifying this source ============================================================================= ----------------------------------------------------------------------------- PRODUCT INFORMATION ----------------------------------------------------------------------------- The driver supports DP8381X series (MacPhyter) 10/100Mbps PCI Ethernet devices ----------------------------------------------------------------------------- INSTALLATION INSTRUCTIONS ----------------------------------------------------------------------------- 1. Build the driver (macphy.ko or macphy.o) as indicated in the build instructions (see next section) 2. The driver can be dynamically loaded and unloaded from a running kernel using insmod/rmmod. # insmod macphy.ko [for 2.6.x kernel] # insmod macphy.o [for 2.4.x kernel] # rmmod macphy 3. Load Options (e.g. insmod macphy.ko option=X) a. TxDCnt - Number of Transmit Descriptors (32bytes each) Default : 64 b. TxQCnt - Number of Transmit Queues to be enabled Default : 1, Max : 4 (only on DP83818) c. RxDCnt - Number of Receive Descriptors (32bytes each) Default : 64 d. RxQCnt Number of Receive Queues to be enabled Default : 1, Max : 1 e. LinkMode - Desired Link Setup Mode Note1: In Forced mode, if the link partner is configured for Auto-neg then only half-duplex is valid Note2: The link settings are effective only after the interface is enabled 0 : Auto Negotiate (Default) 1 : Force Speed and Duplex Mode f. LinkSpeed - Desired Link Speed Note1 : If set in AutoNeg mode then this is the Max speed advertized Note2: The link settings are effective only after the interface is enabled 0 : 100Mbps (Default) 1 : 10Mbps g. LinkDuplex - Desired Link Duplex Mode Note1 : If set in AutoNeg mode then this is the mode advertized Note2 : In Forced mode, if the link partner is configured for Auto-neg then only half-duplex is valid Note3: The link settings are effective only after the interface is enabled 0 : Full Duplex (Default) 1 : Half Duplex h. LinkPause - Desired Link Pause Mode Note1 : If set in AutoNeg mode then this is the mode advertized Note2: The link settings are effective only after the interface is enabled 0 : Receive Pause Only (Default) 1 : Transmit Pause Only 2 : Transmit and Receive Pause (Symmetrical) 3 : No Pause generation i. IntTimeHold - Interrupt Holdoff in usec (Micro) Default : 100, Max : 25500 (i.e. 25.5 msec) j. IntTxHold - Interrupt Holdoff in Tx packets Default : 2 k. IntRxHold - Interrupt Holdoff in Rx packets Default : 2 l. Wol - Desired Wol Events (Logical OR) 0x01 : MPL_WOL_MAGIC - Enable wake on Magic Pattern. 0x04 : MPL_WOL_BROADCAST - Enable wake on any broadcast packet. 0x08 : MPL_WOL_MULTICAST - Enable wake on multicast packet. 0x10 : MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to the device's address. 0x20 : MPL_WOL_LINK - Enable wake on link status change. 0x40 : MPL_WOL_ARP - Enable wake on any ARP packet. m. NSC Internal (Diag Mode only) DiagStsQueue - Number of pkts possible in the status queue Default : 256 4. The ifconfig utility may be used to activate the interface & assign an IP address. ----------------------------------------------------------------------------- BUILD INSTRUCTIONS ----------------------------------------------------------------------------- A) If you receive a single DP8381X-Linux-Ver-X.Y.tgz file then follow these instructions. The below descriptions refers to your install directory as 1. Untar the driver files - "tar -xvzf DP8381X-Linux-Ver-X.Y.tgz" 2. Change directory to the DP8381X folder 3. Select the right make file (Makefile.2.x) depending on the kernel you are running (selects between 2.4.X and 2.6.X kernels) and rename it to Makefile 4. Run the "make" command [This produces a loadable kernel module called macphy.ko for 2.6.x and macphy.o for 2.4.x] B) If you receive two files MPL-Version.tgz and NSM-Version.tgz follow these instructions. Driver is built using the gcc compiler. The driver source consists of two modules, 1. NSM - NOS Specific Module 2. MPL - MacPhyter Portability Layer The below descriptions refers to your base directory as 1. Copy the NSM files to your . 2. Copy MPL to [Now directory structure should look like - /Mpl ] 3. Select the right make file (Makefile.2.x) and rename it to Makefile 4. Run the "make" command in [This produces a loadable kernel module called macphy.ko for 2.6.x and macphy.o for 2.4.x] ----------------------------------------------------------------------------- UNIT TEST ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- REVISION HISTORY ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- FUNCTIONAL CHANGES ----------------------------------------------------------------------------- 1. v-0.9 - First Release to Validation 2. v-1.0 - First Release to field 3. v-1.2 - Added Diag support 4. v-1.3 - Fixes to support external PHY 5. v-1.4 - After validating MacPhy3, Added VLAN 5. v-1.5 - Added Pause support ----------------------------------------------------------------------------- DEFECTS CORRECTED ----------------------------------------------------------------------------- 1. v-1.1 - Fixed forced mode link-up issues ----------------------------------------------------------------------------- KNOWN ERRATA ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- VALIDATION NOTES (Responsibility - Validation) ----------------------------------------------------------------------------- * Validation Issues/Errata * Issue Details ----------------------------------------------------------------------------- Design Notes ----------------------------------------------------------------------------- 1. This driver is designed as two layers - One is a hardware specific block (MPL - MacPhyter Portablity Layer) and the other is OS specific (NSM). Both the layers share APIs as defined in oai.h (for MPL to NSM data-flow) and mplclient.h (for NSM to MPL dataflow). 2. For effecting the behavior of MPL's functional blocks, a NSM implementor needs to modify oai.h (See instructions in the file). Many options like working on Big-endian machines, disabling internal PHY, enabling task offload blocks etc can be done by simply changing the #defines in this file. 3. To change the default register values that are set on the device while it is being initialized modify the constants defined in Mpl/Public/mplregdefaults.h. You need to be careful while changing the values - Refer to the datasheets when in doubt. 5. The NSM_DIAG_MODE flag controls diagnostics APIs that are internal to NSC. Enabling this will DISABLE the network stack traffic. 6. If you are implementing a new NSM layer then refer to the file Mpl/Public/mplclient.h for all APIs that you have access to and use the Mpl/Public/oai_template.h for guidelines on what MPL expects from you.