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

Side by Side Diff: chromeos/drivers/ath6kl/htc2/htc_services.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
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------
2 // <copyright file="htc_services.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 void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket)
22 {
23 /* not implemented
24 * we do not send control TX frames during normal runtime, only during s etup */
25 AR_DEBUG_ASSERT(FALSE);
26 }
27
28 /* callback when a control message arrives on this endpoint */
29 void HTCControlRecv(void *Context, HTC_PACKET *pPacket)
30 {
31 AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);
32
33 if (pPacket->Status == A_ECANCELED) {
34 /* this is a flush operation, return the control packet back to the pool */
35 HTC_FREE_CONTROL_RX((HTC_TARGET*)Context,pPacket);
36 return;
37 }
38
39 /* the only control messages we are expecting are NULL messages (credit resports) */
40 if (pPacket->ActualLength > 0) {
41 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
42 ("HTCControlRecv, got message with length:%d \n",
43 pPacket->ActualLength + HTC_HDR_LENGTH));
44
45 /* dump header and message */
46 DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
47 pPacket->ActualLength + HTC_HDR_LENGTH,
48 "Unexpected ENDPOINT 0 Message");
49 }
50
51 HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->End Point[0]);
52 }
53
54 A_STATUS HTCSendSetupComplete(HTC_TARGET *target)
55 {
56 HTC_PACKET *pSendPacket = NULL;
57 A_STATUS status;
58
59 do {
60 /* allocate a packet to send to the target */
61 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
62
63 if (NULL == pSendPacket) {
64 status = A_NO_MEMORY;
65 break;
66 }
67
68 if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
69 HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
70 A_UINT32 setupFlags = 0;
71
72 pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer ;
73 A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
74 pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;
75 if (target->MaxMsgPerBundle > 0) {
76 /* host can do HTC bundling, indicate this to the target */
77 setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
78 pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundl e;
79 }
80 A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCo mpleteEx->SetupFlags));
81 SET_HTC_PACKET_INFO_TX(pSendPacket,
82 NULL,
83 (A_UINT8 *)pSetupCompleteEx,
84 sizeof(HTC_SETUP_COMPLETE_EX_MSG),
85 ENDPOINT_0,
86 HTC_SERVICE_TX_PACKET_TAG);
87
88 } else {
89 HTC_SETUP_COMPLETE_MSG *pSetupComplete;
90 /* assemble setup complete message */
91 pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
92 A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
93 pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;
94 SET_HTC_PACKET_INFO_TX(pSendPacket,
95 NULL,
96 (A_UINT8 *)pSetupComplete,
97 sizeof(HTC_SETUP_COMPLETE_MSG),
98 ENDPOINT_0,
99 HTC_SERVICE_TX_PACKET_TAG);
100 }
101
102 /* we want synchronous operation */
103 pSendPacket->Completion = NULL;
104 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
105 /* send the message */
106 status = HTCIssueSend(target,pSendPacket);
107
108 } while (FALSE);
109
110 if (pSendPacket != NULL) {
111 HTC_FREE_CONTROL_TX(target,pSendPacket);
112 }
113
114 return status;
115 }
116
117
118 A_STATUS HTCConnectService(HTC_HANDLE HTCHandle,
119 HTC_SERVICE_CONNECT_REQ *pConnectReq,
120 HTC_SERVICE_CONNECT_RESP *pConnectResp)
121 {
122 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
123 A_STATUS status = A_OK;
124 HTC_PACKET *pRecvPacket = NULL;
125 HTC_PACKET *pSendPacket = NULL;
126 HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg;
127 HTC_CONNECT_SERVICE_MSG *pConnectMsg;
128 HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX;
129 HTC_ENDPOINT *pEndpoint;
130 int maxMsgSize = 0;
131
132 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%X SvcID:0x%X \n",
133 (A_UINT32)target, pConnectReq->ServiceID));
134
135 do {
136
137 AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);
138
139 if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
140 /* special case for pseudo control service */
141 assignedEndpoint = ENDPOINT_0;
142 maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
143 } else {
144 /* allocate a packet to send to the target */
145 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
146
147 if (NULL == pSendPacket) {
148 AR_DEBUG_ASSERT(FALSE);
149 status = A_NO_MEMORY;
150 break;
151 }
152 /* assemble connect service message */
153 pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
154 AR_DEBUG_ASSERT(pConnectMsg != NULL);
155 A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
156 pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
157 pConnectMsg->ServiceID = pConnectReq->ServiceID;
158 pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
159 /* check caller if it wants to transfer meta data */
160 if ((pConnectReq->pMetaData != NULL) &&
161 (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH )) {
162 /* copy meta data into message buffer (after header ) */
163 A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG ),
164 pConnectReq->pMetaData,
165 pConnectReq->MetaDataLength);
166 pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
167 }
168
169 SET_HTC_PACKET_INFO_TX(pSendPacket,
170 NULL,
171 (A_UINT8 *)pConnectMsg,
172 sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg ->ServiceMetaLength,
173 ENDPOINT_0,
174 HTC_SERVICE_TX_PACKET_TAG);
175
176 /* we want synchronous operation */
177 pSendPacket->Completion = NULL;
178 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
179 status = HTCIssueSend(target,pSendPacket);
180
181 if (A_FAILED(status)) {
182 break;
183 }
184
185 /* wait for response */
186 status = HTCWaitforControlMessage(target, &pRecvPacket);
187
188 if (A_FAILED(status)) {
189 break;
190 }
191 /* we controlled the buffer creation so it has to be properly al igned */
192 pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuf fer;
193
194 if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
195 (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE _MSG))) {
196 /* this message is not valid */
197 AR_DEBUG_ASSERT(FALSE);
198 status = A_EPROTO;
199 break;
200 }
201
202 pConnectResp->ConnectRespCode = pResponseMsg->Status;
203 /* check response status */
204 if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
205 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
206 (" Target failed service 0x%X connect request (status:%d)\n" ,
207 pResponseMsg->ServiceID, pResponseMsg->Status));
208 status = A_EPROTO;
209 break;
210 }
211
212 assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
213 maxMsgSize = pResponseMsg->MaxMsgSize;
214
215 if ((pConnectResp->pMetaData != NULL) &&
216 (pResponseMsg->ServiceMetaLength > 0) &&
217 (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LE NGTH)) {
218 /* caller supplied a buffer and the target responded with da ta */
219 int copyLength = min((int)pConnectResp->BufferLength, (int)pResp onseMsg->ServiceMetaLength);
220 /* copy the meta data */
221 A_MEMCPY(pConnectResp->pMetaData,
222 ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_ RESPONSE_MSG),
223 copyLength);
224 pConnectResp->ActualLength = copyLength;
225 }
226
227 }
228
229 /* the rest of these are parameter checks so set the error status */
230 status = A_EPROTO;
231
232 if (assignedEndpoint >= ENDPOINT_MAX) {
233 AR_DEBUG_ASSERT(FALSE);
234 break;
235 }
236
237 if (0 == maxMsgSize) {
238 AR_DEBUG_ASSERT(FALSE);
239 break;
240 }
241
242 pEndpoint = &target->EndPoint[assignedEndpoint];
243 pEndpoint->Id = assignedEndpoint;
244 if (pEndpoint->ServiceID != 0) {
245 /* endpoint already in use! */
246 AR_DEBUG_ASSERT(FALSE);
247 break;
248 }
249
250 /* return assigned endpoint to caller */
251 pConnectResp->Endpoint = assignedEndpoint;
252 pConnectResp->MaxMsgLength = maxMsgSize;
253
254 /* setup the endpoint */
255 pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoin t in use */
256 pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
257 pEndpoint->MaxMsgLength = maxMsgSize;
258 /* copy all the callbacks */
259 pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
260 /* set the credit distribution info for this endpoint, this informat ion is
261 * passed back to the credit distribution callback function */
262 pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
263 pEndpoint->CreditDist.pHTCReserved = pEndpoint;
264 pEndpoint->CreditDist.Endpoint = assignedEndpoint;
265 pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
266
267 if (pConnectReq->MaxSendMsgSize != 0) {
268 /* override TxCreditsPerMaxMsg calculation, this optimizes the c redit-low indications
269 * since the host will actually issue smaller messages in the Se nd path */
270 if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
271 /* can't be larger than the maximum the target can support * /
272 AR_DEBUG_ASSERT(FALSE);
273 break;
274 }
275 pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSi ze / target->TargetCreditSize;
276 } else {
277 pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->Targ etCreditSize;
278 }
279
280 if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
281 pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
282 }
283
284 /* save local connection flags */
285 pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
286
287 status = A_OK;
288
289 } while (FALSE);
290
291 if (pSendPacket != NULL) {
292 HTC_FREE_CONTROL_TX(target,pSendPacket);
293 }
294
295 if (pRecvPacket != NULL) {
296 HTC_FREE_CONTROL_RX(target,pRecvPacket);
297 }
298
299 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));
300
301 return status;
302 }
303
304 static void AddToEndpointDistList(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST * pEpDist)
305 {
306 HTC_ENDPOINT_CREDIT_DIST *pCurEntry,*pLastEntry;
307
308 if (NULL == target->EpCreditDistributionListHead) {
309 target->EpCreditDistributionListHead = pEpDist;
310 pEpDist->pNext = NULL;
311 pEpDist->pPrev = NULL;
312 return;
313 }
314
315 /* queue to the end of the list, this does not have to be very
316 * fast since this list is built at startup time */
317 pCurEntry = target->EpCreditDistributionListHead;
318
319 while (pCurEntry) {
320 pLastEntry = pCurEntry;
321 pCurEntry = pCurEntry->pNext;
322 }
323
324 pLastEntry->pNext = pEpDist;
325 pEpDist->pPrev = pLastEntry;
326 pEpDist->pNext = NULL;
327 }
328
329
330
331 /* default credit init callback */
332 static void HTCDefaultCreditInit(void *Context,
333 HTC_ENDPOINT_CREDIT_DIST *pEPList,
334 int TotalCredits)
335 {
336 HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
337 int totalEps = 0;
338 int creditsPerEndpoint;
339
340 pCurEpDist = pEPList;
341 /* first run through the list and figure out how many endpoints we are d ealing with */
342 while (pCurEpDist != NULL) {
343 pCurEpDist = pCurEpDist->pNext;
344 totalEps++;
345 }
346
347 /* even distribution */
348 creditsPerEndpoint = TotalCredits/totalEps;
349
350 pCurEpDist = pEPList;
351 /* run through the list and set minimum and normal credits and
352 * provide the endpoint with some credits to start */
353 while (pCurEpDist != NULL) {
354
355 if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) {
356 /* too many endpoints and not enough credits */
357 AR_DEBUG_ASSERT(FALSE);
358 break;
359 }
360 /* our minimum is set for at least 1 max message */
361 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
362 /* this value is ignored by our credit alg, since we do
363 * not dynamically adjust credits, this is the policy of
364 * the "default" credit distribution, something simple and easy */
365 pCurEpDist->TxCreditsNorm = 0xFFFF;
366 /* give the endpoint minimum credits */
367 pCurEpDist->TxCredits = creditsPerEndpoint;
368 pCurEpDist->TxCreditsAssigned = creditsPerEndpoint;
369 pCurEpDist = pCurEpDist->pNext;
370 }
371
372 }
373
374 /* default credit distribution callback, NOTE, this callback holds the TX lock * /
375 void HTCDefaultCreditDist(void *Context,
376 HTC_ENDPOINT_CREDIT_DIST *pEPDistList,
377 HTC_CREDIT_DIST_REASON Reason)
378 {
379 HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
380
381 if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) {
382 pCurEpDist = pEPDistList;
383 /* simple distribution */
384 while (pCurEpDist != NULL) {
385 if (pCurEpDist->TxCreditsToDist > 0) {
386 /* just give the endpoint back the credits */
387 pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
388 pCurEpDist->TxCreditsToDist = 0;
389 }
390 pCurEpDist = pCurEpDist->pNext;
391 }
392 }
393
394 /* note we do not need to handle the other reason codes as this is a very
395 * simple distribution scheme, no need to seek for more credits or handle in activity */
396 }
397
398 void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
399 void *pCreditDistContext,
400 HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
401 HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
402 HTC_SERVICE_ID ServicePriorityOrder[],
403 int ListLength)
404 {
405 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
406 int i;
407 int ep;
408
409 if (CreditInitFunc != NULL) {
410 /* caller has supplied their own distribution functions */
411 target->InitCredits = CreditInitFunc;
412 AR_DEBUG_ASSERT(CreditDistFunc != NULL);
413 target->DistributeCredits = CreditDistFunc;
414 target->pCredDistContext = pCreditDistContext;
415 } else {
416 /* caller wants HTC to do distribution */
417 /* if caller wants service to handle distributions then
418 * it must set both of these to NULL! */
419 AR_DEBUG_ASSERT(CreditDistFunc == NULL);
420 target->InitCredits = HTCDefaultCreditInit;
421 target->DistributeCredits = HTCDefaultCreditDist;
422 target->pCredDistContext = target;
423 }
424
425 /* always add HTC control endpoint first, we only expose the list after the
426 * first one, this is added for TX queue checking */
427 AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);
428
429 /* build the list of credit distribution structures in priority order
430 * supplied by the caller, these will follow endpoint 0 */
431 for (i = 0; i < ListLength; i++) {
432 /* match services with endpoints and add the endpoints to the distri bution list
433 * in FIFO order */
434 for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
435 if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
436 /* queue this one to the list */
437 AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
438 break;
439 }
440 }
441 AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
442 }
443
444 }
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/htc2/htc_send.c ('k') | chromeos/drivers/ath6kl/include/AR6002/AR6002_regdump.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698