#include "headers.h"

static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path,
                        unsigned int loc);
static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
static int bcm_parse_target_params(PMINI_ADAPTER Adapter);
static void beceem_protocol_reset (PMINI_ADAPTER Adapter);

static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter)
{

	UINT    uiLoopIndex;

    for(uiLoopIndex=0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++)
    {
    	Adapter->PackInfo[uiLoopIndex].uiThreshold=TX_PACKET_THRESHOLD;
        Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate=MAX_ALLOWED_RATE;
        Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize=20*1024*1024;
    }

    Adapter->BEBucketSize=BE_BUCKET_SIZE;
    Adapter->rtPSBucketSize=rtPS_BUCKET_SIZE;
    Adapter->LinkStatus=SYNC_UP_REQUEST;
    Adapter->TransferMode=IP_PACKET_ONLY_MODE;
    Adapter->usBestEffortQueueIndex=-1;
    return;
}


INT
InitAdapter(PMINI_ADAPTER psAdapter)
{
    int i = 0;
	INT Status = STATUS_SUCCESS ;
	BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT,  DBG_LVL_ALL,  "Initialising Adapter = %p", psAdapter);

	if(psAdapter == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT,  DBG_LVL_ALL, "Adapter is NULL");
		return -EINVAL;
	}

	sema_init(&psAdapter->NVMRdmWrmLock,1);
//	psAdapter->ulFlashCalStart = FLASH_AUTO_INIT_BASE_ADDR;

	sema_init(&psAdapter->rdmwrmsync, 1);
	spin_lock_init(&psAdapter->control_queue_lock);
	spin_lock_init(&psAdapter->txtransmitlock);
    sema_init(&psAdapter->RxAppControlQueuelock, 1);
//    sema_init(&psAdapter->data_packet_queue_lock, 1);
    sema_init(&psAdapter->fw_download_sema, 1);
  	sema_init(&psAdapter->LowPowerModeSync,1);

  // spin_lock_init(&psAdapter->sleeper_lock);

    for(i=0;i<NO_OF_QUEUES; i++)
        spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock);
    i=0;

    init_waitqueue_head(&psAdapter->process_rx_cntrlpkt);
    init_waitqueue_head(&psAdapter->tx_packet_wait_queue);
    init_waitqueue_head(&psAdapter->process_read_wait_queue);
    init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue);
    init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue);
	psAdapter->waiting_to_fw_download_done = TRUE;
    //init_waitqueue_head(&psAdapter->device_wake_queue);
    psAdapter->fw_download_done=FALSE;


	default_wimax_protocol_initialize(psAdapter);
	for (i=0;i<MAX_CNTRL_PKTS;i++)
	{
		psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL);
		if(!psAdapter->txctlpacket[i])
		{
			BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
			return -ENOMEM;
		}
	}
	if(AllocAdapterDsxBuffer(psAdapter))
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers");
		return -EINVAL;
	}

	//Initialize PHS interface
	if(phs_init(&psAdapter->stBCMPhsContext,psAdapter)!=0)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __FUNCTION__, __LINE__);
		return -ENOMEM;
	}

	Status = BcmAllocFlashCSStructure(psAdapter);
	if(Status)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Memory Allocation for Flash structure failed");
		return Status ;
	}

	Status = vendorextnInit(psAdapter);

	if(STATUS_SUCCESS != Status)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Vendor Init Failed");
		return Status ;
	}

	BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,  "Adapter initialised");


	return STATUS_SUCCESS;
}

VOID AdapterFree(PMINI_ADAPTER Adapter)
{
	int count;

	beceem_protocol_reset(Adapter);

	vendorextnExit(Adapter);

	if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
	  	kthread_stop (Adapter->control_packet_handler);

	if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
		kthread_stop (Adapter->transmit_packet_thread);

	wake_up(&Adapter->process_read_wait_queue);

	if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
		kthread_stop (Adapter->LEDInfo.led_cntrl_threadid);

	unregister_networkdev(Adapter);

	/* FIXME: use proper wait_event and refcounting */
	while(atomic_read(&Adapter->ApplicationRunning))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning));
		msleep(100);
	}
	unregister_control_device_interface(Adapter);

	kfree(Adapter->pstargetparams);

	for (count =0;count < MAX_CNTRL_PKTS;count++)
		kfree(Adapter->txctlpacket[count]);

	FreeAdapterDsxBuffer(Adapter);

	kfree(Adapter->pvInterfaceAdapter);

	//Free the PHS Interface
	PhsCleanup(&Adapter->stBCMPhsContext);

	BcmDeAllocFlashCSStructure(Adapter);

	free_netdev(Adapter->dev);
}

static int create_worker_threads(PMINI_ADAPTER psAdapter)
{
	// Rx Control Packets Processing
	psAdapter->control_packet_handler = kthread_run((int (*)(void *))
							control_packet_handler, psAdapter, "%s-rx", DRV_NAME);
	if(IS_ERR(psAdapter->control_packet_handler))
	{
		pr_notice(DRV_NAME ": could not create control thread\n");
		return PTR_ERR(psAdapter->control_packet_handler);
	}

	// Tx Thread
	psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
							tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME);
	if(IS_ERR (psAdapter->transmit_packet_thread))
	{
		pr_notice(DRV_NAME ": could not creat transmit thread\n");
		kthread_stop(psAdapter->control_packet_handler);
		return PTR_ERR(psAdapter->transmit_packet_thread);
	}
	return 0;
}

static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path)
{
    struct file             *flp=NULL;
    mm_segment_t        oldfs;
    oldfs=get_fs();
	set_fs(get_ds());
    flp=filp_open(path, O_RDONLY, S_IRWXU);
    set_fs(oldfs);
    if(IS_ERR(flp))
    {
	    pr_err(DRV_NAME "Unable To Open File %s, err %ld",
		   path, PTR_ERR(flp));
	    flp = NULL;
    }

    if(Adapter->device_removed)
	    flp = NULL;

    return flp;
}


