staging: Beeceem USB Wimax driver

The Sprint 4G network uses a Wimax dongle with Beecem
chipset. The driver is typical of out of tree drivers, but
maybe useful for people, and the hardware is readily available.

Here is a staging ready version (i.e warts and all)

0. Started with Rel_5.2.7.3P1_USB from Sprint4GDeveloperPack-1.1
1. Consolidated files in staging
2. Remove Dos cr/lf
3. Remove unnecessary ioctl from usbbcm_fops

Applied patches that were in the developer pack, surprising
there were ones for 2.6.35 already.

This is compile tested only, see TODO for what still needs
to be done.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Stephen Hemminger 2010-09-08 14:46:36 -07:00 committed by Greg Kroah-Hartman
parent 2d2f03b022
commit f8942e07a3
63 changed files with 27606 additions and 0 deletions

View File

@ -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

View File

@ -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/

View File

@ -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__

94
drivers/staging/bcm/Arp.c Normal file
View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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");

2443
drivers/staging/bcm/CmHost.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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<bufferlen;i++)
{
if(i && !(i%16) )
printk("\n");
switch(base)
{
case BCM_BASE_TYPE_DEC:
printk("%03d ", buffer[i]);
break;
case BCM_BASE_TYPE_OCT:
printk("%0x03o ", buffer[i]);
break;
case BCM_BASE_TYPE_BIN:
printk("%02x ", buffer[i]);
break;
case BCM_BASE_TYPE_HEX:
default:
printk("%02X ", buffer[i]);
break;
}
}
printk("\n");
}
return 0;
}

297
drivers/staging/bcm/Debug.h Normal file
View File

@ -0,0 +1,297 @@
/*
* Debug.h
*
* Dynamic (runtime) debug framework implementation.
* -kaiwan.
*/
#ifndef _DEBUG_H
#define _DEBUG_H
#include <linux/string.h>
#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

View File

@ -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, /**<Pointer to the Adapter structure*/
struct sk_buff *skb) /**<Pointer to the socket buffer*/
{
PPER_TARANG_DATA pTarang = NULL;
BOOLEAN HighPriorityMessage = FALSE;
struct sk_buff * newPacket = NULL;
CHAR cntrl_msg_mask_bit = 0;
BOOLEAN drop_pkt_flag = TRUE ;
USHORT usStatus = *(PUSHORT)(skb->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<<cntrl_msg_mask_bit))
drop_pkt_flag = FALSE;
if ((drop_pkt_flag == TRUE) || (pTarang->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 ;
}

View File

@ -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

View File

@ -0,0 +1,7 @@
#ifndef _HOST_MIBS_H
#define _HOST_MIBS_H
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
PVOID ioBuffer,
ULONG inputBufferLength);
#endif

View File

