| OLD | NEW |
| 1 //------------------------------------------------------------------------------ | 1 //------------------------------------------------------------------------------ |
| 2 // <copyright file="credit_dist.c" company="Atheros"> | 2 // <copyright file="credit_dist.c" company="Atheros"> |
| 3 // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved. | 3 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. |
| 4 // | 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 // | 5 // |
| 9 // Software distributed under the License is distributed on an "AS | 6 // Permission to use, copy, modify, and/or distribute this software for any |
| 10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | 7 // purpose with or without fee is hereby granted, provided that the above |
| 11 // implied. See the License for the specific language governing | 8 // copyright notice and this permission notice appear in all copies. |
| 12 // rights and limitations under the License. | 9 // |
| 10 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 13 // | 17 // |
| 14 // | 18 // |
| 15 //------------------------------------------------------------------------------ | 19 //------------------------------------------------------------------------------ |
| 16 //============================================================================== | 20 //============================================================================== |
| 17 // Author(s): ="Atheros" | 21 // Author(s): ="Atheros" |
| 18 //============================================================================== | 22 //============================================================================== |
| 19 | 23 |
| 20 #include "a_config.h" | 24 #include "a_config.h" |
| 21 #include "athdefs.h" | 25 #include "athdefs.h" |
| 22 #include "a_types.h" | 26 #include "a_types.h" |
| 23 #include "a_osapi.h" | 27 #include "a_osapi.h" |
| 24 #define ATH_MODULE_NAME misc | 28 #define ATH_MODULE_NAME misc |
| 25 #include "a_debug.h" | 29 #include "a_debug.h" |
| 26 #include "htc_api.h" | 30 #include "htc_api.h" |
| 27 #include "common_drv.h" | 31 #include "common_drv.h" |
| 28 | 32 |
| 29 /********* CREDIT DISTRIBUTION FUNCTIONS ***************************************
***/ | 33 /********* CREDIT DISTRIBUTION FUNCTIONS ***************************************
***/ |
| 30 | 34 |
| 31 #define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave V
O service inactive */ | 35 #define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave V
O service inactive */ |
| 36 #define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1 |
| 32 | 37 |
| 33 #ifdef NO_VO_SERVICE | 38 #ifdef NO_VO_SERVICE |
| 34 #define DATA_SVCS_USED 3 | 39 #define DATA_SVCS_USED 3 |
| 35 #else | 40 #else |
| 36 #define DATA_SVCS_USED 4 | 41 #define DATA_SVCS_USED 4 |
| 37 #endif | 42 #endif |
| 38 | 43 |
| 39 static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, | 44 static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, |
| 40 HTC_ENDPOINT_CREDIT_DIST *pEPDistList); | 45 HTC_ENDPOINT_CREDIT_DIST *pEPDistList); |
| 41 | 46 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 pCredInfo->TotalAvailableCredits = TotalCredits; | 92 pCredInfo->TotalAvailableCredits = TotalCredits; |
| 88 | 93 |
| 89 pCurEpDist = pEPList; | 94 pCurEpDist = pEPList; |
| 90 | 95 |
| 91 /* run through the list and initialize */ | 96 /* run through the list and initialize */ |
| 92 while (pCurEpDist != NULL) { | 97 while (pCurEpDist != NULL) { |
| 93 | 98 |
| 94 /* set minimums for each endpoint */ | 99 /* set minimums for each endpoint */ |
| 95 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; | 100 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; |
| 96 | 101 |
| 102 #ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS |
| 103 |
| 104 if (TotalCredits > 4) |
| 105 { |
| 106 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->Servic
eID == WMI_DATA_BE_SVC)){ |
| 107 /* assign at least min credits to lower than VO priority ser
vices */ |
| 108 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); |
| 109 /* force active */ |
| 110 SET_EP_ACTIVE(pCurEpDist); |
| 111 } |
| 112 } |
| 113 |
| 114 #endif |
| 115 |
| 97 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { | 116 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { |
| 98 /* give control service some credits */ | 117 /* give control service some credits */ |
| 99 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); | 118 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); |
| 100 /* control service is always marked active, it never goes inacti
ve EVER */ | 119 /* control service is always marked active, it never goes inacti
ve EVER */ |
| 101 SET_EP_ACTIVE(pCurEpDist); | 120 SET_EP_ACTIVE(pCurEpDist); |
| 102 } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) { | 121 } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) { |
| 103 /* this is the lowest priority data endpoint, save this off for
easy access */ | 122 /* this is the lowest priority data endpoint, save this off for
easy access */ |
| 104 pCredInfo->pLowestPriEpDist = pCurEpDist; | 123 pCredInfo->pLowestPriEpDist = pCurEpDist; |
| 105 } | 124 } |
| 106 | 125 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 | 244 |
| 226 /* redistribute credits based on activity change */ | 245 /* redistribute credits based on activity change */ |
| 227 static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, | 246 static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, |
| 228 HTC_ENDPOINT_CREDIT_DIST *pEPDistList) | 247 HTC_ENDPOINT_CREDIT_DIST *pEPDistList) |
| 229 { | 248 { |
| 230 HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList; | 249 HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList; |
| 231 | 250 |
| 232 /* walk through the list and remove credits from inactive endpoints */ | 251 /* walk through the list and remove credits from inactive endpoints */ |
| 233 while (pCurEpDist != NULL) { | 252 while (pCurEpDist != NULL) { |
| 234 | 253 |
| 254 #ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS |
| 255 |
| 256 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceI
D == WMI_DATA_BE_SVC)) { |
| 257 /* force low priority streams to always be active to retain their
minimum credit distribution */ |
| 258 SET_EP_ACTIVE(pCurEpDist); |
| 259 } |
| 260 #endif |
| 261 |
| 235 if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) { | 262 if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) { |
| 236 if (!IS_EP_ACTIVE(pCurEpDist)) { | 263 if (!IS_EP_ACTIVE(pCurEpDist)) { |
| 237 if (pCurEpDist->TxQueueDepth == 0) { | 264 if (pCurEpDist->TxQueueDepth == 0) { |
| 238 /* EP is inactive and there are no pending messages, red
uce credits back to zero */ | 265 /* EP is inactive and there are no pending messages, red
uce credits back to zero */ |
| 239 ReduceCredits(pCredInfo, pCurEpDist, 0); | 266 ReduceCredits(pCredInfo, pCurEpDist, 0); |
| 240 } else { | 267 } else { |
| 241 /* we cannot zero the credits assigned to this EP, but t
o keep | 268 /* we cannot zero the credits assigned to this EP, but t
o keep |
| 242 * the credits available for these leftover packets, red
uce to | 269 * the credits available for these leftover packets, red
uce to |
| 243 * a minimum */ | 270 * a minimum */ |
| 244 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMi
n); | 271 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMi
n); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 265 | 292 |
| 266 do { | 293 do { |
| 267 | 294 |
| 268 if (pEPDist->ServiceID == WMI_CONTROL_SVC) { | 295 if (pEPDist->ServiceID == WMI_CONTROL_SVC) { |
| 269 /* we never oversubscribe on the control service, this is not | 296 /* we never oversubscribe on the control service, this is not |
| 270 * a high performance path and the target never holds onto contr
ol | 297 * a high performance path and the target never holds onto contr
ol |
| 271 * credits for too long */ | 298 * credits for too long */ |
| 272 break; | 299 break; |
| 273 } | 300 } |
| 274 | 301 |
| 302 #ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS |
| 303 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) { |
| 304 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) { |
| 305 /* limit VI service from oversubscribing */ |
| 306 break; |
| 307 } |
| 308 } |
| 309 |
| 310 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) { |
| 311 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) { |
| 312 /* limit VO service from oversubscribing */ |
| 313 break; |
| 314 } |
| 315 } |
| 316 #else |
| 275 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) { | 317 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) { |
| 276 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || | 318 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || |
| 277 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg))
{ | 319 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg))
{ |
| 278 /* limit VI service from oversubscribing */ | 320 /* limit VI service from oversubscribing */ |
| 279 /* at least one free credit will not be used by VI */ | 321 /* at least one free credit will not be used by VI */ |
| 280 break; | 322 break; |
| 281 } | 323 } |
| 282 } | 324 } |
| 283 | 325 |
| 284 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) { | 326 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) { |
| 285 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || | 327 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || |
| 286 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg))
{ | 328 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg))
{ |
| 287 /* limit VO service from oversubscribing */ | 329 /* limit VO service from oversubscribing */ |
| 288 /* at least one free credit will not be used by VO */ | 330 /* at least one free credit will not be used by VO */ |
| 289 break; | 331 break; |
| 290 } | 332 } |
| 291 } | 333 } |
| 334 #endif |
| 292 | 335 |
| 293 /* for all other services, we follow a simple algorithm of | 336 /* for all other services, we follow a simple algorithm of |
| 294 * 1. checking the free pool for credits | 337 * 1. checking the free pool for credits |
| 295 * 2. checking lower priority endpoints for credits to take */ | 338 * 2. checking lower priority endpoints for credits to take */ |
| 296 | 339 |
| 297 /* give what we can */ | 340 /* give what we can */ |
| 298 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); | 341 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); |
| 299 | 342 |
| 300 if (credits >= pEPDist->TxCreditsSeek) { | 343 if (credits >= pEPDist->TxCreditsSeek) { |
| 301 /* we found some to fullfill the seek request */ | 344 /* we found some to fullfill the seek request */ |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 HTCSetCreditDistribution(HTCHandle, | 409 HTCSetCreditDistribution(HTCHandle, |
| 367 pCredInfo, | 410 pCredInfo, |
| 368 ar6000_credit_distribute, | 411 ar6000_credit_distribute, |
| 369 ar6000_credit_init, | 412 ar6000_credit_init, |
| 370 servicepriority, | 413 servicepriority, |
| 371 5); | 414 5); |
| 372 | 415 |
| 373 return A_OK; | 416 return A_OK; |
| 374 } | 417 } |
| 375 | 418 |
| OLD | NEW |