static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
                        const char *path,     /**< path to image file */
                        unsigned int loc    /**< Download Address on the chip*/
                        )
{
    int             errorno=0;
    struct file     *flp=NULL;
    mm_segment_t    oldfs;
    struct timeval tv={0};

    flp=open_firmware_file(Adapter, path);
    if(!flp)
    {
        errorno = -ENOENT;
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path);
        goto exit_download;
    }
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path,(unsigned long)flp->f_dentry->d_inode->i_size, loc);
    do_gettimeofday(&tv);

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) +
                            (tv.tv_usec/1000)));
    if(Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc))
    {
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error\
		 %x!!!", -EIO);
        errorno=-EIO;
        goto exit_download;
    }
    oldfs=get_fs();set_fs(get_ds());
    vfs_llseek(flp, 0, 0);
    set_fs(oldfs);
    if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter,
										flp, loc))
    {
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!");
        errorno=-EIO;
        goto exit_download;
    }

exit_download:
    oldfs=get_fs();set_fs(get_ds());
	if(flp && !(IS_ERR(flp)))
    	filp_close(flp, current->files);
    set_fs(oldfs);

    return errorno;
}

/**
@ingroup ctrl_pkt_functions
This function copies the contents of given buffer
to the control packet and queues it for transmission.
@note Do not acquire the spinock, as it it already acquired.
@return  SUCCESS/FAILURE.
*/
INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
									  PVOID ioBuffer/**<Control Packet Buffer*/
									  )
{
	PLEADER				pLeader=NULL;
	INT					Status=0;
	unsigned char		*ctrl_buff=NULL;
	UINT				pktlen=0;
	PLINK_REQUEST		pLinkReq 	= NULL;
	PUCHAR				pucAddIndication = NULL;

	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>");
	if(!ioBuffer)
	{
		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Got Null Buffer\n");
		return -EINVAL;
	}

	pLinkReq = (PLINK_REQUEST)ioBuffer;
	pLeader=(PLEADER)ioBuffer; //ioBuffer Contains sw_Status and Payload

	if(Adapter->bShutStatus == TRUE &&
		pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD &&
		pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)
	{
		//Got sync down in SHUTDOWN..we could not process this.
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n");
		return STATUS_FAILURE;
	}

	if((pLeader->Status == LINK_UP_CONTROL_REQ) &&
		((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD &&
		 (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) ||//Sync Up Command
		 pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) //Net Entry Command
	{
		if(Adapter->LinkStatus > PHY_SYNC_ACHIVED)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"LinkStatus is Greater than PHY_SYN_ACHIEVED");
			return STATUS_FAILURE;
		}
		if(TRUE == Adapter->bShutStatus)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n");
			if(Adapter->bTriedToWakeUpFromlowPowerMode == FALSE)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Waking up for the First Time..\n");
				Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; // change it to 1 for current support.
				Adapter->bWakeUpDevice = TRUE;
				wake_up(&Adapter->process_rx_cntrlpkt);

				Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
					!Adapter->bShutStatus, (5 * HZ));

				if(Status == -ERESTARTSYS)
					return Status;

				if(Adapter->bShutStatus)
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n");
					return STATUS_FAILURE;
				}
			}
			else
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Wakeup has been tried already...\n");
			}
		}

	}
	if(TRUE == Adapter->IdleMode)
	{
		//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence \n");
		if(pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 ||
			pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ )

		{
			if((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0]==LINK_DOWN_REQ_PAYLOAD))
			{
				if((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE))
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Link Down Sent in Idle Mode\n");
					Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN;//LINK DOWN sent in Idle Mode
				}
				else
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n");
					Adapter->usIdleModePattern = ABORT_IDLE_REG;
				}
			}
			else
			{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n");
					Adapter->usIdleModePattern = ABORT_IDLE_MODE;
			}

			/*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
			  the wake up from idlemode is from host*/
			//Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE;
			Adapter->bWakeUpDevice = TRUE;
			wake_up(&Adapter->process_rx_cntrlpkt);



			if(LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0])
			{
				// We should not send DREG message down while in idlemode.
				return STATUS_SUCCESS;
			}

			Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
				!Adapter->IdleMode, (5 * HZ));

			if(Status == -ERESTARTSYS)
				return Status;

			if(Adapter->IdleMode)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n");
				return STATUS_FAILURE;
			}
		}
		else
			return STATUS_SUCCESS;
	}
	//The Driver has to send control messages with a particular VCID
	pLeader->Vcid = VCID_CONTROL_PACKET;//VCID for control packet.

	/* Allocate skb for Control Packet */
	pktlen = pLeader->PLength;
	ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS];

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x",
								atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen);
	if(ctrl_buff)
	{
		if(pLeader)
		{
			if((pLeader->Status == 0x80) ||
				(pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ))
			{
				/*
				//Restructure the DSX message to handle Multiple classifier Support
				// Write the Service Flow param Structures directly to the target
				//and embed the pointers in the DSX messages sent to target.
				*/
				//Lets store the current length of the control packet we are transmitting
				pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
				pktlen = pLeader->PLength;
				Status = StoreCmControlResponseMessage(Adapter,pucAddIndication, &pktlen);
				if(Status != 1)
				{
					ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE);
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly ");
					return STATUS_FAILURE;
				}
				/*
				//update the leader to use the new length
				//The length of the control packet is length of message being sent + Leader length
				*/
				pLeader->PLength = pktlen;
			}
		}
		memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
		*(PLEADER)ctrl_buff=*pLeader;
		memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");

		/*Update the statistics counters */
		spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
		Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost+=pLeader->PLength;
		Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
		atomic_inc(&Adapter->TotalPacketCount);
		spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);

		Adapter->PackInfo[HiPriority].bValid = TRUE;

		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
			Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
			Adapter->PackInfo[HiPriority].bValid);
		Status=STATUS_SUCCESS;
		/*Queue the packet for transmission */
		atomic_inc(&Adapter->index_wr_txcntrlpkt);
		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
		atomic_set(&Adapter->TxPktAvail, 1);
		wake_up(&Adapter->tx_packet_wait_queue);
	}
	else
	{
		Status=-ENOMEM;
		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
    }
	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<====");
	return Status;
}

