sl@0: /* sl@0: * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: // Ethernet.h sl@0: // sl@0: // sl@0: /** @file ethernet.h sl@0: Base classes for implementating ethernet support (Kernel-side only) sl@0: @internalComponent sl@0: */ sl@0: sl@0: #ifndef __ETHERNET_H__ sl@0: #define __ETHERNET_H__ sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: /** @addtogroup enet Ethernet Drivers sl@0: * Kernel Ethernet Support sl@0: */ sl@0: sl@0: /** @addtogroup enet_ldd Driver LDD's sl@0: * @ingroup enet sl@0: */ sl@0: sl@0: const TInt KEthernetMajorVersionNumber = 1; sl@0: const TInt KEthernetMinorVersionNumber = 0; sl@0: const TInt KEthernetBuildVersionNumber = KE32BuildVersionNumber; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: const TInt KTxWorkBudgetLimit = 10; sl@0: sl@0: // Card Rx constants. sl@0: const TInt KNumRXBuffers = 40; sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: const TInt KIRQWorkBudgetLimit = 4; sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: const TInt KRxWorkBudgetLimit = 6; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: const TInt KMaxEthernetPacket = 1518; sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: const TUint16 CRC_LEN = 4; sl@0: sl@0: /** @addtogroup enet_pdd Driver PDD's sl@0: * @ingroup enet sl@0: * @{ sl@0: */ sl@0: sl@0: /** sl@0: Different Stop Modes sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: enum TStopMode sl@0: { sl@0: EStopNormal, /**< Finish sending and then stop */ sl@0: EStopEmergency /**< Just stop now */ sl@0: }; sl@0: sl@0: sl@0: class DChannelEthernet; sl@0: sl@0: sl@0: /** sl@0: Ethernet driver base class sl@0: The base class for an ethernet driver that doesn't support power control sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class DEthernet : public DBase sl@0: { sl@0: public: sl@0: /** sl@0: * Start receiving frames sl@0: * @return KErrNone if driver started sl@0: */ sl@0: virtual TInt Start() =0; sl@0: /** sl@0: * Stop receiving frames sl@0: * @param aMode The stop mode sl@0: */ sl@0: virtual void Stop(TStopMode aMode) =0; sl@0: sl@0: /** sl@0: * Validate a new config sl@0: * Validates a new configuration should be called before Configure sl@0: * @param aConfig is the configuration to be validated sl@0: * @return ETrue or EFalse if the Configuration is allowed sl@0: * @see Configure() sl@0: */ sl@0: virtual TInt ValidateConfig(const TEthernetConfigV01 &aConfig) const =0; sl@0: /** sl@0: * Configure the device sl@0: * Reconfigure the device using the new configuration supplied. sl@0: * This should not change the MAC address. sl@0: * @param aConfig The new configuration sl@0: * @see ValidateConfig() sl@0: * @see MacConfigure() sl@0: */ sl@0: virtual TInt Configure(TEthernetConfigV01 &aConfig) =0; sl@0: /** sl@0: * Change the MAC address sl@0: * Attempt to change the MAC address of the device sl@0: * @param aConfig A Configuration containing the new MAC sl@0: * @see Configure() sl@0: */ sl@0: virtual void MacConfigure(TEthernetConfigV01 &aConfig) =0; sl@0: /** sl@0: * Get the current config from the chip sl@0: * This returns the current configuration of the chip with the folling fields sl@0: * The Transmit Speed sl@0: * The Duplex Setting sl@0: * The MAC address sl@0: * @param aConfig is a TEthernetConfigV01 referance that will be filled in sl@0: */ sl@0: virtual void GetConfig(TEthernetConfigV01 &aConfig) const =0; sl@0: /** sl@0: * Check a configuration sl@0: * @param aConfig a reference to the structure TEthernetConfigV01 with configuration to check sl@0: */ sl@0: virtual void CheckConfig(TEthernetConfigV01& aConfig)=0; sl@0: sl@0: /** sl@0: * Querie the device's capibilitys sl@0: * @param aCaps To be filled in with the capibilites sl@0: */ sl@0: virtual void Caps(TDes8 &aCaps) const =0; sl@0: sl@0: /** sl@0: * Transmit data sl@0: * @param aBuffer referance to the data to be sent sl@0: * @return KErrNone if the data has been sent sl@0: */ sl@0: virtual TInt Send(TBuf8 &aBuffer) =0; sl@0: /** sl@0: * Retrieve data from the device sl@0: * Pull the received data out of the device and into the supplied buffer. sl@0: * Need to be told if the buffer is OK to use as if it not we could dump sl@0: * the waiting frame in order to clear the interrupt if necessory. sl@0: * @param aBuffer Referance to the buffer to be used to store the data in sl@0: * @param okToUse Bool to indicate if the buffer is usable sl@0: * @return KErrNone if the buffer has been filled. sl@0: */ sl@0: virtual TInt ReceiveFrame(TBuf8 &aBuffer, sl@0: TBool okToUse) =0; sl@0: sl@0: /** sl@0: * Disables all IRQ's sl@0: * @return The IRQ level before it was changed sl@0: * @see RestoreIrqs() sl@0: */ sl@0: virtual TInt DisableIrqs()=0; sl@0: /** sl@0: * Restore the IRQ's to the supplied level sl@0: * @param aIrq The level to set the irqs to. sl@0: * @see DisableIrqs() sl@0: */ sl@0: virtual void RestoreIrqs(TInt aIrq)=0; sl@0: /** sl@0: * Return the DFC Queue that this device should use sl@0: * @param aUnit The Channel number sl@0: * @return Then DFC Queue to use sl@0: */ sl@0: virtual TDfcQue* DfcQ(TInt aUnit)=0; sl@0: /** sl@0: * The Receive Isr for the device sl@0: */ sl@0: inline void ReceiveIsr(); sl@0: sl@0: #ifdef ETH_CHIP_IO_ENABLED sl@0: virtual TInt BgeChipIOCtrl(TPckgBuf &aIOData)=0; sl@0: #endif sl@0: /** sl@0: * A pointer to the logical device drivers channel that owns this device sl@0: */ sl@0: DChannelEthernet * iLdd ; sl@0: }; sl@0: sl@0: /** @} */ // End of pdd group sl@0: sl@0: /** sl@0: * @addtogroup enet_ldd_nopm_nopccard Ethernet LDD Not PCMCIA and No Power Managment sl@0: * @ingroup enet_ldd sl@0: * @ingroup enet_misa sl@0: * @ingroup enet_wins sl@0: * @{ sl@0: */ sl@0: sl@0: /** sl@0: Ethernet logical device sl@0: The class representing the ethernet logical device sl@0: @internalComponent sl@0: */ sl@0: class DDeviceEthernet : public DLogicalDevice sl@0: { sl@0: public: sl@0: /** sl@0: * The constructor sl@0: */ sl@0: DDeviceEthernet(); sl@0: /** sl@0: * Install the device sl@0: */ sl@0: virtual TInt Install(); sl@0: /** sl@0: * Get the Capabilites of the device sl@0: * @param aDes descriptor that will contain the returned capibilites sl@0: */ sl@0: virtual void GetCaps(TDes8 &aDes) const; sl@0: /** sl@0: * Create a logical channel to the device sl@0: */ sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); sl@0: }; sl@0: sl@0: sl@0: /** sl@0: Stores the Tx and RX buffers for use in a ethernet logical channel sl@0: @internalComponent sl@0: */ sl@0: class DChannelEthernetFIFO sl@0: { sl@0: public: sl@0: /** sl@0: * The TX Buffer sl@0: */ sl@0: TBuf8 iTxBuf; sl@0: sl@0: /** sl@0: * The constructor sl@0: */ sl@0: DChannelEthernetFIFO(); sl@0: /** sl@0: * The destructor sl@0: */ sl@0: ~DChannelEthernetFIFO(); sl@0: /** sl@0: * Get a empty receive buffer sl@0: * @return NULL or a pointer to the free buffer sl@0: */ sl@0: TBuf8 * GetFree(); sl@0: /** sl@0: * Get the next full buffer sl@0: * @return NULL or a pointer to the full buffer sl@0: */ sl@0: TBuf8 * GetNext(); sl@0: /** sl@0: * Move on to the next full buffer sl@0: */ sl@0: void SetNext(); sl@0: sl@0: private: sl@0: /** sl@0: * The array of receive buffers sl@0: */ sl@0: TBuf8 iRxBuf[KNumRXBuffers]; sl@0: /** sl@0: * Index into the array of the next full buffer sl@0: */ sl@0: TInt iRxQueIterNext; sl@0: /** sl@0: * Index into the array of the next empty buffer sl@0: */ sl@0: TInt iRxQueIterFree; sl@0: /** sl@0: * Count of the number of empty buffers sl@0: */ sl@0: TInt iNumFree; sl@0: }; sl@0: sl@0: /** sl@0: The logical channel for ethernet devices sl@0: The basic ethernet logical channel that doesn't support sl@0: power control or PCCard ethernet devices sl@0: @internalComponent sl@0: */ sl@0: class DChannelEthernet : public DLogicalChannel sl@0: { sl@0: public: sl@0: /** sl@0: * The state of the logical channel sl@0: */ sl@0: enum TState sl@0: { sl@0: EOpen, /**< The channel is open */ sl@0: EActive, /**< The channel is open and busy */ sl@0: EClosed /**< The channel is closed */ sl@0: }; sl@0: sl@0: /** sl@0: * Requests that can be made on the channel sl@0: */ sl@0: enum TRequest sl@0: { sl@0: ERx=1, /**< Receive a frame */ sl@0: ETx=2, /**< Transmit a frame */ sl@0: EAll=0xff /**< Complete/cancel all outstanding requests */ sl@0: }; sl@0: sl@0: /** sl@0: * The constructor sl@0: */ sl@0: DChannelEthernet(); sl@0: /** sl@0: * The destructor sl@0: */ sl@0: ~DChannelEthernet(); sl@0: sl@0: /** sl@0: * The ISR function for the channel sl@0: * This is called by the pycical channels ISR when data is received sl@0: * It passes a empty buffer to the PDD for it to store the frame in sl@0: */ sl@0: virtual void ReceiveIsr(); sl@0: sl@0: protected: sl@0: /** sl@0: * Create a logical ethernet channel sl@0: * @param aUnit The channel number to create sl@0: * @param anInfo not used, can be NULL sl@0: * @param aVer The minimun driver version allowed sl@0: * @return KErrNone if channel created sl@0: */ sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: /** sl@0: * Handle a message from the channels user sl@0: * @param aMsg The message to handle sl@0: */ sl@0: virtual void HandleMsg(TMessageBase* aMsg); sl@0: /** sl@0: * Cancel an outstanding request sl@0: * @param aMask A mask containing the requests to be canceled sl@0: */ sl@0: void DoCancel(TInt aMask); sl@0: /** sl@0: * Preform a control operation on the channel sl@0: * Control operations are: sl@0: * - Get the current configuration sl@0: * - Configure the channel sl@0: * - Set the MAC address for the channel sl@0: * - Get the capibilities of the channel sl@0: * @param aId The operation to preform sl@0: * @param a1 The data to use with the operation sl@0: * @param a2 can be NULL - not used sl@0: * @return KErrNone if operation done sl@0: */ sl@0: TInt DoControl(TInt aId, TAny* a1, TAny* a2); sl@0: /** sl@0: * Preform an asynchros operation on the channel sl@0: * Operations are: sl@0: * - Read data from the channel sl@0: * - Write data to the channel sl@0: * @param aId The operation to perform sl@0: * @param aStatus The status object to use when complete sl@0: * @param a1 The data to use sl@0: * @param a2 The length of the data to use sl@0: * @return KErrNone if operation started ok sl@0: * @see Complete() sl@0: */ sl@0: TInt DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2); sl@0: sl@0: //Override sendMsg to copy clients memory in client context for WDP. sl@0: virtual TInt SendMsg(TMessageBase* aMsg); sl@0: sl@0: TInt SendControl(TMessageBase* aMsg); sl@0: sl@0: TInt SendRequest(TMessageBase* aMsg); sl@0: sl@0: /** sl@0: * Start the channel receiving sl@0: */ sl@0: void Start(); sl@0: /** sl@0: * Shutdown the channel sl@0: */ sl@0: void Shutdown(); sl@0: sl@0: /** sl@0: * Complete an RX request sl@0: * Is run as the RX DFC and reads a buffer from the receive FIFO into sl@0: * the users buffer sl@0: */ sl@0: void DoCompleteRx(); sl@0: /** sl@0: * Completes an outstanding request sl@0: * @param aMask Specifies what request to complete sl@0: * @param aReason The reason the request is complete sl@0: * @see DoRequest() sl@0: */ sl@0: void Complete(TInt aMask, TInt aReason); sl@0: sl@0: /** sl@0: * Disables all IRQ's sl@0: * @return The IRQ level before it was changed sl@0: * @see RestoreIrqs() sl@0: */ sl@0: inline TInt DisableIrqs(); sl@0: /** sl@0: * Restore the IRQ's to the supplied level sl@0: * @param aIrq The level to set the irqs to. sl@0: * @see DisableIrqs() sl@0: */ sl@0: inline void RestoreIrqs(TInt aIrq); sl@0: sl@0: /** sl@0: * Calls the PDD's start method sl@0: * @return KErrNone if the PDD started ok sl@0: */ sl@0: inline TInt PddStart(); sl@0: /** sl@0: * Calls the PDD's Validate method sl@0: * @param aConfig The configuration to be validated sl@0: * @return KErrNone if config is valid sl@0: */ sl@0: inline TInt ValidateConfig(const TEthernetConfigV01 &aConfig) const; sl@0: /** sl@0: * Calls the PDD's Configure method sl@0: * Should call Validate first sl@0: * Will not change the MAC address sl@0: * @param aConfig The new configuration sl@0: * @see ValidateConfig() sl@0: */ sl@0: inline void PddConfigure(TEthernetConfigV01 &aConfig); sl@0: /** sl@0: * Calls the PDD's MacConfigure method sl@0: * Will not change anything but the MAC address sl@0: * @param aConfig A configuration containing the new MAC address sl@0: */ sl@0: inline void MacConfigure(TEthernetConfigV01 &aConfig); sl@0: /** sl@0: * Calls the PDD's ChheckConfig Method sl@0: * @param aConfig The config to check sl@0: */ sl@0: inline void PddCheckConfig(TEthernetConfigV01 &aConfig); sl@0: sl@0: /** sl@0: * Calls the PDD's get capibilities method sl@0: * @param aCaps Filled in with the PDD capibilites on return sl@0: */ sl@0: inline void PddCaps(TDes8 &aCaps) const; sl@0: sl@0: /** sl@0: * Sends data using the PDD sl@0: * @param aBuffer A referance to a buffer to be sent sl@0: * @return KErrNone if buffer sent sl@0: */ sl@0: inline TInt PddSend(TBuf8 &aBuffer); sl@0: /** sl@0: * Receive a frame from the PDD sl@0: * @param aBuffer A referance to the buffer that the frame is to be put in sl@0: * @param okToUse Flag to say if the buffer is valid sl@0: * @return KErrNone if the buffer now contains a frame sl@0: */ sl@0: inline TInt PddReceive(TBuf8 &aBuffer, TBool okToUse); sl@0: sl@0: private: sl@0: /** sl@0: * The DFC called by the kernel sl@0: * @param aPtr A pointer to the channel object sl@0: */ sl@0: static void CompleteRxDfc(TAny* aPtr); sl@0: sl@0: /** sl@0: * Start a read request sl@0: * @param aRxDes The buffer to be filled with data sl@0: * @param aLength The max size frame that can fit in the buffer sl@0: */ sl@0: void InitiateRead(TAny* aRxDes, TInt aLength); sl@0: /** sl@0: * Start a write request sl@0: * @param aTxDes The buffer containing the frame to be sent sl@0: * @param aLength The length of the frame to be sent sl@0: */ sl@0: void InitiateWrite(TAny* aTxDes, TInt aLength); sl@0: /** sl@0: * Validates and set a new configuration sl@0: * @param c The configuration to try sl@0: * @return KErrNone if new configuration set sl@0: */ sl@0: TInt SetConfig(TEthernetConfigV01& c); sl@0: /** sl@0: * Validates and sets a new MAC address sl@0: * @param c The configuration containing the MAC to be set sl@0: * @return KErrNone if the MAC is set ok sl@0: */ sl@0: TInt SetMAC(TEthernetConfigV01& c); sl@0: sl@0: /** sl@0: * The current channel configuration sl@0: */ sl@0: TEthernetConfigV01 iConfig; sl@0: sl@0: /** sl@0: * Pointer to the client thread sl@0: */ sl@0: DThread* iClient; sl@0: sl@0: /** sl@0: * Current state of the LDD sl@0: */ sl@0: TState iStatus; sl@0: sl@0: /** sl@0: * The receive complete DFC sl@0: */ sl@0: TDfc iRxCompleteDfc; sl@0: sl@0: /** sl@0: * Records if the channel is being shutdown sl@0: */ sl@0: TBool iShutdown; // ETrue means device is being closed sl@0: sl@0: /** sl@0: * The length of the clients buffer sl@0: */ sl@0: TInt iRxLength; sl@0: sl@0: /** sl@0: * The TX and RX buffers sl@0: */ sl@0: DChannelEthernetFIFO iFIFO; sl@0: sl@0: //Read request to store user request status for WDP sl@0: TClientBufferRequest* iReadRequest; sl@0: //Read buffer to pin client buffer in client context for WDP sl@0: TClientBuffer* iClientReadBuffer; sl@0: sl@0: //Write request to store user request status for WDP sl@0: TClientRequest* iWriteRequest; sl@0: sl@0: #ifdef ETH_CHIP_IO_ENABLED sl@0: TPckgBuf iChipInfo; sl@0: #endif sl@0: }; sl@0: /** @} */ sl@0: sl@0: #include sl@0: sl@0: #endif