Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: chromeos/drivers/ath6kl/htc2/htc.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/drivers/ath6kl/htc2/AR6000/makefile ('k') | chromeos/drivers/ath6kl/htc2/htc_debug.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------
2 // <copyright file="htc.c" company="Atheros">
3 // Copyright (c) 2007-2008 Atheros Corporation. All rights reserved.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // Software distributed under the License is distributed on an "AS
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 // implied. See the License for the specific language governing
12 // rights and limitations under the License.
13 //
14 //
15 //------------------------------------------------------------------------------
16 //==============================================================================
17 // Author(s): ="Atheros"
18 //==============================================================================
19 #include "htc_internal.h"
20
21 #ifdef DEBUG
22 static ATH_DEBUG_MASK_DESCRIPTION g_HTCDebugDescription[] = {
23 { ATH_DEBUG_SEND , "Send"},
24 { ATH_DEBUG_RECV , "Recv"},
25 { ATH_DEBUG_SYNC , "Sync"},
26 { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"},
27 { ATH_DEBUG_IRQ , "Interrupt Processing"}
28 };
29
30 ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
31 "htc",
32 "Host Target Communications",
33 ATH_DEBUG_MASK_DEFAULTS,
34 ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescripti on),
35 g_HTCDebugDescription);
36
37 #endif
38
39 static void HTCReportFailure(void *Context);
40 static void ResetEndpointStates(HTC_TARGET *target);
41
42 void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QU EUE *pList)
43 {
44 LOCK_HTC(target);
45 HTC_PACKET_ENQUEUE(pList,pPacket);
46 UNLOCK_HTC(target);
47 }
48
49 HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList)
50 {
51 HTC_PACKET *pPacket;
52
53 LOCK_HTC(target);
54 pPacket = HTC_PACKET_DEQUEUE(pList);
55 UNLOCK_HTC(target);
56
57 return pPacket;
58 }
59
60 /* cleanup the HTC instance */
61 static void HTCCleanup(HTC_TARGET *target)
62 {
63 A_INT32 i;
64
65 DevCleanup(&target->Device);
66
67 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
68 if (target->HTCControlBuffers[i].Buffer) {
69 A_FREE(target->HTCControlBuffers[i].Buffer);
70 }
71 }
72
73 if (A_IS_MUTEX_VALID(&target->HTCLock)) {
74 A_MUTEX_DELETE(&target->HTCLock);
75 }
76
77 if (A_IS_MUTEX_VALID(&target->HTCRxLock)) {
78 A_MUTEX_DELETE(&target->HTCRxLock);
79 }
80
81 if (A_IS_MUTEX_VALID(&target->HTCTxLock)) {
82 A_MUTEX_DELETE(&target->HTCTxLock);
83 }
84 /* free our instance */
85 A_FREE(target);
86 }
87
88 /* registered target arrival callback from the HIF layer */
89 HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo)
90 {
91 HTC_TARGET *target = NULL;
92 A_STATUS status = A_OK;
93 int i;
94 A_UINT32 ctrl_bufsz;
95 A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];
96
97 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
98
99 A_REGISTER_MODULE_DEBUG_INFO(htc);
100
101 do {
102
103 /* allocate target memory */
104 if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
105 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
106 status = A_ERROR;
107 break;
108 }
109
110 A_MEMZERO(target, sizeof(HTC_TARGET));
111 A_MUTEX_INIT(&target->HTCLock);
112 A_MUTEX_INIT(&target->HTCRxLock);
113 A_MUTEX_INIT(&target->HTCTxLock);
114 INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
115 INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);
116
117 /* give device layer the hif device handle */
118 target->Device.HIFDevice = hif_handle;
119 /* give the device layer our context (for event processing)
120 * the device layer will register it's own context with HIF
121 * so we need to set this so we can fetch it in the target remove ha ndler */
122 target->Device.HTCContext = target;
123 /* set device layer target failure callback */
124 target->Device.TargetFailureCallback = HTCReportFailure;
125 /* set device layer recv message pending callback */
126 target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
127 target->EpWaitingForBuffers = ENDPOINT_MAX;
128
129 A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
130
131 ResetEndpointStates(target);
132
133 /* setup device layer */
134 status = DevSetup(&target->Device);
135
136 if (A_FAILED(status)) {
137 break;
138 }
139
140
141 /* get the block sizes */
142 status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
143 blocksizes, sizeof(blocksizes));
144 if (A_FAILED(status)) {
145 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from H IF layer...\n"));
146 break;
147 }
148
149 /* Set the control buffer size based on the block size */
150 if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) {
151 ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
152 } else {
153 ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
154 }
155 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
156 target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);
157 if (target->HTCControlBuffers[i].Buffer == NULL) {
158 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
159 status = A_ERROR;
160 break;
161 }
162 }
163
164 if (A_FAILED(status)) {
165 break;
166 }
167
168 /* carve up buffers/packets for control messages */
169 for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
170 HTC_PACKET *pControlPacket;
171 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
172 SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
173 target,
174 target->HTCControlBuffers[i].Buffer,
175 ctrl_bufsz,
176 ENDPOINT_0);
177 HTC_FREE_CONTROL_RX(target,pControlPacket);
178 }
179
180 for (;i < NUM_CONTROL_BUFFERS;i++) {
181 HTC_PACKET *pControlPacket;
182 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
183 INIT_HTC_PACKET_INFO(pControlPacket,
184 target->HTCControlBuffers[i].Buffer,
185 ctrl_bufsz);
186 HTC_FREE_CONTROL_TX(target,pControlPacket);
187 }
188
189 } while (FALSE);
190
191 if (A_FAILED(status)) {
192 if (target != NULL) {
193 HTCCleanup(target);
194 target = NULL;
195 }
196 }
197
198 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
199
200 return target;
201 }
202
203 void HTCDestroy(HTC_HANDLE HTCHandle)
204 {
205 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
206 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%X \n",(A_UIN T32)target));
207 HTCCleanup(target);
208 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
209 }
210
211 /* get the low level HIF device for the caller , the caller may wish to do low l evel
212 * HIF requests */
213 void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
214 {
215 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
216 return target->Device.HIFDevice;
217 }
218
219 /* wait for the target to arrive (sends HTC Ready message)
220 * this operation is fully synchronous and the message is polled for */
221 A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
222 {
223 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
224 A_STATUS status;
225 HTC_PACKET *pPacket = NULL;
226 HTC_READY_EX_MSG *pRdyMsg;
227 HTC_SERVICE_CONNECT_REQ connect;
228 HTC_SERVICE_CONNECT_RESP resp;
229
230 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A _UINT32)target));
231
232 do {
233
234 #ifdef MBOXHW_UNIT_TEST
235
236 status = DoMboxHWTest(&target->Device);
237
238 if (status != A_OK) {
239 break;
240 }
241
242 #endif
243
244 /* we should be getting 1 control message that the target is ready * /
245 status = HTCWaitforControlMessage(target, &pPacket);
246
247 if (A_FAILED(status)) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
249 break;
250 }
251
252 /* we controlled the buffer creation so it has to be properly aligne d */
253 pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer;
254
255 if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) ||
256 (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
257 /* this message is not valid */
258 AR_DEBUG_ASSERT(FALSE);
259 status = A_EPROTO;
260 break;
261 }
262
263
264 if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Inf o.CreditSize == 0) {
265 /* this message is not valid */
266 AR_DEBUG_ASSERT(FALSE);
267 status = A_EPROTO;
268 break;
269 }
270
271 target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount;
272 target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize;
273
274 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size : %d\n",
275 target->TargetCredits, target->TargetCreditSize));
276
277 /* check if this is an extended ready message */
278 if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) {
279 /* this is an extended message */
280 target->HTCTargetVersion = pRdyMsg->HTCVersion;
281 target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle;
282 } else {
283 /* legacy */
284 target->HTCTargetVersion = HTC_VERSION_2P0;
285 target->MaxMsgPerBundle = 0;
286 }
287
288 #ifdef HTC_FORCE_LEGACY_2P0
289 /* for testing and comparison...*/
290 target->HTCTargetVersion = HTC_VERSION_2P0;
291 target->MaxMsgPerBundle = 0;
292 #endif
293
294 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
295 ("Using HTC Protocol Version : %s (%d)\n ",
296 (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
297 target->HTCTargetVersion));
298
299 if (target->MaxMsgPerBundle > 0) {
300 /* limit what HTC can handle */
301 target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->M axMsgPerBundle);
302 /* target supports message bundling, setup device layer */
303 if (A_FAILED(DevSetupMsgBundling(&target->Device,target->MaxMsgPerBu ndle))) {
304 /* device layer can't handle bundling */
305 target->MaxMsgPerBundle = 0;
306 } else {
307 /* limit bundle what the device layer can handle */
308 target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target ->Device),
309 target->MaxMsgPerBundle);
310 }
311 }
312
313 if (target->MaxMsgPerBundle > 0) {
314 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
315 (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", targ et->MaxMsgPerBundle));
316 target->SendBundlingEnabled = TRUE;
317 target->RecvBundlingEnabled = TRUE;
318 if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSi ze)) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not blo ck aligned! Disabling send bundling \n",
320 target->TargetCreditSize));
321 /* disallow send bundling since the credit size is not align ed to a block size
322 * the I/O block padding will spill into the next credit buf fer which is fatal */
323 target->SendBundlingEnabled = FALSE;
324 }
325 }
326
327 /* setup our pseudo HTC control endpoint connection */
328 A_MEMZERO(&connect,sizeof(connect));
329 A_MEMZERO(&resp,sizeof(resp));
330 connect.EpCallbacks.pContext = target;
331 connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
332 connect.EpCallbacks.EpRecv = HTCControlRecv;
333 connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */
334 connect.EpCallbacks.EpSendFull = NULL; /* not nedded */
335 connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
336 connect.ServiceID = HTC_CTRL_RSVD_SVC;
337
338 /* connect fake service */
339 status = HTCConnectService((HTC_HANDLE)target,
340 &connect,
341 &resp);
342
343 if (!A_FAILED(status)) {
344 break;
345 }
346
347 } while (FALSE);
348
349 if (pPacket != NULL) {
350 HTC_FREE_CONTROL_RX(target,pPacket);
351 }
352
353 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));
354
355 return status;
356 }
357
358
359
360 /* Start HTC, enable interrupts and let the target know host has finished setup */
361 A_STATUS HTCStart(HTC_HANDLE HTCHandle)
362 {
363 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
364 HTC_PACKET *pPacket;
365 A_STATUS status;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
368
369 /* make sure interrupts are disabled at the chip level,
370 * this function can be called again from a reboot of the target without shutting down HTC */
371 DevDisableInterrupts(&target->Device);
372 /* make sure state is cleared again */
373 target->OpStateFlags = 0;
374 target->RecvStateFlags = 0;
375
376 /* now that we are starting, push control receive buffers into the
377 * HTC control endpoint */
378
379 while (1) {
380 pPacket = HTC_ALLOC_CONTROL_RX(target);
381 if (NULL == pPacket) {
382 break;
383 }
384 HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
385 }
386
387 do {
388
389 AR_DEBUG_ASSERT(target->InitCredits != NULL);
390 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
391 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);
392
393 /* call init credits callback to do the distribution ,
394 * NOTE: the first entry in the distribution list is ENDPOINT_0, so
395 * we pass the start of the list after this one. */
396 target->InitCredits(target->pCredDistContext,
397 target->EpCreditDistributionListHead->pNext,
398 target->TargetCredits);
399
400 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
401 DumpCreditDistStates(target);
402 }
403
404 /* the caller is done connecting to services, so we can indicate to the
405 * target that the setup phase is complete */
406 status = HTCSendSetupComplete(target);
407
408 if (A_FAILED(status)) {
409 break;
410 }
411
412 /* unmask interrupts */
413 status = DevUnmaskInterrupts(&target->Device);
414
415 if (A_FAILED(status)) {
416 HTCStop(target);
417 }
418
419 } while (FALSE);
420
421 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
422 return status;
423 }
424
425 static void ResetEndpointStates(HTC_TARGET *target)
426 {
427 HTC_ENDPOINT *pEndpoint;
428 int i;
429
430 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
431 pEndpoint = &target->EndPoint[i];
432
433 A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
434 pEndpoint->ServiceID = 0;
435 pEndpoint->MaxMsgLength = 0;
436 pEndpoint->MaxTxQueueDepth = 0;
437 #ifdef HTC_EP_STAT_PROFILING
438 A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
439 #endif
440 INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
441 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
442 INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
443 pEndpoint->target = target;
444 }
445 /* reset distribution list */
446 target->EpCreditDistributionListHead = NULL;
447 }
448
449 /* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
450 void HTCStop(HTC_HANDLE HTCHandle)
451 {
452 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
453 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));
454
455 LOCK_HTC(target);
456 /* mark that we are shutting down .. */
457 target->OpStateFlags |= HTC_OP_STATE_STOPPING;
458 UNLOCK_HTC(target);
459
460 /* Masking interrupts is a synchronous operation, when this function ret urns
461 * all pending HIF I/O has completed, we can safely flush the queues */
462 DevMaskInterrupts(&target->Device);
463
464 /* flush all send packets */
465 HTCFlushSendPkts(target);
466 /* flush all recv buffers */
467 HTCFlushRecvBuffers(target);
468
469 ResetEndpointStates(target);
470
471 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
472 }
473
474 void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
475 {
476 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
477
478 LOCK_HTC_TX(target);
479
480 DumpCreditDistStates(target);
481
482 UNLOCK_HTC_TX(target);
483
484 DumpAR6KDevState(&target->Device);
485 }
486
487 /* report a target failure from the device, this is a callback from the device l ayer
488 * which uses a mechanism to report errors from the target (i.e. special interru pts) */
489 static void HTCReportFailure(void *Context)
490 {
491 HTC_TARGET *target = (HTC_TARGET *)Context;
492
493 target->TargetFailure = TRUE;
494
495 if (target->HTCInitInfo.TargetFailure != NULL) {
496 /* let upper layer know, it needs to call HTCStop() */
497 target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR) ;
498 }
499 }
500
501 A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
502 HTC_ENDPOINT_ID Endpoint,
503 HTC_ENDPOINT_STAT_ACTION Action,
504 HTC_ENDPOINT_STATS *pStats)
505 {
506
507 #ifdef HTC_EP_STAT_PROFILING
508 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
509 A_BOOL clearStats = FALSE;
510 A_BOOL sample = FALSE;
511
512 switch (Action) {
513 case HTC_EP_STAT_SAMPLE :
514 sample = TRUE;
515 break;
516 case HTC_EP_STAT_SAMPLE_AND_CLEAR :
517 sample = TRUE;
518 clearStats = TRUE;
519 break;
520 case HTC_EP_STAT_CLEAR :
521 clearStats = TRUE;
522 break;
523 default:
524 break;
525 }
526
527 A_ASSERT(Endpoint < ENDPOINT_MAX);
528
529 /* lock out TX and RX while we sample and/or clear */
530 LOCK_HTC_TX(target);
531 LOCK_HTC_RX(target);
532
533 if (sample) {
534 A_ASSERT(pStats != NULL);
535 /* return the stats to the caller */
536 A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_E NDPOINT_STATS));
537 }
538
539 if (clearStats) {
540 /* reset stats */
541 A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT _STATS));
542 }
543
544 UNLOCK_HTC_RX(target);
545 UNLOCK_HTC_TX(target);
546
547 return TRUE;
548 #else
549 return FALSE;
550 #endif
551 }
552
553 AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle)
554 {
555 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
556 return &target->Device;
557 }
558
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/htc2/AR6000/makefile ('k') | chromeos/drivers/ath6kl/htc2/htc_debug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698