#if 0
/*****************************************************************
* Function    - SendStatisticsPointerRequest()
*
* Description - This function builds and forwards the Statistics
*				Pointer Request control Packet.
*
* Parameters  - Adapter					: Pointer to Adapter structure.
* 			  - pstStatisticsPtrRequest : Pointer to link request.
*
* Returns     - None.
*****************************************************************/
static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter,
								PLINK_REQUEST	pstStatisticsPtrRequest)
{
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>");
	pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS;
	pstStatisticsPtrRequest->Leader.PLength = sizeof(ULONG);//minimum 4 bytes
	pstStatisticsPtrRequest->szData[0] = STATISTICS_POINTER_REQ;

	CopyBufferToControlPacket(Adapter,pstStatisticsPtrRequest);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "<=====");
	return;
}
#endif


/******************************************************************
* Function    - LinkMessage()
*
* Description - This function builds the Sync-up and Link-up request
*				packet messages depending on the device Link status.
*
* Parameters  - Adapter:	Pointer to the Adapter structure.
*
* Returns     - None.
*******************************************************************/
VOID LinkMessage(PMINI_ADAPTER Adapter)
{
	PLINK_REQUEST	pstLinkRequest=NULL;
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
	if(Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup)
	{
		pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC);
		if(!pstLinkRequest)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
			return;
		}
		//sync up request...
		Adapter->LinkStatus = WAIT_FOR_SYNC;// current link status
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp...");
		pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD;
		pstLinkRequest->szData[1]=LINK_SYNC_UP_SUBTYPE;
		pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ;
		pstLinkRequest->Leader.PLength=sizeof(ULONG);
		Adapter->bSyncUpRequestSent = TRUE;
	}
	else if(Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp)
	{
		pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC);
		if(!pstLinkRequest)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
			return;
		}
		//LINK_UP_REQUEST
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp...");
		pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD;
		pstLinkRequest->szData[1]=LINK_NET_ENTRY;
		pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ;
		pstLinkRequest->Leader.PLength=sizeof(ULONG);
	}
	if(pstLinkRequest)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
		CopyBufferToControlPacket(Adapter, pstLinkRequest);
		kfree(pstLinkRequest);
	}
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
	return;
}


/**********************************************************************
* Function    - StatisticsResponse()
*
* Description - This function handles the Statistics response packet.
*
* Parameters  - Adapter	: Pointer to the Adapter structure.
* 			  - pvBuffer: Starting address of Statistic response data.
*
* Returns     - None.
************************************************************************/
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
{
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
	Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__);
	return;
}


/**********************************************************************
* Function    - LinkControlResponseMessage()
*
* Description - This function handles the Link response packets.
*
* Parameters  - Adapter	 : Pointer to the Adapter structure.
* 			  - pucBuffer: Starting address of Link response data.
*
* Returns     - None.
***********************************************************************/
VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
{
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>");

	if(*pucBuffer==LINK_UP_ACK)
	{
		switch(*(pucBuffer+1))
		{
			case PHY_SYNC_ACHIVED: //SYNCed UP
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED");

				if(Adapter->LinkStatus == LINKUP_DONE)
			   	{
					beceem_protocol_reset(Adapter);
				}

				Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ;
				Adapter->LinkStatus=PHY_SYNC_ACHIVED;

				if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
				{
					Adapter->DriverState = NO_NETWORK_ENTRY;
					wake_up(&Adapter->LEDInfo.notify_led_event);
				}

				LinkMessage(Adapter);
				break;

			case LINKUP_DONE:
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE");
				Adapter->LinkStatus=LINKUP_DONE;
				Adapter->bPHSEnabled = *(pucBuffer+3);
               	Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK;
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x \n",Adapter->bPHSEnabled);
				if((FALSE == Adapter->bShutStatus)&&
					(FALSE == Adapter->IdleMode))
				{
					if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
					{
						Adapter->DriverState = NORMAL_OPERATION;
						wake_up(&Adapter->LEDInfo.notify_led_event);
					}
				}
				LinkMessage(Adapter);
				break;
			case WAIT_FOR_SYNC:

				/*
				 * Driver to ignore the DREG_RECEIVED
				 * WiMAX Application should handle this Message
				 */
				//Adapter->liTimeSinceLastNetEntry = 0;
				Adapter->LinkUpStatus = 0;
				Adapter->LinkStatus = 0;
				Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ;
				Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
				Adapter->IdleMode = FALSE;
				beceem_protocol_reset(Adapter);

				break;
			case LINK_SHUTDOWN_REQ_FROM_FIRMWARE:
			case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW:
			{
				HandleShutDownModeRequest(Adapter, pucBuffer);
			}
				break;
			default:
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x",*(pucBuffer+1));
				break;
		}
	}
	else if(SET_MAC_ADDRESS_RESPONSE==*pucBuffer)
	{
		PUCHAR puMacAddr = (pucBuffer + 1);
		Adapter->LinkStatus=SYNC_UP_REQUEST;
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP");
		LinkMessage(Adapter);
		memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
	}
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====",__FUNCTION__);
	return;
}