@ -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, /**<Pointer to the IP Hdr of the packet*/
S_CLASSIFIER_RULE *pstClassifierRule )
{
USHORT ushDestPort = 0;
USHORT ushSrcPort = 0;
UCHAR ucNextProtocolAboveIP =0;
IPV6Header *pstIpv6Header = NULL;
BOOLEAN bClassificationSucceed = FALSE;
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\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;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
{
aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
}
for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
{
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Recieved Packet : \n ");
DumpIpv6Address(aulSrcIP);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n");
DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.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;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
{
if((pstClassifierRule->stSrcIpAddress.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;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
{
aulDestIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
}
for(uiLoopIndex=0;uiLoopIndex<uiCountIPDestinationAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
{
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Recieved Packet : \n ");
DumpIpv6Address(aulDestIP);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n");
DumpIpv6Address(&pstClassifierRule->stDestIpAddress.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;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
{
if((pstClassifierRule->stDestIpAddress.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;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
{
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]);
}
}
VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
{
UCHAR ucVersion;
UCHAR ucPrio ;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---");
ucVersion = pstIpv6Header->ucVersionPrio & 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---");
}

View File

@ -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, /**<Pointer to the IP Hdr of the packet*/
S_CLASSIFIER_RULE *pstClassifierRule );
VOID DumpIpv6Address(ULONG *puIpv6Address);
VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
extern BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
#endif

View File

@ -0,0 +1,97 @@
#ifndef _INTERFACE_ADAPTER_H
#define _INTERFACE_ADAPTER_H
typedef struct _BULK_ENDP_IN
{
PCHAR bulk_in_buffer;
size_t bulk_in_size;
UCHAR bulk_in_endpointAddr;
UINT bulk_in_pipe;
}BULK_ENDP_IN, *PBULK_ENDP_IN;
typedef struct _BULK_ENDP_OUT
{
UCHAR bulk_out_buffer;
size_t bulk_out_size;
UCHAR bulk_out_endpointAddr;
UINT bulk_out_pipe;
//this is used when int out endpoint is used as bulk out end point
UCHAR int_out_interval;
}BULK_ENDP_OUT, *PBULK_ENDP_OUT;
typedef struct _INTR_ENDP_IN
{
PCHAR int_in_buffer;
size_t int_in_size;
UCHAR int_in_endpointAddr;
UCHAR int_in_interval;
UINT int_in_pipe;
}INTR_ENDP_IN, *PINTR_ENDP_IN;
typedef struct _INTR_ENDP_OUT
{
PCHAR int_out_buffer;
size_t int_out_size;
UCHAR int_out_endpointAddr;
UCHAR int_out_interval;
UINT int_out_pipe;
}INTR_ENDP_OUT, *PINTR_ENDP_OUT;
typedef struct _USB_TCB
{
struct urb *urb;
PVOID psIntfAdapter;
BOOLEAN bUsed;
}USB_TCB, *PUSB_TCB;
typedef struct _USB_RCB
{
struct urb *urb;
PVOID psIntfAdapter;
BOOLEAN bUsed;
}USB_RCB, *PUSB_RCB;
/*
//This is the interface specific Sub-Adapter
//Structure.
*/
typedef struct _S_INTERFACE_ADAPTER
{
struct usb_device * udev;
struct usb_interface * interface;
/* Bulk endpoint in info */
BULK_ENDP_IN sBulkIn;
/* Bulk endpoint out info */
BULK_ENDP_OUT sBulkOut;
/* Interrupt endpoint in info */
INTR_ENDP_IN sIntrIn;
/* Interrupt endpoint out info */
INTR_ENDP_OUT sIntrOut;
ULONG ulInterruptData[2];
struct urb *psInterruptUrb;
USB_TCB asUsbTcb[MAXIMUM_USB_TCB];
USB_RCB asUsbRcb[MAXIMUM_USB_RCB];
atomic_t uNumTcbUsed;
atomic_t uCurrTcb;
atomic_t uNumRcbUsed;
atomic_t uCurrRcb;
PMINI_ADAPTER psAdapter;
BOOLEAN bFlashBoot;
BOOLEAN bHighSpeedDevice ;
BOOLEAN bSuspended;
BOOLEAN bPreparingForBusSuspend;
struct work_struct usbSuspendWork;
}S_INTERFACE_ADAPTER,*PS_INTERFACE_ADAPTER;
#endif

View File

@ -0,0 +1,509 @@
#include "headers.h"
#ifndef BCM_SHM_INTERFACE
int InterfaceFileDownload( PVOID arg,
struct file *flp,
unsigned int on_chip_loc)
{
char *buff=NULL;
// unsigned int reg=0;
mm_segment_t oldfs={0};
int errno=0, len=0 /*,is_config_file = 0*/;
loff_t pos=0;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
//PMINI_ADAPTER Adapter = psIntfAdapter->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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
#ifndef _INTERFACE_RX_H
#define _INTERFACE_RX_H
BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter);
#endif

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,10 @@
#ifndef _MAIN_
#define _MAIN_
#if 0
typedef struct _MINI_ADAPTER
{
S_INTERFACE_ADAPTER stInterfaceAdapter;
}MINI_ADAPTER,*PMINI_ADAPTER;
#endif
#endif

360
drivers/staging/bcm/Ioctl.h Normal file
View File

@ -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

View File

@ -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.

View File

@ -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,/**<Logical Adapter*/
PacketInfo *psSF, /**<Queue identifier*/
struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
{
INT Status=STATUS_FAILURE;
UINT uiIndex =0,PktLen = 0;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>");
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, "<======");
}

View File

@ -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__

View File

@ -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

2239
drivers/staging/bcm/Misc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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));
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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__

View File

@ -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, /**<Pointer to the Adapter structure*/
struct sk_buff *skb); /**<Pointer to the socket buffer*/
int control_packet_handler (PMINI_ADAPTER Adapter);
VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
VOID flush_all_queues(PMINI_ADAPTER Adapter);
int register_control_device_interface(PMINI_ADAPTER ps_adapter);
void unregister_control_device_interface(PMINI_ADAPTER Adapter);
INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
PVOID ioBuffer/**<Control Packet Buffer*/
);
VOID SortPackInfo(PMINI_ADAPTER Adapter);
VOID SortClassifiers(PMINI_ADAPTER Adapter);
VOID flush_all_queues(PMINI_ADAPTER Adapter);
USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
S_CLASSIFIER_RULE *pstClassifierRule );
VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
INT iIndex/**<Queue Index*/
);
VOID PruneQueueAllSF(PMINI_ADAPTER Adapter);
INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
);
VOID
reply_to_arp_request(struct sk_buff *skb /**<sk_buff of ARP request*/
);
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
struct sk_buff *Packet, /**<data buffer*/
USHORT Vcid) ;
VOID LinkMessage(PMINI_ADAPTER Adapter);
VOID transmit_packets(PMINI_ADAPTER Adapter);
INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
char *pControlPacket/**<Control Packet*/
);
INT bcm_transmit(struct sk_buff *skb, /**< skb */
struct net_device *dev /**< net device pointer */
);
int register_networkdev(PMINI_ADAPTER Adapter);
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
VOID AdapterFree(PMINI_ADAPTER Adapter);
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
int create_worker_threads(PMINI_ADAPTER psAdapter);
int tx_pkt_handler(PMINI_ADAPTER Adapter);
int reset_card_proc(PMINI_ADAPTER Adapter );
int run_card_proc(PMINI_ADAPTER Adapter );
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter);
int bcm_parse_target_params(PMINI_ADAPTER Adapter);
INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter);
int register_control_device_interface(PMINI_ADAPTER ps_adapter);
void DumpPackInfo(PMINI_ADAPTER Adapter);
int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
int wrmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId,
PUCHAR user_buffer);
void SendLinkDown(PMINI_ADAPTER Adapter);
void SendIdleModeResponse(PMINI_ADAPTER Adapter);
void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
int ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer,
ULONG inputBufferLength);
int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang);
void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
void doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo);
void bcm_unregister_networkdev(PMINI_ADAPTER Adapter);
int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid);
void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);
VOID ResetCounters(PMINI_ADAPTER Adapter);
int InitLedSettings(PMINI_ADAPTER Adapter);
S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP);
void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo);
void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp);
void update_per_cid_rx (PMINI_ADAPTER Adapter);
void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter);
void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
void beceem_protocol_reset (PMINI_ADAPTER Adapter);
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
INT flushAllAppQ(VOID);
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);
INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData);
UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
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 ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
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 BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
INT BcmInitNVM(PMINI_ADAPTER Adapter);
INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter);
INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd);
INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage);
INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
INT BcmFlash2xBulkWrite(
PMINI_ADAPTER Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlashSectionVal,
UINT uiOffset,
UINT uiNumBytes,
UINT bVerify);
INT BcmFlash2xBulkRead(
PMINI_ADAPTER Adapter,
PUINT pBuffer,
FLASH2X_SECTION_VAL eFlashSectionVal,
UINT uiOffsetWithinSectionVal,
UINT uiNumBytes);
INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal);
INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter);
INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter);
INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut);
INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
INT IsFlash2x(PMINI_ADAPTER Adapter);
INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
INT BcmCopySection(PMINI_ADAPTER Adapter,
FLASH2X_SECTION_VAL SrcSection,
FLASH2X_SECTION_VAL DstSection,
UINT offset,
UINT numOfBytes);
INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset);
INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
PUINT pBuff,
FLASH2X_SECTION_VAL eFlash2xSectionVal,
UINT uiOffset,
UINT uiNumBytes
);
//UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType);
BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter);
VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer);
int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
unsigned long u32StartingAddress);
VOID putUsbSuspend(struct work_struct *work);
BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios);
#ifdef BCM_SHM_INTERFACE
INT beceem_virtual_device_init(void);
VOID virtual_mail_box_interrupt(void);
INT beceem_virtual_device_exit(void);
#endif
#endif

