blob: a0637eb278479282f4249dc76dc67fb9a3708b6f [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
Kevin McKinney29794602012-05-26 12:05:12 -04003static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc);
Kevin McKinney7a15b792012-10-18 22:40:08 -04004static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter);
Kevin McKinney29794602012-05-26 12:05:12 -04005static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer);
6static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter);
7static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter);
Stephen Hemminger9dd47ee2010-11-01 12:24:00 -04008
Kevin McKinney7a15b792012-10-18 22:40:08 -04009static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070010{
Kevin McKinney9ef07602012-10-18 22:40:12 -040011 unsigned int uiLoopIndex;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070012
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040013 for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) {
14 Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD;
15 Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate = MAX_ALLOWED_RATE;
16 Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize = 20*1024*1024;
17 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070018
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040019 Adapter->BEBucketSize = BE_BUCKET_SIZE;
20 Adapter->rtPSBucketSize = rtPS_BUCKET_SIZE;
21 Adapter->LinkStatus = SYNC_UP_REQUEST;
22 Adapter->TransferMode = IP_PACKET_ONLY_MODE;
23 Adapter->usBestEffortQueueIndex = -1;
24 return;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070025}
26
Kevin McKinney7af141342012-10-18 22:40:13 -040027int InitAdapter(struct bcm_mini_adapter *psAdapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070028{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040029 int i = 0;
Kevin McKinney7af141342012-10-18 22:40:13 -040030 int Status = STATUS_SUCCESS;
Robin Schroerfe830732014-06-16 13:01:46 +020031
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040032 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070033
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040034 if (psAdapter == NULL) {
35 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070036 return -EINVAL;
37 }
38
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040039 sema_init(&psAdapter->NVMRdmWrmLock, 1);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070040 sema_init(&psAdapter->rdmwrmsync, 1);
41 spin_lock_init(&psAdapter->control_queue_lock);
42 spin_lock_init(&psAdapter->txtransmitlock);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040043 sema_init(&psAdapter->RxAppControlQueuelock, 1);
44 sema_init(&psAdapter->fw_download_sema, 1);
45 sema_init(&psAdapter->LowPowerModeSync, 1);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070046
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040047 for (i = 0; i < NO_OF_QUEUES; i++)
48 spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock);
49 i = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070050
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040051 init_waitqueue_head(&psAdapter->process_rx_cntrlpkt);
52 init_waitqueue_head(&psAdapter->tx_packet_wait_queue);
53 init_waitqueue_head(&psAdapter->process_read_wait_queue);
54 init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue);
55 init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070056 psAdapter->waiting_to_fw_download_done = TRUE;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -070057 psAdapter->fw_download_done = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070058
59 default_wimax_protocol_initialize(psAdapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040060 for (i = 0; i < MAX_CNTRL_PKTS; i++) {
Jesper Juhl3701bef2010-11-10 21:31:38 +010061 psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040062 if (!psAdapter->txctlpacket[i]) {
63 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070064 return -ENOMEM;
65 }
66 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040067
68 if (AllocAdapterDsxBuffer(psAdapter)) {
69 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070070 return -EINVAL;
71 }
72
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040073 /* Initialize PHS interface */
74 if (phs_init(&psAdapter->stBCMPhsContext, psAdapter) != 0) {
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -040075 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __func__, __LINE__);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070076 return -ENOMEM;
77 }
78
79 Status = BcmAllocFlashCSStructure(psAdapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040080 if (Status) {
81 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Memory Allocation for Flash structure failed");
82 return Status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070083 }
84
85 Status = vendorextnInit(psAdapter);
86
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040087 if (STATUS_SUCCESS != Status) {
88 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Vendor Init Failed");
89 return Status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070090 }
91
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -040092 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070093
94 return STATUS_SUCCESS;
95}
96
Kevin McKinney7a15b792012-10-18 22:40:08 -040097void AdapterFree(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070098{
Stephen Hemmingere614e282010-11-01 09:52:14 -040099 int count;
Robin Schroerfe830732014-06-16 13:01:46 +0200100
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700101 beceem_protocol_reset(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700102 vendorextnExit(Adapter);
103
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400104 if (Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
105 kthread_stop(Adapter->control_packet_handler);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400106
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400107 if (Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
108 kthread_stop(Adapter->transmit_packet_thread);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400109
110 wake_up(&Adapter->process_read_wait_queue);
111
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400112 if (Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
113 kthread_stop(Adapter->LEDInfo.led_cntrl_threadid);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400114
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400115 unregister_networkdev(Adapter);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400116
117 /* FIXME: use proper wait_event and refcounting */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400118 while (atomic_read(&Adapter->ApplicationRunning)) {
119 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n", atomic_read(&Adapter->ApplicationRunning));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700120 msleep(100);
121 }
122 unregister_control_device_interface(Adapter);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400123 kfree(Adapter->pstargetparams);
124
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400125 for (count = 0; count < MAX_CNTRL_PKTS; count++)
Stephen Hemmingere614e282010-11-01 09:52:14 -0400126 kfree(Adapter->txctlpacket[count]);
127
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700128 FreeAdapterDsxBuffer(Adapter);
Stephen Hemmingere614e282010-11-01 09:52:14 -0400129 kfree(Adapter->pvInterfaceAdapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700130
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400131 /* Free the PHS Interface */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700132 PhsCleanup(&Adapter->stBCMPhsContext);
133
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700134 BcmDeAllocFlashCSStructure(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700135
Stephen Hemmingere614e282010-11-01 09:52:14 -0400136 free_netdev(Adapter->dev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700137}
138
Kevin McKinney29794602012-05-26 12:05:12 -0400139static int create_worker_threads(struct bcm_mini_adapter *psAdapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700140{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400141 /* Rx Control Packets Processing */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700142 psAdapter->control_packet_handler = kthread_run((int (*)(void *))
Stephen Hemminger2d087482010-11-01 12:14:01 -0400143 control_packet_handler, psAdapter, "%s-rx", DRV_NAME);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400144 if (IS_ERR(psAdapter->control_packet_handler)) {
Stephen Hemminger2d087482010-11-01 12:14:01 -0400145 pr_notice(DRV_NAME ": could not create control thread\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700146 return PTR_ERR(psAdapter->control_packet_handler);
147 }
Stephen Hemminger2d087482010-11-01 12:14:01 -0400148
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400149 /* Tx Thread */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700150 psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
Stephen Hemminger2d087482010-11-01 12:14:01 -0400151 tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400152 if (IS_ERR(psAdapter->transmit_packet_thread)) {
Stephen Hemminger2d087482010-11-01 12:14:01 -0400153 pr_notice(DRV_NAME ": could not creat transmit thread\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700154 kthread_stop(psAdapter->control_packet_handler);
155 return PTR_ERR(psAdapter->transmit_packet_thread);
156 }
157 return 0;
158}
159
Kevin McKinney29794602012-05-26 12:05:12 -0400160static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700161{
Al Viro32aecdd2012-07-22 21:02:01 +0400162 struct file *flp = filp_open(path, O_RDONLY, S_IRWXU);
Robin Schroerfe830732014-06-16 13:01:46 +0200163
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400164 if (IS_ERR(flp)) {
165 pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp));
166 flp = NULL;
167 }
Stephen Hemminger2d087482010-11-01 12:14:01 -0400168
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400169 if (Adapter->device_removed)
170 flp = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700171
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400172 return flp;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700173}
174
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400175/* Arguments:
176 * Logical Adapter
177 * Path to image file
178 * Download Address on the chip
179 */
Kevin McKinney29794602012-05-26 12:05:12 -0400180static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700181{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400182 int errorno = 0;
183 struct file *flp = NULL;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400184 struct timeval tv = {0};
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700185
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400186 flp = open_firmware_file(Adapter, path);
187 if (!flp) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400188 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path);
Al Viro32aecdd2012-07-22 21:02:01 +0400189 return -ENOENT;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400190 }
Al Viro496ad9a2013-01-23 17:07:38 -0500191 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)file_inode(flp)->i_size, loc);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400192 do_gettimeofday(&tv);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700193
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400194 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
195 if (Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) {
196 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error %x!!!", -EIO);
197 errorno = -EIO;
198 goto exit_download;
199 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400200 vfs_llseek(flp, 0, 0);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400201 if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) {
202 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!");
203 errorno = -EIO;
204 goto exit_download;
205 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700206
207exit_download:
Al Viro32aecdd2012-07-22 21:02:01 +0400208 filp_close(flp, NULL);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400209 return errorno;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700210}
211
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700212/**
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400213 * @ingroup ctrl_pkt_functions
214 * This function copies the contents of given buffer
215 * to the control packet and queues it for transmission.
Masanari Iida6abaf582013-08-23 22:55:31 +0900216 * @note Do not acquire the spinlock, as it it already acquired.
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400217 * @return SUCCESS/FAILURE.
218 * Arguments:
219 * Logical Adapter
220 * Control Packet Buffer
221 */
Kevin McKinney7af141342012-10-18 22:40:13 -0400222int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700223{
Kevin McKinneyff352042012-05-26 12:05:11 -0400224 struct bcm_leader *pLeader = NULL;
Kevin McKinney7af141342012-10-18 22:40:13 -0400225 int Status = 0;
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400226 unsigned char *ctrl_buff;
Kevin McKinney9ef07602012-10-18 22:40:12 -0400227 unsigned int pktlen = 0;
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400228 struct bcm_link_request *pLinkReq = NULL;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400229 PUCHAR pucAddIndication = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700230
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400231 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>");
232 if (!ioBuffer) {
233 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got Null Buffer\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700234 return -EINVAL;
235 }
236
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400237 pLinkReq = (struct bcm_link_request *)ioBuffer;
Kevin McKinneyff352042012-05-26 12:05:11 -0400238 pLeader = (struct bcm_leader *)ioBuffer; /* ioBuffer Contains sw_Status and Payload */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700239
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400240 if (Adapter->bShutStatus == TRUE &&
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700241 pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD &&
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400242 pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) {
243
244 /* Got sync down in SHUTDOWN..we could not process this. */
245 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700246 return STATUS_FAILURE;
247 }
248
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400249 if ((pLeader->Status == LINK_UP_CONTROL_REQ) &&
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700250 ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD &&
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400251 (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) || /* Sync Up Command */
252 pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) /* Net Entry Command */ {
253
254 if (Adapter->LinkStatus > PHY_SYNC_ACHIVED) {
255 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "LinkStatus is Greater than PHY_SYN_ACHIEVED");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700256 return STATUS_FAILURE;
257 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400258
Kevin McKinneyb64c8462012-10-18 22:40:15 -0400259 if (Adapter->bShutStatus == TRUE) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700261 if (Adapter->bTriedToWakeUpFromlowPowerMode == false) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400262 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n");
263 Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; /* change it to 1 for current support. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700264 Adapter->bWakeUpDevice = TRUE;
265 wake_up(&Adapter->process_rx_cntrlpkt);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400266 Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->bShutStatus, (5 * HZ));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700267
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400268 if (Status == -ERESTARTSYS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700269 return Status;
270
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400271 if (Adapter->bShutStatus) {
272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700273 return STATUS_FAILURE;
274 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400275 } else {
276 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Wakeup has been tried already...\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700277 }
278 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700279 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700280
Kevin McKinneyb64c8462012-10-18 22:40:15 -0400281 if (Adapter->IdleMode == TRUE) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400282 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */
283 if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 ||
284 pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) {
285
286 if ((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD)) {
Robin Schroer28c520a2014-06-16 13:01:47 +0200287 if (pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Link Down Sent in Idle Mode\n");
289 Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN; /* LINK DOWN sent in Idle Mode */
290 } else {
291 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700292 Adapter->usIdleModePattern = ABORT_IDLE_REG;
293 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400294 } else {
295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n");
296 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700297 }
298
299 /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400300 * the wake up from idlemode is from host
301 */
302 /* Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700303 Adapter->bWakeUpDevice = TRUE;
304 wake_up(&Adapter->process_rx_cntrlpkt);
305
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400306 /* We should not send DREG message down while in idlemode. */
307 if (LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0])
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700308 return STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700309
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400310 Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->IdleMode, (5 * HZ));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700311
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400312 if (Status == -ERESTARTSYS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700313 return Status;
314
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400315 if (Adapter->IdleMode) {
316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700317 return STATUS_FAILURE;
318 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400319 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700320 return STATUS_SUCCESS;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400321 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700322 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400323
324 /* The Driver has to send control messages with a particular VCID */
325 pLeader->Vcid = VCID_CONTROL_PACKET; /* VCID for control packet. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700326
327 /* Allocate skb for Control Packet */
328 pktlen = pLeader->PLength;
329 ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS];
330
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400331 if (!ctrl_buff) {
332 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
333 return -ENOMEM;
334 }
335
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400336 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",
337 atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen);
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400338
339 if (pLeader) {
340 if ((pLeader->Status == 0x80) ||
341 (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) {
342 /*
343 * Restructure the DSX message to handle Multiple classifier Support
344 * Write the Service Flow param Structures directly to the target
345 * and embed the pointers in the DSX messages sent to target.
346 */
347 /* Lets store the current length of the control packet we are transmitting */
348 pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
349 pktlen = pLeader->PLength;
350 Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen);
351 if (Status != 1) {
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700352 ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, false);
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400353 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 ");
354 return STATUS_FAILURE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700355 }
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400356 /*
357 * update the leader to use the new length
358 * The length of the control packet is length of message being sent + Leader length
359 */
360 pLeader->PLength = pktlen;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700361 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700362 }
Kevin McKinney895b1fb2012-10-18 22:40:14 -0400363
364 if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE)
365 return -EINVAL;
366
367 memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
368 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
369 *(struct bcm_leader *)ctrl_buff = *pLeader;
370 memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
371 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
372
373 /* Update the statistics counters */
374 spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
375 Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength;
376 Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
377 atomic_inc(&Adapter->TotalPacketCount);
378 spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
379 Adapter->PackInfo[HiPriority].bValid = TRUE;
380
381 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
382 Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
383 Adapter->PackInfo[HiPriority].bValid);
384 Status = STATUS_SUCCESS;
385 /*Queue the packet for transmission */
386 atomic_inc(&Adapter->index_wr_txcntrlpkt);
387 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets");
388 atomic_set(&Adapter->TxPktAvail, 1);
389 wake_up(&Adapter->tx_packet_wait_queue);
390
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400391 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<====");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700392 return Status;
393}
394
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700395/******************************************************************
396* Function - LinkMessage()
397*
398* Description - This function builds the Sync-up and Link-up request
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400399* packet messages depending on the device Link status.
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700400*
401* Parameters - Adapter: Pointer to the Adapter structure.
402*
403* Returns - None.
404*******************************************************************/
Kevin McKinney7a15b792012-10-18 22:40:08 -0400405void LinkMessage(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700406{
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400407 struct bcm_link_request *pstLinkRequest = NULL;
Robin Schroerfe830732014-06-16 13:01:46 +0200408
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400409 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
410 if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) {
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400411 pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400412 if (!pstLinkRequest) {
413 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700414 return;
415 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400416 /* sync up request... */
417 Adapter->LinkStatus = WAIT_FOR_SYNC; /* current link status */
418 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp...");
419 pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD;
420 pstLinkRequest->szData[1] = LINK_SYNC_UP_SUBTYPE;
421 pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ;
422 pstLinkRequest->Leader.PLength = sizeof(ULONG);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700423 Adapter->bSyncUpRequestSent = TRUE;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400424
425 } else if (Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) {
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400426 pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400427 if (!pstLinkRequest) {
428 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700429 return;
430 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400431 /* LINK_UP_REQUEST */
432 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp...");
433 pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD;
434 pstLinkRequest->szData[1] = LINK_NET_ENTRY;
435 pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ;
436 pstLinkRequest->Leader.PLength = sizeof(ULONG);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700437 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400438 if (pstLinkRequest) {
439 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700440 CopyBufferToControlPacket(Adapter, pstLinkRequest);
Stephen Hemminger082e8892010-11-01 09:35:21 -0400441 kfree(pstLinkRequest);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700442 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400443 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700444 return;
445}
446
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700447/**********************************************************************
448* Function - StatisticsResponse()
449*
450* Description - This function handles the Statistics response packet.
451*
452* Parameters - Adapter : Pointer to the Adapter structure.
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400453* - pvBuffer: Starting address of Statistic response data.
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700454*
455* Returns - None.
456************************************************************************/
Kevin McKinney7a15b792012-10-18 22:40:08 -0400457void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700458{
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -0400459 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__);
Stephen Hemmingere39e3be2010-11-01 11:14:29 -0400460 Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
Kevin McKinney9ef07602012-10-18 22:40:12 -0400461 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer);
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -0400462 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700463 return;
464}
465
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700466/**********************************************************************
467* Function - LinkControlResponseMessage()
468*
469* Description - This function handles the Link response packets.
470*
471* Parameters - Adapter : Pointer to the Adapter structure.
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400472* - pucBuffer: Starting address of Link response data.
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700473*
474* Returns - None.
475***********************************************************************/
Kevin McKinney7a15b792012-10-18 22:40:08 -0400476void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700477{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400478 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700479
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400480 if (*pucBuffer == LINK_UP_ACK) {
481 switch (*(pucBuffer+1)) {
482 case PHY_SYNC_ACHIVED: /* SYNCed UP */
483 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700484
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400485 if (Adapter->LinkStatus == LINKUP_DONE)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700486 beceem_protocol_reset(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700487
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400488 Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX;
489 Adapter->LinkStatus = PHY_SYNC_ACHIVED;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700490
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400491 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700492 Adapter->DriverState = NO_NETWORK_ENTRY;
493 wake_up(&Adapter->LEDInfo.notify_led_event);
494 }
495
496 LinkMessage(Adapter);
497 break;
498
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400499 case LINKUP_DONE:
500 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE");
501 Adapter->LinkStatus = LINKUP_DONE;
502 Adapter->bPHSEnabled = *(pucBuffer+3);
503 Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK;
504 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x\n", Adapter->bPHSEnabled);
505
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700506 if ((false == Adapter->bShutStatus) && (false == Adapter->IdleMode)) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400507 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
508 Adapter->DriverState = NORMAL_OPERATION;
509 wake_up(&Adapter->LEDInfo.notify_led_event);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700510 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700511 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400512 LinkMessage(Adapter);
513 break;
514
515 case WAIT_FOR_SYNC:
516 /*
517 * Driver to ignore the DREG_RECEIVED
518 * WiMAX Application should handle this Message
519 */
520 /* Adapter->liTimeSinceLastNetEntry = 0; */
521 Adapter->LinkUpStatus = 0;
522 Adapter->LinkStatus = 0;
523 Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700524 Adapter->bTriedToWakeUpFromlowPowerMode = false;
525 Adapter->IdleMode = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400526 beceem_protocol_reset(Adapter);
527
528 break;
529 case LINK_SHUTDOWN_REQ_FROM_FIRMWARE:
530 case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW:
531 {
532 HandleShutDownModeRequest(Adapter, pucBuffer);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700533 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400534 break;
535 default:
536 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x", *(pucBuffer + 1));
537 break;
538 }
539 } else if (SET_MAC_ADDRESS_RESPONSE == *pucBuffer) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700540 PUCHAR puMacAddr = (pucBuffer + 1);
Robin Schroerfe830732014-06-16 13:01:46 +0200541
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400542 Adapter->LinkStatus = SYNC_UP_REQUEST;
543 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700544 LinkMessage(Adapter);
545 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
546 }
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -0400547 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====", __func__);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700548 return;
549}
550
Kevin McKinney29794602012-05-26 12:05:12 -0400551void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700552{
Kevin McKinney7af141342012-10-18 22:40:13 -0400553 int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700554 struct timeval tv;
Kevin McKinney2610c7a2012-05-26 12:05:08 -0400555 struct bcm_link_request stIdleResponse = {{0} };
Robin Schroerfe830732014-06-16 13:01:46 +0200556
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700557 memset(&tv, 0, sizeof(tv));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400558 stIdleResponse.Leader.Status = IDLE_MESSAGE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700559 stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH;
560 stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400561 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, " ============>");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700562
563 /*********************************
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400564 *down_trylock -
565 * if [ semaphore is available ]
566 * acquire semaphone and return value 0 ;
567 * else
568 * return non-zero value ;
569 *
570 ***********************************/
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700571
572 NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400573 lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700574
575
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400576 if ((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) &&
577 (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) {
578
579 if (!NVMAccess)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700580 up(&Adapter->NVMRdmWrmLock);
581
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400582 if (!lowPwrAbortMsg)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700583 up(&Adapter->LowPowerModeSync);
584
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400585 stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */
586 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700587 Adapter->bPreparingForLowPowerMode = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400588 } else {
589 stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; /* 2; Idle ACK */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700590 Adapter->StatisticsPointer = 0;
591
592 /* Wait for the LED to TURN OFF before sending ACK response */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400593 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Kevin McKinney7af141342012-10-18 22:40:13 -0400594 int iRetVal = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700595
596 /* Wake the LED Thread with IDLEMODE_ENTER State */
597 Adapter->DriverState = LOWPOWER_MODE_ENTER;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400598 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);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700599 wake_up(&Adapter->LEDInfo.notify_led_event);
600
601 /* Wait for 1 SEC for LED to OFF */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400602 iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700603
604 /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400605 if (iRetVal <= 0) {
606 stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700607 Adapter->DriverState = NORMAL_OPERATION;
608 wake_up(&Adapter->LEDInfo.notify_led_event);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400609 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700610 }
611 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400612
613 if (stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) {
614 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "ACKING IDLE MODE !!!!!!!!!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700615 down(&Adapter->rdmwrmsync);
616 Adapter->bPreparingForLowPowerMode = TRUE;
617 up(&Adapter->rdmwrmsync);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400618 /* Killing all URBS. */
619 if (Adapter->bDoSuspend == TRUE)
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400620 Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400621 } else {
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700622 Adapter->bPreparingForLowPowerMode = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700623 }
624
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400625 if (!NVMAccess)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700626 up(&Adapter->NVMRdmWrmLock);
627
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400628 if (!lowPwrAbortMsg)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700629 up(&Adapter->LowPowerModeSync);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700630 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400631
632 status = CopyBufferToControlPacket(Adapter, &stIdleResponse);
Robin Schroer28c520a2014-06-16 13:01:47 +0200633 if (status != STATUS_SUCCESS) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400634 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700635 Adapter->bPreparingForLowPowerMode = false;
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400636 StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700637 }
638 do_gettimeofday(&tv);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400639 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);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700640}
641
642/******************************************************************
643* Function - DumpPackInfo()
644*
645* Description - This function dumps the all Queue(PackInfo[]) details.
646*
647* Parameters - Adapter: Pointer to the Adapter structure.
648*
649* Returns - None.
650*******************************************************************/
Kevin McKinney7a15b792012-10-18 22:40:08 -0400651void DumpPackInfo(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700652{
Kevin McKinney9ef07602012-10-18 22:40:12 -0400653 unsigned int uiLoopIndex = 0;
654 unsigned int uiIndex = 0;
655 unsigned int uiClsfrIndex = 0;
Kevin McKinney92562ae2012-05-26 12:05:03 -0400656 struct bcm_classifier_rule *pstClassifierEntry = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700657
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400658 for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
659 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "*********** Showing Details Of Queue %d***** ******", uiLoopIndex);
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700660 if (false == Adapter->PackInfo[uiLoopIndex].bValid) {
661 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is false for %X index\n", uiLoopIndex);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700662 continue;
663 }
664
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400665 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " Dumping SF Rule Entry For SFID %lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID);
666 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " ucDirection %X\n", Adapter->PackInfo[uiLoopIndex].ucDirection);
667
668 if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
669 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv6 Service Flow\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700670 else
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400671 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv4 Service Flow\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700672
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400673 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SF Traffic Priority %X\n", Adapter->PackInfo[uiLoopIndex].u8TrafficPriority);
674
675 for (uiClsfrIndex = 0; uiClsfrIndex < MAX_CLASSIFIERS; uiClsfrIndex++) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700676 pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex];
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400677 if (!pstClassifierEntry->bUsed)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700678 continue;
679
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400680 if (pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700681 continue;
682
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400683 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);
684 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);
685 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);
686 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);
687 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);
688 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);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700689
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400690 for (uiIndex = 0; uiIndex < MAX_PORT_RANGE; uiIndex++) {
691 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeLo:%X\n", pstClassifierEntry->usSrcPortRangeLo[uiIndex]);
692 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeHi:%X\n", pstClassifierEntry->usSrcPortRangeHi[uiIndex]);
693 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeLo:%X\n", pstClassifierEntry->usDestPortRangeLo[uiIndex]);
694 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeHi:%X\n", pstClassifierEntry->usDestPortRangeHi[uiIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700695 }
696
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400697 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPSourceAddressLength : 0x%x\n", pstClassifierEntry->ucIPSourceAddressLength);
698 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPDestinationAddressLength : 0x%x\n", pstClassifierEntry->ucIPDestinationAddressLength);
699 for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPSourceAddressLength; uiIndex++) {
700 if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) {
701 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpAddr :\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700702 DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400703 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpMask :\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700704 DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400705 } else {
706 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpAddr:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]);
707 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpMask:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700708 }
709 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400710
711 for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPDestinationAddressLength; uiIndex++) {
712 if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) {
713 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpAddr :\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700714 DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400715 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpMask :\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700716 DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400717 } else {
718 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpAddr:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]);
719 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpMask:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700720 }
721 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400722 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucProtocol:0x%X\n", pstClassifierEntry->ucProtocol[0]);
723 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tu8ClassifierRulePriority:%X\n", pstClassifierEntry->u8ClassifierRulePriority);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700724 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400725 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ulSFID:%lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID);
726 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "usVCID_Value:%X\n", Adapter->PackInfo[uiLoopIndex].usVCID_Value);
727 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "PhsEnabled: 0x%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
728 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThreshold:%X\n", Adapter->PackInfo[uiLoopIndex].uiThreshold);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700729
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400730 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid:%X\n", Adapter->PackInfo[uiLoopIndex].bValid);
731 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bActive:%X\n", Adapter->PackInfo[uiLoopIndex].bActive);
732 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent);
733 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "u8QueueType:%X\n", Adapter->PackInfo[uiLoopIndex].u8QueueType);
734 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxBucketSize:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize);
735 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPerSFTxResourceCount:%X\n", atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount));
736 /* DumpDebug(DUMP_INFO,("bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); */
737 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget);
738 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentBytesOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost);
739 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentPacketsOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost);
740 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes);
741 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets);
742 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentBytes);
743 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentPackets);
744 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentDrainRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate);
745 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThisPeriodSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes);
746 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liDrainCalculated:%llX\n", Adapter->PackInfo[uiLoopIndex].liDrainCalculated);
747 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentTokenCount:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount);
748 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liLastUpdateTokenAt:%llX\n", Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt);
749 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxAllowedRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate);
750 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPendedLast:%X\n", Adapter->PackInfo[uiLoopIndex].uiPendedLast);
751 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "NumOfPacketsSent:%X\n", Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent);
752 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection);
753 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID);
754 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid);
755 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid);
756 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid);
757 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid);
758 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet);
759 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet);
760 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet);
761 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority);
762 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency);
Andy Shevchenkobcb6ef62012-08-02 19:05:44 +0300763 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO,
764 DBG_LVL_ALL, "ServiceClassName: %*ph\n",
765 4, Adapter->PackInfo[uiLoopIndex].
766 ucServiceClassName);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400767/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
768 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes);
769 * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes);
770 * DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount));
771 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700772 }
773
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400774 for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++)
775 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aRxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aRxPktSizeHist[uiLoopIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700776
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400777 for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++)
778 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aTxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aTxPktSizeHist[uiLoopIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700779
780 return;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700781}
782
Kevin McKinney29794602012-05-26 12:05:12 -0400783int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700784{
785 int retval = STATUS_SUCCESS;
Kevin McKinney29794602012-05-26 12:05:12 -0400786 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400787 struct bcm_interface_adapter *psIntfAdapter = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700788 unsigned int value = 0, uiResetValue = 0;
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500789 int bytes;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700790
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400791 psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter));
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700792 ps_adapter->bDDRInitDone = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700793
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400794 if (ps_adapter->chip_id >= T3LPB) {
795 /* SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before */
796 rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
797 rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700798
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400799 /* making bit[6...5] same as was before f/w download. this setting force the h/w to */
800 /* re-populated the SP RAM area with the string descriptor. */
801 value = value | (ps_adapter->syscfgBefFwDld & 0x00000060);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700802 wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
803 }
804
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400805 /* killing all submitted URBs. */
806 psIntfAdapter->psAdapter->StopAllXaction = TRUE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700807 Bcm_kill_all_URBs(psIntfAdapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700808 /* Reset the UMA-B Device */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400809 if (ps_adapter->chip_id >= T3LPB) {
Masanari Iida73e29182012-04-06 23:33:52 +0900810 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700811 retval = usb_reset_device(psIntfAdapter->udev);
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700812 psIntfAdapter->psAdapter->StopAllXaction = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700813
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400814 if (retval != STATUS_SUCCESS) {
815 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700816 goto err_exit;
817 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400818
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700819 if (ps_adapter->chip_id == BCS220_2 ||
820 ps_adapter->chip_id == BCS220_2BC ||
821 ps_adapter->chip_id == BCS250_BC ||
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400822 ps_adapter->chip_id == BCS220_3) {
823
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500824 bytes = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
825 if (bytes < 0) {
826 retval = bytes;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400827 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700828 goto err_exit;
829 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400830 /* setting 0th bit */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700831 value |= (1<<0);
832 retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400833 if (retval < 0) {
834 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700835 goto err_exit;
836 }
837 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400838 } else {
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500839 bytes = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value));
840 if (bytes < 0) {
841 retval = bytes;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400842 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700843 goto err_exit;
844 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400845 value &= (~(1<<16));
846 retval = wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value));
847 if (retval < 0) {
848 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700849 goto err_exit;
850 }
851
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400852 /* Toggling the GPIO 8, 9 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700853 value = 0;
854 retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400855 if (retval < 0) {
856 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700857 goto err_exit;
858 }
859 value = 0x300;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400860 retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value));
861 if (retval < 0) {
862 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700863 goto err_exit;
864 }
865 mdelay(50);
866 }
867
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400868 /* ps_adapter->downloadDDR = false; */
869 if (ps_adapter->bFlashBoot) {
870 /* In flash boot mode MIPS state register has reverse polarity.
871 * So just or with setting bit 30.
872 * Make the MIPS in Reset state.
873 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700874 rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400875 uiResetValue |= (1<<30);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700876 wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));
877 }
878
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400879 if (ps_adapter->chip_id >= T3LPB) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700880 uiResetValue = 0;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400881 /*
882 * WA for SYSConfig Issue.
883 * Read SYSCFG Twice to make it writable.
884 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700885 rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400886 if (uiResetValue & (1<<4)) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700887 uiResetValue = 0;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400888 rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); /* 2nd read to make it writable. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700889 uiResetValue &= (~(1<<4));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400890 wrmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700891 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700892 }
893 uiResetValue = 0;
894 wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue));
895
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400896err_exit:
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700897 psIntfAdapter->psAdapter->StopAllXaction = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700898 return retval;
899}
900
Kevin McKinney29794602012-05-26 12:05:12 -0400901int run_card_proc(struct bcm_mini_adapter *ps_adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700902{
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500903 int status = STATUS_SUCCESS;
904 int bytes;
905
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400906 unsigned int value = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700907 {
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500908 bytes = rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value));
909 if (bytes < 0) {
910 status = bytes;
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -0400911 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__);
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500912 return status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700913 }
914
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400915 if (ps_adapter->bFlashBoot)
916 value &= (~(1<<30));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700917 else
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400918 value |= (1<<30);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700919
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400920 if (wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
Kevin McKinneya8a1cdd2011-10-07 18:50:10 -0400921 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700922 return STATUS_FAILURE;
923 }
924 }
Kevin McKinney41c7b7c2011-11-06 09:40:11 -0500925 return status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700926}
927
Kevin McKinney29794602012-05-26 12:05:12 -0400928int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700929{
Dan Carpenter2e316132010-11-13 11:24:22 +0300930 int status;
Kevin McKinney9ef07602012-10-18 22:40:12 -0400931 unsigned int value = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700932 /*
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400933 * Create the threads first and then download the
934 * Firm/DDR Settings..
935 */
Stephen Hemminger2d087482010-11-01 12:14:01 -0400936 status = create_worker_threads(ps_adapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400937 if (status < 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700938 return status;
Stephen Hemminger2d087482010-11-01 12:14:01 -0400939
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400940 status = bcm_parse_target_params(ps_adapter);
941 if (status)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700942 return status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700943
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400944 if (ps_adapter->chip_id >= T3LPB) {
945 rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
946 ps_adapter->syscfgBefFwDld = value;
947
948 if ((value & 0x60) == 0)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700949 ps_adapter->bFlashBoot = TRUE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700950 }
951
952 reset_card_proc(ps_adapter);
953
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400954 /* Initializing the NVM. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700955 BcmInitNVM(ps_adapter);
956 status = ddr_init(ps_adapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400957 if (status) {
Stephen Hemminger2d087482010-11-01 12:14:01 -0400958 pr_err(DRV_NAME "ddr_init Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700959 return status;
960 }
961
962 /* Download cfg file */
963 status = buffDnldVerify(ps_adapter,
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400964 (PUCHAR)ps_adapter->pstargetparams,
Kevin McKinneyc8182332012-12-17 17:35:20 -0500965 sizeof(struct bcm_target_params),
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400966 CONFIG_BEGIN_ADDR);
967 if (status) {
968 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700969 goto OUT;
970 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700971
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400972 if (register_networkdev(ps_adapter)) {
973 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700974 return -EIO;
975 }
976
Lisa Nguyenf70c8a92013-10-28 01:36:19 -0700977 if (false == ps_adapter->AutoFirmDld) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400978 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n");
979 /* If Auto f/w download is disable, register the control interface, */
980 /* register the control interface after the mailbox. */
981 if (register_control_device_interface(ps_adapter) < 0) {
982 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700983 return -EIO;
984 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700985 return STATUS_SUCCESS;
986 }
987
988 /*
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400989 * Do the LED Settings here. It will be used by the Firmware Download
990 * Thread.
991 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700992
993 /*
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400994 * 1. If the LED Settings fails, do not stop and do the Firmware download.
995 * 2. This init would happened only if the cfg file is present, else
996 * call from the ioctl context.
997 */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700998
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -0400999 status = InitLedSettings(ps_adapter);
1000 if (status) {
1001 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "INIT LED FAILED\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001002 return status;
1003 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001004
1005 if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001006 ps_adapter->DriverState = DRIVER_INIT;
1007 wake_up(&ps_adapter->LEDInfo.notify_led_event);
1008 }
1009
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001010 if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001011 ps_adapter->DriverState = FW_DOWNLOAD;
1012 wake_up(&ps_adapter->LEDInfo.notify_led_event);
1013 }
1014
1015 value = 0;
1016 wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1017 wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1018
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001019 if (ps_adapter->eNVMType == NVM_FLASH) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001020 status = PropagateCalParamsFromFlashToMemory(ps_adapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001021 if (status) {
1022 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Propagation of Cal param failed ..");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001023 goto OUT;
1024 }
1025 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001026
1027 /* Download Firmare */
Kevin McKinneyd4910612011-10-07 18:50:12 -04001028 status = BcmFileDownload(ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR);
1029 if (status != 0) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001030 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present...\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001031 goto OUT;
1032 }
1033
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001034 status = run_card_proc(ps_adapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001035 if (status) {
1036 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001037 goto OUT;
1038 }
1039
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001040 ps_adapter->fw_download_done = TRUE;
1041 mdelay(10);
1042
1043OUT:
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001044 if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001045 ps_adapter->DriverState = FW_DOWNLOAD_DONE;
1046 wake_up(&ps_adapter->LEDInfo.notify_led_event);
1047 }
1048
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001049 return status;
1050}
1051
Kevin McKinney29794602012-05-26 12:05:12 -04001052static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001053{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001054 struct file *flp = NULL;
Jesper Juhl3701bef2010-11-10 21:31:38 +01001055 char *buff;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001056 int len = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001057
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001058 buff = kmalloc(BUFFER_1K, GFP_KERNEL);
1059 if (!buff)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001060 return -ENOMEM;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001061
Kevin McKinneyc8182332012-12-17 17:35:20 -05001062 Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
Kevin McKinney9d4f1d02011-10-07 18:50:11 -04001063 if (Adapter->pstargetparams == NULL) {
Stephen Hemminger082e8892010-11-01 09:35:21 -04001064 kfree(buff);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001065 return -ENOMEM;
1066 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001067
1068 flp = open_firmware_file(Adapter, CFG_FILE);
1069 if (!flp) {
1070 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE\n", CFG_FILE);
Stephen Hemminger082e8892010-11-01 09:35:21 -04001071 kfree(buff);
1072 kfree(Adapter->pstargetparams);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001073 Adapter->pstargetparams = NULL;
1074 return -ENOENT;
1075 }
Al Viro32aecdd2012-07-22 21:02:01 +04001076 len = kernel_read(flp, 0, buff, BUFFER_1K);
1077 filp_close(flp, NULL);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001078
Kevin McKinneyc8182332012-12-17 17:35:20 -05001079 if (len != sizeof(struct bcm_target_params)) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001080 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n");
Stephen Hemminger082e8892010-11-01 09:35:21 -04001081 kfree(buff);
1082 kfree(Adapter->pstargetparams);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001083 Adapter->pstargetparams = NULL;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001084 return -ENOENT;
1085 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001086
1087 /* Check for autolink in config params */
1088 /*
1089 * Values in Adapter->pstargetparams are in network byte order
1090 */
Kevin McKinneyc8182332012-12-17 17:35:20 -05001091 memcpy(Adapter->pstargetparams, buff, sizeof(struct bcm_target_params));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001092 kfree(buff);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001093 beceem_parse_target_struct(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001094 return STATUS_SUCCESS;
1095}
1096
Kevin McKinney29794602012-05-26 12:05:12 -04001097void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001098{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001099 unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001100
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001101 if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) {
Stephen Hemminger2d087482010-11-01 12:14:01 -04001102 pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001103 Adapter->AutoSyncup = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001104 } else {
Stephen Hemminger2d087482010-11-01 12:14:01 -04001105 pr_info(DRV_NAME ": AutoSyncup is Enabled\n");
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001106 Adapter->AutoSyncup = TRUE;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001107 }
Stephen Hemminger2d087482010-11-01 12:14:01 -04001108
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001109 if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) {
Stephen Hemminger2d087482010-11-01 12:14:01 -04001110 pr_info(DRV_NAME ": Enabling autolink up");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001111 Adapter->AutoLinkUp = TRUE;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001112 } else {
Stephen Hemminger2d087482010-11-01 12:14:01 -04001113 pr_info(DRV_NAME ": Disabling autolink up");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001114 Adapter->AutoLinkUp = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001115 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001116 /* Setting the DDR Setting.. */
1117 Adapter->DDRSetting = (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >> 8)&0x0F;
1118 Adapter->ulPowerSaveMode = (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
Stephen Hemminger2d087482010-11-01 12:14:01 -04001119 pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting);
1120 pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001121 if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) {
1122 pr_info(DRV_NAME ": Enabling Auto Firmware Download\n");
1123 Adapter->AutoFirmDld = TRUE;
1124 } else {
1125 pr_info(DRV_NAME ": Disabling Auto Firmware Download\n");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001126 Adapter->AutoFirmDld = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001127 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001128 uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
1129 Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001130 pr_info(DRV_NAME ": MIPSConfig : 0x%X\n", Adapter->bMipsConfig);
1131 /* used for backward compatibility. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001132 Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001133 Adapter->PmuMode = (uiHostDrvrCfg6 >> 24) & 0x03;
Stephen Hemminger2d087482010-11-01 12:14:01 -04001134 pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001135
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001136 if ((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT) & (0x01)) {
1137 Adapter->bDoSuspend = TRUE;
1138 pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile");
1139 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001140
1141 uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001142 pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n", uiEEPROMFlag);
Kevin McKinneyaf72c612012-12-21 15:10:36 -05001143 Adapter->eNVMType = (enum bcm_nvm_type)((uiEEPROMFlag>>4)&0x3);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001144 Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001145 Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001146 Adapter->bSectorSizeOverride = (bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001147
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001148 if (ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x01)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001149 Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
Stephen Hemminger2d087482010-11-01 12:14:01 -04001150
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001151 if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001152 doPowerAutoCorrection(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001153}
1154
Kevin McKinney7a15b792012-10-18 22:40:08 -04001155static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001156{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001157 unsigned int reporting_mode;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001158
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001159 reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001160 psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
1161
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001162 if (reporting_mode == TRUE) {
1163 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001164 psAdapter->bDoSuspend = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001165 }
1166
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001167 if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) {
1168 /* If reporting mode is enable, switch PMU to PMC */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001169 {
1170 psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001171 psAdapter->bDoSuspend = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001172 }
1173
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001174 /* clearing space bit[15..12] */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001175 psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12)));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001176 /* placing the power save mode option */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001177 psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12));
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001178 } else if (psAdapter->bIsAutoCorrectEnabled == false) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001179 /* remove the autocorrect disable bit set before dumping. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001180 psAdapter->ulPowerSaveMode &= ~(1 << 3);
1181 psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001182 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001183 }
1184}
Arnd Bergmann44a17eff2010-09-30 10:24:12 +02001185
Kevin McKinney9ef07602012-10-18 22:40:12 -04001186static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001187{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001188 unsigned int uiIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001189
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001190 if (RWM_WRITE == rwFlag) {
Kevin McKinney9ef07602012-10-18 22:40:12 -04001191 for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001192 puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001193 } else {
Kevin McKinney9ef07602012-10-18 22:40:12 -04001194 for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001195 puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001196 }
1197}
1198
Kevin McKinney9ef07602012-10-18 22:40:12 -04001199int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001200{
Greg Dietschec5274ab2011-06-13 13:11:47 -05001201 return Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001202 uiAddress, pucBuff, sSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001203}
Greg Dietschec5274ab2011-06-13 13:11:47 -05001204
Kevin McKinney9ef07602012-10-18 22:40:12 -04001205int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001206{
1207 int iRetVal;
1208
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001209 iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001210 uiAddress, pucBuff, sSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001211 return iRetVal;
1212}
1213
Kevin McKinney9ef07602012-10-18 22:40:12 -04001214int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001215{
1216 convertEndian(RWM_WRITE, pucBuff, size);
1217 return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
1218}
1219
Kevin McKinney9ef07602012-10-18 22:40:12 -04001220int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001221{
Kevin McKinney7af141342012-10-18 22:40:13 -04001222 int uiRetVal = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001223
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001224 uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
Kevin McKinneyb23f7f62012-10-18 22:40:09 -04001225 convertEndian(RWM_READ, (unsigned int *)pucBuff, size);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001226
1227 return uiRetVal;
1228}
1229
Kevin McKinney9ef07602012-10-18 22:40:12 -04001230int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001231{
Kevin McKinney7af141342012-10-18 22:40:13 -04001232 int status = STATUS_SUCCESS;
Robin Schroerfe830732014-06-16 13:01:46 +02001233
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001234 down(&Adapter->rdmwrmsync);
1235
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001236 if ((Adapter->IdleMode == TRUE) ||
1237 (Adapter->bShutStatus == TRUE) ||
1238 (Adapter->bPreparingForLowPowerMode == TRUE)) {
1239
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001240 status = -EACCES;
1241 goto exit;
1242 }
1243
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001244 status = wrm(Adapter, uiAddress, pucBuff, sSize);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001245exit:
1246 up(&Adapter->rdmwrmsync);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001247 return status;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001248}
1249
Kevin McKinney9ef07602012-10-18 22:40:12 -04001250int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001251{
1252 int iRetVal = STATUS_SUCCESS;
1253
1254 down(&Adapter->rdmwrmsync);
1255
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001256 if ((Adapter->IdleMode == TRUE) ||
1257 (Adapter->bShutStatus == TRUE) ||
1258 (Adapter->bPreparingForLowPowerMode == TRUE)) {
1259
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001260 iRetVal = -EACCES;
1261 goto exit;
1262 }
1263
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001264 iRetVal = wrmalt(Adapter, uiAddress, pucBuff, size);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001265exit:
1266 up(&Adapter->rdmwrmsync);
1267 return iRetVal;
1268}
1269
Kevin McKinney9ef07602012-10-18 22:40:12 -04001270int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001271{
Kevin McKinney7af141342012-10-18 22:40:13 -04001272 int uiRetVal = STATUS_SUCCESS;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001273
1274 down(&Adapter->rdmwrmsync);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001275 if ((Adapter->IdleMode == TRUE) ||
1276 (Adapter->bShutStatus == TRUE) ||
1277 (Adapter->bPreparingForLowPowerMode == TRUE)) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001278
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001279 uiRetVal = -EACCES;
1280 goto exit;
1281 }
1282
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001283 uiRetVal = rdmalt(Adapter, uiAddress, pucBuff, size);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001284exit:
1285 up(&Adapter->rdmwrmsync);
1286 return uiRetVal;
1287}
1288
Kevin McKinney7a15b792012-10-18 22:40:08 -04001289static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001290{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001291 int clear_abort_pattern = 0, Status = 0;
Robin Schroerfe830732014-06-16 13:01:46 +02001292
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001293 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
1294 /* target has woken up From Shut Down */
1295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
Kevin McKinneyb23f7f62012-10-18 22:40:09 -04001296 Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001297 if (Status) {
1298 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001299 return;
1300 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001301
1302 if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001303 msleep(100);
1304 InterfaceHandleShutdownModeWakeup(Adapter);
1305 msleep(100);
1306 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001307
1308 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001309 Adapter->DriverState = NO_NETWORK_ENTRY;
1310 wake_up(&Adapter->LEDInfo.notify_led_event);
1311 }
1312
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001313 Adapter->bTriedToWakeUpFromlowPowerMode = false;
1314 Adapter->bShutStatus = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001315 wake_up(&Adapter->lowpower_mode_wait_queue);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001317}
1318
Kevin McKinney7a15b792012-10-18 22:40:08 -04001319static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001320{
Kevin McKinney2610c7a2012-05-26 12:05:08 -04001321 struct bcm_link_request stShutdownResponse;
Kevin McKinney9ef07602012-10-18 22:40:12 -04001322 unsigned int NVMAccess = 0, lowPwrAbortMsg = 0;
1323 unsigned int Status = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001324
Kevin McKinney2610c7a2012-05-26 12:05:08 -04001325 memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001326 stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001327 stShutdownResponse.Leader.PLength = 8; /* 8 bytes; */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001328 stShutdownResponse.szData[0] = LINK_UP_ACK;
1329 stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE;
1330
1331 /*********************************
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001332 * down_trylock -
1333 * if [ semaphore is available ]
1334 * acquire semaphone and return value 0 ;
1335 * else
1336 * return non-zero value ;
1337 *
1338 ***********************************/
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001339
1340 NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001341 lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001342
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001343 if (NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) {
1344 if (!NVMAccess)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001345 up(&Adapter->NVMRdmWrmLock);
1346
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001347 if (!lowPwrAbortMsg)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001348 up(&Adapter->LowPowerModeSync);
1349
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001350 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n");
1351 stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001352 Adapter->bPreparingForLowPowerMode = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001353 } else {
1354 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n");
1355 stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER; /* ShutDown ACK */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001356
1357 /* Wait for the LED to TURN OFF before sending ACK response */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001358 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
Kevin McKinney7af141342012-10-18 22:40:13 -04001359 int iRetVal = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001360
1361 /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */
1362 Adapter->DriverState = LOWPOWER_MODE_ENTER;
1363 wake_up(&Adapter->LEDInfo.notify_led_event);
1364
1365 /* Wait for 1 SEC for LED to OFF */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001366 iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001367
1368 /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001369 if (iRetVal <= 0) {
1370 stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001371 Adapter->DriverState = NO_NETWORK_ENTRY;
1372 wake_up(&Adapter->LEDInfo.notify_led_event);
1373 }
1374 }
1375
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001376 if (stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) {
1377 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ACKING SHUTDOWN MODE !!!!!!!!!");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001378 down(&Adapter->rdmwrmsync);
1379 Adapter->bPreparingForLowPowerMode = TRUE;
1380 up(&Adapter->rdmwrmsync);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001381 /* Killing all URBS. */
1382 if (Adapter->bDoSuspend == TRUE)
Kevin McKinneyd6861cf2012-11-01 23:42:21 -04001383 Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001384 } else {
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001385 Adapter->bPreparingForLowPowerMode = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001386 }
1387
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001388 if (!NVMAccess)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001389 up(&Adapter->NVMRdmWrmLock);
1390
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001391 if (!lowPwrAbortMsg)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001392 up(&Adapter->LowPowerModeSync);
1393 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001394
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001395 Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse);
Robin Schroer28c520a2014-06-16 13:01:47 +02001396 if (Status != STATUS_SUCCESS) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001397 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n");
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001398 Adapter->bPreparingForLowPowerMode = false;
Kevin McKinneyd6861cf2012-11-01 23:42:21 -04001399 StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001400 }
1401}
1402
Kevin McKinney29794602012-05-26 12:05:12 -04001403static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001404{
Kevin McKinney70522082012-10-18 22:40:11 -04001405 unsigned int uiResetValue = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001406
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001407 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001408
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001409 if (*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001410 HandleShutDownModeWakeup(Adapter);
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001411 } else if (*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) {
1412 /* Target wants to go to Shut Down Mode */
1413 /* InterfacePrepareForShutdown(Adapter); */
1414 if (Adapter->chip_id == BCS220_2 ||
1415 Adapter->chip_id == BCS220_2BC ||
1416 Adapter->chip_id == BCS250_BC ||
1417 Adapter->chip_id == BCS220_3) {
1418
1419 rdmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001420 uiResetValue |= (1<<17);
1421 wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4);
1422 }
1423
1424 SendShutModeResponse(Adapter);
Kevin McKinney7af141342012-10-18 22:40:13 -04001425 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001426 }
1427
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001428 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001429 return;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001430}
1431
Kevin McKinney7a15b792012-10-18 22:40:08 -04001432void ResetCounters(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001433{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001434 beceem_protocol_reset(Adapter);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001435 Adapter->CurrNumRecvDescs = 0;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001436 Adapter->PrevNumRecvDescs = 0;
1437 Adapter->LinkUpStatus = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001438 Adapter->LinkStatus = 0;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001439 atomic_set(&Adapter->cntrlpktCnt, 0);
1440 atomic_set(&Adapter->TotalPacketCount, 0);
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001441 Adapter->fw_download_done = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001442 Adapter->LinkStatus = 0;
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001443 Adapter->AutoLinkUp = false;
1444 Adapter->IdleMode = false;
1445 Adapter->bShutStatus = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001446}
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001447
Kevin McKinney29794602012-05-26 12:05:12 -04001448struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001449{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001450 unsigned int uiIndex = 0;
Robin Schroerfe830732014-06-16 13:01:46 +02001451
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001452 for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
1453 if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
1454 (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
1455 (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIP) &&
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001456 !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment)
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001457
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001458 return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry;
1459 }
1460 return NULL;
1461}
1462
Kevin McKinney29794602012-05-26 12:05:12 -04001463void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001464{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001465 unsigned int uiIndex = 0;
Robin Schroerfe830732014-06-16 13:01:46 +02001466
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001467 for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
1468 if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) {
Kevin McKinney7f224852012-05-26 12:05:02 -04001469 memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001470 break;
1471 }
1472 }
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001473}
1474
Kevin McKinney29794602012-05-26 12:05:12 -04001475void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001476{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001477 unsigned int uiIndex = 0;
Robin Schroerfe830732014-06-16 13:01:46 +02001478
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001479 for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
1480 if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
1481 (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
1482 (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIp))
1483
Kevin McKinney7f224852012-05-26 12:05:02 -04001484 memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(struct bcm_fragmented_packet_info));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001485 }
1486}
1487
Kevin McKinney29794602012-05-26 12:05:12 -04001488void update_per_cid_rx(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001489{
Kevin McKinney9ef07602012-10-18 22:40:12 -04001490 unsigned int qindex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001491
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001492 if ((jiffies - Adapter->liDrainCalculated) < XSECONDS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001493 return;
1494
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001495 for (qindex = 0; qindex < HiPriority; qindex++) {
1496 if (Adapter->PackInfo[qindex].ucDirection == 0) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001497 Adapter->PackInfo[qindex].uiCurrentRxRate =
1498 (Adapter->PackInfo[qindex].uiCurrentRxRate +
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001499 Adapter->PackInfo[qindex].uiThisPeriodRxBytes) / 2;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001500
1501 Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001502 } else {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001503 Adapter->PackInfo[qindex].uiCurrentDrainRate =
1504 (Adapter->PackInfo[qindex].uiCurrentDrainRate +
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001505 Adapter->PackInfo[qindex].uiThisPeriodSentBytes) / 2;
1506 Adapter->PackInfo[qindex].uiThisPeriodSentBytes = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001507 }
1508 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001509 Adapter->liDrainCalculated = jiffies;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001510}
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001511
Kevin McKinney29794602012-05-26 12:05:12 -04001512void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001513{
Kevin McKinney7af141342012-10-18 22:40:13 -04001514 int iIndex = 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001515 u32 uibuff[MAX_TARGET_DSX_BUFFERS];
Kevin McKinney41c7b7c2011-11-06 09:40:11 -05001516 int bytes;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001517
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001518 if (!atomic_read(&Adapter->uiMBupdate))
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001519 return;
1520
Kevin McKinney9ef07602012-10-18 22:40:12 -04001521 bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS);
Kevin McKinney41c7b7c2011-11-06 09:40:11 -05001522 if (bytes < 0) {
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001523 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001524 return;
1525 }
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001526
1527 for (iIndex = 0; iIndex < HiPriority; iIndex++) {
1528 if (Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) {
1529 if (Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001530 atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001531 else
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001532 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x\n", Adapter->PackInfo[iIndex].usVCID_Value);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001533 }
1534 }
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001535 atomic_set(&Adapter->uiMBupdate, false);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001536}
1537
Kevin McKinney9ef07602012-10-18 22:40:12 -04001538void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001539{
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001540 struct sk_buff *PacketToDrop = NULL;
1541 struct net_device_stats *netstats = &Adapter->dev->stats;
Robin Schroerfe830732014-06-16 13:01:46 +02001542
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001543 spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
1544
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001545 while (Adapter->PackInfo[iQIndex].FirstTxQueue && atomic_read(&Adapter->TotalPacketCount)) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001546 PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001547 if (PacketToDrop && PacketToDrop->len) {
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001548 netstats->tx_dropped++;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001549 DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, Adapter->PackInfo[iQIndex].LastTxQueue);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001550 Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--;
1551 Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len;
1552
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001553 /* Adding dropped statistics */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001554 Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
1555 Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
Stephen Hemminger082e8892010-11-01 09:35:21 -04001556 dev_kfree_skb(PacketToDrop);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001557 atomic_dec(&Adapter->TotalPacketCount);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001558 }
1559 }
1560 spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001561}
1562
Kevin McKinney29794602012-05-26 12:05:12 -04001563static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001564{
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -04001565 int i;
Robin Schroerfe830732014-06-16 13:01:46 +02001566
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -04001567 if (netif_msg_link(Adapter))
Stephen Hemminger9ec44752010-11-01 12:18:36 -04001568 pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -04001569
1570 netif_carrier_off(Adapter->dev);
1571 netif_stop_queue(Adapter->dev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001572
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001573 Adapter->IdleMode = false;
1574 Adapter->LinkUpStatus = false;
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001575 ClearTargetDSXBuffer(Adapter, 0, TRUE);
1576 /* Delete All Classifier Rules */
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001577
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001578 for (i = 0; i < HiPriority; i++)
1579 DeleteAllClassifiersForSF(Adapter, i);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001580
1581 flush_all_queues(Adapter);
1582
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001583 if (Adapter->TimerActive == TRUE)
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07001584 Adapter->TimerActive = false;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001585
Kevin McKinney7f224852012-05-26 12:05:02 -04001586 memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(struct bcm_fragmented_packet_info) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001587
Kevin McKinney6a4ef5f2011-10-07 18:50:09 -04001588 for (i = 0; i < HiPriority; i++) {
1589 /* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */
1590 /* It is same between MIBs and SF. */
Kevin McKinney8c7d51a2012-11-25 19:28:59 -05001591 memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(struct bcm_mibs_parameters));
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001592 }
1593}