void SendIdleModeResponse(PMINI_ADAPTER Adapter)
{
	INT status = 0, NVMAccess = 0,lowPwrAbortMsg = 0;
	struct timeval tv;
	CONTROL_MESSAGE		stIdleResponse = {{0}};
	memset(&tv, 0, sizeof(tv));
	stIdleResponse.Leader.Status  = IDLE_MESSAGE;
	stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH;
	stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD;
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL," ============>");

	/*********************************
	**down_trylock -
	** if [ semaphore is available ]
	**		 acquire semaphone and return value 0 ;
	**   else
	**		 return non-zero value ;
	**
	***********************************/

	NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);

	lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync);


	if((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) &&
		  (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)  )
	{
		if(!NVMAccess)
			up(&Adapter->NVMRdmWrmLock);

		if(!lowPwrAbortMsg)
			up(&Adapter->LowPowerModeSync);

		stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on.
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!");
		Adapter->bPreparingForLowPowerMode = FALSE;
	}
	else
	{
		stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; //2;//Idle ACK
		Adapter->StatisticsPointer = 0;

		/* Wait for the LED to TURN OFF before sending ACK response */
		if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
		{
			INT iRetVal = 0;

			/* Wake the LED Thread with IDLEMODE_ENTER State */
			Adapter->DriverState = LOWPOWER_MODE_ENTER;
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);
			wake_up(&Adapter->LEDInfo.notify_led_event);

			/* Wait for 1 SEC for LED to OFF */
			iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, \
				Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));


			/* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
			if(iRetVal <= 0)
			{
				stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on.
				Adapter->DriverState = NORMAL_OPERATION;
				wake_up(&Adapter->LEDInfo.notify_led_event);
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!");
			}
		}
		if(stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"ACKING IDLE MODE !!!!!!!!!");
			down(&Adapter->rdmwrmsync);
			Adapter->bPreparingForLowPowerMode = TRUE;
			up(&Adapter->rdmwrmsync);
			//Killing all URBS.
			if(Adapter->bDoSuspend == TRUE)
				Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));

		}
		else
		{
			Adapter->bPreparingForLowPowerMode = FALSE;
		}

		if(!NVMAccess)
			up(&Adapter->NVMRdmWrmLock);

		if(!lowPwrAbortMsg)
			up(&Adapter->LowPowerModeSync);

	}
	status = CopyBufferToControlPacket(Adapter,&stIdleResponse);
	if((status != STATUS_SUCCESS))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n");
		Adapter->bPreparingForLowPowerMode = FALSE;
		StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
	}
	do_gettimeofday(&tv);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);

}

/******************************************************************
* Function    - DumpPackInfo()
*
* Description - This function dumps the all Queue(PackInfo[]) details.
*
* Parameters  - Adapter: Pointer to the Adapter structure.
*
* Returns     - None.
*******************************************************************/
VOID DumpPackInfo(PMINI_ADAPTER Adapter)
{

    UINT uiLoopIndex = 0;
	UINT uiIndex = 0;
	UINT uiClsfrIndex = 0;
	S_CLASSIFIER_RULE *pstClassifierEntry = NULL;

	for(uiLoopIndex=0;uiLoopIndex<NO_OF_QUEUES;uiLoopIndex++)
	{
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"*********** Showing Details Of Queue %d***** ******",uiLoopIndex);
		if(FALSE == Adapter->PackInfo[uiLoopIndex].bValid)
		{
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid is FALSE for %X index\n",uiLoopIndex);
			continue;
		}

		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"	Dumping	SF Rule Entry For SFID %lX \n",Adapter->PackInfo[uiLoopIndex].ulSFID);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"	ucDirection %X \n",Adapter->PackInfo[uiLoopIndex].ucDirection);
		if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
		{
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv6 Service Flow \n");
		}
		else
		{
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv4 Service Flow \n");
		}
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"	SF Traffic Priority %X \n",Adapter->PackInfo[uiLoopIndex].u8TrafficPriority);

		for(uiClsfrIndex=0;uiClsfrIndex<MAX_CLASSIFIERS;uiClsfrIndex++)
		{
			pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex];
			if(!pstClassifierEntry->bUsed)
				continue;

			if(pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID)
				continue;

			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n",uiClsfrIndex,pstClassifierEntry->uiClassifierRuleIndex);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n",uiClsfrIndex,pstClassifierEntry->usVCID_Value);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n",uiClsfrIndex,pstClassifierEntry->bProtocolValid);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping	Classifier Rule Entry For Index: %X bTOSValid : %X\n",uiClsfrIndex,pstClassifierEntry->bTOSValid);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping	Classifier Rule Entry For Index: %X bDestIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bDestIpValid);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping	Classifier Rule Entry For Index: %X bSrcIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bSrcIpValid);


			for(uiIndex=0;uiIndex<MAX_PORT_RANGE;uiIndex++)
			{
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeLo:%X\n",pstClassifierEntry->usSrcPortRangeLo[uiIndex]);
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeHi:%X\n",pstClassifierEntry->usSrcPortRangeHi[uiIndex]);
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeLo:%X\n",pstClassifierEntry->usDestPortRangeLo[uiIndex]);
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeHi:%X\n",pstClassifierEntry->usDestPortRangeHi[uiIndex]);
			}

			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," \tucIPSourceAddressLength : 0x%x\n",pstClassifierEntry->ucIPSourceAddressLength);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucIPDestinationAddressLength : 0x%x\n",pstClassifierEntry->ucIPDestinationAddressLength);
			for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPSourceAddressLength;uiIndex++)
			{
				if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
				{
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpAddr :\n");
					DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr);
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpMask :\n");
					DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask);
				}
				else
				{
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpAddr:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]);
				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpMask:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]);
				}
			}
			for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPDestinationAddressLength;uiIndex++)
			{
				if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
				{
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpAddr :\n");
					DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr);
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpMask :\n");
					DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask);

				}
				else
				{
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpAddr:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]);
					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpMask:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]);
				}
			}
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucProtocol:0x%X\n",pstClassifierEntry->ucProtocol[0]);
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tu8ClassifierRulePriority:%X\n",pstClassifierEntry->u8ClassifierRulePriority);


		}
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ulSFID:%lX\n",Adapter->PackInfo[uiLoopIndex].ulSFID);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"usVCID_Value:%X\n",Adapter->PackInfo[uiLoopIndex].usVCID_Value);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"PhsEnabled: 0x%X\n",Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThreshold:%X\n",Adapter->PackInfo[uiLoopIndex].uiThreshold);


		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid:%X\n",Adapter->PackInfo[uiLoopIndex].bValid);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bActive:%X\n",Adapter->PackInfo[uiLoopIndex].bActive);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"u8QueueType:%X\n",Adapter->PackInfo[uiLoopIndex].u8QueueType);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxBucketSize:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPerSFTxResourceCount:%X\n",atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount));
		//DumpDebug(DUMP_INFO,("				bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport));
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentBytesOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentPacketsOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentBytes);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentPackets);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentDrainRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThisPeriodSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liDrainCalculated:%llX\n",Adapter->PackInfo[uiLoopIndex].liDrainCalculated);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentTokenCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liLastUpdateTokenAt:%llX\n",Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxAllowedRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPendedLast:%X\n",Adapter->PackInfo[uiLoopIndex].uiPendedLast);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"NumOfPacketsSent:%X\n",Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n",Adapter->PackInfo[uiLoopIndex].uiMaxLatency);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n",Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]);
//	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
//		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes);
//		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes);
//		DumpDebug(DUMP_INFO,("				uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount));
	}

	for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++)
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aRxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aRxPktSizeHist[uiLoopIndex]);

	for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++)
			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aTxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aTxPktSizeHist[uiLoopIndex]);



	return;


}