893
drivers/staging/bcm/Qos.c Normal file
View File

@ -0,0 +1,893 @@
/**
@file Qos.C
This file contains the routines related to Quality of Service.
*/
#include "headers.h"
BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP);
BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService);
BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort);
BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP);
USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
/*******************************************************************
* Function - MatchSrcIpAddress()
*
* Description - Checks whether the Source IP address from the packet
* matches with that of Queue.
*
* Parameters - pstClassifierRule: Pointer to the packet info structure.
* - ulSrcIP : Source IP address from the packet.
*
* Returns - TRUE(If address matches) else FAIL .
*********************************************************************/
BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP)
{
UCHAR ucLoopIndex=0;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
ulSrcIP=ntohl(ulSrcIP);
if(0 == pstClassifierRule->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;ucLoopIndex<pstClassifierRule->ucProtocolLength;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;ucLoopIndex<pstClassifierRule->ucSrcPortRangeLength;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;ucLoopIndex<pstClassifierRule->ucDestPortRangeLength;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, /**<Pointer to the IP Hdr of the packet*/
S_CLASSIFIER_RULE *pstClassifierRule )
{
//IPHeaderFormat *pIpHeader=NULL;
xporthdr *xprt_hdr=NULL;
BOOLEAN bClassificationSucceed=FALSE;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>");
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, /**<Pointer to the driver control structure */
struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
)
{
USHORT usIndex=-1;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "=====>");
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,/**<Pointer to the driver control structure*/
INT iIndex/**<Queue Index*/
)
{
struct sk_buff* PacketToDrop=NULL;
struct net_device_stats* netstats=NULL;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> 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; iQIndex<HiPriority; iQIndex++)
{
spin_lock_bh(&Adapter->PackInfo[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;i<MAC_ADDRESS_SIZE;i++)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSSrcMAC[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;i<MAC_ADDRESS_SIZE;i++)
{
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSDestMAC[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<<PKT_CLASSIFICATION_USER_PRIORITY_VALID))
{
if(pstEthCsPktInfo->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<<PKT_CLASSIFICATION_VLANID_VALID))
{
if(pstEthCsPktInfo->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);
}

View File

@ -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__

15
drivers/staging/bcm/TODO Normal file
View File

@ -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?

View File

@ -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, /**<Logical Adapter*/
char *pControlPacket/**<Control Packet*/
)
{
PLEADER PLeader = NULL;
struct timeval tv;
memset(&tv, 0, sizeof(tv));
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
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, /**<Logical Adapter*/
struct sk_buff *Packet, /**<data buffer*/
USHORT Vcid) /**<VCID for this packet*/
{
int status=0;
int dontfree = 0;
BOOLEAN bHeaderSupressionEnabled = FALSE;
B_UINT16 uiClassifierRuleID;
int QueueIndex = NO_OF_QUEUES + 1;
if(!Adapter || !Packet)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
return -EINVAL;
}
if(Packet->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

View File

@ -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__

View File

@ -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

View File

@ -0,0 +1,677 @@
#ifndef CNTRL_SIGNALING_INTERFACE_
#define CNTRL_SIGNALING_INTERFACE_
#ifdef BECEEM_TARGET
#include <mac_common.h>
#include <msg_Dsa.h>
#include <msg_Dsc.h>
#include <msg_Dsd.h>
#include <sch_definitions.h>
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

View File

@ -0,0 +1,109 @@
/*******************************************************************
* Headers.h
*******************************************************************/
#ifndef __HEADERS_H__
#define __HEADERS_H__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/string.h>
#include <linux/etherdevice.h>
#include <net/ip.h>
#include <linux/wait.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <asm/uaccess.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#include <linux/kthread.h>
#endif
#include <linux/tcp.h>
#include <linux/udp.h>
#ifndef BCM_SHM_INTERFACE
#include <linux/usb.h>
#endif
#ifdef BECEEM_TARGET
#include <mac_common.h>
#include <msg_Dsa.h>
#include <msg_Dsc.h>
#include <msg_Dsd.h>
#include <sch_definitions.h>
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 <linux/cpe_config.h>
#ifdef GDMA_INTERFACE
#include "GdmaInterface.h"
#include "symphony.h"
#else
#include "virtual_interface.h"
#endif
#endif
#endif

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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

5614
drivers/staging/bcm/nvm.c Normal file

File diff suppressed because it is too large Load Diff

489
drivers/staging/bcm/nvm.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 /* */