diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 35ad9397a6b9..af9b8e471a70 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -161,5 +161,7 @@ source "drivers/staging/ath6kl/Kconfig" source "drivers/staging/keucr/Kconfig" +source "drivers/staging/bcm/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a33209be3bab..cad2574a2196 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/ obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ +obj-$(CONFIG_BCM_WIMAX) += bcm/ diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h new file mode 100644 index 000000000000..a7c0ce9e7fa7 --- /dev/null +++ b/drivers/staging/bcm/Adapter.h @@ -0,0 +1,714 @@ +/*********************************** +* Adapter.h +************************************/ +#ifndef __ADAPTER_H__ +#define __ADAPTER_H__ + +#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 +#include "Debug.h" + +typedef struct _LIST_ENTRY{ + struct _LIST_ENTRY *next; + struct _LIST_ENTRY *prev; +} LIST_ENTRY, *PLIST_ENTRY; + +typedef struct _BCM_LIST_ENTRY { + + LIST_ENTRY Link; + +} BCM_LIST_ENTRY, *PBCM_LIST_ENTRY; + +typedef enum _RCB_STATUS +{ + DRIVER_PROCESSED=1, + APPLICATION_PROCESSED +} RCB_STATUS, *PRCB_STATUS; + +#define fFILLED 1 +#define fEMPTY 0 + +struct _BCM_CB +{ + // The network packet that this RCB is receiving + PVOID pv_packet; + // Describes the length of the packet . + UINT ui_packet_length; + // Pointer to the first buffer in the packet (only one buffer for Rx) + PUCHAR buffer; + atomic_t status; + UINT filled; +} __attribute__((packed)); +typedef struct _BCM_CB BCM_CB,*PBCM_CB; + +typedef BCM_CB BCM_RCB, *PBCM_RCB; +typedef BCM_CB BCM_TCB, *PBCM_TCB; + +/* This is to be stored in the "pvOsDepData" of ADAPTER */ +typedef struct LINUX_DEP_DATA +{ + struct net_device *virtualdev; /* Our Interface (veth0) */ + struct net_device *actualdev; /* True Interface (eth0) */ + struct net_device_stats netstats; /* Net statistics */ + struct fasync_struct *async_queue; /* For asynchronus notification */ + +} LINUX_DEP_DATA, *PLINUX_DEP_DATA; + + +struct _LEADER +{ + USHORT Vcid; + USHORT PLength; + UCHAR Status; + UCHAR Unused[3]; +}__attribute__((packed)); +typedef struct _LEADER LEADER,*PLEADER; + +struct _PACKETTOSEND +{ + LEADER Leader; + UCHAR ucPayload; +}__attribute__((packed)); +typedef struct _PACKETTOSEND PACKETTOSEND, *PPACKETTOSEND; + + +struct _CONTROL_PACKET +{ + PVOID ControlBuff; + UINT ControlBuffLen; + struct _CONTROL_PACKET* next; +}__attribute__((packed)); +typedef struct _CONTROL_PACKET CONTROL_PACKET,*PCONTROL_PACKET; + + +struct link_request +{ + LEADER Leader; + UCHAR szData[4]; +}__attribute__((packed)); +typedef struct link_request LINK_REQUEST, *PLINK_REQUEST; + + +//classification extension is added +typedef struct _ADD_CONNECTION +{ + ULONG SrcIpAddressCount; + ULONG SrcIpAddress[MAX_CONNECTIONS]; + ULONG SrcIpMask[MAX_CONNECTIONS]; + + ULONG DestIpAddressCount; + ULONG DestIpAddress[MAX_CONNECTIONS]; + ULONG DestIpMask[MAX_CONNECTIONS]; + + USHORT SrcPortBegin; + USHORT SrcPortEnd; + + USHORT DestPortBegin; + USHORT DestPortEnd; + + UCHAR SrcTOS; + UCHAR SrcProtocol; +} ADD_CONNECTION,*PADD_CONNECTION; + + +typedef struct _CLASSIFICATION_RULE +{ + UCHAR ucIPSrcAddrLen; + UCHAR ucIPSrcAddr[32]; + UCHAR ucIPDestAddrLen; + UCHAR ucIPDestAddr[32]; + UCHAR ucSrcPortRangeLen; + UCHAR ucSrcPortRange[4]; + UCHAR ucDestPortRangeLen; + UCHAR ucDestPortRange[4]; + USHORT usVcid; +} CLASSIFICATION_RULE,*PCLASSIFICATION_RULE; + +typedef struct _CLASSIFICATION_ONLY +{ + USHORT usVcid; + ULONG DestIpAddress; + ULONG DestIpMask; + USHORT usPortLo; + USHORT usPortHi; + BOOLEAN bIpVersion; + UCHAR ucDestinationAddress[16]; +} CLASSIFICATION_ONLY, *PCLASSIFICATION_ONLY; + + +#define MAX_IP_RANGE_LENGTH 4 +#define MAX_PORT_RANGE 4 +#define MAX_PROTOCOL_LENGTH 32 +#define IPV6_ADDRESS_SIZEINBYTES 0x10 + +typedef union _U_IP_ADDRESS +{ + struct + { + ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH];//Source Ip Address Range + ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH];//Source Ip Mask Address Range + }; + struct + { + ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4];//Source Ip Address Range + ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4];//Source Ip Mask Address Range + + }; + struct + { + UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; + UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; + }; + struct + { + UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; + UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; + }; +}U_IP_ADDRESS; +struct _packet_info; + +typedef struct _S_HDR_SUPRESSION_CONTEXTINFO +{ + + UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; //Intermediate buffer to accumulate pkt Header for PHS + UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; //Intermediate buffer containing pkt Header after PHS + +}S_HDR_SUPRESSION_CONTEXTINFO; + + +typedef struct _S_CLASSIFIER_RULE +{ + ULONG ulSFID; + UCHAR ucReserved[2]; + B_UINT16 uiClassifierRuleIndex; + BOOLEAN bUsed; + USHORT usVCID_Value; + B_UINT8 u8ClassifierRulePriority; //This field detemines the Classifier Priority + U_IP_ADDRESS stSrcIpAddress; + UCHAR ucIPSourceAddressLength;//Ip Source Address Length + + U_IP_ADDRESS stDestIpAddress; + UCHAR ucIPDestinationAddressLength;//Ip Destination Address Length + UCHAR ucIPTypeOfServiceLength;//Type of service Length + UCHAR ucTosLow;//Tos Low + UCHAR ucTosHigh;//Tos High + UCHAR ucTosMask;//Tos Mask + + UCHAR ucProtocolLength;//protocol Length + UCHAR ucProtocol[MAX_PROTOCOL_LENGTH];//protocol Length + USHORT usSrcPortRangeLo[MAX_PORT_RANGE]; + USHORT usSrcPortRangeHi[MAX_PORT_RANGE]; + UCHAR ucSrcPortRangeLength; + + USHORT usDestPortRangeLo[MAX_PORT_RANGE]; + USHORT usDestPortRangeHi[MAX_PORT_RANGE]; + UCHAR ucDestPortRangeLength; + + BOOLEAN bProtocolValid; + BOOLEAN bTOSValid; + BOOLEAN bDestIpValid; + BOOLEAN bSrcIpValid; + + //For IPv6 Addressing + UCHAR ucDirection; + BOOLEAN bIpv6Protocol; + UINT32 u32PHSRuleID; + S_PHS_RULE sPhsRule; + UCHAR u8AssociatedPHSI; + + //Classification fields for ETH CS + UCHAR ucEthCSSrcMACLen; + UCHAR au8EThCSSrcMAC[MAC_ADDRESS_SIZE]; + UCHAR au8EThCSSrcMACMask[MAC_ADDRESS_SIZE]; + UCHAR ucEthCSDestMACLen; + UCHAR au8EThCSDestMAC[MAC_ADDRESS_SIZE]; + UCHAR au8EThCSDestMACMask[MAC_ADDRESS_SIZE]; + UCHAR ucEtherTypeLen; + UCHAR au8EthCSEtherType[NUM_ETHERTYPE_BYTES]; + UCHAR usUserPriority[2]; + USHORT usVLANID; + USHORT usValidityBitMap; +}S_CLASSIFIER_RULE; +//typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE; + +typedef struct _S_FRAGMENTED_PACKET_INFO +{ + BOOLEAN bUsed; + ULONG ulSrcIpAddress; + USHORT usIpIdentification; + S_CLASSIFIER_RULE *pstMatchedClassifierEntry; + BOOLEAN bOutOfOrderFragment; +}S_FRAGMENTED_PACKET_INFO,*PS_FRAGMENTED_PACKET_INFO; + +struct _packet_info +{ + //classification extension Rule + ULONG ulSFID; + USHORT usVCID_Value; + UINT uiThreshold; + // This field determines the priority of the SF Queues + B_UINT8 u8TrafficPriority; + + BOOLEAN bValid; + BOOLEAN bActive; + BOOLEAN bActivateRequestSent; + + B_UINT8 u8QueueType;//BE or rtPS + + UINT uiMaxBucketSize;//maximum size of the bucket for the queue + UINT uiCurrentQueueDepthOnTarget; + UINT uiCurrentBytesOnHost; + UINT uiCurrentPacketsOnHost; + UINT uiDroppedCountBytes; + UINT uiDroppedCountPackets; + UINT uiSentBytes; + UINT uiSentPackets; + UINT uiCurrentDrainRate; + UINT uiThisPeriodSentBytes; + LARGE_INTEGER liDrainCalculated; + UINT uiCurrentTokenCount; + LARGE_INTEGER liLastUpdateTokenAt; + UINT uiMaxAllowedRate; + UINT NumOfPacketsSent; + UCHAR ucDirection; + USHORT usCID; + S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable; + UINT uiCurrentRxRate; + UINT uiThisPeriodRxBytes; + UINT uiTotalRxBytes; + UINT uiTotalTxBytes; + UINT uiPendedLast; + UCHAR ucIpVersion; + + union + { + struct + { + struct sk_buff* FirstTxQueue; + struct sk_buff* LastTxQueue; + }; + struct + { + struct sk_buff* ControlHead; + struct sk_buff* ControlTail; + }; + }; + BOOLEAN bProtocolValid; + BOOLEAN bTOSValid; + BOOLEAN bDestIpValid; + BOOLEAN bSrcIpValid; + + BOOLEAN bActiveSet; + BOOLEAN bAdmittedSet; + BOOLEAN bAuthorizedSet; + BOOLEAN bClassifierPriority; + UCHAR ucServiceClassName[MAX_CLASS_NAME_LENGTH]; + BOOLEAN bHeaderSuppressionEnabled; + spinlock_t SFQueueLock; + void *pstSFIndication; + struct timeval stLastUpdateTokenAt; + atomic_t uiPerSFTxResourceCount; + UINT uiMaxLatency; + UCHAR bIPCSSupport; + UCHAR bEthCSSupport; +}; +typedef struct _packet_info PacketInfo; + + +typedef struct _PER_TARANG_DATA +{ + struct _PER_TARANG_DATA * next; + struct _MINI_ADAPTER * Adapter; + struct sk_buff* RxAppControlHead; + struct sk_buff* RxAppControlTail; + volatile INT AppCtrlQueueLen; + BOOLEAN MacTracingEnabled; + BOOLEAN bApplicationToExit; + S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs; + ULONG RxCntrlMsgBitMask; +} PER_TARANG_DATA, *PPER_TARANG_DATA; + + +#ifdef REL_4_1 +typedef struct _TARGET_PARAMS +{ + B_UINT32 m_u32CfgVersion; + + // Scanning Related Params + B_UINT32 m_u32CenterFrequency; + B_UINT32 m_u32BandAScan; + B_UINT32 m_u32BandBScan; + B_UINT32 m_u32BandCScan; + + // QoS Params + B_UINT32 m_u32minGrantsize; // size of minimum grant is 0 or 6 + B_UINT32 m_u32PHSEnable; + + // HO Params + B_UINT32 m_u32HoEnable; + B_UINT32 m_u32HoReserved1; + B_UINT32 m_u32HoReserved2; + + // Power Control Params + B_UINT32 m_u32MimoEnable; + B_UINT32 m_u32SecurityEnable; + /* + * bit 1: 1 Idlemode enable; + * bit 2: 1 Sleepmode Enable + */ + B_UINT32 m_u32PowerSavingModesEnable; + /* PowerSaving Mode Options: + bit 0 = 1: CPE mode - to keep pcmcia if alive; + bit 1 = 1: CINR reporing in Idlemode Msg + bit 2 = 1: Default PSC Enable in sleepmode*/ + B_UINT32 m_u32PowerSavingModeOptions; + + B_UINT32 m_u32ArqEnable; + + // From Version #3, the HARQ section renamed as general + B_UINT32 m_u32HarqEnable; + // EEPROM Param Location + B_UINT32 m_u32EEPROMFlag; + /* BINARY TYPE - 4th MSByte: + * Interface Type - 3rd MSByte: + * Vendor Type - 2nd MSByte + */ + // Unused - LSByte + B_UINT32 m_u32Customize; + B_UINT32 m_u32ConfigBW; /* In Hz */ + B_UINT32 m_u32ShutDownTimer; + + + B_UINT32 m_u32RadioParameter; + B_UINT32 m_u32PhyParameter1; + B_UINT32 m_u32PhyParameter2; + B_UINT32 m_u32PhyParameter3; + + /* in eval mode only; + * lower 16bits = basic cid for testing; + * then bit 16 is test cqich, + * bit 17 test init rang; + * bit 18 test periodic rang + * bit 19 is test harq ack/nack + */ + B_UINT32 m_u32TestOptions; + + B_UINT32 m_u32MaxMACDataperDLFrame; + B_UINT32 m_u32MaxMACDataperULFrame; + + B_UINT32 m_u32Corr2MacFlags; + + //adding driver params. + B_UINT32 HostDrvrConfig1; + B_UINT32 HostDrvrConfig2; + B_UINT32 HostDrvrConfig3; + B_UINT32 HostDrvrConfig4; + B_UINT32 HostDrvrConfig5; + B_UINT32 HostDrvrConfig6; + B_UINT32 m_u32SegmentedPUSCenable; + + // BAMC enable - but 4.x does not support this feature + // This is added just to sync 4.x and 5.x CFGs + B_UINT32 m_u32BandAMCEnable; +} STARGETPARAMS, *PSTARGETPARAMS; +#endif + +typedef struct _STTARGETDSXBUFFER +{ + ULONG ulTargetDsxBuffer; + B_UINT16 tid; + BOOLEAN valid; +}STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER; + +typedef INT (*FP_FLASH_WRITE)(struct _MINI_ADAPTER*,UINT,PVOID); + +typedef INT (*FP_FLASH_WRITE_STATUS)(struct _MINI_ADAPTER*,UINT,PVOID); + +/** +Driver adapter data structure +*/ +struct _MINI_ADAPTER +{ + struct _MINI_ADAPTER *next; + PVOID pvOsDepData; + CHAR *caDsxReqResp; + atomic_t ApplicationRunning; + volatile INT CtrlQueueLen; + atomic_t AppCtrlQueueLen; + BOOLEAN AppCtrlQueueOverFlow; + atomic_t CurrentApplicationCount; + atomic_t RegisteredApplicationCount; + BOOLEAN TimerActive; + ULONG StatisticsPointer; + struct sk_buff *RxControlHead; + struct sk_buff *RxControlTail; +// spinlock_t RxControlQueuelock; + struct semaphore RxAppControlQueuelock; + struct semaphore fw_download_sema; + + PPER_TARANG_DATA pTarangs; + spinlock_t control_queue_lock; + wait_queue_head_t process_read_wait_queue; + ULONG bcm_jiffies; /* Store Jiffies value */ + + // the pointer to the first packet we have queued in send + // deserialized miniport support variables + atomic_t TotalPacketCount; + atomic_t TxPktAvail; + + // this to keep track of the Tx and Rx MailBox Registers. + atomic_t CurrNumFreeTxDesc; + // to keep track the no of byte recieved + atomic_t RxRollOverCount; + USHORT PrevNumRecvDescs; + USHORT CurrNumRecvDescs; + atomic_t GoodRxByteCount; + atomic_t GoodRxPktCount; + atomic_t BadRxByteCount; + atomic_t RxPacketDroppedCount; + atomic_t GoodTxByteCount; + atomic_t TxTotalPacketCount; + atomic_t TxDroppedPacketCount; + ULONG LinkUpStatus; + BOOLEAN TransferMode; + UINT u32TotalDSD; + PacketInfo PackInfo[NO_OF_QUEUES]; + S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; + + /*************** qos ******************/ + UINT bETHCSEnabled; + + ULONG BEBucketSize; + ULONG rtPSBucketSize; + UCHAR LinkStatus; + BOOLEAN AutoLinkUp; + BOOLEAN AutoSyncup; + + struct net_device *dev; + UINT major; + UINT minor; + wait_queue_head_t tx_packet_wait_queue; + wait_queue_head_t process_rx_cntrlpkt; + atomic_t process_waiting; + BOOLEAN fw_download_done; + + unsigned int ctrlpkt_present; + BOOLEAN packets_given_to_all; + char *txctlpacket[MAX_CNTRL_PKTS]; + atomic_t cntrlpktCnt ; + atomic_t index_app_read_cntrlpkt; + atomic_t index_wr_txcntrlpkt; + atomic_t index_rd_txcntrlpkt; + UINT index_datpkt; + struct semaphore rdmwrmsync; + + STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; + ULONG ulFreeTargetBufferCnt; + ULONG ulCurrentTargetBuffer; + ULONG ulTotalTargetBuffersAvailable; + unsigned int timeout; + int irq; + unsigned long chip_id; + unsigned int bFlashBoot; + unsigned int if_up; +// spinlock_t sleeper_lock; + atomic_t rdm_wrm_access; + atomic_t tx_rx_access; + wait_queue_head_t lowpower_mode_wait_queue; + atomic_t bAbortedByHost; + BOOLEAN bBinDownloaded; + BOOLEAN bCfgDownloaded; + USHORT usBestEffortQueueIndex; + BOOLEAN bSyncUpRequestSent; +// struct semaphore data_packet_queue_lock; + wait_queue_head_t ioctl_fw_dnld_wait_queue; + BOOLEAN waiting_to_fw_download_done; + pid_t fw_download_process_pid; + PSTARGETPARAMS pstargetparams; + BOOLEAN device_removed; + BOOLEAN DeviceAccess; + INT DDRSetting; + BOOLEAN bDDRInitDone; + ULONG ulPowerSaveMode; + BOOLEAN bIsAutoCorrectEnabled; + spinlock_t txtransmitlock; + B_UINT8 txtransmit_running; + /* Thread for control packet handling */ + struct task_struct *control_packet_handler; + /* thread for transmitting packets. */ + struct task_struct *transmit_packet_thread; + + /* LED Related Structures */ + LED_INFO_STRUCT LEDInfo; + + /* Driver State for LED Blinking */ + LedEventInfo_t DriverState; + /* Interface Specific */ + PVOID pvInterfaceAdapter; + int (*bcm_file_download)( PVOID, + struct file *, + unsigned int); + int (*bcm_file_readback_from_chip)( PVOID, + struct file *, + unsigned int); + INT (*interface_rdm)(PVOID, + UINT , + PVOID , + INT); + INT (*interface_wrm)(PVOID, + UINT , + PVOID , + INT); + int (*interface_transmit)(PVOID, PVOID , UINT); + BOOLEAN IdleMode; + BOOLEAN bDregRequestSentInIdleMode; + BOOLEAN bTriedToWakeUpFromlowPowerMode; + BOOLEAN bShutStatus; + BOOLEAN bWakeUpDevice; + unsigned int usIdleModePattern; + //BOOLEAN bTriedToWakeUpFromShutdown; + BOOLEAN bLinkDownRequested; + unsigned int check_for_hang; + int downloadDDR; + PHS_DEVICE_EXTENSION stBCMPhsContext; + S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; + uint8_t ucaPHSPktRestoreBuf[2048]; + uint8_t bPHSEnabled; + int AutoFirmDld; + BOOLEAN bMipsConfig; + BOOLEAN bDPLLConfig; + UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; + UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; + S_FRAGMENTED_PACKET_INFO astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; + atomic_t uiMBupdate; + UINT32 PmuMode; + NVM_TYPE eNVMType; + UINT uiSectorSize; + UINT uiSectorSizeInCFG; + BOOLEAN bSectorSizeOverride; + BOOLEAN bStatusWrite; + UINT uiNVMDSDSize; + UINT uiVendorExtnFlag; + //it will always represent choosed DSD at any point of time. + // Generally it is Active DSD but in case of NVM RD/WR it might be different. + UINT ulFlashCalStart; + ULONG ulFlashControlSectionStart; + ULONG ulFlashWriteSize; + ULONG ulFlashID; + FP_FLASH_WRITE fpFlashWrite; + FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck; + + + struct semaphore NVMRdmWrmLock; + BOOLEAN bNetworkInterfaceRegistered; + BOOLEAN bNetdeviceNotifierRegistered; + struct device *pstCreatedClassDevice; + BOOLEAN bUsbClassDriverRegistered; +// BOOLEAN InterfaceUpStatus; + PFLASH2X_CS_INFO psFlash2xCSInfo; + PFLASH_CS_INFO psFlashCSInfo ; + PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo; + UINT uiFlashBaseAdd; //Flash start address + UINT uiActiveISOOffset; //Active ISO offset choosen before f/w download + FLASH2X_SECTION_VAL eActiveISO; //Active ISO section val + FLASH2X_SECTION_VAL eActiveDSD; //Active DSD val choosen before f/w download + UINT uiActiveDSDOffsetAtFwDld; //For accessing Active DSD choosen before f/w download + UINT uiFlashLayoutMajorVersion ; + UINT uiFlashLayoutMinorVersion; + BOOLEAN bAllDSDWriteAllow ; + BOOLEAN bSigCorrupted ; + //this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately. + BOOLEAN bHeaderChangeAllowed ; + INT SelectedChip ; + BOOLEAN bEndPointHalted; + //while bFlashRawRead will be true, Driver ignore map lay out and consider flash as of without any map. + BOOLEAN bFlashRawRead; + BOOLEAN bPreparingForLowPowerMode ; + BOOLEAN bDoSuspend ; + UINT syscfgBefFwDld ; + BOOLEAN StopAllXaction ; + UINT32 liTimeSinceLastNetEntry; //Used to Support extended CAPI requirements from + struct semaphore LowPowerModeSync; + ULONG liDrainCalculated; + UINT gpioBitMap; + S_BCM_DEBUG_STATE stDebugState; + +}; +typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; + + +typedef struct _DEVICE_EXTENSION +{ + PMINI_ADAPTER pAdapt; +}DEVICE_EXTENSION,*PDEVICE_EXTENSION; + + +struct _ETH_HEADER_STRUC { + UCHAR au8DestinationAddress[6]; + UCHAR au8SourceAddress[6]; + USHORT u16Etype; +}__attribute__((packed)); +typedef struct _ETH_HEADER_STRUC ETH_HEADER_STRUC, *PETH_HEADER_STRUC; + + +typedef struct FirmwareInfo +{ + PVOID pvMappedFirmwareAddress; + ULONG u32FirmwareLength; + ULONG u32StartingAddress; +}__attribute__((packed)) FIRMWARE_INFO, *PFIRMWARE_INFO; + +// holds the value of net_device structure.. +extern struct net_device *gblpnetdev; +typedef struct _cntl_pkt{ + PMINI_ADAPTER Adapter; + PLEADER PLeader; +}cntl_pkt; +typedef LINK_REQUEST CONTROL_MESSAGE; + +typedef struct _DDR_SETTING +{ + ULONG ulRegAddress; + ULONG ulRegValue; +}DDR_SETTING, *PDDR_SETTING; +typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE; +INT +InitAdapter(PMINI_ADAPTER psAdapter); + +// ===================================================================== +// Beceem vendor request codes for EP0 +// ===================================================================== + +#define BCM_REQUEST_READ 0x2 +#define BCM_REQUEST_WRITE 0x1 +#define EP2_MPS_REG 0x0F0110A0 +#define EP2_MPS 0x40 + +#define EP2_CFG_REG 0x0F0110A8 +#define EP2_CFG_INT 0x27 +#define EP2_CFG_BULK 0x25 + +#define EP4_MPS_REG 0x0F0110F0 +#define EP4_MPS 0x8C + +#define EP4_CFG_REG 0x0F0110F8 + +#define ISO_MPS_REG 0x0F0110C8 +#define ISO_MPS 0x00000000 + + +#define EP1 0 +#define EP2 1 +#define EP3 2 +#define EP4 3 +#define EP5 4 +#define EP6 5 + + +typedef enum eInterface_setting +{ + DEFAULT_SETTING_0 = 0, + ALTERNATE_SETTING_1 = 1, +}INTERFACE_SETTING; + +#endif //__ADAPTER_H__ + diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c new file mode 100644 index 000000000000..d60d8593d2ef --- /dev/null +++ b/drivers/staging/bcm/Arp.c @@ -0,0 +1,94 @@ + +/* + * File Name: Arp.c + * Abstract: This file contains the routines for handling ARP PACKETS + */ +#include "headers.h" +#define ARP_PKT_SIZE 60 + +/* ========================================================================= + * Function - reply_to_arp_request() + * + * Description - When this host tries to broadcast ARP request packet through + * the virtual interface (veth0), reply directly to upper layer. + * This function allocates a new skb for ARP reply packet, + * fills in the fields of the packet and then sends it to + * upper layer. + * + * Parameters - skb: Pointer to sk_buff structure of the ARP request pkt. + * + * Returns - None + * =========================================================================*/ + +VOID +reply_to_arp_request(struct sk_buff *skb) +{ + PMINI_ADAPTER Adapter; + struct ArpHeader *pArpHdr = NULL; + struct ethhdr *pethhdr = NULL; + UCHAR uiIPHdr[4]; + /* Check for valid skb */ + if(skb == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n"); + return; + } + + + Adapter = GET_BCM_ADAPTER(skb->dev); + /* Print the ARP Request Packet */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :"); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); + + /* + * Extract the Ethernet Header and Arp Payload including Header + */ + pethhdr = (struct ethhdr *)skb->data; + pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN); + + if(Adapter->bETHCSEnabled) + { + if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) + { + bcm_kfree_skb(skb); + return; + } + } + + // Set the Ethernet Header First. + memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN); + if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) + { + pethhdr->h_source[5]++; + } + + /* Set the reply to ARP Reply */ + pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY); + + /* Set the HW Address properly */ + memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN); + memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN); + + // Swapping the IP Adddress + memcpy(uiIPHdr,pArpHdr->ar_sip,4); + memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4); + memcpy(pArpHdr->ar_tip,uiIPHdr,4); + + /* Print the ARP Reply Packet */ + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: "); + + /* Send the Packet to upper layer */ + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); + + skb->protocol = eth_type_trans(skb,skb->dev); + skb->pkt_type = PACKET_HOST; + +// skb->mac.raw=skb->data+LEADER_SIZE; + skb_set_mac_header (skb, LEADER_SIZE); + netif_rx(skb); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n"); + return; +} + + diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c new file mode 100644 index 000000000000..489487a6edb6 --- /dev/null +++ b/drivers/staging/bcm/Bcmchar.c @@ -0,0 +1,2420 @@ +#include "headers.h" +/*************************************************************** +* Function - bcm_char_open() +* +* Description - This is the "open" entry point for the character +* driver. +* +* Parameters - inode: Pointer to the Inode structure of char device +* filp : File pointer of the char device +* +* Returns - Zero(Success) +****************************************************************/ +static struct class *bcm_class = NULL; +static int bcm_char_open(struct inode *inode, struct file * filp) +{ + PMINI_ADAPTER Adapter = NULL; + PPER_TARANG_DATA pTarang = NULL; + + Adapter = GET_BCM_ADAPTER(gblpnetdev); + pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL); + if (!pTarang) + return -ENOMEM; + + memset (pTarang, 0, sizeof(PER_TARANG_DATA)); + pTarang->Adapter = Adapter; + pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB) ; + + down(&Adapter->RxAppControlQueuelock); + pTarang->next = Adapter->pTarangs; + Adapter->pTarangs = pTarang; + up(&Adapter->RxAppControlQueuelock); + + /* Store the Adapter structure */ + filp->private_data = pTarang; + + /*Start Queuing the control response Packets*/ + atomic_inc(&Adapter->ApplicationRunning); + return 0; +} +static int bcm_char_release(struct inode *inode, struct file *filp) +{ + PPER_TARANG_DATA pTarang, tmp, ptmp; + PMINI_ADAPTER Adapter=NULL; + struct sk_buff * pkt, * npkt; + + pTarang = (PPER_TARANG_DATA)filp->private_data; + + if(pTarang == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ptarang is null\n"); + return 0; + } + + Adapter = pTarang->Adapter; + + down( &Adapter->RxAppControlQueuelock); + + tmp = Adapter->pTarangs; + for ( ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next ) + { + if ( tmp == pTarang ) + break; + } + + if ( tmp ) + { + if ( !ptmp ) + Adapter->pTarangs = tmp->next; + else + ptmp->next = tmp->next; + } + + else + { + up( &Adapter->RxAppControlQueuelock); + return 0; + } + + pkt = pTarang->RxAppControlHead; + while ( pkt ) + { + npkt = pkt->next; + kfree_skb(pkt); + pkt = npkt; + } + + up( &Adapter->RxAppControlQueuelock); + + /*Stop Queuing the control response Packets*/ + atomic_dec(&Adapter->ApplicationRunning); + + bcm_kfree(pTarang); + + /* remove this filp from the asynchronously notified filp's */ + filp->private_data = NULL; + return 0; +} + +static int bcm_char_read(struct file *filp, PCHAR buf, size_t size, loff_t *f_pos) +{ + PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; + PMINI_ADAPTER Adapter = pTarang->Adapter; + struct sk_buff* Packet = NULL; + UINT PktLen = 0; + int wait_ret_val=0; + + wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, + (pTarang->RxAppControlHead || Adapter->device_removed)); + if((wait_ret_val == -ERESTARTSYS)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Exiting as i've been asked to exit!!!\n"); + return wait_ret_val; + } + + if(Adapter->device_removed) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device Removed... Killing the Apps...\n"); + return -ENODEV; + } + + if(FALSE == Adapter->fw_download_done) + return -EACCES; + + down( &Adapter->RxAppControlQueuelock); + + if(pTarang->RxAppControlHead) + { + Packet = pTarang->RxAppControlHead; + DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail); + pTarang->AppCtrlQueueLen--; + } + + up(&Adapter->RxAppControlQueuelock); + + if(Packet) + { + PktLen = Packet->len; + if(copy_to_user(buf, Packet->data, PktLen)) + { + bcm_kfree_skb(Packet); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); + return -EFAULT; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid); + bcm_kfree_skb(Packet); + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n"); + return PktLen; +} + +static INT bcm_char_ioctl(struct inode *inode, struct file *filp, + UINT cmd, ULONG arg) +{ + PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; + PMINI_ADAPTER Adapter = pTarang->Adapter; + INT Status = STATUS_FAILURE; + IOCTL_BUFFER IoBuffer={0}; +#ifndef BCM_SHM_INTERFACE + int timeout = 0; +#endif + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); + + if(_IOC_TYPE(cmd) != BCM_IOCTL) + return -EFAULT; + if(_IOC_DIR(cmd) & _IOC_READ) + Status = !access_ok(VERIFY_WRITE, (PVOID)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + Status = !access_ok(VERIFY_READ, (PVOID)arg, _IOC_SIZE(cmd)); + else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) + Status = STATUS_SUCCESS; + + if(Status) + return -EFAULT; + + if(Adapter->device_removed) + { + return -EFAULT; + } + + if(FALSE == Adapter->fw_download_done) + { + switch (cmd) + { + case IOCTL_MAC_ADDR_REQ: + case IOCTL_LINK_REQ: + case IOCTL_CM_REQUEST: + case IOCTL_SS_INFO_REQ: + case IOCTL_SEND_CONTROL_MESSAGE: + case IOCTL_IDLE_REQ: + case IOCTL_BCM_GPIO_SET_REQUEST: + case IOCTL_BCM_GPIO_STATUS_REQUEST: + return -EACCES; + default: + break; + } + } + + Status = vendorextnIoctl(Adapter, cmd, arg); + if(Status != CONTINUE_COMMON_PATH ) + { + return Status; + } + + switch(cmd){ + // Rdms for Swin Idle... + case IOCTL_BCM_REGISTER_READ_PRIVATE: + { + RDM_BUFFER sRdmBuffer = {0}; + PCHAR temp_buff = NULL; + UINT Bufflen = 0; + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + + Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; + temp_buff = (PCHAR)kmalloc(Bufflen, GFP_KERNEL); + if(!temp_buff) + { + return STATUS_FAILURE; + } + if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, + (PUINT)temp_buff, Bufflen); + if(Status != STATUS_SUCCESS) + { + bcm_kfree(temp_buff); + return Status; + } + if(copy_to_user((PCHAR)IoBuffer.OutputBuffer, + (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) + { + Status = -EFAULT; + } + bcm_kfree(temp_buff); + break; + } + case IOCTL_BCM_REGISTER_WRITE_PRIVATE: + { + WRM_BUFFER sWrmBuffer = {0}; + UINT uiTempVar=0; + /* Copy Ioctl Buffer structure */ + + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + /* Get WrmBuffer structure */ + if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + ((uiTempVar == EEPROM_REJECT_REG_1)|| + (uiTempVar == EEPROM_REJECT_REG_2) || + (uiTempVar == EEPROM_REJECT_REG_3) || + (uiTempVar == EEPROM_REJECT_REG_4))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + Status = -EFAULT; + break; + } + Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, + (PUINT)sWrmBuffer.Data, sizeof(ULONG)); + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + Status = -EFAULT; + } + break; + } + + case IOCTL_BCM_REGISTER_READ: + case IOCTL_BCM_EEPROM_REGISTER_READ: + { + RDM_BUFFER sRdmBuffer = {0}; + PCHAR temp_buff = NULL; + UINT uiTempVar = 0; + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); + Status = -EACCES; + break; + } + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + + temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); + if(!temp_buff) + { + return STATUS_FAILURE; + } + if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + + if( +#if !defined(BCM_SHM_INTERFACE) + (((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || +#endif + ((ULONG)sRdmBuffer.Register & 0x3) + ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", + (int)sRdmBuffer.Register); + Status = -EINVAL; + break; + } + + uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; + Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, + (PUINT)temp_buff, IoBuffer.OutputLength); + if(Status != STATUS_SUCCESS) + { + bcm_kfree(temp_buff); + return Status; + } + if(copy_to_user((PCHAR)IoBuffer.OutputBuffer, + (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) + { + Status = -EFAULT; + } + bcm_kfree(temp_buff); + break; + } + case IOCTL_BCM_REGISTER_WRITE: + case IOCTL_BCM_EEPROM_REGISTER_WRITE: + { + WRM_BUFFER sWrmBuffer = {0}; + UINT uiTempVar=0; + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); + Status = -EACCES; + break; + } + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + /* Get WrmBuffer structure */ + if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + if( +#if !defined(BCM_SHM_INTERFACE) + + (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || +#endif + ((ULONG)sWrmBuffer.Register & 0x3) + ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", + (int)sWrmBuffer.Register); + Status = -EINVAL; + break; + } + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + ((uiTempVar == EEPROM_REJECT_REG_1)|| + (uiTempVar == EEPROM_REJECT_REG_2) || + (uiTempVar == EEPROM_REJECT_REG_3) || + (uiTempVar == EEPROM_REJECT_REG_4)) && + (cmd == IOCTL_BCM_REGISTER_WRITE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + Status = -EFAULT; + break; + } + + Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, + (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + Status = -EFAULT; + } + break; + } + case IOCTL_BCM_GPIO_SET_REQUEST: + { + UCHAR ucResetValue[4]; + UINT value =0; + UINT uiBit = 0; + UINT uiOperation = 0; + + GPIO_INFO gpio_info = {0}; + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); + Status = -EACCES; + break; + } + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + uiBit = gpio_info.uiGpioNumber; + uiOperation = gpio_info.uiGpioValue; + + value= (1< is not correspond to LED !!!",value); + Status = -EINVAL; + break; + } + + + if(uiOperation)//Set - setting 1 + { + //Set the gpio output register + Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG , + (PUINT)(&value), sizeof(UINT)); + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit); + break; + } + } + else//Unset - setting 0 + { + //Set the gpio output register + Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG , + (PUINT)(&value), sizeof(UINT)); + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit); + break; + } + } + + Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, + (PUINT)ucResetValue, sizeof(UINT)); + if (STATUS_SUCCESS != Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed"); + break; + } + //Set the gpio mode register to output + *(UINT*)ucResetValue |= (1<IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); + Status = -EACCES; + break; + } + Status =copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); + break; + } + + Status= copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the InputBuffer from user space err:%d",Status); + break; + } + //if LED thread is running(Actively or Inactively) set it state to make inactive + if(Adapter->LEDInfo.led_thread_running) + { + if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req"); + Adapter->DriverState = LED_THREAD_ACTIVE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req....."); + Adapter->DriverState = LED_THREAD_INACTIVE; + } + + //signal thread. + wake_up(&Adapter->LEDInfo.notify_led_event); + + } + } + break; + case IOCTL_BCM_GPIO_STATUS_REQUEST: + { + ULONG uiBit = 0; + UCHAR ucRead[4]; + GPIO_INFO gpio_info = {0}; + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + Status = -EACCES; + break; + } + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + { + Status = -EFAULT; + break; + } + uiBit = gpio_info.uiGpioNumber; + //Set the gpio output register + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, + (PUINT)ucRead, sizeof(UINT)); + if(Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); + return Status; + } + + } + break; + case IOCTL_BCM_GPIO_MULTI_REQUEST: + { + UCHAR ucResetValue[4]; + GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; + PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; + + memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO)); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + Status = -EINVAL; + break; + } + Status = copy_from_user( (PCHAR)&IoBuffer, ( PCHAR)arg, sizeof( IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); + break; + } + + Status = copy_from_user( &gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); + break; + } + if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); + Status = -EINVAL; + break; + } + + /* Set the gpio output register */ + + if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & + ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) + { + /* Set 1's in GPIO OUTPUT REGISTER */ + *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & + pgpio_multi_info[WIMAX_IDX].uiGPIOValue; + + if( *(UINT*) ucResetValue) + Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG)); + + if( Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); + return Status; + } + + /* Clear to 0's in GPIO OUTPUT REGISTER */ + *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & + ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); + + if( *(UINT*) ucResetValue) + Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG)); + + if( Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." ); + return Status; + } + } + + if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) + { + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + + if(Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed."); + return Status; + } + + pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue & + pgpio_multi_info[WIMAX_IDX].uiGPIOMask); + } + + Status = copy_to_user( (PCHAR)IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); + break; + } + } + break; + case IOCTL_BCM_GPIO_MODE_REQUEST: + { + UCHAR ucResetValue[4]; + GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; + PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode; + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + Status = -EINVAL; + break; + } + Status = copy_from_user( (PCHAR)&IoBuffer, ( PCHAR)arg, sizeof( IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); + break; + } + + Status = copy_from_user( &gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); + break; + } + + Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT)); + if( STATUS_SUCCESS != Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed"); + return Status; + } + + //Validating the request + if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); + Status = -EINVAL; + break; + } + + if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) + { + /* write all OUT's (1's) */ + *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); + /* write all IN's (0's) */ + *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); + + /* Currently implemented return the modes of all GPIO's + * else needs to bit AND with mask + * */ + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue; + + Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG)); + if( Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done"); + } + else + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed"); + Status = -EFAULT; + break; + } + } + else /* if uiGPIOMask is 0 then return mode register configuration */ + { + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue; + } + Status = copy_to_user( (PCHAR)IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); + break; + } + } + break; + + case IOCTL_MAC_ADDR_REQ: + case IOCTL_LINK_REQ: + case IOCTL_CM_REQUEST: + case IOCTL_SS_INFO_REQ: + case IOCTL_SEND_CONTROL_MESSAGE: + case IOCTL_IDLE_REQ: + { + PVOID pvBuffer=NULL; + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); + if(!pvBuffer) + { + return -ENOMEM; + } + + if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + Status = -EFAULT; + bcm_kfree(pvBuffer); + break; + } + + down(&Adapter->LowPowerModeSync); + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, + !Adapter->bPreparingForLowPowerMode, + (1 * HZ)); + if(Status == -ERESTARTSYS) + goto cntrlEnd; + + if(Adapter->bPreparingForLowPowerMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n"); + Status = STATUS_FAILURE ; + goto cntrlEnd ; + } + Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); + cntrlEnd: + up(&Adapter->LowPowerModeSync); + bcm_kfree(pvBuffer); + break; + } +#ifndef BCM_SHM_INTERFACE + case IOCTL_BCM_BUFFER_DOWNLOAD_START: + { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ; + if(NVMAccess) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); + return -EACCES; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); + if(!down_trylock(&Adapter->fw_download_sema)) + { + Adapter->bBinDownloaded=FALSE; + Adapter->fw_download_process_pid=current->pid; + Adapter->bCfgDownloaded=FALSE; + Adapter->fw_download_done=FALSE; + netif_carrier_off(Adapter->dev); + netif_stop_queue(Adapter->dev); + Status = reset_card_proc(Adapter); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "reset_card_proc Failed!\n"); + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; + } + mdelay(10); + } + else + { + + Status = -EBUSY; + + } + up(&Adapter->NVMRdmWrmLock); + break; + } + case IOCTL_BCM_BUFFER_DOWNLOAD: + { + FIRMWARE_INFO *psFwInfo=NULL; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); + do{ + if(!down_trylock(&Adapter->fw_download_sema)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n"); + Status=-EINVAL; + break; + } + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); + Status = -EFAULT; + break; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", + IoBuffer.InputLength); + psFwInfo=kmalloc(sizeof(*psFwInfo), GFP_KERNEL); + if(!psFwInfo) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Failed to allocate buffer!!!!\n"); + Status = -ENOMEM; + break; + } + if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, + IoBuffer.InputLength)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from_user 2 failed\n"); + Status = -EFAULT; + break; + } + + if(!psFwInfo->pvMappedFirmwareAddress || + (psFwInfo->u32FirmwareLength == 0)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", + psFwInfo->u32FirmwareLength); + Status = -EINVAL; + break; + } + Status = bcm_ioctl_fw_download(Adapter, psFwInfo); + if(Status != STATUS_SUCCESS) + { + if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); + } + //up(&Adapter->fw_download_sema); + + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = DRIVER_INIT; + Adapter->LEDInfo.bLedInitDone = FALSE; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + } + break ; + }while(0); + + if(Status != STATUS_SUCCESS) + up(&Adapter->fw_download_sema); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); + bcm_kfree(psFwInfo); + break; + } + case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: + { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + if(NVMAccess) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n"); + up(&Adapter->fw_download_sema); + return -EACCES; + } + if(down_trylock(&Adapter->fw_download_sema)) + { + Adapter->bBinDownloaded=TRUE; + Adapter->bCfgDownloaded=TRUE; + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); + atomic_set(&Adapter->RxRollOverCount, 0); + Adapter->CurrNumRecvDescs=0; + Adapter->downloadDDR = 0; + + //setting the Mips to Run + Status = run_card_proc(Adapter); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; + } + else + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n"); + mdelay(10); + /* Wait for MailBox Interrupt */ + if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); + } + timeout = 5*HZ; + Adapter->waiting_to_fw_download_done = FALSE; + wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, + Adapter->waiting_to_fw_download_done, timeout); + Adapter->fw_download_process_pid=INVALID_PID; + Adapter->fw_download_done=TRUE; + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); + Adapter->CurrNumRecvDescs = 0; + Adapter->PrevNumRecvDescs = 0; + atomic_set(&Adapter->cntrlpktCnt,0); + Adapter->LinkUpStatus = 0; + Adapter->LinkStatus = 0; + + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = FW_DOWNLOAD_DONE; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + + if(!timeout) + { + Status = -ENODEV; + } + } + else + { + Status = -EINVAL; + } + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; + } +#endif + case IOCTL_BE_BUCKET_SIZE: + Adapter->BEBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; + break; + + case IOCTL_RTPS_BUCKET_SIZE: + Adapter->rtPSBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; + break; + case IOCTL_CHIP_RESET: + { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + if(NVMAccess) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); + return -EACCES; + } + down(&Adapter->RxAppControlQueuelock); + Status = reset_card_proc(Adapter); + flushAllAppQ(); + up(&Adapter->RxAppControlQueuelock); + up(&Adapter->NVMRdmWrmLock); + ResetCounters(Adapter); + break; + } + case IOCTL_QOS_THRESHOLD: + { + USHORT uiLoopIndex; + for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++) + { + Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg; + } + Status = STATUS_SUCCESS; + break; + } + + case IOCTL_DUMP_PACKET_INFO: + + DumpPackInfo(Adapter); + DumpPhsRules(&Adapter->stBCMPhsContext); + Status = STATUS_SUCCESS; + break; + + case IOCTL_GET_PACK_INFO: + if(copy_to_user((PCHAR)arg, &Adapter->PackInfo, + sizeof(PacketInfo)*NO_OF_QUEUES)) + { + Status = -EFAULT; + break; + } + Status = STATUS_SUCCESS; + break; + case IOCTL_BCM_SWITCH_TRANSFER_MODE: + { + UINT uiData = 0; + if(copy_from_user(&uiData, (PUINT)arg, sizeof(UINT))) + { + Status = -EFAULT; + break; + } + if(uiData) /* Allow All Packets */ + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); + Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; + } + else /* Allow IP only Packets */ + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); + Adapter->TransferMode = IP_PACKET_ONLY_MODE; + } + Status = STATUS_SUCCESS; + break; + } + + case IOCTL_BCM_GET_DRIVER_VERSION: + { + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, + (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + if(copy_to_user((PUCHAR)IoBuffer.OutputBuffer, + VER_FILEVERSION_STR, (UINT)IoBuffer.OutputLength)) + { + Status = -EFAULT; + break; + } + Status = STATUS_SUCCESS; + break; + } + case IOCTL_BCM_GET_CURRENT_STATUS: + { + LINK_STATE *plink_state = NULL; + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, + (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); + Status = -EFAULT; + break; + } + plink_state = (LINK_STATE*)arg; + plink_state->bIdleMode = (UCHAR)Adapter->IdleMode; + plink_state->bShutdownMode = Adapter->bShutStatus; + plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus; + if(copy_to_user((PUCHAR)IoBuffer.OutputBuffer, + (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); + Status = -EFAULT; + break; + } + Status = STATUS_SUCCESS; + break; + } + case IOCTL_BCM_SET_MAC_TRACING: + { + UINT tracing_flag; + /* copy ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, + (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + if(copy_from_user((PCHAR)&tracing_flag, + (PCHAR)IoBuffer.InputBuffer,sizeof(UINT))) + { + Status = -EFAULT; + break; + } + if (tracing_flag) + Adapter->pTarangs->MacTracingEnabled = TRUE; + else + Adapter->pTarangs->MacTracingEnabled = FALSE; + break; + } + case IOCTL_BCM_GET_DSX_INDICATION: + { + ULONG ulSFId=0; + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, + sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid IO buffer!!!" ); + Status = -EFAULT; + break; + } + if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%x!!!", + IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); + return -EINVAL; + } + if(copy_from_user((PCHAR)&ulSFId, (PCHAR)IoBuffer.InputBuffer, + sizeof(ulSFId))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid SFID!!! %lu", ulSFId ); + Status = -EFAULT; + break; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId ); + get_dsx_sf_data_to_application(Adapter, ulSFId, + IoBuffer.OutputBuffer); + Status=STATUS_SUCCESS; + } + break; + case IOCTL_BCM_GET_HOST_MIBS: + { + PCHAR temp_buff; + + if(copy_from_user((PCHAR)&IoBuffer, + (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from user for IoBuff failed\n"); + Status = -EFAULT; + break; + } + + if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length Check failed %lu %d\n", IoBuffer.OutputLength, + sizeof(S_MIBS_HOST_STATS_MIBS)); + return -EINVAL; + } + + temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); + + if(!temp_buff) + { + return STATUS_FAILURE; + } + + Status = ProcessGetHostMibs(Adapter, + (PUCHAR)temp_buff, IoBuffer.OutputLength); + + Status = GetDroppedAppCntrlPktMibs((PVOID)temp_buff, + (PPER_TARANG_DATA)filp->private_data); + + if(copy_to_user((PCHAR)IoBuffer.OutputBuffer,(PCHAR)temp_buff, + sizeof(S_MIBS_HOST_STATS_MIBS))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n"); + bcm_kfree(temp_buff); + return -EFAULT; + } + + bcm_kfree(temp_buff); + break; + } + + case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: + if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode)) + { + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); + #if 0 + Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; + InterfaceAbortIdlemode (Adapter, Adapter->usIdleModePattern); + #endif + } + Status = STATUS_SUCCESS; + break; + + case IOCTL_BCM_BULK_WRM: + { + PBULKWRM_BUFFER pBulkBuffer; + UINT uiTempVar=0; + PCHAR pvBuffer = NULL; + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); + Status = -EACCES; + break; + } + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + Status = -EFAULT; + break; + } + + pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); + if(!pvBuffer) + { + return -ENOMEM; + break; + } + + /* Get WrmBuffer structure */ + if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + { + bcm_kfree(pvBuffer); + Status = -EFAULT; + break; + } + + pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; + + if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || + ((ULONG)pBulkBuffer->Register & 0x3)) + { + bcm_kfree(pvBuffer); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register); + Status = -EINVAL; + break; + } + + + uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; + if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) + && ((uiTempVar == EEPROM_REJECT_REG_1)|| + (uiTempVar == EEPROM_REJECT_REG_2) || + (uiTempVar == EEPROM_REJECT_REG_3) || + (uiTempVar == EEPROM_REJECT_REG_4)) && + (cmd == IOCTL_BCM_REGISTER_WRITE)) + { + bcm_kfree(pvBuffer); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n"); + Status = -EFAULT; + break; + } + + if(pBulkBuffer->SwapEndian == FALSE) + Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); + else + Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); + + if(Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); + } + + bcm_kfree(pvBuffer); + break; + } + + case IOCTL_BCM_GET_NVM_SIZE: + { + + if(copy_from_user((unsigned char *)&IoBuffer, + (unsigned char *)arg, sizeof(IOCTL_BUFFER))) + { + //IOLog("failed NVM first"); + Status = -EFAULT; + break; + } + if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) { + if(copy_to_user(IoBuffer.OutputBuffer, + (unsigned char *)&Adapter->uiNVMDSDSize, (UINT)sizeof(UINT))) + { + Status = -EFAULT; + return Status; + } + } + + Status = STATUS_SUCCESS ; + } + break; + + case IOCTL_BCM_CAL_INIT : + + { + UINT uiSectorSize = 0 ; + if(Adapter->eNVMType == NVM_FLASH) + { + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); + return Status; + } + uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); + if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) + { + + Status = copy_to_user(IoBuffer.OutputBuffer, + (unsigned char *)&Adapter->uiSectorSize , + (UINT)sizeof(UINT)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); + return Status; + } + } + else + { + if(IsFlash2x(Adapter)) + { + Status = copy_to_user(IoBuffer.OutputBuffer, + (unsigned char *)&Adapter->uiSectorSize , + (UINT)sizeof(UINT)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); + return Status; + } + + } + else + { + if((TRUE == Adapter->bShutStatus) || + (TRUE == Adapter->IdleMode)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n"); + return -EACCES; + } + + Adapter->uiSectorSize = uiSectorSize ; + BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize); + } + } + Status = STATUS_SUCCESS ; + } + else + { + Status = STATUS_FAILURE; + } + } + break; + case IOCTL_BCM_SET_DEBUG : + { + USER_BCM_DBG_STATE sUserDebugState; + +// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG ); + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy from user failed\n"); + break; + } + Status = copy_from_user(&sUserDebugState,(USER_BCM_DBG_STATE *)IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)); + if(Status) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IoBuffer.InputBuffer failed"); + return Status; + } + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", + sUserDebugState.OnOff, sUserDebugState.Type); + //sUserDebugState.Subtype <<= 1; + sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); + + // Update new 'DebugState' in the Adapter + Adapter->stDebugState.type |= sUserDebugState.Type; + /* Subtype: A bitmap of 32 bits for Subtype per Type. + * Valid indexes in 'subtype' array: 1,2,4,8 + * corresponding to valid Type values. Hence we can use the 'Type' field + * as the index value, ignoring the array entries 0,3,5,6,7 ! + */ + if (sUserDebugState.OnOff) + Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; + else + Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; + + BCM_SHOW_DEBUG_BITMAP(Adapter); + + } + break; + case IOCTL_BCM_NVM_READ: + case IOCTL_BCM_NVM_WRITE: + { + + NVM_READWRITE stNVMReadWrite = {0}; + PUCHAR pReadData = NULL; + PUCHAR pBuffertobeCopied = NULL; + ULONG ulDSDMagicNumInUsrBuff = 0 ; + struct timeval tv0, tv1; + memset(&tv0,0,sizeof(struct timeval)); + memset(&tv1,0,sizeof(struct timeval)); + if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); + Status = -EFAULT; + break; + } + + if(IsFlash2x(Adapter)) + { + if((Adapter->eActiveDSD != DSD0) && + (Adapter->eActiveDSD != DSD1) && + (Adapter->eActiveDSD != DSD2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked"); + return STATUS_FAILURE ; + } + } + + /* Copy Ioctl Buffer structure */ + + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copy_from_user failed\n"); + Status = -EFAULT; + break; + } + if(IOCTL_BCM_NVM_READ == cmd) + pBuffertobeCopied = IoBuffer.OutputBuffer; + else + pBuffertobeCopied = IoBuffer.InputBuffer; + + if(copy_from_user(&stNVMReadWrite, pBuffertobeCopied,sizeof(NVM_READWRITE))) + { + Status = -EFAULT; + break; + } + + // + // Deny the access if the offset crosses the cal area limit. + // + if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) + { + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset , +// stNVMReadWrite.uiNumBytes); + Status = STATUS_FAILURE; + break; + } + + pReadData =(PCHAR)kmalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); + + if(!pReadData) + return -ENOMEM; + + memset(pReadData,0,stNVMReadWrite.uiNumBytes); + + if(copy_from_user(pReadData, stNVMReadWrite.pBuffer, + stNVMReadWrite.uiNumBytes)) + { + Status = -EFAULT; + bcm_kfree(pReadData); + break; + } + + do_gettimeofday(&tv0); + if(IOCTL_BCM_NVM_READ == cmd) + { + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadData); + return -EACCES; + } + + Status = BeceemNVMRead(Adapter, (PUINT)pReadData, + stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); + + up(&Adapter->NVMRdmWrmLock); + + if(Status != STATUS_SUCCESS) + { + bcm_kfree(pReadData); + return Status; + } + if(copy_to_user((PCHAR)stNVMReadWrite.pBuffer, + (PCHAR)pReadData, (UINT)stNVMReadWrite.uiNumBytes)) + { + bcm_kfree(pReadData); + Status = -EFAULT; + } + } + else + { + + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadData); + return -EACCES; + } + + Adapter->bHeaderChangeAllowed = TRUE ; + if(IsFlash2x(Adapter)) + { + /* + New Requirement:- + DSD section updation will be allowed in two case:- + 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull + 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is + corrupted then user space program first modify the DSD header with valid DSD sig so + that this as well as further write may be worthwhile. + + This restriction has been put assuming that if DSD sig is corrupted, DSD + data won't be considered valid. + + + */ + Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD); + if(Status != STATUS_SUCCESS) + { + if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) || + (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadData); + return Status; + } + + ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); + if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadData); + return Status; + } + } + } + Status = BeceemNVMWrite(Adapter, (PUINT )pReadData, + stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); + if(IsFlash2x(Adapter)) + BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD); + + Adapter->bHeaderChangeAllowed = FALSE ; + + up(&Adapter->NVMRdmWrmLock); + + + if(Status != STATUS_SUCCESS) + { + bcm_kfree(pReadData); + return Status; + } + } + do_gettimeofday(&tv1); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000); + + + bcm_kfree(pReadData); + Status = STATUS_SUCCESS; + } + break; + case IOCTL_BCM_FLASH2X_SECTION_READ : + { + + FLASH2X_READWRITE sFlash2xRead = {0}; + PUCHAR pReadBuff = NULL ; + UINT NOB = 0; + UINT BuffSize = 0; + UINT ReadBytes = 0; + UINT ReadOffset = 0; + PUCHAR OutPutBuff = NULL; + + if(IsFlash2x(Adapter) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); + return -EINVAL; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status ; + } + + //Reading FLASH 2.x READ structure + Status = copy_from_user((PUCHAR)&sFlash2xRead, (PUCHAR)IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Input Buffer failed"); + return Status ; + } + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify); + + //This was internal to driver for raw read. now it has ben exposed to user space app. + if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE) + return STATUS_FAILURE ; + + NOB = sFlash2xRead.numOfBytes; + if(NOB > Adapter->uiSectorSize ) + BuffSize = Adapter->uiSectorSize; + else + BuffSize = NOB ; + + ReadOffset = sFlash2xRead.offset ; + OutPutBuff = (PUCHAR)(IoBuffer.OutputBuffer) ; + + + pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); + if(pReadBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); + return -ENOMEM; + } + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadBuff); + return -EACCES; + } + + while(NOB) + { + + if(NOB > Adapter->uiSectorSize ) + ReadBytes = Adapter->uiSectorSize; + else + ReadBytes = NOB; + + + //Reading the data from Flash 2.x + + Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status); + break ; + } + + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); + + Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status); + break; + } + NOB = NOB - ReadBytes; + if(NOB) + { + ReadOffset = ReadOffset + ReadBytes ; + OutPutBuff = OutPutBuff + ReadBytes ; + } + + } + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadBuff); + + } + break ; + case IOCTL_BCM_FLASH2X_SECTION_WRITE : + { + FLASH2X_READWRITE sFlash2xWrite = {0}; + PUCHAR pWriteBuff = NULL; + PUCHAR InputAddr = NULL; + UINT NOB = 0; + UINT BuffSize = 0; + UINT WriteOffset = 0; + UINT WriteBytes = 0; + + if(IsFlash2x(Adapter) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); + return -EINVAL; + } + + //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite + Adapter->bAllDSDWriteAllow = FALSE; + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } + + //Reading FLASH 2.x READ structure + Status = copy_from_user((PCHAR)&sFlash2xWrite, (PCHAR)IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reading of output Buffer from IOCTL buffer fails"); + return Status; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify); + #if 0 + if((sFlash2xWrite.Section == ISO_IMAGE1) ||(sFlash2xWrite.Section == ISO_IMAGE2) || + (sFlash2xWrite.Section == DSD0) || (sFlash2xWrite.Section == DSD1) || (sFlash2xWrite.Section == DSD2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"ISO/DSD Image write is not allowed.... "); + return STATUS_FAILURE ; + } + #endif + if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && + (sFlash2xWrite.Section != VSA2) ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed"); + return -EINVAL; + } + + if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE) + return STATUS_FAILURE ; + + InputAddr = (PCHAR)(sFlash2xWrite.pDataBuff) ; + WriteOffset = sFlash2xWrite.offset ; + NOB = sFlash2xWrite.numOfBytes; + + if(NOB > Adapter->uiSectorSize ) + BuffSize = Adapter->uiSectorSize; + else + BuffSize = NOB ; + + pWriteBuff = (PCHAR)kmalloc(BuffSize, GFP_KERNEL); + if(pWriteBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); + return -ENOMEM; + } + + //extracting the remainder of the given offset. + WriteBytes = Adapter->uiSectorSize ; + if(WriteOffset % Adapter->uiSectorSize) + WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); + if(NOB < WriteBytes) + WriteBytes = NOB; + + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pWriteBuff); + return -EACCES; + } + + BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section); + do + { + Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status); + break ; + } + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes); + //Writing the data from Flash 2.x + Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); + break ; + } + + NOB = NOB - WriteBytes; + if(NOB) + { + WriteOffset = WriteOffset + WriteBytes ; + InputAddr = InputAddr + WriteBytes ; + if(NOB > Adapter->uiSectorSize ) + WriteBytes = Adapter->uiSectorSize; + else + WriteBytes = NOB; + } + + + } while(NOB > 0); + BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pWriteBuff); + } + break ; + case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : + { + + PFLASH2X_BITMAP psFlash2xBitMap = NULL ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } + if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Structure size mismatch Lib :0x%lx Driver :0x%x ",IoBuffer.OutputLength, sizeof(FLASH2X_BITMAP)); + break; + } + + psFlash2xBitMap = (PFLASH2X_BITMAP)kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); + if(psFlash2xBitMap == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available"); + return -ENOMEM ; + } + //Reading the Flash Sectio Bit map + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(psFlash2xBitMap); + return -EACCES; + } + + BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); + up(&Adapter->NVMRdmWrmLock); + Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)psFlash2xBitMap, sizeof(FLASH2X_BITMAP)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed"); + bcm_kfree(psFlash2xBitMap); + return Status; + } + bcm_kfree(psFlash2xBitMap); + } + break ; + case IOCTL_BCM_SET_ACTIVE_SECTION : + { + FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); + + if(IsFlash2x(Adapter) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); + return -EINVAL; + } + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } + + Status = copy_from_user((PCHAR)&eFlash2xSectionVal,(PCHAR)IoBuffer.InputBuffer, sizeof(INT)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); + return Status; + } + + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } + + Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status); + } + up(&Adapter->NVMRdmWrmLock); + } + break ; + case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION : + { + //Right Now we are taking care of only DSD + Adapter->bAllDSDWriteAllow = FALSE ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); + + #if 0 + SECTION_TYPE section = 0 ; + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION Called"); + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of IOCTL BUFFER failed"); + return Status; + } + Status = copy_from_user((PCHAR)section,(PCHAR)&IoBuffer, sizeof(INT)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of section type failed failed"); + return Status; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", section); + if(section == DSD) + Adapter->ulFlashCalStart = Adapter->uiActiveDSDOffsetAtFwDld ; + else + Status = STATUS_FAILURE ; + #endif + Status = STATUS_SUCCESS ; + } + break ; + case IOCTL_BCM_COPY_SECTION : + { + FLASH2X_COPY_SECTION sCopySectStrut = {0}; + Status = STATUS_SUCCESS; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); + + Adapter->bAllDSDWriteAllow = FALSE ; + if(IsFlash2x(Adapter) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); + return -EINVAL; + } + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); + return Status; + } + + Status = copy_from_user((PCHAR)&sCopySectStrut,(PCHAR)IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); + return Status; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); + + + if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); + return -EINVAL; + } + + if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); + return -EINVAL; + } + + if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different"); + return -EINVAL; + } + + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } + + if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) + { + if(IsNonCDLessDevice(Adapter)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!"); + Status = -EINVAL ; + } + else if(sCopySectStrut.numOfBytes == 0) + { + Status = BcmCopyISO(Adapter,sCopySectStrut); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed.."); + Status = STATUS_FAILURE ; + } + up(&Adapter->NVMRdmWrmLock); + return Status; + } + + Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, + sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes); + up(&Adapter->NVMRdmWrmLock); + } + break ; + case IOCTL_BCM_GET_FLASH_CS_INFO : + { + Status = STATUS_SUCCESS; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + break; + } + if(Adapter->eNVMType != NVM_FLASH) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash"); + Status = -EINVAL; + break; + } + if(IsFlash2x(Adapter) == TRUE) + { + + if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. \nRequired size :0x%x ",IoBuffer.OutputLength, sizeof(FLASH2X_CS_INFO)); + Status = -EINVAL; + break; + } + + Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x cs info failed"); + break; + } + } + else + { + if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. Required size :0x%u ",IoBuffer.OutputLength, sizeof(FLASH_CS_INFO)); + Status = -EINVAL; + break; + } + Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash CS info failed"); + break; + } + + } + } + break ; + case IOCTL_BCM_SELECT_DSD : + { + UINT SectOfset = 0; + FLASH2X_SECTION_VAL eFlash2xSectionVal; + eFlash2xSectionVal = NO_SECTION_VAL ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called"); + + if(IsFlash2x(Adapter) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); + return -EINVAL; + } + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } + Status = copy_from_user((PCHAR)&eFlash2xSectionVal,(PCHAR)IoBuffer.InputBuffer, sizeof(INT)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); + return Status; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal); + if((eFlash2xSectionVal != DSD0) && + (eFlash2xSectionVal != DSD1) && + (eFlash2xSectionVal != DSD2) ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal); + return STATUS_FAILURE ; + } + + SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); + if(SectOfset == INVALID_OFFSET) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); + return -EINVAL; + } + + Adapter->bAllDSDWriteAllow = TRUE ; + + Adapter->ulFlashCalStart = SectOfset ; + Adapter->eActiveDSD = eFlash2xSectionVal; + } + Status = STATUS_SUCCESS ; + break; + + case IOCTL_BCM_NVM_RAW_READ : + { + + NVM_READWRITE stNVMRead = {0}; + INT NOB ; + INT BuffSize ; + INT ReadOffset = 0; + UINT ReadBytes = 0 ; + PUCHAR pReadBuff = NULL ; + PUCHAR OutPutBuff = NULL ; + + if(Adapter->eNVMType != NVM_FLASH) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash "); + return -EINVAL ; + } + + /* Copy Ioctl Buffer structure */ + if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); + Status = -EFAULT; + break; + } + + if(copy_from_user(&stNVMRead, (PUCHAR)IoBuffer.OutputBuffer,sizeof(NVM_READWRITE))) + { + Status = -EFAULT; + break; + } + + NOB = stNVMRead.uiNumBytes; + //In Raw-Read max Buff size : 64MB + + if(NOB > DEFAULT_BUFF_SIZE) + BuffSize = DEFAULT_BUFF_SIZE; + else + BuffSize = NOB ; + + ReadOffset = stNVMRead.uiOffset ; + OutPutBuff = (PUCHAR)(stNVMRead.pBuffer) ; + + + pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); + if(pReadBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); + Status = -ENOMEM; + break; + } + down(&Adapter->NVMRdmWrmLock); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); + bcm_kfree(pReadBuff); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } + + Adapter->bFlashRawRead = TRUE ; + while(NOB) + { + if(NOB > DEFAULT_BUFF_SIZE ) + ReadBytes = DEFAULT_BUFF_SIZE; + else + ReadBytes = NOB; + + //Reading the data from Flash 2.x + Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); + break; + } + + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); + + Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status); + break; + } + NOB = NOB - ReadBytes; + if(NOB) + { + ReadOffset = ReadOffset + ReadBytes ; + OutPutBuff = OutPutBuff + ReadBytes ; + } + + } + Adapter->bFlashRawRead = FALSE ; + up(&Adapter->NVMRdmWrmLock); + bcm_kfree(pReadBuff); + break ; + } + + case IOCTL_BCM_CNTRLMSG_MASK: + { + ULONG RxCntrlMsgBitMask = 0 ; + + /* Copy Ioctl Buffer structure */ + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); + break; + } + + Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); + break; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); + pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ; + } + break; + case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: + { + DEVICE_DRIVER_INFO DevInfo; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); + + DevInfo.MaxRDMBufferSize = BUFFER_4K; + DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; + DevInfo.u32RxAlignmentCorrection = 0; + DevInfo.u32NVMType = Adapter->eNVMType; + DevInfo.u32InterfaceType = BCM_USB; + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + break; + } + if(IoBuffer.OutputLength < sizeof(DevInfo)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length is less than actural buffer size"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"user passed buffer size :0x%lX, expected size :0x%x",IoBuffer.OutputLength, sizeof(DevInfo)); + Status = -EINVAL; + break; + } + Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)&DevInfo, sizeof(DevInfo)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying Dev info structure to user space buffer failed"); + break; + } + } + break ; + + case IOCTL_BCM_TIME_SINCE_NET_ENTRY: + { + ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; + struct timeval tv = {0} ; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); + + Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + break; + } + if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length:0x%lx is less than expected buff size :0x%X",IoBuffer.OutputLength,sizeof(ST_TIME_ELAPSED)); + Status = -EINVAL; + break; + } + + //stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = Adapter->liTimeSinceLastNetEntry; + do_gettimeofday(&tv); + stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = tv.tv_sec - Adapter->liTimeSinceLastNetEntry; + + Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)&stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying ST_TIME_ELAPSED structure to user space buffer failed"); + break; + } + + } + break; + + default: + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "wrong input %x",cmd); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In default ioctl %d\n", cmd); + Status = STATUS_FAILURE; + + break; + } + return Status; +} + + +static struct file_operations bcm_fops = { + .owner = THIS_MODULE, + .open = bcm_char_open, + .release = bcm_char_release, + .read = bcm_char_read, + .unlocked_ioctl = bcm_char_ioctl, +}; + + +int register_control_device_interface(PMINI_ADAPTER Adapter) +{ + if(Adapter->major>0) + return Adapter->major; + Adapter->major = register_chrdev(0, "tarang", &bcm_fops); + if(Adapter->major < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "register_chrdev:Failed to registering WiMax control char device!"); + return Adapter->major; + } + + bcm_class = NULL; + bcm_class = class_create (THIS_MODULE, "tarang"); + if(IS_ERR (bcm_class)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unable to create class\n"); + unregister_chrdev(Adapter->major, "tarang"); + Adapter->major = 0; + return -ENODEV; + } + Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL, + MKDEV(Adapter->major, 0), +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) + NULL , +#endif + "tarang"); + + if(IS_ERR(Adapter->pstCreatedClassDevice)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "class device did not get created : %ld", PTR_ERR(Adapter->pstCreatedClassDevice) ); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Got Major No: %d", Adapter->major); + return 0; +} + +void unregister_control_device_interface(PMINI_ADAPTER Adapter) +{ + if(Adapter->major > 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying class device"); + device_destroy (bcm_class, MKDEV(Adapter->major, 0)); + } + if(!IS_ERR(bcm_class)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying created class "); + class_destroy (bcm_class); + bcm_class = NULL; + } + if(Adapter->major > 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"unregistering character interface"); + unregister_chrdev(Adapter->major, "tarang"); + } + +} diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c new file mode 100644 index 000000000000..d4f4800ca5dd --- /dev/null +++ b/drivers/staging/bcm/Bcmnet.c @@ -0,0 +1,266 @@ +#include "headers.h" + +static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev) +{ + struct net_device *ndev = (struct net_device*)dev; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + //PMINI_ADAPTER Adapter = (PMINI_ADAPTER)ndev->priv; + if(strncmp(ndev->name,gblpnetdev->name,5)==0) + { + switch(event) + { + case NETDEV_CHANGEADDR: + case NETDEV_GOING_DOWN: + /*ignore this */ + break; + case NETDEV_DOWN: + break; + + case NETDEV_UP: + break; + + case NETDEV_REGISTER: + /* Increment the Reference Count for "veth0" */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n", + atomic_read(&ndev->refcnt)); + atomic_inc(&ndev->refcnt); + break; + + case NETDEV_UNREGISTER: + /* Decrement the Reference Count for "veth0" */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n", + atomic_read(&ndev->refcnt)); + atomic_dec(&ndev->refcnt); + if((int)atomic_read(&ndev->refcnt) < 0) + atomic_set(&ndev->refcnt, 0); + break; + }; + } + return NOTIFY_DONE; +} + +/* Notifier block to receive netdevice events */ +static struct notifier_block bcm_notifier_block = +{ + .notifier_call = bcm_notify_event, +}; + +struct net_device *gblpnetdev; +/***************************************************************************************/ +/* proto-type of lower function */ +#ifdef BCM_SHM_INTERFACE +const char *bcmVirtDeviceName="bcmeth"; +#endif + +static INT bcm_open(struct net_device *dev) +{ + PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv; + Adapter = GET_BCM_ADAPTER(dev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>"); + if(Adapter->fw_download_done==FALSE) + return -EINVAL; + Adapter->if_up=1; + if(Adapter->LinkUpStatus == 1){ + if(netif_queue_stopped(Adapter->dev)){ + netif_carrier_on(Adapter->dev); + netif_start_queue(Adapter->dev); + } + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======"); + return 0; +} + +static INT bcm_close(struct net_device *dev) +{ + PMINI_ADAPTER Adapter = NULL ;//gpadapter ; + Adapter = GET_BCM_ADAPTER(dev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>"); + Adapter->if_up=0; + if(!netif_queue_stopped(dev)) { + netif_carrier_off(dev); + netif_stop_queue(dev); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<====="); + return 0; +} + +static struct net_device_stats *bcm_get_stats(struct net_device *dev) +{ + PLINUX_DEP_DATA pLinuxData=NULL; + PMINI_ADAPTER Adapter = NULL ;// gpadapter ; + Adapter = GET_BCM_ADAPTER(dev); + pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData); + + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData); + pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs; + pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount); + pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount); + pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount); + pLinuxData->netstats.rx_length_errors=0; + pLinuxData->netstats.rx_frame_errors=0; + pLinuxData->netstats.rx_crc_errors=0; + pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount); + pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount); + pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount); + + return &(pLinuxData->netstats); +} +/** +@ingroup init_functions +Register other driver entry points with the kernel +*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +struct net_device_ops bcmNetDevOps = { + .ndo_open = bcm_open, + .ndo_stop = bcm_close, + .ndo_get_stats = bcm_get_stats, + .ndo_start_xmit = bcm_transmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; +#endif + +int register_networkdev(PMINI_ADAPTER Adapter) +{ + int result=0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + int *temp = NULL ; +#endif + Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER)); + if(!Adapter->dev) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev"); + return -ENOMEM; + } + gblpnetdev = Adapter->dev; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + Adapter->dev->priv = Adapter; +#else + temp = netdev_priv(Adapter->dev); + *temp = (UINT)Adapter; +#endif + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) + Adapter->dev->netdev_ops = &bcmNetDevOps; +#else + Adapter->dev->open = bcm_open; + Adapter->dev->stop = bcm_close; + Adapter->dev->get_stats = bcm_get_stats; + Adapter->dev->hard_start_xmit = bcm_transmit; + Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE; +#endif + +#ifndef BCM_SHM_INTERFACE + Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */ + /* Read the MAC Address from EEPROM */ + ReadMacAddressFromNVM(Adapter); + + + /* Register the notifier block for getting netdevice events */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n"); + result = register_netdevice_notifier(&bcm_notifier_block); + if(result) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered"); + Adapter->bNetdeviceNotifierRegistered = FALSE; + return result; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered"); + Adapter->bNetdeviceNotifierRegistered = TRUE; + } + +#else + + Adapter->dev->mtu = CPE_MTU_SIZE; + +#if 0 + //for CPE - harcode the virtual mac address + Adapter->dev->dev_addr[0] = MII_WIMAX_MACADDRESS[0]; + Adapter->dev->dev_addr[1] = MII_WIMAX_MACADDRESS[1]; + Adapter->dev->dev_addr[2] = MII_WIMAX_MACADDRESS[2]; + Adapter->dev->dev_addr[3] = MII_WIMAX_MACADDRESS[3]; + Adapter->dev->dev_addr[4] = MII_WIMAX_MACADDRESS[4]; + Adapter->dev->dev_addr[5] = MII_WIMAX_MACADDRESS[5]; +#else + ReadMacAddressFromNVM(Adapter); +#endif + strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name + +#endif + + result = register_netdev(Adapter->dev); + if (!result) + { + Adapter->bNetworkInterfaceRegistered = TRUE ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!"); + Adapter->bNetworkInterfaceRegistered = FALSE ; + return result; + } + +#if 0 + Adapter->stDebugState.debug_level = DBG_LVL_CURR; + Adapter->stDebugState.type =(UINT)0xffffffff; + Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff; + Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff; + Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff; + Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff; + + printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type); + printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]); + printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]); + printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]); +#endif + + return 0; +} + +void bcm_unregister_networkdev(PMINI_ADAPTER Adapter) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n"); + if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered) + unregister_netdev(Adapter->dev); + /* Unregister the notifier block */ + if(Adapter->bNetdeviceNotifierRegistered == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n"); + unregister_netdevice_notifier(&bcm_notifier_block); + } +} + +static int bcm_init(void) +{ + int result; + result = InterfaceInitialize(); + if(result) + { + printk("Initialisation failed for usbbcm"); + } + else + { + printk("Initialised usbbcm"); + } + return result; +} + + +static void bcm_exit(void) +{ + printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__); + InterfaceExit(); + printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__); +} + +module_init(bcm_init); +module_exit(bcm_exit); +MODULE_LICENSE ("GPL"); + + diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c new file mode 100644 index 000000000000..d1a668339982 --- /dev/null +++ b/drivers/staging/bcm/CmHost.c @@ -0,0 +1,2443 @@ +/************************************************************ +* CMHOST.C +* This file contains the routines for handling Connnection +* Management. +************************************************************/ + +//#define CONN_MSG +#include "headers.h" + +typedef enum _E_CLASSIFIER_ACTION +{ + eInvalidClassifierAction, + eAddClassifier, + eReplaceClassifier, + eDeleteClassifier +}E_CLASSIFIER_ACTION; + + +/************************************************************ +* Function - SearchSfid +* +* Description - This routinue would search QOS queues having +* specified SFID as input parameter. +* +* Parameters - Adapter: Pointer to the Adapter structure +* uiSfid : Given SFID for matching +* +* Returns - Queue index for this SFID(If matched) + Else Invalid Queue Index(If Not matched) +************************************************************/ +__inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid) +{ + INT iIndex=0; + for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--) + if(Adapter->PackInfo[iIndex].ulSFID==uiSfid) + return iIndex; + return NO_OF_QUEUES+1; +} + +/*************************************************************** +* Function - SearchFreeSfid +* +* Description - This routinue would search Free available SFID. +* +* Parameter - Adapter: Pointer to the Adapter structure +* +* Returns - Queue index for the free SFID +* Else returns Invalid Index. +****************************************************************/ +__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter) +{ + UINT uiIndex=0; + for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++) + if(Adapter->PackInfo[uiIndex].ulSFID==0) + return uiIndex; + return NO_OF_QUEUES+1; +} + +__inline int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) +{ + int iIndex=0; + for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) + if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) + return iIndex; + return NO_OF_QUEUES+1; + +} + + +/* +Function: SearchClsid +Description: This routinue would search Classifier having specified ClassifierID as input parameter +Input parameters: PMINI_ADAPTER Adapter - Adapter Context + unsigned int uiSfid - The SF in which the classifier is to searched + B_UINT16 uiClassifierID - The classifier ID to be searched +Return: int :Classifier table index of matching entry +*/ + +__inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID) +{ + unsigned int uiClassifierIndex = 0; + for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) && + (Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID)&& + (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == ulSFID)) + return uiClassifierIndex; + } + return MAX_CLASSIFIERS+1; +} + +/** +@ingroup ctrl_pkt_functions +This routinue would search Free available Classifier entry in classifier table. +@return free Classifier Entry index in classifier table for specified SF +*/ +static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/ + ) +{ + unsigned int uiClassifierIndex = 0; + for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) + return uiClassifierIndex; + } + return MAX_CLASSIFIERS+1; +} + +VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) +{ + //deleting all the packet held in the SF + flush_queue(Adapter,uiSearchRuleIndex); + + //Deleting the all classifiers for this SF + DeleteAllClassifiersForSF(Adapter,uiSearchRuleIndex); + + //Resetting only MIBS related entries in the SF + memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE)); +} + +static inline VOID +CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry , + B_UINT8 u8IpAddressLen , B_UINT8 *pu8IpAddressMaskSrc , + BOOLEAN bIpVersion6 , E_IPADDR_CONTEXT eIpAddrContext) +{ + UINT ucLoopIndex=0; + UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; + UCHAR *ptrClassifierIpAddress = NULL; + UCHAR *ptrClassifierIpMask = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + if(bIpVersion6) + { + nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES; + } + //Destination Ip Address + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Address Range Length:0x%X ", + u8IpAddressLen); + if((bIpVersion6?(IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2): + (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) + { + /* + //checking both the mask and address togethor in Classification. + //So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2 + //(nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask) + */ + if(eIpAddrContext == eDestIpAddress) + { + pstClassifierEntry->ucIPDestinationAddressLength = + u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); + if(bIpVersion6) + { + ptrClassifierIpAddress = + pstClassifierEntry->stDestIpAddress.ucIpv6Address; + ptrClassifierIpMask = + pstClassifierEntry->stDestIpAddress.ucIpv6Mask; + } + else + { + ptrClassifierIpAddress = + pstClassifierEntry->stDestIpAddress.ucIpv4Address; + ptrClassifierIpMask = + pstClassifierEntry->stDestIpAddress.ucIpv4Mask; + } + } + else if(eIpAddrContext == eSrcIpAddress) + { + pstClassifierEntry->ucIPSourceAddressLength = + u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); + if(bIpVersion6) + { + ptrClassifierIpAddress = + pstClassifierEntry->stSrcIpAddress.ucIpv6Address; + ptrClassifierIpMask = + pstClassifierEntry->stSrcIpAddress.ucIpv6Mask; + } + else + { + ptrClassifierIpAddress = + pstClassifierEntry->stSrcIpAddress.ucIpv4Address; + ptrClassifierIpMask = + pstClassifierEntry->stSrcIpAddress.ucIpv4Mask; + } + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Address Length:0x%X \n", + pstClassifierEntry->ucIPDestinationAddressLength); + while((u8IpAddressLen>= nSizeOfIPAddressInBytes) && + (ucLoopIndex < MAX_IP_RANGE_LENGTH)) + { + memcpy(ptrClassifierIpAddress + + (ucLoopIndex * nSizeOfIPAddressInBytes), + (pu8IpAddressMaskSrc+(ucLoopIndex*nSizeOfIPAddressInBytes*2)), + nSizeOfIPAddressInBytes); + if(!bIpVersion6) + { + if(eIpAddrContext == eSrcIpAddress) + { + pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]= + ntohl(pstClassifierEntry->stSrcIpAddress. + ulIpv4Addr[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); + } + else if(eIpAddrContext == eDestIpAddress) + { + pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. + ulIpv4Addr[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + } + } + u8IpAddressLen-=nSizeOfIPAddressInBytes; + if(u8IpAddressLen >= nSizeOfIPAddressInBytes) + { + memcpy(ptrClassifierIpMask + + (ucLoopIndex * nSizeOfIPAddressInBytes), + (pu8IpAddressMaskSrc+nSizeOfIPAddressInBytes + + (ucLoopIndex*nSizeOfIPAddressInBytes*2)), + nSizeOfIPAddressInBytes); + if(!bIpVersion6) + { + if(eIpAddrContext == eSrcIpAddress) + { + pstClassifierEntry->stSrcIpAddress. + ulIpv4Mask[ucLoopIndex]= + ntohl(pstClassifierEntry->stSrcIpAddress. + ulIpv4Mask[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Mask Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); + } + else if(eIpAddrContext == eDestIpAddress) + { + pstClassifierEntry->stDestIpAddress. + ulIpv4Mask[ucLoopIndex] = + ntohl(pstClassifierEntry->stDestIpAddress. + ulIpv4Mask[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Mask Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); + } + } + u8IpAddressLen-=nSizeOfIPAddressInBytes; + } + if(0==u8IpAddressLen) + { + pstClassifierEntry->bDestIpValid=TRUE; + } + ucLoopIndex++; + } + if(bIpVersion6) + { + //Restore EndianNess of Struct + for(ucLoopIndex =0 ; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4 ; + ucLoopIndex++) + { + if(eIpAddrContext == eSrcIpAddress) + { + pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]= + ntohl(pstClassifierEntry->stSrcIpAddress. + ulIpv6Addr[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stSrcIpAddress. + ulIpv6Mask[ucLoopIndex]); + } + else if(eIpAddrContext == eDestIpAddress) + { + pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. + ulIpv6Addr[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. + ulIpv6Mask[ucLoopIndex]); + } + } + } + } +} + + +void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll) +{ + ULONG ulIndex; + for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) + { + if(Adapter->astTargetDsxBuffer[ulIndex].valid) + continue; + if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)){ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", + TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); + Adapter->astTargetDsxBuffer[ulIndex].valid=1; + Adapter->astTargetDsxBuffer[ulIndex].tid=0; + Adapter->ulFreeTargetBufferCnt++; + } + } +} + +/** +@ingroup ctrl_pkt_functions +copy classifier rule into the specified SF index +*/ +static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLTypes *psfCSType,UINT uiSearchRuleIndex,UINT nClassifierIndex) +{ + S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + //VOID *pvPhsContext = NULL; + UINT ucLoopIndex=0; + //UCHAR ucProtocolLength=0; + //ULONG ulPhsStatus; + + + if(Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 || + nClassifierIndex > (MAX_CLASSIFIERS-1)) + return; + + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Storing Classifier Rule Index : %X",ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex)); + + if(nClassifierIndex > MAX_CLASSIFIERS-1) + return; + + pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; + if(pstClassifierEntry) + { + //Store if Ipv6 + pstClassifierEntry->bIpv6Protocol = + (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE; + + //Destinaiton Port + pstClassifierEntry->ucDestPortRangeLength=psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength/4; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Length:0x%X ",pstClassifierEntry->ucDestPortRangeLength); + if( MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength) + { + for(ucLoopIndex=0;ucLoopIndex<(pstClassifierEntry->ucDestPortRangeLength);ucLoopIndex++) + { + pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = + *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex)); + pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = + *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+ucLoopIndex)); + pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Lo:0x%X ",pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); + pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]); + } + } + else + { + pstClassifierEntry->ucDestPortRangeLength=0; + } + //Source Port + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Length:0x%X ",psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + if(MAX_PORT_RANGE >= + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength) + { + pstClassifierEntry->ucSrcPortRangeLength = + psfCSType->cCPacketClassificationRule. + u8ProtocolSourcePortRangeLength/4; + for(ucLoopIndex = 0; ucLoopIndex < + (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++) + { + pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = + *((PUSHORT)(psfCSType->cCPacketClassificationRule. + u8ProtocolSourcePortRange+ucLoopIndex)); + pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] = + *((PUSHORT)(psfCSType->cCPacketClassificationRule. + u8ProtocolSourcePortRange+2+ucLoopIndex)); + pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = + ntohs(pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Lo:0x%X ",pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); + pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]); + } + } + //Destination Ip Address and Mask + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Destination Parameters : "); + + CopyIpAddrToClassifier(pstClassifierEntry, + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength, + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress, + (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)? + TRUE:FALSE, eDestIpAddress); + + //Source Ip Address and Mask + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Source Parameters : "); + + CopyIpAddrToClassifier(pstClassifierEntry, + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength, + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress, + (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE, + eSrcIpAddress); + + //TOS + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"TOS Length:0x%X ",psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + if(3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength) + { + pstClassifierEntry->ucIPTypeOfServiceLength = + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength; + pstClassifierEntry->ucTosLow = + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0]; + pstClassifierEntry->ucTosHigh = + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1]; + pstClassifierEntry->ucTosMask = + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]; + pstClassifierEntry->bTOSValid = TRUE; + } + if(psfCSType->cCPacketClassificationRule.u8Protocol == 0) + { + //we didnt get protocol field filled in by the BS + pstClassifierEntry->ucProtocolLength=0; + } + else + { + pstClassifierEntry->ucProtocolLength=1;// 1 valid protocol + } + + pstClassifierEntry->ucProtocol[0] = + psfCSType->cCPacketClassificationRule.u8Protocol; + + pstClassifierEntry->u8ClassifierRulePriority = + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority; + + //store the classifier rule ID and set this classifier entry as valid + pstClassifierEntry->ucDirection = + Adapter->PackInfo[uiSearchRuleIndex].ucDirection; + pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType-> + cCPacketClassificationRule.u16PacketClassificationRuleIndex); + pstClassifierEntry->usVCID_Value = + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; + pstClassifierEntry->ulSFID = + Adapter->PackInfo[uiSearchRuleIndex].ulSFID; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n", + uiSearchRuleIndex, pstClassifierEntry->ucDirection, + pstClassifierEntry->uiClassifierRuleIndex, + pstClassifierEntry->usVCID_Value); + + if(psfCSType->cCPacketClassificationRule.u8AssociatedPHSI) + { + pstClassifierEntry->u8AssociatedPHSI = psfCSType->cCPacketClassificationRule.u8AssociatedPHSI; + } + + //Copy ETH CS Parameters + pstClassifierEntry->ucEthCSSrcMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddressLength); + memcpy(pstClassifierEntry->au8EThCSSrcMAC,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress,MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSSrcMACMask,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE); + pstClassifierEntry->ucEthCSDestMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + memcpy(pstClassifierEntry->au8EThCSDestMAC,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress,MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSDestMACMask,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE); + pstClassifierEntry->ucEtherTypeLen = (psfCSType->cCPacketClassificationRule.u8EthertypeLength); + memcpy(pstClassifierEntry->au8EthCSEtherType,psfCSType->cCPacketClassificationRule.u8Ethertype,NUM_ETHERTYPE_BYTES); + memcpy(pstClassifierEntry->usUserPriority, &psfCSType->cCPacketClassificationRule.u16UserPriority, 2); + pstClassifierEntry->usVLANID = ntohs(psfCSType->cCPacketClassificationRule.u16VLANID); + pstClassifierEntry->usValidityBitMap = ntohs(psfCSType->cCPacketClassificationRule.u16ValidityBitMap); + + pstClassifierEntry->bUsed = TRUE; + } +} + + +/** +@ingroup ctrl_pkt_functions +*/ +static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex,UINT nClassifierIndex) +{ + S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + B_UINT16 u16PacketClassificationRuleIndex; + USHORT usVCID; + //VOID *pvPhsContext = NULL; + //ULONG ulPhsStatus; + + usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; + + if(nClassifierIndex > MAX_CLASSIFIERS-1) + return; + + if(usVCID == 0) + return; + + u16PacketClassificationRuleIndex = Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex; + + + pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; + if(pstClassifierEntry) + { + pstClassifierEntry->bUsed = FALSE; + pstClassifierEntry->uiClassifierRuleIndex = 0; + memset(pstClassifierEntry,0,sizeof(S_CLASSIFIER_RULE)); + + //Delete the PHS Rule for this classifier + PhsDeleteClassifierRule( + &Adapter->stBCMPhsContext, + usVCID, + u16PacketClassificationRuleIndex); + } +} + +/** +@ingroup ctrl_pkt_functions +*/ +VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex) +{ + S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + UINT nClassifierIndex; + //B_UINT16 u16PacketClassificationRuleIndex; + USHORT ulVCID; + //VOID *pvPhsContext = NULL; + //ULONG ulPhsStatus; + + ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; + + if(ulVCID == 0) + return; + + + for(nClassifierIndex =0 ; nClassifierIndex < MAX_CLASSIFIERS ; nClassifierIndex++) + { + if(Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID) + { + pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; + if(pstClassifierEntry->bUsed) + { + DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex); + } + } + } + + //Delete All Phs Rules Associated with this SF + PhsDeleteSFRules( + &Adapter->stBCMPhsContext, + ulVCID); + +} + + +/** +This routinue copies the Connection Management +related data into the Adapter structure. +@ingroup ctrl_pkt_functions +*/ + +static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**PackInfo[uiSearchRuleIndex].usVCID_Value; + UINT UGIValue = 0; + + + Adapter->PackInfo[uiSearchRuleIndex].bValid=TRUE; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s: SFID= %x ",__FUNCTION__, ntohl(psfLocalSet->u32SFID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Updating Queue %d",uiSearchRuleIndex); + + ulSFID = ntohl(psfLocalSet->u32SFID); + //Store IP Version used + //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF + + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = 0; + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0; + + /*Enable IP/ETh CS Support As Required*/ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : u8CSSpecification : %X\n",psfLocalSet->u8CSSpecification); + switch(psfLocalSet->u8CSSpecification) + { + case eCSPacketIPV4: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + break; + } + case eCSPacketIPV6: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; + break; + } + + case eCS802_3PacketEthernet: + case eCS802_1QPacketVLAN: + { + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + + case eCSPacketIPV4Over802_1QVLAN: + case eCSPacketIPV4Over802_3Ethernet: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + + case eCSPacketIPV6Over802_1QVLAN: + case eCSPacketIPV6Over802_3Ethernet: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + + default: + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error in value of CS Classification.. setting default to IP CS\n"); + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + break; + } + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X \n", + uiSearchRuleIndex, + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport, + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport); + + //Store IP Version used + //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF + if(Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS) + { + Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV6; + } + else + { + Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV4; + } + + /* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */ + if(!Adapter->bETHCSEnabled) + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0; + + if(psfLocalSet->u8ServiceClassNameLength > 0 && + psfLocalSet->u8ServiceClassNameLength < 32) + { + memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName, + psfLocalSet->u8ServiceClassName, + psfLocalSet->u8ServiceClassNameLength); + } + Adapter->PackInfo[uiSearchRuleIndex].u8QueueType = + psfLocalSet->u8ServiceFlowSchedulingType; + + if(Adapter->PackInfo[uiSearchRuleIndex].u8QueueType==BE && + Adapter->PackInfo[uiSearchRuleIndex].ucDirection) + { + Adapter->usBestEffortQueueIndex=uiSearchRuleIndex; + } + + Adapter->PackInfo[uiSearchRuleIndex].ulSFID = ntohl(psfLocalSet->u32SFID); + + Adapter->PackInfo[uiSearchRuleIndex].u8TrafficPriority = psfLocalSet->u8TrafficPriority; + + //copy all the classifier in the Service Flow param structure + for(nIndex=0; nIndexu8TotalClassifiers; nIndex++) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex); + psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex); + + if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) + { + Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE; + } + + if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) + { + Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE; + } + + + if(ucDsxType== DSA_ACK) + { + eClassifierAction = eAddClassifier; + } + else if(ucDsxType == DSC_ACK) + { + switch(psfCSType->u8ClassfierDSCAction) + { + case 0://DSC Add Classifier + { + eClassifierAction = eAddClassifier; + } + break; + case 1://DSC Replace Classifier + { + eClassifierAction = eReplaceClassifier; + } + break; + case 2://DSC Delete Classifier + { + eClassifierAction = eDeleteClassifier; + + } + break; + default: + { + eClassifierAction = eInvalidClassifierAction; + } + } + } + + u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + switch(eClassifierAction) + { + case eAddClassifier: + { + //Get a Free Classifier Index From Classifier table for this SF to add the Classifier + //Contained in this message + nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); + + if(nClassifierIndex > MAX_CLASSIFIERS) + { + nClassifierIndex = SearchFreeClsid(Adapter); + if(nClassifierIndex > MAX_CLASSIFIERS) + { + //Failed To get a free Entry + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Failed To get a free Classifier Entry"); + break; + } + //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. + CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex); + } + + else + { + //This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Error The Specified Classifier Already Exists \ + and attempted To Add Classifier with Same PCRI : 0x%x\n", u16PacketClassificationRuleIndex); + } + } + break; + + case eReplaceClassifier: + { + //Get the Classifier Index From Classifier table for this SF and replace existing Classifier + //with the new classifier Contained in this message + nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); + if(nClassifierIndex > MAX_CLASSIFIERS) + { + //Failed To search the classifier + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be replaced failed"); + break; + } + //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. + CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex); + } + break; + + case eDeleteClassifier: + { + //Get the Classifier Index From Classifier table for this SF and replace existing Classifier + //with the new classifier Contained in this message + nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); + if(nClassifierIndex > MAX_CLASSIFIERS) + { + //Failed To search the classifier + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be deleted failed"); + break; + } + + //Delete This classifier + DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex); + } + break; + + default: + { + //Invalid Action for classifier + break; + } + } + } + + //Repeat parsing Classification Entries to process PHS Rules + for(nIndex=0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++) + { + psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n", + psfCSType->u8PhsDSCAction ); + + switch (psfCSType->u8PhsDSCAction) + { + case eDeleteAllPHSRules: + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Deleting All PHS Rules For VCID: 0x%X\n",uVCID); + + //Delete All the PHS rules for this Service flow + + PhsDeleteSFRules( + &Adapter->stBCMPhsContext, + uVCID); + + break; + } + case eDeletePHSRule: + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"PHS DSC Action = Delete PHS Rule \n"); + + if(psfCSType->cPhsRule.u8PHSI) + { + PhsDeletePHSRule( + &Adapter->stBCMPhsContext, + uVCID, + psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + } + else + { + //BCM_DEBUG_PRINT(CONN_MSG,("Error CPHSRule.PHSI is ZERO \n")); + } + break; + } + default : + { + if(ucDsxType == DSC_ACK) + { + //BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC \n",psfCSType->cPhsRule.u8PHSI)); + break; //FOr DSC ACK Case PHS DSC Action must be in valid set + } + } + //Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified + //No Break Here . Intentionally! + + case eAddPHSRule: + case eSetPHSRule: + { + if(psfCSType->cPhsRule.u8PHSI) + { + //Apply This PHS Rule to all classifiers whose Associated PHSI Match + unsigned int uiClassifierIndex = 0; + if(pstAddIndication->u8Direction == UPLINK_DIR ) + { + for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) && + (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) && + (Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adding PHS Rule For Classifier : 0x%x cPhsRule.u8PHSI : 0x%x\n", + Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex, + psfCSType->cPhsRule.u8PHSI); + //Update The PHS Rule for this classifier as Associated PHSI id defined + + //Copy the PHS Rule + sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; + sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; + sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength; + sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS; + sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV; + memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS); + memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS); + sPhsRule.u8RefCnt = 0; + sPhsRule.bUnclassifiedPHSRule = FALSE; + sPhsRule.PHSModifiedBytes = 0; + sPhsRule.PHSModifiedNumPackets = 0; + sPhsRule.PHSErrorNumPackets = 0; + + //bPHSRuleAssociated = TRUE; + //Store The PHS Rule for this classifier + + PhsUpdateClassifierRule( + &Adapter->stBCMPhsContext, + uVCID, + Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex, + &sPhsRule, + Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI); + + //Update PHS Rule For the Classifier + if(sPhsRule.u8PHSI) + { + Adapter->astClassifierTable[uiClassifierIndex].u32PHSRuleID = sPhsRule.u8PHSI; + memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule,&sPhsRule,sizeof(S_PHS_RULE)); + } + + } + } + } + else + { + //Error PHS Rule specified in signaling could not be applied to any classifier + + //Copy the PHS Rule + sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; + sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; + sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength; + sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS; + sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV; + memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS); + memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS); + sPhsRule.u8RefCnt = 0; + sPhsRule.bUnclassifiedPHSRule = TRUE; + sPhsRule.PHSModifiedBytes = 0; + sPhsRule.PHSModifiedNumPackets = 0; + sPhsRule.PHSErrorNumPackets = 0; + //Store The PHS Rule for this classifier + + /* + Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule, + clsid will be zero hence we cant have multiple PHS rules for the same SF. + To support multiple PHS rule, passing u8PHSI. + */ + + PhsUpdateClassifierRule( + &Adapter->stBCMPhsContext, + uVCID, + sPhsRule.u8PHSI, + &sPhsRule, + sPhsRule.u8PHSI); + + } + + } + } + break; + } + } + + if(psfLocalSet->u32MaxSustainedTrafficRate == 0 ) + { + //No Rate Limit . Set Max Sustained Traffic Rate to Maximum + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = + WIMAX_MAX_ALLOWED_RATE; + + } + else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > + WIMAX_MAX_ALLOWED_RATE) + { + //Too large Allowed Rate specified. Limiting to Wi Max Allowed rate + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = + WIMAX_MAX_ALLOWED_RATE; + } + else + { + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = + ntohl(psfLocalSet->u32MaxSustainedTrafficRate); + } + + Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency); + + if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */ + Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = MAX_LATENCY_ALLOWED; + + + if(( Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS || + Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS ) ) + UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval); + + if(UGIValue == 0) + UGIValue = DEFAULT_UG_INTERVAL; + + /* + For UGI based connections... + DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host... + The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput... + In case of non-UGI based connection, 200 frames worth of data is the max token count at host... + */ + + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = + (DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; + + if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8) + { + UINT UGIFactor = 0; + /* Special Handling to ensure the biggest size of packet can go out from host to FW as follows: + 1. Any packet from Host to FW can go out in different packet size. + 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped. + 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer + */ + UGIFactor = (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency/UGIValue + 1); + + if(UGIFactor > DEFAULT_UGI_FACTOR) + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = + (UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; + + if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8) + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = WIMAX_MAX_MTU*8; + } + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"LAT: %d, UGI: %d \n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x", + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate, + ntohl(psfLocalSet->u32MaxSustainedTrafficRate), + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize); + + //copy the extended SF Parameters to Support MIBS + CopyMIBSExtendedSFParameters(Adapter,psfLocalSet,uiSearchRuleIndex); + + //store header suppression enabled flag per SF + Adapter->PackInfo[uiSearchRuleIndex].bHeaderSuppressionEnabled = + !(psfLocalSet->u8RequesttransmissionPolicy & + MASK_DISABLE_HEADER_SUPPRESSION); + + if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication) + { + bcm_kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); + Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL; + } + Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication; + + //Re Sort the SF list in PackInfo according to Traffic Priority + SortPackInfo(Adapter); + + /* Re Sort the Classifier Rules table and re - arrange + according to Classifier Rule Priority */ + SortClassifiers(Adapter); + + DumpPhsRules(&Adapter->stBCMPhsContext); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s <=====", __FUNCTION__); +} + + +/*********************************************************************** +* Function - DumpCmControlPacket +* +* Description - This routinue Dumps the Contents of the AddIndication +* Structure in the Connection Management Control Packet +* +* Parameter - pvBuffer: Pointer to the buffer containing the +* AddIndication data. +* +* Returns - None +*************************************************************************/ +VOID DumpCmControlPacket(PVOID pvBuffer) +{ + UINT uiLoopIndex; + UINT nIndex; + stLocalSFAddIndicationAlt *pstAddIndication; + UINT nCurClassifierCnt; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>"); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type : 0x%X",pstAddIndication->u8Type); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction : 0x%X",pstAddIndication->u8Direction); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",ntohs(pstAddIndication->u16CID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID)); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->"); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",htonl(pstAddIndication->sfAuthorizedSet.u32SFID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",htons(pstAddIndication->sfAuthorizedSet.u16CID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", + pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X", + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0], + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1], + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2], + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[3], + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4], + pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%X", + pstAddIndication->sfAuthorizedSet.u8MBSService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%X", + pstAddIndication->sfAuthorizedSet.u8QosParamSet); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%X, %p", + pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%X 0x%p", + pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate, + &pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", + pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", + pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", + pstAddIndication->sfAuthorizedSet.u32MinimumTolerableTrafficRate); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", + pstAddIndication->sfAuthorizedSet.u32RequesttransmissionPolicy); +#endif + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X", + pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X", + pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%X", + pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", + pstAddIndication->sfAuthorizedSet.u32ToleratedJitter); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", + pstAddIndication->sfAuthorizedSet.u32MaximumLatency); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X", + pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X", + pstAddIndication->sfAuthorizedSet.u8SDUSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%X", + pstAddIndication->sfAuthorizedSet.u16TargetSAID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%X", + pstAddIndication->sfAuthorizedSet.u8ARQEnable); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQWindowSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%X", + pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X", + pstAddIndication->sfAuthorizedSet.u16ARQBlockSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%X", + pstAddIndication->sfAuthorizedSet.u8CSSpecification); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%X", + pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X", + pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X", + pstAddIndication->sfAuthorizedSet.u16TimeBase); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X", + pstAddIndication->sfAuthorizedSet.u8PagingPreference); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X", + pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X", + pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignmentLength); + for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X", + pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignment[uiLoopIndex]); +#endif + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", + *(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, + *(unsigned int*)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4], + *(USHORT*) &pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%X", + pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); + + nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers; + + if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) + { + nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead); + if(!pstAddIndication->sfAuthorizedSet.bValid) + pstAddIndication->sfAuthorizedSet.bValid=1; + for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) + { + stConvergenceSLTypes *psfCSType = NULL; + psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex]; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>"); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); +#if 0 + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u8ProtocolLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolLength); +#endif + + for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ", + psfCSType->cCPacketClassificationRule.u16UserPriority); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ", + psfCSType->cCPacketClassificationRule.u16VLANID); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); +#ifdef VERSION_D5 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); +#endif + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%02X",pstAddIndication->sfAuthorizedSet.bValid); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->"); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfAdmittedSet.u32SFID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfAdmittedSet.u16CID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", + pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X", + pstAddIndication->sfAdmittedSet.u8ServiceClassName[0], + pstAddIndication->sfAdmittedSet.u8ServiceClassName[1], + pstAddIndication->sfAdmittedSet.u8ServiceClassName[2], + pstAddIndication->sfAdmittedSet.u8ServiceClassName[3], + pstAddIndication->sfAdmittedSet.u8ServiceClassName[4], + pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X", + pstAddIndication->sfAdmittedSet.u8MBSService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X", + pstAddIndication->sfAdmittedSet.u8QosParamSet); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", + pstAddIndication->sfAdmittedSet.u8TrafficPriority); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X", + ntohl(pstAddIndication->sfAdmittedSet.u32MaxSustainedTrafficRate)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", + pstAddIndication->sfAdmittedSet.u32MinimumTolerableTrafficRate); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", + pstAddIndication->sfAdmittedSet.u32RequesttransmissionPolicy); +#endif + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", + pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", + pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X", + pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X", + pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X", + pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", + pstAddIndication->sfAdmittedSet.u32ToleratedJitter); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", + pstAddIndication->sfAdmittedSet.u32MaximumLatency); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", + pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%02X", + pstAddIndication->sfAdmittedSet.u8SDUSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%02X", + pstAddIndication->sfAdmittedSet.u16TargetSAID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%02X", + pstAddIndication->sfAdmittedSet.u8ARQEnable); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQWindowSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%02X", + pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X", + pstAddIndication->sfAdmittedSet.u16ARQBlockSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%02X", + pstAddIndication->sfAdmittedSet.u8CSSpecification); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%02X", + pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X", + pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X", + pstAddIndication->sfAdmittedSet.u16TimeBase); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X", + pstAddIndication->sfAdmittedSet.u8PagingPreference); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X", + pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignmentLength); + for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X", + pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignment[uiLoopIndex]); +#endif + + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X", + pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers); + + nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers; + + if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) + { + nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; + } + + + for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) + { + + stConvergenceSLTypes *psfCSType = NULL; + psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%02X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%02X", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); +#if 0 + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolLength :0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolLength); +#endif + for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4] : 0x %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4] : 0x %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ", + psfCSType->cCPacketClassificationRule.u16UserPriority); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ", + psfCSType->cCPacketClassificationRule.u16VLANID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%02X", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); +#ifdef VERSION_D5 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength : 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); +#endif + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%X",pstAddIndication->sfAdmittedSet.bValid); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->"); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfActiveSet.u32SFID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfActiveSet.u16CID); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", + pstAddIndication->sfActiveSet.u8ServiceClassNameLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X", + pstAddIndication->sfActiveSet.u8ServiceClassName[0], + pstAddIndication->sfActiveSet.u8ServiceClassName[1], + pstAddIndication->sfActiveSet.u8ServiceClassName[2], + pstAddIndication->sfActiveSet.u8ServiceClassName[3], + pstAddIndication->sfActiveSet.u8ServiceClassName[4], + pstAddIndication->sfActiveSet.u8ServiceClassName[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X", + pstAddIndication->sfActiveSet.u8MBSService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X", + pstAddIndication->sfActiveSet.u8QosParamSet); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", + pstAddIndication->sfActiveSet.u8TrafficPriority); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X", + ntohl(pstAddIndication->sfActiveSet.u32MaxSustainedTrafficRate)); +#endif + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", + pstAddIndication->sfActiveSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", + pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", + pstAddIndication->sfActiveSet.u32MinimumTolerableTrafficRate); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", + pstAddIndication->sfActiveSet.u32RequesttransmissionPolicy); +#endif + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X", + pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X", + pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X", + pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", + pstAddIndication->sfActiveSet.u32ToleratedJitter); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", + pstAddIndication->sfActiveSet.u32MaximumLatency); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", + pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X", + pstAddIndication->sfActiveSet.u8SDUSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID : 0x%X", + pstAddIndication->sfActiveSet.u16TargetSAID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable : 0x%X", + pstAddIndication->sfActiveSet.u8ARQEnable); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize : 0x%X", + pstAddIndication->sfActiveSet.u16ARQWindowSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut : 0x%X", + pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut : 0x%X", + pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime : 0x%X", + pstAddIndication->sfActiveSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut : 0x%X", + pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder : 0x%X", + pstAddIndication->sfActiveSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut : 0x%X", + pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize : 0x%X", + pstAddIndication->sfActiveSet.u16ARQBlockSize); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification : 0x%X", + pstAddIndication->sfActiveSet.u8CSSpecification); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService : 0x%X", + pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime : 0x%X", + pstAddIndication->sfActiveSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase : 0x%X", + pstAddIndication->sfActiveSet.u16TimeBase); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X", + pstAddIndication->sfActiveSet.u8PagingPreference); +#if 0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignmentLength : 0x%X", + pstAddIndication->sfActiveSet.MBSZoneIdentifierassignmentLength); + for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignment : 0x%X", + pstAddIndication->sfActiveSet.MBSZoneIdentifierassignment[uiLoopIndex]); +#endif + + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X", + pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers); + + nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers; + + if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) + { + nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; + } + + for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) + { + + stConvergenceSLTypes *psfCSType = NULL; + psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; + + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ClassifierRulePriority :0x%X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfServiceLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); +#if 0 + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " u8ProtocolLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolLength); +#endif + for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ", + psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]:0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for(uiLoopIndex=0;uiLoopIndex<32;uiLoopIndex++) + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPDestinationAddress[32]:0x%X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRangeLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRangeLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddressLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetSourceMACAddressLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthertypeLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Ethertype[3] :0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16UserPriority :0x%X ", + psfCSType->cCPacketClassificationRule.u16UserPriority); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16VLANID :0x%X ", + psfCSType->cCPacketClassificationRule.u16VLANID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8AssociatedPHSI :0x%X ", + psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16PacketClassificationRuleIndex:0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParamLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParam[1]:0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); +#ifdef VERSION_D5 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLableLength :0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLable[6] :0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); +#endif + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid : 0x%X",pstAddIndication->sfActiveSet.bValid); + +} + +static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet,PUCHAR pucDestBuffer) +{ + UINT nBytesToRead = sizeof(stServiceFlowParamSI); + + if(ulAddrSFParamSet == 0 || NULL == pucDestBuffer) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!"); + return 0; + } + ulAddrSFParamSet = ntohl(ulAddrSFParamSet); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " RestoreSFParam: Total Words of DSX Message To Read: 0x%x From Target At : 0x%lx ", + nBytesToRead/sizeof(ULONG),ulAddrSFParamSet); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "sizeof(stServiceFlowParamSI) = %x", sizeof(stServiceFlowParamSI)); + + //Read out the SF Param Set At the indicated Location + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "nBytesToRead = %x", nBytesToRead); + if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) + return STATUS_FAILURE; + + return 1; +} + + +static __inline ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet) +{ + UINT nBytesToWrite = sizeof(stServiceFlowParamSI); + UINT uiRetVal =0; + + if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) + { + return 0; + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " StoreSFParam: Total Words of DSX Message To Write: 0x%X To Target At : 0x%lX ",(nBytesToWrite/sizeof(ULONG)),ulAddrSFParamSet); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "WRM with %x bytes",nBytesToWrite); + + uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite); + if(uiRetVal < 0) { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__); + return uiRetVal; + } + return 1; +} + +ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength) +{ + stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; + stLocalSFAddIndication * pstAddIndication = NULL; + stLocalSFDeleteRequest *pstDeletionRequest; + UINT uiSearchRuleIndex; + ULONG ulSFID; + + pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer); + + /* + * In case of DSD Req By MS, we should immediately delete this SF so that + * we can stop the further classifying the pkt for this SF. + */ + if(pstAddIndicationAlt->u8Type == DSD_REQ) + { + pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer; + + ulSFID = ntohl(pstDeletionRequest->u32SFID); + uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); + + if(uiSearchRuleIndex < NO_OF_QUEUES) + { + deleteSFBySfid(Adapter,uiSearchRuleIndex); + Adapter->u32TotalDSD++; + } + return 1; + } + + + if( (pstAddIndicationAlt->u8Type == DSD_RSP) || + (pstAddIndicationAlt->u8Type == DSD_ACK)) + { + //No Special handling send the message as it is + return 1; + } + // For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver! + + pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); + if(NULL==pstAddIndication) + return 0; + + /* AUTHORIZED SET */ + pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *) + GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); + if(!pstAddIndication->psfAuthorizedSet) + return 0; + + if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet, + (ULONG)pstAddIndication->psfAuthorizedSet)!= 1) + return 0; + + pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *) + ntohl((ULONG)pstAddIndication->psfAuthorizedSet); + + if(pstAddIndicationAlt->u8Type == DSA_REQ) + { + stLocalSFAddRequest AddRequest; + + AddRequest.u8Type = pstAddIndicationAlt->u8Type; + AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction; + AddRequest.u16TID = pstAddIndicationAlt->u16TID; + AddRequest.u16CID = pstAddIndicationAlt->u16CID; + AddRequest.u16VCID = pstAddIndicationAlt->u16VCID; + AddRequest.psfParameterSet =pstAddIndication->psfAuthorizedSet ; + (*puBufferLength) = sizeof(stLocalSFAddRequest); + memcpy(pvBuffer,&AddRequest,sizeof(stLocalSFAddRequest)); + return 1; + } + + // Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt + + //We need to extract the structure from the buffer and pack it differently + + pstAddIndication->u8Type = pstAddIndicationAlt->u8Type; + pstAddIndication->eConnectionDir= pstAddIndicationAlt->u8Direction ; + pstAddIndication->u16TID = pstAddIndicationAlt->u16TID; + pstAddIndication->u16CID = pstAddIndicationAlt->u16CID; + pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID; + pstAddIndication->u8CC = pstAddIndicationAlt->u8CC; + + /* ADMITTED SET */ + pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *) + GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); + if(!pstAddIndication->psfAdmittedSet) + return 0; + if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAdmittedSet,(ULONG)pstAddIndication->psfAdmittedSet) != 1) + return 0; + + pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet); + + + /* ACTIVE SET */ + pstAddIndication->psfActiveSet = (stServiceFlowParamSI *) + GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); + if(!pstAddIndication->psfActiveSet) + return 0; + if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfActiveSet,(ULONG)pstAddIndication->psfActiveSet) != 1) + return 0; + + pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet); + + (*puBufferLength) = sizeof(stLocalSFAddIndication); + *(stLocalSFAddIndication *)pvBuffer = *pstAddIndication; + bcm_kfree(pstAddIndication); + return 1; +} + + +static inline stLocalSFAddIndicationAlt +*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter,register PVOID pvBuffer) +{ + ULONG ulStatus=0; + stLocalSFAddIndication *pstAddIndication = NULL; + stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL; + pstAddIndication = (stLocalSFAddIndication *)(pvBuffer); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>" ); + if ((pstAddIndication->u8Type == DSD_REQ) || + (pstAddIndication->u8Type == DSD_RSP) || + (pstAddIndication->u8Type == DSD_ACK)) + { + return (stLocalSFAddIndicationAlt *)pvBuffer; + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage "); + /* + //Need to Allocate memory to contain the SUPER Large structures + //Our driver cant create these structures on Stack :( + */ + pstAddIndicationDest=kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL); + + if(pstAddIndicationDest) + { + memset(pstAddIndicationDest,0,sizeof(stLocalSFAddIndicationAlt)); + } + else + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure "); + return NULL; + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Type : 0x%X",pstAddIndication->u8Type); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Direction : 0x%X",pstAddIndication->eConnectionDir); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8TID : 0x%X",ntohs(pstAddIndication->u16TID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8CID : 0x%X",ntohs(pstAddIndication->u16CID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-autorized set loc : 0x%x",ntohl(pstAddIndication->psfAuthorizedSet)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-admitted set loc : 0x%x",ntohl(pstAddIndication->psfAdmittedSet)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-Active set loc : 0x%x",ntohl(pstAddIndication->psfActiveSet)); + + pstAddIndicationDest->u8Type = pstAddIndication->u8Type; + pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir; + pstAddIndicationDest->u16TID = pstAddIndication->u16TID; + pstAddIndicationDest->u16CID = pstAddIndication->u16CID; + pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID; + pstAddIndicationDest->u8CC = pstAddIndication->u8CC; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Active Set "); + ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet); + if(ulStatus != 1) + { + goto failed_restore_sf_param; + } + if(pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Admitted Set "); + ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAdmittedSet,(PUCHAR)&pstAddIndicationDest->sfAdmittedSet); + if(ulStatus != 1) + { + goto failed_restore_sf_param; + } + if(pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Authorized Set "); + ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAuthorizedSet,(PUCHAR)&pstAddIndicationDest->sfAuthorizedSet); + if(ulStatus != 1) + { + goto failed_restore_sf_param; + } + if(pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet"); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size %x %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest); + //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); + return pstAddIndicationDest; +failed_restore_sf_param: + bcm_kfree(pstAddIndicationDest); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" ); + return NULL; +} + +ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) +{ + ULONG ulTargetDsxBuffersBase = 0; + ULONG ulCntTargetBuffers; + ULONG ulIndex=0; + int Status; + + if(Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) + return 1; + + if(NULL == Adapter) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adapter was NULL!!!"); + return 0; + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %x ",sizeof(stServiceFlowParamSI)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ",DSX_MESSAGE_EXCHANGE_BUFFER); + + Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, + (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); + if(Status < 0) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!"); + return 0; + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx",ulTargetDsxBuffersBase); + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :",ulTargetDsxBuffersBase); + + ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE/sizeof(stServiceFlowParamSI); + + Adapter->ulTotalTargetBuffersAvailable = + ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ? + MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ",Adapter->ulTotalTargetBuffersAvailable); + + for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable ; ulIndex++) + { + Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer = ulTargetDsxBuffersBase; + Adapter->astTargetDsxBuffer[ulIndex].valid=1; + Adapter->astTargetDsxBuffer[ulIndex].tid=0; + ulTargetDsxBuffersBase+=sizeof(stServiceFlowParamSI); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", + ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); + } + Adapter->ulCurrentTargetBuffer = 0; + Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable; + return 1; +} + +ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid) +{ + ULONG ulTargetDSXBufferAddress; + ULONG ulTargetDsxBufferIndexToUse,ulMaxTry; + + if((Adapter->ulTotalTargetBuffersAvailable == 0)|| + (Adapter->ulFreeTargetBufferCnt == 0)) + { + ClearTargetDSXBuffer(Adapter,tid,FALSE); + return 0; + } + + ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer; + ulMaxTry = Adapter->ulTotalTargetBuffersAvailable; + while((ulMaxTry)&&(Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) + { + ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)% + Adapter->ulTotalTargetBuffersAvailable; + ulMaxTry--; + } + + if(ulMaxTry==0) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ",Adapter->ulFreeTargetBufferCnt); + ClearTargetDSXBuffer(Adapter,tid,FALSE); + return 0; + } + + + ulTargetDSXBufferAddress = + Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer; + Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid=0; + Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid=tid; + Adapter->ulFreeTargetBufferCnt--; + + + ulTargetDsxBufferIndexToUse = + (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable; + Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", + ulTargetDSXBufferAddress,tid); + return ulTargetDSXBufferAddress; +} + + +INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) +{ + /* + //Need to Allocate memory to contain the SUPER Large structures + //Our driver cant create these structures on Stack + */ + Adapter->caDsxReqResp=kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL); + if(!Adapter->caDsxReqResp) + return -ENOMEM; + return 0; +} + +INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) +{ + if(Adapter->caDsxReqResp) + { + bcm_kfree(Adapter->caDsxReqResp); + } + return 0; + +} +/** +@ingroup ctrl_pkt_functions +This routinue would process the Control responses +for the Connection Management. +@return - Queue index for the free SFID else returns Invalid Index. +*/ +BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**u16TID, FALSE); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); + return FALSE; + } + + DumpCmControlPacket(pstAddIndication); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>"); + pLeader = (PLEADER)Adapter->caDsxReqResp; + + pLeader->Status =CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; + pLeader->Vcid = 0; + + ClearTargetDSXBuffer(Adapter,pstAddIndication->u16TID,FALSE); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n",pstAddIndication->u16TID); + switch(pstAddIndication->u8Type) + { + case DSA_REQ: + { + pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength ); + *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) + = *pstAddIndication; + ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); + CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); + bcm_kfree(pstAddIndication); + } + break; + case DSA_RSP: + { + pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", + pLeader->PLength); + *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) + = *pstAddIndication; + ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; + + }//no break here..we should go down. + case DSA_ACK: + { + UINT uiSearchRuleIndex=0; + struct timeval tv = {0}; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X", + ntohs(pstAddIndication->u16VCID)); + uiSearchRuleIndex=SearchFreeSfid(Adapter); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiSearchRuleIndex:0x%X ", + uiSearchRuleIndex); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Direction:0x%X ", + pstAddIndication->u8Direction); + if((uiSearchRuleIndex< NO_OF_QUEUES) ) + { + Adapter->PackInfo[uiSearchRuleIndex].ucDirection = + pstAddIndication->u8Direction; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ", + pstAddIndication->sfActiveSet.bValid); + if(pstAddIndication->sfActiveSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE; + } + if(pstAddIndication->sfAuthorizedSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE; + } + if(pstAddIndication->sfAdmittedSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE; + } + if(FALSE == pstAddIndication->sfActiveSet.bValid) + { + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; + if(pstAddIndication->sfAdmittedSet.bValid) + { + psfLocalSet = &pstAddIndication->sfAdmittedSet; + } + else if(pstAddIndication->sfAuthorizedSet.bValid) + { + psfLocalSet = &pstAddIndication->sfAuthorizedSet; + } + } + else + { + psfLocalSet = &pstAddIndication->sfActiveSet; + Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; + } + + if(!psfLocalSet) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); + Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; + bcm_kfree(pstAddIndication); + } + + else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK"); + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = + ntohs(pstAddIndication->u16VCID); + Adapter->PackInfo[uiSearchRuleIndex].usCID = + ntohs(pstAddIndication->u16CID); + + if(UPLINK_DIR == pstAddIndication->u8Direction) + atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT); + CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex, + DSA_ACK, pstAddIndication); + // don't free pstAddIndication + + /* Inside CopyToAdapter, Sorting of all the SFs take place. + Hence any access to the newly added SF through uiSearchRuleIndex is invalid. + SHOULD BE STRICTLY AVOIDED. + */ +// *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; + memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4); + + if(pstAddIndication->sfActiveSet.bValid == TRUE) + { + if(UPLINK_DIR == pstAddIndication->u8Direction) + { + if(!Adapter->LinkUpStatus) + { + netif_carrier_on(Adapter->dev); + netif_start_queue(Adapter->dev); + Adapter->LinkUpStatus = 1; + do_gettimeofday(&tv); + + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); + Adapter->liTimeSinceLastNetEntry = tv.tv_sec; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!"); + } + } + } + } + + else + { + Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; + bcm_kfree(pstAddIndication); + } + } + else + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); + bcm_kfree(pstAddIndication); + return FALSE; + } + } + break; + case DSC_REQ: + { + pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); + pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); + + *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; + + CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); + bcm_kfree(pstAddIndication); + } + break; + case DSC_RSP: + { + pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); + pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); + *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; + } + case DSC_ACK: + { + UINT uiSearchRuleIndex=0; + + pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + uiSearchRuleIndex=SearchSfid(Adapter,ntohl(pstChangeIndication->sfActiveSet.u32SFID)); + if(uiSearchRuleIndex > NO_OF_QUEUES-1) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); + } + if((uiSearchRuleIndex < NO_OF_QUEUES)) + { + Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction; + if(pstChangeIndication->sfActiveSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE; + } + if(pstChangeIndication->sfAuthorizedSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE; + } + if(pstChangeIndication->sfAdmittedSet.bValid==TRUE) + { + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE; + } + + if(FALSE==pstChangeIndication->sfActiveSet.bValid) + { + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; + if(pstChangeIndication->sfAdmittedSet.bValid) + { + psfLocalSet = &pstChangeIndication->sfAdmittedSet; + } + else if(pstChangeIndication->sfAuthorizedSet.bValid) + { + psfLocalSet = &pstChangeIndication->sfAuthorizedSet; + } + } + + else + { + psfLocalSet = &pstChangeIndication->sfActiveSet; + Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; + } + if(psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) + { + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = + ntohs(pstChangeIndication->u16VCID); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n", + pstChangeIndication->u8CC, psfLocalSet->bValid); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID)); + Adapter->PackInfo[uiSearchRuleIndex].usCID = + ntohs(pstChangeIndication->u16CID); + CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex, + DSC_ACK, pstAddIndication); + + *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; + } + else if(pstChangeIndication->u8CC == 6) + { + deleteSFBySfid(Adapter,uiSearchRuleIndex); + bcm_kfree(pstAddIndication); + } + } + else + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); + bcm_kfree(pstAddIndication); + return FALSE; + } + } + break; + case DSD_REQ: + { + UINT uiSearchRuleIndex; + ULONG ulSFID; + + pLeader->PLength = sizeof(stLocalSFDeleteIndication); + *((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication*)pstAddIndication); + + ulSFID = ntohl(((stLocalSFDeleteIndication*)pstAddIndication)->u32SFID); + uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x",uiSearchRuleIndex); + + if(uiSearchRuleIndex < NO_OF_QUEUES) + { + //Delete All Classifiers Associated with this SFID + deleteSFBySfid(Adapter,uiSearchRuleIndex); + Adapter->u32TotalDSD++; + } + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC"); + ((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; + CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); + } + case DSD_RSP: + { + //Do nothing as SF has already got Deleted + } + break; + case DSD_ACK: + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n"); + break; + default: + bcm_kfree(pstAddIndication); + return FALSE ; + } + return TRUE; +} + +int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, PUCHAR user_buffer) +{ + int status = 0; + struct _packet_info *psSfInfo=NULL; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status); + status = SearchSfid(Adapter, uiSFId); + if(status>NO_OF_QUEUES) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId ); + return -EINVAL; + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status); + psSfInfo=&Adapter->PackInfo[status]; + if(psSfInfo->pstSFIndication && copy_to_user((PCHAR)user_buffer, + (PCHAR)psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId ); + status = -EFAULT; + return status; + } + return STATUS_SUCCESS; +} + +VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer) +{ + B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); + stIM_SFHostNotify *pHostInfo = NULL; + UINT uiSearchRuleIndex = 0; + ULONG ulSFID = 0; + + puiBuffer+=2; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n",u32NumofSFsinMsg); + + while(u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) + { + u32NumofSFsinMsg--; + pHostInfo = (stIM_SFHostNotify *)puiBuffer; + puiBuffer = (PUINT)(pHostInfo + 1); + + ulSFID = ntohl(pHostInfo->SFID); + uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"SFID: 0x%lx\n",ulSFID); + + if(uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID); + continue; + } + + if(pHostInfo->RetainSF == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Going to Delete SF"); + deleteSFBySfid(Adapter,uiSearchRuleIndex); + } + else + { + + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pHostInfo->VCID); + Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pHostInfo->newCID); + Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"pHostInfo->QoSParamSet: 0x%x\n",pHostInfo->QoSParamSet); + + if(pHostInfo->QoSParamSet & 0x1) + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet =TRUE; + if(pHostInfo->QoSParamSet & 0x2) + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet =TRUE; + if(pHostInfo->QoSParamSet & 0x4) + { + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet =TRUE; + Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; + } + } + } +} + + + diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h new file mode 100644 index 000000000000..847782c3765b --- /dev/null +++ b/drivers/staging/bcm/CmHost.h @@ -0,0 +1,166 @@ +/// ************************************************************************** +/// (c) Beceem Communications Inc. +/// All Rights Reserved +/// +/// \file : CmHost.h +/// \author : Rajeev Tirumala +/// \date : September 8 , 2006 +/// \brief : Definitions for Connection Management Requests structure +/// which we will use to setup our connection structures.Its high +/// time we had a header file for CmHost.cpp to isolate the way +/// f/w sends DSx messages and the way we interpret them in code. +/// Revision History +/// +/// Date Author Version Description +/// 08-Sep-06 Rajeev 0.1 Created +/// ************************************************************************** +#ifndef _CM_HOST_H +#define _CM_HOST_H + +#pragma once +#pragma pack (push,4) + +#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 // This contains the pointer +#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 // 24 K Bytes + +/// \brief structure stLocalSFAddRequest +typedef struct stLocalSFAddRequestAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + + + /// \brief structure ParameterSet + stServiceFlowParamSI sfParameterSet; + + //USE_MEMORY_MANAGER(); +}stLocalSFAddRequestAlt; + +/// \brief structure stLocalSFAddIndication +typedef struct stLocalSFAddIndicationAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + /// \brief structure AuthorizedSet + stServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + stServiceFlowParamSI sfAdmittedSet; + /// \brief structure ActiveSet + stServiceFlowParamSI sfActiveSet; + + B_UINT8 u8CC; /**< Confirmation Code*/ + B_UINT8 u8Padd; /**< 8-bit Padding */ + B_UINT16 u16Padd; /**< 16 bit Padding */ +// USE_MEMORY_MANAGER(); +}stLocalSFAddIndicationAlt; + +/// \brief structure stLocalSFAddConfirmation +typedef struct stLocalSFAddConfirmationAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + /// \brief structure AuthorizedSet + stServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + stServiceFlowParamSI sfAdmittedSet; + /// \brief structure ActiveSet + stServiceFlowParamSI sfActiveSet; +}stLocalSFAddConfirmationAlt; + + +/// \brief structure stLocalSFChangeRequest +typedef struct stLocalSFChangeRequestAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + /* + //Pointer location at which following Service Flow param Structure can be read + //from the target. We get only the address location and we need to read out the + //entire SF param structure at the given location on target + */ + /// \brief structure AuthorizedSet + stServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + stServiceFlowParamSI sfAdmittedSet; + /// \brief structure ParameterSet + stServiceFlowParamSI sfActiveSet; + + B_UINT8 u8CC; /**< Confirmation Code*/ + B_UINT8 u8Padd; /**< 8-bit Padding */ + B_UINT16 u16Padd; /**< 16 bit */ + +}stLocalSFChangeRequestAlt; + +/// \brief structure stLocalSFChangeConfirmation +typedef struct stLocalSFChangeConfirmationAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + /// \brief structure AuthorizedSet + stServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + stServiceFlowParamSI sfAdmittedSet; + /// \brief structure ActiveSet + stServiceFlowParamSI sfActiveSet; + +}stLocalSFChangeConfirmationAlt; + +/// \brief structure stLocalSFChangeIndication +typedef struct stLocalSFChangeIndicationAlt{ + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /// \brief 16bitCID + B_UINT16 u16CID; + /// \brief 16bitVCID + B_UINT16 u16VCID; + /// \brief structure AuthorizedSet + stServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + stServiceFlowParamSI sfAdmittedSet; + /// \brief structure ActiveSet + stServiceFlowParamSI sfActiveSet; + + B_UINT8 u8CC; /**< Confirmation Code*/ + B_UINT8 u8Padd; /**< 8-bit Padding */ + B_UINT16 u16Padd; /**< 16 bit */ + +}stLocalSFChangeIndicationAlt; + +ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength); + +ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid); + +INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter); + +INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter); +ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter); + +BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer); + +VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex); + +#pragma pack (pop) + +#endif diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c new file mode 100644 index 000000000000..8907e211d483 --- /dev/null +++ b/drivers/staging/bcm/DDRInit.c @@ -0,0 +1,1302 @@ +#include "headers.h" + +#ifndef BCM_SHM_INTERFACE + + +#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00 +#define MIPS_CLOCK_REG 0x0f000820 + + //DDR INIT-133Mhz +#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 //index for 0x0F007000 +static DDR_SET_NODE asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting + {0x0F000800,0x00007212}, + {0x0f000820,0x07F13FFF}, + {0x0f000810,0x00000F95}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF1B00}, + {0x0f000870,0x00000002}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00a04C,0x0000000C}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x02000007}, + {0x0F007028,0x02020202}, + {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x05000000}, + {0x0F007034,0x00000003}, + {0x0F007038,0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x02101010},//ROB - 0x02101010,//0x02101018}, + {0x0F007040,0x45751200},//ROB - 0x45751200,//0x450f1200}, + {0x0F007044,0x110a0d00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x081b0306}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0000001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x0010246c}, + {0x0F007064,0x00000010}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00007000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00000104}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} + }; +//80Mhz +#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 //index for 0x0F007000 +static DDR_SET_NODE asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting + {0x0f000810,0x00000F95}, + {0x0f000820,0x07f1ffff}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00a000,0x00000016}, + {0x0F00a04C,0x0000000C}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01000000}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020000}, + {0x0F007020,0x04020107}, + {0x0F007024,0x00000007}, + {0x0F007028,0x02020201}, + {0x0F00702c,0x0204040a}, + {0x0F007030,0x04000000}, + {0x0F007034,0x00000002}, + {0x0F007038,0x1F060200}, + {0x0F00703C,0x1C22221F}, + {0x0F007040,0x8A006600}, + {0x0F007044,0x221a0800}, + {0x0F007048,0x02690204}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0000001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x000A15D6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00004000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007094,0x00000104}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} + }; +//100Mhz +#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 //index for 0x0F007000 +static DDR_SET_NODE asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting + {0x0F000800,0x00007008}, + {0x0f000810,0x00000F95}, + {0x0f000820,0x07F13E3F}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + //0x0f000840,0x0FFF1800, + {0x0f000840,0x0FFF1B00}, + {0x0f000870,0x00000002}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00a04C,0x0000000C}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020001}, // POP - 0x00020000 Normal 0x01020000 + {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x00000007}, + {0x0F007028,0x01020201}, + {0x0F00702c,0x0204040A}, + {0x0F007030,0x06000000}, + {0x0F007034,0x00000004}, + {0x0F007038,0x20080200}, + {0x0F00703C,0x02030320}, + {0x0F007040,0x6E7F1200}, + {0x0F007044,0x01190A00}, + {0x0F007048,0x06120305},//0x02690204 // 0x06120305 + {0x0F00704c,0x00000000}, + {0x0F007050,0x0000001C}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x00082ED6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00005000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00000104}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} + }; + +//Net T3B DDR Settings +//DDR INIT-133Mhz +static DDR_SET_NODE asDPLL_266MHZ[] = { + {0x0F000800,0x00007212}, + {0x0f000820,0x07F13FFF}, + {0x0f000810,0x00000F95}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF1B00}, + {0x0f000870,0x00000002} + }; +#if 0 +static DDR_SET_NODE asDPLL_800MHZ[] = { + {0x0f000810,0x00000F95}, + {0x0f000810,0x00000F95}, + {0x0f000810,0x00000F95}, + {0x0f000820,0x03F1365B}, + {0x0f000840,0x0FFF0000}, + {0x0f000880,0x000003DD}, + {0x0f000860,0x00000000} + }; +#endif + +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000 +static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting + {0x0f000810,0x00000F95}, + {0x0f000810,0x00000F95}, + {0x0f000810,0x00000F95}, + {0x0f000820,0x07F13652}, + {0x0f000840,0x0FFF0800}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000880,0x000003DD}, + {0x0f000860,0x00000000}, + // Changed source for X-bar and MIPS clock to APLL + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x02000007}, + {0x0F007028,0x02020202}, + {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x05000000}, + {0x0F007034,0x00000003}, + {0x0F007038,0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x02101012},//ROB - 0x02101010,//0x02101018}, + {0x0F007040,0x457D1200},//ROB - 0x45751200,//0x450f1200}, + {0x0F007044,0x11130d00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x040D0306}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0000001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x0010246c}, + {0x0F007064,0x00000012}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00007000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00000104}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000}, + }; + +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 +static DDR_SET_NODE asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting + {0x0f000810,0x00000F95}, + {0x0f000820,0x07F13FFF}, + {0x0f000840,0x0FFF1F00}, + {0x0f000880,0x000003DD}, + {0x0f000860,0x00000000}, + + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00a000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01000000}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020000}, + {0x0F007020,0x04020107}, + {0x0F007024,0x00000007}, + {0x0F007028,0x02020201}, + {0x0F00702c,0x0204040a}, + {0x0F007030,0x04000000}, + {0x0F007034,0x02000002}, + {0x0F007038,0x1F060202}, + {0x0F00703C,0x1C22221F}, + {0x0F007040,0x8A006600}, + {0x0F007044,0x221a0800}, + {0x0F007048,0x02690204}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x000A15D6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00004000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007094,0x00000104}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} + }; + +//100Mhz +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 //index for 0x0F007000 +static DDR_SET_NODE asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting + {0x0f000810,0x00000F95}, + {0x0f000820,0x07F1369B}, + {0x0f000840,0x0FFF0800}, + {0x0f000880,0x000003DD}, + {0x0f000860,0x00000000}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020000}, // POP - 0x00020000 Normal 0x01020000 + {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x00000007}, + {0x0F007028,0x01020201}, + {0x0F00702c,0x0204040A}, + {0x0F007030,0x06000000}, + {0x0F007034,0x02000004}, + {0x0F007038,0x20080200}, + {0x0F00703C,0x02030320}, + {0x0F007040,0x6E7F1200}, + {0x0F007044,0x01190A00}, + {0x0F007048,0x06120305},//0x02690204 // 0x06120305 + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001C}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x00082ED6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00005000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00000104}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} + }; + + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 //index for 0x0F007000 +static DDR_SET_NODE asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting + {0x0f000820,0x03F1365B}, + {0x0f000810,0x00002F95}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF0000}, + {0x0f000860,0x00000000}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00A000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x02000007}, + {0x0F007028,0x02020200}, + {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x05000000}, + {0x0F007034,0x00000003}, + {0x0F007038,0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x02101020},//ROB - 0x02101010,//0x02101018, + {0x0F007040,0x45711200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044,0x110D0D00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x04080306}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x0010245F}, + {0x0F007064,0x00000010}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00007000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007088,0x01000001}, + {0x0F00708c,0x00000101}, + {0x0F007090,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00040000}, + {0x0F007098,0x00000000}, + {0x0F0070c8,0x00000104}, + //# Enable 2 ports within X-bar + //# Enable start bit within memory controller + {0x0F007018,0x01010000} +}; + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 //index for 0x0F007000 +static DDR_SET_NODE asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting + {0x0f000810,0x00002F95}, + {0x0f000820,0x03F1369B}, + {0x0f000840,0x0fff0000}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF0000}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x00000007}, + {0x0F007028,0x01020200}, + {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x06000000}, + {0x0F007034,0x00000004}, + {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, + {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x03000305}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x00082ED6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00005000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007088,0x01000001}, + {0x0F00708c,0x00000101}, + {0x0F007090,0x00000000}, + {0x0F007094,0x00010000}, + {0x0F007098,0x00000000}, + {0x0F0070C8,0x00000104}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} +}; + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 +static DDR_SET_NODE asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting + {0x0f000820,0x07F13FFF}, + {0x0f000810,0x00002F95}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + {0x0f000840,0x0FFF1F00}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0F00a084,0x1Cffffff}, + {0x0F00a080,0x1C000000}, + {0x0F00A000,0x00000016}, + {0x0f007000,0x00010001}, + {0x0f007004,0x01000000}, + {0x0f007008,0x01000001}, + {0x0f00700c,0x00000000}, + {0x0f007010,0x01000000}, + {0x0f007014,0x01000100}, + {0x0f007018,0x01000000}, + {0x0f00701c,0x01020000}, + {0x0f007020,0x04020107}, + {0x0f007024,0x00000007}, + {0x0f007028,0x02020200}, + {0x0f00702c,0x0204040a}, + {0x0f007030,0x04000000}, + {0x0f007034,0x00000002}, + {0x0f007038,0x1d060200}, + {0x0f00703c,0x1c22221d}, + {0x0f007040,0x8A116600}, + {0x0f007044,0x222d0800}, + {0x0f007048,0x02690204}, + {0x0f00704c,0x00000000}, + {0x0f007050,0x0100001c}, + {0x0f007054,0x00000000}, + {0x0f007058,0x00000000}, + {0x0f00705c,0x00000000}, + {0x0f007060,0x000A15D6}, + {0x0f007064,0x0000000A}, + {0x0f007068,0x00000000}, + {0x0f00706c,0x00000001}, + {0x0f007070,0x00004000}, + {0x0f007074,0x00000000}, + {0x0f007078,0x00000000}, + {0x0f00707c,0x00000000}, + {0x0f007080,0x00000000}, + {0x0f007084,0x00000000}, + {0x0f007088,0x01000001}, + {0x0f00708c,0x00000101}, + {0x0f007090,0x00000000}, + {0x0f007094,0x00010000}, + {0x0f007098,0x00000000}, + {0x0F0070C8,0x00000104}, + {0x0F007018,0x01010000} +}; + + + + +///T3 LP-B (UMA-B) + +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 //index for 0x0F007000 +static DDR_SET_NODE asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting + + {0x0f000820,0x03F137DB}, + {0x0f000810,0x01842795}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + {0x0f000840,0x0FFF0400}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0f003050,0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084,0x1Cffffff},//Now dump from her in internal memory + {0x0F00a080,0x1C000000}, + {0x0F00A000,0x00000016}, + {0x0f007000,0x00010001}, + {0x0f007004,0x01000001}, + {0x0f007008,0x01000101}, + {0x0f00700c,0x00000000}, + {0x0f007010,0x01000100}, + {0x0f007014,0x01000100}, + {0x0f007018,0x01000000}, + {0x0f00701c,0x01020000}, + {0x0f007020,0x04030107}, + {0x0f007024,0x02000007}, + {0x0f007028,0x02020200}, + {0x0f00702c,0x0206060a}, + {0x0f007030,0x050d0d00}, + {0x0f007034,0x00000003}, + {0x0f007038,0x170a0200}, + {0x0f00703c,0x02101012}, + {0x0f007040,0x45161200}, + {0x0f007044,0x11250c00}, + {0x0f007048,0x04da0307}, + {0x0f00704c,0x00000000}, + {0x0f007050,0x0000001c}, + {0x0f007054,0x00000000}, + {0x0f007058,0x00000000}, + {0x0f00705c,0x00000000}, + {0x0f007060,0x00142bb6}, + {0x0f007064,0x20430014}, + {0x0f007068,0x00000000}, + {0x0f00706c,0x00000001}, + {0x0f007070,0x00009000}, + {0x0f007074,0x00000000}, + {0x0f007078,0x00000000}, + {0x0f00707c,0x00000000}, + {0x0f007080,0x00000000}, + {0x0f007084,0x00000000}, + {0x0f007088,0x01000001}, + {0x0f00708c,0x00000101}, + {0x0f007090,0x00000000}, + {0x0f007094,0x00040000}, + {0x0f007098,0x00000000}, + {0x0F0070C8,0x00000104}, + {0x0F007018,0x01010000} +}; + + +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 //index for 0x0F007000 +static DDR_SET_NODE asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting + {0x0f000820,0x03F1365B}, + {0x0f000810,0x00002F95}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF0000}, + {0x0f000860,0x00000000}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084,0x1Cffffff},//dump from here in internal memory + {0x0F00a080,0x1C000000}, + {0x0F00A000,0x00000016}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x02000007}, + {0x0F007028,0x02020200}, + {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x05000000}, + {0x0F007034,0x00000003}, + {0x0F007038,0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x02101017},//ROB - 0x02101010,//0x02101018, + {0x0F007040,0x45171200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044,0x11290D00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x04080306}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x0010245F}, + {0x0F007064,0x00000010}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00007000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007088,0x01000001}, + {0x0F00708c,0x00000101}, + {0x0F007090,0x00000000}, + //# Enable BW improvement within memory controller + {0x0F007094,0x00040000}, + {0x0F007098,0x00000000}, + {0x0F0070c8,0x00000104}, + //# Enable 2 ports within X-bar + //# Enable start bit within memory controller + {0x0F007018,0x01010000} +}; + +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 //index for 0x0F007000 +static DDR_SET_NODE asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting + {0x0f000810,0x00002F95}, + {0x0f000820,0x03F1369B}, + {0x0f000840,0x0fff0000}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + // Changed source for X-bar and MIPS clock to APLL + {0x0f000840,0x0FFF0000}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084,0x1Cffffff}, //dump from here in internal memory + {0x0F00a080,0x1C000000}, + //Memcontroller Default values + {0x0F007000,0x00010001}, + {0x0F007004,0x01010100}, + {0x0F007008,0x01000001}, + {0x0F00700c,0x00000000}, + {0x0F007010,0x01000000}, + {0x0F007014,0x01000100}, + {0x0F007018,0x01000000}, + {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024,0x00000007}, + {0x0F007028,0x01020200}, + {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030,0x06000000}, + {0x0F007034,0x00000004}, + {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, + {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048,0x03000305}, + {0x0F00704c,0x00000000}, + {0x0F007050,0x0100001c}, + {0x0F007054,0x00000000}, + {0x0F007058,0x00000000}, + {0x0F00705c,0x00000000}, + {0x0F007060,0x00082ED6}, + {0x0F007064,0x0000000A}, + {0x0F007068,0x00000000}, + {0x0F00706c,0x00000001}, + {0x0F007070,0x00005000}, + {0x0F007074,0x00000000}, + {0x0F007078,0x00000000}, + {0x0F00707C,0x00000000}, + {0x0F007080,0x00000000}, + {0x0F007084,0x00000000}, + {0x0F007088,0x01000001}, + {0x0F00708c,0x00000101}, + {0x0F007090,0x00000000}, + {0x0F007094,0x00010000}, + {0x0F007098,0x00000000}, + {0x0F0070C8,0x00000104}, + //# Enable 2 ports within X-bar + {0x0F00A000,0x00000016}, + //# Enable start bit within memory controller + {0x0F007018,0x01010000} +}; + +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 //index for 0x0F007000 +static DDR_SET_NODE asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting + {0x0f000820,0x07F13FFF}, + {0x0f000810,0x00002F95}, + {0x0f000860,0x00000000}, + {0x0f000880,0x000003DD}, + {0x0f000840,0x0FFF1F00}, + {0x0F00a044,0x1fffffff}, + {0x0F00a040,0x1f000000}, + {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084,0x1Cffffff},// dump from here in internal memory + {0x0F00a080,0x1C000000}, + {0x0F00A000,0x00000016}, + {0x0f007000,0x00010001}, + {0x0f007004,0x01000000}, + {0x0f007008,0x01000001}, + {0x0f00700c,0x00000000}, + {0x0f007010,0x01000000}, + {0x0f007014,0x01000100}, + {0x0f007018,0x01000000}, + {0x0f00701c,0x01020000}, + {0x0f007020,0x04020107}, + {0x0f007024,0x00000007}, + {0x0f007028,0x02020200}, + {0x0f00702c,0x0204040a}, + {0x0f007030,0x04000000}, + {0x0f007034,0x00000002}, + {0x0f007038,0x1d060200}, + {0x0f00703c,0x1c22221d}, + {0x0f007040,0x8A116600}, + {0x0f007044,0x222d0800}, + {0x0f007048,0x02690204}, + {0x0f00704c,0x00000000}, + {0x0f007050,0x0100001c}, + {0x0f007054,0x00000000}, + {0x0f007058,0x00000000}, + {0x0f00705c,0x00000000}, + {0x0f007060,0x000A15D6}, + {0x0f007064,0x0000000A}, + {0x0f007068,0x00000000}, + {0x0f00706c,0x00000001}, + {0x0f007070,0x00004000}, + {0x0f007074,0x00000000}, + {0x0f007078,0x00000000}, + {0x0f00707c,0x00000000}, + {0x0f007080,0x00000000}, + {0x0f007084,0x00000000}, + {0x0f007088,0x01000001}, + {0x0f00708c,0x00000101}, + {0x0f007090,0x00000000}, + {0x0f007094,0x00010000}, + {0x0f007098,0x00000000}, + {0x0F0070C8,0x00000104}, + {0x0F007018,0x01010000} +}; + + +int ddr_init(MINI_ADAPTER *Adapter) +{ + PDDR_SETTING psDDRSetting=NULL; + ULONG RegCount=0; + ULONG value = 0; + UINT uiResetValue = 0; + UINT uiClockSetting = 0; + int retval = STATUS_SUCCESS; + + switch (Adapter->chip_id) + { + case 0xbece3200: + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting=asT3LP_DDRSetting80MHz; + RegCount=(sizeof(asT3LP_DDRSetting80MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_100_MHZ: + psDDRSetting=asT3LP_DDRSetting100MHz; + RegCount=(sizeof(asT3LP_DDRSetting100MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_133_MHZ: + psDDRSetting=asT3LP_DDRSetting133MHz; + RegCount=(sizeof(asT3LP_DDRSetting133MHz)/ + sizeof(DDR_SETTING)); + if(Adapter->bMipsConfig == MIPS_200_MHZ) + { + uiClockSetting = 0x03F13652; + } + else + { + uiClockSetting = 0x03F1365B; + } + break; + default: + return -EINVAL; + } + + break; + case T3LPB: + case BCS220_2: + case BCS220_2BC: + case BCS250_BC: + case BCS220_3 : + /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive + * (please check current value and additionally set these bits) + */ + if( (Adapter->chip_id != BCS220_2) && + (Adapter->chip_id != BCS220_2BC) && + (Adapter->chip_id != BCS220_3) ) + { + retval= rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue |= 0x44; + retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, WRM, DBG_LVL_ALL, "%s:%d WRM failed\n", __FUNCTION__, __LINE__); + return retval; + } + } + switch(Adapter->DDRSetting) + { + + + + case DDR_80_MHZ: + psDDRSetting = asT3LPB_DDRSetting80MHz; + RegCount=(sizeof(asT3B_DDRSetting80MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_100_MHZ: + psDDRSetting=asT3LPB_DDRSetting100MHz; + RegCount=(sizeof(asT3B_DDRSetting100MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_133_MHZ: + psDDRSetting = asT3LPB_DDRSetting133MHz; + RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + sizeof(DDR_SETTING)); + + if(Adapter->bMipsConfig == MIPS_200_MHZ) + { + uiClockSetting = 0x03F13652; + } + else + { + uiClockSetting = 0x03F1365B; + } + break; + + case DDR_160_MHZ: + psDDRSetting = asT3LPB_DDRSetting160MHz; + RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SETTING); + + if(Adapter->bMipsConfig == MIPS_200_MHZ) + { + uiClockSetting = 0x03F137D2; + } + else + { + uiClockSetting = 0x03F137DB; + } + } + break; + + case 0xbece0110: + case 0xbece0120: + case 0xbece0121: + case 0xbece0130: + case 0xbece0300: + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting); + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3_DDRSetting80MHz; + RegCount = (sizeof(asT3_DDRSetting80MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_100_MHZ: + psDDRSetting = asT3_DDRSetting100MHz; + RegCount = (sizeof(asT3_DDRSetting100MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_133_MHZ: + psDDRSetting = asT3_DDRSetting133MHz; + RegCount = (sizeof(asT3_DDRSetting133MHz)/ + sizeof(DDR_SETTING)); + break; + default: + return -EINVAL; + } + case 0xbece0310: + { + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3B_DDRSetting80MHz; + RegCount=(sizeof(asT3B_DDRSetting80MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_100_MHZ: + psDDRSetting=asT3B_DDRSetting100MHz; + RegCount=(sizeof(asT3B_DDRSetting100MHz)/ + sizeof(DDR_SETTING)); + break; + case DDR_133_MHZ: + + if(Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected. + { + memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, + sizeof(asDPLL_266MHZ)); + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + sizeof(DDR_SETTING)); + } + else + { + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + sizeof(DDR_SETTING)); + if(Adapter->bMipsConfig == MIPS_200_MHZ) + { + uiClockSetting = 0x07F13652; + } + else + { + uiClockSetting = 0x07F1365B; + } + } + break; + default: + return -EINVAL; + } + break; + + } + default: + return -EINVAL; + } + + value=0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount); + while(RegCount && !retval) + { + if(uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) + { + value = uiClockSetting; + } + else + { + value = psDDRSetting->ulRegValue; + } + retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value)); + if(STATUS_SUCCESS != retval) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); + break; + } + + RegCount--; + psDDRSetting++; + } + + if(Adapter->chip_id >= 0xbece3300 ) + { + + mdelay(3); + if( (Adapter->chip_id != BCS220_2)&& + (Adapter->chip_id != BCS220_2BC)&& + (Adapter->chip_id != BCS220_3)) + { + /* drive MDDR to half in case of UMA-B: */ + uiResetValue = 0x01010001; + retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x00040020; + retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x01020101; + retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x01010000; + retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + } + mdelay(3); + + /* DC/DC standby change... + * This is to be done only for Hybrid PMU mode. + * with the current h/w there is no way to detect this. + * and since we dont have internal PMU lets do it under UMA-B chip id. + * we will change this when we will have internal PMU. + */ + if(Adapter->PmuMode == HYBRID_MODE_7C) + { + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x1322a8; + retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x132296; + retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + } + else if(Adapter->PmuMode == HYBRID_MODE_6 ) + { + + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x6003229a; + retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + uiResetValue = 0x1322a8; + retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__); + return retval; + } + } + + } + Adapter->bDDRInitDone = TRUE; + return retval; +} + +int download_ddr_settings(PMINI_ADAPTER Adapter) +{ + PDDR_SET_NODE psDDRSetting=NULL; + ULONG RegCount=0; + unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY; + UINT value = 0; + int retval = STATUS_SUCCESS; + BOOLEAN bOverrideSelfRefresh = FALSE; + + switch (Adapter->chip_id) + { + case 0xbece3200: + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3LP_DDRSetting80MHz; + RegCount = (sizeof(asT3LP_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3LP_DDRSetting100MHz; + RegCount = (sizeof(asT3LP_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LP_DDRSetting133MHz; + RegCount = (sizeof(asT3LP_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + break; + default: + return -EINVAL; + } + break; + + case T3LPB: + case BCS220_2: + case BCS220_2BC: + case BCS250_BC: + case BCS220_3 : + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3LPB_DDRSetting80MHz; + RegCount=(sizeof(asT3LPB_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3LPB_DDRSetting100MHz; + RegCount = (sizeof(asT3LPB_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LPB_DDRSetting133MHz; + RegCount = (sizeof(asT3LPB_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + break; + + case DDR_160_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LPB_DDRSetting160MHz; + RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SET_NODE); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; + + break; + default: + return -EINVAL; + } + break; + case 0xbece0300: + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3_DDRSetting80MHz; + RegCount = (sizeof(asT3_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3_DDRSetting100MHz; + RegCount = (sizeof(asT3_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + psDDRSetting = asT3_DDRSetting133MHz; + RegCount = (sizeof(asT3_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + break; + default: + return -EINVAL; + } + break; + case 0xbece0310: + { + switch (Adapter->DDRSetting) + { + case DDR_80_MHZ: + psDDRSetting = asT3B_DDRSetting80MHz; + RegCount = (sizeof(asT3B_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3B_DDRSetting100MHz; + RegCount = (sizeof(asT3B_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount = (sizeof(asT3B_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + break; + } + break; + } + default: + return -EINVAL; + } + //total number of Register that has to be dumped + value =RegCount ; + retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); + + return retval; + } + ul_ddr_setting_load_addr+=sizeof(ULONG); + /*signature */ + value =(0x1d1e0dd0); + retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); + return retval; + } + + ul_ddr_setting_load_addr+=sizeof(ULONG); + RegCount*=(sizeof(DDR_SETTING)/sizeof(ULONG)); + + while(RegCount && !retval) + { + value = psDDRSetting->ulRegAddress ; + retval = wrmalt( Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); + ul_ddr_setting_load_addr+=sizeof(ULONG); + if(!retval) + { + if(bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) + { + value = (psDDRSetting->ulRegValue |(1<<8)); + if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr, + &value, sizeof(value))){ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); + break; + } + } + else + { + value = psDDRSetting->ulRegValue; + + if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr , + &value, sizeof(value))){ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); + break; + } + } + } + ul_ddr_setting_load_addr+=sizeof(ULONG); + RegCount--; + psDDRSetting++; + } + return retval; +} + +#endif + diff --git a/drivers/staging/bcm/DDRInit.h b/drivers/staging/bcm/DDRInit.h new file mode 100644 index 000000000000..550e260df539 --- /dev/null +++ b/drivers/staging/bcm/DDRInit.h @@ -0,0 +1,9 @@ +#ifndef _DDR_INIT_H_ +#define _DDR_INIT_H_ + + + +int ddr_init(PMINI_ADAPTER psAdapter); +int download_ddr_settings(PMINI_ADAPTER psAdapter); + +#endif diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c new file mode 100644 index 000000000000..213f4bcc5dfc --- /dev/null +++ b/drivers/staging/bcm/Debug.c @@ -0,0 +1,40 @@ +#include "headers.h" + +char *buff_dump_base[]={"DEC", "HEX", "OCT", "BIN" }; + +static UINT current_debug_level=BCM_SCREAM; + +int bcm_print_buffer( UINT debug_level, const char *function_name, + char *file_name, int line_number, unsigned char *buffer, int bufferlen, unsigned int base) +{ + if(debug_level>=current_debug_level) + { + int i=0; + printk("\n%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", file_name, function_name, line_number, bufferlen, buff_dump_base[1]); + for(;i +#define NONE 0xFFFF + +typedef enum _BASE_TYPE +{ + BCM_BASE_TYPE_DEC, + BCM_BASE_TYPE_OCT, + BCM_BASE_TYPE_BIN, + BCM_BASE_TYPE_HEX, + BCM_BASE_TYPE_NONE, +} BASE_TYPE, *PBASE_TYPE; + +int bcm_print_buffer( UINT debug_level, const char *function_name, + char *file_name, int line_number, unsigned char *buffer, int bufferlen, BASE_TYPE base); + +#ifdef BCM_SHM_INTERFACE +#define CPE_VIRTUAL_ERROR_CODE_BASE_ADDR (0xBFC02E00 + 0x4C) +// ERROR codes for debugging +extern unsigned char u32ErrorCounter ; +#define ERROR_DEVICE_REMOVED 0x1 +#define ERROR_LEADER_LENGTH_ZERO 0x2 +#define ERROR_LEADER_LENGTH_CORRUPTED 0x3 +#define ERROR_NO_SKBUFF 0x4 + +#define ERROR_DL_MODULE 0xaa000000 +extern void CPE_ERROR_LOG(unsigned int module,unsigned int code); + +#endif + + + + +//-------------------------------------------------------------------------------- + +/* TYPE and SUBTYPE + * Define valid TYPE (or category or code-path, however you like to think of it) + * and SUBTYPE s. + * Type and SubType are treated as bitmasks. + */ +/*-----------------BEGIN TYPEs------------------------------------------*/ +#define DBG_TYPE_INITEXIT (1 << 0) // 1 +#define DBG_TYPE_TX (1 << 1) // 2 +#define DBG_TYPE_RX (1 << 2) // 4 +#define DBG_TYPE_OTHERS (1 << 3) // 8 +/*-----------------END TYPEs------------------------------------------*/ +#define NUMTYPES 4 // careful! + +/*-----------------BEGIN SUBTYPEs---------------------------------------*/ + +/*-SUBTYPEs for TX : TYPE is DBG_TYPE_TX -----// + Transmit.c ,Arp.c, LeakyBucket.c, And Qos.c + total 17 macros */ +// Transmit.c +#define TX 1 +#define MP_SEND (TX<<0) +#define NEXT_SEND (TX<<1) +#define TX_FIFO (TX<<2) +#define TX_CONTROL (TX<<3) + +// Arp.c +#define IP_ADDR (TX<<4) +#define ARP_REQ (TX<<5) +#define ARP_RESP (TX<<6) + +// dhcp.c +//#define DHCP TX +//#define DHCP_REQ (DHCP<<7) + +// Leakybucket.c +#define TOKEN_COUNTS (TX<<8) +#define CHECK_TOKENS (TX<<9) +#define TX_PACKETS (TX<<10) +#define TIMER (TX<<11) + +// Qos.c +#define QOS TX +#define QUEUE_INDEX (QOS<<12) +#define IPV4_DBG (QOS<<13) +#define IPV6_DBG (QOS<<14) +#define PRUNE_QUEUE (QOS<<15) +#define SEND_QUEUE (QOS<<16) + +//TX_Misc +#define TX_OSAL_DBG (TX<<17) + + +//--SUBTYPEs for ------INIT & EXIT--------------------- +/*------------ TYPE is DBG_TYPE_INITEXIT -----// +DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c */ +#define MP 1 +#define DRV_ENTRY (MP<<0) +#define MP_INIT (MP<<1) +#define READ_REG (MP<<3) +#define DISPATCH (MP<<2) +#define CLAIM_ADAP (MP<<4) +#define REG_IO_PORT (MP<<5) +#define INIT_DISP (MP<<6) +#define RX_INIT (MP<<7) + + +//-SUBTYPEs for --RX---------------------------------- +//------------RX : TYPE is DBG_TYPE_RX -----// +// Receive.c +#define RX 1 +#define RX_DPC (RX<<0) +#define RX_CTRL (RX<<3) +#define RX_DATA (RX<<4) +#define MP_RETURN (RX<<1) +#define LINK_MSG (RX<<2) + + +//-SUBTYPEs for ----OTHER ROUTINES------------------ +//------------OTHERS : TYPE is DBG_TYPE_OTHER -----// +// HaltnReset,CheckForHang,PnP,Misc,CmHost +// total 12 macros +#define OTHERS 1 +// ??ISR.C + +#define ISR OTHERS +#define MP_DPC (ISR<<0) + +// HaltnReset.c +#define HALT OTHERS +#define MP_HALT (HALT<<1) +#define CHECK_HANG (HALT<<2) +#define MP_RESET (HALT<<3) +#define MP_SHUTDOWN (HALT<<4) + +// pnp.c +#define PNP OTHERS +#define MP_PNP (PNP<<5) + +// Misc.c +#define MISC OTHERS +#define DUMP_INFO (MISC<<6) +#define CLASSIFY (MISC<<7) +#define LINK_UP_MSG (MISC<<8) +#define CP_CTRL_PKT (MISC<<9) +#define DUMP_CONTROL (MISC<<10) +#define LED_DUMP_INFO (MISC<<11) + +// CmHost.c +#define CMHOST OTHERS + + +#define SERIAL (OTHERS<<12) +#define IDLE_MODE (OTHERS<<13) + +#define WRM (OTHERS<<14) +#define RDM (OTHERS<<15) + +// TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ? +#define PHS_SEND (OTHERS<<16) +#define PHS_RECIEVE (OTHERS<<17) +#define PHS_MODULE (OTHERS<<18) + +#define INTF_INIT (OTHERS<<19) +#define INTF_ERR (OTHERS<<20) +#define INTF_WARN (OTHERS<<21) +#define INTF_NORM (OTHERS<<22) + +#define IRP_COMPLETION (OTHERS<<23) +#define SF_DESCRIPTOR_CNTS (OTHERS<<24) +#define PHS_DISPATCH (OTHERS << 25) +#define OSAL_DBG (OTHERS << 26) +#define NVM_RW (OTHERS << 27) + +#define HOST_MIBS (OTHERS << 28) +#define CONN_MSG (CMHOST << 29) +//#define OTHERS_MISC (OTHERS << 29) // ProcSupport.c +/*-----------------END SUBTYPEs------------------------------------------*/ + + +/* Debug level + * We have 8 debug levels, in (numerical) increasing order of verbosity. + * IMP: Currently implementing ONLY DBG_LVL_ALL , i.e. , all debug prints will + * appear (of course, iff global debug flag is ON and we match the Type and SubType). + * Finer granularity debug levels are currently not in use, although the feature exists. + * + * Another way to say this: + * All the debug prints currently have 'debug_level' set to DBG_LVL_ALL . + * You can compile-time change that to any of the below, if you wish to. However, as of now, there's + * no dynamic facility to have the userspace 'TestApp' set debug_level. Slated for future expansion. + */ +#define BCM_ALL 7 +#define BCM_LOW 6 +#define BCM_PRINT 5 +#define BCM_NORMAL 4 +#define BCM_MEDIUM 3 +#define BCM_SCREAM 2 +#define BCM_ERR 1 +/* Not meant for developer in debug prints. + * To be used to disable all prints by setting the DBG_LVL_CURR to this value */ +#define BCM_NONE 0 + +/* The current driver logging level. + * Everything at this level and (numerically) lower (meaning higher prio) + * is logged. +* Replace 'BCM_ALL' in the DBG_LVL_CURR macro with the logging level desired. + * For eg. to set the logging level to 'errors only' use: + * #define DBG_LVL_CURR (BCM_ERR) + */ + +#define DBG_LVL_CURR (BCM_ALL) +#define DBG_LVL_ALL BCM_ALL + +/*---Userspace mapping of Debug State. + * Delibrately matches that of the Windows driver.. + * The TestApp's ioctl passes this struct to us. + */ +typedef struct +{ + unsigned int Subtype, Type; + unsigned int OnOff; +// unsigned int debug_level; /* future expansion */ +} __attribute__((packed)) USER_BCM_DBG_STATE; + +//---Kernel-space mapping of Debug State +typedef struct _S_BCM_DEBUG_STATE { + UINT type; + /* A bitmap of 32 bits for Subtype per Type. + * Valid indexes in 'subtype' array are *only* 1,2,4 and 8, + * corresponding to valid Type values. Hence we use the 'Type' field + * as the index value, ignoring the array entries 0,3,5,6,7 ! + */ + UINT subtype[(NUMTYPES*2)+1]; + UINT debug_level; +} S_BCM_DEBUG_STATE; +/* Instantiated in the Adapter structure */ +/* We'll reuse the debug level parameter to include a bit (the MSB) to indicate whether or not + * we want the function's name printed. */ +#define DBG_NO_FUNC_PRINT 1 << 31 +#define DBG_LVL_BITMASK 0xFF + +//--- Only for direct printk's; "hidden" to API. +#define DBG_TYPE_PRINTK 3 +#define PRINTKS_ON 1 // "hidden" from API, set to 0 to turn off all printk's + +#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) do { \ + if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \ + printk ("%s:" string, __FUNCTION__, ##args); \ + printk("\n"); \ + } else if (!Adapter) \ + ; \ + else { \ + if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \ + ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \ + if (dbg_level & DBG_NO_FUNC_PRINT) \ + printk (string, ##args); \ + else \ + { \ + printk ("%s:" string, __FUNCTION__, ##args); \ + printk("\n"); \ + } \ + } \ + } \ +} while (0) + +#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \ + if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \ + bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ + } else if (!Adapter) \ + ; \ + else { \ + if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \ + ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \ + if (dbg_level & DBG_NO_FUNC_PRINT) \ + bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ + else \ + bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ + } \ + } \ + } while (0) + + +#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \ + int i; \ + for (i=0; i<(NUMTYPES*2)+1; i++) { \ + if ((i == 1) || (i == 2) || (i == 4) || (i == 8)) { \ + /* CAUTION! Forcefully turn on ALL debug paths and subpaths! \ + Adapter->stDebugState.subtype[i] = 0xffffffff; */ \ + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "subtype[%d] = 0x%08x\n", \ + i, Adapter->stDebugState.subtype[i]); \ + } \ + } \ +} while (0) + +#endif + diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c new file mode 100644 index 000000000000..849951345ab2 --- /dev/null +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -0,0 +1,247 @@ +/** +@file HandleControlPacket.c +This file contains the routines to deal with +sending and receiving of control packets. +*/ +#include "headers.h" + +/** +When a control packet is received, analyze the +"status" and call appropriate response function. +Enqueue the control packet for Application. +@return None +*/ +VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**data); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "=====>"); + /* Get the Leader field */ + + switch(usStatus) + { + case CM_RESPONSES: // 0xA0 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "MAC Version Seems to be Non Multi-Classifier, rejected by Driver"); + HighPriorityMessage = TRUE ; + break; + case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: + HighPriorityMessage = TRUE ; + if(Adapter->LinkStatus==LINKUP_DONE) + { + CmControlResponseMessage(Adapter,(skb->data +sizeof(USHORT))); + } + break; + case LINK_CONTROL_RESP: //0xA2 + case STATUS_RSP: //0xA1 + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"LINK_CONTROL_RESP"); + HighPriorityMessage = TRUE ; + LinkControlResponseMessage(Adapter,(skb->data + sizeof(USHORT))); + break; + case STATS_POINTER_RESP: //0xA6 + HighPriorityMessage = TRUE ; + StatisticsResponse(Adapter, (skb->data + sizeof(USHORT))); + break; + case IDLE_MODE_STATUS: //0xA3 + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"IDLE_MODE_STATUS Type Message Got from F/W"); + InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data + + sizeof(USHORT))); + HighPriorityMessage = TRUE ; + break; + + case AUTH_SS_HOST_MSG: + HighPriorityMessage = TRUE ; + break; + + default: + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"Got Default Response"); + /* Let the Application Deal with This Packet */ + break; + } + + //Queue The Control Packet to The Application Queues + down(&Adapter->RxAppControlQueuelock); + + for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) + { + if(Adapter->device_removed) + { + break; + } + + drop_pkt_flag = TRUE ; + /* + There are cntrl msg from A0 to AC. It has been mapped to 0 to C bit in the cntrl mask. + Also, by default AD to BF has been masked to the rest of the bits... which wil be ON by default. + if mask bit is enable to particular pkt status, send it out to app else stop it. + */ + cntrl_msg_mask_bit = (usStatus & 0x1F); + //printk("\ninew msg mask bit which is disable in mask:%X", cntrl_msg_mask_bit); + if(pTarang->RxCntrlMsgBitMask & (1<AppCtrlQueueLen > MAX_APP_QUEUE_LEN) || + ((pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN/2) && (HighPriorityMessage == FALSE))) + { + /* + Assumption:- + 1. every tarang manages it own dropped pkt statitistics + 2. Total packet dropped per tarang will be equal to the sum of all types of dropped + pkt by that tarang only. + + */ + switch(*(PUSHORT)skb->data) + { + case CM_RESPONSES: + pTarang->stDroppedAppCntrlMsgs.cm_responses++; + break; + case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: + pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++; + break; + case LINK_CONTROL_RESP: + pTarang->stDroppedAppCntrlMsgs.link_control_resp++; + break; + case STATUS_RSP: + pTarang->stDroppedAppCntrlMsgs.status_rsp++; + break; + case STATS_POINTER_RESP: + pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++; + break; + case IDLE_MODE_STATUS: + pTarang->stDroppedAppCntrlMsgs.idle_mode_status++ ; + break; + case AUTH_SS_HOST_MSG: + pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++ ; + break; + default: + pTarang->stDroppedAppCntrlMsgs.low_priority_message++ ; + break; + } + + continue; + } + + newPacket = skb_clone(skb, GFP_KERNEL); + if (!newPacket) + break; + ENQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail, + newPacket); + pTarang->AppCtrlQueueLen++; + } + up(&Adapter->RxAppControlQueuelock); + wake_up(&Adapter->process_read_wait_queue); + bcm_kfree_skb(skb); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible"); +} + +/** +@ingroup ctrl_pkt_functions +Thread to handle control pkt reception +*/ +int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter object*/ + ) +{ + struct sk_buff *ctrl_packet= NULL; + unsigned long flags = 0; + //struct timeval tv ; + //int *puiBuffer = NULL ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Entering to make thread wait on control packet event!"); + while(1) + { + wait_event_interruptible(Adapter->process_rx_cntrlpkt, + atomic_read(&Adapter->cntrlpktCnt) || + Adapter->bWakeUpDevice || + kthread_should_stop() + ); + + + if(kthread_should_stop()) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Exiting \n"); + return 0; + } + if(TRUE == Adapter->bWakeUpDevice) + { + Adapter->bWakeUpDevice = FALSE; + if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && + ((TRUE == Adapter->IdleMode)|| (TRUE == Adapter->bShutStatus))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Calling InterfaceAbortIdlemode\n"); + // Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; + InterfaceIdleModeWakeup (Adapter); + } + continue; + } + + while(atomic_read(&Adapter->cntrlpktCnt)) + { + spin_lock_irqsave(&Adapter->control_queue_lock, flags); + ctrl_packet = Adapter->RxControlHead; + if(ctrl_packet) + { + DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail); +// Adapter->RxControlHead=ctrl_packet->next; + ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_packets++; + ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_bytes+= + ((PLEADER)ctrl_packet->data)->PLength; + } + #if 0 //Idle mode debug profiling... + if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS) + { + puiBuffer = (PUINT)(ctrl_packet->data +sizeof(USHORT)); + if((ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD)) + { + memset(&tv, 0, sizeof(tv)); + do_gettimeofday(&tv); + if((ntohl(*(puiBuffer+1)) == 0)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode Wake-up Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode req Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); + } + } + else if((ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "GOT IDLE_MODE_SF_UPDATE MSG at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); + } + } + #endif + + spin_unlock_irqrestore (&Adapter->control_queue_lock, flags); + handle_rx_control_packet(Adapter, ctrl_packet); + atomic_dec(&Adapter->cntrlpktCnt); + } + + SetUpTargetDsxBuffers(Adapter); + } + return STATUS_SUCCESS; +} + +INT flushAllAppQ() +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PPER_TARANG_DATA pTarang = NULL; + struct sk_buff *PacketToDrop = NULL; + for(pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) + { + while(pTarang->RxAppControlHead != NULL) + { + PacketToDrop=pTarang->RxAppControlHead; + DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail); + bcm_kfree_skb(PacketToDrop); + } + pTarang->AppCtrlQueueLen = 0; + //dropped contrl packet statistics also should be reset. + memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); + + } + return STATUS_SUCCESS ; +} + + diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h new file mode 100644 index 000000000000..f17a4f13474c --- /dev/null +++ b/drivers/staging/bcm/HostMIBSInterface.h @@ -0,0 +1,230 @@ + + +#ifndef _HOST_MIBSINTERFACE_H +#define _HOST_MIBSINTERFACE_H + +/* + * Copyright (c) 2007 Beceem Communications Pvt. Ltd + * File Name: HostMIBSInterface.h + * Abstract: This file contains DS used by the Host to update the Host + * statistics used for the MIBS. + */ + +#define MIBS_MAX_CLASSIFIERS 100 +#define MIBS_MAX_PHSRULES 100 +#define MIBS_MAX_SERVICEFLOWS 17 +#define MIBS_MAX_IP_RANGE_LENGTH 4 +#define MIBS_MAX_PORT_RANGE 4 +#define MIBS_MAX_PROTOCOL_LENGTH 32 +#define MIBS_MAX_PHS_LENGTHS 255 +#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10 +#define MIBS_IP_LENGTH_OF_ADDRESS 4 +#define MIBS_MAX_HIST_ENTRIES 12 +#define MIBS_PKTSIZEHIST_RANGE 128 + +typedef union _U_MIBS_IP_ADDRESS +{ + struct + { + //Source Ip Address Range + ULONG ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH]; + //Source Ip Mask Address Range + ULONG ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH]; + }; + struct + { + //Source Ip Address Range + ULONG ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4]; + //Source Ip Mask Address Range + ULONG ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4]; + + }; + struct + { + UCHAR ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH * + MIBS_IP_LENGTH_OF_ADDRESS]; + UCHAR ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH * + MIBS_IP_LENGTH_OF_ADDRESS]; + }; + struct + { + UCHAR ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; + UCHAR ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; + }; +}U_MIBS_IP_ADDRESS; + + +typedef struct _S_MIBS_HOST_INFO +{ + ULONG64 GoodTransmits; + ULONG64 GoodReceives; + // this to keep track of the Tx and Rx MailBox Registers. + ULONG NumDesUsed; + ULONG CurrNumFreeDesc; + ULONG PrevNumFreeDesc; + // to keep track the no of byte recieved + ULONG PrevNumRcevBytes; + ULONG CurrNumRcevBytes; + + /* QOS Related */ + ULONG BEBucketSize; + ULONG rtPSBucketSize; + ULONG LastTxQueueIndex; + BOOLEAN TxOutofDescriptors; + BOOLEAN TimerActive; + UINT32 u32TotalDSD; + UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; + UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; +}S_MIBS_HOST_INFO; + +typedef struct _S_MIBS_CLASSIFIER_RULE +{ + ULONG ulSFID; + UCHAR ucReserved[2]; + B_UINT16 uiClassifierRuleIndex; + BOOLEAN bUsed; + USHORT usVCID_Value; + // This field detemines the Classifier Priority + B_UINT8 u8ClassifierRulePriority; + U_MIBS_IP_ADDRESS stSrcIpAddress; + /*IP Source Address Length*/ + UCHAR ucIPSourceAddressLength; + + U_MIBS_IP_ADDRESS stDestIpAddress; + /* IP Destination Address Length */ + UCHAR ucIPDestinationAddressLength; + UCHAR ucIPTypeOfServiceLength;//Type of service Length + UCHAR ucTosLow;//Tos Low + UCHAR ucTosHigh;//Tos High + UCHAR ucTosMask;//Tos Mask + UCHAR ucProtocolLength;//protocol Length + UCHAR ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];//protocol Length + USHORT usSrcPortRangeLo[MIBS_MAX_PORT_RANGE]; + USHORT usSrcPortRangeHi[MIBS_MAX_PORT_RANGE]; + UCHAR ucSrcPortRangeLength; + USHORT usDestPortRangeLo[MIBS_MAX_PORT_RANGE]; + USHORT usDestPortRangeHi[MIBS_MAX_PORT_RANGE]; + UCHAR ucDestPortRangeLength; + BOOLEAN bProtocolValid; + BOOLEAN bTOSValid; + BOOLEAN bDestIpValid; + BOOLEAN bSrcIpValid; + UCHAR ucDirection; + BOOLEAN bIpv6Protocol; + UINT32 u32PHSRuleID; +}S_MIBS_CLASSIFIER_RULE; + + +typedef struct _S_MIBS_PHS_RULE +{ + ULONG ulSFID; + /// brief 8bit PHSI Of The Service Flow + B_UINT8 u8PHSI; + /// brief PHSF Of The Service Flow + B_UINT8 u8PHSFLength; + B_UINT8 u8PHSF[MIBS_MAX_PHS_LENGTHS]; + /// brief PHSM Of The Service Flow + B_UINT8 u8PHSMLength; + B_UINT8 u8PHSM[MIBS_MAX_PHS_LENGTHS]; + /// brief 8bit PHSS Of The Service Flow + B_UINT8 u8PHSS; + /// brief 8bit PHSV Of The Service Flow + B_UINT8 u8PHSV; + // Reserved bytes are 5, so that it is similar to S_PHS_RULE structure. + B_UINT8 reserved[5]; + + LONG PHSModifiedBytes; + ULONG PHSModifiedNumPackets; + ULONG PHSErrorNumPackets; +}S_MIBS_PHS_RULE; + +typedef struct _S_MIBS_EXTSERVICEFLOW_PARAMETERS +{ + UINT32 wmanIfSfid; + UINT32 wmanIfCmnCpsSfState; + UINT32 wmanIfCmnCpsMaxSustainedRate; + UINT32 wmanIfCmnCpsMaxTrafficBurst; + UINT32 wmanIfCmnCpsMinReservedRate; + UINT32 wmanIfCmnCpsToleratedJitter; + UINT32 wmanIfCmnCpsMaxLatency; + UINT32 wmanIfCmnCpsFixedVsVariableSduInd; + UINT32 wmanIfCmnCpsSduSize; + UINT32 wmanIfCmnCpsSfSchedulingType; + UINT32 wmanIfCmnCpsArqEnable; + UINT32 wmanIfCmnCpsArqWindowSize; + UINT32 wmanIfCmnCpsArqBlockLifetime; + UINT32 wmanIfCmnCpsArqSyncLossTimeout; + UINT32 wmanIfCmnCpsArqDeliverInOrder; + UINT32 wmanIfCmnCpsArqRxPurgeTimeout; + UINT32 wmanIfCmnCpsArqBlockSize; + UINT32 wmanIfCmnCpsMinRsvdTolerableRate; + UINT32 wmanIfCmnCpsReqTxPolicy; + UINT32 wmanIfCmnSfCsSpecification; + UINT32 wmanIfCmnCpsTargetSaid; + +}S_MIBS_EXTSERVICEFLOW_PARAMETERS; + + +typedef struct _S_MIBS_SERVICEFLOW_TABLE +{ + //classification extension Rule + ULONG ulSFID; + USHORT usVCID_Value; + UINT uiThreshold; + // This field determines the priority of the SF Queues + B_UINT8 u8TrafficPriority; + + BOOLEAN bValid; + BOOLEAN bActive; + BOOLEAN bActivateRequestSent; + //BE or rtPS + B_UINT8 u8QueueType; + //maximum size of the bucket for the queue + UINT uiMaxBucketSize; + UINT uiCurrentQueueDepthOnTarget; + UINT uiCurrentBytesOnHost; + UINT uiCurrentPacketsOnHost; + UINT uiDroppedCountBytes; + UINT uiDroppedCountPackets; + UINT uiSentBytes; + UINT uiSentPackets; + UINT uiCurrentDrainRate; + UINT uiThisPeriodSentBytes; + LARGE_INTEGER liDrainCalculated; + UINT uiCurrentTokenCount; + LARGE_INTEGER liLastUpdateTokenAt; + UINT uiMaxAllowedRate; + UINT NumOfPacketsSent; + UCHAR ucDirection; + USHORT usCID; + S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable; + UINT uiCurrentRxRate; + UINT uiThisPeriodRxBytes; + UINT uiTotalRxBytes; + UINT uiTotalTxBytes; +}S_MIBS_SERVICEFLOW_TABLE; + +typedef struct _S_MIBS_DROPPED_APP_CNTRL_MESSAGES +{ + ULONG cm_responses; + ULONG cm_control_newdsx_multiclassifier_resp; + ULONG link_control_resp; + ULONG status_rsp; + ULONG stats_pointer_resp; + ULONG idle_mode_status; + ULONG auth_ss_host_msg; + ULONG low_priority_message; + +}S_MIBS_DROPPED_APP_CNTRL_MESSAGES; + +typedef struct _S_MIBS_HOST_STATS_MIBS +{ + S_MIBS_HOST_INFO stHostInfo; + S_MIBS_CLASSIFIER_RULE astClassifierTable[MIBS_MAX_CLASSIFIERS]; + S_MIBS_SERVICEFLOW_TABLE astSFtable[MIBS_MAX_SERVICEFLOWS]; + S_MIBS_PHS_RULE astPhsRulesTable[MIBS_MAX_PHSRULES]; + S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs; +}S_MIBS_HOST_STATS_MIBS; +#endif + + diff --git a/drivers/staging/bcm/HostMibs.h b/drivers/staging/bcm/HostMibs.h new file mode 100644 index 000000000000..28a578311378 --- /dev/null +++ b/drivers/staging/bcm/HostMibs.h @@ -0,0 +1,7 @@ +#ifndef _HOST_MIBS_H +#define _HOST_MIBS_H + +INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, + PVOID ioBuffer, + ULONG inputBufferLength); +#endif diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c new file mode 100644 index 000000000000..cb4ca9a44c88 --- /dev/null +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -0,0 +1,400 @@ +#include "headers.h" + +UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength) +{ + UCHAR *pucRetHeaderPtr = NULL; + UCHAR *pucPayloadPtr = NULL; + USHORT usNextHeaderOffset = 0 ; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone)) + { + *bParseDone = TRUE; + return NULL; + + } + + pucRetHeaderPtr = *ppucPayload; + pucPayloadPtr = *ppucPayload; + + if(!pucRetHeaderPtr || !pucPayloadPtr) + { + *bParseDone = TRUE; + return NULL; + } + + //Get the Nextt Header Type + *bParseDone = FALSE; + + + + switch(*pucNextHeader) + { + case IPV6HDR_TYPE_HOPBYHOP: + { + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); + usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader); + } + break; + + case IPV6HDR_TYPE_ROUTING: + { + IPV6RoutingHeader *pstIpv6RoutingHeader; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); + pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr; + usNextHeaderOffset += sizeof(IPV6RoutingHeader); + usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES; + + } + break; + case IPV6HDR_TYPE_FRAGMENTATION: + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); + usNextHeaderOffset+= sizeof(IPV6FragmentHeader); + + } + break; + case IPV6HDR_TYPE_DESTOPTS: + { + IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; + int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); + usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader); + usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; + + } + break; + case IPV6HDR_TYPE_AUTHENTICATION: + { + IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; + int nHdrLen = pstIpv6AuthHdr->ucLength; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); + usNextHeaderOffset+= nHdrLen * 4; + } + break; + case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); + *bParseDone = TRUE; + + } + break; + case IPV6_ICMP_HDR_TYPE: + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); + *bParseDone = TRUE; + } + break; + case TCP_HEADER_TYPE: + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); + *bParseDone = TRUE; + } + break; + case UDP_HEADER_TYPE: + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); + *bParseDone = TRUE; + } + break; + default : + { + *bParseDone = TRUE; + + } + break; + + + } + + if(*bParseDone == FALSE) + { + if(*pusPayloadLength <= usNextHeaderOffset) + { + *bParseDone = TRUE; + } + else + { + *pucNextHeader = *pucPayloadPtr; + pucPayloadPtr+=usNextHeaderOffset; + (*pusPayloadLength)-=usNextHeaderOffset; + } + + } + + + + *ppucPayload = pucPayloadPtr; + return pucRetHeaderPtr; +} + + +UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader) +{ + UCHAR *pIpv6HdrScanContext = pucPayload; + BOOLEAN bDone = FALSE; + UCHAR ucHeaderType =0; + UCHAR *pucNextHeader = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + if( !pucPayload || (usPayloadLength == 0)) + { + return 0; + } + + *pusSrcPort = *pusDestPort = 0; + ucHeaderType = ucNextHeader; + while(!bDone) + { + pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength); + if(bDone) + { + if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) + { + *pusSrcPort=*((PUSHORT)(pucNextHeader)); + *pusDestPort=*((PUSHORT)(pucNextHeader+2)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort)); + } + break; + + } + } + return ucHeaderType; +} + + + +USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ + PVOID pcIpHeader, /**\n"); + + pstIpv6Header = (IPV6Header *)pcIpHeader; + + DumpIpv6Header(pstIpv6Header); + + //Try to get the next higher layer protocol and the Ports Nos if TCP or UDP + ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)), + &ushSrcPort, + &ushDestPort, + pstIpv6Header->usPayloadLength, + pstIpv6Header->ucNextHeader); + + do + { + if(0 == pstClassifierRule->ucDirection) + { + //cannot be processed for classification. + // it is a down link connection + break; + } + + if(!pstClassifierRule->bIpv6Protocol) + { + //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one. + break; + } + + bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header); + if(!bClassificationSucceed) + break; + + bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header); + if(!bClassificationSucceed) + break; + + //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers + bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP); + if(!bClassificationSucceed) + break; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + + if((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) + { + //Match Src Port + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort)); + bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort)); + if(!bClassificationSucceed) + break; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); + + //Match Dest Port + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); + bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); + if(!bClassificationSucceed) + break; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); + } + }while(0); + + if(TRUE==bClassificationSucceed) + { + INT iMatchedSFQueueIndex = 0; + iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); + if(iMatchedSFQueueIndex >= NO_OF_QUEUES) + { + bClassificationSucceed = FALSE; + } + else + { + if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) + { + bClassificationSucceed = FALSE; + } + } + } + + return bClassificationSucceed; +} + + +BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +{ + UINT uiLoopIndex=0; + UINT uiIpv6AddIndex=0; + UINT uiIpv6AddrNoLongWords = 4; + ULONG aulSrcIP[4]; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + /* + //This is the no. of Src Addresses ie Range of IP Addresses contained + //in the classifier rule for which we need to match + */ + UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; + + + if(0 == uiCountIPSrcAddresses) + return TRUE; + + + //First Convert the Ip Address in the packet to Host Endian order + for(uiIpv6AddIndex=0;uiIpv6AddIndexulSrcIpAddress[uiIpv6AddIndex]); + } + + for(uiLoopIndex=0;uiLoopIndexstSrcIpAddress.ulIpv6Mask[uiLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); + DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); + + for(uiIpv6AddIndex=0;uiIpv6AddIndexstSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) + != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) + { + //Match failed for current Ipv6 Address.Try next Ipv6 Address + break; + } + + if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) + { + //Match Found + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); + return TRUE; + } + } + } + return FALSE; +} + +BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +{ + UINT uiLoopIndex=0; + UINT uiIpv6AddIndex=0; + UINT uiIpv6AddrNoLongWords = 4; + ULONG aulDestIP[4]; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + /* + //This is the no. of Destination Addresses ie Range of IP Addresses contained + //in the classifier rule for which we need to match + */ + UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; + + + if(0 == uiCountIPDestinationAddresses) + return TRUE; + + + //First Convert the Ip Address in the packet to Host Endian order + for(uiIpv6AddIndex=0;uiIpv6AddIndexulDestIpAddress[uiIpv6AddIndex]); + } + + for(uiLoopIndex=0;uiLoopIndexstDestIpAddress.ulIpv6Mask[uiLoopIndex]); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n"); + DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); + + for(uiIpv6AddIndex=0;uiIpv6AddIndexstDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) + != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) + { + //Match failed for current Ipv6 Address.Try next Ipv6 Address + break; + } + + if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) + { + //Match Found + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); + return TRUE; + } + } + } + return FALSE; + +} + +VOID DumpIpv6Address(ULONG *puIpv6Address) +{ + UINT uiIpv6AddrNoLongWords = 4; + UINT uiIpv6AddIndex=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + for(uiIpv6AddIndex=0;uiIpv6AddIndexucVersionPrio & 0xf0; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion); + ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio); + //BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength)); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); + DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); + DumpIpv6Address(pstIpv6Header->ulDestIpAddress); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); + + +} diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h new file mode 100644 index 000000000000..b93f7902e283 --- /dev/null +++ b/drivers/staging/bcm/IPv6ProtocolHdr.h @@ -0,0 +1,119 @@ +#ifndef _IPV6_PROTOCOL_DEFINES_ +#define _IPV6_PROTOCOL_DEFINES_ + + +#define IPV6HDR_TYPE_HOPBYHOP 0x0 +#define IPV6HDR_TYPE_ROUTING 0x2B +#define IPV6HDR_TYPE_FRAGMENTATION 0x2C +#define IPV6HDR_TYPE_DESTOPTS 0x3c +#define IPV6HDR_TYPE_AUTHENTICATION 0x33 +#define IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD 0x34 +#define MASK_IPV6_CS_SPEC 0x2 + + +#define TCP_HEADER_TYPE 0x6 +#define UDP_HEADER_TYPE 0x11 +#define IPV6_ICMP_HDR_TYPE 0x2 +#define IPV6_FLOWLABEL_BITOFFSET 9 + +#define IPV6_MAX_CHAINEDHDR_BUFFBYTES 0x64 +/* +// Size of Dest Options field of Destinations Options Header +// in bytes. +*/ +#define IPV6_DESTOPTS_HDR_OPTIONSIZE 0x8 + +//typedef unsigned char UCHAR; +//typedef unsigned short USHORT; +//typedef unsigned long int ULONG; + +typedef struct IPV6HeaderFormatTag +{ + UCHAR ucVersionPrio; + UCHAR aucFlowLabel[3]; + USHORT usPayloadLength; + UCHAR ucNextHeader; + UCHAR ucHopLimit; + ULONG ulSrcIpAddress[4]; + ULONG ulDestIpAddress[4]; +}IPV6Header; + +typedef struct IPV6RoutingHeaderFormatTag +{ + UCHAR ucNextHeader; + UCHAR ucRoutingType; + UCHAR ucNumAddresses; + UCHAR ucNextAddress; + ULONG ulReserved; + //UCHAR aucAddressList[0]; + +}IPV6RoutingHeader; + +typedef struct IPV6FragmentHeaderFormatTag +{ + UCHAR ucNextHeader; + UCHAR ucReserved; + USHORT usFragmentOffset; + ULONG ulIdentification; +}IPV6FragmentHeader; + +typedef struct IPV6DestOptionsHeaderFormatTag +{ + UCHAR ucNextHeader; + UCHAR ucHdrExtLen; + UCHAR ucDestOptions[6]; + //UCHAR udExtDestOptions[0]; +}IPV6DestOptionsHeader; + +typedef struct IPV6HopByHopOptionsHeaderFormatTag +{ + UCHAR ucNextHeader; + UCHAR ucMisc[3]; + ULONG ulJumboPayloadLen; +}IPV6HopByHopOptionsHeader; + +typedef struct IPV6AuthenticationHeaderFormatTag +{ + UCHAR ucNextHeader; + UCHAR ucLength; + USHORT usReserved; + ULONG ulSecurityParametersIndex; + //UCHAR ucAuthenticationData[0]; + +}IPV6AuthenticationHeader; + +typedef struct IPV6IcmpHeaderFormatTag +{ + UCHAR ucType; + UCHAR ucCode; + USHORT usChecksum; + //UCHAR ucIcmpMsg[0]; + +}IPV6IcmpHeader; + +typedef enum _E_IPADDR_CONTEXT +{ + eSrcIpAddress, + eDestIpAddress + +}E_IPADDR_CONTEXT; + + + +//Function Prototypes +BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); +BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); + +USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ + PVOID pcIpHeader, /**psAdapter; + + buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); + if(!buff) + { + return -ENOMEM; + } + while(1) + { + oldfs=get_fs(); set_fs(get_ds()); + len=vfs_read(flp, buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); + set_fs(oldfs); + if(len<=0) + { + if(len<0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); + errno=len; + } + else + { + errno = 0; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); + } + break; + } + //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB); + errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len) ; + if(errno) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno); + break; + + } + on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; + }/* End of for(;;)*/ + + bcm_kfree(buff); + return errno; +} + +int InterfaceFileReadbackFromChip( PVOID arg, + struct file *flp, + unsigned int on_chip_loc) +{ + char *buff=NULL, *buff_readback=NULL; + unsigned int reg=0; + mm_segment_t oldfs={0}; + int errno=0, len=0, is_config_file = 0; + loff_t pos=0; + static int fw_down = 0; + INT Status = STATUS_SUCCESS; + PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; + + buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); + buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); + if(!buff || !buff_readback) + { + bcm_kfree(buff); + bcm_kfree(buff_readback); + + return -ENOMEM; + } + + is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR)? 1:0; + + memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB); + memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB); + while(1) + { + oldfs=get_fs(); set_fs(get_ds()); + len=vfs_read(flp, buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); + set_fs(oldfs); + fw_down++; + if(len<=0) + { + if(len<0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); + errno=len; + } + else + { + errno = 0; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); + } + break; + } + + + Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len); + if(Status) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg); + goto exit; + } + reg++; + if((len-sizeof(unsigned int))<4) + { + if(memcmp(buff_readback, buff, len)) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL,"Length is: %d",len); + Status = -EIO; + goto exit; + } + } + else + { + len-=4; + while(len) + { + if(*(unsigned int*)&buff_readback[len] != *(unsigned int *)&buff[len]) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); + Status = -EIO; + goto exit; + } + len-=4; + } + } + on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; + }/* End of while(1)*/ +exit: + bcm_kfree(buff); + bcm_kfree(buff_readback); + return Status; +} + +static int bcm_download_config_file(PMINI_ADAPTER Adapter, + FIRMWARE_INFO *psFwInfo) +{ + int retval = STATUS_SUCCESS; + B_UINT32 value = 0; + + if(Adapter->pstargetparams == NULL) + { + if((Adapter->pstargetparams = + kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL) + { + return -ENOMEM; + } + } + if(psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS)) + { + return -EIO; + } + retval = copy_from_user(Adapter->pstargetparams, + psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); + if(retval) + { + bcm_kfree (Adapter->pstargetparams); + Adapter->pstargetparams = NULL; + return retval; + } + /* Parse the structure and then Download the Firmware */ + beceem_parse_target_struct(Adapter); + + //Initializing the NVM. + BcmInitNVM(Adapter); + + retval = InitLedSettings (Adapter); + + if(retval) + { + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n"); + return retval; + } + + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->LEDInfo.bLedInitDone = FALSE; + Adapter->DriverState = DRIVER_INIT; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = FW_DOWNLOAD; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + + /* Initialize the DDR Controller */ + retval = ddr_init(Adapter); + if(retval) + { + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n"); + return retval; + } + + value = 0; + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); + + if(Adapter->eNVMType == NVM_FLASH) + { + retval = PropagateCalParamsFromFlashToMemory(Adapter); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"propagaion of cal param failed with status :%d", retval); + return retval; + } + } + + + retval =buffDnldVerify(Adapter,(PUCHAR)Adapter->pstargetparams,sizeof(STARGETPARAMS),CONFIG_BEGIN_ADDR); + + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly"); + } + else + Adapter->bCfgDownloaded = TRUE; + + + return retval; +} +#if 0 +static int bcm_download_buffer(PMINI_ADAPTER Adapter, + unsigned char *mappedbuffer, unsigned int u32FirmwareLength, + unsigned long u32StartingAddress) +{ + char *buff=NULL; + unsigned int len = 0; + int retval = STATUS_SUCCESS; + buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); + + len = u32FirmwareLength; + + while(u32FirmwareLength) + { + len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); + if(STATUS_SUCCESS != (retval = copy_from_user(buff, + (unsigned char *)mappedbuffer, len))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n"); + break; + } + retval = wrm (Adapter, u32StartingAddress, buff, len); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n"); + break; + } + u32StartingAddress += len; + u32FirmwareLength -= len; + mappedbuffer +=len; + } + bcm_kfree(buff); + return retval; +} +#endif +static int bcm_compare_buff_contents(unsigned char *readbackbuff, + unsigned char *buff,unsigned int len) +{ + int retval = STATUS_SUCCESS; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if((len-sizeof(unsigned int))<4) + { + if(memcmp(readbackbuff , buff, len)) + { + retval=-EINVAL; + } + } + else + { + len-=4; + while(len) + { + if(*(unsigned int*)&readbackbuff[len] != + *(unsigned int *)&buff[len]) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); + retval=-EINVAL; + break; + } + len-=4; + } + } + return retval; +} +#if 0 +static int bcm_buffer_readback(PMINI_ADAPTER Adapter, + unsigned char *mappedbuffer, unsigned int u32FirmwareLength, + unsigned long u32StartingAddress) +{ + unsigned char *buff = NULL; + unsigned char *readbackbuff = NULL; + unsigned int len = u32FirmwareLength; + int retval = STATUS_SUCCESS; + + buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); + if(NULL == buff) + return -ENOMEM; + readbackbuff = (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, + GFP_KERNEL); + if(NULL == readbackbuff) + { + bcm_kfree(buff); + return -ENOMEM; + } + while (u32FirmwareLength && !retval) + { + len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); + + /* read from the appl buff and then read from the target, compare */ + if(STATUS_SUCCESS != (retval = copy_from_user(buff, + (unsigned char *)mappedbuffer, len))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n"); + break; + } + retval = rdm (Adapter, u32StartingAddress, readbackbuff, len); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n"); + break; + } + + if (STATUS_SUCCESS != + (retval = bcm_compare_buff_contents (readbackbuff, buff, len))) + { + break; + } + u32StartingAddress += len; + u32FirmwareLength -= len; + mappedbuffer +=len; + }/* end of while (u32FirmwareLength && !retval) */ + bcm_kfree(buff); + bcm_kfree(readbackbuff); + return retval; +} +#endif +int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) +{ + int retval = STATUS_SUCCESS; + PUCHAR buff = NULL; + + /* Config File is needed for the Driver to download the Config file and + Firmware. Check for the Config file to be first to be sent from the + Application + */ + atomic_set (&Adapter->uiMBupdate, FALSE); + if(!Adapter->bCfgDownloaded && + psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) + { + /*Can't Download Firmware.*/ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n"); + return -EINVAL; + } + + /* If Config File, Finish the DDR Settings and then Download CFG File */ + if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) + { + retval = bcm_download_config_file (Adapter, psFwInfo); + } + else + { + + buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL); + if(buff==NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory"); + return -ENOMEM; + } + retval = copy_from_user(buff,(PUCHAR)psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); + if(retval != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); + goto error ; + } + + #if 0 + retval = bcm_download_buffer(Adapter, + (unsigned char *)psFwInfo->pvMappedFirmwareAddress, + psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); + if(retval != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails...."); + } + retval = bcm_buffer_readback (Adapter, + (unsigned char *)psFwInfo->pvMappedFirmwareAddress, + psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); + + if(retval != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ...."); + } + #endif + retval = buffDnldVerify(Adapter, + buff, + psFwInfo->u32FirmwareLength, + psFwInfo->u32StartingAddress); + if(retval != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval); + goto error; + } + } +error: + bcm_kfree(buff); + return retval; +} + +static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, + ULONG u32StartingAddress) +{ + + unsigned int len = 0; + int retval = STATUS_SUCCESS; + len = u32FirmwareLength; + + while(u32FirmwareLength) + { + len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); + retval = wrm (Adapter, u32StartingAddress, mappedbuffer, len); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval); + break; + } + u32StartingAddress += len; + u32FirmwareLength -= len; + mappedbuffer +=len; + } + return retval; + +} + +static INT buffRdbkVerify(PMINI_ADAPTER Adapter, + PUCHAR mappedbuffer, UINT u32FirmwareLength, + ULONG u32StartingAddress) +{ + PUCHAR readbackbuff = NULL; + UINT len = u32FirmwareLength; + INT retval = STATUS_SUCCESS; + + readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL); + if(NULL == readbackbuff) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); + return -ENOMEM; + } + while (u32FirmwareLength && !retval) + { + + len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); + + retval = rdm (Adapter, u32StartingAddress, readbackbuff, len); + if(retval) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d" ,retval); + break; + } + + if (STATUS_SUCCESS != (retval = bcm_compare_buff_contents (readbackbuff, mappedbuffer, len))) + { + break; + } + u32StartingAddress += len; + u32FirmwareLength -= len; + mappedbuffer +=len; + }/* end of while (u32FirmwareLength && !retval) */ + bcm_kfree(readbackbuff); + return retval; +} + +INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, + unsigned long u32StartingAddress) +{ + INT status = STATUS_SUCCESS; + + status = buffDnld(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress); + if(status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer download failed"); + goto error; + } + + status= buffRdbkVerify(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress); + if(status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer readback verifier failed"); + goto error; + } +error: + return status; +} + +#endif + diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c new file mode 100644 index 000000000000..d99fc7c31a11 --- /dev/null +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -0,0 +1,318 @@ +#include "headers.h" + +/* +Function: InterfaceIdleModeWakeup + +Description: This is the hardware specific Function for waking up HW device from Idle mode. + A software abort pattern is written to the device to wake it and necessary power state + transitions from host are performed here. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + +Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful. + Other - If an error occured. +*/ + + +/* +Function: InterfaceIdleModeRespond + +Description: This is the hardware specific Function for responding to Idle mode request from target. + Necessary power state transitions from host for idle mode or other device specific + initializations are performed here. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + +Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful. + Other - If an error occured. +*/ + +/* +"dmem bfc02f00 100" tells how many time device went in Idle mode. +this value will be at address bfc02fa4.just before value d0ea1dle. + +Set time value by writing at bfc02f98 7d0 + +checking the Ack timer expire on kannon by running command +d qcslog .. if it shows e means host has not send response to f/w with in 200 ms. Response should be +send to f/w with in 200 ms after the Idle/Shutdown req issued + +*/ + + +int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter,int* puiBuffer) +{ + int status = STATUS_SUCCESS; + unsigned int uiRegRead = 0; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"SubType of Message :0x%X", ntohl(*puiBuffer)); + + if(ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL," Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype"); + if(ntohl(*(puiBuffer+1)) == 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Got IDLE MODE WAKE UP Response From F/W"); + + status = wrmalt (Adapter,SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg"); + return status; + } + + if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) + { + uiRegRead = 0x00000000 ; + status = wrmalt (Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg"); + return status; + } + } + //Below Register should not br read in case of Manual and Protocol Idle mode. + else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) + { + //clear on read Register + status = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0"); + return status; + } + //clear on read Register + status = rdmalt (Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg1"); + return status; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode"); + + // Set Idle Mode Flag to False and Clear IdleMode reg. + Adapter->IdleMode = FALSE; + Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; + + wake_up(&Adapter->lowpower_mode_wait_queue); + #if 0 + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"LED Thread is Running. Hence Setting the LED Event as IDLEMODE_EXIT"); + Adapter->DriverState = IDLEMODE_EXIT; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + #endif + + } + else + { + if(TRUE == Adapter->IdleMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Device is already in Idle mode...."); + return status ; + } + + uiRegRead = 0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n"); + + if (Adapter->chip_id== BCS220_2 || + Adapter->chip_id == BCS220_2BC || + Adapter->chip_id== BCS250_BC || + Adapter->chip_id== BCS220_3) + { + + status = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n"); + return status; + } + + + uiRegRead |= (1<<17); + + status = wrmalt (Adapter,HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n"); + return status; + } + + } + SendIdleModeResponse(Adapter); + } + } + else if(ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params"); + OverrideServiceFlowParams(Adapter,puiBuffer); + } + return status; +} + + +VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter) +{ +/* BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e); + BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e); + BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea); + BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);*/ + return; +} + +int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern) +{ + int status = STATUS_SUCCESS; + unsigned int value; + unsigned int chip_id ; + unsigned long timeout = 0 ,itr = 0; + + int lenwritten = 0; + unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter; + + //Abort Bus suspend if its already suspended + if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend)) + { + status = usb_autopm_get_interface(psInterfaceAdapter->interface); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Bus got wakeup..Aborting Idle mode... status:%d \n",status); + + } + + if((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) + || + (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) + { + //write the SW abort pattern. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern); + status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to Register SW_ABORT_IDLEMODE_LOC failed.."); + return status; + } + } + + if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) + { + value = 0x80000000; + status = wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed"); + return status; + } + } + else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) + { + /* + * Get a Interrupt Out URB and send 8 Bytes Down + * To be Done in Thread Context. + * Not using Asynchronous Mechanism. + */ + status = usb_interrupt_msg (psInterfaceAdapter->udev, + usb_sndintpipe(psInterfaceAdapter->udev, + psInterfaceAdapter->sIntrOut.int_out_endpointAddr), + aucAbortPattern, + 8, + &lenwritten, + 5000); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n",status); + return status; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten); + } + + //mdelay(25); + + timeout= jiffies + msecs_to_jiffies(50) ; + while( timeout > jiffies ) + { + itr++ ; + rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT)); + if(0xbece3200==(chip_id&~(0xF0))) + { + chip_id = chip_id&~(0xF0); + } + if(chip_id == Adapter->chip_id) + break; + } + if(timeout < jiffies ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Not able to read chip-id even after 25 msec"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Number of completed iteration to read chip-id :%lu", itr); + } + + status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status)); + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to Register SW_ABORT_IDLEMODE_LOC failed.."); + return status; + } + } + return status; +} +int InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter) +{ + ULONG Status = 0; + if(Adapter->bTriedToWakeUpFromlowPowerMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Writing Low Power Mode Abort pattern to the Device\n"); + Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; + InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern); + + } + return Status; +} + +void InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter) +{ + unsigned int uiRegVal = 0; + INT Status = 0; + if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) + { + // clear idlemode interrupt. + uiRegVal = 0; + Status =wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status); + return; + } + } + + else + { + + //clear Interrupt EP registers. + Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status); + return; + } + + Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status); + return; + } + } +} + diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h new file mode 100644 index 000000000000..f87c132989f9 --- /dev/null +++ b/drivers/staging/bcm/InterfaceIdleMode.h @@ -0,0 +1,16 @@ +#ifndef _INTERFACE_IDLEMODE_H +#define _INTERFACE_IDLEMODE_H + +INT InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter); + +INT InterfaceIdleModeRespond(PMINI_ADAPTER Adapter,PINT puiBuffer); + +VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter); + +INT InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern); + +INT InterfaceWakeUp(PMINI_ADAPTER Adapter); + +VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter); +#endif + diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c new file mode 100644 index 000000000000..e06f168a52bd --- /dev/null +++ b/drivers/staging/bcm/InterfaceInit.c @@ -0,0 +1,868 @@ +#include "headers.h" + +static struct usb_device_id InterfaceUsbtable[] = { + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, + {} +}; + +VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + INT i = 0; + // Wake up the wait_queue... + if(psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + psIntfAdapter->psAdapter->DriverState = DRIVER_HALT; + wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event); + } + reset_card_proc(psIntfAdapter->psAdapter); + + //worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms + //to accertain the device is not being accessed. After this No RDM/WRM should be made. + while(psIntfAdapter->psAdapter->DeviceAccess) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Device is being Accessed \n"); + msleep(100); + } + /* Free interrupt URB */ + //psIntfAdapter->psAdapter->device_removed = TRUE; + if(psIntfAdapter->psInterruptUrb) + { + usb_free_urb(psIntfAdapter->psInterruptUrb); + } + + /* Free transmit URBs */ + for(i = 0; i < MAXIMUM_USB_TCB; i++) + { + if(psIntfAdapter->asUsbTcb[i].urb != NULL) + { + usb_free_urb(psIntfAdapter->asUsbTcb[i].urb); + psIntfAdapter->asUsbTcb[i].urb = NULL; + } + } + /* Free receive URB and buffers */ + for(i = 0; i < MAXIMUM_USB_RCB; i++) + { + if (psIntfAdapter->asUsbRcb[i].urb != NULL) + { + bcm_kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); + usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); + psIntfAdapter->asUsbRcb[i].urb = NULL; + } + } + AdapterFree(psIntfAdapter->psAdapter); +} + + + +static int usbbcm_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int usbbcm_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static ssize_t usbbcm_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + return 0; +} + +static ssize_t usbbcm_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) +{ + return 0; +} + + +VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) +{ + ULONG ulReg = 0; + +// Program EP2 MAX_PKT_SIZE + ulReg = ntohl(EP2_MPS_REG); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x128,4,TRUE); + ulReg = ntohl(EP2_MPS); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x12C,4,TRUE); + + ulReg = ntohl(EP2_CFG_REG); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x132,4,TRUE); + if(((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) + { + ulReg = ntohl(EP2_CFG_INT); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); + } + else + { +// USE BULK EP as TX in FS mode. + ulReg = ntohl(EP2_CFG_BULK); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); + } + + +// Program EP4 MAX_PKT_SIZE. + ulReg = ntohl(EP4_MPS_REG); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x13C,4,TRUE); + ulReg = ntohl(EP4_MPS); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x140,4,TRUE); + +// Program TX EP as interrupt (Alternate Setting) + if( rdmalt(Adapter,0x0F0110F8, (PUINT)&ulReg,4)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing"); + return ; + } + ulReg |= 0x6; + + ulReg = ntohl(ulReg); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1CC,4,TRUE); + + ulReg = ntohl(EP4_CFG_REG); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C8,4,TRUE); +// Program ISOCHRONOUS EP size to zero. + ulReg = ntohl(ISO_MPS_REG); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D2,4,TRUE); + ulReg = ntohl(ISO_MPS); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D6,4,TRUE); + +// Update EEPROM Version. +// Read 4 bytes from 508 and modify 511 and 510. +// + ReadBeceemEEPROM(Adapter,0x1FC,(PUINT)&ulReg); + ulReg &= 0x0101FFFF; + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1FC,4,TRUE); +// +//Update length field if required. Also make the string NULL terminated. +// + ReadBeceemEEPROM(Adapter,0xA8,(PUINT)&ulReg); + if((ulReg&0x00FF0000)>>16 > 0x30) + { + ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0xA8,4,TRUE); + } + ReadBeceemEEPROM(Adapter,0x148,(PUINT)&ulReg); + if((ulReg&0x00FF0000)>>16 > 0x30) + { + ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x148,4,TRUE); + } + ulReg = 0; + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x122,4,TRUE); + ulReg = 0; + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C2,4,TRUE); + +} + +static struct file_operations usbbcm_fops = { + .open = usbbcm_open, + .release = usbbcm_release, + .read = usbbcm_read, + .write = usbbcm_write, + .owner = THIS_MODULE, +}; + +static struct usb_class_driver usbbcm_class = { + .name = "usbbcm", + .fops = &usbbcm_fops, + .minor_base = BCM_USB_MINOR_BASE, +}; + +static int +usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + int retval =0 ; + PMINI_ADAPTER psAdapter = NULL; + PS_INTERFACE_ADAPTER psIntfAdapter = NULL; + struct usb_device *udev = NULL; + +// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!"); + if((intf == NULL) || (id == NULL)) + { + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL"); + return -EINVAL; + } + + /* Allocate Adapter structure */ + if((psAdapter = kmalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL) + { + //BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); + return -ENOMEM; + } + + memset(psAdapter, 0, sizeof(MINI_ADAPTER)); + + /* Init default driver debug state */ + + psAdapter->stDebugState.debug_level = DBG_LVL_CURR; + psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; + memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype)); + + /* Technically, one can start using BCM_DEBUG_PRINT after this point. + * However, realize that by default the Type/Subtype bitmaps are all zero now; + * so no prints will actually appear until the TestApp turns on debug paths via + * the ioctl(); so practically speaking, in early init, no logging happens. + * + * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT + * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug + * during early init. + * Further, we turn this OFF once init_module() completes. + */ + + psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; + BCM_SHOW_DEBUG_BITMAP(psAdapter); + + retval = InitAdapter(psAdapter); + if(retval) + { + BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n"); + AdapterFree(psAdapter); + return retval; + } + + /* Allocate interface adapter structure */ + if((psAdapter->pvInterfaceAdapter = + kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); + AdapterFree (psAdapter); + return -ENOMEM; + } + memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER)); + + psIntfAdapter = InterfaceAdapterGet(psAdapter); + psIntfAdapter->psAdapter = psAdapter; + + /* Store usb interface in Interface Adapter */ + psIntfAdapter->interface = intf; + usb_set_intfdata(intf, psIntfAdapter); + + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); + retval = InterfaceAdapterInit(psIntfAdapter); + if(retval) + { + /* If the Firmware/Cfg File is not present + * then return success, let the application + * download the files. + */ + if(-ENOENT == retval){ + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); + return STATUS_SUCCESS; + } + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); + usb_set_intfdata(intf, NULL); + udev = interface_to_usbdev (intf); + usb_put_dev(udev); + if(psAdapter->bUsbClassDriverRegistered == TRUE) + usb_deregister_dev (intf, &usbbcm_class); + InterfaceAdapterFree(psIntfAdapter); + return retval ; + } + if(psAdapter->chip_id > T3) + { + uint32_t uiNackZeroLengthInt=4; + if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) + { + return -EIO;; + } + } + + udev = interface_to_usbdev (intf); + /* Check whether the USB-Device Supports remote Wake-Up */ + if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) + { + /* If Suspend then only support dynamic suspend */ + if(psAdapter->bDoSuspend) + { + udev->autosuspend_delay = 0; + intf->needs_remote_wakeup = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) + udev->autosuspend_disabled = 0; +#else + usb_enable_autosuspend(udev); +#endif + device_init_wakeup(&intf->dev,1); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) + usb_autopm_disable(intf); +#endif + INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); + } + else + { + intf->needs_remote_wakeup = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) + udev->autosuspend_disabled = 1; +#else + usb_disable_autosuspend(udev); +#endif + } + } + + psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; + return retval; +} + +static void usbbcm_disconnect (struct usb_interface *intf) +{ + PS_INTERFACE_ADAPTER psIntfAdapter = NULL; + PMINI_ADAPTER psAdapter = NULL; + struct usb_device *udev = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected"); + if(intf == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL"); + return; + } + psIntfAdapter = usb_get_intfdata(intf); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); + if(psIntfAdapter == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL"); + return; + } + psAdapter = psIntfAdapter->psAdapter; + if(psAdapter->bDoSuspend) + intf->needs_remote_wakeup = 0; + + psAdapter->device_removed = TRUE ; + usb_set_intfdata(intf, NULL); + InterfaceAdapterFree(psIntfAdapter); + udev = interface_to_usbdev (intf); + usb_put_dev(udev); + usb_deregister_dev (intf, &usbbcm_class); +} + + +static __inline int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + int i = 0; + for(i = 0; i < MAXIMUM_USB_TCB; i++) + { + if((psIntfAdapter->asUsbTcb[i].urb = + usb_alloc_urb(0, GFP_KERNEL)) == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); + return -ENOMEM; + } + } + + for(i = 0; i < MAXIMUM_USB_RCB; i++) + { + if ((psIntfAdapter->asUsbRcb[i].urb = + usb_alloc_urb(0, GFP_KERNEL)) == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); + return -ENOMEM; + } + if((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = + kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); + return -ENOMEM; + } + psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE; + } + return 0; +} + + + +static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + INT value = 0; + UINT status = STATUS_SUCCESS; + + status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); + if(status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n"); + return status; + } + if(TRUE == psIntfAdapter->psAdapter->fw_download_done) + { + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......"); + if(StartInterruptUrb(psIntfAdapter)) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); + } + //now register the cntrl interface. + //after downloading the f/w waiting for 5 sec to get the mailbox interrupt. + + psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE; + value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue, + psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); + + if(value == 0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver.."); + } + else + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n "); + } + if(register_control_device_interface(psIntfAdapter->psAdapter) < 0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed..."); + return -EIO; + } + } + return 0; +} + +#if 0 +static void print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface); +} +static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor *usb_ep_desc) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** ENDPOINT DESCRIPTOR *********************"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength :%x ", usb_ep_desc->bLength); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType :%x ", usb_ep_desc->bDescriptorType); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bEndpointAddress :%x ", usb_ep_desc->bEndpointAddress); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bmAttributes :%x ", usb_ep_desc->bmAttributes); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "wMaxPacketSize :%x ",usb_ep_desc->wMaxPacketSize); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterval :%x ",usb_ep_desc->bInterval); +} + +#endif + +static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) +{ + return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +} + +static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor *epd) +{ + return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; +} + +static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); +} + +static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); +} + +static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK); +} + +static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL); +} + +static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT); +} + +static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC); +} + +static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd)); +} + +static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd)); +} + +static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd)); +} + +static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd)); +} + +static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd)); +} + +static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) +{ + return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); +} + +INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t buffer_size; + ULONG value; + INT retval = 0; + INT usedIntOutForBulkTransfer = 0 ; + BOOLEAN bBcm16 = FALSE; + UINT uiData = 0; + + if(psIntfAdapter == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface Adapter is NULL"); + return -EINVAL; + } + /* Store the usb dev into interface adapter */ + psIntfAdapter->udev = usb_get_dev(interface_to_usbdev( + psIntfAdapter->interface)); + + if((psIntfAdapter->udev->speed == USB_SPEED_HIGH)) + { + psIntfAdapter->bHighSpeedDevice = TRUE ; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO HIGH_SPEED "); + } + else + { + psIntfAdapter->bHighSpeedDevice = FALSE ; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO FULL_SPEED "); + } + + psIntfAdapter->psAdapter->interface_rdm = BcmRDM; + psIntfAdapter->psAdapter->interface_wrm = BcmWRM; + + if(rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); + return STATUS_FAILURE; + } + if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0))) + { + psIntfAdapter->psAdapter->chip_id=(psIntfAdapter->psAdapter->chip_id&~(0xF0)); + } + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "First RDM Chip ID 0x%lx\n", psIntfAdapter->psAdapter->chip_id); + + iface_desc = psIntfAdapter->interface->cur_altsetting; + //print_usb_interface_desc(&(iface_desc->desc)); + + if(psIntfAdapter->psAdapter->chip_id == T3B) + { + + // + //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not. + // + BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4); + if(uiData == BECM) + { + bBcm16 = TRUE; + } + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Number of Altsetting aviailable for This Modem 0x%x\n", psIntfAdapter->interface->num_altsetting); + if(bBcm16 == TRUE) + { + //selecting alternate setting one as a default setting for High Speed modem. + if(psIntfAdapter->bHighSpeedDevice) + retval= usb_set_interface(psIntfAdapter->udev,DEFAULT_SETTING_0,ALTERNATE_SETTING_1); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle"); + if(retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) + { + usedIntOutForBulkTransfer = EP2 ; + endpoint = &iface_desc->endpoint[EP2].desc; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n"); + /* + If Modem is high speed device EP2 should be INT OUT End point + If Mode is FS then EP2 should be bulk end point + */ + if(((psIntfAdapter->bHighSpeedDevice ==TRUE ) && (bcm_usb_endpoint_is_int_out(endpoint)== FALSE)) + ||((psIntfAdapter->bHighSpeedDevice == FALSE)&& (bcm_usb_endpoint_is_bulk_out(endpoint)== FALSE))) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Configuring the EEPROM "); + //change the EP2, EP4 to INT OUT end point + ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); + + /* + It resets the device and if any thing gets changed in USB descriptor it will show fail and + re-enumerate the device + */ + retval = usb_reset_device(psIntfAdapter->udev); + if(retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + return retval ; + } + + } + if((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) + { + // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. + UINT uiData = ntohl(EP2_CFG_INT); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Reverting Bulk to INT as it is FS MODE"); + BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter,(PUCHAR)&uiData,0x136,4,TRUE); + } + } + else + { + usedIntOutForBulkTransfer = EP4 ; + endpoint = &iface_desc->endpoint[EP4].desc; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting"); + if( bcm_usb_endpoint_is_int_out(endpoint) == FALSE) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix"); + //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting + ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); + + /* + It resets the device and if any thing gets changed in USB descriptor it will show fail and + re-enumerate the device + */ + retval = usb_reset_device(psIntfAdapter->udev); + if(retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + return retval ; + } + + } + } + } + } + + iface_desc = psIntfAdapter->interface->cur_altsetting; + //print_usb_interface_desc(&(iface_desc->desc)); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Current number of endpoints :%x \n", iface_desc->desc.bNumEndpoints); + for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) + { + endpoint = &iface_desc->endpoint[value].desc; + //print_usb_endpoint_descriptor(endpoint); + + if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) + { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; + psIntfAdapter->sBulkIn.bulk_in_endpointAddr = + endpoint->bEndpointAddress; + psIntfAdapter->sBulkIn.bulk_in_pipe = + usb_rcvbulkpipe(psIntfAdapter->udev, + psIntfAdapter->sBulkIn.bulk_in_endpointAddr); + } + + if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) + { + + psIntfAdapter->sBulkOut.bulk_out_endpointAddr = + endpoint->bEndpointAddress; + psIntfAdapter->sBulkOut.bulk_out_pipe = + usb_sndbulkpipe(psIntfAdapter->udev, + psIntfAdapter->sBulkOut.bulk_out_endpointAddr); + } + + if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) + { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sIntrIn.int_in_size = buffer_size; + psIntfAdapter->sIntrIn.int_in_endpointAddr = + endpoint->bEndpointAddress; + psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval; + psIntfAdapter->sIntrIn.int_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!psIntfAdapter->sIntrIn.int_in_buffer) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_in_buffer"); + return -EINVAL; + } + //psIntfAdapter->sIntrIn.int_in_pipe = + } + + if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) + { + + if( !psIntfAdapter->sBulkOut.bulk_out_endpointAddr && + (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) + { + //use first intout end point as a bulk out end point + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sBulkOut.bulk_out_size = buffer_size; + //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1); + psIntfAdapter->sBulkOut.bulk_out_endpointAddr = + endpoint->bEndpointAddress; + psIntfAdapter->sBulkOut.bulk_out_pipe = + usb_sndintpipe(psIntfAdapter->udev, + psIntfAdapter->sBulkOut.bulk_out_endpointAddr); + psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval; + + } + else if(value == EP6) + { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sIntrOut.int_out_size = buffer_size; + psIntfAdapter->sIntrOut.int_out_endpointAddr = + endpoint->bEndpointAddress; + psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; + psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, + GFP_KERNEL); + if (!psIntfAdapter->sIntrOut.int_out_buffer) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_out_buffer"); + return -EINVAL; + } + } + } + } + usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); + retval = usb_register_dev(psIntfAdapter->interface, &usbbcm_class); + if(retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb register dev failed = %d", retval); + psIntfAdapter->psAdapter->bUsbClassDriverRegistered = FALSE; + return retval; + } + else + { + psIntfAdapter->psAdapter->bUsbClassDriverRegistered = TRUE; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb dev registered"); + } + + psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload; + psIntfAdapter->psAdapter->bcm_file_readback_from_chip = + InterfaceFileReadbackFromChip; + psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket; + + retval = CreateInterruptUrb(psIntfAdapter); + + if(retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb"); + return retval; + } + + retval = AllocUsbCb(psIntfAdapter); + if(retval) + { + return retval; + } + + + retval = device_run(psIntfAdapter); + if(retval) + { + return retval; + } + + + return 0; +} +int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) +{ + PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n"); + //Bcm_kill_all_URBs(psIntfAdapter); + psIntfAdapter->bSuspended = TRUE; + + if(TRUE == psIntfAdapter->bPreparingForBusSuspend) + { + psIntfAdapter->bPreparingForBusSuspend = FALSE; + + if(psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) + { + psIntfAdapter->psAdapter->IdleMode = TRUE ; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); + } + else + { + psIntfAdapter->psAdapter->bShutStatus = TRUE; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); + } + } + psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE; + + //Signaling the control pkt path + wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); + + return 0; +} +int InterfaceResume (struct usb_interface *intf) +{ + PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + printk("=================================\n"); + mdelay(100); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) + intf->pm_usage_cnt =1 ; +#endif + psIntfAdapter->bSuspended = FALSE; + + StartInterruptUrb(psIntfAdapter); + InterfaceRx(psIntfAdapter); + return 0; +} +int InterfacePreReset(struct usb_interface *intf) +{ + printk("====================>"); + return STATUS_SUCCESS; +} +int InterfacePostReset(struct usb_interface *intf) +{ + printk("Do Post chip reset setting here if it is required"); + return STATUS_SUCCESS; +} +static struct usb_driver usbbcm_driver = { + .name = "usbbcm", + .probe = usbbcm_device_probe, + .disconnect = usbbcm_disconnect, + .suspend = InterfaceSuspend, + .resume = InterfaceResume, + .pre_reset=InterfacePreReset, + .post_reset=InterfacePostReset, + .id_table = InterfaceUsbtable, + .supports_autosuspend = 1, +}; + + +/* +Function: InterfaceInitialize + +Description: This is the hardware specific initialization Function. + Registering the driver with NDIS , other device specific NDIS + and hardware initializations are done here. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + +Return: BCM_STATUS_SUCCESS - If Initialization of the + HW Interface was successful. + Other - If an error occured. +*/ +INT InterfaceInitialize(void) +{ +// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!"); + return usb_register(&usbbcm_driver); +} + +INT InterfaceExit(void) +{ + //PMINI_ADAPTER psAdapter = NULL; + int status = 0; + + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!"); + usb_deregister(&usbbcm_driver); + return status; +} +MODULE_LICENSE ("GPL"); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h new file mode 100644 index 000000000000..e7a96e5c5c50 --- /dev/null +++ b/drivers/staging/bcm/InterfaceInit.h @@ -0,0 +1,51 @@ +#ifndef _INTERFACE_INIT_H +#define _INTERFACE_INIT_H + +#define BCM_USB_VENDOR_ID_T3 0x198f +#define BCM_USB_VENDOR_ID_FOXCONN 0x0489 +#define BCM_USB_VENDOR_ID_ZTE 0x19d2 + +#define BCM_USB_PRODUCT_ID_T3 0x0300 +#define BCM_USB_PRODUCT_ID_T3B 0x0210 +#define BCM_USB_PRODUCT_ID_T3L 0x0220 +#define BCM_USB_PRODUCT_ID_SYM 0x15E +#define BCM_USB_PRODUCT_ID_1901 0xe017 +#define BCM_USB_PRODUCT_ID_226 0x0132 + +#define BCM_USB_MINOR_BASE 192 + + +INT InterfaceInitialize(void); + +INT InterfaceExit(void); + +#ifndef BCM_SHM_INTERFACE +INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); + +INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); + +VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter); + +#else +INT InterfaceAdapterInit(PMINI_ADAPTER Adapter); +#endif + + +#if 0 + +ULONG InterfaceClaimAdapter(PMINI_ADAPTER Adapter); + +VOID InterfaceDDRControllerInit(PMINI_ADAPTER Adapter); + +ULONG InterfaceReset(PMINI_ADAPTER Adapter); + +ULONG InterfaceRegisterResources(PMINI_ADAPTER Adapter); + +VOID InterfaceUnRegisterResources(PMINI_ADAPTER Adapter); + +ULONG InterfaceFirmwareDownload(PMINI_ADAPTER Adapter); + +#endif + +#endif + diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c new file mode 100644 index 000000000000..f928fe4d564d --- /dev/null +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -0,0 +1,203 @@ +#include "headers.h" + +#ifndef BCM_SHM_INTERFACE + +static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) +{ + int status = urb->status; + PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; + PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ; + + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed."); + return ; + } + + if(((Adapter->bPreparingForLowPowerMode == TRUE) && (Adapter->bDoSuspend == TRUE)) || + psIntfAdapter->bSuspended || + psIntfAdapter->bPreparingForBusSuspend) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt call back is called while suspending the device"); + return ; + } + + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "interrupt urb status %d", status); + switch (status) { + /* success */ + case STATUS_SUCCESS: + if ( urb->actual_length ) + { + + if(psIntfAdapter->ulInterruptData[1] & 0xFF) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Got USIM interrupt"); + } + + if(psIntfAdapter->ulInterruptData[1] & 0xFF00) + { + atomic_set(&Adapter->CurrNumFreeTxDesc, + (psIntfAdapter->ulInterruptData[1] & 0xFF00) >> 8); + atomic_set (&Adapter->uiMBupdate, TRUE); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "TX mailbox contains %d", + atomic_read(&Adapter->CurrNumFreeTxDesc)); + } + if(psIntfAdapter->ulInterruptData[1] >> 16) + { + Adapter->CurrNumRecvDescs= + (psIntfAdapter->ulInterruptData[1] >> 16); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"RX mailbox contains %d", + Adapter->CurrNumRecvDescs); + InterfaceRx(psIntfAdapter); + } + if(Adapter->fw_download_done && + !Adapter->downloadDDR && + atomic_read(&Adapter->CurrNumFreeTxDesc)) + { + psIntfAdapter->psAdapter->downloadDDR +=1; + wake_up(&Adapter->tx_packet_wait_queue); + } + if(FALSE == Adapter->waiting_to_fw_download_done) + { + Adapter->waiting_to_fw_download_done = TRUE; + wake_up(&Adapter->ioctl_fw_dnld_wait_queue); + } + if(!atomic_read(&Adapter->TxPktAvail)) + { + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Firing interrupt in URB"); + } + break; + case -ENOENT : + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"URB has got disconnected ...."); + return ; + } + case -EINPROGRESS: + { + //This situation may happend when URBunlink is used. for detail check usb_unlink_urb documentation. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occured... something very bad is going on"); + break ; + //return; + } + case -EPIPE: + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint has got halted/stalled...need to clear this"); + Adapter->bEndPointHalted = TRUE ; + wake_up(&Adapter->tx_packet_wait_queue); + urb->status = STATUS_SUCCESS ;; + return; + } + /* software-driven interface shutdown */ + case -ECONNRESET: //URB got unlinked. + case -ESHUTDOWN: // hardware gone. this is the serious problem. + //Occurs only when something happens with the host controller device + case -ENODEV : //Device got removed + case -EINVAL : //Some thing very bad happened with the URB. No description is available. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"interrupt urb error %d", status); + urb->status = STATUS_SUCCESS ; + break ; + //return; + default: + //This is required to check what is the defaults conditions when it occurs.. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", status); + break; + } + + StartInterruptUrb(psIntfAdapter); + + +} + +int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); + if (!psIntfAdapter->psInterruptUrb) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot allocate interrupt urb"); + return -ENOMEM; + } + psIntfAdapter->psInterruptUrb->transfer_buffer = + psIntfAdapter->ulInterruptData; + psIntfAdapter->psInterruptUrb->transfer_buffer_length = + sizeof(psIntfAdapter->ulInterruptData); + + psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev, + psIntfAdapter->sIntrIn.int_in_endpointAddr); + + usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev, + psIntfAdapter->sIntrIn.int_in_pipe, + psIntfAdapter->psInterruptUrb->transfer_buffer, + psIntfAdapter->psInterruptUrb->transfer_buffer_length, + read_int_callback, psIntfAdapter, + psIntfAdapter->sIntrIn.int_in_interval); + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt Interval: %d\n", + psIntfAdapter->sIntrIn.int_in_interval); + return 0; +} + + +INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + INT status = 0; + + if( FALSE == psIntfAdapter->psAdapter->device_removed && + FALSE == psIntfAdapter->psAdapter->bEndPointHalted && + FALSE == psIntfAdapter->bSuspended && + FALSE == psIntfAdapter->bPreparingForBusSuspend && + FALSE == psIntfAdapter->psAdapter->StopAllXaction) + { + status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC); + if (status) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot send int urb %d\n", status); + if(status == -EPIPE) + { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); + } + } + } + return status; +} + +/* +Function: InterfaceEnableInterrupt + +Description: This is the hardware specific Function for configuring + and enabling the interrupts on the device. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + +Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful. + Other - If an error occured. +*/ + +void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter) +{ + +} + +/* +Function: InterfaceDisableInterrupt + +Description: This is the hardware specific Function for disabling the interrupts on the device. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + +Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful. + Other - If an error occured. +*/ + +void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter) +{ + +} + +#endif + diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h new file mode 100644 index 000000000000..6065a7141bca --- /dev/null +++ b/drivers/staging/bcm/InterfaceIsr.h @@ -0,0 +1,15 @@ +#ifndef _INTERFACE_ISR_H +#define _INTERFACE_ISR_H + +int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); + + +INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); + + +VOID InterfaceEnableInterrupt(PMINI_ADAPTER Adapter); + +VOID InterfaceDisableInterrupt(PMINI_ADAPTER Adapter); + +#endif + diff --git a/drivers/staging/bcm/InterfaceMacros.h b/drivers/staging/bcm/InterfaceMacros.h new file mode 100644 index 000000000000..7001caff9e26 --- /dev/null +++ b/drivers/staging/bcm/InterfaceMacros.h @@ -0,0 +1,18 @@ +#ifndef _INTERFACE_MACROS_H +#define _INTERFACE_MACROS_H + +#define BCM_USB_MAX_READ_LENGTH 2048 + +#define MAXIMUM_USB_TCB 128 +#define MAXIMUM_USB_RCB 128 + +#define MAX_BUFFERS_PER_QUEUE 256 + +#define MAX_DATA_BUFFER_SIZE 2048 + +//Num of Asynchronous reads pending +#define NUM_RX_DESC 64 + +#define SYS_CFG 0x0F000C00 + +#endif diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c new file mode 100644 index 000000000000..8fc893b37fe4 --- /dev/null +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -0,0 +1,290 @@ +#include "headers.h" + +#ifndef BCM_SHM_INTERFACE + +PS_INTERFACE_ADAPTER +InterfaceAdapterGet(PMINI_ADAPTER psAdapter) +{ + if(psAdapter == NULL) + { + return NULL; + } + return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter); +} + +INT +InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, + UINT addr, + PVOID buff, + INT len) +{ + int retval = 0; + USHORT usRetries = 0 ; + if(psIntfAdapter == NULL ) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL"); + return -EINVAL ; + } + + if(psIntfAdapter->psAdapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed"); + return -ENODEV; + } + + if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus"); + return -EACCES; + } + + if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed.."); + return -EACCES; + } + psIntfAdapter->psAdapter->DeviceAccess = TRUE ; + do { + retval = usb_control_msg(psIntfAdapter->udev, + usb_rcvctrlpipe(psIntfAdapter->udev,0), + 0x02, + 0xC2, + (addr & 0xFFFF), + ((addr >> 16) & 0xFFFF), + buff, + len, + 5000); + + usRetries++ ; + if(-ENODEV == retval) + { + psIntfAdapter->psAdapter->device_removed =TRUE; + break; + } + + }while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) ); + + if(retval < 0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries); + psIntfAdapter->psAdapter->DeviceAccess = FALSE ; + return retval; + } + else + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval); + psIntfAdapter->psAdapter->DeviceAccess = FALSE ; + return STATUS_SUCCESS; + } +} + +INT +InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, + UINT addr, + PVOID buff, + INT len) +{ + int retval = 0; + USHORT usRetries = 0 ; + + if(psIntfAdapter == NULL ) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); + return -EINVAL; + } + if(psIntfAdapter->psAdapter->device_removed == TRUE) + { + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed"); + return -ENODEV; + } + + if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus..."); + return EACCES; + } + + if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed.."); + return -EACCES; + } + psIntfAdapter->psAdapter->DeviceAccess = TRUE ; + do{ + retval = usb_control_msg(psIntfAdapter->udev, + usb_sndctrlpipe(psIntfAdapter->udev,0), + 0x01, + 0x42, + (addr & 0xFFFF), + ((addr >> 16) & 0xFFFF), + buff, + len, + 5000); + + usRetries++ ; + if(-ENODEV == retval) + { + psIntfAdapter->psAdapter->device_removed = TRUE ; + break; + } + + }while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES)); + + if(retval < 0) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries); + psIntfAdapter->psAdapter->DeviceAccess = FALSE ; + return retval; + } + else + { + psIntfAdapter->psAdapter->DeviceAccess = FALSE ; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval); + return STATUS_SUCCESS; + + } + +} + +INT +BcmRDM(PVOID arg, + UINT addr, + PVOID buff, + INT len) +{ + return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); +} + +INT +BcmWRM(PVOID arg, + UINT addr, + PVOID buff, + INT len) +{ + return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); +} + + + +INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter) +{ + PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); + INT status = STATUS_SUCCESS ; + + /* + usb_clear_halt - tells device to clear endpoint halt/stall condition + @dev: device whose endpoint is halted + @pipe: endpoint "pipe" being cleared + @ Context: !in_interrupt () + + usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code. + This is used to clear halt conditions for bulk and interrupt endpoints only. + Control and isochronous endpoints never halts. + + Any URBs queued for such an endpoint should normally be unlinked by the driver + before clearing the halt condition. + + */ + + //Killing all the submitted urbs to different end points. + Bcm_kill_all_URBs(psIntfAdapter); + + + //clear the halted/stalled state for every end point + status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe); + if(status != STATUS_SUCCESS) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status); + + status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe); + if(status != STATUS_SUCCESS) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status); + + status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe); + if(status != STATUS_SUCCESS) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status); + + return status ; +} + + +VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + struct urb *tempUrb = NULL; + UINT i; + + /** + * usb_kill_urb - cancel a transfer request and wait for it to finish + * @urb: pointer to URB describing a previously submitted request, + * returns nothing as it is void returned API. + * + * This routine cancels an in-progress request. It is guaranteed that + * upon return all completion handlers will have finished and the URB + * will be totally idle and available for reuse + + * This routine may not be used in an interrupt context (such as a bottom + * half or a completion handler), or when holding a spinlock, or in other + * situations where the caller can't schedule(). + * + **/ + + /* Cancel submitted Interrupt-URB's */ + if(psIntfAdapter->psInterruptUrb != NULL) + { + if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) + usb_kill_urb(psIntfAdapter->psInterruptUrb); + } + + /* Cancel All submitted TX URB's */ + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n"); + + for(i = 0; i < MAXIMUM_USB_TCB; i++) + { + tempUrb = psIntfAdapter->asUsbTcb[i].urb; + if(tempUrb) + { + if(tempUrb->status == -EINPROGRESS) + usb_kill_urb(tempUrb); + } + } + + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n"); + + for(i = 0; i < MAXIMUM_USB_RCB; i++) + { + tempUrb = psIntfAdapter->asUsbRcb[i].urb; + if(tempUrb) + { + if(tempUrb->status == -EINPROGRESS) + usb_kill_urb(tempUrb); + } + } + + + atomic_set(&psIntfAdapter->uNumTcbUsed, 0); + atomic_set(&psIntfAdapter->uCurrTcb, 0); + + atomic_set(&psIntfAdapter->uNumRcbUsed, 0); + atomic_set(&psIntfAdapter->uCurrRcb, 0); + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb)); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb)); + +} + +VOID putUsbSuspend(struct work_struct *work) +{ + PS_INTERFACE_ADAPTER psIntfAdapter = NULL ; + struct usb_interface *intf = NULL ; + psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork); + intf=psIntfAdapter->interface ; + + if(psIntfAdapter->bSuspended == FALSE) + usb_autopm_put_interface(intf); + else + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n"); + +} + +#endif diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h new file mode 100644 index 000000000000..74c81d45cff4 --- /dev/null +++ b/drivers/staging/bcm/InterfaceMisc.h @@ -0,0 +1,45 @@ +#ifndef __INTERFACE_MISC_H +#define __INTERFACE_MISC_H + +PS_INTERFACE_ADAPTER +InterfaceAdapterGet(PMINI_ADAPTER psAdapter); + +INT +InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, + UINT addr, + PVOID buff, + INT len); + +INT +InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, + UINT addr, + PVOID buff, + INT len); + + +int InterfaceFileDownload( PVOID psIntfAdapter, + struct file *flp, + unsigned int on_chip_loc); + +int InterfaceFileReadbackFromChip( PVOID psIntfAdapter, + struct file *flp, + unsigned int on_chip_loc); + + +int BcmRDM(PVOID arg, + UINT addr, + PVOID buff, + INT len); + +int BcmWRM(PVOID arg, + UINT addr, + PVOID buff, + INT len); + +INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter); + +VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter); + +#define DISABLE_USB_ZERO_LEN_INT 0x0F011878 + +#endif // __INTERFACE_MISC_H diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c new file mode 100644 index 000000000000..6fee9684f2ef --- /dev/null +++ b/drivers/staging/bcm/InterfaceRx.c @@ -0,0 +1,256 @@ +#include "headers.h" +extern int SearchVcid(PMINI_ADAPTER , unsigned short); + + +static PUSB_RCB +GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + PUSB_RCB pRcb = NULL; + UINT index = 0; + + if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && + (psIntfAdapter->psAdapter->StopAllXaction == FALSE)) + { + index = atomic_read(&psIntfAdapter->uCurrRcb); + pRcb = &psIntfAdapter->asUsbRcb[index]; + pRcb->bUsed = TRUE; + pRcb->psIntfAdapter= psIntfAdapter; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d", + index, atomic_read(&psIntfAdapter->uNumRcbUsed)); + index = (index + 1) % MAXIMUM_USB_RCB; + atomic_set(&psIntfAdapter->uCurrRcb, index); + atomic_inc(&psIntfAdapter->uNumRcbUsed); + } + return pRcb; +} + +/*this is receive call back - when pkt avilable for receive (BULK IN- end point)*/ +static void read_bulk_callback(struct urb *urb) +{ + struct sk_buff *skb = NULL; + BOOLEAN bHeaderSupressionEnabled = FALSE; + int QueueIndex = NO_OF_QUEUES + 1; + UINT uiIndex=0; + int process_done = 1; + //int idleflag = 0 ; + PUSB_RCB pRcb = (PUSB_RCB)urb->context; + PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter; + PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; + PLEADER pLeader = urb->transfer_buffer; + + + #if 0 + int *puiBuffer = NULL; + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + do_gettimeofday(&tv); + #endif + + if((Adapter->device_removed == TRUE) || + (TRUE == Adapter->bEndPointHalted) || + (0 == urb->actual_length) + ) + { + pRcb->bUsed = FALSE; + atomic_dec(&psIntfAdapter->uNumRcbUsed); + return; + } + + if(urb->status != STATUS_SUCCESS) + { + if(urb->status == -EPIPE) + { + Adapter->bEndPointHalted = TRUE ; + wake_up(&Adapter->tx_packet_wait_queue); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status); + } + pRcb->bUsed = FALSE; + atomic_dec(&psIntfAdapter->uNumRcbUsed); + urb->status = STATUS_SUCCESS ; + return ; + } + + if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"device is going in low power mode while PMU option selected..hence rx packet should not be process"); + return ; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength); + if(!pLeader->PLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0"); + atomic_dec(&psIntfAdapter->uNumRcbUsed); + return; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid); + if(MAX_CNTL_PKT_SIZE < pLeader->PLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n", + pLeader->PLength); + atomic_inc(&Adapter->RxPacketDroppedCount); + atomic_add(pLeader->PLength, &Adapter->BadRxByteCount); + atomic_dec(&psIntfAdapter->uNumRcbUsed); + return; + } + + QueueIndex = SearchVcid( Adapter,pLeader->Vcid); + if(QueueIndex < NO_OF_QUEUES) + { + bHeaderSupressionEnabled = + Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; + bHeaderSupressionEnabled = + bHeaderSupressionEnabled & Adapter->bPHSEnabled; + } + + skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment + if(!skb) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet"); + atomic_dec(&psIntfAdapter->uNumRcbUsed); + return; + } + /* If it is a control Packet, then call handle_bcm_packet ()*/ + if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || + (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Recived control pkt..."); + *(PUSHORT)skb->data = pLeader->Status; + memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + + (sizeof(LEADER)), pLeader->PLength); + skb->len = pLeader->PLength + sizeof(USHORT); + + spin_lock(&Adapter->control_queue_lock); + ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb); + spin_unlock(&Adapter->control_queue_lock); + + atomic_inc(&Adapter->cntrlpktCnt); + wake_up(&Adapter->process_rx_cntrlpkt); + } + else + { + /* + * Data Packet, Format a proper Ethernet Header + * and give it to the stack + */ + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt..."); + skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); + memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength); + skb->dev = Adapter->dev; + + /* currently skb->len has extra ETH_HLEN bytes in the beginning */ + skb_put (skb, pLeader->PLength + ETH_HLEN); + Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength; + Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength; + atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength); + + if(Adapter->if_up) + { + /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ + skb_pull(skb, ETH_HLEN); + PHSRecieve(Adapter, pLeader->Vcid, skb, &skb->len, + NULL,bHeaderSupressionEnabled); + + if(!Adapter->PackInfo[QueueIndex].bEthCSSupport) + { + skb_push(skb, ETH_HLEN); + + memcpy(skb->data, skb->dev->dev_addr, 6); + memcpy(skb->data+6, skb->dev->dev_addr, 6); + (*(skb->data+11))++; + *(skb->data+12) = 0x08; + *(skb->data+13) = 0x00; + pLeader->PLength+=ETH_HLEN; + } + + skb->protocol = eth_type_trans(skb, Adapter->dev); + process_done = netif_rx(skb); + } + else + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); + bcm_kfree_skb(skb); + } + atomic_inc(&Adapter->GoodRxPktCount); + for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) + { + if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) + && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) + Adapter->aRxPktSizeHist[uiIndex]++; + } + } + Adapter->PrevNumRecvDescs++; + pRcb->bUsed = FALSE; + atomic_dec(&psIntfAdapter->uNumRcbUsed); +} + +static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb) +{ + struct urb *urb = pRcb->urb; + int retval = 0; + + usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe( + psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr), + urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback, + pRcb); + if(FALSE == psIntfAdapter->psAdapter->device_removed && + FALSE == psIntfAdapter->psAdapter->bEndPointHalted && + FALSE == psIntfAdapter->bSuspended && + FALSE == psIntfAdapter->bPreparingForBusSuspend) + { + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval); + //if this return value is because of pipe halt. need to clear this. + if(retval == -EPIPE) + { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); + } + + } + } + return retval; +} + +/* +Function: InterfaceRx + +Description: This is the hardware specific Function for Recieveing + data packet/control packets from the device. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + + + +Return: TRUE - If Rx was successful. + Other - If an error occured. +*/ + +BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter) +{ + USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed); + PUSB_RCB pRcb = NULL; + +// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs - +// psIntfAdapter->psAdapter->PrevNumRecvDescs; + while(RxDescCount) + { + pRcb = GetBulkInRcb(psIntfAdapter); + if(pRcb == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer"); + return FALSE; + } + //atomic_inc(&psIntfAdapter->uNumRcbUsed); + ReceiveRcb(psIntfAdapter, pRcb); + RxDescCount--; + } + return TRUE; +} + diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h new file mode 100644 index 000000000000..96e81a1d37b8 --- /dev/null +++ b/drivers/staging/bcm/InterfaceRx.h @@ -0,0 +1,7 @@ +#ifndef _INTERFACE_RX_H +#define _INTERFACE_RX_H + +BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter); + +#endif + diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c new file mode 100644 index 000000000000..771f7b34d2ec --- /dev/null +++ b/drivers/staging/bcm/InterfaceTx.c @@ -0,0 +1,259 @@ +#include "headers.h" + +#ifndef BCM_SHM_INTERFACE + +/* +Function: InterfaceTxDataPacket + +Description: This is the hardware specific Function for Transmitting + data packet to the device. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + PVOID Packet - Packet Containing the data to be transmitted + USHORT usVcid - VCID on which data packet is to be sent + + +Return: BCM_STATUS_SUCCESS - If Tx was successful. + Other - If an error occured. +*/ + +ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid) +{ + ULONG Status = 0; + return Status; +} + +/* +Function: InterfaceTxControlPacket + +Description: This is the hardware specific Function for Transmitting + control packet to the device. + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + PVOID pvBuffer - Buffer containg control packet + UINT uiBufferLength - Buffer Length + +Return: BCM_STATUS_SUCCESS - If control packet transmit was successful. + Other - If an error occured. +*/ + +ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength) +{ + ULONG Status = 0; + + + + return Status; +} +/*this is transmit call-back(BULK OUT)*/ +static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) +{ + PUSB_TCB pTcb= (PUSB_TCB)urb->context; + PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; + CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; + PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; + BOOLEAN bpowerDownMsg = FALSE ; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); +#if 0 + struct timeval tv; + UINT time_ms = 0; +#endif + if(urb->status != STATUS_SUCCESS) + { + if(urb->status == -EPIPE) + { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); + } + } + + pTcb->bUsed = FALSE; + atomic_dec(&psIntfAdapter->uNumTcbUsed); + + + + if(TRUE == psAdapter->bPreparingForLowPowerMode) + { + #if 0 + do_gettimeofday(&tv); + time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); + #endif + + if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && + (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) + + { + bpowerDownMsg = TRUE ; + //This covers the bus err while Idle Request msg sent down. + if(urb->status != STATUS_SUCCESS) + { + psAdapter->bPreparingForLowPowerMode = FALSE ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); + //Signalling the cntrl pkt path in Ioctl + wake_up(&psAdapter->lowpower_mode_wait_queue); + StartInterruptUrb(psIntfAdapter); + goto err_exit; + } + + if(psAdapter->bDoSuspend == FALSE) + { + psAdapter->IdleMode = TRUE; + //since going in Idle mode completed hence making this var false; + psAdapter->bPreparingForLowPowerMode = FALSE ; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); + //Signalling the cntrl pkt path in Ioctl + wake_up(&psAdapter->lowpower_mode_wait_queue); + } + + } + else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && + (pControlMsg->szData[0] == LINK_UP_ACK) && + (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && + (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) + { + //This covers the bus err while shutdown Request msg sent down. + if(urb->status != STATUS_SUCCESS) + { + psAdapter->bPreparingForLowPowerMode = FALSE ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); + //Signalling the cntrl pkt path in Ioctl + wake_up(&psAdapter->lowpower_mode_wait_queue); + StartInterruptUrb(psIntfAdapter); + goto err_exit; + } + + bpowerDownMsg = TRUE ; + if(psAdapter->bDoSuspend == FALSE) + { + psAdapter->bShutStatus = TRUE; + //since going in shutdown mode completed hence making this var false; + psAdapter->bPreparingForLowPowerMode = FALSE ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); + //Signalling the cntrl pkt path in Ioctl + wake_up(&psAdapter->lowpower_mode_wait_queue); + } + } + + if(psAdapter->bDoSuspend && bpowerDownMsg) + { + //issuing bus suspend request + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); + psIntfAdapter->bPreparingForBusSuspend = TRUE; + schedule_work(&psIntfAdapter->usbSuspendWork); + + } + + } + +err_exit : +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) + usb_buffer_free(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); +#else + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); +#endif +} + + +static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter) +{ + PUSB_TCB pTcb = NULL; + UINT index = 0; + + if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && + (psIntfAdapter->psAdapter->StopAllXaction ==FALSE)) + { + index = atomic_read(&psIntfAdapter->uCurrTcb); + pTcb = &psIntfAdapter->asUsbTcb[index]; + pTcb->bUsed = TRUE; + pTcb->psIntfAdapter= psIntfAdapter; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d", + index, atomic_read(&psIntfAdapter->uNumTcbUsed)); + index = (index + 1) % MAXIMUM_USB_TCB; + atomic_set(&psIntfAdapter->uCurrTcb, index); + atomic_inc(&psIntfAdapter->uNumTcbUsed); + } + return pTcb; +} + +static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) +{ + + struct urb *urb = pTcb->urb; + int retval = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) + urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len, + GFP_ATOMIC, &urb->transfer_dma); +#else + urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, + GFP_ATOMIC, &urb->transfer_dma); +#endif + + if (!urb->transfer_buffer) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); + return -ENOMEM; + } + memcpy(urb->transfer_buffer, data, len); + urb->transfer_buffer_length = len; + + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); + //For T3B,INT OUT end point will be used as bulk out end point + if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) + { + usb_fill_int_urb(urb, psIntfAdapter->udev, + psIntfAdapter->sBulkOut.bulk_out_pipe, + urb->transfer_buffer, len, write_bulk_callback, pTcb, + psIntfAdapter->sBulkOut.int_out_interval); + } + else + { + usb_fill_bulk_urb(urb, psIntfAdapter->udev, + psIntfAdapter->sBulkOut.bulk_out_pipe, + urb->transfer_buffer, len, write_bulk_callback, pTcb); + } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ + + if(FALSE == psIntfAdapter->psAdapter->device_removed && + FALSE == psIntfAdapter->psAdapter->bEndPointHalted && + FALSE == psIntfAdapter->bSuspended && + FALSE == psIntfAdapter->bPreparingForBusSuspend) + { + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); + if(retval == -EPIPE) + { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); + } + } + } + return retval; +} + +int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) +{ + PUSB_TCB pTcb= NULL; + + PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; + pTcb= GetBulkOutTcb(psIntfAdapter); + if(pTcb == NULL) + { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet"); + return -EFAULT; + } + return TransmitTcb(psIntfAdapter, pTcb, data, len); +} + +#endif + diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h new file mode 100644 index 000000000000..053f631e2042 --- /dev/null +++ b/drivers/staging/bcm/InterfaceTx.h @@ -0,0 +1,13 @@ +#ifndef _INTERFACE_TX_H +#define _INTERFACE_TX_H + +INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len); + + +ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid); + +ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength); + + +#endif + diff --git a/drivers/staging/bcm/Interfacemain.h b/drivers/staging/bcm/Interfacemain.h new file mode 100644 index 000000000000..e0db563c5e0f --- /dev/null +++ b/drivers/staging/bcm/Interfacemain.h @@ -0,0 +1,10 @@ +#ifndef _MAIN_ +#define _MAIN_ +#if 0 +typedef struct _MINI_ADAPTER +{ + S_INTERFACE_ADAPTER stInterfaceAdapter; +}MINI_ADAPTER,*PMINI_ADAPTER; + +#endif +#endif diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h new file mode 100644 index 000000000000..2651fc2432ce --- /dev/null +++ b/drivers/staging/bcm/Ioctl.h @@ -0,0 +1,360 @@ +#ifndef _IOCTL_H_ +#define _IOCTL_H_ + +typedef struct rdmbuffer +{ + ULONG Register; + ULONG Length; +}__attribute__((packed)) RDM_BUFFER, *PRDM_BUFFER; + + +typedef struct wrmbuffer +{ + ULONG Register; + ULONG Length; + UCHAR Data[4]; +}__attribute__((packed)) WRM_BUFFER, *PWRM_BUFFER; + + +typedef struct ioctlbuffer +{ + PVOID InputBuffer; + ULONG InputLength; + PVOID OutputBuffer; + ULONG OutputLength; +}__attribute__((packed)) IOCTL_BUFFER, *PIOCTL_BUFFER; + +typedef struct stGPIOInfo +{ + UINT uiGpioNumber ; /* valid numbers 0-15 */ + UINT uiGpioValue; /* 1 set ; 0 not set */ +}__attribute__((packed))GPIO_INFO,*PGPIO_INFO; +typedef struct stUserThreadReq +{ + //0->Inactivate LED thread. + //1->Activate the LED thread + UINT ThreadState; +}__attribute__((packed))USER_THREAD_REQ,*PUSER_THREAD_REQ; +#define LED_THREAD_ACTIVATION_REQ 1 + + +////********** ioctl codes ***********//// + +#define BCM_IOCTL 'k' + +//1.Control code for CONTROL MESSAGES + +#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801,int) + +//2.Control code to write a particular value to a particular register +#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) // + +//3. +#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) // + +//4.Control code to write x number of bytes to common memory +//starting from address y +#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)// + +//5.Control code to write x number of bytes to common memory +//starting from address y +#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)// + +//6.Control code for CONTROL MESSAGES +#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)// + +//7.Control code for FIRMWARE DOWNLOAD +#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)// + +#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int) + +//9.Control code for TRANSFER MODE SWITCHING +#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int) +//10.Control code for LINK UP +#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int) + +//11.Control code for RSSI Level Request +#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int) +//12.Control code for IDLE MODE CONTROL +#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int) +//13.Control code for SS/BS info +#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int) + +#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int) + +#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int) + +#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int) + +#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int) + +#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int) + +#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char) + +#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814) + +#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815) + +#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, IOCTL_BUFFER) + +#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816) + +#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char) + +#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817,char) + +#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long) + +#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long) + +#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long) + +#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821) + +#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int) + +#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int) + +#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int) + +#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int) + +#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int) + +#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int) + +#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int) + +#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int) + +#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int) + +#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char) + +#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char) + +#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, IOCTL_BUFFER) + +#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int) + +#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int) + +#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int) + +#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int) + +#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int) + +#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int) + +#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int) + +#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int) + +#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int) + +#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int) + +#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int) + +#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int) + +#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL,0x867, int) + +#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL,0x868, int) + +#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL,0x869) + +#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870,int) + +#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int) + +#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int) + +#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int) + +#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int) + +#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int) + +#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int) + +#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int) + +#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, IOCTL_BUFFER) +#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, IOCTL_BUFFER) + + + +typedef enum _BCM_INTERFACE_TYPE +{ + BCM_MII, + BCM_CARDBUS, + BCM_USB, + BCM_SDIO, + BCM_PCMCIA +}BCM_INTERFACE_TYPE; + +typedef struct _DEVICE_DRIVER_INFO +{ + NVM_TYPE u32NVMType; + UINT MaxRDMBufferSize; + BCM_INTERFACE_TYPE u32InterfaceType; + UINT u32DSDStartOffset; + UINT u32RxAlignmentCorrection; + UINT u32Reserved[10]; +} DEVICE_DRIVER_INFO; + +typedef struct _NVM_READWRITE +{ + + void *pBuffer; +// Data to be written from|read to. Memory should be allocated by the caller. + + uint32_t uiOffset; +// offset at which data should be written to or read from. + + uint32_t uiNumBytes; +// No. of bytes to be written or read. + + bool bVerify; +// Applicable only for write. If set verification of written data will be done. + +} NVM_READWRITE,*PNVM_READWRITE; +typedef struct bulkwrmbuffer +{ + ULONG Register; + ULONG SwapEndian; + ULONG Values[1]; + +}BULKWRM_BUFFER,*PBULKWRM_BUFFER; + + +/***********Structure used for FlashMap2.x *******************************/ + +/* +* These are Sction present inside the Flash. +* There is sectional RD/WR for flash Map 2.x. +* hence these section will be used in read/write API. +*/ + +typedef enum _FLASH2X_SECTION_VAL +{ + NO_SECTION_VAL = 0, //no section is choosen when absolute offset is given for RD/WR + ISO_IMAGE1, + ISO_IMAGE2, + DSD0, + DSD1, + DSD2, + VSA0, + VSA1, + VSA2, + SCSI, + CONTROL_SECTION, + ISO_IMAGE1_PART2, + ISO_IMAGE1_PART3, + ISO_IMAGE2_PART2, + ISO_IMAGE2_PART3, + TOTAL_SECTIONS +}FLASH2X_SECTION_VAL; + +/* +* Structure used for READ/WRITE Flash Map2.x +*/ +typedef struct _FLASH2X_READWRITE +{ + + FLASH2X_SECTION_VAL Section; //which section has to be read/written + B_UINT32 offset; //Offset within Section. + B_UINT32 numOfBytes; //NOB from the offset + B_UINT32 bVerify; + PVOID pDataBuff; //Buffer for reading/writing + +}FLASH2X_READWRITE, *PFLASH2X_READWRITE; +/* +* This structure is used for coping one section to other. +* there are two ways to copy one section to other. +* it NOB =0, complete section will be copied on to other. +* if NOB !=0, only NOB will be copied from the given offset. +*/ + +typedef struct _FLASH2X_COPY_SECTION +{ + //Src Section from which Data has to be copied to DstSection + FLASH2X_SECTION_VAL SrcSection; + + //Destination Section from where Data has to be coppied. + FLASH2X_SECTION_VAL DstSection; + + //Offset within Section. if NOB =0 it will be ignored and data will be coped from offset 0. + B_UINT32 offset; + + //NOB from the offset. if NOB = 0 complete src section will be copied to Destination section. + B_UINT32 numOfBytes; +} FLASH2X_COPY_SECTION, *PFLASH2X_COPY_SECTION; + + +typedef enum _SECTION_TYPE +{ + ISO = 0, + VSA = 1, + DSD = 2 +} SECTION_TYPE, *PSECTION_TYPE; + +/* +* This section provide the complete bitmap of the Flash. +* using this map lib/APP will isssue read/write command. + Fields are defined as : + Bit [0] = section is present //1:present, 0: Not present +* Bit [1] = section is valid //1: valid, 0: not valid +* Bit [2] = Section is R/W //0: RW, 1: RO +* Bit [3] = Section is Active or not 1 means Active, 0->inactive +* Bit [7...3] = Reserved +*/ + +typedef struct _FLASH2X_BITMAP +{ + UCHAR ISO_IMAGE1; + UCHAR ISO_IMAGE2; + UCHAR DSD0; + UCHAR DSD1; + UCHAR DSD2; + UCHAR VSA0; + UCHAR VSA1; + UCHAR VSA2; + UCHAR SCSI; + UCHAR CONTROL_SECTION; + //Reserved for future use + UCHAR Reserved0; + UCHAR Reserved1; + UCHAR Reserved2; +}FLASH2X_BITMAP, *PFLASH2X_BITMAP; + +//for net entry time check +typedef struct _ST_TIME_ELAPSED_ +{ + ULONG64 ul64TimeElapsedSinceNetEntry; + UINT32 uiReserved[4]; //By chance if required for future proofing +}ST_TIME_ELAPSED,*PST_TIME_ELAPSED; + +enum { + WIMAX_IDX=0, /*To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/ + HOST_IDX, /*To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/ + MAX_IDX +}; +typedef struct stGPIOMultiInfo +{ + UINT uiGPIOCommand; /* 1 for set and 0 for get*/ + UINT uiGPIOMask; /* set the correspondig bit to 1 to access GPIO*/ + UINT uiGPIOValue; /* 0 or 1; value to be set when command is 1.*/ +}__attribute__((packed))GPIO_MULTI_INFO , *PGPIO_MULTI_INFO; + +typedef struct stGPIOMultiMode +{ + UINT uiGPIOMode; /* 1 for OUT mode, 0 for IN mode*/ + UINT uiGPIOMask; /* GPIO mask to set mode*/ +}__attribute__((packed))GPIO_MULTI_MODE, *PGPIO_MULTI_MODE; + + +#endif diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig new file mode 100644 index 000000000000..96adb1026c4f --- /dev/null +++ b/drivers/staging/bcm/Kconfig @@ -0,0 +1,7 @@ +config BCM_WIMAX + tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support" + depends on USB && NET && EXPERIMENTAL + default N + help + This is an experimental driver for the Beceem WIMAX chipset used + by Sprint 4G. diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c new file mode 100644 index 000000000000..1875c8289010 --- /dev/null +++ b/drivers/staging/bcm/LeakyBucket.c @@ -0,0 +1,399 @@ +/********************************************************************** +* LEAKYBUCKET.C +* This file contains the routines related to Leaky Bucket Algorithm. +***********************************************************************/ +#include "headers.h" + +/********************************************************************* +* Function - UpdateTokenCount() +* +* Description - This function calculates the token count for each +* channel and updates the same in Adapter strucuture. +* +* Parameters - Adapter: Pointer to the Adapter structure. +* +* Returns - None +**********************************************************************/ + +VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) +{ + ULONG liCurrentTime; + INT i = 0; + struct timeval tv; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n"); + if(NULL == Adapter) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n"); + return; + } + + do_gettimeofday(&tv); + for(i = 0; i < NO_OF_QUEUES; i++) + { + if(TRUE == Adapter->PackInfo[i].bValid && + (1 == Adapter->PackInfo[i].ucDirection)) + { + liCurrentTime = ((tv.tv_sec- + Adapter->PackInfo[i].stLastUpdateTokenAt.tv_sec)*1000 + + (tv.tv_usec-Adapter->PackInfo[i].stLastUpdateTokenAt.tv_usec)/ + 1000); + if(0!=liCurrentTime) + { + Adapter->PackInfo[i].uiCurrentTokenCount += (ULONG) + ((Adapter->PackInfo[i].uiMaxAllowedRate) * + ((ULONG)((liCurrentTime)))/1000); + memcpy(&Adapter->PackInfo[i].stLastUpdateTokenAt, + &tv, sizeof(struct timeval)); + Adapter->PackInfo[i].liLastUpdateTokenAt = liCurrentTime; + if((Adapter->PackInfo[i].uiCurrentTokenCount) >= + Adapter->PackInfo[i].uiMaxBucketSize) + { + Adapter->PackInfo[i].uiCurrentTokenCount = + Adapter->PackInfo[i].uiMaxBucketSize; + } + } + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n"); + return; + +} + + +/********************************************************************* +* Function - IsPacketAllowedForFlow() +* +* Description - This function checks whether the given packet from the +* specified queue can be allowed for transmission by +* checking the token count. +* +* Parameters - Adapter : Pointer to the Adpater structure. +* - iQIndex : The queue Identifier. +* - ulPacketLength: Number of bytes to be transmitted. +* +* Returns - The number of bytes allowed for transmission. +* +***********************************************************************/ +static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); + /* Validate the parameters */ + if(NULL == Adapter || (psSF < Adapter->PackInfo && + (UINT)psSF > (UINT) &Adapter->PackInfo[HiPriority])) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %d\n", Adapter, (psSF-Adapter->PackInfo)); + return 0; + } + + if(FALSE != psSF->bValid && psSF->ucDirection) + { + if(0 != psSF->uiCurrentTokenCount) + { + return psSF->uiCurrentTokenCount; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %d Available %u\n", + psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); + psSF->uiPendedLast = 1; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %d not valid\n", psSF-Adapter->PackInfo); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); + return 0; +} + +static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet) +{ + struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL; + psQueueCurrent = pPackInfo->FirstTxQueue; + while(psQueueCurrent) + { + if((UINT)Packet == (UINT)psQueueCurrent) + { + if((UINT)psQueueCurrent == (UINT)pPackInfo->FirstTxQueue) + { + pPackInfo->FirstTxQueue=psQueueCurrent->next; + if((UINT)psQueueCurrent==(UINT)pPackInfo->LastTxQueue) + pPackInfo->LastTxQueue=NULL; + } + else + { + psLastQueueNode->next=psQueueCurrent->next; + } + break; + } + psLastQueueNode = psQueueCurrent; + psQueueCurrent=psQueueCurrent->next; + } +} +/** +@ingroup tx_functions +This function despatches packet from the specified queue. +@return Zero(success) or Negative value(failure) +*/ +static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**"); + if(!Adapter || !Packet || !psSF) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet"); + return -EINVAL; + } + + if(psSF->liDrainCalculated==0) + { + psSF->liDrainCalculated = jiffies; + } + ///send the packet to the fifo.. + PktLen = Packet->len; + Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); + if(Status == 0) + { + for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) + { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) + Adapter->aTxPktSizeHist[uiIndex]++; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<====="); + return Status; +} + +/************************************************************************ +* Function - CheckAndSendPacketFromIndex() +* +* Description - This function dequeues the data/control packet from the +* specified queue for transmission. +* +* Parameters - Adapter : Pointer to the driver control structure. +* - iQIndex : The queue Identifier. +* +* Returns - None. +* +****************************************************************************/ +static __inline VOID CheckAndSendPacketFromIndex +(PMINI_ADAPTER Adapter, PacketInfo *psSF) +{ + struct sk_buff *QueuePacket=NULL; + char *pControlPacket = NULL; + INT Status=0; + int iPacketLen=0; + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%d ====>", (psSF-Adapter->PackInfo)); + if(((UINT)psSF != (UINT)&Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet + { + if(!psSF->ucDirection ) + return; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); + if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n"); + return; + } + // Check for Free Descriptors + if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..",atomic_read(&Adapter->CurrNumFreeTxDesc)); + return ; + } + +#if 0 + PruneQueue(Adapter,(psSF-Adapter->PackInfo)); +#endif + spin_lock_bh(&psSF->SFQueueLock); + QueuePacket=psSF->FirstTxQueue; + + if(QueuePacket) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); + + if(psSF->bEthCSSupport) + iPacketLen = QueuePacket->len; + else + iPacketLen = QueuePacket->len-ETH_HLEN; + + iPacketLen<<=3; + if(iPacketLen <= GetSFTokenCount(Adapter, psSF)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", + (iPacketLen >> 3)); + + DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue); + psSF->uiCurrentBytesOnHost -= (QueuePacket->len); + psSF->uiCurrentPacketsOnHost--; + atomic_dec(&Adapter->TotalPacketCount); + spin_unlock_bh(&psSF->SFQueueLock); + + Status = SendPacketFromQueue(Adapter, psSF, QueuePacket); + psSF->uiPendedLast = FALSE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %d\n", psSF-Adapter->PackInfo); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", + psSF->uiCurrentTokenCount, iPacketLen); + //this part indicates that becuase of non-availability of the tokens + //pkt has not been send out hence setting the pending flag indicating the host to send it out + //first next iteration . + psSF->uiPendedLast = TRUE; + spin_unlock_bh(&psSF->SFQueueLock); + } + } + else + { + spin_unlock_bh(&psSF->SFQueueLock); + } + } + else + { + + if((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0 ) && + (atomic_read(&Adapter->index_rd_txcntrlpkt) != + atomic_read(&Adapter->index_wr_txcntrlpkt)) + ) + { + pControlPacket = Adapter->txctlpacket + [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)]; + if(pControlPacket) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet"); + Status = SendControlPacket(Adapter, pControlPacket); + if(STATUS_SUCCESS==Status) + { + spin_lock_bh(&psSF->SFQueueLock); + psSF->NumOfPacketsSent++; + psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength; + psSF->uiSentPackets++; + atomic_dec(&Adapter->TotalPacketCount); + psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength; + psSF->uiCurrentPacketsOnHost--; + atomic_inc(&Adapter->index_rd_txcntrlpkt); + spin_unlock_bh(&psSF->SFQueueLock); + } + else + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n"); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong...."); + } + } + } + + if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed + { + if(Adapter->bcm_jiffies == 0) + Adapter->bcm_jiffies = jiffies; + } + else + { + Adapter->bcm_jiffies = 0; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<====="); +} + + +/******************************************************************* +* Function - transmit_packets() +* +* Description - This function transmits the packets from different +* queues, if free descriptors are available on target. +* +* Parameters - Adapter: Pointer to the Adapter structure. +* +* Returns - None. +********************************************************************/ +VOID transmit_packets(PMINI_ADAPTER Adapter) +{ + UINT uiPrevTotalCount = 0; + int iIndex = 0; + + BOOLEAN exit_flag = TRUE ; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>"); + + if(NULL == Adapter) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX,TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter"); + return; + } + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed"); + return; + } + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n"); + + UpdateTokenCount(Adapter); + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n"); + + PruneQueueAllSF(Adapter); + + uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount); + + for(iIndex=HiPriority;iIndex>=0;iIndex--) + { + if( !uiPrevTotalCount || (TRUE == Adapter->device_removed)) + break; + + if(Adapter->PackInfo[iIndex].bValid && + Adapter->PackInfo[iIndex].uiPendedLast && + Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); + CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); + uiPrevTotalCount--; + } + } + + while(uiPrevTotalCount > 0 && !Adapter->device_removed) + { + exit_flag = TRUE ; + //second iteration to parse non-pending queues + for(iIndex=HiPriority;iIndex>=0;iIndex--) + { + if( !uiPrevTotalCount || (TRUE == Adapter->device_removed)) + break; + + if(Adapter->PackInfo[iIndex].bValid && + Adapter->PackInfo[iIndex].uiCurrentBytesOnHost && + !Adapter->PackInfo[iIndex].uiPendedLast ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); + CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); + uiPrevTotalCount--; + exit_flag = FALSE; + } + } + + if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n"); + break; + } + if(exit_flag == TRUE ) + break ; + }/* end of inner while loop */ + if(Adapter->bcm_jiffies == 0 && + atomic_read(&Adapter->TotalPacketCount) != 0 && + uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount)) + { + Adapter->bcm_jiffies = jiffies; + } + update_per_cid_rx (Adapter); + Adapter->txtransmit_running = 0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======"); +} diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h new file mode 100644 index 000000000000..f559b599bd25 --- /dev/null +++ b/drivers/staging/bcm/Macros.h @@ -0,0 +1,399 @@ +/************************************* +* Macros.h +**************************************/ +#ifndef __MACROS_H__ +#define __MACROS_H__ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#define kthread_run(threadfn,data,datafmt)(struct task_struct *)kernel_thread(threadfn,data,0) +#endif + +#define TX_TIMER_PERIOD 10 //10 msec +#define MAX_CLASSIFIERS 100 +//#define MAX_CLASSIFIERS_PER_SF 20 +#define MAX_TARGET_DSX_BUFFERS 24 + +#define MAX_CNTRL_PKTS 100 +#define MAX_DATA_PKTS 200 +#define MAX_ETH_SIZE 1536 +#define MAX_CNTL_PKT_SIZE 2048 +/* TIMER RELATED */ +#define JIFFIES_2_QUADPART() (ULONG)(jiffies * 10000) // jiffies(1msec) to Quadpart(100nsec) + +#define MTU_SIZE 1400 + +#define MAC_ADDR_REGISTER 0xbf60d000 + + +///////////Quality of Service/////////////////////////// +#define NO_OF_QUEUES 17 +#define HiPriority NO_OF_QUEUES-1 +#define LowPriority 0 +#define BE 2 +#define rtPS 4 +#define ERTPS 5 +#define UGS 6 + +#define BE_BUCKET_SIZE 1024*1024*100 //32kb +#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb +#define MAX_ALLOWED_RATE 1024*1024*100 +#define TX_PACKET_THRESHOLD 10 +#define XSECONDS 1*HZ +#define DSC_ACTIVATE_REQUEST 248 +#define QUEUE_DEPTH_OFFSET 0x1fc01000 +#define MAX_DEVICE_DESC_SIZE 2040 +#define MAX_CTRL_QUEUE_LEN 100 +#define MAX_APP_QUEUE_LEN 200 +#define MAX_LATENCY_ALLOWED 0xFFFFFFFF +#define DEFAULT_UG_INTERVAL 250 +#define DEFAULT_UGI_FACTOR 4 + +#define DEFAULT_PERSFCOUNT 60 +#define MAX_CONNECTIONS 10 +#define MAX_CLASS_NAME_LENGTH 32 + +#define ETH_LENGTH_OF_ADDRESS 6 +#define MAX_MULTICAST_ADDRESSES 32 +#define IP_LENGTH_OF_ADDRESS 4 + +#define IP_PACKET_ONLY_MODE 0 +#define ETH_PACKET_TUNNELING_MODE 1 + +////////////Link Request////////////// +#define SET_MAC_ADDRESS_REQUEST 0 +#define SYNC_UP_REQUEST 1 +#define SYNCED_UP 2 +#define LINK_UP_REQUEST 3 +#define LINK_CONNECTED 4 +#define SYNC_UP_NOTIFICATION 2 +#define LINK_UP_NOTIFICATION 4 + + +#define LINK_NET_ENTRY 0x0002 +#define HMC_STATUS 0x0004 +#define LINK_UP_CONTROL_REQ 0x83 + +#define STATS_POINTER_REQ_STATUS 0x86 +#define NETWORK_ENTRY_REQ_PAYLOAD 198 +#define LINK_DOWN_REQ_PAYLOAD 226 +#define SYNC_UP_REQ_PAYLOAD 228 +#define STATISTICS_POINTER_REQ 237 +#define LINK_UP_REQ_PAYLOAD 245 +#define LINK_UP_ACK 246 + +#define STATS_MSG_SIZE 4 +#define INDEX_TO_DATA 4 + +#define GO_TO_IDLE_MODE_PAYLOAD 210 +#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 +#define IDLE_MODE_SF_UPDATE_MSG 187 + +#define SKB_RESERVE_ETHERNET_HEADER 16 +#define SKB_RESERVE_PHS_BYTES 32 + +#define IP_PACKET_ONLY_MODE 0 +#define ETH_PACKET_TUNNELING_MODE 1 + +#define ETH_CS_802_3 1 +#define ETH_CS_802_1Q_VLAN 3 +#define IPV4_CS 1 +#define IPV6_CS 2 +#define ETH_CS_MASK 0x3f + +/** \brief Validity bit maps for TLVs in packet classification rule */ + +#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 +#define PKT_CLASSIFICATION_VLANID_VALID 1 + +#ifndef MIN +#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b)) +#endif + + +/*Leader related terms */ +#define LEADER_STATUS 0x00 +#define LEADER_STATUS_TCP_ACK 0x1 +#define LEADER_SIZE sizeof(LEADER) +#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) +#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) +#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest) +#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) + + +#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024 + +#define GET_MAILBOX1_REG_REQUEST 0x87 +#define GET_MAILBOX1_REG_RESPONSE 0x67 +#define VCID_CONTROL_PACKET 0x00 + +#define TRANSMIT_NETWORK_DATA 0x00 +#define RECEIVED_NETWORK_DATA 0x20 + +#define CM_RESPONSES 0xA0 +#define STATUS_RSP 0xA1 +#define LINK_CONTROL_RESP 0xA2 +#define IDLE_MODE_STATUS 0xA3 +#define STATS_POINTER_RESP 0xA6 +#define MGMT_MSG_INFO_SW_STATUS 0xA7 +#define AUTH_SS_HOST_MSG 0xA8 + +#define CM_DSA_ACK_PAYLOAD 247 +#define CM_DSC_ACK_PAYLOAD 248 +#define CM_DSD_ACK_PAYLOAD 249 +#define CM_DSDEACTVATE 250 +#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 + +#define MAC_REQ 0 +#define LINK_RESP 1 +#define RSSI_INDICATION 2 + +#define SS_INFO 4 +#define STATISTICS_INFO 5 +#define CM_INDICATION 6 +#define PARAM_RESP 7 +#define BUFFER_1K 1024 +#define BUFFER_2K BUFFER_1K*2 +#define BUFFER_4K BUFFER_2K*2 +#define BUFFER_8K BUFFER_4K*2 +#define BUFFER_16K BUFFER_8K*2 +#define DOWNLINK_DIR 0 +#define UPLINK_DIR 1 + +#define BCM_SIGNATURE "BECEEM" + + +#define GPIO_OUTPUT_REGISTER 0x0F00003C +#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 +#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 +#define GPIO_MODE_REGISTER 0x0F000034 +#define GPIO_PIN_STATE_REGISTER 0x0F000038 + + +typedef struct _LINK_STATE { + UCHAR ucLinkStatus; + UCHAR bIdleMode; + UCHAR bShutdownMode; +}LINK_STATE, *PLINK_STATE; + + +enum enLinkStatus { + WAIT_FOR_SYNC = 1, + PHY_SYNC_ACHIVED = 2, + LINKUP_IN_PROGRESS = 3, + LINKUP_DONE = 4, + DREG_RECIEVED = 5, + LINK_STATUS_RESET_RECIEVED = 6, + PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, + LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, + COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9 +}; + +typedef enum _E_PHS_DSC_ACTION +{ + eAddPHSRule=0, + eSetPHSRule, + eDeletePHSRule, + eDeleteAllPHSRules +}E_PHS_DSC_ACTION; + + +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host +#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000 +#define MINIMUM_PENDING_DESCRIPTORS 5 + +#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC +#define SHUTDOWN_ACK_FROM_DRIVER 0x1 +#define SHUTDOWN_NACK_FROM_DRIVER 0x2 + +#define LINK_SYNC_UP_SUBTYPE 0x0001 +#define LINK_SYNC_DOWN_SUBTYPE 0x0001 + + + +#define CONT_MODE 1 +#define SINGLE_DESCRIPTOR 1 + + +#define DESCRIPTOR_LENGTH 0x30 +#define FIRMWARE_DESCS_ADDRESS 0x1F100000 + + +#define CLOCK_RESET_CNTRL_REG_1 0x0F00000C +#define CLOCK_RESET_CNTRL_REG_2 0x0F000840 + + + +#define TX_DESCRIPTOR_HEAD_REGISTER 0x0F010034 +#define RX_DESCRIPTOR_HEAD_REGISTER 0x0F010094 + +#define STATISTICS_BEGIN_ADDR 0xbf60f02c + +#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) + +#define WIMAX_MAX_MTU MTU_SIZE + ETH_HLEN +#define AUTO_LINKUP_ENABLE 0x2 +#define AUTO_SYNC_DISABLE 0x1 +#define AUTO_FIRM_DOWNLOAD 0x1 +#define SETTLE_DOWN_TIME 50 + +#define HOST_BUS_SUSPEND_BIT 16 + +#define IDLE_MESSAGE 0x81 + +#define MIPS_CLOCK_133MHz 1 + +#define TARGET_CAN_GO_TO_IDLE_MODE 2 +#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 +#define IDLE_MODE_PAYLOAD_LENGTH 8 + +#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer)) +#define IPV4 4 +#define IP_VERSION(byte) (((byte&0xF0)>>4)) + +#define SET_MAC_ADDRESS 193 +#define SET_MAC_ADDRESS_RESPONSE 236 + +#define IDLE_MODE_WAKEUP_PATTERN 0xd0ea1d1e +#define IDLE_MODE_WAKEUP_NOTIFIER_ADDRESS 0x1FC02FA8 +#define IDLE_MODE_MAX_RETRY_COUNT 1000 + +#ifdef REL_4_1 +#define CONFIG_BEGIN_ADDR 0xBF60B004 +#else +#define CONFIG_BEGIN_ADDR 0xBF60B000 +#endif + +#define FIRMWARE_BEGIN_ADDR 0xBFC00000 + +#define INVALID_QUEUE_INDEX (USHORT)-1 + +#define INVALID_PID (pid_t)-1 +#define DDR_80_MHZ 0 +#define DDR_100_MHZ 1 +#define DDR_120_MHZ 2 // Additional Frequency for T3LP +#define DDR_133_MHZ 3 +#define DDR_140_MHZ 4 // Not Used (Reserved for future) +#define DDR_160_MHZ 5 // Additional Frequency for T3LP +#define DDR_180_MHZ 6 // Not Used (Reserved for future) +#define DDR_200_MHZ 7 // Not Used (Reserved for future) + +#define MIPS_200_MHZ 0 +#define MIPS_160_MHZ 1 + +#define PLL_800_MHZ 0 +#define PLL_266_MHZ 1 + +#define DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING 0 +#define DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING 1 +#define DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN 2 +#define DEVICE_POWERSAVE_MODE_AS_RESERVED 3 +#define DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE 4 + + +#define EEPROM_REJECT_REG_1 0x0f003018 +#define EEPROM_REJECT_REG_2 0x0f00301c +#define EEPROM_REJECT_REG_3 0x0f003008 +#define EEPROM_REJECT_REG_4 0x0f003020 +#define EEPROM_REJECT_MASK 0x0fffffff +#define VSG_MODE 0x3 + +/* Idle Mode Related Registers */ +#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C +#ifdef BCM_SHM_INTERFACE +#define SW_ABORT_IDLEMODE_LOC 0xbfc02f9c +#define CPE_VIRTUAL_MAILBOX_REG 0xBFC02E58 +#else +#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC +#endif + +#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e +#define DEVICE_INT_OUT_EP_REG0 0x0F011870 +#define DEVICE_INT_OUT_EP_REG1 0x0F011874 + +#define BIN_FILE "/lib/firmware/macxvi200.bin" +#define CFG_FILE "/lib/firmware/macxvi.cfg" +#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 +#define MIN_VAL(x,y) ((x)<(y)?(x):(y)) +#define MAC_ADDRESS_SIZE 6 +#define EEPROM_COMMAND_Q_REG 0x0F003018 +#define EEPROM_READ_DATA_Q_REG 0x0F003020 +#define CHIP_ID_REG 0x0F000000 +#define GPIO_MODE_REG 0x0F000034 +#define GPIO_OUTPUT_REG 0x0F00003C +#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50 + +#define T3 0xbece0300 +#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 + +#define RWM_READ 0 +#define RWM_WRITE 1 + +#define T3LPB 0xbece3300 +#define BCS220_2 0xbece3311 +#define BCS220_2BC 0xBECE3310 +#define BCS250_BC 0xbece3301 +#define BCS220_3 0xbece3321 + + +#define HPM_CONFIG_LDO145 0x0F000D54 +#define HPM_CONFIG_MSW 0x0F000D58 + +#define T3B 0xbece0310 +typedef enum eNVM_TYPE +{ + NVM_AUTODETECT = 0, + NVM_EEPROM, + NVM_FLASH, + NVM_UNKNOWN +}NVM_TYPE; + +typedef enum ePMU_MODES +{ + HYBRID_MODE_7C = 0, + INTERNAL_MODE_6 = 1, + HYBRID_MODE_6 = 2 +}PMU_MODE; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +#define MAX_RDM_WRM_RETIRES 16 +#else +#define MAX_RDM_WRM_RETIRES 1 +#endif + + +enum eAbortPattern { + ABORT_SHUTDOWN_MODE = 1, + ABORT_IDLE_REG = 1, + ABORT_IDLE_MODE = 2, + ABORT_IDLE_SYNCDOWN = 3 +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + #define GET_BCM_ADAPTER(net_dev) ({\ + PMINI_ADAPTER __Adapter = NULL; \ + if (net_dev) { \ + __Adapter = (PMINI_ADAPTER)(net_dev->priv); \ + } \ + else { \ + __Adapter = NULL; \ + }__Adapter;} ) +#else + #define GET_BCM_ADAPTER(net_dev) ({\ + PMINI_ADAPTER __Adapter = NULL; \ + if (net_dev) { \ + __Adapter = (PMINI_ADAPTER)(*((UINT *)netdev_priv(net_dev))); \ + } \ + else { \ + __Adapter = NULL; \ + }__Adapter;}) + + +#endif + +/* Offsets used by driver in skb cb variable */ +#define SKB_CB_CLASSIFICATION_OFFSET 0 +#define SKB_CB_LATENCY_OFFSET 1 +#define SKB_CB_TCPACK_OFFSET 2 + +#endif //__MACROS_H__ diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile new file mode 100644 index 000000000000..3fdec2ea0c49 --- /dev/null +++ b/drivers/staging/bcm/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for Beceem USB Wimax card +# + +obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o + +bcm_wimax-objs := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \ + InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \ + Arp.o CmHost.o Debug.o IPv6Protocol.o Qos.o Transmit.o\ + Bcmnet.o DDRInit.o HandleControlPacket.o\ + LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ + Osal_Misc.o led_control.o nvm.o vendorspecificextn.o diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c new file mode 100644 index 000000000000..5ed58a863ebd --- /dev/null +++ b/drivers/staging/bcm/Misc.c @@ -0,0 +1,2239 @@ +#include "headers.h" + +static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter) +{ + + UINT uiLoopIndex; + + for(uiLoopIndex=0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) + { + Adapter->PackInfo[uiLoopIndex].uiThreshold=TX_PACKET_THRESHOLD; + Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate=MAX_ALLOWED_RATE; + Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize=20*1024*1024; + } + + Adapter->BEBucketSize=BE_BUCKET_SIZE; + Adapter->rtPSBucketSize=rtPS_BUCKET_SIZE; + Adapter->LinkStatus=SYNC_UP_REQUEST; + Adapter->TransferMode=IP_PACKET_ONLY_MODE; + Adapter->usBestEffortQueueIndex=-1; + return; +} + + +INT +InitAdapter(PMINI_ADAPTER psAdapter) +{ + int i = 0; + INT Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = 0x%x",(unsigned int) psAdapter); + + if(psAdapter == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL"); + return -EINVAL; + } + + sema_init(&psAdapter->NVMRdmWrmLock,1); +// psAdapter->ulFlashCalStart = FLASH_AUTO_INIT_BASE_ADDR; + + sema_init(&psAdapter->rdmwrmsync, 1); + spin_lock_init(&psAdapter->control_queue_lock); + spin_lock_init(&psAdapter->txtransmitlock); + sema_init(&psAdapter->RxAppControlQueuelock, 1); +// sema_init(&psAdapter->data_packet_queue_lock, 1); + sema_init(&psAdapter->fw_download_sema, 1); + sema_init(&psAdapter->LowPowerModeSync,1); + + // spin_lock_init(&psAdapter->sleeper_lock); + + for(i=0;iPackInfo[i].SFQueueLock); + i=0; + + init_waitqueue_head(&psAdapter->process_rx_cntrlpkt); + init_waitqueue_head(&psAdapter->tx_packet_wait_queue); + init_waitqueue_head(&psAdapter->process_read_wait_queue); + init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue); + init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue); + psAdapter->waiting_to_fw_download_done = TRUE; + //init_waitqueue_head(&psAdapter->device_wake_queue); + psAdapter->fw_download_done=FALSE; + + psAdapter->pvOsDepData = (PLINUX_DEP_DATA) kmalloc(sizeof(LINUX_DEP_DATA), + GFP_KERNEL); + + if(psAdapter->pvOsDepData == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Linux Specific Data allocation failed"); + return -ENOMEM; + } + memset(psAdapter->pvOsDepData, 0, sizeof(LINUX_DEP_DATA)); + + default_wimax_protocol_initialize(psAdapter); + for (i=0;itxctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE, + GFP_KERNEL); + if(!psAdapter->txctlpacket[i]) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); + return -ENOMEM; + } + } + if(AllocAdapterDsxBuffer(psAdapter)) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers"); + return -EINVAL; + } + + //Initialize PHS interface + if(phs_init(&psAdapter->stBCMPhsContext,psAdapter)!=0) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __FUNCTION__, __LINE__); + return -ENOMEM; + } + + Status = BcmAllocFlashCSStructure(psAdapter); + if(Status) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Memory Allocation for Flash structure failed"); + return Status ; + } + + Status = vendorextnInit(psAdapter); + + if(STATUS_SUCCESS != Status) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Vendor Init Failed"); + return Status ; + } + + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised"); + + + return STATUS_SUCCESS; +} + +VOID AdapterFree(PMINI_ADAPTER Adapter) +{ + INT count = 0; + + beceem_protocol_reset(Adapter); + + vendorextnExit(Adapter); + + if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) + kthread_stop (Adapter->control_packet_handler); + if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) + kthread_stop (Adapter->transmit_packet_thread); + wake_up(&Adapter->process_read_wait_queue); + if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) + kthread_stop (Adapter->LEDInfo.led_cntrl_threadid); + bcm_unregister_networkdev(Adapter); + while(atomic_read(&Adapter->ApplicationRunning)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning)); + msleep(100); + } + unregister_control_device_interface(Adapter); + if(Adapter->dev && !IS_ERR(Adapter->dev)) + free_netdev(Adapter->dev); + if(Adapter->pstargetparams != NULL) + { + bcm_kfree(Adapter->pstargetparams); + } + for (count =0;count < MAX_CNTRL_PKTS;count++) + { + if(Adapter->txctlpacket[count]) + bcm_kfree(Adapter->txctlpacket[count]); + } + FreeAdapterDsxBuffer(Adapter); + if(Adapter->pvOsDepData) + bcm_kfree (Adapter->pvOsDepData); + if(Adapter->pvInterfaceAdapter) + bcm_kfree(Adapter->pvInterfaceAdapter); + + //Free the PHS Interface + PhsCleanup(&Adapter->stBCMPhsContext); + +#ifndef BCM_SHM_INTERFACE + BcmDeAllocFlashCSStructure(Adapter); +#endif + + bcm_kfree (Adapter); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n"); +} + + +int create_worker_threads(PMINI_ADAPTER psAdapter) +{ + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads..."); + // Rx Control Packets Processing + psAdapter->control_packet_handler = kthread_run((int (*)(void *)) + control_packet_handler, psAdapter, "CtrlPktHdlr"); + if(IS_ERR(psAdapter->control_packet_handler)) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n"); + return PTR_ERR(psAdapter->control_packet_handler); + } + // Tx Thread + psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) + tx_pkt_handler, psAdapter, "TxPktThread"); + if(IS_ERR (psAdapter->transmit_packet_thread)) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success"); + kthread_stop(psAdapter->control_packet_handler); + return PTR_ERR(psAdapter->transmit_packet_thread); + } + return 0; +} + + +static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) +{ + struct file *flp=NULL; + mm_segment_t oldfs; + oldfs=get_fs(); + set_fs(get_ds()); + flp=filp_open(path, O_RDONLY, S_IRWXU); + set_fs(oldfs); + if(IS_ERR(flp)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err %lx", + path, PTR_ERR(flp)); + flp = NULL; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!", + path); + } + if(Adapter->device_removed) + { + flp = NULL; + } + + return flp; +} + + +int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ + char *path, /**< path to image file */ + unsigned int loc /**< Download Address on the chip*/ + ) +{ + int errorno=0; + struct file *flp=NULL; + mm_segment_t oldfs; + struct timeval tv={0}; + + flp=open_firmware_file(Adapter, path); + if(!flp) + { + errorno = -ENOENT; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path); + goto exit_download; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path,(unsigned long)flp->f_dentry->d_inode->i_size, loc); + do_gettimeofday(&tv); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + + (tv.tv_usec/1000))); + if(Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error\ + %x!!!", -EIO); + errorno=-EIO; + goto exit_download; + } + oldfs=get_fs();set_fs(get_ds()); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + vfs_llseek(flp, 0, 0); +#endif + set_fs(oldfs); + if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, + flp, loc)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!"); + errorno=-EIO; + goto exit_download; + } + +exit_download: + oldfs=get_fs();set_fs(get_ds()); + if(flp && !(IS_ERR(flp))) + filp_close(flp, current->files); + set_fs(oldfs); + do_gettimeofday(&tv); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "file download done at %lx", ((tv.tv_sec * 1000) + + (tv.tv_usec/1000))); + return errorno; +} + + +void bcm_kfree_skb(struct sk_buff *skb) +{ + if(skb) + { + kfree_skb(skb); + } + skb = NULL ; +} + +VOID bcm_kfree(VOID *ptr) +{ + if(ptr) + { + kfree(ptr); + } + ptr = NULL ; +} + +/** +@ingroup ctrl_pkt_functions +This function copies the contents of given buffer +to the control packet and queues it for transmission. +@note Do not acquire the spinock, as it it already acquired. +@return SUCCESS/FAILURE. +*/ +INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**"); + if(!ioBuffer) + { + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Got Null Buffer\n"); + return -EINVAL; + } + + pLinkReq = (PLINK_REQUEST)ioBuffer; + pLeader=(PLEADER)ioBuffer; //ioBuffer Contains sw_Status and Payload + + if(Adapter->bShutStatus == TRUE && + pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD && + pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) + { + //Got sync down in SHUTDOWN..we could not process this. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n"); + return STATUS_FAILURE; + } + + if((pLeader->Status == LINK_UP_CONTROL_REQ) && + ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD && + (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) ||//Sync Up Command + pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) //Net Entry Command + { + if(Adapter->LinkStatus > PHY_SYNC_ACHIVED) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"LinkStatus is Greater than PHY_SYN_ACHIEVED"); + return STATUS_FAILURE; + } + if(TRUE == Adapter->bShutStatus) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); + if(Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Waking up for the First Time..\n"); + Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; // change it to 1 for current support. + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); + + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, + !Adapter->bShutStatus, (5 * HZ)); + + if(Status == -ERESTARTSYS) + return Status; + + if(Adapter->bShutStatus) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n"); + return STATUS_FAILURE; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Wakeup has been tried already...\n"); + } + } + + } + if(TRUE == Adapter->IdleMode) + { + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence \n"); + if(pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || + pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ ) + + { + if((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0]==LINK_DOWN_REQ_PAYLOAD)) + { + if((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Link Down Sent in Idle Mode\n"); + Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN;//LINK DOWN sent in Idle Mode + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n"); + Adapter->usIdleModePattern = ABORT_IDLE_REG; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n"); + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + } + + /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent + the wake up from idlemode is from host*/ + //Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; +#if 0 + if(STATUS_SUCCESS != InterfaceIdleModeWakeup(Adapter)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Wake up Failed\n"); + return STATUS_FAILURE; + } +#endif + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); + + + + if(LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0]) + { + // We should not send DREG message down while in idlemode. + return STATUS_SUCCESS; + } + + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, + !Adapter->IdleMode, (5 * HZ)); + + if(Status == -ERESTARTSYS) + return Status; + + if(Adapter->IdleMode) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n"); + return STATUS_FAILURE; + } + } + else + return STATUS_SUCCESS; + } + //The Driver has to send control messages with a particular VCID + pLeader->Vcid = VCID_CONTROL_PACKET;//VCID for control packet. + + /* Allocate skb for Control Packet */ + pktlen = pLeader->PLength; + ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS]; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", + atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); + if(ctrl_buff) + { + if(pLeader) + { + if((pLeader->Status == 0x80) || + (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) + { + /* + //Restructure the DSX message to handle Multiple classifier Support + // Write the Service Flow param Structures directly to the target + //and embed the pointers in the DSX messages sent to target. + */ + //Lets store the current length of the control packet we are transmitting + pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; + pktlen = pLeader->PLength; + Status = StoreCmControlResponseMessage(Adapter,pucAddIndication, &pktlen); + if(Status != 1) + { + ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); + return STATUS_FAILURE; + } + /* + //update the leader to use the new length + //The length of the control packet is length of message being sent + Leader length + */ + pLeader->PLength = pktlen; + } + } + memset(ctrl_buff, 0, pktlen+LEADER_SIZE); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); + *(PLEADER)ctrl_buff=*pLeader; + memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); + + /*Update the statistics counters */ + spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost+=pLeader->PLength; + Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; + atomic_inc(&Adapter->TotalPacketCount); + spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); + + Adapter->PackInfo[HiPriority].bValid = TRUE; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, + Adapter->PackInfo[HiPriority].bValid); + Status=STATUS_SUCCESS; + /*Queue the packet for transmission */ + atomic_inc(&Adapter->index_wr_txcntrlpkt); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets"); + atomic_set(&Adapter->TxPktAvail, 1); +#ifdef BCM_SHM_INTERFACE + virtual_mail_box_interrupt(); +#endif + wake_up(&Adapter->tx_packet_wait_queue); + } + else + { + Status=-ENOMEM; + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); + } + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); + return Status; +} + +/***************************************************************** +* Function - SendStatisticsPointerRequest() +* +* Description - This function builds and forwards the Statistics +* Pointer Request control Packet. +* +* Parameters - Adapter : Pointer to Adapter structure. +* - pstStatisticsPtrRequest : Pointer to link request. +* +* Returns - None. +*****************************************************************/ +VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, + PLINK_REQUEST pstStatisticsPtrRequest) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>"); + pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS; + pstStatisticsPtrRequest->Leader.PLength = sizeof(ULONG);//minimum 4 bytes + pstStatisticsPtrRequest->szData[0] = STATISTICS_POINTER_REQ; + + CopyBufferToControlPacket(Adapter,pstStatisticsPtrRequest); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "<====="); + return; +} + + + +void SendLinkDown(PMINI_ADAPTER Adapter) +{ + LINK_REQUEST stLinkDownRequest; + memset(&stLinkDownRequest, 0, sizeof(LINK_REQUEST)); + stLinkDownRequest.Leader.Status=LINK_UP_CONTROL_REQ; + stLinkDownRequest.Leader.PLength=sizeof(ULONG);//minimum 4 bytes + stLinkDownRequest.szData[0]=LINK_DOWN_REQ_PAYLOAD; + Adapter->bLinkDownRequested = TRUE; + + CopyBufferToControlPacket(Adapter,&stLinkDownRequest); +} + +/****************************************************************** +* Function - LinkMessage() +* +* Description - This function builds the Sync-up and Link-up request +* packet messages depending on the device Link status. +* +* Parameters - Adapter: Pointer to the Adapter structure. +* +* Returns - None. +*******************************************************************/ +__inline VOID LinkMessage(PMINI_ADAPTER Adapter) +{ + PLINK_REQUEST pstLinkRequest=NULL; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); + if(Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) + { + pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + if(!pstLinkRequest) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); + return; + } + memset(pstLinkRequest,0,sizeof(LINK_REQUEST)); + //sync up request... + Adapter->LinkStatus = WAIT_FOR_SYNC;// current link status + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); + pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD; + pstLinkRequest->szData[1]=LINK_SYNC_UP_SUBTYPE; + pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ; + pstLinkRequest->Leader.PLength=sizeof(ULONG); + Adapter->bSyncUpRequestSent = TRUE; + } + else if(Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) + { + pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + if(!pstLinkRequest) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); + return; + } + memset(pstLinkRequest,0,sizeof(LINK_REQUEST)); + //LINK_UP_REQUEST + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); + pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD; + pstLinkRequest->szData[1]=LINK_NET_ENTRY; + pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ; + pstLinkRequest->Leader.PLength=sizeof(ULONG); + } + if(pstLinkRequest) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); + CopyBufferToControlPacket(Adapter, pstLinkRequest); + bcm_kfree(pstLinkRequest); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); + return; +} + + +/********************************************************************** +* Function - StatisticsResponse() +* +* Description - This function handles the Statistics response packet. +* +* Parameters - Adapter : Pointer to the Adapter structure. +* - pvBuffer: Starting address of Statistic response data. +* +* Returns - None. +************************************************************************/ +VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__); + Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__); + return; +} + + +/********************************************************************** +* Function - LinkControlResponseMessage() +* +* Description - This function handles the Link response packets. +* +* Parameters - Adapter : Pointer to the Adapter structure. +* - pucBuffer: Starting address of Link response data. +* +* Returns - None. +***********************************************************************/ +VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) +{ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); + + if(*pucBuffer==LINK_UP_ACK) + { + switch(*(pucBuffer+1)) + { + case PHY_SYNC_ACHIVED: //SYNCed UP + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED"); + + if(Adapter->LinkStatus == LINKUP_DONE) + { + beceem_protocol_reset(Adapter); + } + + Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ; + Adapter->LinkStatus=PHY_SYNC_ACHIVED; + + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = NO_NETWORK_ENTRY; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + + LinkMessage(Adapter); + break; + + case LINKUP_DONE: + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE"); + Adapter->LinkStatus=LINKUP_DONE; + Adapter->bPHSEnabled = *(pucBuffer+3); + Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Recieved In LinkUp Ack : %x \n",Adapter->bPHSEnabled); + if((FALSE == Adapter->bShutStatus)&& + (FALSE == Adapter->IdleMode)) + { + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = NORMAL_OPERATION; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + } + LinkMessage(Adapter); + break; + case WAIT_FOR_SYNC: + + /* + * Driver to ignore the DREG_RECEIVED + * WiMAX Application should handle this Message + */ + //Adapter->liTimeSinceLastNetEntry = 0; + Adapter->LinkUpStatus = 0; + Adapter->LinkStatus = 0; + Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ; + Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; + Adapter->IdleMode = FALSE; + beceem_protocol_reset(Adapter); + + break; + case LINK_SHUTDOWN_REQ_FROM_FIRMWARE: + case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW: + { + HandleShutDownModeRequest(Adapter, pucBuffer); + } + break; + default: + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x",*(pucBuffer+1)); + break; + } + } + else if(SET_MAC_ADDRESS_RESPONSE==*pucBuffer) + { + PUCHAR puMacAddr = (pucBuffer + 1); + Adapter->LinkStatus=SYNC_UP_REQUEST; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP"); + LinkMessage(Adapter); + memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====",__FUNCTION__); + return; +} + +void SendIdleModeResponse(PMINI_ADAPTER Adapter) +{ + INT status = 0, NVMAccess = 0,lowPwrAbortMsg = 0; + struct timeval tv; + CONTROL_MESSAGE stIdleResponse = {{0}}; + memset(&tv, 0, sizeof(tv)); + stIdleResponse.Leader.Status = IDLE_MESSAGE; + stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH; + stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL," ============>"); + + /********************************* + **down_trylock - + ** if [ semaphore is available ] + ** acquire semaphone and return value 0 ; + ** else + ** return non-zero value ; + ** + ***********************************/ + + NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + + lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync); + + + if((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) && + (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) ) + { + if(!NVMAccess) + up(&Adapter->NVMRdmWrmLock); + + if(!lowPwrAbortMsg) + up(&Adapter->LowPowerModeSync); + + stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!"); + Adapter->bPreparingForLowPowerMode = FALSE; + } + else + { + stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; //2;//Idle ACK + Adapter->StatisticsPointer = 0; + + /* Wait for the LED to TURN OFF before sending ACK response */ + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + INT iRetVal = 0; + + /* Wake the LED Thread with IDLEMODE_ENTER State */ + Adapter->DriverState = LOWPOWER_MODE_ENTER; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);; + wake_up(&Adapter->LEDInfo.notify_led_event); + + /* Wait for 1 SEC for LED to OFF */ + iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, \ + Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); + + + /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ + if(iRetVal <= 0) + { + stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on. + Adapter->DriverState = NORMAL_OPERATION; + wake_up(&Adapter->LEDInfo.notify_led_event); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!"); + } + } + if(stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"ACKING IDLE MODE !!!!!!!!!"); + down(&Adapter->rdmwrmsync); + Adapter->bPreparingForLowPowerMode = TRUE; + up(&Adapter->rdmwrmsync); +#ifndef BCM_SHM_INTERFACE + //Killing all URBS. + if(Adapter->bDoSuspend == TRUE) + Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + +#endif + } + else + { + Adapter->bPreparingForLowPowerMode = FALSE; + } + + if(!NVMAccess) + up(&Adapter->NVMRdmWrmLock); + + if(!lowPwrAbortMsg) + up(&Adapter->LowPowerModeSync); + + } + status = CopyBufferToControlPacket(Adapter,&stIdleResponse); + if((status != STATUS_SUCCESS)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n"); + Adapter->bPreparingForLowPowerMode = FALSE; +#ifndef BCM_SHM_INTERFACE + StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); +#endif + } + do_gettimeofday(&tv); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); + +} + +/****************************************************************** +* Function - DumpPackInfo() +* +* Description - This function dumps the all Queue(PackInfo[]) details. +* +* Parameters - Adapter: Pointer to the Adapter structure. +* +* Returns - None. +*******************************************************************/ +VOID DumpPackInfo(PMINI_ADAPTER Adapter) +{ + + UINT uiLoopIndex = 0; + UINT uiIndex = 0; + UINT uiClsfrIndex = 0; + S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + + for(uiLoopIndex=0;uiLoopIndexPackInfo[uiLoopIndex].bValid) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid is FALSE for %X index\n",uiLoopIndex); + continue; + } + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," Dumping SF Rule Entry For SFID %lX \n",Adapter->PackInfo[uiLoopIndex].ulSFID); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," ucDirection %X \n",Adapter->PackInfo[uiLoopIndex].ucDirection); + if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv6 Service Flow \n"); + } + else + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv4 Service Flow \n"); + } + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," SF Traffic Priority %X \n",Adapter->PackInfo[uiLoopIndex].u8TrafficPriority); + + for(uiClsfrIndex=0;uiClsfrIndexastClassifierTable[uiClsfrIndex]; + if(!pstClassifierEntry->bUsed) + continue; + + if(pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID) + continue; + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n",uiClsfrIndex,pstClassifierEntry->uiClassifierRuleIndex); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n",uiClsfrIndex,pstClassifierEntry->usVCID_Value); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n",uiClsfrIndex,pstClassifierEntry->bProtocolValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n",uiClsfrIndex,pstClassifierEntry->bTOSValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bDestIpValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bSrcIpValid); + + + for(uiIndex=0;uiIndexusSrcPortRangeLo[uiIndex]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeHi:%X\n",pstClassifierEntry->usSrcPortRangeHi[uiIndex]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeLo:%X\n",pstClassifierEntry->usDestPortRangeLo[uiIndex]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeHi:%X\n",pstClassifierEntry->usDestPortRangeHi[uiIndex]); + } + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," \tucIPSourceAddressLength : 0x%x\n",pstClassifierEntry->ucIPSourceAddressLength); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucIPDestinationAddressLength : 0x%x\n",pstClassifierEntry->ucIPDestinationAddressLength); + for(uiIndex=0;uiIndexucIPSourceAddressLength;uiIndex++) + { + if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpAddr :\n"); + DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpMask :\n"); + DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask); + } + else + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpAddr:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpMask:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]); + } + } + for(uiIndex=0;uiIndexucIPDestinationAddressLength;uiIndex++) + { + if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpAddr :\n"); + DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpMask :\n"); + DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask); + + } + else + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpAddr:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpMask:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]); + } + } + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucProtocol:0x%X\n",pstClassifierEntry->ucProtocol[0]); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tu8ClassifierRulePriority:%X\n",pstClassifierEntry->u8ClassifierRulePriority); + + + } + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ulSFID:%lX\n",Adapter->PackInfo[uiLoopIndex].ulSFID); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"usVCID_Value:%X\n",Adapter->PackInfo[uiLoopIndex].usVCID_Value); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"PhsEnabled: 0x%X\n",Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThreshold:%X\n",Adapter->PackInfo[uiLoopIndex].uiThreshold); + + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid:%X\n",Adapter->PackInfo[uiLoopIndex].bValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bActive:%X\n",Adapter->PackInfo[uiLoopIndex].bActive); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"u8QueueType:%X\n",Adapter->PackInfo[uiLoopIndex].u8QueueType); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxBucketSize:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPerSFTxResourceCount:%X\n",atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount)); + //DumpDebug(DUMP_INFO,(" bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentBytesOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentPacketsOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentBytes); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentPackets); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentDrainRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThisPeriodSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liDrainCalculated:%llX\n",Adapter->PackInfo[uiLoopIndex].liDrainCalculated); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentTokenCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liLastUpdateTokenAt:%llX\n",Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxAllowedRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPendedLast:%X\n",Adapter->PackInfo[uiLoopIndex].uiPendedLast); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"NumOfPacketsSent:%X\n",Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n",Adapter->PackInfo[uiLoopIndex].uiMaxLatency); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n",Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]); +// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); +// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); +// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); +// DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount)); + } + + for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++) + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aRxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aRxPktSizeHist[uiLoopIndex]); + + for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++) + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aTxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aTxPktSizeHist[uiLoopIndex]); + + + + return; + + +} + + +__inline int reset_card_proc(PMINI_ADAPTER ps_adapter) +{ + int retval = STATUS_SUCCESS; + +#ifndef BCM_SHM_INTERFACE + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PS_INTERFACE_ADAPTER psIntfAdapter = NULL; + unsigned int value = 0, uiResetValue = 0; + + psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)) ; + + ps_adapter->bDDRInitDone = FALSE; + + if(ps_adapter->chip_id >= T3LPB) + { + //SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before + rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value)); + rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value)); + + //making bit[6...5] same as was before f/w download. this setting force the h/w to + //re-populated the SP RAM area with the string descriptor . + value = value | (ps_adapter->syscfgBefFwDld & 0x00000060) ; + wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); + } + +#ifndef BCM_SHM_INTERFACE + //killing all submitted URBs. + psIntfAdapter->psAdapter->StopAllXaction = TRUE ; + Bcm_kill_all_URBs(psIntfAdapter); +#endif + /* Reset the UMA-B Device */ + if(ps_adapter->chip_id >= T3LPB) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B \n"); + retval = usb_reset_device(psIntfAdapter->udev); + + psIntfAdapter->psAdapter->StopAllXaction = FALSE ; + + if(retval != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval); + goto err_exit; + } + if (ps_adapter->chip_id == BCS220_2 || + ps_adapter->chip_id == BCS220_2BC || + ps_adapter->chip_id == BCS250_BC || + ps_adapter->chip_id == BCS220_3) + { + retval = rdmalt(ps_adapter,HPM_CONFIG_LDO145, &value, sizeof(value)); + if( retval < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval); + goto err_exit; + } + //setting 0th bit + value |= (1<<0); + retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); + if( retval < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); + goto err_exit; + } + } + + } + else + { + retval = rdmalt(ps_adapter,0x0f007018, &value, sizeof(value)); + if( retval < 0) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval); + goto err_exit; + } + value&=(~(1<<16)); + retval= wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)) ; + if( retval < 0) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); + goto err_exit; + } + + // Toggling the GPIO 8, 9 + value = 0; + retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value)); + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); + goto err_exit; + } + value = 0x300; + retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)) ; + if(retval < 0) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); + goto err_exit; + } + mdelay(50); + } + + //ps_adapter->downloadDDR = false; + + if(ps_adapter->bFlashBoot) + { + //In flash boot mode MIPS state register has reverse polarity. + // So just or with setting bit 30. + //Make the MIPS in Reset state. + rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); + + uiResetValue |=(1<<30); + wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); + } + + if(ps_adapter->chip_id >= T3LPB) + { + uiResetValue = 0; + // + // WA for SYSConfig Issue. + // Read SYSCFG Twice to make it writable. + // + rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); + if(uiResetValue & (1<<4)) + { + uiResetValue = 0; + rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));//2nd read to make it writable. + uiResetValue &= (~(1<<4)); + wrmalt(ps_adapter,SYS_CFG, &uiResetValue, sizeof(uiResetValue)); + } + + } + uiResetValue = 0; + wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue)); + +err_exit : + psIntfAdapter->psAdapter->StopAllXaction = FALSE ; +#endif + return retval; +} + +__inline int run_card_proc(PMINI_ADAPTER ps_adapter ) +{ + unsigned int value=0; + { + + if(rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__); + return STATUS_FAILURE; + } + + if(ps_adapter->bFlashBoot) + { + + value&=(~(1<<30)); + } + else + { + value |=(1<<30); + } + + if(wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__); + return STATUS_FAILURE; + } + } + return STATUS_SUCCESS; +} + +int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) +{ + + UINT status = STATUS_SUCCESS; + UINT value = 0; +#ifdef BCM_SHM_INTERFACE + unsigned char *pConfigFileAddr = (unsigned char *)CPE_MACXVI_CFG_ADDR; +#endif + /* + * Create the threads first and then download the + * Firm/DDR Settings.. + */ + + if((status = create_worker_threads(ps_adapter))<0) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread"); + return status; + } + /* + * For Downloading the Firm, parse the cfg file first. + */ + status = bcm_parse_target_params (ps_adapter); + if(status){ + return status; + } + +#ifndef BCM_SHM_INTERFACE + if(ps_adapter->chip_id >= T3LPB) + { + rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value)); + ps_adapter->syscfgBefFwDld = value ; + if((value & 0x60)== 0) + { + ps_adapter->bFlashBoot = TRUE; + } + } + + reset_card_proc(ps_adapter); + + //Initializing the NVM. + BcmInitNVM(ps_adapter); + status = ddr_init(ps_adapter); + if(status) + { + BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "ddr_init Failed\n"); + return status; + } + + /* Download cfg file */ + status = buffDnldVerify(ps_adapter, + (PUCHAR)ps_adapter->pstargetparams, + sizeof(STARGETPARAMS), + CONFIG_BEGIN_ADDR); + if(status) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); + goto OUT; + } + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded"); + + if(register_networkdev(ps_adapter)) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); + return -EIO; + } + + if(FALSE == ps_adapter->AutoFirmDld) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n"); + //If Auto f/w download is disable, register the control interface, + //register the control interface after the mailbox. + if(register_control_device_interface(ps_adapter) < 0) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); + return -EIO; + } + + return STATUS_SUCCESS; + } + + /* + * Do the LED Settings here. It will be used by the Firmware Download + * Thread. + */ + + /* + * 1. If the LED Settings fails, do not stop and do the Firmware download. + * 2. This init would happend only if the cfg file is present, else + * call from the ioctl context. + */ + + status = InitLedSettings (ps_adapter); + + if(status) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n"); + return status; + } + if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + ps_adapter->DriverState = DRIVER_INIT; + wake_up(&ps_adapter->LEDInfo.notify_led_event); + } + + if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + ps_adapter->DriverState = FW_DOWNLOAD; + wake_up(&ps_adapter->LEDInfo.notify_led_event); + } + + value = 0; + wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); + wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); + + if(ps_adapter->eNVMType == NVM_FLASH) + { + status = PropagateCalParamsFromFlashToMemory(ps_adapter); + if(status) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propogation of Cal param failed .." ); + goto OUT; + } + } +#if 0 + else if(psAdapter->eNVMType == NVM_EEPROM) + { + PropagateCalParamsFromEEPROMToMemory(); + } +#endif + + /* Download Firmare */ + if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR))) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present... \n"); + goto OUT; + } + + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded"); + status = run_card_proc(ps_adapter); + if(status) + { + BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n"); + goto OUT; + } + + + ps_adapter->fw_download_done = TRUE; + mdelay(10); + +OUT: + if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + ps_adapter->DriverState = FW_DOWNLOAD_DONE; + wake_up(&ps_adapter->LEDInfo.notify_led_event); + } + +#else + + ps_adapter->bDDRInitDone = TRUE; + //Initializing the NVM. + BcmInitNVM(ps_adapter); + + //Propagating the cal param from Flash to DDR + value = 0; + wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); + wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); + + if(ps_adapter->eNVMType == NVM_FLASH) + { + status = PropagateCalParamsFromFlashToMemory(ps_adapter); + if(status) + { + printk("\nPropogation of Cal param from flash to DDR failed ..\n" ); + } + } + + //Copy config file param to DDR. + memcpy(pConfigFileAddr,ps_adapter->pstargetparams, sizeof(STARGETPARAMS)); + + if(register_networkdev(ps_adapter)) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); + return -EIO; + } + + + status = InitLedSettings (ps_adapter); + if(status) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n"); + return status; + } + + + if(register_control_device_interface(ps_adapter) < 0) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); + return -EIO; + } + + ps_adapter->fw_download_done = TRUE; +#endif + return status; +} + + +int bcm_parse_target_params(PMINI_ADAPTER Adapter) +{ +#ifdef BCM_SHM_INTERFACE + extern void read_cfg_file(PMINI_ADAPTER Adapter); +#endif + struct file *flp=NULL; + mm_segment_t oldfs={0}; + char *buff = NULL; + int len = 0; + loff_t pos = 0; + + buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL); + if(!buff) + { + return -ENOMEM; + } + if((Adapter->pstargetparams = + kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL) + { + bcm_kfree(buff); + return -ENOMEM; + } + flp=open_firmware_file(Adapter, CFG_FILE); + if(!flp) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE); + bcm_kfree(buff); + bcm_kfree(Adapter->pstargetparams); + Adapter->pstargetparams = NULL; + return -ENOENT; + } + oldfs=get_fs(); set_fs(get_ds()); + len=vfs_read(flp, buff, BUFFER_1K, &pos); + set_fs(oldfs); + + if(len != sizeof(STARGETPARAMS)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n"); + bcm_kfree(buff); + bcm_kfree(Adapter->pstargetparams); + Adapter->pstargetparams = NULL; + filp_close(flp, current->files); + return -ENOENT; + } + filp_close(flp, current->files); + + /* Check for autolink in config params */ + /* + * Values in Adapter->pstargetparams are in network byte order + */ + memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS)); + bcm_kfree (buff); + beceem_parse_target_struct(Adapter); +#ifdef BCM_SHM_INTERFACE + read_cfg_file(Adapter); + +#endif + return STATUS_SUCCESS; +} + +void beceem_parse_target_struct(PMINI_ADAPTER Adapter) +{ + UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;; + + if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Disabled\n"); + Adapter->AutoSyncup = FALSE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Enabled\n"); + Adapter->AutoSyncup = TRUE; + } + if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling autolink up"); + Adapter->AutoLinkUp = TRUE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling autolink up"); + Adapter->AutoLinkUp = FALSE; + } + // Setting the DDR Setting.. + Adapter->DDRSetting = + (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >>8)&0x0F; + Adapter->ulPowerSaveMode = + (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n", + Adapter->ulPowerSaveMode); + if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling Auto Firmware Download\n"); + Adapter->AutoFirmDld = TRUE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling Auto Firmware Download\n"); + Adapter->AutoFirmDld = FALSE; + } + uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6); + Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"MIPSConfig : 0x%X\n",Adapter->bMipsConfig); + //used for backward compatibility. + Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01; + + Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "PMU MODE: %x", Adapter->PmuMode); + + if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01)) + { + Adapter->bDoSuspend = TRUE; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Making DoSuspend TRUE as per configFile"); + } + + uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "uiEEPROMFlag : 0x%X\n",uiEEPROMFlag); + Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3); + + + Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1; + //printk(("bStatusWrite : 0x%X\n", Adapter->bStatusWrite)); + + Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4)); + //printk(("uiSectorSize : 0x%X\n", Adapter->uiSectorSizeInCFG)); + + Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; + //printk(MP_INIT,("bSectorSizeOverride : 0x%X\n",Adapter->bSectorSizeOverride)); + + if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01) + Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE; + //autocorrection part + if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) + doPowerAutoCorrection(Adapter); + +} + +VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) +{ + UINT reporting_mode = 0; + + reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ; + psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); + + if(reporting_mode == TRUE) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"can't do suspen/resume as reporting mode is enable"); + psAdapter->bDoSuspend = FALSE; + } + + if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) + { + //If reporting mode is enable, switch PMU to PMC + #if 0 + if(reporting_mode == FALSE) + { + psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN; + psAdapter->bDoSuspend = TRUE; + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMU selected ...."); + + } + else + #endif + { + psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; + psAdapter->bDoSuspend =FALSE; + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMC selected.."); + + } + + //clearing space bit[15..12] + psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12))); + //placing the power save mode option + psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12)); + + } + else if (psAdapter->bIsAutoCorrectEnabled == FALSE) + { + + // remove the autocorrect disable bit set before dumping. + psAdapter->ulPowerSaveMode &= ~(1 << 3); + psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15)); + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode); + } +} +unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) +{ + unsigned char *pucmacaddr = NULL; + int status = 0, i=0; + unsigned int temp =0; + + + pucmacaddr = (unsigned char *)kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL); + if(!pucmacaddr) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n"); + return NULL; + } + + dwAddress |= 0x5b000000; + status = wrmalt(Adapter, EEPROM_COMMAND_Q_REG, + (PUINT)&dwAddress, sizeof(UINT)); + if(status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n"); + bcm_kfree(pucmacaddr); + pucmacaddr = NULL; + goto OUT; + } + for(i=0;idev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); + for(i=0;idev->dev_addr[i]); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n"); + bcm_kfree(puMacAddr); + } + return STATUS_SUCCESS; +} +#endif + +void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) +{ + UINT uiIndex = 0; + + if(RWM_WRITE == rwFlag) { + for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) { + puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]); + } + } else { + for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) { + puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]); + } + } +} + +#define CACHE_ADDRESS_MASK 0x80000000 +#define UNCACHE_ADDRESS_MASK 0xa0000000 + +int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +{ + INT uiRetVal =0; + +#ifndef BCM_SHM_INTERFACE + uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter, + uiAddress, pucBuff, sSize); + + if(uiRetVal < 0) + return uiRetVal; + +#else + int indx; + uiRetVal = STATUS_SUCCESS; + if(uiAddress & 0x10000000) { + // DDR Memory Access + uiAddress |= CACHE_ADDRESS_MASK; + memcpy(pucBuff,(unsigned char *)uiAddress ,sSize); + } + else { + // Register, SPRAM, Flash + uiAddress |= UNCACHE_ADDRESS_MASK; + if ((uiAddress & FLASH_ADDR_MASK) == (FLASH_CONTIGIOUS_START_ADDR_BCS350 & FLASH_ADDR_MASK)) + { + #if defined(FLASH_DIRECT_ACCESS) + memcpy(pucBuff,(unsigned char *)uiAddress ,sSize); + #else + printk("\nInvalid GSPI ACCESS :Addr :%#X", uiAddress); + uiRetVal = STATUS_FAILURE; + #endif + } + else if(((unsigned int )uiAddress & 0x3) || + ((unsigned int )pucBuff & 0x3) || + ((unsigned int )sSize & 0x3)) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"rdmalt :unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize); + uiRetVal = STATUS_FAILURE; + } + else { + for (indx=0;indxinterface_wrm(Adapter->pvInterfaceAdapter, + uiAddress, pucBuff, sSize); + +#else + int indx; + if(uiAddress & 0x10000000) { + // DDR Memory Access + uiAddress |= CACHE_ADDRESS_MASK; + memcpy((unsigned char *)(uiAddress),pucBuff,sSize); + } + else { + // Register, SPRAM, Flash + uiAddress |= UNCACHE_ADDRESS_MASK; + + if(((unsigned int )uiAddress & 0x3) || + ((unsigned int )pucBuff & 0x3) || + ((unsigned int )sSize & 0x3)) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrmalt: unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize); + iRetVal = STATUS_FAILURE; + } + else { + for (indx=0;indxrdmwrmsync); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + status = -EACCES; + goto exit; + } + + status = rdm(Adapter, uiAddress, pucBuff, sSize); + +exit: + up(&Adapter->rdmwrmsync); + return status ; +} +int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +{ + INT status = STATUS_SUCCESS ; + down(&Adapter->rdmwrmsync); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + status = -EACCES; + goto exit; + } + + status =wrm(Adapter, uiAddress, pucBuff, sSize); + +exit: + up(&Adapter->rdmwrmsync); + return status ; +} + +int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +{ + int iRetVal = STATUS_SUCCESS; + + down(&Adapter->rdmwrmsync); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + iRetVal = -EACCES; + goto exit; + } + + iRetVal = wrmalt(Adapter,uiAddress,pucBuff,size); + +exit: + up(&Adapter->rdmwrmsync); + return iRetVal; +} + +int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +{ + INT uiRetVal =STATUS_SUCCESS; + + down(&Adapter->rdmwrmsync); + + if((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus ==TRUE) || + (Adapter->bPreparingForLowPowerMode ==TRUE)) + { + uiRetVal = -EACCES; + goto exit; + } + + uiRetVal = rdmalt(Adapter,uiAddress, pucBuff, size); + +exit: + up(&Adapter->rdmwrmsync); + return uiRetVal; +} + + +VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) +{ + int clear_abort_pattern = 0,Status = 0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); + //target has woken up From Shut Down + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); + Status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); + return; + } + if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) + { + msleep(100); + InterfaceHandleShutdownModeWakeup(Adapter); + msleep(100); + } + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + Adapter->DriverState = NO_NETWORK_ENTRY; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + + Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; + Adapter->bShutStatus = FALSE; + wake_up(&Adapter->lowpower_mode_wait_queue); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); +} + +VOID SendShutModeResponse(PMINI_ADAPTER Adapter) +{ + CONTROL_MESSAGE stShutdownResponse; + UINT NVMAccess = 0,lowPwrAbortMsg = 0; + UINT Status = 0; + + memset (&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE)); + stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; + stShutdownResponse.Leader.PLength = 8;//8 bytes; + stShutdownResponse.szData[0] = LINK_UP_ACK; + stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE; + + /********************************* + **down_trylock - + ** if [ semaphore is available ] + ** acquire semaphone and return value 0 ; + ** else + ** return non-zero value ; + ** + ***********************************/ + + NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + + lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync); + + + if(NVMAccess || lowPwrAbortMsg|| atomic_read(&Adapter->TotalPacketCount)) + { + if(!NVMAccess) + up(&Adapter->NVMRdmWrmLock); + + if(!lowPwrAbortMsg) + up(&Adapter->LowPowerModeSync); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n"); + stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on. + Adapter->bPreparingForLowPowerMode = FALSE; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n"); + stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER;//ShutDown ACK + + /* Wait for the LED to TURN OFF before sending ACK response */ + if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) + { + INT iRetVal = 0; + + /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */ + Adapter->DriverState = LOWPOWER_MODE_ENTER; + wake_up(&Adapter->LEDInfo.notify_led_event); + + /* Wait for 1 SEC for LED to OFF */ + iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent,\ + Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); + + /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ + if(iRetVal <= 0) + { + stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on. + + Adapter->DriverState = NO_NETWORK_ENTRY; + wake_up(&Adapter->LEDInfo.notify_led_event); + } + } + + if(stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ACKING SHUTDOWN MODE !!!!!!!!!"); + down(&Adapter->rdmwrmsync); + Adapter->bPreparingForLowPowerMode = TRUE; + up(&Adapter->rdmwrmsync); + //Killing all URBS. +#ifndef BCM_SHM_INTERFACE + if(Adapter->bDoSuspend == TRUE) + Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); +#endif + } + else + { + Adapter->bPreparingForLowPowerMode = FALSE; + } + + if(!NVMAccess) + up(&Adapter->NVMRdmWrmLock); + + if(!lowPwrAbortMsg) + up(&Adapter->LowPowerModeSync); + } + Status = CopyBufferToControlPacket(Adapter,&stShutdownResponse); + if((Status != STATUS_SUCCESS)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n"); + Adapter->bPreparingForLowPowerMode = FALSE; + +#ifndef BCM_SHM_INTERFACE + StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); +#endif + } +} + + +void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) +{ + B_UINT32 uiResetValue = 0; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); + + if(*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) + { + HandleShutDownModeWakeup(Adapter); + } + else if(*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) + { + //Target wants to go to Shut Down Mode + //InterfacePrepareForShutdown(Adapter); + if(Adapter->chip_id == BCS220_2 || + Adapter->chip_id == BCS220_2BC || + Adapter->chip_id == BCS250_BC || + Adapter->chip_id == BCS220_3) + { + rdmalt(Adapter,HPM_CONFIG_MSW, &uiResetValue, 4); + uiResetValue |= (1<<17); + wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); + } + + SendShutModeResponse(Adapter); + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); + return; + +} + +VOID ResetCounters(PMINI_ADAPTER Adapter) +{ + + beceem_protocol_reset(Adapter); + + Adapter->CurrNumRecvDescs = 0; + Adapter->PrevNumRecvDescs = 0; + Adapter->LinkUpStatus = 0; + Adapter->LinkStatus = 0; + atomic_set(&Adapter->cntrlpktCnt,0); + atomic_set (&Adapter->TotalPacketCount,0); + Adapter->fw_download_done=FALSE; + Adapter->LinkStatus = 0; + Adapter->AutoLinkUp = FALSE; + Adapter->IdleMode = FALSE; + Adapter->bShutStatus = FALSE; + +} +S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP) +{ + UINT uiIndex=0; + for(uiIndex=0;uiIndexastFragmentedPktClassifierTable[uiIndex].bUsed)&& + (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&& + (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIP)&& + !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment) + return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry; + } + return NULL; +} + +void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo) +{ + UINT uiIndex=0; + for(uiIndex=0;uiIndexastFragmentedPktClassifierTable[uiIndex].bUsed) + { + memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex],psFragPktInfo,sizeof(S_FRAGMENTED_PACKET_INFO)); + break; + } + } + +} + +void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp) +{ + UINT uiIndex=0; + for(uiIndex=0;uiIndexastFragmentedPktClassifierTable[uiIndex].bUsed)&& + (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&& + (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIp)) + memset(&Adapter->astFragmentedPktClassifierTable[uiIndex],0,sizeof(S_FRAGMENTED_PACKET_INFO)); + } +} + +void update_per_cid_rx (PMINI_ADAPTER Adapter) +{ + UINT qindex = 0; + + if((jiffies - Adapter->liDrainCalculated) < XSECONDS) + return; + + for(qindex = 0; qindex < HiPriority; qindex++) + { + if(Adapter->PackInfo[qindex].ucDirection == 0) + { + Adapter->PackInfo[qindex].uiCurrentRxRate = + (Adapter->PackInfo[qindex].uiCurrentRxRate + + Adapter->PackInfo[qindex].uiThisPeriodRxBytes)/2; + + Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0; + } + else + { + Adapter->PackInfo[qindex].uiCurrentDrainRate = + (Adapter->PackInfo[qindex].uiCurrentDrainRate + + Adapter->PackInfo[qindex].uiThisPeriodSentBytes)/2; + + Adapter->PackInfo[qindex].uiThisPeriodSentBytes=0; + } + } + Adapter->liDrainCalculated=jiffies; +} +void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter) +{ + INT iIndex = 0; + u32 uibuff[MAX_TARGET_DSX_BUFFERS]; + + if(!atomic_read (&Adapter->uiMBupdate)) + return; + +#ifdef BCM_SHM_INTERFACE + if(rdmalt(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0) +#else + if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0) +#endif + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); + return; + } + for(iIndex = 0;iIndex < HiPriority; iIndex++) + { + if(Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) + { + if(Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS) + { + atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x \n", + Adapter->PackInfo[iIndex].usVCID_Value); + } + } + } + atomic_set (&Adapter->uiMBupdate, FALSE); +} + +void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) +{ + struct sk_buff* PacketToDrop=NULL; + struct net_device_stats* netstats=NULL; + + netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; + + spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); + + while(Adapter->PackInfo[iQIndex].FirstTxQueue && + atomic_read(&Adapter->TotalPacketCount)) + { + PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; + if(PacketToDrop && PacketToDrop->len) + { + netstats->tx_dropped++; + DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, \ + Adapter->PackInfo[iQIndex].LastTxQueue); + + Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; + Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len; + + //Adding dropped statistics + Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len; + Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; + + bcm_kfree_skb(PacketToDrop); + atomic_dec(&Adapter->TotalPacketCount); + atomic_inc(&Adapter->TxDroppedPacketCount); + + } + } + spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); + +} + +void beceem_protocol_reset (PMINI_ADAPTER Adapter) +{ + int i =0; + + if(NULL != Adapter->dev) + { + netif_carrier_off(Adapter->dev); + netif_stop_queue(Adapter->dev); + } + + Adapter->IdleMode = FALSE; + Adapter->LinkUpStatus = FALSE; + ClearTargetDSXBuffer(Adapter,0, TRUE); + //Delete All Classifier Rules + + for(i = 0;iTimerActive == TRUE) + Adapter->TimerActive = FALSE; + + memset(Adapter->astFragmentedPktClassifierTable, 0, + sizeof(S_FRAGMENTED_PACKET_INFO) * + MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); + + for(i = 0;iPackInfo[i],0,sizeof(S_MIBS_SERVICEFLOW_TABLE)); + } +} + + + +#ifdef BCM_SHM_INTERFACE + + +#define GET_GTB_DIFF(start, end) \ +( (start) < (end) )? ( (end) - (start) ) : ( ~0x0 - ( (start) - (end)) +1 ) + +void usdelay ( unsigned int a) { + unsigned int start= *(unsigned int *)0xaf8051b4; + unsigned int end = start+1; + unsigned int diff = 0; + + while(1) { + end = *(unsigned int *)0xaf8051b4; + diff = (GET_GTB_DIFF(start,end))/80; + if (diff >= a) + break; + } +} +void read_cfg_file(PMINI_ADAPTER Adapter) { + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Config File Version = 0x%x \n",Adapter->pstargetparams->m_u32CfgVersion ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Center Frequency = 0x%x \n",Adapter->pstargetparams->m_u32CenterFrequency ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band A Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandAScan ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band B Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandBScan ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band C Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandCScan ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ERTPS Options = 0x%x \n",Adapter->pstargetparams->m_u32ErtpsOptions ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PHS Enable = 0x%x \n",Adapter->pstargetparams->m_u32PHSEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Handoff Enable = 0x%x \n",Adapter->pstargetparams->m_u32HoEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved1 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved1 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved2 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved2 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MIMO Enable = 0x%x \n",Adapter->pstargetparams->m_u32MimoEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PKMv2 Enable = 0x%x \n",Adapter->pstargetparams->m_u32SecurityEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Powersaving Modes Enable = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModesEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Power Saving Mode Options = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModeOptions ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ARQ Enable = 0x%x \n",Adapter->pstargetparams->m_u32ArqEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Harq Enable = 0x%x \n",Adapter->pstargetparams->m_u32HarqEnable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"EEPROM Flag = 0x%x \n",Adapter->pstargetparams->m_u32EEPROMFlag ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Customize = 0x%x \n",Adapter->pstargetparams->m_u32Customize ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Bandwidth = 0x%x \n",Adapter->pstargetparams->m_u32ConfigBW ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ShutDown Timer Value = 0x%x \n",Adapter->pstargetparams->m_u32ShutDownInitThresholdTimer ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RadioParameter = 0x%x \n",Adapter->pstargetparams->m_u32RadioParameter ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter1 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter1 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter2 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter2 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter3 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter3 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"m_u32TestOptions = 0x%x \n",Adapter->pstargetparams->m_u32TestOptions ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperDLFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperDLFrame ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperULFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperULFrame ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corr2MacFlags = 0x%x \n",Adapter->pstargetparams->m_u32Corr2MacFlags ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig1 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig1 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig2 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig2 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig3 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig3 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig4 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig4 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig5 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig5 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig6 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig6 ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Segmented PUSC Enable = 0x%x \n",Adapter->pstargetparams->m_u32SegmentedPUSCenable ); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BamcEnable = 0x%x \n",Adapter->pstargetparams->m_u32BandAMCEnable ); +} + +#endif + + diff --git a/drivers/staging/bcm/Osal_Misc.c b/drivers/staging/bcm/Osal_Misc.c new file mode 100644 index 000000000000..feefd20a5291 --- /dev/null +++ b/drivers/staging/bcm/Osal_Misc.c @@ -0,0 +1,27 @@ + /*++ + + Copyright (c) Beceem Communications Inc. + + Module Name: + WIN_Misc.c + + Abstract: + Implements the Miscelanneous OS Construts + Linked Lists + Dispatcher Objects(Events,Semaphores,Spin Locks and the like) + Files + + Revision History: + Who When What + -------- -------- ---------------------------------------------- + Name Date Created/reviewed/modified + Rajeev 24/1/08 Created + Notes: + + --*/ +#include "headers.h" + +bool OsalMemCompare(void *dest, void *src, UINT len) +{ + return (memcmp(src, dest, len)); +} diff --git a/drivers/staging/bcm/PHSDefines.h b/drivers/staging/bcm/PHSDefines.h new file mode 100644 index 000000000000..9889a993ad5b --- /dev/null +++ b/drivers/staging/bcm/PHSDefines.h @@ -0,0 +1,125 @@ +#ifndef BCM_PHS_DEFINES_H +#define BCM_PHS_DEFINES_H + +#define PHS_INVALID_TABLE_INDEX 0xffffffff + +/************************* MACROS **********************************************/ +#define PHS_MEM_TAG '_SHP' + + + +//PHS Defines +#define STATUS_PHS_COMPRESSED 0xa1 +#define STATUS_PHS_NOCOMPRESSION 0xa2 +#define APPLY_PHS 1 +#define MAX_NO_BIT 7 +#define ZERO_PHSI 0 +#define VERIFY 0 +#define SIZE_MULTIPLE_32 4 +#define UNCOMPRESSED_PACKET 0 +#define DYNAMIC 0 +#define SUPPRESS 0x80 +#define NO_CLASSIFIER_MATCH 0 +#define SEND_PACKET_UNCOMPRESSED 0 +#define PHSI_IS_ZERO 0 +#define PHSI_LEN 1 +#define ERROR_LEN 0 +#define PHS_BUFFER_SIZE 1532 + + +//#define MAX_PHS_LENGTHS 100 +#define MAX_PHSRULE_PER_SF 20 +#define MAX_SERVICEFLOWS 17 + +//PHS Error Defines +#define PHS_SUCCESS 0 +#define ERR_PHS_INVALID_DEVICE_EXETENSION 0x800 +#define ERR_PHS_INVALID_PHS_RULE 0x801 +#define ERR_PHS_RULE_ALREADY_EXISTS 0x802 +#define ERR_SF_MATCH_FAIL 0x803 +#define ERR_INVALID_CLASSIFIERTABLE_FOR_SF 0x804 +#define ERR_SFTABLE_FULL 0x805 +#define ERR_CLSASSIFIER_TABLE_FULL 0x806 +#define ERR_PHSRULE_MEMALLOC_FAIL 0x807 +#define ERR_CLSID_MATCH_FAIL 0x808 +#define ERR_PHSRULE_MATCH_FAIL 0x809 + +typedef struct _S_PHS_RULE +{ + /// brief 8bit PHSI Of The Service Flow + B_UINT8 u8PHSI; + /// brief PHSF Of The Service Flow + B_UINT8 u8PHSFLength; + B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; + /// brief PHSM Of The Service Flow + B_UINT8 u8PHSMLength; + B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; + /// brief 8bit PHSS Of The Service Flow + B_UINT8 u8PHSS; + /// brief 8bit PHSV Of The Service Flow + B_UINT8 u8PHSV; + //Reference Count for this PHS Rule + B_UINT8 u8RefCnt; + //Flag to Store Unclassified PHS rules only in DL + B_UINT8 bUnclassifiedPHSRule; + + B_UINT8 u8Reserved[3]; + + LONG PHSModifiedBytes; + ULONG PHSModifiedNumPackets; + ULONG PHSErrorNumPackets; +}S_PHS_RULE; + + +typedef enum _E_CLASSIFIER_ENTRY_CONTEXT +{ + eActiveClassifierRuleContext, + eOldClassifierRuleContext +}E_CLASSIFIER_ENTRY_CONTEXT; + +typedef struct _S_CLASSIFIER_ENTRY +{ + B_UINT8 bUsed; + B_UINT16 uiClassifierRuleId; + B_UINT8 u8PHSI; + S_PHS_RULE *pstPhsRule; + B_UINT8 bUnclassifiedPHSRule; + +}S_CLASSIFIER_ENTRY; + + +typedef struct _S_CLASSIFIER_TABLE +{ + B_UINT16 uiTotalClassifiers; + S_CLASSIFIER_ENTRY stActivePhsRulesList[MAX_PHSRULE_PER_SF]; + S_CLASSIFIER_ENTRY stOldPhsRulesList[MAX_PHSRULE_PER_SF]; + B_UINT16 uiOldestPhsRuleIndex; + +}S_CLASSIFIER_TABLE; + + +typedef struct _S_SERVICEFLOW_ENTRY +{ + B_UINT8 bUsed; + B_UINT16 uiVcid; + S_CLASSIFIER_TABLE *pstClassifierTable; +}S_SERVICEFLOW_ENTRY; + +typedef struct _S_SERVICEFLOW_TABLE +{ + B_UINT16 uiTotalServiceFlows; + S_SERVICEFLOW_ENTRY stSFList[MAX_SERVICEFLOWS]; + +}S_SERVICEFLOW_TABLE; + + +typedef struct _PHS_DEVICE_EXTENSION +{ + /* PHS Specific data*/ + S_SERVICEFLOW_TABLE *pstServiceFlowPhsRulesTable; + void *CompressedTxBuffer; + void *UnCompressedRxBuffer; +}PHS_DEVICE_EXTENSION,*PPHS_DEVICE_EXTENSION; + + +#endif diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c new file mode 100644 index 000000000000..8ba8489afc2c --- /dev/null +++ b/drivers/staging/bcm/PHSModule.c @@ -0,0 +1,1641 @@ +#include "headers.h" + +#define IN +#define OUT + +void DumpDataPacketHeader(PUCHAR pPkt); + +/* +Function: PHSTransmit + +Description: This routine handle PHS(Payload Header Suppression for Tx path. + It extracts a fragment of the NDIS_PACKET containing the header + to be suppressed.It then supresses the header by invoking PHS exported compress routine. + The header data after supression is copied back to the NDIS_PACKET. + + +Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context + IN Packet - NDIS packet containing data to be transmitted + IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to + identify PHS rule to be applied. + B_UINT16 uiClassifierRuleID - Classifier Rule ID + BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. + +Return: STATUS_SUCCESS - If the send was successful. + Other - If an error occured. +*/ + +int PHSTransmit(PMINI_ADAPTER Adapter, + struct sk_buff **pPacket, + USHORT Vcid, + B_UINT16 uiClassifierRuleID, + BOOLEAN bHeaderSuppressionEnabled, + UINT *PacketLen, + UCHAR bEthCSSupport) +{ + + //PHS Sepcific + UINT unPHSPktHdrBytesCopied = 0; + UINT unPhsOldHdrSize = 0; + UINT unPHSNewPktHeaderLen = 0; + /* Pointer to PHS IN Hdr Buffer */ + PUCHAR pucPHSPktHdrInBuf = + Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf; + /* Pointer to PHS OUT Hdr Buffer */ + PUCHAR pucPHSPktHdrOutBuf = + Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf; + UINT usPacketType; + UINT BytesToRemove=0; + BOOLEAN bPHSI = 0; + LONG ulPhsStatus = 0; + UINT numBytesCompressed = 0; + struct sk_buff *newPacket = NULL; + struct sk_buff *Packet = *pPacket; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit"); + + if(!bEthCSSupport) + BytesToRemove=ETH_HLEN; + /* + Accumulate the header upto the size we support supression + from NDIS packet + */ + + usPacketType=((struct ethhdr *)(Packet->data))->h_proto; + + + pucPHSPktHdrInBuf = Packet->data + BytesToRemove; + //considering data after ethernet header + if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) + { + + unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); + } + else + { + unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; + } + + if( (unPHSPktHdrBytesCopied > 0 ) && + (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) + { + + + //DumpDataPacketHeader(pucPHSPktHdrInBuf); + + // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. + // Suppress only if IP Header and PHS Enabled For the Service Flow + if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) || + (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && + (bHeaderSuppressionEnabled)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID); + + + unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; + ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, + Vcid, + uiClassifierRuleID, + pucPHSPktHdrInBuf, + pucPHSPktHdrOutBuf, + &unPhsOldHdrSize, + &unPHSNewPktHeaderLen); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen); + + if(unPHSNewPktHeaderLen == unPhsOldHdrSize) + { + if( ulPhsStatus == STATUS_PHS_COMPRESSED) + bPHSI = *pucPHSPktHdrOutBuf; + ulPhsStatus = STATUS_PHS_NOCOMPRESSION; + } + + if( ulPhsStatus == STATUS_PHS_COMPRESSED) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed"); + + if(skb_cloned(Packet)) + { + newPacket = skb_copy(Packet, GFP_ATOMIC); + + if(newPacket == NULL) + return STATUS_FAILURE; + + bcm_kfree_skb(Packet); + *pPacket = Packet = newPacket; + pucPHSPktHdrInBuf = Packet->data + BytesToRemove; + } + + numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN); + + OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); + OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); + skb_pull(Packet, numBytesCompressed); + + return STATUS_SUCCESS; + } + + else + { + //if one byte headroom is not available, increase it through skb_cow + if(!(skb_headroom(Packet) > 0)) + { + if(skb_cow(Packet, 1)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n"); + return STATUS_FAILURE; + } + } + skb_push(Packet, 1); + + // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it. + *(Packet->data + BytesToRemove) = bPHSI; + return STATUS_SUCCESS; + } + } + else + { + if(!bHeaderSuppressionEnabled) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n"); + } + + return STATUS_SUCCESS; + } + } + + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); + return STATUS_SUCCESS; +} + +int PHSRecieve(PMINI_ADAPTER Adapter, + USHORT usVcid, + struct sk_buff *packet, + UINT *punPacketLen, + UCHAR *pucEthernetHdr, + UINT bHeaderSuppressionEnabled) +{ + u32 nStandardPktHdrLen = 0; + u32 nTotalsupressedPktHdrBytes = 0; + int ulPhsStatus = 0; + PUCHAR pucInBuff = NULL ; + UINT TotalBytesAdded = 0; + if(!bHeaderSuppressionEnabled) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet"); + return ulPhsStatus; + } + + pucInBuff = packet->data; + + //Restore PHS suppressed header + nStandardPktHdrLen = packet->len; + ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, + usVcid, + pucInBuff, + Adapter->ucaPHSPktRestoreBuf, + &nTotalsupressedPktHdrBytes, + &nStandardPktHdrLen); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", + nTotalsupressedPktHdrBytes,nStandardPktHdrLen); + + if(ulPhsStatus != STATUS_PHS_COMPRESSED) + { + skb_pull(packet, 1); + return STATUS_SUCCESS; + } + else + { + TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN; + if(TotalBytesAdded) + { + if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) + skb_push(packet, TotalBytesAdded); + else + { + if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n"); + return STATUS_FAILURE; + } + + skb_push(packet, TotalBytesAdded); + } + } + + OsalMemMove(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen); + } + + return STATUS_SUCCESS; +} + +void DumpDataPacketHeader(PUCHAR pPkt) +{ + struct iphdr *iphd = (struct iphdr*)pPkt; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src IP : %x \n",iphd->saddr); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr); + +} + +void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet"); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen); +} + +//----------------------------------------------------------------------------- +// Procedure: phs_init +// +// Description: This routine is responsible for allocating memory for classifier and +// PHS rules. +// +// Arguments: +// pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc +// +// Returns: +// TRUE(1) -If allocation of memory was success full. +// FALSE -If allocation of memory fails. +//----------------------------------------------------------------------------- +int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) +{ + int i; + S_SERVICEFLOW_TABLE *pstServiceFlowTable; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function "); + + if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable) + return -EINVAL; + + pPhsdeviceExtension->pstServiceFlowPhsRulesTable = + (S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE), + PHS_MEM_TAG); + + if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable) + { + OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable, + sizeof(S_SERVICEFLOW_TABLE)); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); + return -ENOMEM; + } + + pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; + for(i=0;istSFList[i]; + sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc( + sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG); + if(sServiceFlow.pstClassifierTable) + { + OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE)); + pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + free_phs_serviceflow_rules(pPhsdeviceExtension-> + pstServiceFlowPhsRulesTable); + pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; + return -ENOMEM; + } + } + + + pPhsdeviceExtension->CompressedTxBuffer = + OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG); + + if(pPhsdeviceExtension->CompressedTxBuffer == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); + pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; + return -ENOMEM; + } + + pPhsdeviceExtension->UnCompressedRxBuffer = + OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG); + if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE); + free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); + pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; + return -ENOMEM; + } + + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull"); + return STATUS_SUCCESS; +} + + +int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt) +{ + if(pPHSDeviceExt->pstServiceFlowPhsRulesTable) + { + free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); + pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; + } + + if(pPHSDeviceExt->CompressedTxBuffer) + { + OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE); + pPHSDeviceExt->CompressedTxBuffer = NULL; + } + if(pPHSDeviceExt->UnCompressedRxBuffer) + { + OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE); + pPHSDeviceExt->UnCompressedRxBuffer = NULL; + } + + return 0; +} + + + +//PHS functions +/*++ +PhsUpdateClassifierRule + +Routine Description: + Exported function to add or modify a PHS Rule. + +Arguments: + IN void* pvContext - PHS Driver Specific Context + IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. + IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. + +Return Value: + + 0 if successful, + >0 Error. + +--*/ +ULONG PhsUpdateClassifierRule(IN void* pvContext, + IN B_UINT16 uiVcid , + IN B_UINT16 uiClsId , + IN S_PHS_RULE *psPhsRule, + IN B_UINT8 u8AssociatedPHSI) +{ + ULONG lStatus =0; + UINT nSFIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + + + PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n"); + + if(pDeviceExtension == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n"); + return ERR_PHS_INVALID_DEVICE_EXETENSION; + } + + + if(u8AssociatedPHSI == 0) + { + return ERR_PHS_INVALID_PHS_RULE; + } + + /* Retrieve the SFID Entry Index for requested Service Flow */ + + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, + uiVcid,&pstServiceFlowEntry); + + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + /* This is a new SF. Create a mapping entry for this */ + lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, + pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); + return lStatus; + } + + /* SF already Exists Add PHS Rule to existing SF */ + lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, + pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); + + return lStatus; +} + +/*++ +PhsDeletePHSRule + +Routine Description: + Deletes the specified phs Rule within Vcid + +Arguments: + IN void* pvContext - PHS Driver Specific Context + IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. + +Return Value: + + 0 if successful, + >0 Error. + +--*/ + +ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) +{ + ULONG lStatus =0; + UINT nSFIndex =0, nClsidIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + + PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); + + if(pDeviceExtension) + { + + //Retrieve the SFID Entry Index for requested Service Flow + nSFIndex = GetServiceFlowEntry(pDeviceExtension + ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry); + + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); + return ERR_SF_MATCH_FAIL; + } + + pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; + if(pstClassifierRulesTable) + { + for(nClsidIndex=0;nClsidIndexstActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) + { + if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule->u8PHSI == u8PHSI) + { + if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule + ->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule + ->u8RefCnt--; + if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt) + OsalMemFree(pstClassifierRulesTable + ->stActivePhsRulesList[nClsidIndex].pstPhsRule, + sizeof(S_PHS_RULE)); + OsalZeroMemory(&pstClassifierRulesTable + ->stActivePhsRulesList[nClsidIndex], + sizeof(S_CLASSIFIER_ENTRY)); + } + } + } + } + + } + return lStatus; +} + +/*++ +PhsDeleteClassifierRule + +Routine Description: + Exported function to Delete a PHS Rule for the SFID,CLSID Pair. + +Arguments: + IN void* pvContext - PHS Driver Specific Context + IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. + +Return Value: + + 0 if successful, + >0 Error. + +--*/ +ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId) +{ + ULONG lStatus =0; + UINT nSFIndex =0, nClsidIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; + + if(pDeviceExtension) + { + //Retrieve the SFID Entry Index for requested Service Flow + nSFIndex = GetServiceFlowEntry(pDeviceExtension + ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n"); + return ERR_SF_MATCH_FAIL; + } + + nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, + uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); + if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) + { + if(pstClassifierEntry->pstPhsRule) + { + if(pstClassifierEntry->pstPhsRule->u8RefCnt) + pstClassifierEntry->pstPhsRule->u8RefCnt--; + if(0==pstClassifierEntry->pstPhsRule->u8RefCnt) + OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); + + } + OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY)); + } + + nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, + uiClsId,eOldClassifierRuleContext,&pstClassifierEntry); + + if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) + { + if(pstClassifierEntry->pstPhsRule) + //Delete the classifier entry + OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); + OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY)); + } + } + return lStatus; +} + +/*++ +PhsDeleteSFRules + +Routine Description: + Exported function to Delete a all PHS Rules for the SFID. + +Arguments: + IN void* pvContext - PHS Driver Specific Context + IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted + +Return Value: + + 0 if successful, + >0 Error. + +--*/ +ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) +{ + + ULONG lStatus =0; + UINT nSFIndex =0, nClsidIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n"); + + if(pDeviceExtension) + { + //Retrieve the SFID Entry Index for requested Service Flow + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, + uiVcid,&pstServiceFlowEntry); + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); + return ERR_SF_MATCH_FAIL; + } + + pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; + if(pstClassifierRulesTable) + { + for(nClsidIndex=0;nClsidIndexstActivePhsRulesList[nClsidIndex].pstPhsRule) + { + if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt--; + if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt) + OsalMemFree(pstClassifierRulesTable + ->stActivePhsRulesList[nClsidIndex].pstPhsRule, + sizeof(S_PHS_RULE)); + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] + .pstPhsRule = NULL; + } + OsalZeroMemory(&pstClassifierRulesTable + ->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY)); + if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) + { + if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt--; + if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] + .pstPhsRule->u8RefCnt) + OsalMemFree(pstClassifierRulesTable + ->stOldPhsRulesList[nClsidIndex].pstPhsRule, + sizeof(S_PHS_RULE)); + pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] + .pstPhsRule = NULL; + } + OsalZeroMemory(&pstClassifierRulesTable + ->stOldPhsRulesList[nClsidIndex], + sizeof(S_CLASSIFIER_ENTRY)); + } + } + pstServiceFlowEntry->bUsed = FALSE; + pstServiceFlowEntry->uiVcid = 0; + + } + + return lStatus; +} + + +/*++ +PhsCompress + +Routine Description: + Exported function to compress the data using PHS. + +Arguments: + IN void* pvContext - PHS Driver Specific Context. + IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies. + IN UINT uiClsId - The Classifier ID to which current packet header compression applies. + IN void *pvInputBuffer - The Input buffer containg packet header data + IN void *pvOutputBuffer - The output buffer returned by this function after PHS + IN UINT *pOldHeaderSize - The actual size of the header before PHS + IN UINT *pNewHeaderSize - The new size of the header after applying PHS + +Return Value: + + 0 if successful, + >0 Error. + +--*/ +ULONG PhsCompress(IN void* pvContext, + IN B_UINT16 uiVcid, + IN B_UINT16 uiClsId, + IN void *pvInputBuffer, + OUT void *pvOutputBuffer, + OUT UINT *pOldHeaderSize, + OUT UINT *pNewHeaderSize ) +{ + UINT nSFIndex =0, nClsidIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; + S_PHS_RULE *pstPhsRule = NULL; + ULONG lStatus =0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + + + PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; + + + if(pDeviceExtension == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n"); + lStatus = STATUS_PHS_NOCOMPRESSION ; + return lStatus; + + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n"); + + + //Retrieve the SFID Entry Index for requested Service Flow + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, + uiVcid,&pstServiceFlowEntry); + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n"); + lStatus = STATUS_PHS_NOCOMPRESSION ; + return lStatus; + } + + nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, + uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry); + + if(nClsidIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n"); + lStatus = STATUS_PHS_NOCOMPRESSION ; + return lStatus; + } + + + //get rule from SF id,Cls ID pair and proceed + pstPhsRule = pstClassifierEntry->pstPhsRule; + + if(!ValidatePHSRuleComplete(pstPhsRule)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n"); + lStatus = STATUS_PHS_NOCOMPRESSION ; + return lStatus; + } + + //Compress Packet + lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer, + (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize); + + if(lStatus == STATUS_PHS_COMPRESSED) + { + pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1; + pstPhsRule->PHSModifiedNumPackets++; + } + else + pstPhsRule->PHSErrorNumPackets++; + + return lStatus; +} + +/*++ +PhsDeCompress + +Routine Description: + Exported function to restore the packet header in Rx path. + +Arguments: + IN void* pvContext - PHS Driver Specific Context. + IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies. + IN void *pvInputBuffer - The Input buffer containg suppressed packet header data + OUT void *pvOutputBuffer - The output buffer returned by this function after restoration + OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter. + +Return Value: + + 0 if successful, + >0 Error. + +--*/ +ULONG PhsDeCompress(IN void* pvContext, + IN B_UINT16 uiVcid, + IN void *pvInputBuffer, + OUT void *pvOutputBuffer, + OUT UINT *pInHeaderSize, + OUT UINT *pOutHeaderSize ) +{ + UINT nSFIndex =0, nPhsRuleIndex =0 ; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_PHS_RULE *pstPhsRule = NULL; + UINT phsi; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PPHS_DEVICE_EXTENSION pDeviceExtension= + (PPHS_DEVICE_EXTENSION)pvContext; + + *pInHeaderSize = 0; + + if(pDeviceExtension == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n"); + return ERR_PHS_INVALID_DEVICE_EXETENSION; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n"); + + phsi = *((unsigned char *)(pvInputBuffer)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi); + if(phsi == UNCOMPRESSED_PACKET ) + { + return STATUS_PHS_NOCOMPRESSION; + } + + //Retrieve the SFID Entry Index for requested Service Flow + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, + uiVcid,&pstServiceFlowEntry); + if(nSFIndex == PHS_INVALID_TABLE_INDEX) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n"); + return ERR_SF_MATCH_FAIL; + } + + nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi, + eActiveClassifierRuleContext,&pstPhsRule); + if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) + { + //Phs Rule does not exist in active rules table. Lets try in the old rules table. + nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, + phsi,eOldClassifierRuleContext,&pstPhsRule); + if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) + { + return ERR_PHSRULE_MATCH_FAIL; + } + + } + + *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, + (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize); + + pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; + + pstPhsRule->PHSModifiedNumPackets++; + return STATUS_PHS_COMPRESSED; +} + + +//----------------------------------------------------------------------------- +// Procedure: free_phs_serviceflow_rules +// +// Description: This routine is responsible for freeing memory allocated for PHS rules. +// +// Arguments: +// rules - ptr to S_SERVICEFLOW_TABLE structure. +// +// Returns: +// Does not return any value. +//----------------------------------------------------------------------------- + +void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) +{ + int i,j; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); + if(psServiceFlowRulesTable) + { + for(i=0;istSFList[i]; + S_CLASSIFIER_TABLE *pstClassifierRulesTable = + stServiceFlowEntry.pstClassifierTable; + + if(pstClassifierRulesTable) + { + for(j=0;jstActivePhsRulesList[j].pstPhsRule) + { + if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule + ->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule + ->u8RefCnt--; + if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule + ->u8RefCnt) + OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j]. + pstPhsRule, sizeof(S_PHS_RULE)); + pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; + } + if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) + { + if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule + ->u8RefCnt) + pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule + ->u8RefCnt--; + if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule + ->u8RefCnt) + OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j] + .pstPhsRule,sizeof(S_PHS_RULE)); + pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL; + } + } + OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE)); + stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; + } + } + } + + OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE)); + psServiceFlowRulesTable = NULL; +} + + + +BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule) +{ + if(psPhsRule) + { + if(!psPhsRule->u8PHSI) + { + // PHSI is not valid + return FALSE; + } + + if(!psPhsRule->u8PHSS) + { + //PHSS Is Undefined + return FALSE; + } + + //Check if PHSF is defines for the PHS Rule + if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF + { + return FALSE; + } + return TRUE; + } + else + { + return FALSE; + } +} + +UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable, + IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry) +{ + int i; + for(i=0;istSFList[i].bUsed) + { + if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid) + { + *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i]; + return i; + } + } + } + + *ppstServiceFlowEntry = NULL; + return PHS_INVALID_TABLE_INDEX; +} + + +UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, + IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, + OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry) +{ + int i; + S_CLASSIFIER_ENTRY *psClassifierRules = NULL; + for(i=0;istActivePhsRulesList[i]; + } + else + { + psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i]; + } + + if(psClassifierRules->bUsed) + { + if(psClassifierRules->uiClassifierRuleId == uiClsid) + { + *ppstClassifierEntry = psClassifierRules; + return i; + } + } + + } + + *ppstClassifierEntry = NULL; + return PHS_INVALID_TABLE_INDEX; +} + +UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, + IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, + OUT S_PHS_RULE **ppstPhsRule) +{ + int i; + S_CLASSIFIER_ENTRY *pstClassifierRule = NULL; + for(i=0;istActivePhsRulesList[i]; + } + else + { + pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i]; + } + if(pstClassifierRule->bUsed) + { + if(pstClassifierRule->u8PHSI == uiPHSI) + { + *ppstPhsRule = pstClassifierRule->pstPhsRule; + return i; + } + } + + } + + *ppstPhsRule = NULL; + return PHS_INVALID_TABLE_INDEX; +} + +UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId, + IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule, + B_UINT8 u8AssociatedPHSI) +{ + + S_CLASSIFIER_TABLE *psaClassifiertable = NULL; + UINT uiStatus = 0; + int iSfIndex; + BOOLEAN bFreeEntryFound =FALSE; + //Check for a free entry in SFID table + for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++) + { + if(!psServiceFlowTable->stSFList[iSfIndex].bUsed) + { + bFreeEntryFound = TRUE; + break; + } + } + + if(!bFreeEntryFound) + return ERR_SFTABLE_FULL; + + + psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable; + uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule, + eActiveClassifierRuleContext,u8AssociatedPHSI); + if(uiStatus == PHS_SUCCESS) + { + //Add entry at free index to the SF + psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE; + psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid; + } + + return uiStatus; + +} + +UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, + IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry, + S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI) +{ + S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; + UINT uiStatus =PHS_SUCCESS; + UINT nClassifierIndex = 0; + S_CLASSIFIER_TABLE *psaClassifiertable = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>"); + + /* Check if the supplied Classifier already exists */ + nClassifierIndex =GetClassifierEntry( + pstServiceFlowEntry->pstClassifierTable,uiClsId, + eActiveClassifierRuleContext,&pstClassifierEntry); + if(nClassifierIndex == PHS_INVALID_TABLE_INDEX) + { + /* + The Classifier doesn't exist. So its a new classifier being added. + Add new entry to associate PHS Rule to the Classifier + */ + + uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable, + psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI); + return uiStatus; + } + + /* + The Classifier exists.The PHS Rule for this classifier + is being modified + */ + if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) + { + if(pstClassifierEntry->pstPhsRule == NULL) + return ERR_PHS_INVALID_PHS_RULE; + + /* + This rule already exists if any fields are changed for this PHS + rule update them. + */ + /* If any part of PHSF is valid then we update PHSF */ + if(psPhsRule->u8PHSFLength) + { + //update PHSF + OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF, + psPhsRule->u8PHSF , MAX_PHS_LENGTHS); + } + if(psPhsRule->u8PHSFLength) + { + //update PHSFLen + pstClassifierEntry->pstPhsRule->u8PHSFLength = + psPhsRule->u8PHSFLength; + } + if(psPhsRule->u8PHSMLength) + { + //update PHSM + OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM, + psPhsRule->u8PHSM, MAX_PHS_LENGTHS); + } + if(psPhsRule->u8PHSMLength) + { + //update PHSM Len + pstClassifierEntry->pstPhsRule->u8PHSMLength = + psPhsRule->u8PHSMLength; + } + if(psPhsRule->u8PHSS) + { + //update PHSS + pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS; + } + + //update PHSV + pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; + + } + else + { + /* + A new rule is being set for this classifier. + */ + uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry, + psaClassifiertable, psPhsRule, u8AssociatedPHSI); + } + + + + return uiStatus; +} + +UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, + S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, + E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI) +{ + UINT iClassifierIndex = 0; + BOOLEAN bFreeEntryFound = FALSE; + S_CLASSIFIER_ENTRY *psClassifierRules = NULL; + UINT nStatus = PHS_SUCCESS; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule"); + if(psaClassifiertable == NULL) + { + return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; + } + + if(eClsContext == eOldClassifierRuleContext) + { + /* If An Old Entry for this classifier ID already exists in the + old rules table replace it. */ + + iClassifierIndex = + GetClassifierEntry(psaClassifiertable, uiClsId, + eClsContext,&psClassifierRules); + if(iClassifierIndex != PHS_INVALID_TABLE_INDEX) + { + /* + The Classifier already exists in the old rules table + Lets replace the old classifier with the new one. + */ + bFreeEntryFound = TRUE; + } + } + + if(!bFreeEntryFound) + { + /* + Continue to search for a free location to add the rule + */ + for(iClassifierIndex = 0; iClassifierIndex < + MAX_PHSRULE_PER_SF; iClassifierIndex++) + { + if(eClsContext == eActiveClassifierRuleContext) + { + psClassifierRules = + &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; + } + else + { + psClassifierRules = + &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + } + + if(!psClassifierRules->bUsed) + { + bFreeEntryFound = TRUE; + break; + } + } + } + + if(!bFreeEntryFound) + { + if(eClsContext == eActiveClassifierRuleContext) + { + return ERR_CLSASSIFIER_TABLE_FULL; + } + else + { + //Lets replace the oldest rule if we are looking in old Rule table + if(psaClassifiertable->uiOldestPhsRuleIndex >= + MAX_PHSRULE_PER_SF) + { + psaClassifiertable->uiOldestPhsRuleIndex =0; + } + + iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; + psClassifierRules = + &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + + (psaClassifiertable->uiOldestPhsRuleIndex)++; + } + } + + if(eClsContext == eOldClassifierRuleContext) + { + if(psClassifierRules->pstPhsRule == NULL) + { + psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc + (sizeof(S_PHS_RULE),PHS_MEM_TAG); + + if(NULL == psClassifierRules->pstPhsRule) + return ERR_PHSRULE_MEMALLOC_FAIL; + } + + psClassifierRules->bUsed = TRUE; + psClassifierRules->uiClassifierRuleId = uiClsId; + psClassifierRules->u8PHSI = psPhsRule->u8PHSI; + psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule; + + /* Update The PHS rule */ + OsalMemMove(psClassifierRules->pstPhsRule, + psPhsRule, sizeof(S_PHS_RULE)); + } + else + { + nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules, + psaClassifiertable,psPhsRule,u8AssociatedPHSI); + } + return nStatus; +} + + +UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, + IN S_CLASSIFIER_ENTRY *pstClassifierEntry, + S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, + B_UINT8 u8AssociatedPHSI) +{ + S_PHS_RULE *pstAddPhsRule = NULL; + UINT nPhsRuleIndex = 0; + BOOLEAN bPHSRuleOrphaned = FALSE; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + psPhsRule->u8RefCnt =0; + + /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ + bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable, + pstClassifierEntry->pstPhsRule); + + //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF + nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI, + eActiveClassifierRuleContext, &pstAddPhsRule); + if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); + + if(psPhsRule->u8PHSI == 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); + return ERR_PHS_INVALID_PHS_RULE; + } + //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId + if(FALSE == bPHSRuleOrphaned) + { + pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG); + if(NULL == pstClassifierEntry->pstPhsRule) + { + return ERR_PHSRULE_MEMALLOC_FAIL; + } + } + OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); + + } + else + { + //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); + if(bPHSRuleOrphaned) + { + if(pstClassifierEntry->pstPhsRule) + { + //Just Free the PHS Rule as Ref Count is Zero + OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); + pstClassifierEntry->pstPhsRule = NULL; + + } + + } + pstClassifierEntry->pstPhsRule = pstAddPhsRule; + + } + pstClassifierEntry->bUsed = TRUE; + pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; + pstClassifierEntry->uiClassifierRuleId = uiClsId; + pstClassifierEntry->pstPhsRule->u8RefCnt++; + pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; + + return PHS_SUCCESS; + +} + +BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule) +{ + if(pstPhsRule==NULL) + return FALSE; + if(pstPhsRule->u8RefCnt) + pstPhsRule->u8RefCnt--; + if(0==pstPhsRule->u8RefCnt) + { + /*if(pstPhsRule->u8PHSI) + //Store the currently active rule into the old rules list + CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/ + return TRUE; + } + else + { + return FALSE; + } +} + +void DumpBuffer(PVOID BuffVAddress, int xferSize) +{ + int i; + int iPrintLength; + PUCHAR temp=(PUCHAR)BuffVAddress; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + iPrintLength=(xferSize<32?xferSize:32); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n"); + + for (i=0;i < iPrintLength;i++) { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n"); +} + + +void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension) +{ + int i,j,k,l; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n"); + for(i=0;ipstServiceFlowPhsRulesTable->stSFList[i]; + if(stServFlowEntry.bUsed) + { + for(j=0;jstActivePhsRulesList[j]; + if(stClsEntry.bUsed) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n"); + } + else + { + stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j]; + if(stClsEntry.bUsed) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n"); + } + if(stClsEntry.bUsed) + { + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); + for(k=0;ku8PHSFLength;k++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); + for(k=0;ku8PHSMLength;k++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); + } + } + } + } + } +} + + +//----------------------------------------------------------------------------- +// Procedure: phs_decompress +// +// Description: This routine restores the static fields within the packet. +// +// Arguments: +// in_buf - ptr to incoming packet buffer. +// out_buf - ptr to output buffer where the suppressed header is copied. +// decomp_phs_rules - ptr to PHS rule. +// header_size - ptr to field which holds the phss or phsf_length. +// +// Returns: +// size -The number of bytes of dynamic fields present with in the incoming packet +// header. +// 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed. +//----------------------------------------------------------------------------- + +int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, + S_PHS_RULE *decomp_phs_rules,UINT *header_size) +{ + int phss,size=0; + S_PHS_RULE *tmp_memb; + int bit,i=0; + unsigned char *phsf,*phsm; + int in_buf_len = *header_size-1; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + in_buf++; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n"); + *header_size = 0; + + if((decomp_phs_rules == NULL )) + return 0; + + + tmp_memb = decomp_phs_rules; + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); + //*header_size = tmp_memb->u8PHSFLength; + phss = tmp_memb->u8PHSS; + phsf = tmp_memb->u8PHSF; + phsm = tmp_memb->u8PHSM; + + if(phss > MAX_PHS_LENGTHS) + phss = MAX_PHS_LENGTHS; + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); + while((phss > 0) && (size < in_buf_len)) + { + bit = ((*phsm << i)& SUPPRESS); + + if(bit == SUPPRESS) + { + *out_buf = *phsf; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", + phss,*phsf,*out_buf); + } + else + { + *out_buf = *in_buf; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", + phss,*in_buf,*out_buf); + in_buf++; + size++; + } + out_buf++; + phsf++; + phss--; + i++; + *header_size=*header_size + 1; + + if(i > MAX_NO_BIT) + { + i=0; + phsm++; + } + } + return size; +} + + + + +//----------------------------------------------------------------------------- +// Procedure: phs_compress +// +// Description: This routine suppresses the static fields within the packet.Before +// that it will verify the fields to be suppressed with the corresponding fields in the +// phsf. For verification it checks the phsv field of PHS rule. If set and verification +// succeeds it suppresses the field.If any one static field is found different none of +// the static fields are suppressed then the packet is sent as uncompressed packet with +// phsi=0. +// +// Arguments: +// phs_rule - ptr to PHS rule. +// in_buf - ptr to incoming packet buffer. +// out_buf - ptr to output buffer where the suppressed header is copied. +// header_size - ptr to field which holds the phss. +// +// Returns: +// size-The number of bytes copied into the output buffer i.e dynamic fields +// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. +//----------------------------------------------------------------------------- +int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf + ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) +{ + unsigned char *old_addr = out_buf; + int supress = 0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if(phs_rule == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!"); + *out_buf = ZERO_PHSI; + return STATUS_PHS_NOCOMPRESSION; + } + + + if(phs_rule->u8PHSS <= *new_header_size) + { + *header_size = phs_rule->u8PHSS; + } + else + { + *header_size = *new_header_size; + } + //To copy PHSI + out_buf++; + supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, + phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size); + + if(supress == STATUS_PHS_COMPRESSED) + { + *old_addr = (unsigned char)phs_rule->u8PHSI; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI); + } + else + { + *old_addr = ZERO_PHSI; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed"); + } + return supress; +} + + +//----------------------------------------------------------------------------- +// Procedure: verify_suppress_phsf +// +// Description: This routine verifies the fields of the packet and if all the +// static fields are equal it adds the phsi of that PHS rule.If any static +// field differs it woun't suppress any field. +// +// Arguments: +// rules_set - ptr to classifier_rules. +// in_buffer - ptr to incoming packet buffer. +// out_buffer - ptr to output buffer where the suppressed header is copied. +// phsf - ptr to phsf. +// phsm - ptr to phsm. +// phss - variable holding phss. +// +// Returns: +// size-The number of bytes copied into the output buffer i.e dynamic fields. +// 0 -Packet has failed the verification. +//----------------------------------------------------------------------------- + + int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, + unsigned char *phsf,unsigned char *phsm,unsigned int phss, + unsigned int phsv,UINT* new_header_size) +{ + unsigned int size=0; + int bit,i=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); + + + if(phss>(*new_header_size)) + { + phss=*new_header_size; + } + while(phss > 0) + { + bit = ((*phsm << i)& SUPPRESS); + if(bit == SUPPRESS) + { + + if(*in_buffer != *phsf) + { + if(phsv == VERIFY) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf); + return STATUS_PHS_NOCOMPRESSION; + } + } + else + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf); + } + else + { + *out_buffer = *in_buffer; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer); + out_buffer++; + size++; + } + in_buffer++; + phsf++; + phss--; + i++; + if(i > MAX_NO_BIT) + { + i=0; + phsm++; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success"); + *new_header_size = size; + return STATUS_PHS_COMPRESSED; +} + + + + + + diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h new file mode 100644 index 000000000000..bf2b5763252c --- /dev/null +++ b/drivers/staging/bcm/PHSModule.h @@ -0,0 +1,95 @@ +#ifndef BCM_MINIPORT_PHSMODULE_H +#define BCM_MINIPORT_PHSMODULE_H + +int PHSTransmit(PMINI_ADAPTER Adapter, + struct sk_buff **pPacket, + USHORT Vcid, + B_UINT16 uiClassifierRuleID, + BOOLEAN bHeaderSuppressionEnabled, + PUINT PacketLen, + UCHAR bEthCSSupport); + +int PHSRecieve(PMINI_ADAPTER Adapter, + USHORT usVcid, + struct sk_buff *packet, + UINT *punPacketLen, + UCHAR *pucEthernetHdr, + UINT + ); + + +void DumpDataPacketHeader(PUCHAR pPkt); + +void DumpFullPacket(UCHAR *pBuf,UINT nPktLen); + +void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension); + + +int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter); + +void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable); + +int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf, + unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size ); + + +int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, + unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size ); + +int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\ + S_PHS_RULE *phs_rules,UINT *header_size); + + +int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt); + +//Utility Functions +ULONG PhsUpdateClassifierRule(void* pvContext,B_UINT16 uiVcid,B_UINT16 uiClsId,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI ); + +ULONG PhsDeletePHSRule(void* pvContext,B_UINT16 uiVcid,B_UINT8 u8PHSI); + +ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsId); + +ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ; + + +ULONG PhsCompress(void* pvContext, + B_UINT16 uiVcid, + B_UINT16 uiClsId, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pOldHeaderSize, + UINT *pNewHeaderSize ); + +ULONG PhsDeCompress(void* pvContext, + B_UINT16 uiVcid, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pInHeaderSize, + UINT *pOutHeaderSize); + + +BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule); + +BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule); + +UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry); + +UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry); + +UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule); + + +UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI); + +UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule); + +void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension); + + +#endif diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h new file mode 100644 index 000000000000..00f1cc12356a --- /dev/null +++ b/drivers/staging/bcm/Protocol.h @@ -0,0 +1,151 @@ +/************************************ +* Protocol.h +*************************************/ +#ifndef __PROTOCOL_H__ +#define __PROTOCOL_H__ + + +#define IPV4 4 +#define IPV6 6 + + +struct ArpHeader { + struct arphdr arp; + unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ + unsigned char ar_sip[4]; /* sender IP address */ + unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ + unsigned char ar_tip[4]; /* target IP address */ +}/*__attribute__((packed))*/; + + +struct TransportHeaderT +{ + union + { + struct udphdr uhdr; + struct tcphdr thdr; + }; +} __attribute__((packed)); +typedef struct TransportHeaderT xporthdr; + + +typedef enum _E_NWPKT_IPFRAME_TYPE +{ + eNonIPPacket, + eIPv4Packet, + eIPv6Packet +}E_NWPKT_IPFRAME_TYPE; + +typedef enum _E_NWPKT_ETHFRAME_TYPE +{ + eEthUnsupportedFrame, + eEth802LLCFrame, + eEth802LLCSNAPFrame, + eEth802QVLANFrame, + eEthOtherFrame +} E_NWPKT_ETHFRAME_TYPE; + +typedef struct _S_ETHCS_PKT_INFO +{ + E_NWPKT_IPFRAME_TYPE eNwpktIPFrameType; + E_NWPKT_ETHFRAME_TYPE eNwpktEthFrameType; + USHORT usEtherType; + UCHAR ucDSAP; +}S_ETHCS_PKT_INFO,*PS_ETHCS_PKT_INFO; + +typedef struct _ETH_CS_802_Q_FRAME +{ + ETH_HEADER_STRUC EThHdr; + USHORT UserPriority:3; + USHORT CFI:1; + USHORT VLANID:12; + USHORT EthType; +} __attribute__((packed)) ETH_CS_802_Q_FRAME; + +typedef struct _ETH_CS_802_LLC_FRAME +{ + ETH_HEADER_STRUC EThHdr; + unsigned char DSAP; + unsigned char SSAP; + unsigned char Control; +}__attribute__((packed)) ETH_CS_802_LLC_FRAME; + +typedef struct _ETH_CS_802_LLC_SNAP_FRAME +{ + ETH_HEADER_STRUC EThHdr; + unsigned char DSAP; + unsigned char SSAP; + unsigned char Control; + unsigned char OUI[3]; + unsigned short usEtherType; +} __attribute__((packed)) ETH_CS_802_LLC_SNAP_FRAME; + +typedef struct _ETH_CS_ETH2_FRAME +{ + ETH_HEADER_STRUC EThHdr; +} __attribute__((packed)) ETH_CS_ETH2_FRAME; + + +#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) +#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd) +#define ETHERNET_FRAMETYPE_802QVLAN 0x8100 +//Per SF CS Specification Encodings +typedef enum _E_SERVICEFLOW_CS_SPEC_ +{ + eCSSpecUnspecified =0, + eCSPacketIPV4, + eCSPacketIPV6, + eCS802_3PacketEthernet, + eCS802_1QPacketVLAN, + eCSPacketIPV4Over802_3Ethernet, + eCSPacketIPV6Over802_3Ethernet, + eCSPacketIPV4Over802_1QVLAN, + eCSPacketIPV6Over802_1QVLAN, + eCSPacketUnsupported +}E_SERVICEFLOW_CS_SPEC; + + +#define IP6_HEADER_LEN 40 + +#define IP_VERSION(byte) (((byte&0xF0)>>4)) + + + +#define MAC_ADDRESS_SIZE 6 +#define ETH_AND_IP_HEADER_LEN 14 + 20 +#define L4_SRC_PORT_LEN 2 +#define L4_DEST_PORT_LEN 2 + + + +#define CTRL_PKT_LEN 8 + ETH_AND_IP_HEADER_LEN + +#define ETH_ARP_FRAME 0x806 +#define ETH_IPV4_FRAME 0x800 +#define ETH_IPV6_FRAME 0x86DD +#define UDP 0x11 +#define TCP 0x06 + +#define ARP_OP_REQUEST 0x01 +#define ARP_OP_REPLY 0x02 +#define ARP_PKT_SIZE 60 + +// This is the format for the TCP packet header +typedef struct _TCP_HEADER +{ + USHORT usSrcPort; + USHORT usDestPort; + ULONG ulSeqNumber; + ULONG ulAckNumber; + UCHAR HeaderLength; + UCHAR ucFlags; + USHORT usWindowsSize; + USHORT usChkSum; + USHORT usUrgetPtr; +} TCP_HEADER,*PTCP_HEADER; +#define TCP_HEADER_LEN sizeof(TCP_HEADER) +#define TCP_ACK 0x10 //Bit 4 in tcpflags field. +#define GET_TCP_HEADER_LEN(byte) ((byte&0xF0)>>4) + + +#endif //__PROTOCOL_H__ diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h new file mode 100644 index 000000000000..7718937c5bd9 --- /dev/null +++ b/drivers/staging/bcm/Prototypes.h @@ -0,0 +1,323 @@ +#ifndef _PROTOTYPES_H_ +#define _PROTOTYPES_H_ + +int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ + char *path, /**< path to image file */ + unsigned int loc /**< Download Address on the chip*/ + ); +VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer); + +VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer); + +VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer); + +void bcm_kfree_skb(struct sk_buff *skb); +VOID bcm_kfree(VOID *ptr); + + +VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**ucIPSourceAddressLength) + return TRUE; + for(ucLoopIndex=0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);ucLoopIndex++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT)pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)ulSrcIP, (UINT)pstClassifierRule->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]); + if((pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] & ulSrcIP)== + (pstClassifierRule->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] )) + { + return TRUE; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched"); + return FALSE; +} + + +/******************************************************************* +* Function - MatchDestIpAddress() +* +* Description - Checks whether the Destination IP address from the packet +* matches with that of Queue. +* +* Parameters - pstClassifierRule: Pointer to the packet info structure. +* - ulDestIP : Destination IP address from the packet. +* +* Returns - TRUE(If address matches) else FAIL . +*********************************************************************/ +BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP) +{ + UCHAR ucLoopIndex=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + ulDestIP=ntohl(ulDestIP); + if(0 == pstClassifierRule->ucIPDestinationAddressLength) + return TRUE; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT)ulDestIP, (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + + for(ucLoopIndex=0;ucLoopIndex<(pstClassifierRule->ucIPDestinationAddressLength);ucLoopIndex++) + { + if((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP)== + (pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex])) + { + return TRUE; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched"); + return FALSE; +} + + +/************************************************************************ +* Function - MatchTos() +* +* Description - Checks the TOS from the packet matches with that of queue. +* +* Parameters - pstClassifierRule : Pointer to the packet info structure. +* - ucTypeOfService: TOS from the packet. +* +* Returns - TRUE(If address matches) else FAIL. +**************************************************************************/ +BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService) +{ + + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if( 3 != pstClassifierRule->ucIPTypeOfServiceLength ) + return TRUE; + + if(((pstClassifierRule->ucTosMask & ucTypeOfService)<=pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService)>=pstClassifierRule->ucTosLow)) + { + return TRUE; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched"); + return FALSE; +} + + +/*************************************************************************** +* Function - MatchProtocol() +* +* Description - Checks the protocol from the packet matches with that of queue. +* +* Parameters - pstClassifierRule: Pointer to the packet info structure. +* - ucProtocol : Protocol from the packet. +* +* Returns - TRUE(If address matches) else FAIL. +****************************************************************************/ +BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol) +{ + UCHAR ucLoopIndex=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if(0 == pstClassifierRule->ucProtocolLength) + return TRUE; + for(ucLoopIndex=0;ucLoopIndexucProtocolLength;ucLoopIndex++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol:0x%X Classification Protocol:0x%X",ucProtocol,pstClassifierRule->ucProtocol[ucLoopIndex]); + if(pstClassifierRule->ucProtocol[ucLoopIndex]==ucProtocol) + { + return TRUE; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched"); + return FALSE; +} + + +/*********************************************************************** +* Function - MatchSrcPort() +* +* Description - Checks, Source port from the packet matches with that of queue. +* +* Parameters - pstClassifierRule: Pointer to the packet info structure. +* - ushSrcPort : Source port from the packet. +* +* Returns - TRUE(If address matches) else FAIL. +***************************************************************************/ +BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort) +{ + UCHAR ucLoopIndex=0; + + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + + if(0 == pstClassifierRule->ucSrcPortRangeLength) + return TRUE; + for(ucLoopIndex=0;ucLoopIndexucSrcPortRangeLength;ucLoopIndex++) + { + if(ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] && + ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex]) + { + return TRUE; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ",ushSrcPort); + return FALSE; +} + + +/*********************************************************************** +* Function - MatchDestPort() +* +* Description - Checks, Destination port from packet matches with that of queue. +* +* Parameters - pstClassifierRule: Pointer to the packet info structure. +* - ushDestPort : Destination port from the packet. +* +* Returns - TRUE(If address matches) else FAIL. +***************************************************************************/ +BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort) +{ + UCHAR ucLoopIndex=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + if(0 == pstClassifierRule->ucDestPortRangeLength) + return TRUE; + + for(ucLoopIndex=0;ucLoopIndexucDestPortRangeLength;ucLoopIndex++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Matching Port:0x%X 0x%X 0x%X",ushDestPort,pstClassifierRule->usDestPortRangeLo[ucLoopIndex],pstClassifierRule->usDestPortRangeHi[ucLoopIndex]); + + if(ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] && + ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex]) + { + return TRUE; + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched",ushDestPort); + return FALSE; +} +/** +@ingroup tx_functions +Compares IPV4 Ip address and port number +@return Queue Index. +*/ +USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ + struct iphdr *iphd, /**"); + + xprt_hdr=(xporthdr *)((PUCHAR)iphd + sizeof(struct iphdr)); + + do { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to see Direction = %d %d", + pstClassifierRule->ucDirection, + pstClassifierRule->usVCID_Value); + + //Checking classifier validity + if(!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR) + { + bClassificationSucceed = FALSE; + break; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!"); + if(pstClassifierRule->bIpv6Protocol) + break; + + //**************Checking IP header parameter**************************// + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address"); + if(FALSE == (bClassificationSucceed = + MatchSrcIpAddress(pstClassifierRule, iphd->saddr))) + break; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched"); + + if(FALSE == (bClassificationSucceed = + MatchDestIpAddress(pstClassifierRule, iphd->daddr))) + break; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched"); + + if(FALSE == (bClassificationSucceed = + MatchTos(pstClassifierRule, iphd->tos))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n"); + break; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched"); + + if(FALSE == (bClassificationSucceed = + MatchProtocol(pstClassifierRule,iphd->protocol))) + break; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched"); + + //if protocol is not TCP or UDP then no need of comparing source port and destination port + if(iphd->protocol!=TCP && iphd->protocol!=UDP) + break; +#if 0 + //check if memory is available of src and Dest port + if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len) + { + //This is not an erroneous condition and pkt will be checked for next classification. + bClassificationSucceed = FALSE; + break; + } +#endif + //******************Checking Transport Layer Header field if present *****************// + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x", + (iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source); + + if(FALSE == (bClassificationSucceed = + MatchSrcPort(pstClassifierRule, + ntohs((iphd->protocol == UDP)? + xprt_hdr->uhdr.source:xprt_hdr->thdr.source)))) + break; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched"); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x", + (iphd->protocol==UDP)?xprt_hdr->uhdr.dest: + xprt_hdr->thdr.dest); + if(FALSE == (bClassificationSucceed = + MatchDestPort(pstClassifierRule, + ntohs((iphd->protocol == UDP)? + xprt_hdr->uhdr.dest:xprt_hdr->thdr.dest)))) + break; + } while(0); + + if(TRUE==bClassificationSucceed) + { + INT iMatchedSFQueueIndex = 0; + iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); + if(iMatchedSFQueueIndex >= NO_OF_QUEUES) + { + bClassificationSucceed = FALSE; + } + else + { + if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) + { + bClassificationSucceed = FALSE; + } + } + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <=========="); + + return bClassificationSucceed; +} +/** +@ingroup tx_functions +@return Queue Index based on priority. +*/ +USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**"); + + if(NULL==Adapter || NULL==Packet) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======"); + return -1; + } + + usIndex = ClassifyPacket(Adapter,Packet); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <=============="); + return usIndex; +} + +VOID PruneQueueAllSF(PMINI_ADAPTER Adapter) +{ + UINT iIndex = 0; + + for(iIndex = 0; iIndex < HiPriority; iIndex++) + { + if(!Adapter->PackInfo[iIndex].bValid) + continue; + + PruneQueue(Adapter, iIndex); + } +} + + +/** +@ingroup tx_functions +This function checks if the max queue size for a queue +is less than number of bytes in the queue. If so - +drops packets from the Head till the number of bytes is +less than or equal to max queue size for the queue. +*/ +VOID PruneQueue(PMINI_ADAPTER Adapter,/** Index %d",iIndex); + + if(iIndex == HiPriority) + return; + + if(!Adapter || (iIndex < 0) || (iIndex > HiPriority)) + return; + + /* To Store the netdevice statistic */ + netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; + + spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); + + while(1) +// while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost > +// SF_MAX_ALLOWED_PACKETS_TO_BACKUP) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x", + Adapter->PackInfo[iIndex].uiCurrentBytesOnHost, + Adapter->PackInfo[iIndex].uiMaxBucketSize); + + PacketToDrop = Adapter->PackInfo[iIndex].FirstTxQueue; + + if(PacketToDrop == NULL) + break; + if((Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost < SF_MAX_ALLOWED_PACKETS_TO_BACKUP) && + ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb)+SKB_CB_LATENCY_OFFSET))/HZ) <= Adapter->PackInfo[iIndex].uiMaxLatency)) + break; + + if(PacketToDrop) + { + if(netstats) + netstats->tx_dropped++; + atomic_inc(&Adapter->TxDroppedPacketCount); + DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue, + Adapter->PackInfo[iIndex].LastTxQueue); + /// update current bytes and packets count + Adapter->PackInfo[iIndex].uiCurrentBytesOnHost -= + PacketToDrop->len; + Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost--; + /// update dropped bytes and packets counts + Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len; + Adapter->PackInfo[iIndex].uiDroppedCountPackets++; + bcm_kfree_skb(PacketToDrop); + + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x", + Adapter->PackInfo[iIndex].uiDroppedCountBytes, + Adapter->PackInfo[iIndex].uiDroppedCountPackets); + + atomic_dec(&Adapter->TotalPacketCount); + Adapter->bcm_jiffies = jiffies; + } + + spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "TotalPacketCount:%x", + atomic_read(&Adapter->TotalPacketCount)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "<====="); +} + +VOID flush_all_queues(PMINI_ADAPTER Adapter) +{ + INT iQIndex; + UINT uiTotalPacketLength; + struct sk_buff* PacketToDrop=NULL; + struct net_device_stats* netstats=NULL; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>"); + /* To Store the netdevice statistic */ + netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; + +// down(&Adapter->data_packet_queue_lock); + for(iQIndex=LowPriority; iQIndexPackInfo[iQIndex].SFQueueLock); + while(Adapter->PackInfo[iQIndex].FirstTxQueue) + { + PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; + if(PacketToDrop) + { + uiTotalPacketLength = PacketToDrop->len; + netstats->tx_dropped++; + atomic_inc(&Adapter->TxDroppedPacketCount); + } + else + uiTotalPacketLength = 0; + + DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, + Adapter->PackInfo[iQIndex].LastTxQueue); + + /* Free the skb */ + bcm_kfree_skb(PacketToDrop); + + /// update current bytes and packets count + Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength; + Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; + + /// update dropped bytes and packets counts + Adapter->PackInfo[iQIndex].uiDroppedCountBytes += uiTotalPacketLength; + Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x", + Adapter->PackInfo[iQIndex].uiDroppedCountBytes, + Adapter->PackInfo[iQIndex].uiDroppedCountPackets); + atomic_dec(&Adapter->TotalPacketCount); + } + spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); + } +// up(&Adapter->data_packet_queue_lock); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<====="); +} + +USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) +{ + INT uiLoopIndex=0; + S_CLASSIFIER_RULE *pstClassifierRule = NULL; + S_ETHCS_PKT_INFO stEthCsPktInfo; + PVOID pvEThPayload = NULL; + struct iphdr *pIpHeader = NULL; + INT uiSfIndex=0; + USHORT usIndex=Adapter->usBestEffortQueueIndex; + BOOLEAN bFragmentedPkt=FALSE,bClassificationSucceed=FALSE; + USHORT usCurrFragment =0; + + PTCP_HEADER pTcpHeader; + UCHAR IpHeaderLength; + UCHAR TcpHeaderLength; + + pvEThPayload = skb->data; + *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = 0; + EThCSGetPktInfo(Adapter,pvEThPayload,&stEthCsPktInfo); + + switch(stEthCsPktInfo.eNwpktEthFrameType) + { + case eEth802LLCFrame: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLCFrame\n"); + pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_FRAME); + break; + } + + case eEth802LLCSNAPFrame: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLC SNAP Frame\n"); + pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_SNAP_FRAME); + break; + } + case eEth802QVLANFrame: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802.1Q VLANFrame\n"); + pIpHeader = pvEThPayload + sizeof(ETH_CS_802_Q_FRAME); + break; + } + case eEthOtherFrame: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : ETH Other Frame\n"); + pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME); + break; + } + default: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Unrecognized ETH Frame\n"); + pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME); + break; + } + } + + if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) + { + usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET); + if((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment) + bFragmentedPkt = TRUE; + + if(bFragmentedPkt) + { + //Fragmented Packet. Get Frag Classifier Entry. + pstClassifierRule = GetFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr); + if(pstClassifierRule) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"It is next Fragmented pkt"); + bClassificationSucceed=TRUE; + } + if(!(ntohs(pIpHeader->frag_off) & IP_MF)) + { + //Fragmented Last packet . Remove Frag Classifier Entry + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"This is the last fragmented Pkt"); + DelFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr); + } + } + } + + for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) + { + if (Adapter->device_removed) + { + bClassificationSucceed = FALSE; + break; + } + + if(bClassificationSucceed) + break; + //Iterate through all classifiers which are already in order of priority + //to classify the packet until match found + do + { + if(FALSE==Adapter->astClassifierTable[uiLoopIndex].bUsed) + { + bClassificationSucceed=FALSE; + break; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex); + + if(0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) + { + bClassificationSucceed=FALSE;//cannot be processed for classification. + break; // it is a down link connection + } + + pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex]; + + uiSfIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); + if(uiSfIndex > NO_OF_QUEUES) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Queue Not Valid. SearchSfid for this classifier Failed\n"); + break; + } + + if(Adapter->PackInfo[uiSfIndex].bEthCSSupport) + { + + if(eEthUnsupportedFrame==stEthCsPktInfo.eNwpktEthFrameType) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n"); + bClassificationSucceed = FALSE; + break; + } + + + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",pstClassifierRule->uiClassifierRuleIndex,Adapter->PackInfo[uiSfIndex].ulSFID); + bClassificationSucceed = EThCSClassifyPkt(Adapter,skb,&stEthCsPktInfo,pstClassifierRule, Adapter->PackInfo[uiSfIndex].bEthCSSupport); + + if(!bClassificationSucceed) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n"); + break; + } + } + + else // No ETH Supported on this SF + { + if(eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF \n"); + bClassificationSucceed = FALSE; + break; + } + } + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification"); + + if(Adapter->PackInfo[uiSfIndex].bIPCSSupport) + { + + if(stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet \n"); + bClassificationSucceed = FALSE; + break; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header : \n"); + DumpFullPacket((PUCHAR)pIpHeader,20); + + if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) + bClassificationSucceed = IpVersion4(Adapter,pIpHeader,pstClassifierRule); + else if(stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet) + bClassificationSucceed = IpVersion6(Adapter,pIpHeader,pstClassifierRule); + } + + }while(0); + } + + if(bClassificationSucceed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu",pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID); + + //Store The matched Classifier in SKB + *((UINT32*)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = pstClassifierRule->uiClassifierRuleIndex; + if((TCP == pIpHeader->protocol ) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len) ) + { + IpHeaderLength = pIpHeader->ihl; + pTcpHeader = (PTCP_HEADER)(((PUCHAR)pIpHeader)+(IpHeaderLength*4)); + TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength); + + if((pTcpHeader->ucFlags & TCP_ACK) && + (ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4))) + { + *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = TCP_ACK; + } + } + + usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex); + + //If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt. + if(bFragmentedPkt && (usCurrFragment == 0)) + { + //First Fragment of Fragmented Packet. Create Frag CLS Entry + S_FRAGMENTED_PACKET_INFO stFragPktInfo; + stFragPktInfo.bUsed = TRUE; + stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr; + stFragPktInfo.usIpIdentification = pIpHeader->id; + stFragPktInfo.pstMatchedClassifierEntry = pstClassifierRule; + stFragPktInfo.bOutOfOrderFragment = FALSE; + AddFragIPClsEntry(Adapter,&stFragPktInfo); + } + + + } + + if(bClassificationSucceed) + return usIndex; + else + return INVALID_QUEUE_INDEX; +} + +BOOLEAN EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) +{ + UINT i=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if(pstClassifierRule->ucEthCSSrcMACLen==0) + return TRUE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); + for(i=0;iau8EThCSSrcMAC[i],pstClassifierRule->au8EThCSSrcMACMask[i]); + if((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i])!= + (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i])) + return FALSE; + } + return TRUE; +} + +BOOLEAN EthCSMatchDestMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac) +{ + UINT i=0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if(pstClassifierRule->ucEthCSDestMACLen==0) + return TRUE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); + for(i=0;iau8EThCSDestMAC[i],pstClassifierRule->au8EThCSDestMACMask[i]); + if((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i])!= + (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i])) + return FALSE; + } + return TRUE; +} + +BOOLEAN EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + if((pstClassifierRule->ucEtherTypeLen==0)|| + (pstClassifierRule->au8EthCSEtherType[0] == 0)) + return TRUE; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s SrcEtherType:%x CLS EtherType[0]:%x\n",__FUNCTION__,pstEthCsPktInfo->usEtherType,pstClassifierRule->au8EthCSEtherType[0]); + if(pstClassifierRule->au8EthCSEtherType[0] == 1) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS EtherType[1]:%x EtherType[2]:%x\n",__FUNCTION__,pstClassifierRule->au8EthCSEtherType[1],pstClassifierRule->au8EthCSEtherType[2]); + + if(memcmp(&pstEthCsPktInfo->usEtherType,&pstClassifierRule->au8EthCSEtherType[1],2)==0) + return TRUE; + else + return FALSE; + } + + if(pstClassifierRule->au8EthCSEtherType[0] == 2) + { + if(eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType) + return FALSE; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s EthCS DSAP:%x EtherType[2]:%x\n",__FUNCTION__,pstEthCsPktInfo->ucDSAP,pstClassifierRule->au8EthCSEtherType[2]); + if(pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2]) + return TRUE; + else + return FALSE; + + } + + return FALSE; + +} + +BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) +{ + BOOLEAN bClassificationSucceed = FALSE; + USHORT usVLANID; + B_UINT8 uPriority = 0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__,ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),pstClassifierRule->usVLANID); + + /* In case FW didn't recieve the TLV, the priority field should be ignored */ + if(pstClassifierRule->usValidityBitMap & (1<eNwpktEthFrameType!=eEth802QVLANFrame) + return FALSE; + + uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xF000) >> 13; + + if((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1])) + bClassificationSucceed = TRUE; + + if(!bClassificationSucceed) + return FALSE; + } + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 D User Priority Rule Matched\n"); + + bClassificationSucceed = FALSE; + + if(pstClassifierRule->usValidityBitMap & (1<eNwpktEthFrameType!=eEth802QVLANFrame) + return FALSE; + + usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xFFF; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__,usVLANID, uPriority); + + if(usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4)) + bClassificationSucceed = TRUE; + + if(!bClassificationSucceed) + return FALSE; + } + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 Q VLAN ID Rule Matched\n"); + + return TRUE; +} + + +BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport) +{ + BOOLEAN bClassificationSucceed = FALSE; + bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress); + if(!bClassificationSucceed) + return FALSE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n"); + + bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((ETH_HEADER_STRUC*)(skb->data))->au8DestinationAddress); + if(!bClassificationSucceed) + return FALSE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n"); + + //classify on ETHType/802.2SAP TLV + bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,skb,pstEthCsPktInfo); + if(!bClassificationSucceed) + return FALSE; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS EthType/802.2SAP Matched\n"); + + //classify on 802.1VLAN Header Parameters + + bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,skb,pstEthCsPktInfo); + if(!bClassificationSucceed) + return FALSE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 VLAN Rules Matched\n"); + + return bClassificationSucceed; +} + +void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo) +{ + USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype); + if(u16Etype > 0x5dc) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame \n"); + //ETH2 Frame + if(u16Etype == ETHERNET_FRAMETYPE_802QVLAN) + { + //802.1Q VLAN Header + pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame; + u16Etype = ((ETH_CS_802_Q_FRAME*)pvEthPayload)->EthType; + //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority + } + else + { + pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame; + u16Etype = ntohs(u16Etype); + } + + } + else + { + //802.2 LLC + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "802.2 LLC Frame \n"); + pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame; + pstEthCsPktInfo->ucDSAP = ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->DSAP; + if(pstEthCsPktInfo->ucDSAP == 0xAA && ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->SSAP == 0xAA) + { + //SNAP Frame + pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame; + u16Etype = ((ETH_CS_802_LLC_SNAP_FRAME*)pvEthPayload)->usEtherType; + } + } + if(u16Etype == ETHERNET_FRAMETYPE_IPV4) + pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet; + else if(u16Etype == ETHERNET_FRAMETYPE_IPV6) + pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet; + else + pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; + + pstEthCsPktInfo->usEtherType = ((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo->eNwpktIPFrameType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo->eNwpktEthFrameType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo->usEtherType); +} + + + diff --git a/drivers/staging/bcm/Queue.h b/drivers/staging/bcm/Queue.h new file mode 100644 index 000000000000..e1f1da2bb6d4 --- /dev/null +++ b/drivers/staging/bcm/Queue.h @@ -0,0 +1,31 @@ +/************************************* +* Queue.h +**************************************/ +#ifndef __QUEUE_H__ +#define __QUEUE_H__ + + + +#define ENQUEUEPACKET(_Head, _Tail,_Packet) \ +do \ +{ \ + if (!_Head) { \ + _Head = _Packet; \ + } \ + else { \ + (_Tail)->next = _Packet; \ + } \ + (_Packet)->next = NULL; \ + _Tail = _Packet; \ +}while(0) +#define DEQUEUEPACKET(Head, Tail ) \ +do \ +{ if(Head) \ + { \ + if (!Head->next) { \ + Tail = NULL; \ + } \ + Head = Head->next; \ + } \ +}while(0) +#endif //__QUEUE_H__ diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO new file mode 100644 index 000000000000..366634be5fe1 --- /dev/null +++ b/drivers/staging/bcm/TODO @@ -0,0 +1,15 @@ +TODO: + - fix non-standard kernel style + - sparse warnings + - checkpatch warnings + - remove compatiablity code for older kernels + - remove #ifdef's + - fix bogus device nameing and reference counting (see bcm_notify_event) + - fix use of file I/O to load config + - request firmware + - update to current network device API + - merge some files together + - cleanup/eliminate debug messages + + - integrate with existing Wimax stack? + diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c new file mode 100644 index 000000000000..9a076b54324f --- /dev/null +++ b/drivers/staging/bcm/Transmit.c @@ -0,0 +1,553 @@ +/** +@file Transmit.c +@defgroup tx_functions Transmission +@section Queueing +@dot +digraph transmit1 { +node[shape=box] +edge[weight=5;color=red] +bcm_transmit->reply_to_arp_request[label="ARP"] +bcm_transmit->GetPacketQueueIndex[label="IP Packet"] +GetPacketQueueIndex->IpVersion4[label="IPV4"] +GetPacketQueueIndex->IpVersion6[label="IPV6"] +} + +@enddot + +@section De-Queueing +@dot +digraph transmit2 { +node[shape=box] +edge[weight=5;color=red] +interrupt_service_thread->transmit_packets +tx_pkt_hdler->transmit_packets +transmit_packets->CheckAndSendPacketFromIndex +transmit_packets->UpdateTokenCount +CheckAndSendPacketFromIndex->PruneQueue +CheckAndSendPacketFromIndex->IsPacketAllowedForFlow +CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] +SendControlPacket->bcm_cmd53 +CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] +SendPacketFromQueue->SetupNextSend->bcm_cmd53 +} +@enddot +*/ + +#include "headers.h" + +/******************************************************************* +* Function - bcm_transmit() +* +* Description - This is the main transmit function for our virtual +* interface(veth0). It handles the ARP packets. It +* clones this packet and then Queue it to a suitable +* Queue. Then calls the transmit_packet(). +* +* Parameter - skb - Pointer to the socket buffer structure +* dev - Pointer to the virtual net device structure +* +* Returns - zero (success) or -ve value (failure) +* +*********************************************************************/ + +INT bcm_transmit(struct sk_buff *skb, /**< skb */ + struct net_device *dev /**< net device pointer */ + ) +{ + PMINI_ADAPTER Adapter = NULL; + USHORT qindex=0; + struct timeval tv; + UINT pkt_type = 0; + UINT calltransmit = 0; + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__); + + memset(&tv, 0, sizeof(tv)); + /* Check for valid parameters */ + if(skb == NULL || dev==NULL) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n"); + return -EINVAL; + } + + Adapter = GET_BCM_ADAPTER(dev); + if(!Adapter) + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n"); + return -EINVAL; + } + if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus) + { + if(!netif_queue_stopped(dev)) { + netif_carrier_off(dev); + netif_stop_queue(dev); + } + return STATUS_FAILURE; + } + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len); + + /*Add Ethernet CS check here*/ + if(Adapter->TransferMode == IP_PACKET_ONLY_MODE ) + { + pkt_type = ntohs(*(PUSHORT)(skb->data + 12)); + /* Get the queue index where the packet is to be queued */ + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index....."); + + qindex = GetPacketQueueIndex(Adapter,skb); + + if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex) + { + if(pkt_type == ETH_ARP_FRAME) + { + /* + Reply directly to ARP request packet + ARP Spoofing only if NO ETH CS rule matches for it + */ + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x", + + (*(PUCHAR)(skb->data + 21))); + + reply_to_arp_request(skb); + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n"); + + } + else + { + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, + "Invalid queue index, dropping pkt\n"); + + bcm_kfree_skb(skb); + } + return STATUS_SUCCESS; + } + + if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) + { + atomic_inc(&Adapter->TxDroppedPacketCount); + bcm_kfree_skb(skb); + return STATUS_SUCCESS; + } + + /* Now Enqueue the packet */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex); + spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); + Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; + Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; + + *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; + ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, + Adapter->PackInfo[qindex].LastTxQueue, skb); + atomic_inc(&Adapter->TotalPacketCount); + spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); + do_gettimeofday(&tv); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n", + (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec); + +#ifdef BCM_SHM_INTERFACE + spin_lock(&Adapter->txtransmitlock); + if(Adapter->txtransmit_running == 0) + { + Adapter->txtransmit_running = 1; + calltransmit = 1; + } + else + calltransmit = 0; + + spin_unlock(&Adapter->txtransmitlock); +#endif + if(calltransmit == 1) + transmit_packets(Adapter); + else + { + if(!atomic_read(&Adapter->TxPktAvail)) + { + atomic_set(&Adapter->TxPktAvail, 1); +#ifdef BCM_SHM_INTERFACE + virtual_mail_box_interrupt(); +#endif + wake_up(&Adapter->tx_packet_wait_queue); + } + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<===="); + } + else + bcm_kfree_skb(skb); + + return STATUS_SUCCESS; +} + + +/** +@ingroup ctrl_pkt_functions +This function dispatches control packet to the h/w interface +@return zero(success) or -ve value(failure) +*/ +INT SendControlPacket(PMINI_ADAPTER Adapter, /**"); + + PLeader=(PLEADER)pControlPacket; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); + if(!pControlPacket || !Adapter) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); + return STATUS_FAILURE; + } + if((atomic_read( &Adapter->CurrNumFreeTxDesc ) < + ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); + if(Adapter->bcm_jiffies == 0) + { + Adapter->bcm_jiffies = jiffies; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu", + Adapter->bcm_jiffies); + } + return STATUS_FAILURE; + } + + /* Update the netdevice statistics */ + /* Dump Packet */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength); + if(Adapter->device_removed) + return 0; +#ifndef BCM_SHM_INTERFACE + Adapter->interface_transmit(Adapter->pvInterfaceAdapter, + pControlPacket, (PLeader->PLength + LEADER_SIZE)); +#else + tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1); + + if(PLeader->Status==IDLE_MESSAGE) + { + if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD && + ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n"); + do_gettimeofday(&tv); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); + if(Adapter->bDoSuspend != TRUE) + { + Adapter->IdleMode = TRUE; + Adapter->bPreparingForLowPowerMode = FALSE ; + } + } + } + if((PLeader->Status == LINK_UP_CONTROL_REQ) && + ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK && + ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] == + LINK_SHUTDOWN_REQ_FROM_FIRMWARE && + ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n"); + if(Adapter->bDoSuspend != TRUE) + { + Adapter->bShutStatus = TRUE; + Adapter->bPreparingForLowPowerMode = FALSE; + Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; + } + + } +#endif + + ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++; + ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+= + PLeader->PLength; + atomic_dec(&Adapter->CurrNumFreeTxDesc); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); + return STATUS_SUCCESS; +} +static LEADER Leader={0}; +/** +@ingroup tx_functions +This function despatches the IP packets with the given vcid +to the target via the host h/w interface. +@return zero(success) or -ve value(failure) +*/ +INT SetupNextSend(PMINI_ADAPTER Adapter, /**len > MAX_DEVICE_DESC_SIZE) + { + status = STATUS_FAILURE; + goto errExit; + } + + /* Get the Classifier Rule ID */ + uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET); + QueueIndex = SearchVcid( Adapter,Vcid); + if(QueueIndex < NO_OF_QUEUES) + { + bHeaderSupressionEnabled = + Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; + bHeaderSupressionEnabled = + bHeaderSupressionEnabled & Adapter->bPHSEnabled; + } + if(Adapter->device_removed) + { + status = STATUS_FAILURE; + goto errExit; + } + + status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, + (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); + + if(status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); + goto errExit; + } + + Leader.Vcid = Vcid; + + if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET )) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n"); + Leader.Status = LEADER_STATUS_TCP_ACK; + } + else + { + Leader.Status = LEADER_STATUS; + } + + if(Adapter->PackInfo[QueueIndex].bEthCSSupport) + { + Leader.PLength = Packet->len; + if(skb_headroom(Packet) < LEADER_SIZE) + { + if((status = skb_cow(Packet,LEADER_SIZE))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n"); + goto errExit; + } + } + skb_push(Packet, LEADER_SIZE); + memcpy(Packet->data, &Leader, LEADER_SIZE); + } + + else + { + Leader.PLength = Packet->len - ETH_HLEN; + memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid); + +#ifndef BCM_SHM_INTERFACE + status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, + Packet->data, (Leader.PLength + LEADER_SIZE)); +#else + status = tx_pkts_to_firmware(Packet,Packet->len,0); +#endif + if(status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n"); + } + else + { + Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; + atomic_add(Leader.PLength, &Adapter->GoodTxByteCount); + atomic_inc(&Adapter->TxTotalPacketCount); +#ifdef GDMA_INTERFACE + dontfree = 1; +#endif + } + + atomic_dec(&Adapter->CurrNumFreeTxDesc); + +errExit: + + if(STATUS_SUCCESS == status) + { + Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3; + Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len); + Adapter->PackInfo[QueueIndex].uiSentPackets++; + Adapter->PackInfo[QueueIndex].NumOfPacketsSent++; + + atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount); +#ifdef BCM_SHM_INTERFACE + if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0) + { + atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0); + } +#endif + Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength; + } + + +#ifdef GDMA_INTERFACE + if(!dontfree){ + bcm_kfree_skb(Packet); + } +#else + bcm_kfree_skb(Packet); +#endif + return status; +} + +/** +@ingroup tx_functions +Transmit thread +*/ +int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ + ) +{ +#ifndef BCM_SHM_INTERFACE + int status = 0; +#endif + + UINT calltransmit = 1; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = 0x%x",(unsigned int) Adapter); + + + while(1) + { + if(Adapter->LinkUpStatus){ + wait_event_timeout(Adapter->tx_packet_wait_queue, + ((atomic_read(&Adapter->TxPktAvail) && + (MINIMUM_PENDING_DESCRIPTORS < + atomic_read(&Adapter->CurrNumFreeTxDesc)) && + (Adapter->device_removed == FALSE))) || + (1 == Adapter->downloadDDR) || kthread_should_stop() +#ifndef BCM_SHM_INTERFACE + || (TRUE == Adapter->bEndPointHalted) +#endif + , msecs_to_jiffies(10)); + } + else{ + wait_event(Adapter->tx_packet_wait_queue, + ((atomic_read(&Adapter->TxPktAvail) && + (MINIMUM_PENDING_DESCRIPTORS < + atomic_read(&Adapter->CurrNumFreeTxDesc)) && + (Adapter->device_removed == FALSE))) || + (1 == Adapter->downloadDDR) || kthread_should_stop() +#ifndef BCM_SHM_INTERFACE + || (TRUE == Adapter->bEndPointHalted) +#endif + ); + } + + if(kthread_should_stop() || Adapter->device_removed) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); + Adapter->transmit_packet_thread = NULL; + return 0; + } + +#ifndef BCM_SHM_INTERFACE + + if(Adapter->downloadDDR == 1) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n"); + Adapter->downloadDDR +=1; + status = download_ddr_settings(Adapter); + if(status) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n"); + continue; + } + + //Check end point for halt/stall. + if(Adapter->bEndPointHalted == TRUE) + { + Bcm_clear_halt_of_endpoints(Adapter); + Adapter->bEndPointHalted = FALSE; + StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + } + + if(Adapter->LinkUpStatus && !Adapter->IdleMode) + { + if(atomic_read(&Adapter->TotalPacketCount)) + { + update_per_sf_desc_cnts(Adapter); + } + } +#endif + + if( atomic_read(&Adapter->CurrNumFreeTxDesc) && + Adapter->LinkStatus == SYNC_UP_REQUEST && + !Adapter->bSyncUpRequestSent) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); + LinkMessage(Adapter); + } + + if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); + } + +#ifdef BCM_SHM_INTERFACE + spin_lock_bh(&Adapter->txtransmitlock); + if(Adapter->txtransmit_running == 0) + { + Adapter->txtransmit_running = 1; + calltransmit = 1; + } + else + calltransmit = 0; + spin_unlock_bh(&Adapter->txtransmitlock); +#endif + + if(calltransmit) + transmit_packets(Adapter); + + atomic_set(&Adapter->TxPktAvail, 0); + } + return 0; +} + +#ifdef BCM_SHM_INTERFACE +extern PMINI_ADAPTER psAdaptertest; +void virtual_mail_box_interrupt(void) +{ + +#ifndef GDMA_INTERFACE + PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG; + UINT intval = (UINT)((*ptr & 0xFF00) >> 8); + if (intval != 0) + { + atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval); + atomic_set (&psAdaptertest->uiMBupdate, TRUE); + + //make it to 0 + *ptr = *ptr & 0xffff00ff; + } +#endif +} +unsigned int total_tx_pkts_pending(void) +{ + return atomic_read(&psAdaptertest->TotalPacketCount); +} + +#endif + + diff --git a/drivers/staging/bcm/Typedefs.h b/drivers/staging/bcm/Typedefs.h new file mode 100644 index 000000000000..a985abf194fd --- /dev/null +++ b/drivers/staging/bcm/Typedefs.h @@ -0,0 +1,47 @@ +/**************************** +* Typedefs.h +****************************/ +#ifndef __TYPEDEFS_H__ +#define __TYPEDEFS_H__ +#define STATUS_SUCCESS 0 +#define STATUS_FAILURE -1 + +#define FALSE 0 +#define TRUE 1 + +typedef char BOOLEAN; +typedef char CHAR; +typedef int INT; +typedef short SHORT; +typedef long LONG; +typedef void VOID; + +typedef unsigned char UCHAR; +typedef unsigned char B_UINT8; +typedef unsigned short USHORT; +typedef unsigned short B_UINT16; +typedef unsigned int UINT; +typedef unsigned int B_UINT32; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +typedef char* PCHAR; +typedef short* PSHORT; +typedef int* PINT; +typedef long* PLONG; +typedef void* PVOID; + +typedef unsigned char* PUCHAR; +typedef unsigned short* PUSHORT; +typedef unsigned int* PUINT; +typedef unsigned long* PULONG; +typedef unsigned long long ULONG64; +typedef unsigned long long LARGE_INTEGER; +typedef unsigned int UINT32; +#ifndef NULL +#define NULL 0 +#endif + + +#endif //__TYPEDEFS_H__ + diff --git a/drivers/staging/bcm/Version.h b/drivers/staging/bcm/Version.h new file mode 100644 index 000000000000..a07b956b9ff5 --- /dev/null +++ b/drivers/staging/bcm/Version.h @@ -0,0 +1,35 @@ + +/*Copyright (c) 2005 Beceem Communications Inc. + +Module Name: + + Version.h + +Abstract: + + +--*/ + +#ifndef VERSION_H +#define VERSION_H + + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_NETWORK + + +#define VER_FILEVERSION 5.2.45 +#define VER_FILEVERSION_STR "5.2.45" + +#undef VER_PRODUCTVERSION +#define VER_PRODUCTVERSION VER_FILEVERSION + +#undef VER_PRODUCTVERSION_STR +#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR + + + + +//#include "common.ver" + +#endif //VERSION_H diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h new file mode 100644 index 000000000000..4cbe30022248 --- /dev/null +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -0,0 +1,677 @@ +#ifndef CNTRL_SIGNALING_INTERFACE_ +#define CNTRL_SIGNALING_INTERFACE_ + + +#ifdef BECEEM_TARGET + +#include +#include +#include +#include +#include +using namespace Beceem; +#ifdef ENABLE_CORRIGENDUM2_UPDATE +extern B_UINT32 g_u32Corr2MacFlags; +#endif + +#else + + +#define DSA_REQ 11 +#define DSA_RSP 12 +#define DSA_ACK 13 +#define DSC_REQ 14 +#define DSC_RSP 15 +#define DSC_ACK 16 +#define DSD_REQ 17 +#define DSD_RSP 18 +#define DSD_ACK 19 +#define MAX_CLASSIFIERS_IN_SF 4 + +#endif + +#define MAX_STRING_LEN 20 +#define MAX_PHS_LENGTHS 255 +#define VENDOR_PHS_PARAM_LENGTH 10 +#define MAX_NUM_ACTIVE_BS 10 +#define AUTH_TOKEN_LENGTH 10 +#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accomodate all HARQ channels +#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it +#define VENDOR_SPECIF_QOS_PARAM 1 +#define VENDOR_PHS_PARAM_LENGTH 10 +#define MBS_CONTENTS_ID_LENGTH 10 +#define GLOBAL_SF_CLASSNAME_LENGTH 6 + +#define TYPE_OF_SERVICE_LENGTH 3 +#define IP_MASKED_SRC_ADDRESS_LENGTH 32 +#define IP_MASKED_DEST_ADDRESS_LENGTH 32 +#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4 +#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4 +#define ETHERNET_DEST_MAC_ADDR_LENGTH 12 +#define ETHERNET_SRC_MAC_ADDR_LENGTH 12 +#define NUM_ETHERTYPE_BYTES 3 +#define NUM_IPV6_FLOWLABLE_BYTES 3 + + +//////////////////////////////////////////////////////////////////////////////// +////////////////////////structure Definitions/////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// \brief class cCPacketClassificationRule +#ifdef BECEEM_TARGET +class CCPacketClassificationRuleSI{ + public: + /// \brief Constructor for the class + CCPacketClassificationRuleSI(): + u8ClassifierRulePriority(mClassifierRulePriority), + u8IPTypeOfServiceLength(mIPTypeOfService), + u8Protocol(mProtocol), + u8IPMaskedSourceAddressLength(0), + u8IPDestinationAddressLength(0), + u8ProtocolSourcePortRangeLength(0), + u8ProtocolDestPortRangeLength(0), + u8EthernetDestMacAddressLength(0), + u8EthernetSourceMACAddressLength(0), + u8EthertypeLength(0), + u16UserPriority(mUserPriority), + u16VLANID(mVLANID), + u8AssociatedPHSI(mAssociatedPHSI), + u16PacketClassificationRuleIndex(mPacketClassifierRuleIndex), + u8VendorSpecificClassifierParamLength(mVendorSpecificClassifierParamLength), + u8IPv6FlowLableLength(mIPv6FlowLableLength), + u8ClassifierActionRule(mClassifierActionRule) + + {} + void Reset() + { + CCPacketClassificationRuleSI(); + } +#else +struct _stCPacketClassificationRuleSI{ +#endif + + /** 16bit UserPriority Of The Service Flow*/ + B_UINT16 u16UserPriority; + /** 16bit VLANID Of The Service Flow*/ + B_UINT16 u16VLANID; + /** 16bit Packet Classification RuleIndex Of The Service Flow*/ + B_UINT16 u16PacketClassificationRuleIndex; + /** 8bit Classifier Rule Priority Of The Service Flow*/ + B_UINT8 u8ClassifierRulePriority; + /** Length of IP TypeOfService field*/ + B_UINT8 u8IPTypeOfServiceLength; + /** 3bytes IP TypeOfService */ + B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; + /** Protocol used in classification of Service Flow*/ + B_UINT8 u8Protocol; + /** Length of IP Masked Source Address */ + B_UINT8 u8IPMaskedSourceAddressLength; + /** IP Masked Source Address used in classification for the Service Flow*/ + B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; + /** Length of IP Destination Address */ + B_UINT8 u8IPDestinationAddressLength; + /** IP Destination Address used in classification for the Service Flow*/ + B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; + /** Length of Protocol Source Port Range */ + B_UINT8 u8ProtocolSourcePortRangeLength; + /** Protocol Source Port Range used in the Service Flow*/ + B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; + /** Length of Protocol Dest Port Range */ + B_UINT8 u8ProtocolDestPortRangeLength; + /** Protocol Dest Port Range used in the Service Flow*/ + B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; + /** Length of Ethernet Destination MAC Address */ + B_UINT8 u8EthernetDestMacAddressLength; + /** Ethernet Destination MAC Address used in classification of the Service Flow*/ + B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; + /** Length of Ethernet Source MAC Address */ + B_UINT8 u8EthernetSourceMACAddressLength; + /** Ethernet Source MAC Address used in classification of the Service Flow*/ + B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; + /** Length of Ethertype */ + B_UINT8 u8EthertypeLength; + /** 3bytes Ethertype Of The Service Flow*/ + B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES]; + /** 8bit Associated PHSI Of The Service Flow*/ + B_UINT8 u8AssociatedPHSI; + /** Length of Vendor Specific Classifier Param length Of The Service Flow*/ + B_UINT8 u8VendorSpecificClassifierParamLength; + /** Vendor Specific Classifier Param Of The Service Flow*/ + B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; + /** Length Of IPv6 Flow Lable of the Service Flow*/ + B_UINT8 u8IPv6FlowLableLength; + /** IPv6 Flow Lable Of The Service Flow*/ + B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; + /** Action associated with the classifier rule*/ + B_UINT8 u8ClassifierActionRule; + B_UINT16 u16ValidityBitMap; +}; +#ifndef BECEEM_TARGET +typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; +#endif + +/// \brief class CPhsRuleSI +#ifdef BECEEM_TARGET +class CPhsRuleSI{ + public: + /// \brief Constructor for the class + CPhsRuleSI(): + u8PHSI(mPHSI), + u8PHSFLength(0), + u8PHSMLength(0), + u8PHSS(mPHSS), + u8PHSV(mPHSV), + u8VendorSpecificPHSParamsLength(mVendorSpecificPHSParamLength){} + void Reset() + { + CPhsRuleSI(); + } +#else +typedef struct _stPhsRuleSI { +#endif + /** 8bit PHS Index Of The Service Flow*/ + B_UINT8 u8PHSI; + /** PHSF Length Of The Service Flow*/ + B_UINT8 u8PHSFLength; + /** String of bytes containing header information to be supressed by the sending CS and reconstructed by the receiving CS*/ + B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; + /** PHSM Length Of The Service Flow*/ + B_UINT8 u8PHSMLength; + /** PHS Mask for the SF*/ + B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; + /** 8bit Total number of bytes to be supressed for the Service Flow*/ + B_UINT8 u8PHSS; + /** 8bit Indicates whether or not Packet Header contents need to be verified prior to supression */ + B_UINT8 u8PHSV; + /** Vendor Specific PHS param Length Of The Service Flow*/ + B_UINT8 u8VendorSpecificPHSParamsLength; + /** Vendor Specific PHS param Of The Service Flow*/ + B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; + + B_UINT8 u8Padding[2]; +#ifdef BECEEM_TARGET +}; +#else +}stPhsRuleSI,*pstPhsRuleSI; +typedef stPhsRuleSI CPhsRuleSI; +#endif + +/// \brief structure cConvergenceSLTypes +#ifdef BECEEM_TARGET +class CConvergenceSLTypes{ + public: + /// \brief Constructor for the class + CConvergenceSLTypes(): + u8ClassfierDSCAction(mClassifierDSCAction), + u8PhsDSCAction (mPhsDSCAction) + {} + void Reset() + { + CConvergenceSLTypes(); + cCPacketClassificationRule.Reset(); + cPhsRule.Reset(); + } +#else +struct _stConvergenceSLTypes{ +#endif + /** 8bit Phs Classfier Action Of The Service Flow*/ + B_UINT8 u8ClassfierDSCAction; + /** 8bit Phs DSC Action Of The Service Flow*/ + B_UINT8 u8PhsDSCAction; + /** 16bit Padding */ + B_UINT8 u8Padding[2]; + /// \brief class cCPacketClassificationRule +#ifdef BECEEM_TARGET + CCPacketClassificationRuleSI cCPacketClassificationRule; +#else + stCPacketClassificationRuleSI cCPacketClassificationRule; +#endif + /// \brief class CPhsRuleSI +#ifdef BECEEM_TARGET + CPhsRuleSI cPhsRule; +#else + struct _stPhsRuleSI cPhsRule; +#endif +}; +#ifndef BECEEM_TARGET +typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes; +#endif + + +/// \brief structure CServiceFlowParamSI +#ifdef BECEEM_TARGET +class CServiceFlowParamSI{ + public: + /// \brief Constructor for the class + CServiceFlowParamSI(): + u32SFID(mSFid), + u16CID(mCid), + u8ServiceClassNameLength(mServiceClassNameLength), + u8MBSService(mMBSService), + u8QosParamSet(mQosParamSetType), + u8TrafficPriority(mTrafficPriority), + u32MaxSustainedTrafficRate(mMaximumSustainedTrafficRate), + u32MaxTrafficBurst(mMaximumTrafficBurst), + u32MinReservedTrafficRate(mMinimumReservedTrafficRate), + u8ServiceFlowSchedulingType(mServiceFlowSchedulingType), + u8RequesttransmissionPolicy(mRequestTransmissionPolicy), + u32ToleratedJitter(mToleratedJitter), + u32MaximumLatency(mMaximumLatency), + u8FixedLengthVSVariableLengthSDUIndicator + (mFixedLengthVSVariableLength), + u8SDUSize(mSDUSize), + u16TargetSAID(mTargetSAID), + u8ARQEnable(mARQEnable), + u16ARQWindowSize(mARQWindowSize), + u16ARQBlockLifeTime(mARQBlockLifeTime), + u16ARQSyncLossTimeOut(mARQSyncLossTimeOut), + u8ARQDeliverInOrder(mARQDeliverInOrder), + u16ARQRxPurgeTimeOut(mARQRXPurgeTimeOut), + //Add ARQ BLOCK SIZE, ARQ TX and RX delay initializations here + //after we move to only CORR2 + u8RxARQAckProcessingTime(mRxARQAckProcessingTime), + u8CSSpecification(mCSSpecification), + u8TypeOfDataDeliveryService(mTypeOfDataDeliveryService), + u16SDUInterArrivalTime(mSDUInterArrivalTime), + u16TimeBase(mTimeBase), + u8PagingPreference(mPagingPreference), + u8MBSZoneIdentifierassignment(mMBSZoneIdentifierassignmentLength), + u8TrafficIndicationPreference(mTrafficIndicationPreference), + u8GlobalServicesClassNameLength(mGlobalServicesClassNameLength), + u8SNFeedbackEnabled(mSNFeedbackEnabled), + u8FSNSize(mFSNSize), + u8CIDAllocation4activeBSsLength(mCIDAllocation4activeBSsLength), + u16UnsolicitedGrantInterval(mUnsolicitedGrantInterval), + u16UnsolicitedPollingInterval(mUnsolicitedPollingInterval), + u8PDUSNExtendedSubheader4HarqReordering(mPDUSNExtendedSubheader4HarqReordering), + u8MBSContentsIDLength(mMBSContentsIDLength), + u8HARQServiceFlows(mHARQServiceFlows), + u8AuthTokenLength(mAuthTokenLength), + u8HarqChannelMappingLength(mHarqChannelMappingLength), + u8VendorSpecificQoSParamLength(mVendorSpecificQoSParamLength), + bValid(FALSE), + u8TotalClassifiers() +{ +//Remove the bolck after we move to Corr2 only code +#ifdef ENABLE_CORRIGENDUM2_UPDATE + if((g_u32Corr2MacFlags & CORR_2_DSX) || (g_u32Corr2MacFlags & CORR_2_ARQ)) + { + /* IEEE Comment #627 / MTG Comment #426 */ + u16ARQBlockSize = mARQBlockSize; + if(g_u32Corr2MacFlags & CORR_2_ARQ) { + u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelay; + if(g_u32VENDOR_TYPE == VENDOR_ALCATEL) { + u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay_ALU; + } else { + u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay; + } + } + else + { + u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1; + u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1; + } + } + else +#endif + { + u16ARQBlockSize = mARQBlockSizeCorr1; + u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1; + u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1; + } +} + + void ComputeMacOverhead(B_UINT8 u8SecOvrhead); + B_UINT16 GetMacOverhead() { return u16MacOverhead; } +#else +typedef struct _stServiceFlowParamSI{ +#endif //end of ifdef BECEEM_TARGET + + /** 32bitSFID Of The Service Flow*/ + B_UINT32 u32SFID; + + /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/ + B_UINT32 u32MaxSustainedTrafficRate; + + /** 32bit Maximum Traffic Burst allowed for the Service Flow*/ + B_UINT32 u32MaxTrafficBurst; + + /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/ + B_UINT32 u32MinReservedTrafficRate; + + /** 32bit Tolerated Jitter of the Service Flow*/ + B_UINT32 u32ToleratedJitter; + + /** 32bit Maximum Latency of the Service Flow*/ + B_UINT32 u32MaximumLatency; + + /** 16bitCID Of The Service Flow*/ + B_UINT16 u16CID; + + /** 16bit SAID on which the service flow being set up shall be mapped*/ + B_UINT16 u16TargetSAID; + + /** 16bit ARQ window size negotiated*/ + B_UINT16 u16ARQWindowSize; + + /** 16bit Total Tx delay incl sending, receiving & processing delays */ + B_UINT16 u16ARQRetryTxTimeOut; + + /** 16bit Total Rx delay incl sending, receiving & processing delays */ + B_UINT16 u16ARQRetryRxTimeOut; + + /** 16bit ARQ block lifetime */ + B_UINT16 u16ARQBlockLifeTime; + + /** 16bit ARQ Sync loss timeout*/ + B_UINT16 u16ARQSyncLossTimeOut; + + /** 16bit ARQ Purge timeout */ + B_UINT16 u16ARQRxPurgeTimeOut; +#if 0 //def ENABLE_CORRIGENDUM2_UPDATE +/* IEEE Comment #627 / MTG Comment #426 */ + /// \brief Size of an ARQ block, changed from 2 bytes to 1 + B_UINT8 u8ARQBlockSize; +#endif +//TODO::Remove this once we move to a new CORR2 driver + /// \brief Size of an ARQ block + B_UINT16 u16ARQBlockSize; + +//#endif + /** 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/ + B_UINT16 u16SDUInterArrivalTime; + + /** 16bit Specifies the time base for rate measurement */ + B_UINT16 u16TimeBase; + + /** 16bit Interval b/w Successive Grant oppurtunities*/ + B_UINT16 u16UnsolicitedGrantInterval; + + /** 16bit Interval b/w Successive Polling grant oppurtunities*/ + B_UINT16 u16UnsolicitedPollingInterval; + + /** internal var to get the overhead */ + B_UINT16 u16MacOverhead; + + /** MBS contents Identifier*/ + B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; + + /** MBS contents Identifier length*/ + B_UINT8 u8MBSContentsIDLength; + + /** ServiceClassName Length Of The Service Flow*/ + B_UINT8 u8ServiceClassNameLength; + + /** 32bytes ServiceClassName Of The Service Flow*/ + B_UINT8 u8ServiceClassName[32]; + + /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/ + B_UINT8 u8MBSService; + + /** 8bit QOS Parameter Set specifies proper application of QoS paramters to Provisioned, Admitted and Active sets*/ + B_UINT8 u8QosParamSet; + + /** 8bit Traffic Priority Of the Service Flow */ + B_UINT8 u8TrafficPriority; + + /** 8bit Uplink Grant Scheduling Type of The Service Flow */ + B_UINT8 u8ServiceFlowSchedulingType; + + /** 8bit Request transmission Policy of the Service Flow*/ + B_UINT8 u8RequesttransmissionPolicy; + + /** 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ + B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator; + + /** 8bit Length of the SDU for a fixed length SDU service flow*/ + B_UINT8 u8SDUSize; + + /** 8bit Indicates whether or not ARQ is requested for this connection*/ + B_UINT8 u8ARQEnable; + + /**< 8bit Indicates whether or not data has tobe delivered in order to higher layer*/ + B_UINT8 u8ARQDeliverInOrder; + + /** 8bit Receiver ARQ ACK processing time */ + B_UINT8 u8RxARQAckProcessingTime; + + /** 8bit Convergence Sublayer Specification Of The Service Flow*/ + B_UINT8 u8CSSpecification; + + /** 8 bit Type of data delivery service*/ + B_UINT8 u8TypeOfDataDeliveryService; + + /** 8bit Specifies whether a service flow may generate Paging */ + B_UINT8 u8PagingPreference; + + /** 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ + B_UINT8 u8MBSZoneIdentifierassignment; + + /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/ + B_UINT8 u8TrafficIndicationPreference; + + /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ + B_UINT8 u8GlobalServicesClassNameLength; + + /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ + B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; + + /** 8bit Indicates whether or not SN feedback is enabled for the conn */ + B_UINT8 u8SNFeedbackEnabled; + + /** Indicates the size of the Fragment Sequence Number for the connection */ + B_UINT8 u8FSNSize; + + /** 8bit Number of CIDs in active BS list */ + B_UINT8 u8CIDAllocation4activeBSsLength; + + /** CIDs of BS in the active list */ + B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; + + /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/ + B_UINT8 u8PDUSNExtendedSubheader4HarqReordering; + + /** 8bit Specifies whether the connection uses HARQ or not */ + B_UINT8 u8HARQServiceFlows; + + /** Specifies the length of Authorization token*/ + B_UINT8 u8AuthTokenLength; + + /** Specifies the Authorization token*/ + B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH]; + + /** specifes Number of HARQ channels used to carry data length*/ + B_UINT8 u8HarqChannelMappingLength; + + /** specifes HARQ channels used to carry data*/ + B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; + + /** 8bit Length of Vendor Specific QoS Params */ + B_UINT8 u8VendorSpecificQoSParamLength; + + /** 1byte Vendor Specific QoS Param Of The Service Flow*/ + B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; + + // indicates total classifiers in the SF + B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/ + B_UINT8 bValid; /**< Validity flag */ + B_UINT8 u8Padding; /**< Padding byte*/ + +#ifdef BECEEM_TARGET +/** +Structure for Convergence SubLayer Types with a maximum of 4 classifiers +*/ + CConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; +#else +/** +Structure for Convergence SubLayer Types with a maximum of 4 classifiers +*/ + stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; +#endif + +#ifdef BECEEM_TARGET +}; +#else +} stServiceFlowParamSI, *pstServiceFlowParamSI; +typedef stServiceFlowParamSI CServiceFlowParamSI; +#endif + +/** +structure stLocalSFAddRequest +*/ +typedef struct _stLocalSFAddRequest{ +#ifdef BECEEM_TARGET + _stLocalSFAddRequest( ) : + u8Type(0x00), eConnectionDir(0x00), + u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000) + {} +#endif + + B_UINT8 u8Type; /**< Type*/ + B_UINT8 eConnectionDir; /**< Connection direction*/ + /// \brief 16 bit TID + B_UINT16 u16TID; /**< 16bit TID*/ + /// \brief 16bitCID + B_UINT16 u16CID; /**< 16bit CID*/ + /// \brief 16bitVCID + B_UINT16 u16VCID; /**< 16bit VCID*/ + /// \brief structure ParameterSet +#ifdef BECEEM_SIGNALLING_INTERFACE_API + CServiceFlowParamSI sfParameterSet; +#endif + +#ifdef BECEEM_TARGET + CServiceFlowParamSI *psfParameterSet; +#else + stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/ +#endif + +#ifdef USING_VXWORKS + USE_DATA_MEMORY_MANAGER(); +#endif +}stLocalSFAddRequest, *pstLocalSFAddRequest; + + +/** +structure stLocalSFAddIndication +*/ +typedef struct _stLocalSFAddIndication{ +#ifdef BECEEM_TARGET + _stLocalSFAddIndication( ) : + u8Type(0x00), eConnectionDir(0x00), + u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000) + {} +#endif + + B_UINT8 u8Type; /**< Type*/ + B_UINT8 eConnectionDir; /**< Connection Direction*/ + /// \brief 16 bit TID + B_UINT16 u16TID; /**< TID*/ + /// \brief 16bitCID + B_UINT16 u16CID; /**< 16bitCID*/ + /// \brief 16bitVCID + B_UINT16 u16VCID; /**< 16bitVCID*/ + +#ifdef BECEEM_SIGNALLING_INTERFACE_API + CServiceFlowParamSI sfAuthorizedSet; + /// \brief structure AdmittedSet + CServiceFlowParamSI sfAdmittedSet; + /// \brief structure ActiveSet + CServiceFlowParamSI sfActiveSet; +#endif + + /// \brief structure AuthorizedSet +#ifdef BECEEM_TARGET + CServiceFlowParamSI *psfAuthorizedSet; + /// \brief structure AdmittedSet + CServiceFlowParamSI *psfAdmittedSet; + /// \brief structure ActiveSet + CServiceFlowParamSI *psfActiveSet; +#else + /// \brief structure AuthorizedSet + stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/ + /// \brief structure AdmittedSet + stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/ + /// \brief structure ActiveSet + stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/ +#endif + B_UINT8 u8CC; /**< Confirmation Code*/ + B_UINT8 u8Padd; /**< 8-bit Padding */ + + B_UINT16 u16Padd; /**< 16 bit Padding */ + +#ifdef USING_VXWORKS + USE_DATA_MEMORY_MANAGER(); +#endif +}stLocalSFAddIndication; + + +typedef struct _stLocalSFAddIndication *pstLocalSFAddIndication; +/** +structure stLocalSFChangeRequest is same as structure stLocalSFAddIndication +*/ +typedef struct _stLocalSFAddIndication stLocalSFChangeRequest, *pstLocalSFChangeRequest; +/** +structure stLocalSFChangeIndication is same as structure stLocalSFAddIndication +*/ +typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFChangeIndication; + +/** +structure stLocalSFDeleteRequest +*/ +typedef struct _stLocalSFDeleteRequest{ +#ifdef BECEEM_TARGET + _stLocalSFDeleteRequest( ) : + u8Type(0x00), u8Padding(0x00), + u16TID(0x0000), u32SFID (0x00000000) + {} +#endif + B_UINT8 u8Type; /**< Type*/ + B_UINT8 u8Padding; /**< Padding byte*/ + B_UINT16 u16TID; /**< TID*/ + /// \brief 32bitSFID + B_UINT32 u32SFID; /**< SFID*/ +#ifdef USING_VXWORKS + USE_DATA_MEMORY_MANAGER(); +#endif +}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest; + +/** +structure stLocalSFDeleteIndication +*/ +typedef struct stLocalSFDeleteIndication{ +#ifdef BECEEM_TARGET + stLocalSFDeleteIndication( ) : + u8Type(0x00), u8Padding(0x00), + u16TID(0x0000), u16CID(0x0000), + u16VCID(0x0000),u32SFID (0x00000000) + {} +#endif + B_UINT8 u8Type; /**< Type */ + B_UINT8 u8Padding; /**< Padding */ + B_UINT16 u16TID; /**< TID */ + /// \brief 16bitCID + B_UINT16 u16CID; /**< CID */ + /// \brief 16bitVCID + B_UINT16 u16VCID; /**< VCID */ + /// \brief 32bitSFID + B_UINT32 u32SFID; /**< SFID */ + /// \brief 8bit Confirmation code + B_UINT8 u8ConfirmationCode; /**< Confirmation code */ + B_UINT8 u8Padding1[3]; /**< 3 byte Padding */ +#ifdef USING_VXWORKS + USE_DATA_MEMORY_MANAGER(); +#endif +}stLocalSFDeleteIndication; + +typedef struct _stIM_SFHostNotify +{ + B_UINT32 SFID; //SFID of the service flow + B_UINT16 newCID; //the new/changed CID + B_UINT16 VCID; //Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid + B_UINT8 RetainSF; //Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete + B_UINT8 QoSParamSet; //QoS paramset of the retained SF + B_UINT16 u16reserved; //For byte alignment + +} stIM_SFHostNotify; + +#endif diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h new file mode 100644 index 000000000000..9d4e3aca1b34 --- /dev/null +++ b/drivers/staging/bcm/headers.h @@ -0,0 +1,109 @@ + +/******************************************************************* +* Headers.h +*******************************************************************/ +#ifndef __HEADERS_H__ +#define __HEADERS_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 +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include +#endif +#include +#include +#ifndef BCM_SHM_INTERFACE +#include +#endif +#ifdef BECEEM_TARGET + +#include +#include +#include +#include +#include +using namespace Beceem; +#ifdef ENABLE_CORRIGENDUM2_UPDATE +extern B_UINT32 g_u32Corr2MacFlags; +#endif +#endif + +#include "Typedefs.h" +#include "Version.h" +#include "Macros.h" +#include "HostMIBSInterface.h" +#include "cntrl_SignalingInterface.h" +#include "PHSDefines.h" +#include "led_control.h" +#include "Ioctl.h" +#include "nvm.h" +#include "target_params.h" +#include "Adapter.h" +#include "CmHost.h" +#include "DDRInit.h" +#include "Debug.h" +#include "HostMibs.h" +#include "IPv6ProtocolHdr.h" +#include "osal_misc.h" +#include "PHSModule.h" +#include "Protocol.h" +#include "Prototypes.h" +#include "Queue.h" +#include "vendorspecificextn.h" + +#ifndef BCM_SHM_INTERFACE + +#include "InterfaceMacros.h" +#include "InterfaceAdapter.h" +#include "InterfaceIsr.h" +#include "Interfacemain.h" +#include "InterfaceMisc.h" +#include "InterfaceRx.h" +#include "InterfaceTx.h" +#endif +#include "InterfaceIdleMode.h" +#include "InterfaceInit.h" + +#ifdef BCM_SHM_INTERFACE +#include + +#ifdef GDMA_INTERFACE +#include "GdmaInterface.h" +#include "symphony.h" +#else +#include "virtual_interface.h" + +#endif + +#endif + +#endif diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c new file mode 100644 index 000000000000..e9da513b3c24 --- /dev/null +++ b/drivers/staging/bcm/hostmibs.c @@ -0,0 +1,164 @@ + +/* + * File Name: hostmibs.c + * + * Author: Beceem Communications Pvt. Ltd + * + * Abstract: This file contains the routines to copy the statistics used by + * the driver to the Host MIBS structure and giving the same to Application. + * + */ +#include "headers.h" + +INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, + PVOID ioBuffer, + ULONG inputBufferLength) +{ + + S_MIBS_HOST_STATS_MIBS *pstHostMibs = NULL; + S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; + S_PHS_RULE *pstPhsRule = NULL; + S_CLASSIFIER_TABLE *pstClassifierTable = NULL; + S_CLASSIFIER_ENTRY *pstClassifierRule = NULL; + PPHS_DEVICE_EXTENSION pDeviceExtension = (PPHS_DEVICE_EXTENSION)&Adapter->stBCMPhsContext; + + UINT nClassifierIndex = 0, nPhsTableIndex = 0,nSfIndex = 0, uiIndex = 0; + + if(pDeviceExtension == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, HOST_MIBS, DBG_LVL_ALL, "Invalid Device Extension\n"); + return STATUS_FAILURE; + } + + if(ioBuffer == NULL) + { + return -EINVAL; + } + memset(ioBuffer,0,sizeof(S_MIBS_HOST_STATS_MIBS)); + + pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer; + + + //Copy the classifier Table + for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS; + nClassifierIndex++) + { + if(Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE) + memcpy((PVOID)&pstHostMibs->astClassifierTable[nClassifierIndex], + (PVOID)&Adapter->astClassifierTable[nClassifierIndex], + sizeof(S_MIBS_CLASSIFIER_RULE)); + } + + //Copy the SF Table + for(nSfIndex=0; nSfIndex < NO_OF_QUEUES ; nSfIndex++) + { + if(Adapter->PackInfo[nSfIndex].bValid) + { + OsalMemMove((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE)); + } + else + { + //if index in not valid, don't process this for the PHS table. Go For the next entry. + continue ; + } + + //Retrieve the SFID Entry Index for requested Service Flow + if(PHS_INVALID_TABLE_INDEX == GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, + Adapter->PackInfo[nSfIndex].usVCID_Value ,&pstServiceFlowEntry)) + { + + continue; + } + + pstClassifierTable = pstServiceFlowEntry->pstClassifierTable; + + + for(uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++) + { + pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[uiIndex]; + + if(pstClassifierRule->bUsed) + { + pstPhsRule = pstClassifierRule->pstPhsRule; + + pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID; + + OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI, + &pstPhsRule->u8PHSI, + sizeof(S_PHS_RULE)); + nPhsTableIndex++; + + } + + } + + } + + + + //copy other Host Statistics parameters + pstHostMibs->stHostInfo.GoodTransmits = + atomic_read(&Adapter->TxTotalPacketCount); + pstHostMibs->stHostInfo.GoodReceives = + atomic_read(&Adapter->GoodRxPktCount); + pstHostMibs->stHostInfo.CurrNumFreeDesc = + atomic_read(&Adapter->CurrNumFreeTxDesc); + pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize; + pstHostMibs->stHostInfo.rtPSBucketSize = Adapter->rtPSBucketSize; + pstHostMibs->stHostInfo.TimerActive = Adapter->TimerActive; + pstHostMibs->stHostInfo.u32TotalDSD = Adapter->u32TotalDSD; + + memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist,Adapter->aTxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES); + memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist,Adapter->aRxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES); + + return STATUS_SUCCESS; +} + + +INT GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang) +{ + S_MIBS_HOST_STATS_MIBS *pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer; + + memcpy((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); + + return STATUS_SUCCESS ; +} + + +VOID CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, + CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex) +{ + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfSfid = psfLocalSet->u32SFID; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = psfLocalSet->u8ServiceFlowSchedulingType; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohs(psfLocalSet->u16ARQBlockLifeTime); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohs(psfLocalSet->u16ARQSyncLossTimeOut); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohs(psfLocalSet->u16ARQRxPurgeTimeOut); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification; + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID); + Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid); + +} diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c new file mode 100644 index 000000000000..0d07664e10f9 --- /dev/null +++ b/drivers/staging/bcm/led_control.c @@ -0,0 +1,1006 @@ +#include "headers.h" + +#define STATUS_IMAGE_CHECKSUM_MISMATCH -199 +#define EVENT_SIGNALED 1 + +static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size) +{ + B_UINT16 u16CheckSum=0; + while(u32Size--) { + u16CheckSum += (B_UINT8)~(*pu8Buffer); + pu8Buffer++; + } + return u16CheckSum; +} +BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios) +{ + INT Status ; + Status = (Adapter->gpioBitMap & gpios) ^ gpios ; + if(Status) + return FALSE; + else + return TRUE; +} + +INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate) +{ + int Status = STATUS_SUCCESS; + BOOLEAN bInfinite = FALSE; + + /*Check if num_of_time is -ve. If yes, blink led in infinite loop*/ + if(num_of_time < 0) + { + bInfinite = TRUE; + num_of_time = 1; + } + while(num_of_time) + { + + if(currdriverstate == Adapter->DriverState) + TURN_ON_LED(GPIO_Num, uiLedIndex); + + /*Wait for timeout after setting on the LED*/ + Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event, + currdriverstate != Adapter->DriverState || kthread_should_stop(), + msecs_to_jiffies(timeout)); + + if(kthread_should_stop()) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting"); + Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED; + TURN_OFF_LED(GPIO_Num, uiLedIndex); + Status=EVENT_SIGNALED; + break; + } + if(Status) + { + TURN_OFF_LED(GPIO_Num, uiLedIndex); + Status=EVENT_SIGNALED; + break; + } + + TURN_OFF_LED(GPIO_Num, uiLedIndex); + Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event, + currdriverstate!= Adapter->DriverState || kthread_should_stop(), + msecs_to_jiffies(timeout)); + if(bInfinite == FALSE) + num_of_time--; + } + return Status; +} + +INT ScaleRateofTransfer(ULONG rate) +{ + if(rate <= 3) + return rate; + else if((rate > 3) && (rate <= 100)) + return 5; + else if((rate > 100) && (rate <= 200)) + return 6; + else if((rate > 200) && (rate <= 300)) + return 7; + else if((rate > 300) && (rate <= 400)) + return 8; + else if((rate > 400) && (rate <= 500)) + return 9; + else if((rate > 500) && (rate <= 600)) + return 10; + else + return MAX_NUM_OF_BLINKS; +} + + + +INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, + UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate) +{ + /* Initial values of TX and RX packets*/ + ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0; + /*values of TX and RX packets after 1 sec*/ + ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0; + /*Rate of transfer of Tx and Rx in 1 sec*/ + ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0; + int Status = STATUS_SUCCESS; + INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0; + UINT remDelay = 0; + BOOLEAN bBlinkBothLED = TRUE; + //UINT GPIO_num = DISABLE_GPIO_NUM; + ulong timeout = 0; + + /*Read initial value of packets sent/received */ + Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount); + Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount); + /*Scale the rate of transfer to no of blinks.*/ + num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx); + num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx); + + while((Adapter->device_removed == FALSE)) + { + #if 0 + if(0 == num_of_time_tx && 0 == num_of_time_rx) + { + timeout = 1000; + Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event, + currdriverstate!= Adapter->DriverState || kthread_should_stop(), + msecs_to_jiffies (timeout)); + if(kthread_should_stop()) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting"); + Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED; + return EVENT_SIGNALED; + } + if(Status) + return EVENT_SIGNALED; + + } + #endif + + timeout = 50; + #if 0 + /*Turn on LED if Tx is high bandwidth*/ + if(num_of_time_tx > MAX_NUM_OF_BLINKS) + { + TURN_ON_LED(1< MAX_NUM_OF_BLINKS) + { + TURN_ON_LED(1< num_of_time_rx) + num_of_time = num_of_time_rx; + else + num_of_time = num_of_time_tx; + if(num_of_time > 0) + { + /*Blink both Tx and Rx LEDs*/ + if(LED_Blink(Adapter, 1< 0) + { + timeout= 100 * remDelay; + Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event, + currdriverstate!= Adapter->DriverState ||kthread_should_stop() , + msecs_to_jiffies (timeout)); + + if(kthread_should_stop()) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting"); + Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED; + return EVENT_SIGNALED; + } + if(Status) + return EVENT_SIGNALED; + } + + /*Turn off both Tx and Rx LEDs before next second*/ + TURN_OFF_LED(1<TxTotalPacketCount); + rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx; + Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount); + rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx; + + /*Read initial value of packets sent/received */ + Initial_num_of_packts_tx = Final_num_of_packts_tx; + Initial_num_of_packts_rx = Final_num_of_packts_rx ; + + /*Scale the rate of transfer to no of blinks.*/ + num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx); + num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx); + + } + return Status; +} + + +//----------------------------------------------------------------------------- +// Procedure: ValidateDSDParamsChecksum +// +// Description: Reads DSD Params and validates checkusm. +// +// Arguments: +// Adapter - Pointer to Adapter structure. +// ulParamOffset - Start offset of the DSD parameter to be read and validated. +// usParamLen - Length of the DSD Parameter. +// +// Returns: +// +//----------------------------------------------------------------------------- + +INT ValidateDSDParamsChecksum( + PMINI_ADAPTER Adapter, + ULONG ulParamOffset, + USHORT usParamLen ) +{ + INT Status = STATUS_SUCCESS; + PUCHAR puBuffer = NULL; + USHORT usChksmOrg = 0; + USHORT usChecksumCalculated = 0; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen); + + puBuffer = OsalMemAlloc(usParamLen,'!MEM'); + if(!puBuffer) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed"); + return -ENOMEM; + + } + + // + // Read the DSD data from the parameter offset. + // + if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)puBuffer,ulParamOffset,usParamLen)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); + Status=STATUS_IMAGE_CHECKSUM_MISMATCH; + goto exit; + } + + // + // Calculate the checksum of the data read from the DSD parameter. + // + usChecksumCalculated = CFG_CalculateChecksum(puBuffer,usParamLen); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated); + + // + // End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated + // Checksum. + // + if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)&usChksmOrg,ulParamOffset+usParamLen,2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); + Status=STATUS_IMAGE_CHECKSUM_MISMATCH; + goto exit; + } + usChksmOrg = ntohs(usChksmOrg); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usChksmOrg = 0x%x", usChksmOrg); + + // + // Compare the checksum calculated with the checksum read from DSD section + // + if(usChecksumCalculated ^ usChksmOrg) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum: Checksums don't match"); + Status = STATUS_IMAGE_CHECKSUM_MISMATCH; + goto exit; + } + +exit: + if(puBuffer) + { + OsalMemFree(puBuffer, usParamLen); + } + return Status; +} + + +//----------------------------------------------------------------------------- +// Procedure: ValidateHWParmStructure +// +// Description: Validates HW Parameters. +// +// Arguments: +// Adapter - Pointer to Adapter structure. +// ulHwParamOffset - Start offset of the HW parameter Section to be read and validated. +// +// Returns: +// +//----------------------------------------------------------------------------- + +INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset) +{ + + INT Status = STATUS_SUCCESS ; + USHORT HwParamLen = 0; + // Add DSD start offset to the hwParamOffset to get the actual address. + ulHwParamOffset += DSD_START_OFFSET; + + /*Read the Length of HW_PARAM structure*/ + BeceemNVMRead(Adapter,(PUINT)&HwParamLen,ulHwParamOffset,2); + HwParamLen = ntohs(HwParamLen); + if(0==HwParamLen || HwParamLen > Adapter->uiNVMDSDSize) + { + return STATUS_IMAGE_CHECKSUM_MISMATCH; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen); + Status =ValidateDSDParamsChecksum(Adapter,ulHwParamOffset,HwParamLen); + return Status; +} /* ValidateHWParmStructure() */ + +int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[]) +{ + int Status = STATUS_SUCCESS; + + ULONG dwReadValue = 0; + USHORT usHwParamData = 0; + USHORT usEEPROMVersion = 0; + UCHAR ucIndex = 0; + UCHAR ucGPIOInfo[32] = {0}; + + BeceemNVMRead(Adapter,(PUINT)&usEEPROMVersion,EEPROM_VERSION_OFFSET,2); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"usEEPROMVersion: Minor:0x%X Major:0x%x",usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF)); + + + if(((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) + { + BeceemNVMRead(Adapter,(PUINT)&usHwParamData,EEPROM_HW_PARAM_POINTER_ADDRESS,2); + usHwParamData = ntohs(usHwParamData); + dwReadValue = usHwParamData; + } + else + { + // + // Validate Compatibility section and then read HW param if compatibility section is valid. + // + Status = ValidateDSDParamsChecksum(Adapter, + DSD_START_OFFSET, + COMPATIBILITY_SECTION_LENGTH_MAP5); + + if(Status != STATUS_SUCCESS) + { + return Status; + } + BeceemNVMRead(Adapter,(PUINT)&dwReadValue,EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5,4); + dwReadValue = ntohl(dwReadValue); + } + + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Start address of HW_PARAM structure = 0x%lx",dwReadValue); + + // + // Validate if the address read out is within the DSD. + // Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit. + // lower limit should be above DSD_START_OFFSET and + // upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET) + // + if(dwReadValue < DSD_START_OFFSET || + dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET)) + { + return STATUS_IMAGE_CHECKSUM_MISMATCH; + } + + Status = ValidateHWParmStructure(Adapter, dwReadValue); + if(Status){ + return Status; + } + + /* + Add DSD_START_OFFSET to the offset read from the EEPROM. + This will give the actual start HW Parameters start address. + To read GPIO section, add GPIO offset further. + */ + + dwReadValue += DSD_START_OFFSET; // = start address of hw param section. + dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section. + + /* Read the GPIO values for 32 GPIOs from EEPROM and map the function + * number to GPIO pin number to GPIO_Array + */ + BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo,dwReadValue,32); + for(ucIndex = 0; ucIndex < 32; ucIndex++) + { + + switch(ucGPIOInfo[ucIndex]) + { + case RED_LED: + { + GPIO_Array[RED_LED] = ucIndex; + Adapter->gpioBitMap |= (1<gpioBitMap |= (1<gpioBitMap |= (1<gpioBitMap |= (1<gpioBitMap); + return Status; +} + + +int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread) +{ + int Status = STATUS_SUCCESS; + UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/ +#ifndef BCM_SHM_INTERFACE + UINT uiIndex = 0; + UINT uiNum_of_LED_Type = 0; + PUCHAR puCFGData = NULL; + UCHAR bData = 0; +#endif + memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1); + + if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) + { + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n"); + return -ENOENT; + } + + /*Populate GPIO_Array with GPIO numbers for LED functions*/ + /*Read the GPIO numbers from EEPROM*/ + Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array); + if(Status == STATUS_IMAGE_CHECKSUM_MISMATCH) + { + *bEnableThread = FALSE; + return STATUS_SUCCESS; + } + else if(Status) + { + *bEnableThread = FALSE; + return Status; + } +#ifdef BCM_SHM_INTERFACE + *bEnableThread = FALSE; + return Status ; +#else + /* + * CONFIG file read successfully. Deallocate the memory of + * uiFileNameBufferSize + */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Config file read successfully\n"); + puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1; + + /* + * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which + * will have the information of LED type, LED on state for different + * driver state and LED blink state. + */ + + for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) + { + bData = *puCFGData; + + /*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/ + if(bData & 0x80) + { + Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0; + /*unset the bit 8*/ + bData = bData & 0x7f; + } + + Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData; + if(bData <= NUM_OF_LEDS) + Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData]; + else + Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM; + + puCFGData++; + bData = *puCFGData; + Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData; + puCFGData++; + bData = *puCFGData; + Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State= bData; + puCFGData++; + } + + /*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/ + for(uiIndex = 0; uiIndexLEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) || + (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) || + (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0)) + uiNum_of_LED_Type++; + } + if(uiNum_of_LED_Type >= NUM_OF_LEDS) + *bEnableThread = FALSE; +#endif + +#if 0 + for(uiIndex=0; uiIndexLEDInfo.LEDState[uiIndex].LED_Type); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex, + Adapter->LEDInfo.LEDState[uiIndex].LED_On_State); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex, + Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex, + Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num); + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n", + Adapter->LEDInfo.BitPolarty); +#endif + return Status; +} +//-------------------------------------------------------------------------- +// Procedure: LedGpioInit +// +// Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the +// initial state to be OFF. +// +// Arguments: +// Adapter - Pointer to MINI_ADAPTER structure. +// +// Returns: VOID +// +//----------------------------------------------------------------------------- + +VOID LedGpioInit(PMINI_ADAPTER Adapter) +{ + UINT uiResetValue = 0; + UINT uiIndex = 0; + + /* Set all LED GPIO Mode to output mode */ + if(rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) <0) + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: RDM Failed\n"); + for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) + { + if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) + uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num); + TURN_OFF_LED(1<LEDInfo.LEDState[uiIndex].GPIO_Num,uiIndex); + } + if(wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0) + BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: WRM Failed\n"); + + Adapter->LEDInfo.bIdle_led_off = FALSE; +} +//----------------------------------------------------------------------------- + +INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx ,UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,LedEventInfo_t currdriverstate) +{ + UINT uiIndex = 0; + + *GPIO_num_tx = DISABLE_GPIO_NUM; + *GPIO_num_rx = DISABLE_GPIO_NUM; + + for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) + { + + if((currdriverstate == NORMAL_OPERATION)|| + (currdriverstate == IDLEMODE_EXIT)|| + (currdriverstate == FW_DOWNLOAD)) + { + if(Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate) + { + if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) + { + if(*GPIO_num_tx == DISABLE_GPIO_NUM) + { + *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num; + *uiLedTxIndex = uiIndex; + } + else + { + *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num; + *uiLedRxIndex = uiIndex; + } + } + } + } + else + { + if(Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate) + { + if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) + { + *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num; + *uiLedTxIndex = uiIndex; + } + } + } + } + return STATUS_SUCCESS ; +} +VOID LEDControlThread(PMINI_ADAPTER Adapter) +{ + UINT uiIndex = 0; + UCHAR GPIO_num = 0; + UCHAR uiLedIndex = 0 ; + UINT uiResetValue = 0; + LedEventInfo_t currdriverstate = 0; + ulong timeout = 0; + + INT Status = 0; + + UCHAR dummyGPIONum = 0; + UCHAR dummyIndex = 0; + + //currdriverstate = Adapter->DriverState; + Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE; + + /*Wait till event is triggered*/ + //wait_event(Adapter->LEDInfo.notify_led_event, + // currdriverstate!= Adapter->DriverState); + + GPIO_num = DISABLE_GPIO_NUM ; + + while(TRUE) + { + /*Wait till event is triggered*/ + if( (GPIO_num == DISABLE_GPIO_NUM) + || + ((currdriverstate != FW_DOWNLOAD) && + (currdriverstate != NORMAL_OPERATION) && + (currdriverstate != LOWPOWER_MODE_ENTER)) + || + (currdriverstate == LED_THREAD_INACTIVE) ) + { + Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event, + currdriverstate != Adapter->DriverState || kthread_should_stop()); + } + + if(kthread_should_stop() || Adapter->device_removed ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting"); + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; + TURN_OFF_LED(1<device_removed) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread.."); + return ; //-ENODEV; + } + #endif + #if 0 + if((GPIO_num != DISABLE_GPIO_NUM) && + ((currdriverstate != FW_DOWNLOAD) && + (currdriverstate != NORMAL_OPERATION) && + (currdriverstate != IDLEMODE_EXIT))) + TURN_OFF_LED(1<LEDInfo.bLedInitDone == FALSE) + { + LedGpioInit(Adapter); + Adapter->LEDInfo.bLedInitDone = TRUE; + } + + switch(Adapter->DriverState) + { + case DRIVER_INIT: + { + currdriverstate = DRIVER_INIT;//Adapter->DriverState; + #if 0 + LedGpioInit(Adapter); + Adapter->LEDInfo.bLedInitDone = TRUE; + #endif + BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate); + + if(GPIO_num != DISABLE_GPIO_NUM) + { + TURN_ON_LED(1<LEDInfo.bLedInitDone == FALSE) + { + LedGpioInit(Adapter); + Adapter->LEDInfo.bLedInitDone = TRUE; + } + #endif + BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate); + + if(GPIO_num != DISABLE_GPIO_NUM) + { + timeout = 50; + LED_Blink(Adapter, 1<ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN) + { + LedGpioInit(Adapter); + } + #endif + //no break, continue to NO_NETWORK_ENTRY state as well. + + case NO_NETWORK_ENTRY: + { + currdriverstate = NO_NETWORK_ENTRY; + BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex,&dummyGPIONum,currdriverstate); + if(GPIO_num != DISABLE_GPIO_NUM) + { + TURN_ON_LED(1<LEDInfo.bIdle_led_off = FALSE; + + BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx,&uiLEDRx,currdriverstate); + if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM)) + { + GPIO_num = DISABLE_GPIO_NUM ; + } + else + { + /*If single LED is selected, use same for both Tx and Rx*/ + if(GPIO_num_tx == DISABLE_GPIO_NUM) + { + GPIO_num_tx = GPIO_num_rx; + uiLEDTx = uiLEDRx; + } + else if(GPIO_num_rx == DISABLE_GPIO_NUM) + { + GPIO_num_rx = GPIO_num_tx; + uiLEDRx = uiLEDTx; + } + /*Blink the LED in proportionate to Tx and Rx transmissions.*/ + LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx,currdriverstate); + } + } + break; + case LOWPOWER_MODE_ENTER: + { + currdriverstate = LOWPOWER_MODE_ENTER; + if( DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode) + { + /* Turn OFF all the LED */ + uiResetValue = 0; + for(uiIndex =0; uiIndex < NUM_OF_LEDS; uiIndex++) + { + if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) + TURN_OFF_LED((1<LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex); + } + + } + /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */ + Adapter->LEDInfo.bLedInitDone = FALSE; + Adapter->LEDInfo.bIdle_led_off = TRUE; + wake_up(&Adapter->LEDInfo.idleModeSyncEvent); + GPIO_num = DISABLE_GPIO_NUM; + break; + } + case IDLEMODE_CONTINUE: + { + currdriverstate = IDLEMODE_CONTINUE; + GPIO_num = DISABLE_GPIO_NUM; + } + break; + case IDLEMODE_EXIT: + { +#if 0 + UCHAR GPIO_num_tx = DISABLE_GPIO_NUM; + UCHAR GPIO_num_rx = DISABLE_GPIO_NUM; + UCHAR uiTxLedIndex = 0; + UCHAR uiRxLedIndex = 0; + + currdriverstate = IDLEMODE_EXIT; + if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode) + { + LedGpioInit(Adapter); + } + BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate); + + Adapter->LEDInfo.bIdle_led_off = FALSE; + + if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM)) + { + GPIO_num = DISABLE_GPIO_NUM ; + } + else + { + timeout = 50; + if(Adapter->LEDInfo.bIdleMode_tx_from_host) + LED_Blink(Adapter, 1<LEDInfo.LEDState[uiIndex].GPIO_Num != + DISABLE_GPIO_NUM) + TURN_OFF_LED((1<LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex); + } + //Adapter->DriverState = DRIVER_INIT; + } + break; + case LED_THREAD_INACTIVE : + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"InActivating LED thread..."); + currdriverstate = LED_THREAD_INACTIVE; + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY ; + Adapter->LEDInfo.bLedInitDone = FALSE ; + //disable ALL LED + for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) + { + if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != + DISABLE_GPIO_NUM) + TURN_OFF_LED((1<LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex); + } + } + break; + case LED_THREAD_ACTIVE : + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Activating LED thread again..."); + if(Adapter->LinkUpStatus == FALSE) + Adapter->DriverState = NO_NETWORK_ENTRY; + else + Adapter->DriverState = NORMAL_OPERATION; + + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY ; + } + break; + //return; + default: + break; + } + } + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; +} + +int InitLedSettings(PMINI_ADAPTER Adapter) +{ + int Status = STATUS_SUCCESS; + BOOLEAN bEnableThread = TRUE; + UCHAR uiIndex = 0; + + /*Initially set BitPolarity to normal polarity. The bit 8 of LED type + * is used to change the polarity of the LED.*/ + + for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { + Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1; + } + + /*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/ + Status = ReadConfigFileStructure(Adapter, &bEnableThread); + if(STATUS_SUCCESS != Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FAILED in ReadConfigFileStructure\n"); + return Status; + } + + if(Adapter->LEDInfo.led_thread_running) + { + if(bEnableThread) + ; + else + { + Adapter->DriverState = DRIVER_HALT; + wake_up(&Adapter->LEDInfo.notify_led_event); + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; + } + + } + + else if(bEnableThread) + { + /*Create secondary thread to handle the LEDs*/ + init_waitqueue_head(&Adapter->LEDInfo.notify_led_event); + init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent); + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY; + Adapter->LEDInfo.bIdle_led_off = FALSE; + Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *)) + LEDControlThread, Adapter, "led_control_thread"); + if(IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n"); + Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; + return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid); + } + } + return Status; +} diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h new file mode 100644 index 000000000000..0711ac20f6fc --- /dev/null +++ b/drivers/staging/bcm/led_control.h @@ -0,0 +1,106 @@ +#ifndef _LED_CONTROL_H +#define _LED_CONTROL_H + +/*************************TYPE DEF**********************/ +#define NUM_OF_LEDS 4 + +#define DSD_START_OFFSET 0x0200 +#define EEPROM_VERSION_OFFSET 0x020E +#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218 +#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220 +#define GPIO_SECTION_START_OFFSET 0x03 + +#define COMPATIBILITY_SECTION_LENGTH 42 +#define COMPATIBILITY_SECTION_LENGTH_MAP5 84 + + +#define EEPROM_MAP5_MAJORVERSION 5 +#define EEPROM_MAP5_MINORVERSION 0 + + +#define MAX_NUM_OF_BLINKS 10 +#define NUM_OF_GPIO_PINS 16 + +#define DISABLE_GPIO_NUM 0xFF +#define EVENT_SIGNALED 1 + +#define MAX_FILE_NAME_BUFFER_SIZE 100 + +#define TURN_ON_LED(GPIO, index) do{ \ + UINT gpio_val = GPIO; \ + (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \ + wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG, &gpio_val ,sizeof(gpio_val)) : \ + wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \ + }while(0); + +#define TURN_OFF_LED(GPIO, index) do { \ + UINT gpio_val = GPIO; \ + (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \ + wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG,&gpio_val ,sizeof(gpio_val)) : \ + wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG,&gpio_val ,sizeof(gpio_val)); \ + }while(0); + +#define B_ULONG32 unsigned long + +/*******************************************************/ + + +typedef enum _LEDColors{ + RED_LED = 1, + BLUE_LED = 2, + YELLOW_LED = 3, + GREEN_LED = 4 +} LEDColors; /*Enumerated values of different LED types*/ + +typedef enum LedEvents { + SHUTDOWN_EXIT = 0x00, + DRIVER_INIT = 0x1, + FW_DOWNLOAD = 0x2, + FW_DOWNLOAD_DONE = 0x4, + NO_NETWORK_ENTRY = 0x8, + NORMAL_OPERATION = 0x10, + LOWPOWER_MODE_ENTER = 0x20, + IDLEMODE_CONTINUE = 0x40, + IDLEMODE_EXIT = 0x80, + LED_THREAD_INACTIVE = 0x100, //Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. + LED_THREAD_ACTIVE = 0x200 //Makes the LED Thread Active back. +} LedEventInfo_t; /*Enumerated values of different driver states*/ + +#define DRIVER_HALT 0xff + + +/*Structure which stores the information of different LED types + * and corresponding LED state information of driver states*/ +typedef struct LedStateInfo_t +{ + UCHAR LED_Type; /* specify GPIO number - use 0xFF if not used */ + UCHAR LED_On_State; /* Bits set or reset for different states */ + UCHAR LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */ + UCHAR GPIO_Num; + UCHAR BitPolarity; /*To represent whether H/W is normal polarity or reverse + polarity*/ +}LEDStateInfo, *pLEDStateInfo; + + +typedef struct _LED_INFO_STRUCT +{ + LEDStateInfo LEDState[NUM_OF_LEDS]; + BOOLEAN bIdleMode_tx_from_host; /*Variable to notify whether driver came out + from idlemode due to Host or target*/ + BOOLEAN bIdle_led_off; + wait_queue_head_t notify_led_event; + wait_queue_head_t idleModeSyncEvent; + struct task_struct *led_cntrl_threadid; + int led_thread_running; + BOOLEAN bLedInitDone; + +} LED_INFO_STRUCT, *PLED_INFO_STRUCT; +//LED Thread state. +#define BCM_LED_THREAD_DISABLED 0 //LED Thread is not running. +#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 //LED thread is running. +#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 //LED thread has been put on hold + + + +#endif + diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c new file mode 100644 index 000000000000..35ff4e761f73 --- /dev/null +++ b/drivers/staging/bcm/nvm.c @@ -0,0 +1,5614 @@ +#include "headers.h" + +#define DWORD unsigned int +// Procedure: ReadEEPROMStatusRegister +// +// Description: Reads the standard EEPROM Status Register. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter ) +{ + UCHAR uiData = 0; + DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + UINT uiStatus = 0; + UINT value = 0; + UINT value1 = 0; + + /* Read the EEPROM status register */ + value = EEPROM_READ_STATUS_REGISTER ; + wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); + + while ( dwRetries != 0 ) + { + value=0; + uiStatus = 0 ; + rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)); + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting...."); + break; + } + + /* Wait for Avail bit to be set. */ + if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 ) + { + /* Clear the Avail/Full bits - which ever is set. */ + value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + + value =0; + rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value)); + uiData = (UCHAR)value; + + break; + } + + dwRetries-- ; + if ( dwRetries == 0 ) + { + rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY); + return uiData; + } + if( !(dwRetries%RETRIES_PER_DELAY) ) + msleep(1); + uiStatus = 0 ; + } + return uiData; +} /* ReadEEPROMStatusRegister */ + +//----------------------------------------------------------------------------- +// Procedure: ReadBeceemEEPROMBulk +// +// Description: This routine reads 16Byte data from EEPROM +// +// Arguments: +// Adapter - ptr to Adapter object instance +// dwAddress - EEPROM Offset to read the data from. +// pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY. +// +// Returns: +// OSAL_STATUS_CODE: +//----------------------------------------------------------------------------- + +INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter, + DWORD dwAddress, + DWORD *pdwData, + DWORD dwNumWords + ) +{ + DWORD dwIndex = 0; + DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + UINT uiStatus = 0; + UINT value= 0; + UINT value1 = 0; + UCHAR *pvalue; + + /* Flush the read and cmd queue. */ + value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH ); + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); + value=0; + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + + /* Clear the Avail/Full bits. */ + value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ); + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + + value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ ); + wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); + + while ( dwRetries != 0 ) + { + + uiStatus = 0; + rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop..."); + return -ENODEV; + } + + /* If we are reading 16 bytes we want to be sure that the queue + * is full before we read. In the other cases we are ok if the + * queue has data available */ + if ( dwNumWords == 4 ) + { + if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 ) + { + /* Clear the Avail/Full bits - which ever is set. */ + value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ; + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + break; + } + } + else if ( dwNumWords == 1 ) + { + + if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 ) + { + /* We just got Avail and we have to read 32bits so we + * need this sleep for Cardbus kind of devices. */ + if (Adapter->chip_id == 0xBECE0210 ) + udelay(800); + + /* Clear the Avail/Full bits - which ever is set. */ + value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ); + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + break; + } + } + + uiStatus = 0; + + dwRetries--; + if(dwRetries == 0) + { + value=0; + value1=0; + rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", dwNumWords, value, value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY); + return STATUS_FAILURE; + } + if( !(dwRetries%RETRIES_PER_DELAY) ) + msleep(1); + } + + for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ ) + { + /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */ + pvalue = (PUCHAR)(pdwData + dwIndex); + + value =0; + rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value)); + + pvalue[0] = value; + + value = 0; + rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value)); + + pvalue[1] = value; + + value =0; + rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value)); + + pvalue[2] = value; + + value = 0; + rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value)); + + pvalue[3] = value; + } + + return STATUS_SUCCESS; +} /* ReadBeceemEEPROMBulk() */ + +//----------------------------------------------------------------------------- +// Procedure: ReadBeceemEEPROM +// +// Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page +// reads to do this operation. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - EEPROM Offset to read the data from. +// pBuffer - Pointer to word where data needs to be stored in. +// +// Returns: +// OSAL_STATUS_CODE: +//----------------------------------------------------------------------------- + +INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter, + DWORD uiOffset, + DWORD *pBuffer + ) +{ + UINT uiData[8] = {0}; + UINT uiByteOffset = 0; + UINT uiTempOffset = 0; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> "); + + uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); + uiByteOffset = uiOffset - uiTempOffset; + + ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); + + /* A word can overlap at most over 2 pages. In that case we read the + * next page too. */ + if ( uiByteOffset > 12 ) + { + ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); + } + + OsalMemMove( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4); + + return STATUS_SUCCESS; +} /* ReadBeceemEEPROM() */ + + +#if 0 +//----------------------------------------------------------------------------- +// Procedure: IsEEPROMWriteDone +// +// Description: Reads the SPI status to see the status of previous write. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// BOOLEAN - TRUE - write went through +// - FALSE - Write Failed. +//----------------------------------------------------------------------------- + +BOOLEAN IsEEPROMWriteDone(PMINI_ADAPTER Adapter) +{ + UINT uiRetries = 16; + //UINT uiStatus = 0; + UINT value; + + //sleep for 1.2ms ..worst case EEPROM write can take up to 1.2ms. + mdelay(2); + + value = 0; + rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + + while(((value >> 14) & 1) == 1) + { + // EEPROM_SPI_Q_STATUS1_REG will be cleared only if write back to that. + value = (0x1 << 14); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + udelay(1000); + uiRetries--; + if(uiRetries == 0) + { + return FALSE; + } + value = 0; + rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + } + return TRUE; + + +} + + +//----------------------------------------------------------------------------- +// Procedure: ReadBeceemEEPROMBulk +// +// Description: This routine reads 16Byte data from EEPROM +// +// Arguments: +// Adapter - ptr to Adapter object instance +// dwAddress - EEPROM Offset to read the data from. +// pdwData - Pointer to double word where data needs to be stored in. +// +// Returns: +// OSAL_STATUS_CODE: +//----------------------------------------------------------------------------- + +INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData) +{ + DWORD dwRetries = 16; + DWORD dwIndex = 0; + UINT value, tmpVal; + + + value = 0; + rdmalt (Adapter, 0x0f003008, &value, sizeof(value)); + + //read 0x0f003020 untill bit 1 of 0x0f003008 is set. + while(((value >> 1) & 1) == 0) + { + + rdmalt (Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal)); + dwRetries--; + if(dwRetries == 0) + { + return -1; + } + value = 0; + rdmalt (Adapter, 0x0f003008, &value, sizeof(value)); + } + + value = dwAddress | 0xfb000000; + wrmalt (Adapter, 0x0f003018, &value, sizeof(value)); + + udelay(1000); + value = 0; + for(dwIndex = 0;dwIndex < 4 ; dwIndex++) + { + value = 0; + rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); + pdwData[dwIndex] = value; + + value = 0; + rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); + pdwData[dwIndex] |= (value << 8); + + value = 0; + rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); + pdwData[dwIndex] |= (value << 16); + + value = 0; + rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); + pdwData[dwIndex] |= (value << 24); + + } + return 0; +} + +//----------------------------------------------------------------------------- +// Procedure: ReadBeceemEEPROM +// +// Description: This routine reads 4Byte data from EEPROM +// +// Arguments: +// Adapter - ptr to Adapter object instance +// dwAddress - EEPROM Offset to read the data from. +// pdwData - Pointer to double word where data needs to be stored in. +// +// Returns: +// OSAL_STATUS_CODE: +//----------------------------------------------------------------------------- + +INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData) +{ + + DWORD dwReadValue = 0; + DWORD dwRetries = 16, dwCompleteWord = 0; + UINT value, tmpVal; + + rdmalt(Adapter, 0x0f003008, &value, sizeof(value)); + while (((value >> 1) & 1) == 0) { + rdmalt(Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal)); + + if (dwRetries == 0) { + return -1; + } + rdmalt(Adapter, 0x0f003008, &value, sizeof(value)); + } + + + //wrm (0x0f003018, 0xNbXXXXXX) // N is the number of bytes u want to read (0 means 1, f means 16, b is the opcode for page read) + // Follow it up by N executions of rdm(0x0f003020) to read the rxed bytes from rx queue. + dwAddress |= 0x3b000000; + wrmalt(Adapter, 0x0f003018,&dwAddress,4); + mdelay(10); + rdmalt(Adapter, 0x0f003020,&dwReadValue,4); + dwCompleteWord=dwReadValue; + rdmalt(Adapter, 0x0f003020,&dwReadValue,4); + dwCompleteWord|=(dwReadValue<<8); + rdmalt(Adapter, 0x0f003020,&dwReadValue,4); + dwCompleteWord|=(dwReadValue<<16); + rdmalt(Adapter, 0x0f003020,&dwReadValue,4); + dwCompleteWord|=(dwReadValue<<24); + + *pdwData = dwCompleteWord; + + return 0; +} +#endif + +INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter) +{ + INT Status=0, i; + unsigned char puMacAddr[6] = {0}; + INT AllZeroMac = 0; + INT AllFFMac = 0; + + Status = BeceemNVMRead(Adapter, + (PUINT)&puMacAddr[0], + INIT_PARAMS_1_MACADDRESS_ADDRESS, + MAC_ADDRESS_SIZE); + + if(Status != STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Error in Reading the mac Addres with status :%d", Status); + return Status; + } + + memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Modem MAC Addr :"); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_PRINTK, 0, DBG_LVL_ALL,&Adapter->dev->dev_addr[0],MAC_ADDRESS_SIZE); + for(i=0;idev->dev_addr[i] == 0x00) + AllZeroMac++; + if(Adapter->dev->dev_addr[i] == 0xFF) + AllFFMac++; + + } + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\n"); + if(AllZeroMac == MAC_ADDRESS_SIZE) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all 00's"); + if(AllFFMac == MAC_ADDRESS_SIZE) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all FF's"); + + return Status; + +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemEEPROMBulkRead +// +// Description: Reads the EEPROM and returns the Data. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Buffer to store the data read from EEPROM +// uiOffset - Offset of EEPROM from where data should be read +// uiNumBytes - Number of bytes to be read from the EEPROM. +// +// Returns: +// OSAL_STATUS_SUCCESS - if EEPROM read is successfull. +// - if failed. +//----------------------------------------------------------------------------- + +INT BeceemEEPROMBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) +{ + UINT uiData[4] = {0}; + //UINT uiAddress = 0; + UINT uiBytesRemaining = uiNumBytes; + UINT uiIndex = 0; + UINT uiTempOffset = 0; + UINT uiExtraBytes = 0; + UINT uiFailureRetries = 0; + PUCHAR pcBuff = (PUCHAR)pBuffer; + + + if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining) + { + uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE); + uiExtraBytes = uiOffset-uiTempOffset; + ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4); + if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) + { + OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes); + + uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); + uiIndex += (MAX_RW_SIZE - uiExtraBytes); + uiOffset += (MAX_RW_SIZE - uiExtraBytes); + } + else + { + OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining); + uiIndex += uiBytesRemaining; + uiOffset += uiBytesRemaining; + uiBytesRemaining = 0; + } + + + } + + + while(uiBytesRemaining && uiFailureRetries != 128) + { + if(Adapter->device_removed ) + { + return -1; + } + + if(uiBytesRemaining >= MAX_RW_SIZE) + { + /* For the requests more than or equal to 16 bytes, use bulk + * read function to make the access faster. + * We read 4 Dwords of data */ + if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4)) + { + OsalMemMove(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE); + uiOffset += MAX_RW_SIZE; + uiBytesRemaining -= MAX_RW_SIZE; + uiIndex += MAX_RW_SIZE; + } + else + { + uiFailureRetries++; + mdelay(3);//sleep for a while before retry... + } + } + else if(uiBytesRemaining >= 4) + { + if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) + { + OsalMemMove(pcBuff+uiIndex,&uiData[0],4); + uiOffset += 4; + uiBytesRemaining -= 4; + uiIndex +=4; + } + else + { + uiFailureRetries++; + mdelay(3);//sleep for a while before retry... + } + } + else + { // Handle the reads less than 4 bytes... + PUCHAR pCharBuff = (PUCHAR)pBuffer; + pCharBuff += uiIndex; + if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) + { + OsalMemMove(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested. + uiBytesRemaining = 0; + } + else + { + uiFailureRetries++; + mdelay(3);//sleep for a while before retry... + } + } + + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemFlashBulkRead +// +// Description: Reads the FLASH and returns the Data. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Buffer to store the data read from FLASH +// uiOffset - Offset of FLASH from where data should be read +// uiNumBytes - Number of bytes to be read from the FLASH. +// +// Returns: +// OSAL_STATUS_SUCCESS - if FLASH read is successfull. +// - if failed. +//----------------------------------------------------------------------------- + +INT BeceemFlashBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) +{ + UINT uiIndex = 0; + UINT uiBytesToRead = uiNumBytes; + INT Status = 0; + UINT uiPartOffset = 0; + + if(Adapter->device_removed ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed "); + return -ENODEV; + } + + //Adding flash Base address +// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); +#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); + return Status; +#endif + + Adapter->SelectedChip = RESET_CHIP_SELECT; + + if(uiOffset % MAX_RW_SIZE) + { + BcmDoChipSelect(Adapter,uiOffset); + uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + + uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE); + uiBytesToRead = MIN(uiNumBytes,uiBytesToRead); + + if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead)) + { + Status = -1; + Adapter->SelectedChip = RESET_CHIP_SELECT; + return Status; + } + + uiIndex += uiBytesToRead; + uiOffset += uiBytesToRead; + uiNumBytes -= uiBytesToRead; + } + + while(uiNumBytes) + { + BcmDoChipSelect(Adapter,uiOffset); + uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + + uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE); + + if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead)) + { + Status = -1; + break; + } + + + uiIndex += uiBytesToRead; + uiOffset += uiBytesToRead; + uiNumBytes -= uiBytesToRead; + + } + Adapter->SelectedChip = RESET_CHIP_SELECT; + return Status; +} + +//----------------------------------------------------------------------------- +// Procedure: BcmGetFlashSize +// +// Description: Finds the size of FLASH. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// UINT - size of the FLASH Storage. +// +//----------------------------------------------------------------------------- + +UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) +{ +#if 0 + if(Adapter->bDDRInitDone) + { + return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT|FLASH_SIZE_ADDR); + } + + return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT|FLASH_SIZE_ADDR); +#endif + if(IsFlash2x(Adapter)) + return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); + else + return 32*1024; + + +} + +//----------------------------------------------------------------------------- +// Procedure: BcmGetEEPROMSize +// +// Description: Finds the size of EEPROM. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// UINT - size of the EEPROM Storage. +// +//----------------------------------------------------------------------------- + +UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) +{ + UINT uiData = 0; + UINT uiIndex = 0; + +// +// if EEPROM is present and already Calibrated,it will have +// 'BECM' string at 0th offset. +// To find the EEPROM size read the possible boundaries of the +// EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will +// result in wrap around. So when we get the End of the EEPROM we will +// get 'BECM' string which is indeed at offset 0. +// + BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4); + if(uiData == BECM) + { + for(uiIndex = 2;uiIndex <=256; uiIndex*=2) + { + BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4); + if(uiData == BECM) + { + return uiIndex*1024; + } + } + } + else + { +// +// EEPROM may not be present or not programmed +// + + uiData = 0xBABEFACE; + if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE)) + { + uiData = 0; + for(uiIndex = 2;uiIndex <=256; uiIndex*=2) + { + BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4); + if(uiData == 0xBABEFACE) + { + return uiIndex*1024; + } + } + } + + } + return 0; +} + +#if 0 +/***********************************************************************************/ +// +// WriteBeceemEEPROM: Writes 4 byte data to EEPROM offset. +// +// uiEEPROMOffset - Offset to be written to. +// uiData - Data to be written. +// +/***********************************************************************************/ + +INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData) +{ + INT Status = 0; + ULONG ulRdBk = 0; + ULONG ulRetryCount = 3; + UINT value; + + if(uiEEPROMOffset > EEPROM_END) + { + + return -1; + } + + uiData = htonl(uiData); + while(ulRetryCount--) + { + value = 0x06000000; + wrmalt(Adapter, 0x0F003018,&value, sizeof(value));//flush the EEPROM FIFO. + wrmalt(Adapter, 0x0F00301C,&uiData, sizeof(uiData)); + value = 0x3A000000 | uiEEPROMOffset; + wrmalt(Adapter, 0x0F003018,&value, sizeof(value)); + __udelay(100000); + //read back and verify. + Status = ReadBeceemEEPROM(Adapter,uiEEPROMOffset,(UINT *)&ulRdBk); + if(Status == 0) + { + if(ulRdBk == uiData) + { + return Status; + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback does not match\n"); + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback failed\n"); + } + } + + return 0; +} +#endif + +//----------------------------------------------------------------------------- +// Procedure: FlashSectorErase +// +// Description: Finds the sector size of the FLASH. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// addr - sector start address +// numOfSectors - number of sectors to be erased. +// +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + + +INT FlashSectorErase(PMINI_ADAPTER Adapter, + UINT addr, + UINT numOfSectors) +{ + UINT iIndex = 0, iRetries = 0; + UINT uiStatus = 0; + UINT value; + + for(iIndex=0;iIndexuiSectorSize; + } + return 0; +} +//----------------------------------------------------------------------------- +// Procedure: flashByteWrite +// +// Description: Performs Byte by Byte write to flash +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - Offset of the flash where data needs to be written to. +// pData - Address of Data to be written. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT flashByteWrite( + PMINI_ADAPTER Adapter, + UINT uiOffset, + PVOID pData) +{ + + UINT uiStatus = 0; + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + + UINT value; + ULONG ulData = *(PUCHAR)pData; + +// +// need not write 0xFF because write requires an erase and erase will +// make whole sector 0xFF. +// + + if(0xFF == ulData) + { + return STATUS_SUCCESS; + } + +// DumpDebug(NVM_RW,("flashWrite ====>\n")); + value = (FLASH_CMD_WRITE_ENABLE << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails"); + return STATUS_FAILURE; + } + if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails"); + return STATUS_FAILURE; + } + value = (0x02000000 | (uiOffset & 0xFFFFFF)); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + + //__udelay(950); + + do + { + value = (FLASH_CMD_STATUS_REG_READ << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + //__udelay(1); + if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails"); + return STATUS_FAILURE; + } + iRetries--; + if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + + }while((uiStatus & 0x1) && (iRetries >0) ); + + if(uiStatus & 0x1) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE ; + } + + return STATUS_SUCCESS; +} + + + +//----------------------------------------------------------------------------- +// Procedure: flashWrite +// +// Description: Performs write to flash +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - Offset of the flash where data needs to be written to. +// pData - Address of Data to be written. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT flashWrite( + PMINI_ADAPTER Adapter, + UINT uiOffset, + PVOID pData) + +{ + //UINT uiStatus = 0; + //INT iRetries = 0; + //UINT uiReadBack = 0; + + UINT uiStatus = 0; + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + + UINT value; + UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; +// +// need not write 0xFFFFFFFF because write requires an erase and erase will +// make whole sector 0xFFFFFFFF. +// + if (!OsalMemCompare(pData, uiErasePattern, MAX_RW_SIZE)) + { + return 0; + } + + value = (FLASH_CMD_WRITE_ENABLE << 24); + + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails..."); + return STATUS_FAILURE; + } + + //__udelay(950); + do + { + value = (FLASH_CMD_STATUS_REG_READ << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + //__udelay(1); + if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails"); + return STATUS_FAILURE; + } + + iRetries--; + //this will ensure that in there will be no changes in the current path. + //currently one rdm/wrm takes 125 us. + //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) + //Hence current implementation cycle will intoduce no delay in current path + if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + }while((uiStatus & 0x1) && (iRetries > 0)); + + if(uiStatus & 0x1) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE ; + } + + return STATUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Procedure: flashByteWriteStatus +// +// Description: Performs byte by byte write to flash with write done status check +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - Offset of the flash where data needs to be written to. +// pData - Address of the Data to be written. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- +INT flashByteWriteStatus( + PMINI_ADAPTER Adapter, + UINT uiOffset, + PVOID pData) +{ + UINT uiStatus = 0; + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + ULONG ulData = *(PUCHAR)pData; + UINT value; + +// +// need not write 0xFFFFFFFF because write requires an erase and erase will +// make whole sector 0xFFFFFFFF. +// + + if(0xFF == ulData) + { + return STATUS_SUCCESS; + } + + // DumpDebug(NVM_RW,("flashWrite ====>\n")); + + value = (FLASH_CMD_WRITE_ENABLE << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails"); + return STATUS_SUCCESS; + } + if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails"); + return STATUS_FAILURE; + } + value = (0x02000000 | (uiOffset & 0xFFFFFF)); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + + //msleep(1); + + do + { + value = (FLASH_CMD_STATUS_REG_READ << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + //__udelay(1); + if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails"); + return STATUS_FAILURE; + } + + iRetries--; + if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + }while((uiStatus & 0x1) && (iRetries > 0)); + + if(uiStatus & 0x1) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE ; + } + + return STATUS_SUCCESS; + +} +//----------------------------------------------------------------------------- +// Procedure: flashWriteStatus +// +// Description: Performs write to flash with write done status check +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - Offset of the flash where data needs to be written to. +// pData - Address of the Data to be written. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT flashWriteStatus( + PMINI_ADAPTER Adapter, + UINT uiOffset, + PVOID pData) +{ + UINT uiStatus = 0; + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + //UINT uiReadBack = 0; + UINT value; + UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + +// +// need not write 0xFFFFFFFF because write requires an erase and erase will +// make whole sector 0xFFFFFFFF. +// + if (!OsalMemCompare(pData,uiErasePattern,MAX_RW_SIZE)) + { + return 0; + } + + value = (FLASH_CMD_WRITE_ENABLE << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails..."); + return STATUS_FAILURE; + } + // __udelay(1); + + do + { + value = (FLASH_CMD_STATUS_REG_READ << 24); + if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + return STATUS_FAILURE; + } + //__udelay(1); + if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails"); + return STATUS_FAILURE; + } + iRetries--; + //this will ensure that in there will be no changes in the current path. + //currently one rdm/wrm takes 125 us. + //Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) + //Hence current implementation cycle will intoduce no delay in current path + if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + }while((uiStatus & 0x1) && (iRetries >0)); + + if(uiStatus & 0x1) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE ; + } + + return STATUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Procedure: BcmRestoreBlockProtectStatus +// +// Description: Restores the original block protection status. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// ulWriteStatus -Original status +// Returns: +// +// +//----------------------------------------------------------------------------- + +VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus) +{ + UINT value; + value = (FLASH_CMD_WRITE_ENABLE<< 24); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); + + udelay(20); + value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); + udelay(20); +} +//----------------------------------------------------------------------------- +// Procedure: BcmFlashUnProtectBlock +// +// Description: UnProtects appropriate blocks for writing. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned. +// Returns: +// ULONG - Status value before UnProtect. +// +//----------------------------------------------------------------------------- +ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength) +{ + ULONG ulStatus = 0; + ULONG ulWriteStatus = 0; + UINT value; + uiOffset = uiOffset&0x000FFFFF; + +// +// Implemented only for 1MB Flash parts. +// + if(FLASH_PART_SST25VF080B == Adapter->ulFlashID) + { + // + // Get Current BP status. + // + value = (FLASH_CMD_STATUS_REG_READ << 24); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); + udelay(10); + // + // Read status will be WWXXYYZZ. We have to take only WW. + // + rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); + ulStatus >>= 24; + ulWriteStatus = ulStatus; + + // + // Bits [5-2] give current block level protection status. + // Bit5: BP3 - DONT CARE + // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 + // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS + // + + if(ulStatus) + { + if((uiOffset+uiLength) <= 0x80000) + { + // + // Offset comes in lower half of 1MB. Protect the upper half. + // Clear BP1 and BP0 and set BP2. + // + ulWriteStatus |= (0x4<<2); + ulWriteStatus &= ~(0x3<<2); + } + else if((uiOffset+uiLength) <= 0xC0000) + { + // + // Offset comes below Upper 1/4. Upper 1/4 can be protected. + // Clear BP2 and set BP1 and BP0. + // + ulWriteStatus |= (0x3<<2); + ulWriteStatus &= ~(0x1<<4); + } + else if((uiOffset+uiLength) <= 0xE0000) + { + // + // Offset comes below Upper 1/8. Upper 1/8 can be protected. + // Clear BP2 and BP0 and set BP1 + // + ulWriteStatus |= (0x1<<3); + ulWriteStatus &= ~(0x5<<2); + + } + else if((uiOffset+uiLength) <= 0xF0000) + { + // + // Offset comes below Upper 1/16. Only upper 1/16 can be protected. + // Set BP0 and Clear BP2,BP1. + // + ulWriteStatus |= (0x1<<2); + ulWriteStatus &= ~(0x3<<3); + } + else + { + // + // Unblock all. + // Clear BP2,BP1 and BP0. + // + ulWriteStatus &= ~(0x7<<2); + } + + value = (FLASH_CMD_WRITE_ENABLE<< 24); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); + udelay(20); + value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); + udelay(20); + + } + + } + return ulStatus; +} +//----------------------------------------------------------------------------- +// Procedure: BeceemFlashBulkWrite +// +// Description: Performs write to the flash +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the flash where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// bVerify - read verify flag. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT BeceemFlashBulkWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) +{ + PCHAR pTempBuff = NULL; + PUCHAR pcBuffer = (PUCHAR)pBuffer; + UINT uiIndex = 0; + UINT uiOffsetFromSectStart = 0; + UINT uiSectAlignAddr = 0; + UINT uiCurrSectOffsetAddr = 0; + UINT uiSectBoundary = 0; + UINT uiNumSectTobeRead = 0; + UCHAR ucReadBk[16] = {0}; + ULONG ulStatus = 0; + INT Status = STATUS_SUCCESS; + UINT uiTemp = 0; + UINT index = 0; + UINT uiPartOffset = 0; + #if 0 + struct timeval tv1 = {0}; + struct timeval tv2 = {0}; + + struct timeval tr = {0}; + struct timeval te = {0}; + struct timeval tw = {0}; + struct timeval twv = {0}; + #endif + +#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); + return Status; +#endif + + uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); + + //Adding flash Base address +// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); + uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; + + //pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN'); + pTempBuff = OsalMemAlloc(Adapter->uiSectorSize ,'!MVN'); + if(NULL == pTempBuff) + { + goto BeceemFlashBulkWrite_EXIT; + } +// +// check if the data to be written is overlapped accross sectors +// + if(uiOffset+uiNumBytes < uiSectBoundary) + { + uiNumSectTobeRead = 1; + } + else + { + // Number of sectors = Last sector start address/First sector start address + uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize; + if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize) + { + uiNumSectTobeRead++; + } + } + #if 1 + //Check whether Requested sector is writable or not in case of flash2x write. But if write call is + // for DSD calibration, allow it without checking of sector permission + + if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) + { + index = 0; + uiTemp = uiNumSectTobeRead ; + while(uiTemp) + { + if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable", + (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); + Status = SECTOR_IS_NOT_WRITABLE; + goto BeceemFlashBulkWrite_EXIT; + } + uiTemp = uiTemp - 1; + index = index + 1 ; + } + } + #endif + Adapter->SelectedChip = RESET_CHIP_SELECT; + while(uiNumSectTobeRead) + { + //do_gettimeofday(&tv1); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); + uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + + BcmDoChipSelect(Adapter,uiSectAlignAddr); + + if(0 != BeceemFlashBulkRead(Adapter, + (PUINT)pTempBuff, + uiOffsetFromSectStart, + Adapter->uiSectorSize)) + { + Status = -1; + goto BeceemFlashBulkWrite_EXIT; + } + + //do_gettimeofday(&tr); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); + + ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize); + + + if(uiNumSectTobeRead > 1) + { + + OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); + uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + } + else + { + OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + } + + if(IsFlash2x(Adapter)) + { + SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart); + } + + FlashSectorErase(Adapter,uiPartOffset,1); + //do_gettimeofday(&te); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); + + for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize) + { + if(Adapter->device_removed) + { + Status = -1; + goto BeceemFlashBulkWrite_EXIT; + } + if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex]))) + { + Status = -1; + goto BeceemFlashBulkWrite_EXIT; + } + } + + //do_gettimeofday(&tw); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); + for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE) + { + if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) + { + if(Adapter->ulFlashWriteSize == 1) + { + UINT uiReadIndex = 0; + for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) + { + if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex]) + { + if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex])) + { + Status = STATUS_FAILURE; + goto BeceemFlashBulkWrite_EXIT; + } + } + } + } + else + { + if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + { + if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex])) + { + Status = STATUS_FAILURE; + goto BeceemFlashBulkWrite_EXIT; + } + } + } + } + } + //do_gettimeofday(&twv); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); + + + if(ulStatus) + { + BcmRestoreBlockProtectStatus(Adapter,ulStatus); + ulStatus = 0; + } + + uiCurrSectOffsetAddr = 0; + uiSectAlignAddr = uiSectBoundary; + uiSectBoundary += Adapter->uiSectorSize; + uiOffsetFromSectStart += Adapter->uiSectorSize; + uiNumSectTobeRead--; + } + //do_gettimeofday(&tv2); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); +// +// Cleanup. +// +BeceemFlashBulkWrite_EXIT: + if(ulStatus) + { + BcmRestoreBlockProtectStatus(Adapter,ulStatus); + } + if(pTempBuff) + { + OsalMemFree(pTempBuff,Adapter->uiSectorSize); + } + + Adapter->SelectedChip = RESET_CHIP_SELECT; + return Status; +} + + +//----------------------------------------------------------------------------- +// Procedure: BeceemFlashBulkWriteStatus +// +// Description: Writes to Flash. Checks the SPI status after each write. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the flash where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// bVerify - read verify flag. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT BeceemFlashBulkWriteStatus( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) +{ + PCHAR pTempBuff = NULL; + PUCHAR pcBuffer = (PUCHAR)pBuffer; + UINT uiIndex = 0; + UINT uiOffsetFromSectStart = 0; + UINT uiSectAlignAddr = 0; + UINT uiCurrSectOffsetAddr = 0; + UINT uiSectBoundary = 0; + UINT uiNumSectTobeRead = 0; + UCHAR ucReadBk[16] = {0}; + ULONG ulStatus = 0; + UINT Status = STATUS_SUCCESS; + UINT uiTemp = 0; + UINT index = 0; + UINT uiPartOffset = 0; + + uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); + + //uiOffset += Adapter->ulFlashCalStart; + //Adding flash Base address +// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); + uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; + + + +// pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN'); + pTempBuff = OsalMemAlloc(Adapter->uiSectorSize,'!MVN'); + if(NULL == pTempBuff) + { + goto BeceemFlashBulkWriteStatus_EXIT; + } +// +// check if the data to be written is overlapped accross sectors +// + if(uiOffset+uiNumBytes < uiSectBoundary) + { + uiNumSectTobeRead = 1; + } + else + { +// Number of sectors = Last sector start address/First sector start address + uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize; + if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize) + { + uiNumSectTobeRead++; + } + } + + if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) + { + index = 0; + uiTemp = uiNumSectTobeRead ; + while(uiTemp) + { + if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable", + (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); + Status = SECTOR_IS_NOT_WRITABLE; + goto BeceemFlashBulkWriteStatus_EXIT; + } + uiTemp = uiTemp - 1; + index = index + 1 ; + } + } + + Adapter->SelectedChip = RESET_CHIP_SELECT; + while(uiNumSectTobeRead) + { + uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + + BcmDoChipSelect(Adapter,uiSectAlignAddr); + if(0 != BeceemFlashBulkRead(Adapter, + (PUINT)pTempBuff, + uiOffsetFromSectStart, + Adapter->uiSectorSize)) + { + Status = -1; + goto BeceemFlashBulkWriteStatus_EXIT; + } + + ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize); + + if(uiNumSectTobeRead > 1) + { + + OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); + uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + } + else + { + OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + } + + if(IsFlash2x(Adapter)) + { + SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart); + } + + FlashSectorErase(Adapter,uiPartOffset,1); + + for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize) + + { + if(Adapter->device_removed) + { + Status = -1; + goto BeceemFlashBulkWriteStatus_EXIT; + } + + if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex])) + { + Status = -1; + goto BeceemFlashBulkWriteStatus_EXIT; + } + } + + if(bVerify) + { + for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE) + { +#if 0 + if(0 == BeceemFlashBulkRead(Adapter,uiReadBk,uiOffsetFromSectStart+uiIndex + Adapter->ulFlashCalStart ,MAX_RW_SIZE)) + { + for(uiReadIndex = 0;uiReadIndex < 4; uiReadIndex++) + { + if(*((PUINT)&pTempBuff[uiIndex+uiReadIndex*4]) != uiReadBk[uiReadIndex]) + { + Status = -1; + goto BeceemFlashBulkWriteStatus_EXIT; + + } + } + + } +#endif + + if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) + { + if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + { + Status = STATUS_FAILURE; + goto BeceemFlashBulkWriteStatus_EXIT; + } + + } + + } + } + + if(ulStatus) + { + BcmRestoreBlockProtectStatus(Adapter,ulStatus); + ulStatus = 0; + } + + uiCurrSectOffsetAddr = 0; + uiSectAlignAddr = uiSectBoundary; + uiSectBoundary += Adapter->uiSectorSize; + uiOffsetFromSectStart += Adapter->uiSectorSize; + uiNumSectTobeRead--; + } +// +// Cleanup. +// +BeceemFlashBulkWriteStatus_EXIT: + if(ulStatus) + { + BcmRestoreBlockProtectStatus(Adapter,ulStatus); + } + if(pTempBuff) + { + OsalMemFree(pTempBuff,Adapter->uiSectorSize); + } + Adapter->SelectedChip = RESET_CHIP_SELECT; + return Status; + +} + +//----------------------------------------------------------------------------- +// Procedure: PropagateCalParamsFromEEPROMToMemory +// +// Description: Dumps the calibration section of EEPROM to DDR. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + + +INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) +{ + PCHAR pBuff = OsalMemAlloc(BUFFER_4K,'3MVN'); + UINT uiEepromSize = 0; + UINT uiIndex = 0; + UINT uiBytesToCopy = 0; + UINT uiCalStartAddr = EEPROM_CALPARAM_START; + UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + UINT value; + INT Status = 0; + if(pBuff == NULL) + { + return -1; + } + + if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4)) + { + + OsalMemFree(pBuff,BUFFER_4K); + return -1; + } + + uiEepromSize >>= 16; + if(uiEepromSize > 1024*1024) + { + OsalMemFree(pBuff,BUFFER_4K); + return -1; + } + + + uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + + while(uiBytesToCopy) + { + if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy)) + { + Status = -1; + break; + } + wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy); + uiMemoryLoc += uiBytesToCopy; + uiEepromSize -= uiBytesToCopy; + uiCalStartAddr += uiBytesToCopy; + uiIndex += uiBytesToCopy/4; + uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + + } + value = 0xbeadbead; + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value)); + value = 0xbeadbead; + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value)); + OsalMemFree(pBuff,MAX_RW_SIZE); + + return Status; + +} + +//----------------------------------------------------------------------------- +// Procedure: PropagateCalParamsFromFlashToMemory +// +// Description: Dumps the calibration section of EEPROM to DDR. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) +{ + PCHAR pBuff, pPtr; + UINT uiEepromSize = 0; + UINT uiBytesToCopy = 0; + //UINT uiIndex = 0; + UINT uiCalStartAddr = EEPROM_CALPARAM_START; + UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + UINT value; + INT Status = 0; +// +// Write the signature first. This will ensure firmware does not access EEPROM. +// + value = 0xbeadbead; + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); + value = 0xbeadbead; + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); + + if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4)) + { + return -1; + } + uiEepromSize = ntohl(uiEepromSize); + uiEepromSize >>= 16; + +// +// subtract the auto init section size +// + uiEepromSize -= EEPROM_CALPARAM_START; + + if(uiEepromSize > 1024*1024) + { + return -1; + } + + pBuff = OsalMemAlloc(uiEepromSize, 0); + + if ( pBuff == NULL ) + { + return -1; + } + + if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize)) + { + OsalMemFree(pBuff, 0); + return -1; + } + + pPtr = pBuff; + + uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + + while(uiBytesToCopy) + { + Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status); + break; + } + + pPtr += uiBytesToCopy; + uiEepromSize -= uiBytesToCopy; + uiMemoryLoc += uiBytesToCopy; + uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + } + + OsalMemFree(pBuff, 0); + return Status; + +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemEEPROMReadBackandVerify +// +// Description: Read back the data written and verifies. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the flash where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT BeceemEEPROMReadBackandVerify( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) +{ + UINT uiRdbk = 0; + UINT uiIndex = 0; + UINT uiData = 0; + UINT auiData[4] = {0}; + + while(uiNumBytes) + { + if(Adapter->device_removed ) + { + return -1; + } + + if(uiNumBytes >= MAX_RW_SIZE) + {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. + BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); + + if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + { + // re-write + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE); + mdelay(3); + BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); + + if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + { + return -1; + } + } + uiOffset += MAX_RW_SIZE; + uiNumBytes -= MAX_RW_SIZE; + uiIndex += 4; + + } + else if(uiNumBytes >= 4) + { + BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4); + if(uiData != pBuffer[uiIndex]) + { + //re-write + BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE); + mdelay(3); + BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4); + if(uiData != pBuffer[uiIndex]) + { + return -1; + } + } + uiOffset += 4; + uiNumBytes -= 4; + uiIndex++; + + } + else + { // Handle the reads less than 4 bytes... + uiData = 0; + OsalMemMove(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes); + BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4); + + if(memcmp(&uiData, &uiRdbk, uiNumBytes)) + return -1; + + uiNumBytes = 0; + } + + } + + return 0; +} + +VOID BcmSwapWord(UINT *ptr1) { + + UINT tempval = (UINT)*ptr1; + char *ptr2 = (char *)&tempval; + char *ptr = (char *)ptr1; + + ptr[0] = ptr2[3]; + ptr[1] = ptr2[2]; + ptr[2] = ptr2[1]; + ptr[3] = ptr2[0]; +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemEEPROMWritePage +// +// Description: Performs page write (16bytes) to the EEPROM +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiData - Data to be written. +// uiOffset - Offset of the EEPROM where data needs to be written to. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- +INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset ) +{ + UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + UINT uiStatus = 0; + UCHAR uiEpromStatus = 0; + UINT value =0 ; + + /* Flush the Write/Read/Cmd queues. */ + value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH ); + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + value = 0 ; + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); + + /* Clear the Empty/Avail/Full bits. After this it has been confirmed + * that the bit was cleared by reading back the register. See NOTE below. + * We also clear the Read queues as we do a EEPROM status register read + * later. */ + value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ; + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + + /* Enable write */ + value = EEPROM_WRITE_ENABLE ; + wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) ); + + /* We can write back to back 8bits * 16 into the queue and as we have + * checked for the queue to be empty we can write in a burst. */ + + value = uiData[0]; + BcmSwapWord(&value); + wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + + value = uiData[1]; + BcmSwapWord(&value); + wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + + value = uiData[2]; + BcmSwapWord(&value); + wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + + value = uiData[3]; + BcmSwapWord(&value); + wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + + /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG + * shows that we see 7 for the EEPROM data write. Which means that + * queue got full, also space is available as well as the queue is empty. + * This may happen in sequence. */ + value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset ; + wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) ); + + /* Ideally we should loop here without tries and eventually succeed. + * What we are checking if the previous write has completed, and this + * may take time. We should wait till the Empty bit is set. */ + uiStatus = 0; + rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ; + while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 ) + { + uiRetries--; + if ( uiRetries == 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY); + return STATUS_FAILURE ; + } + + if( !(uiRetries%RETRIES_PER_DELAY) ) + msleep(1); + + uiStatus = 0; + rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ; + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop...."); + return -ENODEV; + } + + } + + if ( uiRetries != 0 ) + { + /* Clear the ones that are set - either, Empty/Full/Avail bits */ + value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) ); + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + } + + /* Here we should check if the EEPROM status register is correct before + * proceeding. Bit 0 in the EEPROM Status register should be 0 before + * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy + * with the previous write. Note also that issuing this read finally + * means the previous write to the EEPROM has completed. */ + uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + uiEpromStatus = 0; + while ( uiRetries != 0 ) + { + uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ; + if(Adapter->device_removed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); + return -ENODEV; + } + if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) ); + return STATUS_SUCCESS ; + } + uiRetries--; + if ( uiRetries == 0 ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY); + return STATUS_FAILURE ; + } + uiEpromStatus = 0; + if( !(uiRetries%RETRIES_PER_DELAY) ) + msleep(1); + } + + return STATUS_SUCCESS ; +} /* BeceemEEPROMWritePage */ + + +//----------------------------------------------------------------------------- +// Procedure: BeceemEEPROMBulkWrite +// +// Description: Performs write to the EEPROM +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the EEPROM where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// bVerify - read verify flag. +// Returns: +// OSAL_STATUS_CODE +// +//----------------------------------------------------------------------------- + +INT BeceemEEPROMBulkWrite( + PMINI_ADAPTER Adapter, + PUCHAR pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) +{ + UINT uiBytesToCopy = uiNumBytes; + //UINT uiRdbk = 0; + UINT uiData[4] = {0}; + UINT uiIndex = 0; + UINT uiTempOffset = 0; + UINT uiExtraBytes = 0; + //PUINT puiBuffer = (PUINT)pBuffer; + //INT value; + + if(uiOffset%MAX_RW_SIZE && uiBytesToCopy) + { + uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE); + uiExtraBytes = uiOffset-uiTempOffset; + + + BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE); + + if(uiBytesToCopy >= (16 -uiExtraBytes)) + { + OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes); + + if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) + return STATUS_FAILURE; + + uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); + uiIndex += (MAX_RW_SIZE - uiExtraBytes); + uiOffset += (MAX_RW_SIZE - uiExtraBytes); + } + else + { + OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy); + + if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) + return STATUS_FAILURE; + + uiIndex += uiBytesToCopy; + uiOffset += uiBytesToCopy; + uiBytesToCopy = 0; + } + + + } + + while(uiBytesToCopy) + { + if(Adapter->device_removed) + { + return -1; + } + + if(uiBytesToCopy >= MAX_RW_SIZE) + { + + if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) ) + return STATUS_FAILURE; + + uiIndex += MAX_RW_SIZE; + uiOffset += MAX_RW_SIZE; + uiBytesToCopy -= MAX_RW_SIZE; + } + else + { + // + // To program non 16byte aligned data, read 16byte and then update. + // + BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16); + OsalMemMove(&uiData[0],pBuffer+uiIndex,uiBytesToCopy); + + + if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) ) + return STATUS_FAILURE; + uiBytesToCopy = 0; + } + + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemNVMRead +// +// Description: Reads n number of bytes from NVM. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Buffer to store the data read from NVM +// uiOffset - Offset of NVM from where data should be read +// uiNumBytes - Number of bytes to be read from the NVM. +// +// Returns: +// OSAL_STATUS_SUCCESS - if NVM read is successfull. +// - if failed. +//----------------------------------------------------------------------------- + +INT BeceemNVMRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) +{ + INT Status = 0; +#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT uiTemp = 0, value; +#endif + + if(Adapter->eNVMType == NVM_FLASH) + { + if(Adapter->bFlashRawRead == FALSE) + { + if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD)) + return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes); + uiOffset = uiOffset+ Adapter->ulFlashCalStart ; + } +#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); +#else + + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + Status = BeceemFlashBulkRead(Adapter, + pBuffer, + uiOffset, + uiNumBytes); + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); +#endif + } + else if(Adapter->eNVMType == NVM_EEPROM) + { + Status = BeceemEEPROMBulkRead(Adapter, + pBuffer, + uiOffset, + uiNumBytes); + } + else + { + Status = -1; + } + return Status; +} + +//----------------------------------------------------------------------------- +// Procedure: BeceemNVMWrite +// +// Description: Writes n number of bytes to NVM. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pBuffer - Buffer contains the data to be written. +// uiOffset - Offset of NVM where data to be written to. +// uiNumBytes - Number of bytes to be written.. +// +// Returns: +// OSAL_STATUS_SUCCESS - if NVM write is successfull. +// - if failed. +//----------------------------------------------------------------------------- + +INT BeceemNVMWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) +{ + INT Status = 0; + UINT uiTemp = 0; + UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + UINT uiIndex = 0; +#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT value; +#endif + UINT uiFlashOffset = 0; + + if(Adapter->eNVMType == NVM_FLASH) + { + if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD)) + Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify); + else + { + uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; + +#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes); +#else + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); + + if(Adapter->bStatusWrite == TRUE) + { + Status = BeceemFlashBulkWriteStatus(Adapter, + pBuffer, + uiFlashOffset, + uiNumBytes , + bVerify); + } + else + { + + Status = BeceemFlashBulkWrite(Adapter, + pBuffer, + uiFlashOffset, + uiNumBytes, + bVerify); + } +#endif + } + + + if(uiOffset >= EEPROM_CALPARAM_START) + { + uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); + while(uiNumBytes) + { + if(uiNumBytes > BUFFER_4K) + { + wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K); + uiNumBytes -= BUFFER_4K; + uiIndex += BUFFER_4K; + } + else + { + wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes); + uiNumBytes = 0; + break; + } + } + } + else + { + if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START) + { + ULONG ulBytesTobeSkipped = 0; + PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases. + uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); + ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); + uiOffset += (EEPROM_CALPARAM_START - uiOffset); + while(uiNumBytes) + { + if(uiNumBytes > BUFFER_4K) + { + wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K); + uiNumBytes -= BUFFER_4K; + uiIndex += BUFFER_4K; + } + else + { + wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes); + uiNumBytes = 0; + break; + } + } + + } + } + + // restore the values. + wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp)); + } + else if(Adapter->eNVMType == NVM_EEPROM) + { + Status = BeceemEEPROMBulkWrite(Adapter, + (PUCHAR)pBuffer, + uiOffset, + uiNumBytes, + bVerify); + if(bVerify) + { + Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes); + } + } + else + { + Status = -1; + } + return Status; +} + +//----------------------------------------------------------------------------- +// Procedure: BcmUpdateSectorSize +// +// Description: Updates the sector size to FLASH. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// uiSectorSize - sector size +// +// Returns: +// OSAL_STATUS_SUCCESS - if NVM write is successfull. +// - if failed. +//----------------------------------------------------------------------------- + +INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize) +{ + INT Status = -1; + FLASH_CS_INFO sFlashCsInfo = {0}; + UINT uiTemp = 0; + + UINT uiSectorSig = 0; + UINT uiCurrentSectorSize = 0; + + UINT value; + + + + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + +// +// Before updating the sector size in the reserved area, check if already present. +// + BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo)); + uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); + uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); + + if(uiSectorSig == FLASH_SECTOR_SIZE_SIG) + { + + if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) + { + if(uiSectorSize == uiCurrentSectorSize) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash"); + Status = STATUS_SUCCESS; + goto Restore ; + } + } + } + + if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) + { + + sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); + sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); + + Status = BeceemFlashBulkWrite(Adapter, + (PUINT)&sFlashCsInfo, + Adapter->ulFlashControlSectionStart, + sizeof(sFlashCsInfo), + TRUE); + + + } + + Restore : + // restore the values. + wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp)); + + + return Status; + +} + +//----------------------------------------------------------------------------- +// Procedure: BcmGetFlashSectorSize +// +// Description: Finds the sector size of the FLASH. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// UINT - sector size. +// +//----------------------------------------------------------------------------- + +UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) +{ + UINT uiSectorSize = 0; + UINT uiSectorSig = 0; + + if(Adapter->bSectorSizeOverride && + (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) + { + Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; + } + else + { + + uiSectorSig = FlashSectorSizeSig; + + if(uiSectorSig == FLASH_SECTOR_SIZE_SIG) + { + uiSectorSize = FlashSectorSize; + // + // If the sector size stored in the FLASH makes sense then use it. + // + if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) + { + Adapter->uiSectorSize = uiSectorSize; + } + //No valid size in FLASH, check if Config file has it. + else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) + { + Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; + } + // Init to Default, if none of the above works. + else + { + Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; + } + + } + else + { + if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) + { + Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; + } + else + { + Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; + } + } + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x \n", Adapter->uiSectorSize); + return Adapter->uiSectorSize; +} + +//----------------------------------------------------------------------------- +// Procedure: BcmInitEEPROMQueues +// +// Description: Initialization of EEPROM queues. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// +//----------------------------------------------------------------------------- + +INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter) +{ + UINT value = 0; + /* CHIP Bug : Clear the Avail bits on the Read queue. The default + * value on this register is supposed to be 0x00001102. + * But we get 0x00001122. */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" ); + value = EEPROM_READ_DATA_AVAIL; + wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + + /* Flush the all the EEPROM queues. */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); + value =EEPROM_ALL_QUEUE_FLUSH ; + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + + value = 0; + wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); + + /* Read the EEPROM Status Register. Just to see, no real purpose. */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) ); + + return STATUS_SUCCESS; +} /* BcmInitEEPROMQueues() */ + +//----------------------------------------------------------------------------- +// Procedure: BcmInitNVM +// +// Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// +//----------------------------------------------------------------------------- + +INT BcmInitNVM(PMINI_ADAPTER ps_adapter) +{ +#ifdef BCM_SHM_INTERFACE +#ifdef FLASH_DIRECT_ACCESS + unsigned int data,data1,data2 = 1; + wrm(ps_adapter, PAD_SELECT_REGISTER, &data2, 4); + data1 = rdm(ps_adapter,SYS_CFG,&data,4); + data1 = rdm(ps_adapter,SYS_CFG,&data,4); + data2 = (data | 0x80 | 0x8000); + wrm(ps_adapter,SYS_CFG, &data2,4); // over-write as Flash boot mode +#endif + ps_adapter->eNVMType = NVM_FLASH; +#else + BcmValidateNvmType(ps_adapter); + BcmInitEEPROMQueues(ps_adapter); +#endif + + if(ps_adapter->eNVMType == NVM_AUTODETECT) + { + ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); + if(ps_adapter->eNVMType == NVM_UNKNOWN) + { + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); + } + } + else if(ps_adapter->eNVMType == NVM_FLASH) + { + BcmGetFlashCSInfo(ps_adapter); + } + + BcmGetNvmSize(ps_adapter); + + return STATUS_SUCCESS; +} +/***************************************************************************/ +/*BcmGetNvmSize : set the EEPROM or flash size in Adapter. +* +*Input Parameter: +* Adapter data structure +*Return Value : +* 0. means sucess; +*/ +/***************************************************************************/ + +INT BcmGetNvmSize(PMINI_ADAPTER Adapter) +{ + if(Adapter->eNVMType == NVM_EEPROM) + { + Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); + } + else if(Adapter->eNVMType == NVM_FLASH) + { + Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); + } + return 0; +} + +//----------------------------------------------------------------------------- +// Procedure: BcmValidateNvm +// +// Description: Validates the NVM Type option selected against the device +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// +//----------------------------------------------------------------------------- +VOID BcmValidateNvmType(PMINI_ADAPTER Adapter) +{ + + // + // if forcing the FLASH through CFG file, we should ensure device really has a FLASH. + // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. + // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. + // + + if(Adapter->eNVMType == NVM_FLASH && + Adapter->chip_id < 0xBECE3300) + { + Adapter->eNVMType = NVM_AUTODETECT; + } +} +//----------------------------------------------------------------------------- +// Procedure: BcmReadFlashRDID +// +// Description: Reads ID from Serial Flash +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// Flash ID +//----------------------------------------------------------------------------- +ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter) +{ + ULONG ulRDID = 0; + UINT value; +// +// Read ID Instruction. +// + value = (FLASH_CMD_READ_ID<<24); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)); + +//Delay + udelay(10); +// +// Read SPI READQ REG. The output will be WWXXYYZZ. +// The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. +// + rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID)); + + return (ulRDID >>8); + + +} + +INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter) +{ + if(psAdapter == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); + return -EINVAL; + } + psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL); + if(psAdapter->psFlashCSInfo == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x"); + return -ENOMEM; + } + + psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL); + if(psAdapter->psFlash2xCSInfo == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x"); + bcm_kfree(psAdapter->psFlashCSInfo); + return -ENOMEM; + } + + psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL); + if(psAdapter->psFlash2xVendorInfo == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x"); + bcm_kfree(psAdapter->psFlashCSInfo); + bcm_kfree(psAdapter->psFlash2xCSInfo); + return -ENOMEM; + } + + return STATUS_SUCCESS; +} + +INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter) +{ + if(psAdapter == NULL) + { + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL"); + return -EINVAL; + } + bcm_kfree(psAdapter->psFlashCSInfo); + bcm_kfree(psAdapter->psFlash2xCSInfo); + bcm_kfree(psAdapter->psFlash2xVendorInfo); + return STATUS_SUCCESS ; +} + +INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter) +{ + UINT Index = 0; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware )); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); + for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, + (psFlash2xCSInfo->SectorAccessBitMap[Index])); + } + + return STATUS_SUCCESS; +} + + +INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) +{ + UINT Index = 0; + psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); + psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion); + //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); + psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); + psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); + psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); + psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); + psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware ); + psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage); + psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart); + psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd); + psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart); + psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd); + psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); + psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData); + psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout); + psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature); + psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig); + psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize); + psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize); + psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize); + psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr); + psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize); + psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig); + psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout); + psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start); + psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End); + psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start); + psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End); + psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start); + psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End); + psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start); + psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End); + psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start); + psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End); + psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start); + psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End); + psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader); + psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start); + psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End); + psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start); + psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End); + psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start); + psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End); + psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start); + psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); + for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++) + { + psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); + } + return STATUS_SUCCESS; +} + +INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) +{ + //UINT Index = 0; + psFlashCSInfo->MagicNumber =ntohl(psFlashCSInfo->MagicNumber); + psFlashCSInfo->FlashLayoutVersion =ntohl(psFlashCSInfo->FlashLayoutVersion); + psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); + //won't convert according to old assumption + psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion); + + psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); + psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); + psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware ); + psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); + psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); + psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); + psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); + psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); + psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); + psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); + psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); + psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); + psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); + psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); + psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); + psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); + psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); + psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); + psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); + psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); + + return STATUS_SUCCESS; +} + +INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) +{ + return ( Adapter->uiVendorExtnFlag && + (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && + (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) ); +} + +VOID UpdateVendorInfo(PMINI_ADAPTER Adapter) +{ + B_UINT32 i = 0; + UINT uiSizeSection = 0; + + Adapter->uiVendorExtnFlag = FALSE; + + for(i = 0;i < TOTAL_SECTIONS;i++) + Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS; + + if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) + return; + + i = 0; + while(i < TOTAL_SECTIONS) + { + if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) + { + i++; + continue; + } + + Adapter->uiVendorExtnFlag = TRUE; + uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - + Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); + + switch(i) + { + case DSD0: + if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; + break; + + case DSD1: + if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; + break; + + case DSD2: + if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; + break; + case VSA0: + if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; + break; + + case VSA1: + if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; + break; + case VSA2: + if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; + break; + + default: + break; + } + i++; + } + +} + +//----------------------------------------------------------------------------- +// Procedure: BcmGetFlashCSInfo +// +// Description: Reads control structure and gets Cal section addresses. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// +//----------------------------------------------------------------------------- + +INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) +{ + //FLASH_CS_INFO sFlashCsInfo = {0}; + +#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT value; +#endif + UINT uiFlashLayoutMajorVersion; + Adapter->uiFlashLayoutMinorVersion = 0; + Adapter->uiFlashLayoutMajorVersion = 0; + Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; + + + Adapter->uiFlashBaseAdd = 0; + Adapter->ulFlashCalStart = 0; + memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO)); + memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO)); + +#ifndef BCM_SHM_INTERFACE + if(!Adapter->bDDRInitDone) + { + { + value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; + wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); + } + } + +#endif + + // Reading first 8 Bytes to get the Flash Layout + // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) + BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8); + + Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); + + if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) + { + uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); + Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); + } + else + { + Adapter->uiFlashLayoutMinorVersion = 0; + uiFlashLayoutMajorVersion = 0; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); + + if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) + { + BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO)); + ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); + Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); + + if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) + { + Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; + } + + if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && + (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && + (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && + (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) + { + Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); + Adapter->fpFlashWrite = flashByteWrite; + Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; + } + else + { + Adapter->ulFlashWriteSize = MAX_RW_SIZE; + Adapter->fpFlashWrite = flashWrite; + Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; + } + + BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), + (Adapter->psFlashCSInfo->FlashSectorSize)); + + + Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; + + + } + else + { + if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL, + Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO))) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n"); + return STATUS_FAILURE; + } + ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); +#ifndef BCM_SHM_INTERFACE + BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter); +#endif + if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && + (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && + (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && + (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) + { + Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; + Adapter->fpFlashWrite = flashByteWrite; + Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; + } + else + { + Adapter->ulFlashWriteSize = MAX_RW_SIZE; + Adapter->fpFlashWrite = flashWrite; + Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; + } + + BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig, + Adapter->psFlash2xCSInfo->FlashSectorSize); + + UpdateVendorInfo(Adapter); + + BcmGetActiveDSD(Adapter); + BcmGetActiveISO(Adapter); + Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF; + Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; + + } + /* + Concerns: what if CS sector size does not match with this sector size ??? + what is the indication of AccessBitMap in CS in flash 2.x ???? + */ +#ifndef BCM_SHM_INTERFACE + Adapter->ulFlashID = BcmReadFlashRDID(Adapter); +#endif + + Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; + + #if 0 + if(FLASH_PART_SST25VF080B == Adapter->ulFlashID) + { + // + // 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS. + // + Adapter->uiSectorSize = 0x10000; + } + #endif + + return STATUS_SUCCESS ; +} + + +//----------------------------------------------------------------------------- +// Procedure: BcmGetNvmType +// +// Description: Finds the type of NVM used. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// +// Returns: +// NVM_TYPE +// +//----------------------------------------------------------------------------- + +NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter) +{ + UINT uiData = 0; + + BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4); + if(uiData == BECM) + { + return NVM_EEPROM; + } + // + // Read control struct and get cal addresses before accessing the flash + // + BcmGetFlashCSInfo(Adapter); + + BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4); + if(uiData == BECM) + { + return NVM_FLASH; + } +// +// even if there is no valid signature on EEPROM/FLASH find out if they really exist. +// if exist select it. +// + if(BcmGetEEPROMSize(Adapter)) + { + return NVM_EEPROM; + } + +//TBD for Flash. + + + return NVM_UNKNOWN; +} + +/** +* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given +* @Adapter : Drivers Private Data structure +* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL +* +* Return value:- +* On success it return the start offset of the provided section val +* On Failure -returns STATUS_FAILURE +**/ + +INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +{ + /* + * Considering all the section for which end offset can be calculated or directly given + * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section + * endoffset can't be calculated or given in CS Stucture. + */ + + INT SectStartOffset = 0 ; + + SectStartOffset = INVALID_OFFSET ; + + if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal)) + { + return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; + } + + switch(eFlashSectionVal) + { + case ISO_IMAGE1 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); + break; + case ISO_IMAGE2 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); + break; + case DSD0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); + break; + case DSD1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); + break; + case DSD2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); + break; + case VSA0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); + break; + case VSA1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); + break; + case VSA2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); + break; + case SCSI : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); + break; + case CONTROL_SECTION : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); + break; + case ISO_IMAGE1_PART2 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); + break; + case ISO_IMAGE1_PART3 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + break; + case ISO_IMAGE2_PART2 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); + break; + case ISO_IMAGE2_PART3 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + break; + default : + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x"); + SectStartOffset = INVALID_OFFSET; + } + return SectStartOffset; +} + +/** +* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given +* @Adapter : Drivers Private Data structure +* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL +* +* Return value:- +* On success it return the end offset of the provided section val +* On Failure -returns STATUS_FAILURE +**/ + +INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +{ + INT SectEndOffset = 0 ; + SectEndOffset = INVALID_OFFSET; + + if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) + { + return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; + } + + switch(eFlash2xSectionVal) + { + case ISO_IMAGE1 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); + break; + case ISO_IMAGE2 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); + break; + case DSD0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); + break; + case DSD1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); + break; + case DSD2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); + break; + case VSA0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); + break; + case VSA1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); + break; + case VSA2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); + break; + case SCSI : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + + (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); + break; + case CONTROL_SECTION : + //Not Clear So Putting failure. confirm and fix it. + SectEndOffset = STATUS_FAILURE; + case ISO_IMAGE1_PART2 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); + break; + case ISO_IMAGE1_PART3 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); + break; + case ISO_IMAGE2_PART2 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); + break; + case ISO_IMAGE2_PART3 : + if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); + break; + + default : + SectEndOffset = INVALID_OFFSET; + } + return SectEndOffset ; +} + +/* +* BcmFlash2xBulkRead:- Read API for Flash Map 2.x . +* @Adapter :Driver Private Data Structure +* @pBuffer : Buffer where data has to be put after reading +* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL +* @uiOffsetWithinSectionVal :- Offset with in provided section +* @uiNumBytes : Number of Bytes for Read +* +* Return value:- +* return true on sucess and STATUS_FAILURE on fail. +*/ + +INT BcmFlash2xBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffsetWithinSectionVal, + UINT uiNumBytes) +{ + + INT Status = STATUS_SUCCESS; + INT SectionStartOffset = 0; + UINT uiAbsoluteOffset = 0 ; + UINT uiTemp =0, value =0 ; + if(Adapter == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); + return -EINVAL; + } + if(Adapter->device_removed ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); + return -ENODEV; + } + + //NO_SECTION_VAL means absolute offset is given. + if(eFlash2xSectionVal == NO_SECTION_VAL) + SectionStartOffset = 0; + else + SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); + + if(SectionStartOffset == STATUS_FAILURE ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal); + return -EINVAL; + } + + if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) + return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); + + //calculating the absolute offset from FLASH; + uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + + Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ; + + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); + return Status ; + } + + return Status; +} + +/* +* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. +* @Adapter :Driver Private Data Structure +* @pBuffer : Buffer From where data has to taken for writing +* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL +* @uiOffsetWithinSectionVal :- Offset with in provided section +* @uiNumBytes : Number of Bytes for Write +* +* Return value:- +* return true on sucess and STATUS_FAILURE on fail. +* +*/ + +INT BcmFlash2xBulkWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + FLASH2X_SECTION_VAL eFlash2xSectVal, + UINT uiOffset, + UINT uiNumBytes, + UINT bVerify) +{ + + INT Status = STATUS_SUCCESS; + UINT FlashSectValStartOffset = 0; + UINT uiTemp = 0, value = 0; + if(Adapter == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); + return -EINVAL; + } + if(Adapter->device_removed ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); + return -ENODEV; + } + + //NO_SECTION_VAL means absolute offset is given. + if(eFlash2xSectVal == NO_SECTION_VAL) + FlashSectValStartOffset = 0; + else + FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal); + + if(FlashSectValStartOffset == STATUS_FAILURE ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal); + return -EINVAL; + } + + if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal)) + return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); + + //calculating the absolute offset from FLASH; + uiOffset = uiOffset + FlashSectValStartOffset; + + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + + Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify); + + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); + return Status ; + } + + return Status; + +} + +/** +* ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument. +* @Adapter : Beceem Private Data Structure +* @psDSDHeader :Pointer of the buffer where header has to be read +* @dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2 +* +* Return Value:- +* if suceeds return STATUS_SUCCESS or negative error code. +**/ +INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd) +{ + INT Status = STATUS_SUCCESS; + + Status =BcmFlash2xBulkRead(Adapter, + (PUINT)psDSDHeader, + dsd, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader, + sizeof(DSD_HEADER)); + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority)); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status); + } + + return Status; +} + +/** +* BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR +* @Adapter :-Drivers private Data Structure +* +* Return Value:- +* Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code +* +**/ +INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) +{ + FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; + + uiHighestPriDSD = getHighestPriDSD(Adapter); + Adapter->eActiveDSD = uiHighestPriDSD; + + if(DSD0 == uiHighestPriDSD) + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; + if(DSD1 == uiHighestPriDSD) + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; + if(DSD2 == uiHighestPriDSD) + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; + if(Adapter->eActiveDSD) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); + if(Adapter->eActiveDSD == 0) + { + //if No DSD gets Active, Make Active the DSD with WR permission + if(IsSectionWritable(Adapter,DSD2)) + { + Adapter->eActiveDSD = DSD2; + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; + } + else if(IsSectionWritable(Adapter,DSD1)) + { + Adapter->eActiveDSD = DSD1; + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; + } + else if(IsSectionWritable(Adapter,DSD0)) + { + Adapter->eActiveDSD = DSD0; + Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; + } + } + + return STATUS_SUCCESS; +} + +/** +* ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument. +* @Adapter : Driver Private Data Structure +* @psISOHeader :Pointer of the location where header has to be read +* @IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2 +* +* Return Value:- +* if suceeds return STATUS_SUCCESS or negative error code. +**/ + +INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage) +{ + INT Status = STATUS_SUCCESS; + + Status = BcmFlash2xBulkRead(Adapter, + (PUINT)psISOHeader, + IsoImage, + 0, + sizeof(ISO_HEADER)); + + if(Status == STATUS_SUCCESS) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority)); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed"); + } + return Status; +} + +/** +* BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue +* @Adapter : Driver private Data Structure +* +* Return Value:- +* Sucsess:- STATUS_SUCESS +* Failure- : negative erro code +* +**/ + +INT BcmGetActiveISO(PMINI_ADAPTER Adapter) +{ + + INT HighestPriISO = 0 ; + HighestPriISO = getHighestPriISO(Adapter); + + Adapter->eActiveISO = HighestPriISO ; + if(Adapter->eActiveISO == ISO_IMAGE2) + Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); + else if(Adapter->eActiveISO == ISO_IMAGE1) + Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); + + if(Adapter->eActiveISO) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO); + + return STATUS_SUCCESS; +} + +/** +* IsOffsetWritable :- it will tell the access permission of the sector having passed offset +* @Adapter : Drivers Private Data Structure +* @uiOffset : Offset provided in the Flash +* +* Return Value:- +* Sucess:-TRUE , offset is writable +* Failure:-FALSE, offset is RO +* +**/ +B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset) +{ + UINT uiSectorNum = 0; + UINT uiWordOfSectorPermission =0; + UINT uiBitofSectorePermission = 0; + B_UINT32 permissionBits = 0; + uiSectorNum = uiOffset/Adapter->uiSectorSize; + + //calculating the word having this Sector Access permission from SectorAccessBitMap Array + uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16]; + + //calculating the bit index inside the word for this sector + uiBitofSectorePermission = 2*(15 - uiSectorNum %16); + + //Setting Access permission + permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ; + permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; + if(permissionBits == SECTOR_READWRITE_PERMISSION) + return TRUE; + else + return FALSE; +} + +INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0 :0X%x", psFlash2xBitMap->DSD0); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1 :0X%x", psFlash2xBitMap->DSD1); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2 :0X%x", psFlash2xBitMap->DSD2); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0 :0X%x", psFlash2xBitMap->VSA0); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1 :0X%x", psFlash2xBitMap->VSA1); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2 :0X%x", psFlash2xBitMap->VSA2); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI :0X%x", psFlash2xBitMap->SCSI); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); + + return STATUS_SUCCESS; +} + +/** +* BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash +* 8bit has been assigned to every section. + bit[0] :Section present or not + bit[1] :section is valid or not + bit[2] : Secton is read only or has write permission too. + bit[3] : Active Section - + bit[7...4] = Reserved . + + @Adapter:-Driver private Data Structure +* +* Return value:- +* Sucess:- STATUS_SUCESS +* Failure:- negative error code +**/ + +INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap) +{ + + + PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo; + FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; + FLASH2X_SECTION_VAL uiHighestPriISO= 0 ; + BOOLEAN SetActiveDSDDone = FALSE ; + BOOLEAN SetActiveISODone = FALSE ; + + //For 1.x map all the section except DSD0 will be shown as not present + //This part will be used by calibration tool to detect the number of DSD present in Flash. + if(IsFlash2x(Adapter) == FALSE) + { + psFlash2xBitMap->ISO_IMAGE2 = 0; + psFlash2xBitMap->ISO_IMAGE1 = 0; + psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present) + psFlash2xBitMap->DSD1 = 0 ; + psFlash2xBitMap->DSD2 = 0 ; + psFlash2xBitMap->VSA0 = 0 ; + psFlash2xBitMap->VSA1 = 0 ; + psFlash2xBitMap->VSA2 = 0 ; + psFlash2xBitMap->CONTROL_SECTION = 0 ; + psFlash2xBitMap->SCSI= 0 ; + psFlash2xBitMap->Reserved0 = 0 ; + psFlash2xBitMap->Reserved1 = 0 ; + psFlash2xBitMap->Reserved2 = 0 ; + return STATUS_SUCCESS ; + + } + + uiHighestPriDSD = getHighestPriDSD(Adapter); + uiHighestPriISO = getHighestPriISO(Adapter); + + /// + // IS0 IMAGE 2 + /// + if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; + + + if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER) + psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; + + + //Calculation for extrating the Access permission + if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) + psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; + + if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) + { + psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ; + SetActiveISODone = TRUE; + } + + } + + /// + // IS0 IMAGE 1 + /// + if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; + + if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) + psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; + + // Calculation for extrating the Access permission + if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) + psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; + + if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) + { + psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ; + SetActiveISODone = TRUE; + } + } + + + + /// + // DSD2 + /// + if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; + + if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER) + psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; + + //Calculation for extrating the Access permission + if(IsSectionWritable(Adapter, DSD2) == FALSE) + { + psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; + + } + else + { + //Means section is writable + if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) + { + psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ; + SetActiveDSDDone =TRUE ; + } + } + } + + /// + // DSD 1 + /// + if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; + + + if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER) + psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; + + //Calculation for extrating the Access permission + if(IsSectionWritable(Adapter, DSD1) == FALSE) + { + psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; + } + else + { + //Means section is writable + if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) + { + psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ; + SetActiveDSDDone =TRUE ; + } + } + + } + + /// + //For DSD 0 + // + if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; + + if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER) + psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; + + //Setting Access permission + if(IsSectionWritable(Adapter, DSD0) == FALSE) + { + psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; + } + else + { + //Means section is writable + if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0)) + { + psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ; + SetActiveDSDDone =TRUE ; + } + } + } + + /// + // VSA 0 + /// + if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; + + //Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; + + //Calculation for extrating the Access permission + if(IsSectionWritable(Adapter, VSA0) == FALSE) + psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; + + //By Default section is Active + psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ; + + } + + + /// + // VSA 1 + /// + + if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; + + //Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID; + + //Checking For Access permission + if(IsSectionWritable(Adapter, VSA1) == FALSE) + psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; + + //By Default section is Active + psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ; + + } + + + /// + // VSA 2 + /// + + if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; + + + //Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; + + //Checking For Access permission + if(IsSectionWritable(Adapter, VSA2) == FALSE) + psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; + + //By Default section is Active + psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ; + } + + /// + // SCSI Section + /// + if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; + + + //Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID; + + //Checking For Access permission + if(IsSectionWritable(Adapter, SCSI) == FALSE) + psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; + + //By Default section is Active + psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ; + + } + + + /// + // Control Section + /// + if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) + { + //Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); + + + //Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; + + //Checking For Access permission + if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE) + psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; + + //By Default section is Active + psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ; + + } + + /// + // For Reserved Sections + /// + psFlash2xBitMap->Reserved0 = 0; + psFlash2xBitMap->Reserved0 = 0; + psFlash2xBitMap->Reserved0 = 0; + + BcmDumpFlash2xSectionBitMap(psFlash2xBitMap); + + return STATUS_SUCCESS ; + +} +/** +BcmSetActiveSection :- Set Active section is used to make priority field highest over other + section of same type. + +@Adapater :- Bcm Driver Private Data Structure +@eFlash2xSectionVal :- Flash section val whose priority has to be made highest. + +Return Value:- Make the priorit highest else return erorr code + +**/ +INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) +{ + INT SectImagePriority = 0; + INT Status =STATUS_SUCCESS; + + //DSD_HEADER sDSD = {0}; + //ISO_HEADER sISO = {0}; + INT HighestPriDSD = 0 ; + INT HighestPriISO = 0; + + + + Status = IsSectionWritable(Adapter,eFlash2xSectVal) ; + if(Status != TRUE ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal); + return STATUS_FAILURE; + } + + Adapter->bHeaderChangeAllowed = TRUE ; + switch(eFlash2xSectVal) + { + case ISO_IMAGE1 : + case ISO_IMAGE2 : + if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER ) + { + HighestPriISO = getHighestPriISO(Adapter); + + if(HighestPriISO == eFlash2xSectVal ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal ); + Status = STATUS_SUCCESS ; + break; + } + + SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; + + if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO)) + { + // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. + // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO + // by user + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + SectImagePriority = htonl(0x1); + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + HighestPriISO, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + SIGNATURE_SIZE, + TRUE); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); + Status = STATUS_FAILURE; + break ; + } + + HighestPriISO = getHighestPriISO(Adapter); + + if(HighestPriISO == eFlash2xSectVal ) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal ); + Status = STATUS_SUCCESS ; + break; + } + + SectImagePriority = 2; + } + + + SectImagePriority = htonl(SectImagePriority); + + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + eFlash2xSectVal, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + SIGNATURE_SIZE, + TRUE); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); + break ; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + Status = STATUS_FAILURE ; + break; + } + break; + case DSD0 : + case DSD1 : + case DSD2 : + if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER) + { + HighestPriDSD = getHighestPriDSD(Adapter); + + if((HighestPriDSD == eFlash2xSectVal)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS ; + break; + } + + SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ; + if(SectImagePriority <= 0) + { + // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. + // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD + // by user + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + SectImagePriority = htonl(0x1); + + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + HighestPriDSD, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break ; + } + + HighestPriDSD = getHighestPriDSD(Adapter); + + if((HighestPriDSD == eFlash2xSectVal)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); + Status = STATUS_SUCCESS ; + break; + } + + SectImagePriority = htonl(0x2); + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + HighestPriDSD, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break ; + } + + HighestPriDSD = getHighestPriDSD(Adapter); + + if((HighestPriDSD == eFlash2xSectVal)) + { + Status = STATUS_SUCCESS ; + break; + } + SectImagePriority = 3 ; + + } + SectImagePriority = htonl(SectImagePriority); + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + eFlash2xSectVal, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE , + TRUE); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); + Status = STATUS_FAILURE ; + break ; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + Status = STATUS_FAILURE ; + break; + } + break; + case VSA0 : + case VSA1 : + case VSA2 : + //Has to be decided + break ; + default : + Status = STATUS_FAILURE ; + break; + + } + + Adapter->bHeaderChangeAllowed = FALSE ; + return Status; + +} + +/** +BcmCopyISO - Used only for copying the ISO section +@Adapater :- Bcm Driver Private Data Structure +@sCopySectStrut :- Section copy structure + +Return value:- SUCCESS if copies successfully else negative error code + +**/ +INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) +{ + + PCHAR Buff = NULL; + FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0; + UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; + UINT uiTotalDataToCopy = 0; + BOOLEAN IsThisHeaderSector = FALSE ; + UINT sigOffset = 0; + UINT ISOLength = 0; + UINT Status = STATUS_SUCCESS; + UINT SigBuff[MAX_RW_SIZE]; + UINT i = 0; + + if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); + return STATUS_FAILURE; + } + + Status = BcmFlash2xBulkRead(Adapter, + &ISOLength, + sCopySectStrut.SrcSection, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize), + 4); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); + return Status; + } + + ISOLength = htonl(ISOLength); + + if(ISOLength % Adapter->uiSectorSize) + { + ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize); + } + + sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); + + Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); + + if(Buff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size"); + return -ENOMEM; + } + + if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2) + { + eISOReadPart = ISO_IMAGE1 ; + eISOWritePart = ISO_IMAGE2 ; + uiReadOffsetWithinPart = 0; + uiWriteOffsetWithinPart = 0 ; + + uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + + if(uiTotalDataToCopy < ISOLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); + return STATUS_FAILURE; + } + + uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + + if(uiTotalDataToCopy < ISOLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); + return STATUS_FAILURE; + } + + uiTotalDataToCopy = ISOLength; + + CorruptISOSig(Adapter,ISO_IMAGE2); + + while(uiTotalDataToCopy) + { + if(uiTotalDataToCopy == Adapter->uiSectorSize) + { + //Setting for write of first sector. First sector is assumed to be written in last + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector"); + eISOReadPart = ISO_IMAGE1 ; + uiReadOffsetWithinPart = 0; + eISOWritePart = ISO_IMAGE2; + uiWriteOffsetWithinPart = 0 ; + IsThisHeaderSector = TRUE ; + + } + else + { + uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ; + uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ; + + if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) )) + { + eISOReadPart = ISO_IMAGE1_PART2 ; + uiReadOffsetWithinPart = 0; + } + if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) + { + eISOReadPart = ISO_IMAGE1_PART3 ; + uiReadOffsetWithinPart = 0; + } + if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) + { + eISOWritePart = ISO_IMAGE2_PART2 ; + uiWriteOffsetWithinPart = 0; + } + if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) + { + eISOWritePart = ISO_IMAGE2_PART3 ; + uiWriteOffsetWithinPart = 0; + } + } + + Status = BcmFlash2xBulkRead(Adapter, + (PUINT)Buff, + eISOReadPart, + uiReadOffsetWithinPart, + Adapter->uiSectorSize + ); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); + break; + } + + if(IsThisHeaderSector == TRUE) + { + //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); + + for(i = 0; i < MAX_RW_SIZE;i++) + *(Buff + sigOffset + i) = 0xFF; + } + Adapter->bHeaderChangeAllowed = TRUE ; + + Status = BcmFlash2xBulkWrite(Adapter, + (PUINT)Buff, + eISOWritePart, + uiWriteOffsetWithinPart, + Adapter->uiSectorSize, + TRUE); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); + break; + } + + Adapter->bHeaderChangeAllowed = FALSE; + + if(IsThisHeaderSector == TRUE) + { + WriteToFlashWithoutSectorErase(Adapter, + SigBuff, + eISOWritePart, + sigOffset, + MAX_RW_SIZE); + IsThisHeaderSector = FALSE ; + } + //substracting the written Data + uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; + } + + + } + + if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1) + { + eISOReadPart = ISO_IMAGE2 ; + eISOWritePart = ISO_IMAGE1 ; + uiReadOffsetWithinPart = 0; + uiWriteOffsetWithinPart = 0 ; + + uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + + if(uiTotalDataToCopy < ISOLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); + return STATUS_FAILURE; + } + + uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+ + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + + if(uiTotalDataToCopy < ISOLength) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); + return STATUS_FAILURE; + } + + uiTotalDataToCopy = ISOLength; + + CorruptISOSig(Adapter,ISO_IMAGE1); + + while(uiTotalDataToCopy) + { + if(uiTotalDataToCopy == Adapter->uiSectorSize) + { + //Setting for write of first sector. First sector is assumed to be written in last + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector"); + eISOReadPart = ISO_IMAGE2 ; + uiReadOffsetWithinPart = 0; + eISOWritePart = ISO_IMAGE1; + uiWriteOffsetWithinPart = 0 ; + IsThisHeaderSector = TRUE; + + } + else + { + uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ; + uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ; + + if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) )) + { + eISOReadPart = ISO_IMAGE2_PART2 ; + uiReadOffsetWithinPart = 0; + } + if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) + { + eISOReadPart = ISO_IMAGE2_PART3 ; + uiReadOffsetWithinPart = 0; + } + if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) + { + eISOWritePart = ISO_IMAGE1_PART2 ; + uiWriteOffsetWithinPart = 0; + } + if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) + { + eISOWritePart = ISO_IMAGE1_PART3 ; + uiWriteOffsetWithinPart = 0; + } + } + + Status = BcmFlash2xBulkRead(Adapter, + (PUINT)Buff, + eISOReadPart, + uiReadOffsetWithinPart, + Adapter->uiSectorSize + ); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); + break; + } + + if(IsThisHeaderSector == TRUE) + { + //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); + + for(i = 0; i < MAX_RW_SIZE;i++) + *(Buff + sigOffset + i) = 0xFF; + + } + Adapter->bHeaderChangeAllowed = TRUE ; + Status = BcmFlash2xBulkWrite(Adapter, + (PUINT)Buff, + eISOWritePart, + uiWriteOffsetWithinPart, + Adapter->uiSectorSize, + TRUE); + + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); + break; + } + + Adapter->bHeaderChangeAllowed = FALSE ; + + if(IsThisHeaderSector == TRUE) + { + WriteToFlashWithoutSectorErase(Adapter, + SigBuff, + eISOWritePart, + sigOffset, + MAX_RW_SIZE); + IsThisHeaderSector = FALSE ; + } + + //substracting the written Data + uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; + } + + + } + + bcm_kfree(Buff); + + return Status; +} +/** +BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. + It will corrupt the sig, if Section is writable, by making first bytes as zero. +@Adapater :- Bcm Driver Private Data Structure +@eFlash2xSectionVal :- Flash section val which has header + +Return Value :- + Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS + Failure :-Return negative error code + + +**/ +INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +{ + + INT Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal); + + if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) + { + Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); + } + else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) + { + Status = CorruptISOSig(Adapter, eFlash2xSectionVal); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal); + return STATUS_SUCCESS; + } + return Status; +} +/** +BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has + header and Write Permission. +@Adapater :- Bcm Driver Private Data Structure +@eFlashSectionVal :- Flash section val which has header + +Return Value :- + Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS + Failure :-Return negative error code + +**/ +INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +{ + + UINT uiSignature = 0 ; + UINT uiOffset = 0; + //DSD_HEADER dsdHeader = {0}; + + if(Adapter->bSigCorrupted == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n"); + return STATUS_SUCCESS; + } + if(Adapter->bAllDSDWriteAllow == FALSE) + { + if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature"); + return SECTOR_IS_NOT_WRITABLE; + } + } + if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) + { + uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ; + uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ; + + uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber); + + if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig"); + return STATUS_FAILURE; + } + + } + else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) + { + uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); + //uiOffset = 0; + uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber); + if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig"); + return STATUS_FAILURE; + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); + return STATUS_FAILURE; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature"); + + + Adapter->bHeaderChangeAllowed = TRUE; + Adapter->bSigCorrupted = FALSE; + BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE); + Adapter->bHeaderChangeAllowed = FALSE; + + + + return STATUS_SUCCESS; +} +/** +validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. + if requested Bytes goes beyond the Requested section, it reports error. +@Adapater :- Bcm Driver Private Data Structure +@psFlash2xReadWrite :-Flash2x Read/write structure pointer + +Return values:-Return TRUE is request is valid else FALSE. + + +**/ +INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) +{ + UINT uiNumOfBytes = 0 ; + UINT uiSectStartOffset = 0 ; + UINT uiSectEndOffset = 0; + uiNumOfBytes = psFlash2xReadWrite->numOfBytes; + + if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section); + return FALSE; + } + uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section); + if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2)) + { + if(psFlash2xReadWrite->Section == ISO_IMAGE1) + { + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+ + BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+ + BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3); + } + else if(psFlash2xReadWrite->Section == ISO_IMAGE2) + { + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+ + BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+ + BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) - + BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3); + + } + + //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset + //it should be added in startoffset. so that check done in last of this function can be valued. + uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ; + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset); + } + else + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset); + + //Checking the boundary condition + if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) + return TRUE; + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request...."); + return FALSE; + } + +} + +/** +IsFlash2x :- check for Flash 2.x +@Adapater :- Bcm Driver Private Data Structure + +Return value:- + return TRUE if flah2.x of hgher version else return false. +**/ + +INT IsFlash2x(PMINI_ADAPTER Adapter) +{ + if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) + return TRUE ; + else + return FALSE; +} +/** +GetFlashBaseAddr :- Calculate the Flash Base address +@Adapater :- Bcm Driver Private Data Structure + +Return Value:- + Success :- Base Address of the Flash +**/ + +INT GetFlashBaseAddr(PMINI_ADAPTER Adapter) +{ + + UINT uiBaseAddr = 0; + + if(Adapter->bDDRInitDone) + { + /* + For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + In case of Raw Read... use the default value + */ + if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && + !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)) + ) + uiBaseAddr = Adapter->uiFlashBaseAdd ; + else + uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; + } + else + { + /* + For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + In case of Raw Read... use the default value + */ + if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && + !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)) + ) + uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; + else + uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; + } + + return uiBaseAddr ; +} +/** +BcmCopySection :- This API is used to copy the One section in another. Both section should + be contiuous and of same size. Hence this Will not be applicabe to copy ISO. + +@Adapater :- Bcm Driver Private Data Structure +@SrcSection :- Source section From where data has to be copied +@DstSection :- Destination section to which data has to be copied +@offset :- Offset from/to where data has to be copied from one section to another. +@numOfBytes :- number of byes that has to be copyed from one section to another at given offset. + in case of numofBytes equal zero complete section will be copied. + +Return Values- + Sucess : Return STATUS_SUCCESS + Faillure :- return negative error code + +**/ + +INT BcmCopySection(PMINI_ADAPTER Adapter, + FLASH2X_SECTION_VAL SrcSection, + FLASH2X_SECTION_VAL DstSection, + UINT offset, + UINT numOfBytes) +{ + UINT BuffSize = 0 ; + UINT BytesToBeCopied = 0; + PUCHAR pBuff = NULL ; + INT Status = STATUS_SUCCESS ; + if(SrcSection == DstSection) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again"); + return -EINVAL; + } + if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection"); + return -EINVAL; + } + if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection"); + return -EINVAL; + } + + #if 0 + else + { + if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2)) + { + if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type"); + return -EINVAL; + } + } + + } + #endif + //if offset zero means have to copy complete secton + + if(numOfBytes == 0) + { + numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection) + - BcmGetSectionValStartOffset(Adapter,SrcSection); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes); + } + + if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection) + - BcmGetSectionValStartOffset(Adapter,SrcSection)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n", + offset, numOfBytes); + return -EINVAL; + } + + if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection) + - BcmGetSectionValStartOffset(Adapter,DstSection)) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", + offset, numOfBytes); + return -EINVAL; + } + + + if(numOfBytes > Adapter->uiSectorSize ) + BuffSize = Adapter->uiSectorSize; + else + BuffSize = numOfBytes ; + + pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL); + if(pBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. "); + return -ENOMEM; + } + + + BytesToBeCopied = Adapter->uiSectorSize ; + if(offset % Adapter->uiSectorSize) + BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize); + if(BytesToBeCopied > numOfBytes) + BytesToBeCopied = numOfBytes ; + + + + Adapter->bHeaderChangeAllowed = TRUE; + + do + { + Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied); + break; + } + Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE); + if(Status) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied); + break; + } + offset = offset + BytesToBeCopied; + numOfBytes = numOfBytes - BytesToBeCopied ; + if(numOfBytes) + { + if(numOfBytes > Adapter->uiSectorSize ) + BytesToBeCopied = Adapter->uiSectorSize; + else + BytesToBeCopied = numOfBytes; + } + }while(numOfBytes > 0) ; + bcm_kfree(pBuff); + Adapter->bHeaderChangeAllowed = FALSE ; + return Status; +} + +/** +SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write +@Adapater :- Bcm Driver Private Data Structure +@pBuff :- Data buffer that has to be written in sector having the header map. +@uiOffset :- Flash offset that has to be written. + +Return value :- + Sucess :- On sucess return STATUS_SUCCESS + Faillure :- Return negative error code + +**/ + +INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) +{ + UINT offsetToProtect = 0,HeaderSizeToProtect =0; + BOOLEAN bHasHeader = FALSE ; + PUCHAR pTempBuff =NULL; + UINT uiSectAlignAddr = 0; + UINT sig = 0; + + #if 0 + //if Chenges in Header is allowed, Return back + if(Adapter->bHeaderChangeAllowed == TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed"); + return STATUS_SUCCESS ; + } + #endif + //making the offset sector alligned + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + + + if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)|| + (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)|| + (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize)) + { + + //offset from the sector boundry having the header map + offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; + HeaderSizeToProtect = sizeof(DSD_HEADER); + bHasHeader = TRUE ; + } + + if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) || + uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)) + { + offsetToProtect = 0; + HeaderSizeToProtect = sizeof(ISO_HEADER); + bHasHeader = TRUE; + } + //If Header is present overwrite passed buffer with this + if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) + { + pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); + if(pTempBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed "); + return -ENOMEM; + } + //Read header + BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect); + //Replace Buffer content with Header + memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect); + + bcm_kfree(pTempBuff); + } + if(bHasHeader && Adapter->bSigCorrupted) + { + sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber))); + sig = ntohl(sig); + if((sig & 0xFF000000) != CORRUPTED_PATTERN) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore"); + Adapter->bSigCorrupted = FALSE; + return STATUS_SUCCESS; + } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig); + *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only"); + Adapter->bSigCorrupted = FALSE; + } + + return STATUS_SUCCESS ; +} +INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset) +{ + UINT GPIOConfig = 0 ; + + + if(Adapter->bFlashRawRead == FALSE) + { + //Applicable for Flash2.x + if(IsFlash2x(Adapter) == FALSE) + return STATUS_SUCCESS; + } + + if(offset/FLASH_PART_SIZE) + { + //bit[14..12] -> will select make Active CS1, CS2 or CS3 + // Select CS1, CS2 and CS3 (CS0 is dedicated pin) + rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); + GPIOConfig |= (7 << 12); + wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); + } + + return STATUS_SUCCESS ; +} +/** +BcmDoChipSelect : This will selcet the appropriate chip for writing. +@Adapater :- Bcm Driver Private Data Structure + +OutPut:- + Select the Appropriate chip and retrn status Sucess +**/ +INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) +{ + UINT FlashConfig = 0; + INT ChipNum = 0; + UINT GPIOConfig = 0; + UINT PartNum = 0; + + ChipNum = offset / FLASH_PART_SIZE ; + + // + // Chip Select mapping to enable flash0. + // To select flash 0, we have to OR with (0<<12). + // ORing 0 will have no impact so not doing that part. + // In future if Chip select value changes from 0 to non zero, + // That needs be taken care with backward comaptibility. No worries for now. + // + + /* + SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured + if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) + Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from + power down modes (Idle mode/shutdown mode), the values in the register will be different. + */ + + if(Adapter->SelectedChip == ChipNum) + return STATUS_SUCCESS; + + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); + Adapter->SelectedChip = ChipNum ; + + //bit[13..12] will select the appropriate chip + rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4); + rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); + + { + switch(ChipNum) + { + case 0: + PartNum = 0; + break; + case 1: + PartNum = 3; + GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); + break; + case 2: + PartNum = 1; + GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); + break; + case 3: + PartNum = 2; + GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); + break; + } + } + /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, + nothing to do... can return immediately. + ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. + Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. + These values are not written by host other than during CHIP_SELECT. + */ + if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) + return STATUS_SUCCESS; + + //clearing the bit[13..12] + FlashConfig &= 0xFFFFCFFF; + FlashConfig = (FlashConfig | (PartNum<psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber), + SIGNATURE_SIZE); + + uiDSDsig = ntohl(uiDSDsig); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig); + + return uiDSDsig ; +} +INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd) +{ + //UINT priOffsetInMap = 0 ; + INT uiDSDPri = STATUS_FAILURE; + //DSD_HEADER dsdHeader = {0}; + //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; + if(IsSectionWritable(Adapter,dsd)) + { + if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER) + { + BcmFlash2xBulkRead(Adapter, + &uiDSDPri, + dsd, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + 4); + + uiDSDPri = ntohl(uiDSDPri); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri); + + } + } + return uiDSDPri; +} +FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter) +{ + INT DSDHighestPri = STATUS_FAILURE; + INT DsdPri= 0 ; + FLASH2X_SECTION_VAL HighestPriDSD = 0 ; + + if(IsSectionWritable(Adapter,DSD2)) + { + DSDHighestPri = ReadDSDPriority(Adapter,DSD2); + HighestPriDSD = DSD2 ; + } + if(IsSectionWritable(Adapter,DSD1)) + { + DsdPri = ReadDSDPriority(Adapter,DSD1); + if(DSDHighestPri < DsdPri) + { + DSDHighestPri = DsdPri ; + HighestPriDSD = DSD1; + } + } + if(IsSectionWritable(Adapter,DSD0)) + { + DsdPri = ReadDSDPriority(Adapter,DSD0); + if(DSDHighestPri < DsdPri) + { + DSDHighestPri = DsdPri ; + HighestPriDSD = DSD0; + } + } + if(HighestPriDSD) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); + return HighestPriDSD ; +} + +INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) +{ + UINT uiISOsig = 0; + //UINT sigoffsetInMap = 0; + //ISO_HEADER ISOHeader = {0}; + + + //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; + + if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs"); + return STATUS_FAILURE; + } + BcmFlash2xBulkRead(Adapter, + &uiISOsig, + iso, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber), + SIGNATURE_SIZE); + + uiISOsig = ntohl(uiISOsig); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig); + + return uiISOsig ; +} +INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) +{ + + INT ISOPri = STATUS_FAILURE; + if(IsSectionWritable(Adapter,iso)) + { + if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER) + { + BcmFlash2xBulkRead(Adapter, + &ISOPri, + iso, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + 4); + + ISOPri = ntohl(ISOPri); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri); + + } + } + return ISOPri; +} +FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter) +{ + INT ISOHighestPri = STATUS_FAILURE; + INT ISOPri= 0 ; + FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ; + + if(IsSectionWritable(Adapter,ISO_IMAGE2)) + { + ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2); + HighestPriISO = ISO_IMAGE2 ; + } + if(IsSectionWritable(Adapter,ISO_IMAGE1)) + { + ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1); + if(ISOHighestPri < ISOPri) + { + ISOHighestPri = ISOPri ; + HighestPriISO = ISO_IMAGE1; + } + } + if(HighestPriISO) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri); + return HighestPriISO ; +} +INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, + PUINT pBuff, + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffset, + UINT uiNumBytes + ) +{ +#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT uiTemp = 0, value = 0 ; + UINT i = 0; + UINT uiPartOffset = 0; +#endif + UINT uiStartOffset = 0; + //Adding section start address + INT Status = STATUS_SUCCESS; + PUCHAR pcBuff = (PUCHAR)pBuff; + + if(uiNumBytes % Adapter->ulFlashWriteSize) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); + return STATUS_FAILURE; + } + + uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); + + if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) + { + return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); + } + + uiOffset = uiOffset + uiStartOffset; + +#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes); +#else + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + + Adapter->SelectedChip = RESET_CHIP_SELECT; + BcmDoChipSelect(Adapter,uiOffset); + uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + + for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize) + { + if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) + Status = flashByteWrite(Adapter,uiPartOffset, pcBuff); + else + Status = flashWrite(Adapter,uiPartOffset, pcBuff); + + if(Status != STATUS_SUCCESS) + break; + + pcBuff = pcBuff + Adapter->ulFlashWriteSize; + uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; + } + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + Adapter->SelectedChip = RESET_CHIP_SELECT; +#endif + + return Status; +} + +#if 0 +UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType) +{ + + UINT numOfWRSubSec = 0; + switch(secType) + { + case ISO : + if(IsSectionWritable(Adapter,ISO_IMAGE1)) + numOfWRSubSec = numOfWRSubSec + 1; + if(IsSectionWritable(Adapter,ISO_IMAGE2)) + numOfWRSubSec = numOfWRSubSec + 1; + break; + + case DSD : + if(IsSectionWritable(Adapter,DSD2)) + numOfWRSubSec = numOfWRSubSec + 1; + if(IsSectionWritable(Adapter,DSD1)) + numOfWRSubSec = numOfWRSubSec + 1; + if(IsSectionWritable(Adapter,DSD0)) + numOfWRSubSec = numOfWRSubSec + 1; + break ; + + case VSA : + //for VSA Add code Here + default : + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\ + numOfWRSubSec = 0; + + } + return numOfWRSubSec; +} +#endif +BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) +{ + + BOOLEAN SectionPresent = FALSE ; + + switch(section) + { + + case ISO_IMAGE1 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE ; + break; + case ISO_IMAGE2 : + if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE ; + break; + case DSD0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case DSD1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case DSD2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case VSA0 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case VSA1 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case VSA2 : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case SCSI : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + case CONTROL_SECTION : + if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE ; + break; + default : + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x"); + SectionPresent = FALSE; + } + return SectionPresent ; +} +INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section) +{ + INT offset = STATUS_FAILURE; + INT Status = FALSE; + if(IsSectionExistInFlash(Adapter,Section) == FALSE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section); + return FALSE; + } + offset = BcmGetSectionValStartOffset(Adapter,Section); + if(offset == INVALID_OFFSET) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section); + return FALSE; + } + + if(IsSectionExistInVendorInfo(Adapter,Section)) + { + return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); + } + + Status = IsOffsetWritable(Adapter,offset); + return Status ; +} + +INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +{ + + PUCHAR pBuff = 0 ; + UINT sig = 0; + UINT uiOffset = 0; + UINT BlockStatus = 0; + UINT uiSectAlignAddr = 0; + + Adapter->bSigCorrupted = FALSE; + + if(Adapter->bAllDSDWriteAllow == FALSE) + { + if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature"); + return SECTOR_IS_NOT_WRITABLE; + } + } + + pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); + if(pBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); + return -ENOMEM ; + } + + uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER); + uiOffset -= MAX_RW_SIZE ; + + BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE); + + + sig = *((PUINT)(pBuff +12)); + sig =ntohl(sig); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE); + //Now corrupting the sig by corrupting 4th last Byte. + *(pBuff + 12) = 0; + + if(sig == DSD_IMAGE_MAGIC_NUMBER) + { + Adapter->bSigCorrupted = TRUE; + if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) + { + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1); + BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize); + + WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal, + (uiOffset + 12),BYTE_WRITE_SUPPORT); + if(BlockStatus) + { + BcmRestoreBlockProtectStatus(Adapter,BlockStatus); + BlockStatus = 0; + } + } + else + { + WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal, + uiOffset ,MAX_RW_SIZE); + } + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); + bcm_kfree(pBuff); + return STATUS_FAILURE; + } + + bcm_kfree(pBuff); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); + return STATUS_SUCCESS ; +} + +INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +{ + + PUCHAR pBuff = 0 ; + UINT sig = 0; + UINT uiOffset = 0; + + Adapter->bSigCorrupted = FALSE; + + if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature"); + return SECTOR_IS_NOT_WRITABLE; + } + + pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); + if(pBuff == NULL) + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey"); + return -ENOMEM ; + } + + uiOffset = 0; + + BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE); + + sig = *((PUINT)pBuff); + sig =ntohl(sig); + + //corrupt signature + *pBuff = 0; + + if(sig == ISO_IMAGE_MAGIC_NUMBER) + { + Adapter->bSigCorrupted = TRUE; + WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal, + uiOffset ,Adapter->ulFlashWriteSize); + } + else + { + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); + bcm_kfree(pBuff); + return STATUS_FAILURE; + } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE); + + bcm_kfree(pBuff); + return STATUS_SUCCESS ; +} + +BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter) +{ + if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) + return TRUE; + else + return FALSE ; +} + diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h new file mode 100644 index 000000000000..6ec6ca85b501 --- /dev/null +++ b/drivers/staging/bcm/nvm.h @@ -0,0 +1,489 @@ +/*************************************************************************************** +// +// Copyright (c) Beceem Communications Inc. +// +// Module Name: +// NVM.h +// +// Abstract: +// This file has the prototypes,preprocessors and definitions various NVM libraries. +// +// +// Revision History: +// Who When What +// -------- -------- ---------------------------------------------- +// Name Date Created/reviewed/modified +// +// Notes: +// +****************************************************************************************/ + + +#ifndef _NVM_H_ +#define _NVM_H_ + +typedef struct _FLASH_SECTOR_INFO +{ + UINT uiSectorSig; + UINT uiSectorSize; + +}FLASH_SECTOR_INFO,*PFLASH_SECTOR_INFO; + +typedef struct _FLASH_CS_INFO +{ + B_UINT32 MagicNumber; +// let the magic number be 0xBECE-F1A5 - F1A5 for "flas-h" + + B_UINT32 FlashLayoutVersion ; + + // ISO Image/Format/BuildTool versioning + B_UINT32 ISOImageVersion; + + // SCSI/Flash BootLoader versioning + B_UINT32 SCSIFirmwareVersion; + + + B_UINT32 OffsetFromZeroForPart1ISOImage; +// typically 0 + + B_UINT32 OffsetFromZeroForScsiFirmware; +//typically at 12MB + + B_UINT32 SizeOfScsiFirmware ; +//size of the firmware - depends on binary size + + B_UINT32 OffsetFromZeroForPart2ISOImage; +// typically at first Word Aligned offset 12MB + sizeOfScsiFirmware. + + B_UINT32 OffsetFromZeroForCalibrationStart; +// typically at 15MB + + B_UINT32 OffsetFromZeroForCalibrationEnd; + +// VSA0 offsets + B_UINT32 OffsetFromZeroForVSAStart; + B_UINT32 OffsetFromZeroForVSAEnd; + +// Control Section offsets + B_UINT32 OffsetFromZeroForControlSectionStart; + B_UINT32 OffsetFromZeroForControlSectionData; + +// NO Data Activity timeout to switch from MSC to NW Mode + B_UINT32 CDLessInactivityTimeout; + +// New ISO Image Signature + B_UINT32 NewImageSignature; + +// Signature to validate the sector size. + B_UINT32 FlashSectorSizeSig; + +// Sector Size + B_UINT32 FlashSectorSize; + +// Write Size Support + B_UINT32 FlashWriteSupportSize; + +// Total Flash Size + B_UINT32 TotalFlashSize; + +// Flash Base Address for offset specified + B_UINT32 FlashBaseAddr; + +// Flash Part Max Size + B_UINT32 FlashPartMaxSize; + +// Is CDLess or Flash Bootloader + B_UINT32 IsCDLessDeviceBootSig; + +// MSC Timeout after reset to switch from MSC to NW Mode + B_UINT32 MassStorageTimeout; + + +}FLASH_CS_INFO,*PFLASH_CS_INFO; + +#define FLASH2X_TOTAL_SIZE (64*1024*1024) +#define DEFAULT_SECTOR_SIZE (64*1024) + +typedef struct _FLASH_2X_CS_INFO +{ + + // magic number as 0xBECE-F1A5 - F1A5 for "flas-h" + B_UINT32 MagicNumber; + + B_UINT32 FlashLayoutVersion ; + + // ISO Image/Format/BuildTool versioning + B_UINT32 ISOImageVersion; + + // SCSI/Flash BootLoader versioning + B_UINT32 SCSIFirmwareVersion; + + // ISO Image1 Part1/SCSI Firmware/Flash Bootloader Start offset, size + B_UINT32 OffsetFromZeroForPart1ISOImage; + B_UINT32 OffsetFromZeroForScsiFirmware; + B_UINT32 SizeOfScsiFirmware ; + + // ISO Image1 Part2 start offset + B_UINT32 OffsetFromZeroForPart2ISOImage; + + + // DSD0 offset + B_UINT32 OffsetFromZeroForDSDStart; + B_UINT32 OffsetFromZeroForDSDEnd; + + // VSA0 offset + B_UINT32 OffsetFromZeroForVSAStart; + B_UINT32 OffsetFromZeroForVSAEnd; + + // Control Section offset + B_UINT32 OffsetFromZeroForControlSectionStart; + B_UINT32 OffsetFromZeroForControlSectionData; + + // NO Data Activity timeout to switch from MSC to NW Mode + B_UINT32 CDLessInactivityTimeout; + + // New ISO Image Signature + B_UINT32 NewImageSignature; + + B_UINT32 FlashSectorSizeSig; // Sector Size Signature + B_UINT32 FlashSectorSize; // Sector Size + B_UINT32 FlashWriteSupportSize; // Write Size Support + + B_UINT32 TotalFlashSize; // Total Flash Size + + // Flash Base Address for offset specified + B_UINT32 FlashBaseAddr; + B_UINT32 FlashPartMaxSize; // Flash Part Max Size + + // Is CDLess or Flash Bootloader + B_UINT32 IsCDLessDeviceBootSig; + + // MSC Timeout after reset to switch from MSC to NW Mode + B_UINT32 MassStorageTimeout; + + /* Flash Map 2.0 Field */ + B_UINT32 OffsetISOImage1Part1Start; // ISO Image1 Part1 offset + B_UINT32 OffsetISOImage1Part1End; + B_UINT32 OffsetISOImage1Part2Start; // ISO Image1 Part2 offset + B_UINT32 OffsetISOImage1Part2End; + B_UINT32 OffsetISOImage1Part3Start; // ISO Image1 Part3 offset + B_UINT32 OffsetISOImage1Part3End; + + B_UINT32 OffsetISOImage2Part1Start; // ISO Image2 Part1 offset + B_UINT32 OffsetISOImage2Part1End; + B_UINT32 OffsetISOImage2Part2Start; // ISO Image2 Part2 offset + B_UINT32 OffsetISOImage2Part2End; + B_UINT32 OffsetISOImage2Part3Start; // ISO Image2 Part3 offset + B_UINT32 OffsetISOImage2Part3End; + + + // DSD Header offset from start of DSD + B_UINT32 OffsetFromDSDStartForDSDHeader; + B_UINT32 OffsetFromZeroForDSD1Start; // DSD 1 offset + B_UINT32 OffsetFromZeroForDSD1End; + B_UINT32 OffsetFromZeroForDSD2Start; // DSD 2 offset + B_UINT32 OffsetFromZeroForDSD2End; + + B_UINT32 OffsetFromZeroForVSA1Start; // VSA 1 offset + B_UINT32 OffsetFromZeroForVSA1End; + B_UINT32 OffsetFromZeroForVSA2Start; // VSA 2 offset + B_UINT32 OffsetFromZeroForVSA2End; + + /* +* ACCESS_BITS_PER_SECTOR 2 +* ACCESS_RW 0 +* ACCESS_RO 1 +* ACCESS_RESVD 2 +* ACCESS_RESVD 3 +* */ + B_UINT32 SectorAccessBitMap[FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)]; + +// All expansions to the control data structure should add here + +}FLASH2X_CS_INFO,*PFLASH2X_CS_INFO; + +typedef struct _VENDOR_SECTION_INFO +{ + B_UINT32 OffsetFromZeroForSectionStart; + B_UINT32 OffsetFromZeroForSectionEnd; + B_UINT32 AccessFlags; + B_UINT32 Reserved[16]; + +} VENDOR_SECTION_INFO, *PVENDOR_SECTION_INFO; + +typedef struct _FLASH2X_VENDORSPECIFIC_INFO +{ + VENDOR_SECTION_INFO VendorSection[TOTAL_SECTIONS]; + B_UINT32 Reserved[16]; + +} FLASH2X_VENDORSPECIFIC_INFO, *PFLASH2X_VENDORSPECIFIC_INFO; + +typedef struct _DSD_HEADER +{ + B_UINT32 DSDImageSize; + B_UINT32 DSDImageCRC; + B_UINT32 DSDImagePriority; + //We should not consider right now. Reading reserve is worthless. + B_UINT32 Reserved[252]; // Resvd for DSD Header + B_UINT32 DSDImageMagicNumber; + +}DSD_HEADER, *PDSD_HEADER; + +typedef struct _ISO_HEADER +{ + B_UINT32 ISOImageMagicNumber; + B_UINT32 ISOImageSize; + B_UINT32 ISOImageCRC; + B_UINT32 ISOImagePriority; + //We should not consider right now. Reading reserve is worthless. + B_UINT32 Reserved[60]; //Resvd for ISO Header extension + +}ISO_HEADER, *PISO_HEADER; + +#define EEPROM_BEGIN_CIS (0) +#define EEPROM_BEGIN_NON_CIS (0x200) +#define EEPROM_END (0x2000) + +#define INIT_PARAMS_SIGNATURE (0x95a7a597) + +#define MAX_INIT_PARAMS_LENGTH (2048) + + +#define MAC_ADDRESS_OFFSET 0x200 + + +#define INIT_PARAMS_1_SIGNATURE_ADDRESS EEPROM_BEGIN_NON_CIS +#define INIT_PARAMS_1_DATA_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+16) +#define INIT_PARAMS_1_MACADDRESS_ADDRESS (MAC_ADDRESS_OFFSET) +#define INIT_PARAMS_1_LENGTH_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+4) + +#define INIT_PARAMS_2_SIGNATURE_ADDRESS (EEPROM_BEGIN_NON_CIS+2048+16) +#define INIT_PARAMS_2_DATA_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+16) +#define INIT_PARAMS_2_MACADDRESS_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+8) +#define INIT_PARAMS_2_LENGTH_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+4) + +#define EEPROM_SPI_DEV_CONFIG_REG 0x0F003000 +#define EEPROM_SPI_Q_STATUS1_REG 0x0F003004 +#define EEPROM_SPI_Q_STATUS1_MASK_REG 0x0F00300C + +#define EEPROM_SPI_Q_STATUS_REG 0x0F003008 +#define EEPROM_CMDQ_SPI_REG 0x0F003018 +#define EEPROM_WRITE_DATAQ_REG 0x0F00301C +#define EEPROM_READ_DATAQ_REG 0x0F003020 +#define SPI_FLUSH_REG 0x0F00304C + +#define EEPROM_WRITE_ENABLE 0x06000000 +#define EEPROM_READ_STATUS_REGISTER 0x05000000 +#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 +#define EEPROM_WRITE_QUEUE_EMPTY 0x00001000 +#define EEPROM_WRITE_QUEUE_AVAIL 0x00002000 +#define EEPROM_WRITE_QUEUE_FULL 0x00004000 +#define EEPROM_16_BYTE_PAGE_READ 0xFB000000 +#define EEPROM_4_BYTE_PAGE_READ 0x3B000000 + +#define EEPROM_CMD_QUEUE_FLUSH 0x00000001 +#define EEPROM_WRITE_QUEUE_FLUSH 0x00000002 +#define EEPROM_READ_QUEUE_FLUSH 0x00000004 +#define EEPROM_ETH_QUEUE_FLUSH 0x00000008 +#define EEPROM_ALL_QUEUE_FLUSH 0x0000000f +#define EEPROM_READ_ENABLE 0x06000000 +#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 +#define EEPROM_READ_DATA_FULL 0x00000010 +#define EEPROM_READ_DATA_AVAIL 0x00000020 +#define EEPROM_READ_QUEUE_EMPTY 0x00000002 +#define EEPROM_CMD_QUEUE_EMPTY 0x00000100 +#define EEPROM_CMD_QUEUE_AVAIL 0x00000200 +#define EEPROM_CMD_QUEUE_FULL 0x00000400 + +/* Most EEPROM status register bit 0 indicates if the EEPROM is busy + * with a write if set 1. See the details of the EEPROM Status Register + * in the EEPROM data sheet. */ +#define EEPROM_STATUS_REG_WRITE_BUSY 0x00000001 + +// We will have 1 mSec for every RETRIES_PER_DELAY count and have a max attempts of MAX_EEPROM_RETRIES +// This will give us 80 mSec minimum of delay = 80mSecs +#define MAX_EEPROM_RETRIES 80 +#define RETRIES_PER_DELAY 64 + + +#define MAX_RW_SIZE 0x10 +#define MAX_READ_SIZE 0x10 +#define MAX_SECTOR_SIZE (512*1024) +#define MIN_SECTOR_SIZE (1024) +#define FLASH_SECTOR_SIZE_OFFSET 0xEFFFC +#define FLASH_SECTOR_SIZE_SIG_OFFSET 0xEFFF8 +#define FLASH_SECTOR_SIZE_SIG 0xCAFEBABE +#define FLASH_CS_INFO_START_ADDR 0xFF0000 +#define FLASH_CONTROL_STRUCT_SIGNATURE 0xBECEF1A5 +#define SCSI_FIRMWARE_MAJOR_VERSION 0x1 +#define SCSI_FIRMWARE_MINOR_VERSION 0x5 +#define BYTE_WRITE_SUPPORT 0x1 + +#define FLASH_AUTO_INIT_BASE_ADDR 0xF00000 + + + +#ifdef BCM_SHM_INTERFACE + +#define FLASH_ADDR_MASK 0x1F000000 +extern int bcmflash_raw_read(unsigned int flash_id, unsigned int offset, unsigned char *inbuf, unsigned int len); +extern int bcmflash_raw_write(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len); +extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len); + + +#endif + +#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000 +#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000 + +#define FLASH_CONTIGIOUS_START_ADDR_BCS350 0x08000000 +#define FLASH_CONTIGIOUS_END_ADDR_BCS350 0x08FFFFFF + + + +#define FLASH_SIZE_ADDR 0xFFFFEC + +#define FLASH_SPI_CMDQ_REG 0xAF003040 +#define FLASH_SPI_WRITEQ_REG 0xAF003044 +#define FLASH_SPI_READQ_REG 0xAF003048 +#define FLASH_CONFIG_REG 0xAF003050 +#define FLASH_GPIO_CONFIG_REG 0xAF000030 + +#define FLASH_CMD_WRITE_ENABLE 0x06 +#define FLASH_CMD_READ_ENABLE 0x03 +#define FLASH_CMD_RESET_WRITE_ENABLE 0x04 +#define FLASH_CMD_STATUS_REG_READ 0x05 +#define FLASH_CMD_STATUS_REG_WRITE 0x01 +#define FLASH_CMD_READ_ID 0x9F + +#define PAD_SELECT_REGISTER 0xAF000410 + +#define FLASH_PART_SST25VF080B 0xBF258E + +#define EEPROM_CAL_DATA_INTERNAL_LOC 0xbFB00008 + +#define EEPROM_CALPARAM_START 0x200 +#define EEPROM_SIZE_OFFSET 524 + +//As Read/Write time vaires from 1.5 to 3.0 ms. +//so After Ignoring the rdm/wrm time(that is dependent on many factor like interface etc.), +//here time calculated meets the worst case delay, 3.0 ms +#define MAX_FLASH_RETRIES 4 +#define FLASH_PER_RETRIES_DELAY 16 + + +#define EEPROM_MAX_CAL_AREA_SIZE 0xF0000 + + + +#define BECM ntohl(0x4245434d) + +#define FLASH_2X_MAJOR_NUMBER 0x2 +#define DSD_IMAGE_MAGIC_NUMBER 0xBECE0D5D +#define ISO_IMAGE_MAGIC_NUMBER 0xBECE0150 +#define NON_CDLESS_DEVICE_BOOT_SIG 0xBECEB007 +#define MINOR_VERSION(x) ((x >>16) & 0xFFFF) +#define MAJOR_VERSION(x) (x & 0xFFFF) +#define CORRUPTED_PATTERN 0x0 +#define UNINIT_PTR_IN_CS 0xBBBBDDDD + +#define VENDOR_PTR_IN_CS 0xAAAACCCC + + +#define FLASH2X_SECTION_PRESENT 1<<0 +#define FLASH2X_SECTION_VALID 1<<1 +#define FLASH2X_SECTION_RO 1<<2 +#define FLASH2X_SECTION_ACT 1<<3 +#define SECTOR_IS_NOT_WRITABLE STATUS_FAILURE +#define INVALID_OFFSET STATUS_FAILURE +#define INVALID_SECTION STATUS_FAILURE +#define SECTOR_1K 1024 +#define SECTOR_64K (64 *SECTOR_1K) +#define SECTOR_128K (2 * SECTOR_64K) +#define SECTOR_256k (2 * SECTOR_128K) +#define SECTOR_512K (2 * SECTOR_256k) +#define FLASH_PART_SIZE (16 * 1024 * 1024) +#define RESET_CHIP_SELECT -1 +#define CHIP_SELECT_BIT12 12 + +#define SECTOR_READWRITE_PERMISSION 0 +#define SECTOR_READONLY 1 +#define SIGNATURE_SIZE 4 +#define DEFAULT_BUFF_SIZE 0x10000 + + +#define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL)) + +#if 0 +INT BeceemEEPROMBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes); + + +INT BeceemFlashBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes); + +UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter); + +UINT BcmGetFlashSize(PMINI_ADAPTER Adapter); + +UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter); + + + +INT BeceemFlashBulkWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify); + +INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter); + +INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter); + + +INT BeceemEEPROMBulkWrite( + PMINI_ADAPTER Adapter, + PUCHAR pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify); + + +INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData); + +NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter); + +INT BeceemNVMRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes); + +INT BeceemNVMWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify); + +INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter); + +INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize); + +INT BcmInitNVM(PMINI_ADAPTER Adapter); + +VOID BcmValidateNvmType(PMINI_ADAPTER Adapter); + +VOID BcmGetFlashCSInfo(PMINI_ADAPTER Adapter); + +#endif + +#endif + diff --git a/drivers/staging/bcm/osal_misc.h b/drivers/staging/bcm/osal_misc.h new file mode 100644 index 000000000000..ff4adde17cd8 --- /dev/null +++ b/drivers/staging/bcm/osal_misc.h @@ -0,0 +1,49 @@ + /*++ + + Copyright (c) Beceem Communications Inc. + + Module Name: + OSAL_Misc.h + + Abstract: + Provides the OS Abstracted macros to access: + Linked Lists + Dispatcher Objects(Events,Semaphores,Spin Locks and the like) + Files + + + Revision History: + Who When What + -------- -------- ---------------------------------------------- + Name Date Created/reviewed/modified + Rajeev 24/1/08 Created + Notes: + + --*/ +#ifndef _OSAL_MISC_H_ +#define _OSAL_MISC_H_ +//OSAL Macros +//OSAL Primitives +typedef PUCHAR POSAL_NW_PACKET ; //Nw packets + + +#define OsalMemAlloc(n,t) kmalloc(n,GFP_KERNEL) + +#define OsalMemFree(x,n) bcm_kfree(x) + +#define OsalMemMove(dest, src, len) \ +{ \ + memcpy(dest,src, len); \ +} + +#define OsalZeroMemory(pDest, Len) \ +{ \ + memset(pDest,0,Len); \ +} + +//#define OsalMemSet(pSrc,Char,Len) memset(pSrc,Char,Len) + +bool OsalMemCompare(void *dest, void *src, UINT len); + +#endif + diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c new file mode 100644 index 000000000000..fc5d07aec3d2 --- /dev/null +++ b/drivers/staging/bcm/sort.c @@ -0,0 +1,63 @@ +#include "headers.h" + +/* + * File Name: sort.c + * + * Author: Beceem Communications Pvt. Ltd + * + * Abstract: This file contains the routines sorting the classification rules. + * + * Copyright (c) 2007 Beceem Communications Pvt. Ltd + */ + +VOID SortPackInfo(PMINI_ADAPTER Adapter) +{ + UINT nIndex1; + UINT nIndex2; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); + + for(nIndex1 = 0; nIndex1 < NO_OF_QUEUES -2 ; nIndex1++) + { + for(nIndex2 = nIndex1 + 1 ; nIndex2 < NO_OF_QUEUES -1 ; nIndex2++) + { + if(Adapter->PackInfo[nIndex1].bValid && Adapter->PackInfo[nIndex2].bValid) + { + if(Adapter->PackInfo[nIndex2].u8TrafficPriority < + Adapter->PackInfo[nIndex1].u8TrafficPriority) + { + PacketInfo stTemppackInfo = Adapter->PackInfo[nIndex2]; + Adapter->PackInfo[nIndex2] = Adapter->PackInfo[nIndex1]; + Adapter->PackInfo[nIndex1] = stTemppackInfo; + + } + } + } + } +} + +VOID SortClassifiers(PMINI_ADAPTER Adapter) +{ + UINT nIndex1; + UINT nIndex2; + + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); + + for(nIndex1 = 0; nIndex1 < MAX_CLASSIFIERS -1 ; nIndex1++) + { + for(nIndex2 = nIndex1 + 1 ; nIndex2 < MAX_CLASSIFIERS ; nIndex2++) + { + if(Adapter->astClassifierTable[nIndex1].bUsed && Adapter->astClassifierTable[nIndex2].bUsed) + { + if(Adapter->astClassifierTable[nIndex2].u8ClassifierRulePriority < + Adapter->astClassifierTable[nIndex1].u8ClassifierRulePriority) + { + S_CLASSIFIER_RULE stTempClassifierRule = Adapter->astClassifierTable[nIndex2]; + Adapter->astClassifierTable[nIndex2] = Adapter->astClassifierTable[nIndex1]; + Adapter->astClassifierTable[nIndex1] = stTempClassifierRule; + + } + } + } + } +} diff --git a/drivers/staging/bcm/target_params.h b/drivers/staging/bcm/target_params.h new file mode 100644 index 000000000000..2d8b8a367b38 --- /dev/null +++ b/drivers/staging/bcm/target_params.h @@ -0,0 +1,81 @@ +#ifndef TARGET_PARAMS_H +#define TARGET_PARAMS_H + +typedef struct _TARGET_PARAMS +{ + B_UINT32 m_u32CfgVersion; + + // Scanning Related Params + B_UINT32 m_u32CenterFrequency; + B_UINT32 m_u32BandAScan; + B_UINT32 m_u32BandBScan; + B_UINT32 m_u32BandCScan; + + + // QoS Params + B_UINT32 m_u32ErtpsOptions; + + B_UINT32 m_u32PHSEnable; + + + // HO Params + B_UINT32 m_u32HoEnable; + + B_UINT32 m_u32HoReserved1; + B_UINT32 m_u32HoReserved2; + // Power Control Params + + B_UINT32 m_u32MimoEnable; + + B_UINT32 m_u32SecurityEnable; + + B_UINT32 m_u32PowerSavingModesEnable; //bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable + /* PowerSaving Mode Options: + bit 0 = 1: CPE mode - to keep pcmcia if alive; + bit 1 = 1: CINR reporing in Idlemode Msg + bit 2 = 1: Default PSC Enable in sleepmode*/ + B_UINT32 m_u32PowerSavingModeOptions; + + B_UINT32 m_u32ArqEnable; + + // From Version #3, the HARQ section renamed as general + B_UINT32 m_u32HarqEnable; + // EEPROM Param Location + B_UINT32 m_u32EEPROMFlag; + // BINARY TYPE - 4th MSByte: Interface Type - 3rd MSByte: Vendor Type - 2nd MSByte + // Unused - LSByte + B_UINT32 m_u32Customize; + B_UINT32 m_u32ConfigBW; /* In Hz */ + B_UINT32 m_u32ShutDownInitThresholdTimer; + + B_UINT32 m_u32RadioParameter; + B_UINT32 m_u32PhyParameter1; + B_UINT32 m_u32PhyParameter2; + B_UINT32 m_u32PhyParameter3; + + B_UINT32 m_u32TestOptions; // in eval mode only; lower 16bits = basic cid for testing; then bit 16 is test cqich,bit 17 test init rang; bit 18 test periodic rang and bit 19 is test harq ack/nack + + B_UINT32 m_u32MaxMACDataperDLFrame; + B_UINT32 m_u32MaxMACDataperULFrame; + + B_UINT32 m_u32Corr2MacFlags; + + //adding driver params. + B_UINT32 HostDrvrConfig1; + B_UINT32 HostDrvrConfig2; + B_UINT32 HostDrvrConfig3; + B_UINT32 HostDrvrConfig4; + B_UINT32 HostDrvrConfig5; + B_UINT32 HostDrvrConfig6; + B_UINT32 m_u32SegmentedPUSCenable; + + // removed SHUT down related 'unused' params from here to sync 4.x and 5.x CFG files.. + + //BAMC Related Parameters + //Bit 0-15 Band AMC signaling configuration: Bit 1 = 1 – Enable Band AMC signaling. + //bit 16-31 Band AMC Data configuration: Bit 16 = 1 – Band AMC 2x3 support. + B_UINT32 m_u32BandAMCEnable; + +} stTargetParams,TARGET_PARAMS,*PTARGET_PARAMS, STARGETPARAMS, *PSTARGETPARAMS; + +#endif diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c new file mode 100644 index 000000000000..4178cd161da3 --- /dev/null +++ b/drivers/staging/bcm/vendorspecificextn.c @@ -0,0 +1,146 @@ +#include "headers.h" +//----------------------------------------------------------------------------- +// Procedure: vendorextnGetSectionInfo +// +// Description: Finds the type of NVM used. +// +// Arguments: +// Adapter - ptr to Adapter object instance +// pNVMType - ptr to NVM type. +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//----------------------------------------------------------------------------- +INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendorInfo) +{ + return STATUS_FAILURE; +} + +//----------------------------------------------------------------------------- +// Procedure: vendorextnInit +// +// Description: Initializing the vendor extension NVM interface +// +// Arguments: +// Adapter - Pointer to MINI Adapter Structure. + +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//----------------------------------------------------------------------------- +INT vendorextnInit(PMINI_ADAPTER Adapter) +{ + return STATUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Procedure: vendorextnExit +// +// Description: Free the resource associated with vendor extension NVM interface +// +// Arguments: +// Adapter - Pointer to MINI Adapter Structure. + +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//----------------------------------------------------------------------------- +INT vendorextnExit(PMINI_ADAPTER Adapter) +{ + return STATUS_SUCCESS; +} + +//------------------------------------------------------------------------ +// Procedure: vendorextnIoctl +// +// Description: execute the vendor extension specific ioctl +// +//Arguments: +// Adapter -Beceem private Adapter Structure +// cmd -vendor extension specific Ioctl commad +// arg -input parameter sent by vendor +// +// Returns: +// CONTINUE_COMMON_PATH in case it is not meant to be processed by vendor ioctls +// STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value +// +//-------------------------------------------------------------------------- +INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg) +{ + return CONTINUE_COMMON_PATH; +} + + + +//------------------------------------------------------------------ +// Procedure: vendorextnReadSection +// +// Description: Reads from a section of NVM +// +// Arguments: +// pContext - ptr to Adapter object instance +// pBuffer - Read the data from Vendor Area to this buffer +// SectionVal - Value of type of Section +// Offset - Read from the Offset of the Vendor Section. +// numOfBytes - Read numOfBytes from the Vendor section to Buffer +// +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//------------------------------------------------------------------ + +INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes) +{ + return STATUS_FAILURE; +} + + + +//------------------------------------------------------------------ +// Procedure: vendorextnWriteSection +// +// Description: Write to a Section of NVM +// +// Arguments: +// pContext - ptr to Adapter object instance +// pBuffer - Write the data provided in the buffer +// SectionVal - Value of type of Section +// Offset - Writes to the Offset of the Vendor Section. +// numOfBytes - Write num Bytes after reading from pBuffer. +// bVerify - the Buffer Written should be verified. +// +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//------------------------------------------------------------------ +INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes, BOOLEAN bVerify) +{ + return STATUS_FAILURE; +} + + + +//------------------------------------------------------------------ +// Procedure: vendorextnWriteSectionWithoutErase +// +// Description: Write to a Section of NVM without erasing the sector +// +// Arguments: +// pContext - ptr to Adapter object instance +// pBuffer - Write the data provided in the buffer +// SectionVal - Value of type of Section +// Offset - Writes to the Offset of the Vendor Section. +// numOfBytes - Write num Bytes after reading from pBuffer. +// +// Returns: +// STATUS_SUCCESS/STATUS_FAILURE +// +//------------------------------------------------------------------ +INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes) +{ + return STATUS_FAILURE; +} + diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h new file mode 100644 index 000000000000..7ff14951f0ca --- /dev/null +++ b/drivers/staging/bcm/vendorspecificextn.h @@ -0,0 +1,18 @@ + +#ifndef __VENDOR_EXTN_NVM_H__ +#define __VENDOR_EXTN_NVM_H__ + +#define CONTINUE_COMMON_PATH 0xFFFF + +INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendorInfo); +INT vendorextnExit(PMINI_ADAPTER Adapter); +INT vendorextnInit(PMINI_ADAPTER Adapter); +INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg); +INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes); +INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes, BOOLEAN bVerify); +INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, + UINT offset, UINT numOfBytes); + +#endif /* */