int reset_card_proc(PMINI_ADAPTER ps_adapter)
{
	int retval = STATUS_SUCCESS;

    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
	unsigned int value = 0, uiResetValue = 0;

	psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)) ;

	ps_adapter->bDDRInitDone = FALSE;

	if(ps_adapter->chip_id >= T3LPB)
	{
		//SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before
		rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value));
		rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value));

		//making bit[6...5] same as was before f/w download. this setting force the h/w to
		//re-populated the SP RAM area with the string descriptor .
		value = value | (ps_adapter->syscfgBefFwDld & 0x00000060) ;
		wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
	}

	//killing all submitted URBs.
	psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
	Bcm_kill_all_URBs(psIntfAdapter);
	/* Reset the UMA-B Device */
	if(ps_adapter->chip_id >= T3LPB)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B \n");
		retval = usb_reset_device(psIntfAdapter->udev);

		psIntfAdapter->psAdapter->StopAllXaction = FALSE ;

		if(retval != STATUS_SUCCESS)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval);
			goto err_exit;
		}
		if (ps_adapter->chip_id == BCS220_2 ||
			ps_adapter->chip_id == BCS220_2BC ||
			ps_adapter->chip_id == BCS250_BC ||
				ps_adapter->chip_id == BCS220_3)
		{
			retval = rdmalt(ps_adapter,HPM_CONFIG_LDO145, &value, sizeof(value));
			if( retval < 0)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval);
				goto err_exit;
			}
			//setting 0th bit
			value |= (1<<0);
			retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
			if( retval < 0)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
				goto err_exit;
			}
		}

	}
	else
	{
		retval = rdmalt(ps_adapter,0x0f007018, &value, sizeof(value));
		if( retval < 0) {
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval);
			goto err_exit;
		}
		value&=(~(1<<16));
		retval= wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)) ;
		if( retval < 0) {
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
			goto err_exit;
		}

		// Toggling the GPIO 8, 9
		value = 0;
		retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value));
		if(retval < 0) {
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
			goto err_exit;
		}
		value = 0x300;
		retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)) ;
		if(retval < 0) {
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
			goto err_exit;
		}
		mdelay(50);
	}

	//ps_adapter->downloadDDR = false;

	if(ps_adapter->bFlashBoot)
	{
		//In flash boot mode MIPS state register has reverse polarity.
		// So just or with setting bit 30.
		//Make the MIPS in Reset state.
		rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));

		uiResetValue |=(1<<30);
		wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));
	}

	if(ps_adapter->chip_id >= T3LPB)
	{
		uiResetValue = 0;
		//
		// WA for SYSConfig Issue.
		// Read SYSCFG Twice to make it writable.
		//
		rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));
		if(uiResetValue & (1<<4))
		{
			uiResetValue = 0;
			rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));//2nd read to make it writable.
			uiResetValue &= (~(1<<4));
			wrmalt(ps_adapter,SYS_CFG, &uiResetValue, sizeof(uiResetValue));
		}

	}
	uiResetValue = 0;
	wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue));

err_exit :
	psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
	return retval;
}

int run_card_proc(PMINI_ADAPTER ps_adapter )
{
	unsigned int value=0;
	{

		if(rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
			BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__);
			return STATUS_FAILURE;
		}

		if(ps_adapter->bFlashBoot)
		{

			value&=(~(1<<30));
		}
		else
		{
			value |=(1<<30);
		}

		if(wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
			BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__);
			return STATUS_FAILURE;
		}
	}
	return STATUS_SUCCESS;
}

int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
{

	int status;
	UINT value = 0;
	/*
 	 * Create the threads first and then download the
 	 * Firm/DDR Settings..
 	 */

	status = create_worker_threads(ps_adapter);
	if (status<0)
		return status;

	/*
 	 * For Downloading the Firm, parse the cfg file first.
 	 */
	status = bcm_parse_target_params (ps_adapter);
	if(status){
		return status;
	}

	if(ps_adapter->chip_id >= T3LPB)
	{
		rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
		ps_adapter->syscfgBefFwDld = value ;
		if((value & 0x60)== 0)
		{
			ps_adapter->bFlashBoot = TRUE;
		}
	}

	reset_card_proc(ps_adapter);

	//Initializing the NVM.
	BcmInitNVM(ps_adapter);
	status = ddr_init(ps_adapter);
	if(status)
	{
		pr_err(DRV_NAME "ddr_init Failed\n");
		return status;
	}

	/* Download cfg file */
	status = buffDnldVerify(ps_adapter,
							 (PUCHAR)ps_adapter->pstargetparams,
							 sizeof(STARGETPARAMS),
							 CONFIG_BEGIN_ADDR);
	if(status)
	{
		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
		goto OUT;
	}

	if(register_networkdev(ps_adapter))
	{
		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
		return -EIO;
	}

	if(FALSE == ps_adapter->AutoFirmDld)
	{
		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n");
		//If Auto f/w download is disable, register the control interface,
		//register the control interface after the mailbox.
		if(register_control_device_interface(ps_adapter) < 0)
		{
			BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
			return -EIO;
		}

		return STATUS_SUCCESS;
	}

	/*
     * Do the LED Settings here. It will be used by the Firmware Download
     * Thread.
     */

	/*
     * 1. If the LED Settings fails, do not stop and do the Firmware download.
     * 2. This init would happened only if the cfg file is present, else
     *    call from the ioctl context.
     */

	status = InitLedSettings (ps_adapter);

	if(status)
	{
		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n");
		return status;
	}
	if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
	{
		ps_adapter->DriverState = DRIVER_INIT;
		wake_up(&ps_adapter->LEDInfo.notify_led_event);
	}

	if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
	{
		ps_adapter->DriverState = FW_DOWNLOAD;
		wake_up(&ps_adapter->LEDInfo.notify_led_event);
	}

	value = 0;
	wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
	wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));

	if(ps_adapter->eNVMType == NVM_FLASH)
	{
		status = PropagateCalParamsFromFlashToMemory(ps_adapter);
		if(status)
		{
			BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propagation of Cal param failed .." );
			goto OUT;
		}
	}

	/* Download Firmare */
	if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
	{
		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present... \n");
		goto OUT;
	}

	status = run_card_proc(ps_adapter);
	if(status)
	{
		BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n");
		goto OUT;
	}


	ps_adapter->fw_download_done = TRUE;
	mdelay(10);

OUT:
	if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
	{
		ps_adapter->DriverState = FW_DOWNLOAD_DONE;
		wake_up(&ps_adapter->LEDInfo.notify_led_event);
	}

	return status;
}


static int bcm_parse_target_params(PMINI_ADAPTER Adapter)
{
	struct file 		*flp=NULL;
	mm_segment_t 	oldfs={0};
	char *buff;
	int len = 0;
	loff_t	pos = 0;

	buff=kmalloc(BUFFER_1K, GFP_KERNEL);
	if(!buff)
	{
		return -ENOMEM;
	}
	if((Adapter->pstargetparams =
		kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
	{
		kfree(buff);
		return -ENOMEM;
	}
	flp=open_firmware_file(Adapter, CFG_FILE);
	if(!flp) {
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE);
		kfree(buff);
		kfree(Adapter->pstargetparams);
		Adapter->pstargetparams = NULL;
		return -ENOENT;
	}
	oldfs=get_fs();	set_fs(get_ds());
	len=vfs_read(flp, (void __user __force *)buff, BUFFER_1K, &pos);
	set_fs(oldfs);

	if(len != sizeof(STARGETPARAMS))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
		kfree(buff);
		kfree(Adapter->pstargetparams);
		Adapter->pstargetparams = NULL;
		filp_close(flp, current->files);
		return -ENOENT;
	}
	filp_close(flp, current->files);

	/* Check for autolink in config params */
	/*
	 * Values in Adapter->pstargetparams are in network byte order
	 */
	memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
	kfree (buff);
	beceem_parse_target_struct(Adapter);
	return STATUS_SUCCESS;
}

void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
{
	UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;

	if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE)
	{
		pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
		Adapter->AutoSyncup = FALSE;
	}
	else
	{
		pr_info(DRV_NAME ": AutoSyncup is Enabled\n");
		Adapter->AutoSyncup	= TRUE;
	}

	if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE)
	{
		pr_info(DRV_NAME ": Enabling autolink up");
		Adapter->AutoLinkUp = TRUE;
	}
	else
	{
		pr_info(DRV_NAME ": Disabling autolink up");
		Adapter->AutoLinkUp = FALSE;
	}
	// Setting the DDR Setting..
	Adapter->DDRSetting =
			(ntohl(Adapter->pstargetparams->HostDrvrConfig6) >>8)&0x0F;
	Adapter->ulPowerSaveMode =
			(ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;

	pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting);
	pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode);
	if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD)
    {
        pr_info(DRV_NAME ": Enabling Auto Firmware Download\n");
        Adapter->AutoFirmDld = TRUE;
    }
    else
    {
        pr_info(DRV_NAME ": Disabling Auto Firmware Download\n");
        Adapter->AutoFirmDld = FALSE;
    }
	uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
	Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
	pr_info(DRV_NAME ": MIPSConfig   : 0x%X\n",Adapter->bMipsConfig);
	//used for backward compatibility.
	Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;

	Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03;
	pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode);

    if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01))
    {
        Adapter->bDoSuspend = TRUE;
        pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile");
    }

	uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
	pr_info(DRV_NAME ": uiEEPROMFlag  : 0x%X\n",uiEEPROMFlag);
	Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3);

	Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;

	Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));

	Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;

	if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01)
		Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;

	if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
		doPowerAutoCorrection(Adapter);

}

static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
{
	UINT reporting_mode;

	reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ;
	psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);

	if(reporting_mode == TRUE)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"can't do suspen/resume as reporting mode is enable");
		psAdapter->bDoSuspend = FALSE;
	}

	if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
	{
		//If reporting mode is enable, switch PMU to PMC
		{
			psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
			psAdapter->bDoSuspend =FALSE;

		}

		//clearing space bit[15..12]
		psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12)));
		//placing the power save mode option
		psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12));

	}
	else if (psAdapter->bIsAutoCorrectEnabled == FALSE)
	{

		// remove the autocorrect disable bit set before dumping.
		psAdapter->ulPowerSaveMode &= ~(1 << 3);
		psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15));
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode);
	}
}

#if 0
static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
{
	int status = 0, i = 0;
	unsigned int temp = 0;
	unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);

	if(!pucmacaddr)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
		return NULL;
	}

	dwAddress |= 0x5b000000;
	status = wrmalt(Adapter, EEPROM_COMMAND_Q_REG,
						(PUINT)&dwAddress, sizeof(UINT));
	if(status != STATUS_SUCCESS)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
		kfree(pucmacaddr);
		pucmacaddr = NULL;
		goto OUT;
	}
	for(i=0;i<MAC_ADDRESS_SIZE;i++)
	{
		status = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp,sizeof(temp));
		if(status != STATUS_SUCCESS)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
			kfree(pucmacaddr);
			pucmacaddr = NULL;
			goto OUT;
		}
		pucmacaddr[i] = temp & 0xff;
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"%x \n", pucmacaddr[i]);
	}
OUT:
	return pucmacaddr;
}
#endif


static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
{
	UINT uiIndex = 0;

	if(RWM_WRITE == rwFlag) {
		for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) {
			puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]);
		}
	} else {
		for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) {
			puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]);
		}
	}
}

#define CACHE_ADDRESS_MASK	0x80000000
#define UNCACHE_ADDRESS_MASK	0xa0000000

int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
	return Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
			uiAddress, pucBuff, sSize);
}

int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
	int iRetVal;

	iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
			uiAddress, pucBuff, sSize);


	return iRetVal;
}

int wrmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
{
	convertEndian(RWM_WRITE, pucBuff, size);
	return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
}

int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
{
	INT uiRetVal =0;

	uiRetVal = rdm(Adapter,uiAddress,(PUCHAR)pucBuff,size);
	convertEndian(RWM_READ, (PUINT)pucBuff, size);

	return uiRetVal;
}


int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
	INT status = STATUS_SUCCESS ;
	down(&Adapter->rdmwrmsync);

	if((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus ==TRUE) ||
		(Adapter->bPreparingForLowPowerMode ==TRUE))
	{
		status = -EACCES;
		goto exit;
	}

	status =wrm(Adapter, uiAddress, pucBuff, sSize);

exit:
	up(&Adapter->rdmwrmsync);
	return status ;
}

int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
{
	int iRetVal = STATUS_SUCCESS;

	down(&Adapter->rdmwrmsync);

	if((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus ==TRUE) ||
		(Adapter->bPreparingForLowPowerMode ==TRUE))
	{
		iRetVal = -EACCES;
		goto exit;
	}

	iRetVal = wrmalt(Adapter,uiAddress,pucBuff,size);

exit:
	up(&Adapter->rdmwrmsync);
	return iRetVal;
}

int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
{
	INT uiRetVal =STATUS_SUCCESS;

	down(&Adapter->rdmwrmsync);

	if((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus ==TRUE) ||
		(Adapter->bPreparingForLowPowerMode ==TRUE))
	{
		uiRetVal = -EACCES;
		goto exit;
	}

	uiRetVal = rdmalt(Adapter,uiAddress, pucBuff, size);

exit:
	up(&Adapter->rdmwrmsync);
	return uiRetVal;
}


static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter)
{
	int clear_abort_pattern = 0,Status = 0;
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
	//target has woken up From Shut Down
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
	Status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern));
	if(Status)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status);
		return;
	}
	if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
	{
		msleep(100);
		InterfaceHandleShutdownModeWakeup(Adapter);
		msleep(100);
	}
	if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
	{
		Adapter->DriverState = NO_NETWORK_ENTRY;
		wake_up(&Adapter->LEDInfo.notify_led_event);
	}

	Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
	Adapter->bShutStatus = FALSE;
	wake_up(&Adapter->lowpower_mode_wait_queue);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
}

static VOID SendShutModeResponse(PMINI_ADAPTER Adapter)
{
	CONTROL_MESSAGE		stShutdownResponse;
	UINT NVMAccess = 0,lowPwrAbortMsg = 0;
	UINT Status = 0;

	memset (&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE));
	stShutdownResponse.Leader.Status  = LINK_UP_CONTROL_REQ;
	stShutdownResponse.Leader.PLength = 8;//8 bytes;
	stShutdownResponse.szData[0] = LINK_UP_ACK;
	stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE;

	/*********************************
	**down_trylock -
	** if [ semaphore is available ]
	**		 acquire semaphone and return value 0 ;
	**   else
	**		 return non-zero value ;
	**
	***********************************/

	NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);

	lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync);


	if(NVMAccess || lowPwrAbortMsg|| atomic_read(&Adapter->TotalPacketCount))
	{
		if(!NVMAccess)
			up(&Adapter->NVMRdmWrmLock);

		if(!lowPwrAbortMsg)
			up(&Adapter->LowPowerModeSync);

		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n");
		stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on.
		Adapter->bPreparingForLowPowerMode = FALSE;
	}
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n");
		stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER;//ShutDown ACK

		/* Wait for the LED to TURN OFF before sending ACK response */
		if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
		{
			INT iRetVal = 0;

			/* Wake the LED Thread with LOWPOWER_MODE_ENTER State */
			Adapter->DriverState = LOWPOWER_MODE_ENTER;
			wake_up(&Adapter->LEDInfo.notify_led_event);

			/* Wait for 1 SEC for LED to OFF */
			iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent,\
				Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));

			/* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
			if(iRetVal <= 0)
			{
				stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on.

				Adapter->DriverState = NO_NETWORK_ENTRY;
				wake_up(&Adapter->LEDInfo.notify_led_event);
			}
		}

		if(stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ACKING SHUTDOWN MODE !!!!!!!!!");
			down(&Adapter->rdmwrmsync);
			Adapter->bPreparingForLowPowerMode = TRUE;
			up(&Adapter->rdmwrmsync);
			//Killing all URBS.
			if(Adapter->bDoSuspend == TRUE)
				Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
		}
		else
		{
			Adapter->bPreparingForLowPowerMode = FALSE;
		}

		if(!NVMAccess)
			up(&Adapter->NVMRdmWrmLock);

		if(!lowPwrAbortMsg)
			up(&Adapter->LowPowerModeSync);
	}
	Status = CopyBufferToControlPacket(Adapter,&stShutdownResponse);
	if((Status != STATUS_SUCCESS))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n");
		Adapter->bPreparingForLowPowerMode = FALSE;

		StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
	}
}


static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
{
	B_UINT32 uiResetValue = 0;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");

	if(*(pucBuffer+1) ==  COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW)
	{
		HandleShutDownModeWakeup(Adapter);
	}
	else if(*(pucBuffer+1) ==  LINK_SHUTDOWN_REQ_FROM_FIRMWARE)
	{
		//Target wants to go to Shut Down Mode
		//InterfacePrepareForShutdown(Adapter);
		if(Adapter->chip_id == BCS220_2 ||
		   Adapter->chip_id == BCS220_2BC ||
		   Adapter->chip_id == BCS250_BC ||
		   Adapter->chip_id == BCS220_3)
		{
			rdmalt(Adapter,HPM_CONFIG_MSW, &uiResetValue, 4);
			uiResetValue |= (1<<17);
			wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4);
		}

		SendShutModeResponse(Adapter);
		BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
	return;

}

VOID ResetCounters(PMINI_ADAPTER Adapter)
{

   	beceem_protocol_reset(Adapter);

	Adapter->CurrNumRecvDescs = 0;
    Adapter->PrevNumRecvDescs = 0;
    Adapter->LinkUpStatus = 0;
	Adapter->LinkStatus = 0;
    atomic_set(&Adapter->cntrlpktCnt,0);
    atomic_set (&Adapter->TotalPacketCount,0);
    Adapter->fw_download_done=FALSE;
	Adapter->LinkStatus = 0;
    Adapter->AutoLinkUp = FALSE;
	Adapter->IdleMode = FALSE;
	Adapter->bShutStatus = FALSE;

}
S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP)
{
	UINT uiIndex=0;
	for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
	{
		if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&&
			(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&&
			(Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIP)&&
			!Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment)
			return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry;
	}
	return NULL;
}

void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo)
{
	UINT uiIndex=0;
	for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
	{
		if(!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)
		{
			memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex],psFragPktInfo,sizeof(S_FRAGMENTED_PACKET_INFO));
			break;
		}
	}

}

void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp)
{
	UINT uiIndex=0;
	for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
	{
		if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&&
			(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&&
			(Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIp))
		memset(&Adapter->astFragmentedPktClassifierTable[uiIndex],0,sizeof(S_FRAGMENTED_PACKET_INFO));
	}
}

void update_per_cid_rx (PMINI_ADAPTER Adapter)
{
	UINT  qindex = 0;

	if((jiffies - Adapter->liDrainCalculated) < XSECONDS)
		return;

	for(qindex = 0; qindex < HiPriority; qindex++)
	{
		if(Adapter->PackInfo[qindex].ucDirection == 0)
		{
			Adapter->PackInfo[qindex].uiCurrentRxRate =
				(Adapter->PackInfo[qindex].uiCurrentRxRate +
				Adapter->PackInfo[qindex].uiThisPeriodRxBytes)/2;

			Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0;
		}
		else
		{
			Adapter->PackInfo[qindex].uiCurrentDrainRate =
				(Adapter->PackInfo[qindex].uiCurrentDrainRate +
				Adapter->PackInfo[qindex].uiThisPeriodSentBytes)/2;

			Adapter->PackInfo[qindex].uiThisPeriodSentBytes=0;
		}
	}
	Adapter->liDrainCalculated=jiffies;
}
void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
{
	INT iIndex = 0;
	u32 uibuff[MAX_TARGET_DSX_BUFFERS];

	if(!atomic_read (&Adapter->uiMBupdate))
		return;

	if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
		return;
	}
	for(iIndex = 0;iIndex < HiPriority; iIndex++)
	{
		if(Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection)
		{
			if(Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS)
			{
				atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]);
			}
			else
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x \n",
					Adapter->PackInfo[iIndex].usVCID_Value);
			}
		}
	}
	atomic_set (&Adapter->uiMBupdate, FALSE);
}

void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
{
	struct sk_buff* 			PacketToDrop=NULL;
	struct net_device_stats*		netstats = &Adapter->dev->stats;

	spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);

	while(Adapter->PackInfo[iQIndex].FirstTxQueue &&
		atomic_read(&Adapter->TotalPacketCount))
	{
		PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
		if(PacketToDrop && PacketToDrop->len)
		{
			netstats->tx_dropped++;
			DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, \
					Adapter->PackInfo[iQIndex].LastTxQueue);

			Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--;
			Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len;

			//Adding dropped statistics
			Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
			Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;

			dev_kfree_skb(PacketToDrop);
			atomic_dec(&Adapter->TotalPacketCount);
		}
	}
	spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);

}

static void beceem_protocol_reset (PMINI_ADAPTER Adapter)
{
	int i;

	if (netif_msg_link(Adapter))
		pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name);

	netif_carrier_off(Adapter->dev);
	netif_stop_queue(Adapter->dev);

	Adapter->IdleMode = FALSE;
	Adapter->LinkUpStatus = FALSE;
	ClearTargetDSXBuffer(Adapter,0, TRUE);
	//Delete All Classifier Rules

	for(i = 0;i<HiPriority;i++)
	{
		DeleteAllClassifiersForSF(Adapter,i);
	}

	flush_all_queues(Adapter);

	if(Adapter->TimerActive == TRUE)
		Adapter->TimerActive = FALSE;

	memset(Adapter->astFragmentedPktClassifierTable, 0,
	       sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);

	for(i = 0;i<HiPriority;i++)
	{
		//resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF.
		// It is same between MIBs and SF.
		memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable,
		       0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS));
	}
}





