1dd1de374Slin wang - Sun Microsystems - Beijing China /* 2*c0c93480Slin wang - Sun Microsystems - Beijing China * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3dd1de374Slin wang - Sun Microsystems - Beijing China * Use is subject to license terms. 4dd1de374Slin wang - Sun Microsystems - Beijing China */ 5dd1de374Slin wang - Sun Microsystems - Beijing China 6dd1de374Slin wang - Sun Microsystems - Beijing China /* 7dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright (c) 2004 Video54 Technologies, Inc. 8dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright (c) 2004-2008 Atheros Communications, Inc. 9dd1de374Slin wang - Sun Microsystems - Beijing China * 10dd1de374Slin wang - Sun Microsystems - Beijing China * Permission to use, copy, modify, and/or distribute this software for any 11dd1de374Slin wang - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 12dd1de374Slin wang - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 13dd1de374Slin wang - Sun Microsystems - Beijing China * 14dd1de374Slin wang - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15dd1de374Slin wang - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16dd1de374Slin wang - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17dd1de374Slin wang - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18dd1de374Slin wang - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19dd1de374Slin wang - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20dd1de374Slin wang - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21dd1de374Slin wang - Sun Microsystems - Beijing China */ 22dd1de374Slin wang - Sun Microsystems - Beijing China #include <sys/time.h> 23dd1de374Slin wang - Sun Microsystems - Beijing China #include <sys/types.h> 24dd1de374Slin wang - Sun Microsystems - Beijing China #include <sys/ddi.h> 25*c0c93480Slin wang - Sun Microsystems - Beijing China #include <sys/net80211_ht.h> 26dd1de374Slin wang - Sun Microsystems - Beijing China 27dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_core.h" 28*c0c93480Slin wang - Sun Microsystems - Beijing China #include "arn_hw.h" 29*c0c93480Slin wang - Sun Microsystems - Beijing China #include "arn_reg.h" 30dd1de374Slin wang - Sun Microsystems - Beijing China 31dd1de374Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table ar5416_11na_ratetable = { 32dd1de374Slin wang - Sun Microsystems - Beijing China 42, 33dd1de374Slin wang - Sun Microsystems - Beijing China {0}, 34dd1de374Slin wang - Sun Microsystems - Beijing China { 35dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 36dd1de374Slin wang - Sun Microsystems - Beijing China 5400, 0x0b, 0x00, 12, 37dd1de374Slin wang - Sun Microsystems - Beijing China 0, 2, 1, 0, 0, 0, 0, 0 }, 38dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 39dd1de374Slin wang - Sun Microsystems - Beijing China 7800, 0x0f, 0x00, 18, 40dd1de374Slin wang - Sun Microsystems - Beijing China 0, 3, 1, 1, 1, 1, 1, 0 }, 41dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 42dd1de374Slin wang - Sun Microsystems - Beijing China 10000, 0x0a, 0x00, 24, 43dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 2, 2, 2, 2, 2, 0 }, 44dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 45dd1de374Slin wang - Sun Microsystems - Beijing China 13900, 0x0e, 0x00, 36, 46dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 2, 3, 3, 3, 3, 0 }, 47dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 48dd1de374Slin wang - Sun Microsystems - Beijing China 17300, 0x09, 0x00, 48, 49dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 4, 4, 4, 4, 0 }, 50dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 51dd1de374Slin wang - Sun Microsystems - Beijing China 23000, 0x0d, 0x00, 72, 52dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 5, 5, 5, 5, 0 }, 53dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 54dd1de374Slin wang - Sun Microsystems - Beijing China 27400, 0x08, 0x00, 96, 55dd1de374Slin wang - Sun Microsystems - Beijing China 4, 20, 3, 6, 6, 6, 6, 0 }, 56dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 57dd1de374Slin wang - Sun Microsystems - Beijing China 29300, 0x0c, 0x00, 108, 58dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 7, 7, 7, 7, 0 }, 59dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 60dd1de374Slin wang - Sun Microsystems - Beijing China 6400, 0x80, 0x00, 0, 61dd1de374Slin wang - Sun Microsystems - Beijing China 0, 2, 3, 8, 24, 8, 24, 3216 }, 62dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 63dd1de374Slin wang - Sun Microsystems - Beijing China 12700, 0x81, 0x00, 1, 64dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 3, 9, 25, 9, 25, 6434 }, 65dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 66dd1de374Slin wang - Sun Microsystems - Beijing China 18800, 0x82, 0x00, 2, 67dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 3, 10, 26, 10, 26, 9650 }, 68dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 69dd1de374Slin wang - Sun Microsystems - Beijing China 25000, 0x83, 0x00, 3, 70dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 11, 27, 11, 27, 12868 }, 71dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 72dd1de374Slin wang - Sun Microsystems - Beijing China 36700, 0x84, 0x00, 4, 73dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 12, 28, 12, 28, 19304 }, 74dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 75dd1de374Slin wang - Sun Microsystems - Beijing China 48100, 0x85, 0x00, 5, 76dd1de374Slin wang - Sun Microsystems - Beijing China 4, 20, 3, 13, 29, 13, 29, 25740 }, 77dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 78dd1de374Slin wang - Sun Microsystems - Beijing China 53500, 0x86, 0x00, 6, 79dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 14, 30, 14, 30, 28956 }, 80dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 81dd1de374Slin wang - Sun Microsystems - Beijing China 59000, 0x87, 0x00, 7, 82dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 15, 31, 15, 32, 32180 }, 83dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 84dd1de374Slin wang - Sun Microsystems - Beijing China 12700, 0x88, 0x00, 85dd1de374Slin wang - Sun Microsystems - Beijing China 8, 0, 2, 3, 16, 33, 16, 33, 6430 }, 86dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 87dd1de374Slin wang - Sun Microsystems - Beijing China 24800, 0x89, 0x00, 9, 88dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 3, 17, 34, 17, 34, 12860 }, 89dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 90dd1de374Slin wang - Sun Microsystems - Beijing China 36600, 0x8a, 0x00, 10, 91dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 3, 18, 35, 18, 35, 19300 }, 92dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 93dd1de374Slin wang - Sun Microsystems - Beijing China 48100, 0x8b, 0x00, 11, 94dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 19, 36, 19, 36, 25736 }, 95dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 96dd1de374Slin wang - Sun Microsystems - Beijing China 69500, 0x8c, 0x00, 12, 97dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 20, 37, 20, 37, 38600 }, 98dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 99dd1de374Slin wang - Sun Microsystems - Beijing China 89500, 0x8d, 0x00, 13, 100dd1de374Slin wang - Sun Microsystems - Beijing China 4, 20, 3, 21, 38, 21, 38, 51472 }, 101dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 102dd1de374Slin wang - Sun Microsystems - Beijing China 98900, 0x8e, 0x00, 14, 103dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 22, 39, 22, 39, 57890 }, 104dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 105dd1de374Slin wang - Sun Microsystems - Beijing China 108300, 0x8f, 0x00, 15, 106dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 23, 40, 23, 41, 64320 }, 107dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 108dd1de374Slin wang - Sun Microsystems - Beijing China 13200, 0x80, 0x00, 0, 109dd1de374Slin wang - Sun Microsystems - Beijing China 0, 2, 3, 8, 24, 24, 24, 6684 }, 110dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 111dd1de374Slin wang - Sun Microsystems - Beijing China 25900, 0x81, 0x00, 1, 112dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 3, 9, 25, 25, 25, 13368 }, 113dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 114dd1de374Slin wang - Sun Microsystems - Beijing China 38600, 0x82, 0x00, 2, 115dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 3, 10, 26, 26, 26, 20052 }, 116dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 117dd1de374Slin wang - Sun Microsystems - Beijing China 49800, 0x83, 0x00, 3, 118dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 11, 27, 27, 27, 26738 }, 119dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 120dd1de374Slin wang - Sun Microsystems - Beijing China 72200, 0x84, 0x00, 4, 121dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 12, 28, 28, 28, 40104 }, 122dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 123dd1de374Slin wang - Sun Microsystems - Beijing China 92900, 0x85, 0x00, 5, 124dd1de374Slin wang - Sun Microsystems - Beijing China 4, 20, 3, 13, 29, 29, 29, 53476 }, 125dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5Mb */ 126dd1de374Slin wang - Sun Microsystems - Beijing China 102700, 0x86, 0x00, 6, 127dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 14, 30, 30, 30, 60156 }, 128dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 129dd1de374Slin wang - Sun Microsystems - Beijing China 112000, 0x87, 0x00, 7, 130dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 15, 31, 32, 32, 66840 }, 131dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 132dd1de374Slin wang - Sun Microsystems - Beijing China 150000, /* 150Mb */ 133dd1de374Slin wang - Sun Microsystems - Beijing China 122000, 0x87, 0x00, 7, 134dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 15, 31, 32, 32, 74200 }, 135dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 136dd1de374Slin wang - Sun Microsystems - Beijing China 25800, 0x88, 0x00, 8, 137dd1de374Slin wang - Sun Microsystems - Beijing China 0, 2, 3, 16, 33, 33, 33, 13360 }, 138dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 139dd1de374Slin wang - Sun Microsystems - Beijing China 49800, 0x89, 0x00, 9, 140dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 3, 17, 34, 34, 34, 26720 }, 141dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 142dd1de374Slin wang - Sun Microsystems - Beijing China 71900, 0x8a, 0x00, 10, 143dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 3, 18, 35, 35, 35, 40080 }, 144dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 145dd1de374Slin wang - Sun Microsystems - Beijing China 92500, 0x8b, 0x00, 11, 146dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 19, 36, 36, 36, 53440 }, 147dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 148dd1de374Slin wang - Sun Microsystems - Beijing China 130300, 0x8c, 0x00, 12, 149dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 20, 37, 37, 37, 80160 }, 150dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 151dd1de374Slin wang - Sun Microsystems - Beijing China 162800, 0x8d, 0x00, 13, 152dd1de374Slin wang - Sun Microsystems - Beijing China 4, 20, 3, 21, 38, 38, 38, 106880 }, 153dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 154dd1de374Slin wang - Sun Microsystems - Beijing China 178200, 0x8e, 0x00, 14, 155dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 22, 39, 39, 39, 120240 }, 156dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 157dd1de374Slin wang - Sun Microsystems - Beijing China 192100, 0x8f, 0x00, 15, 158dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 23, 40, 41, 41, 133600 }, 159dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 160dd1de374Slin wang - Sun Microsystems - Beijing China 300000, /* 300 Mb */ 161dd1de374Slin wang - Sun Microsystems - Beijing China 207000, 0x8f, 0x00, 15, 162dd1de374Slin wang - Sun Microsystems - Beijing China 4, 25, 3, 23, 40, 41, 41, 148400 }, 163dd1de374Slin wang - Sun Microsystems - Beijing China }, 164dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* probe interval */ 165dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* rssi reduce interval */ 166dd1de374Slin wang - Sun Microsystems - Beijing China WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 167dd1de374Slin wang - Sun Microsystems - Beijing China }; 168dd1de374Slin wang - Sun Microsystems - Beijing China 169dd1de374Slin wang - Sun Microsystems - Beijing China /* 170dd1de374Slin wang - Sun Microsystems - Beijing China * 4ms frame limit not used for NG mode. The values filled 171dd1de374Slin wang - Sun Microsystems - Beijing China * for HT are the 64K max aggregate limit 172dd1de374Slin wang - Sun Microsystems - Beijing China */ 173dd1de374Slin wang - Sun Microsystems - Beijing China 174dd1de374Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table ar5416_11ng_ratetable = { 175dd1de374Slin wang - Sun Microsystems - Beijing China 46, 176dd1de374Slin wang - Sun Microsystems - Beijing China {0}, 177dd1de374Slin wang - Sun Microsystems - Beijing China { 178dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 179dd1de374Slin wang - Sun Microsystems - Beijing China 900, 0x1b, 0x00, 2, 180dd1de374Slin wang - Sun Microsystems - Beijing China 0, 0, 1, 0, 0, 0, 0, 0 }, 181dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 182dd1de374Slin wang - Sun Microsystems - Beijing China 1900, 0x1a, 0x04, 4, 183dd1de374Slin wang - Sun Microsystems - Beijing China 1, 1, 1, 1, 1, 1, 1, 0 }, 184dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 185dd1de374Slin wang - Sun Microsystems - Beijing China 4900, 0x19, 0x04, 11, 186dd1de374Slin wang - Sun Microsystems - Beijing China 2, 2, 2, 2, 2, 2, 2, 0 }, 187dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 188dd1de374Slin wang - Sun Microsystems - Beijing China 8100, 0x18, 0x04, 22, 189dd1de374Slin wang - Sun Microsystems - Beijing China 3, 3, 2, 3, 3, 3, 3, 0 }, 190dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 191dd1de374Slin wang - Sun Microsystems - Beijing China 5400, 0x0b, 0x00, 12, 192dd1de374Slin wang - Sun Microsystems - Beijing China 4, 2, 1, 4, 4, 4, 4, 0 }, 193dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 194dd1de374Slin wang - Sun Microsystems - Beijing China 7800, 0x0f, 0x00, 18, 195dd1de374Slin wang - Sun Microsystems - Beijing China 4, 3, 1, 5, 5, 5, 5, 0 }, 196dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 197dd1de374Slin wang - Sun Microsystems - Beijing China 10100, 0x0a, 0x00, 24, 198dd1de374Slin wang - Sun Microsystems - Beijing China 6, 4, 1, 6, 6, 6, 6, 0 }, 199dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 200dd1de374Slin wang - Sun Microsystems - Beijing China 14100, 0x0e, 0x00, 36, 201dd1de374Slin wang - Sun Microsystems - Beijing China 6, 6, 2, 7, 7, 7, 7, 0 }, 202dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 203dd1de374Slin wang - Sun Microsystems - Beijing China 17700, 0x09, 0x00, 48, 204dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 8, 8, 8, 8, 0 }, 205dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 206dd1de374Slin wang - Sun Microsystems - Beijing China 23700, 0x0d, 0x00, 72, 207dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 9, 9, 9, 9, 0 }, 208dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 209dd1de374Slin wang - Sun Microsystems - Beijing China 27400, 0x08, 0x00, 96, 210dd1de374Slin wang - Sun Microsystems - Beijing China 8, 20, 3, 10, 10, 10, 10, 0 }, 211dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 212dd1de374Slin wang - Sun Microsystems - Beijing China 30900, 0x0c, 0x00, 108, 213dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 11, 11, 11, 11, 0 }, 214dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 215dd1de374Slin wang - Sun Microsystems - Beijing China 6400, 0x80, 0x00, 0, 216dd1de374Slin wang - Sun Microsystems - Beijing China 4, 2, 3, 12, 28, 12, 28, 3216 }, 217dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 218dd1de374Slin wang - Sun Microsystems - Beijing China 12700, 0x81, 0x00, 1, 219dd1de374Slin wang - Sun Microsystems - Beijing China 6, 4, 3, 13, 29, 13, 29, 6434 }, 220dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 221dd1de374Slin wang - Sun Microsystems - Beijing China 18800, 0x82, 0x00, 2, 222dd1de374Slin wang - Sun Microsystems - Beijing China 6, 6, 3, 14, 30, 14, 30, 9650 }, 223dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 224dd1de374Slin wang - Sun Microsystems - Beijing China 25000, 0x83, 0x00, 3, 225dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 15, 31, 15, 31, 12868 }, 226dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 227dd1de374Slin wang - Sun Microsystems - Beijing China 36700, 0x84, 0x00, 4, 228dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 16, 32, 16, 32, 19304 }, 229dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 230dd1de374Slin wang - Sun Microsystems - Beijing China 48100, 0x85, 0x00, 5, 231dd1de374Slin wang - Sun Microsystems - Beijing China 8, 20, 3, 17, 33, 17, 33, 25740 }, 232dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 233dd1de374Slin wang - Sun Microsystems - Beijing China 53500, 0x86, 0x00, 6, 234dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 18, 34, 18, 34, 28956 }, 235dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 236dd1de374Slin wang - Sun Microsystems - Beijing China 59000, 0x87, 0x00, 7, 237dd1de374Slin wang - Sun Microsystems - Beijing China 8, 25, 3, 19, 35, 19, 36, 32180 }, 238dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 239dd1de374Slin wang - Sun Microsystems - Beijing China 12700, 0x88, 0x00, 8, 240dd1de374Slin wang - Sun Microsystems - Beijing China 4, 2, 3, 20, 37, 20, 37, 6430 }, 241dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 242dd1de374Slin wang - Sun Microsystems - Beijing China 24800, 0x89, 0x00, 9, 243dd1de374Slin wang - Sun Microsystems - Beijing China 6, 4, 3, 21, 38, 21, 38, 12860 }, 244dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 245dd1de374Slin wang - Sun Microsystems - Beijing China 36600, 0x8a, 0x00, 10, 246dd1de374Slin wang - Sun Microsystems - Beijing China 6, 6, 3, 22, 39, 22, 39, 19300 }, 247dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 248dd1de374Slin wang - Sun Microsystems - Beijing China 48100, 0x8b, 0x00, 11, 249dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 23, 40, 23, 40, 25736 }, 250dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 251dd1de374Slin wang - Sun Microsystems - Beijing China 69500, 0x8c, 0x00, 12, 252dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 24, 41, 24, 41, 38600 }, 253dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 254dd1de374Slin wang - Sun Microsystems - Beijing China 89500, 0x8d, 0x00, 13, 255dd1de374Slin wang - Sun Microsystems - Beijing China 8, 20, 3, 25, 42, 25, 42, 51472 }, 256dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 257dd1de374Slin wang - Sun Microsystems - Beijing China 98900, 0x8e, 0x00, 14, 258dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 26, 43, 26, 44, 57890 }, 259dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 260dd1de374Slin wang - Sun Microsystems - Beijing China 108300, 0x8f, 0x00, 15, 261dd1de374Slin wang - Sun Microsystems - Beijing China 8, 25, 3, 27, 44, 27, 45, 64320 }, 262dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 263dd1de374Slin wang - Sun Microsystems - Beijing China 13200, 0x80, 0x00, 0, 264dd1de374Slin wang - Sun Microsystems - Beijing China 8, 2, 3, 12, 28, 28, 28, 6684 }, 265dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 266dd1de374Slin wang - Sun Microsystems - Beijing China 25900, 0x81, 0x00, 1, 267dd1de374Slin wang - Sun Microsystems - Beijing China 8, 4, 3, 13, 29, 29, 29, 13368 }, 268dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 269dd1de374Slin wang - Sun Microsystems - Beijing China 38600, 0x82, 0x00, 2, 270dd1de374Slin wang - Sun Microsystems - Beijing China 8, 6, 3, 14, 30, 30, 30, 20052 }, 271dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 272dd1de374Slin wang - Sun Microsystems - Beijing China 49800, 0x83, 0x00, 3, 273dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 15, 31, 31, 31, 26738 }, 274dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 275dd1de374Slin wang - Sun Microsystems - Beijing China 72200, 0x84, 0x00, 4, 276dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 16, 32, 32, 32, 40104 }, 277dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 278dd1de374Slin wang - Sun Microsystems - Beijing China 92900, 0x85, 0x00, 5, 279dd1de374Slin wang - Sun Microsystems - Beijing China 8, 20, 3, 17, 33, 33, 33, 53476 }, 280dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 281dd1de374Slin wang - Sun Microsystems - Beijing China 121500, /* 121.5 Mb */ 282dd1de374Slin wang - Sun Microsystems - Beijing China 102700, 0x86, 0x00, 6, 283dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 18, 34, 34, 34, 60156 }, 284dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 285dd1de374Slin wang - Sun Microsystems - Beijing China 112000, 0x87, 0x00, 7, 286dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 19, 35, 36, 36, 66840 }, 287dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 288dd1de374Slin wang - Sun Microsystems - Beijing China 150000, /* 150 Mb */ 289dd1de374Slin wang - Sun Microsystems - Beijing China 122000, 0x87, 0x00, 7, 290dd1de374Slin wang - Sun Microsystems - Beijing China 8, 25, 3, 19, 35, 36, 36, 74200 }, 291dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 292dd1de374Slin wang - Sun Microsystems - Beijing China 25800, 0x88, 0x00, 8, 293dd1de374Slin wang - Sun Microsystems - Beijing China 8, 2, 3, 20, 37, 37, 37, 13360 }, 294dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 295dd1de374Slin wang - Sun Microsystems - Beijing China 49800, 0x89, 0x00, 9, 296dd1de374Slin wang - Sun Microsystems - Beijing China 8, 4, 3, 21, 38, 38, 38, 26720 }, 297dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 298dd1de374Slin wang - Sun Microsystems - Beijing China 71900, 0x8a, 0x00, 10, 299dd1de374Slin wang - Sun Microsystems - Beijing China 8, 6, 3, 22, 39, 39, 39, 40080 }, 300dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 301dd1de374Slin wang - Sun Microsystems - Beijing China 92500, 0x8b, 0x00, 11, 302dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 23, 40, 40, 40, 53440 }, 303dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 304dd1de374Slin wang - Sun Microsystems - Beijing China 130300, 0x8c, 0x00, 12, 305dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 24, 41, 41, 41, 80160 }, 306dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 307dd1de374Slin wang - Sun Microsystems - Beijing China 162800, 0x8d, 0x00, 13, 308dd1de374Slin wang - Sun Microsystems - Beijing China 8, 20, 3, 25, 42, 42, 42, 106880 }, 309dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 310dd1de374Slin wang - Sun Microsystems - Beijing China 178200, 0x8e, 0x00, 14, 311dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 26, 43, 43, 43, 120240 }, 312dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 313dd1de374Slin wang - Sun Microsystems - Beijing China 192100, 0x8f, 0x00, 15, 314dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 27, 44, 45, 45, 133600 }, 315dd1de374Slin wang - Sun Microsystems - Beijing China { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 316dd1de374Slin wang - Sun Microsystems - Beijing China 300000, /* 300 Mb */ 317dd1de374Slin wang - Sun Microsystems - Beijing China 207000, 0x8f, 0x00, 15, 318dd1de374Slin wang - Sun Microsystems - Beijing China 8, 25, 3, 27, 44, 45, 45, 148400 }, 319dd1de374Slin wang - Sun Microsystems - Beijing China }, 320dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* probe interval */ 321dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* rssi reduce interval */ 322dd1de374Slin wang - Sun Microsystems - Beijing China WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 323dd1de374Slin wang - Sun Microsystems - Beijing China }; 324dd1de374Slin wang - Sun Microsystems - Beijing China 325dd1de374Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table ar5416_11a_ratetable = { 326dd1de374Slin wang - Sun Microsystems - Beijing China 8, 327dd1de374Slin wang - Sun Microsystems - Beijing China {0}, 328dd1de374Slin wang - Sun Microsystems - Beijing China { 329dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 330dd1de374Slin wang - Sun Microsystems - Beijing China 5400, 0x0b, 0x00, (0x80|12), 331dd1de374Slin wang - Sun Microsystems - Beijing China 0, 2, 1, 0, 0 }, 332dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 333dd1de374Slin wang - Sun Microsystems - Beijing China 7800, 0x0f, 0x00, 18, 334dd1de374Slin wang - Sun Microsystems - Beijing China 0, 3, 1, 1, 0 }, 335dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 336dd1de374Slin wang - Sun Microsystems - Beijing China 10000, 0x0a, 0x00, (0x80|24), 337dd1de374Slin wang - Sun Microsystems - Beijing China 2, 4, 2, 2, 0 }, 338dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 339dd1de374Slin wang - Sun Microsystems - Beijing China 13900, 0x0e, 0x00, 36, 340dd1de374Slin wang - Sun Microsystems - Beijing China 2, 6, 2, 3, 0 }, 341dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 342dd1de374Slin wang - Sun Microsystems - Beijing China 17300, 0x09, 0x00, (0x80|48), 343dd1de374Slin wang - Sun Microsystems - Beijing China 4, 10, 3, 4, 0 }, 344dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 345dd1de374Slin wang - Sun Microsystems - Beijing China 23000, 0x0d, 0x00, 72, 346dd1de374Slin wang - Sun Microsystems - Beijing China 4, 14, 3, 5, 0 }, 347dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 348dd1de374Slin wang - Sun Microsystems - Beijing China 27400, 0x08, 0x00, 96, 349dd1de374Slin wang - Sun Microsystems - Beijing China 4, 19, 3, 6, 0 }, 350dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 351dd1de374Slin wang - Sun Microsystems - Beijing China 29300, 0x0c, 0x00, 108, 352dd1de374Slin wang - Sun Microsystems - Beijing China 4, 23, 3, 7, 0 }, 353dd1de374Slin wang - Sun Microsystems - Beijing China }, 354dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* probe interval */ 355dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* rssi reduce interval */ 356dd1de374Slin wang - Sun Microsystems - Beijing China 0, /* Phy rates allowed initially */ 357dd1de374Slin wang - Sun Microsystems - Beijing China }; 358dd1de374Slin wang - Sun Microsystems - Beijing China 359dd1de374Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table ar5416_11g_ratetable = { 360dd1de374Slin wang - Sun Microsystems - Beijing China 12, 361dd1de374Slin wang - Sun Microsystems - Beijing China {0}, 362dd1de374Slin wang - Sun Microsystems - Beijing China { 363dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 364dd1de374Slin wang - Sun Microsystems - Beijing China 900, 0x1b, 0x00, 2, 365dd1de374Slin wang - Sun Microsystems - Beijing China 0, 0, 1, 0, 0 }, 366dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 367dd1de374Slin wang - Sun Microsystems - Beijing China 1900, 0x1a, 0x04, 4, 368dd1de374Slin wang - Sun Microsystems - Beijing China 1, 1, 1, 1, 0 }, 369dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 370dd1de374Slin wang - Sun Microsystems - Beijing China 4900, 0x19, 0x04, 11, 371dd1de374Slin wang - Sun Microsystems - Beijing China 2, 2, 2, 2, 0 }, 372dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 373dd1de374Slin wang - Sun Microsystems - Beijing China 8100, 0x18, 0x04, 22, 374dd1de374Slin wang - Sun Microsystems - Beijing China 3, 3, 2, 3, 0 }, 375dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 376dd1de374Slin wang - Sun Microsystems - Beijing China 5400, 0x0b, 0x00, 12, 377dd1de374Slin wang - Sun Microsystems - Beijing China 4, 2, 1, 4, 0 }, 378dd1de374Slin wang - Sun Microsystems - Beijing China { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 379dd1de374Slin wang - Sun Microsystems - Beijing China 7800, 0x0f, 0x00, 18, 380dd1de374Slin wang - Sun Microsystems - Beijing China 4, 3, 1, 5, 0 }, 381dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 382dd1de374Slin wang - Sun Microsystems - Beijing China 10000, 0x0a, 0x00, 24, 383dd1de374Slin wang - Sun Microsystems - Beijing China 6, 4, 1, 6, 0 }, 384dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 385dd1de374Slin wang - Sun Microsystems - Beijing China 13900, 0x0e, 0x00, 36, 386dd1de374Slin wang - Sun Microsystems - Beijing China 6, 6, 2, 7, 0 }, 387dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 388dd1de374Slin wang - Sun Microsystems - Beijing China 17300, 0x09, 0x00, 48, 389dd1de374Slin wang - Sun Microsystems - Beijing China 8, 10, 3, 8, 0 }, 390dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 391dd1de374Slin wang - Sun Microsystems - Beijing China 23000, 0x0d, 0x00, 72, 392dd1de374Slin wang - Sun Microsystems - Beijing China 8, 14, 3, 9, 0 }, 393dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 394dd1de374Slin wang - Sun Microsystems - Beijing China 27400, 0x08, 0x00, 96, 395dd1de374Slin wang - Sun Microsystems - Beijing China 8, 19, 3, 10, 0 }, 396dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 397dd1de374Slin wang - Sun Microsystems - Beijing China 29300, 0x0c, 0x00, 108, 398dd1de374Slin wang - Sun Microsystems - Beijing China 8, 23, 3, 11, 0 }, 399dd1de374Slin wang - Sun Microsystems - Beijing China }, 400dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* probe interval */ 401dd1de374Slin wang - Sun Microsystems - Beijing China 50, /* rssi reduce interval */ 402dd1de374Slin wang - Sun Microsystems - Beijing China 0, /* Phy rates allowed initially */ 403dd1de374Slin wang - Sun Microsystems - Beijing China }; 404dd1de374Slin wang - Sun Microsystems - Beijing China 405dd1de374Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table ar5416_11b_ratetable = { 406dd1de374Slin wang - Sun Microsystems - Beijing China 4, 407dd1de374Slin wang - Sun Microsystems - Beijing China {0}, 408dd1de374Slin wang - Sun Microsystems - Beijing China { 409dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 410dd1de374Slin wang - Sun Microsystems - Beijing China 900, 0x1b, 0x00, (0x80|2), 411dd1de374Slin wang - Sun Microsystems - Beijing China 0, 0, 1, 0, 0 }, 412dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 413dd1de374Slin wang - Sun Microsystems - Beijing China 1800, 0x1a, 0x04, (0x80|4), 414dd1de374Slin wang - Sun Microsystems - Beijing China 1, 1, 1, 1, 0 }, 415dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 416dd1de374Slin wang - Sun Microsystems - Beijing China 4300, 0x19, 0x04, (0x80|11), 417dd1de374Slin wang - Sun Microsystems - Beijing China 1, 2, 2, 2, 0 }, 418dd1de374Slin wang - Sun Microsystems - Beijing China { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 419dd1de374Slin wang - Sun Microsystems - Beijing China 7100, 0x18, 0x04, (0x80|22), 420dd1de374Slin wang - Sun Microsystems - Beijing China 1, 4, 100, 3, 0 }, 421dd1de374Slin wang - Sun Microsystems - Beijing China }, 422dd1de374Slin wang - Sun Microsystems - Beijing China 100, /* probe interval */ 423dd1de374Slin wang - Sun Microsystems - Beijing China 100, /* rssi reduce interval */ 424dd1de374Slin wang - Sun Microsystems - Beijing China 0, /* Phy rates allowed initially */ 425dd1de374Slin wang - Sun Microsystems - Beijing China }; 426dd1de374Slin wang - Sun Microsystems - Beijing China 427*c0c93480Slin wang - Sun Microsystems - Beijing China static inline int8_t 428*c0c93480Slin wang - Sun Microsystems - Beijing China median(int8_t a, int8_t b, int8_t c) 429*c0c93480Slin wang - Sun Microsystems - Beijing China { 430*c0c93480Slin wang - Sun Microsystems - Beijing China if (a >= b) { 431*c0c93480Slin wang - Sun Microsystems - Beijing China if (b >= c) 432*c0c93480Slin wang - Sun Microsystems - Beijing China return (b); 433*c0c93480Slin wang - Sun Microsystems - Beijing China else if (a > c) 434*c0c93480Slin wang - Sun Microsystems - Beijing China return (c); 435*c0c93480Slin wang - Sun Microsystems - Beijing China else 436*c0c93480Slin wang - Sun Microsystems - Beijing China return (a); 437*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 438*c0c93480Slin wang - Sun Microsystems - Beijing China if (a >= c) 439*c0c93480Slin wang - Sun Microsystems - Beijing China return (a); 440*c0c93480Slin wang - Sun Microsystems - Beijing China else if (b >= c) 441*c0c93480Slin wang - Sun Microsystems - Beijing China return (c); 442*c0c93480Slin wang - Sun Microsystems - Beijing China else 443*c0c93480Slin wang - Sun Microsystems - Beijing China return (b); 444*c0c93480Slin wang - Sun Microsystems - Beijing China } 445*c0c93480Slin wang - Sun Microsystems - Beijing China } 446*c0c93480Slin wang - Sun Microsystems - Beijing China 447*c0c93480Slin wang - Sun Microsystems - Beijing China static void 448*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_sort_validrates(struct ath_rate_table *rate_table, 449*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv) 450*c0c93480Slin wang - Sun Microsystems - Beijing China { 451*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i, j, idx, idx_next; 452*c0c93480Slin wang - Sun Microsystems - Beijing China 453*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) { 454*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = 0; j <= i-1; j++) { 455*c0c93480Slin wang - Sun Microsystems - Beijing China idx = ath_rc_priv->valid_rate_index[j]; 456*c0c93480Slin wang - Sun Microsystems - Beijing China idx_next = ath_rc_priv->valid_rate_index[j+1]; 457*c0c93480Slin wang - Sun Microsystems - Beijing China 458*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate_table->info[idx].ratekbps > 459*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[idx_next].ratekbps) { 460*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_rate_index[j] = idx_next; 461*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_rate_index[j+1] = idx; 462*c0c93480Slin wang - Sun Microsystems - Beijing China } 463*c0c93480Slin wang - Sun Microsystems - Beijing China } 464*c0c93480Slin wang - Sun Microsystems - Beijing China } 465*c0c93480Slin wang - Sun Microsystems - Beijing China } 466*c0c93480Slin wang - Sun Microsystems - Beijing China 467*c0c93480Slin wang - Sun Microsystems - Beijing China static void 468*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) 469*c0c93480Slin wang - Sun Microsystems - Beijing China { 470*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i; 471*c0c93480Slin wang - Sun Microsystems - Beijing China 472*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ath_rc_priv->rate_table_size; i++) 473*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_rate_index[i] = 0; 474*c0c93480Slin wang - Sun Microsystems - Beijing China } 475*c0c93480Slin wang - Sun Microsystems - Beijing China 476*c0c93480Slin wang - Sun Microsystems - Beijing China static inline void 477*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, 478*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t index, int valid_tx_rate) 479*c0c93480Slin wang - Sun Microsystems - Beijing China { 480*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT(index <= ath_rc_priv->rate_table_size); 481*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; 482*c0c93480Slin wang - Sun Microsystems - Beijing China } 483*c0c93480Slin wang - Sun Microsystems - Beijing China 484*c0c93480Slin wang - Sun Microsystems - Beijing China static inline int 485*c0c93480Slin wang - Sun Microsystems - Beijing China /* LINTED E_STATIC_UNUSED */ 486*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv, uint8_t index) 487*c0c93480Slin wang - Sun Microsystems - Beijing China { 488*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT(index <= ath_rc_priv->rate_table_size); 489*c0c93480Slin wang - Sun Microsystems - Beijing China return (ath_rc_priv->valid_rate_index[index]); 490*c0c93480Slin wang - Sun Microsystems - Beijing China } 491*c0c93480Slin wang - Sun Microsystems - Beijing China 492*c0c93480Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 493*c0c93480Slin wang - Sun Microsystems - Beijing China static inline int 494*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, 495*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 496*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t cur_valid_txrate, 497*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t *next_idx) 498*c0c93480Slin wang - Sun Microsystems - Beijing China { 499*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i; 500*c0c93480Slin wang - Sun Microsystems - Beijing China 501*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) { 502*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { 503*c0c93480Slin wang - Sun Microsystems - Beijing China *next_idx = ath_rc_priv->valid_rate_index[i+1]; 504*c0c93480Slin wang - Sun Microsystems - Beijing China return (1); 505*c0c93480Slin wang - Sun Microsystems - Beijing China } 506*c0c93480Slin wang - Sun Microsystems - Beijing China } 507*c0c93480Slin wang - Sun Microsystems - Beijing China 508*c0c93480Slin wang - Sun Microsystems - Beijing China /* No more valid rates */ 509*c0c93480Slin wang - Sun Microsystems - Beijing China *next_idx = 0; 510*c0c93480Slin wang - Sun Microsystems - Beijing China 511*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 512*c0c93480Slin wang - Sun Microsystems - Beijing China } 513*c0c93480Slin wang - Sun Microsystems - Beijing China 514*c0c93480Slin wang - Sun Microsystems - Beijing China /* Return true only for single stream */ 515*c0c93480Slin wang - Sun Microsystems - Beijing China static int 516*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_valid_phyrate(uint32_t phy, uint32_t capflag, int ignore_cw) 517*c0c93480Slin wang - Sun Microsystems - Beijing China { 518*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) 519*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 520*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) 521*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 522*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) 523*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 524*c0c93480Slin wang - Sun Microsystems - Beijing China if (!ignore_cw && WLAN_RC_PHY_HT(phy)) 525*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) 526*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 527*c0c93480Slin wang - Sun Microsystems - Beijing China if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) 528*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 529*c0c93480Slin wang - Sun Microsystems - Beijing China 530*c0c93480Slin wang - Sun Microsystems - Beijing China return (1); 531*c0c93480Slin wang - Sun Microsystems - Beijing China } 532*c0c93480Slin wang - Sun Microsystems - Beijing China 533*c0c93480Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 534*c0c93480Slin wang - Sun Microsystems - Beijing China static inline int 535*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table, 536*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 537*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t cur_valid_txrate, uint8_t *next_idx) 538*c0c93480Slin wang - Sun Microsystems - Beijing China { 539*c0c93480Slin wang - Sun Microsystems - Beijing China int8_t i; 540*c0c93480Slin wang - Sun Microsystems - Beijing China 541*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 1; i < ath_rc_priv->max_valid_rate; i++) { 542*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { 543*c0c93480Slin wang - Sun Microsystems - Beijing China *next_idx = ath_rc_priv->valid_rate_index[i-1]; 544*c0c93480Slin wang - Sun Microsystems - Beijing China return (1); 545*c0c93480Slin wang - Sun Microsystems - Beijing China } 546*c0c93480Slin wang - Sun Microsystems - Beijing China } 547*c0c93480Slin wang - Sun Microsystems - Beijing China 548*c0c93480Slin wang - Sun Microsystems - Beijing China return (0); 549*c0c93480Slin wang - Sun Microsystems - Beijing China } 550*c0c93480Slin wang - Sun Microsystems - Beijing China 551*c0c93480Slin wang - Sun Microsystems - Beijing China static uint8_t 552*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, 553*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, uint32_t capflag) 554*c0c93480Slin wang - Sun Microsystems - Beijing China { 555*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i, hi = 0; 556*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t valid; 557*c0c93480Slin wang - Sun Microsystems - Beijing China 558*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < rate_table->rate_cnt; i++) { 559*c0c93480Slin wang - Sun Microsystems - Beijing China valid = (ath_rc_priv->single_stream ? 560*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[i].valid_single_stream : 561*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[i].valid); 562*c0c93480Slin wang - Sun Microsystems - Beijing China if (valid == 1) { 563*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t phy = rate_table->info[i].phy; 564*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t valid_rate_count = 0; 565*c0c93480Slin wang - Sun Microsystems - Beijing China 566*c0c93480Slin wang - Sun Microsystems - Beijing China if (!arn_rc_valid_phyrate(phy, capflag, 0)) 567*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 568*c0c93480Slin wang - Sun Microsystems - Beijing China 569*c0c93480Slin wang - Sun Microsystems - Beijing China valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; 570*c0c93480Slin wang - Sun Microsystems - Beijing China 571*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv-> 572*c0c93480Slin wang - Sun Microsystems - Beijing China valid_phy_rateidx[phy][valid_rate_count] = i; 573*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_ratecnt[phy] += 1; 574*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_set_valid_txmask(ath_rc_priv, i, 1); 575*c0c93480Slin wang - Sun Microsystems - Beijing China hi = A_MAX(hi, i); 576*c0c93480Slin wang - Sun Microsystems - Beijing China } 577*c0c93480Slin wang - Sun Microsystems - Beijing China } 578*c0c93480Slin wang - Sun Microsystems - Beijing China 579*c0c93480Slin wang - Sun Microsystems - Beijing China return (hi); 580*c0c93480Slin wang - Sun Microsystems - Beijing China } 581*c0c93480Slin wang - Sun Microsystems - Beijing China 582*c0c93480Slin wang - Sun Microsystems - Beijing China static uint8_t 583*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, 584*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, 585*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rateset *rateset, 586*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t capflag) 587*c0c93480Slin wang - Sun Microsystems - Beijing China { 588*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i, j, hi = 0; 589*c0c93480Slin wang - Sun Microsystems - Beijing China 590*c0c93480Slin wang - Sun Microsystems - Beijing China /* Use intersection of working rates and valid rates */ 591*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < rateset->rs_nrates; i++) { 592*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = 0; j < rate_table->rate_cnt; j++) { 593*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t phy = rate_table->info[j].phy; 594*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t valid = (ath_rc_priv->single_stream ? 595*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[j].valid_single_stream : 596*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[j].valid); 597*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t rate = rateset->rs_rates[i]; 598*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t dot11rate = rate_table->info[j].dot11rate; 599*c0c93480Slin wang - Sun Microsystems - Beijing China 600*c0c93480Slin wang - Sun Microsystems - Beijing China /* 601*c0c93480Slin wang - Sun Microsystems - Beijing China * We allow a rate only if its valid and the 602*c0c93480Slin wang - Sun Microsystems - Beijing China * capflag matches one of the validity 603*c0c93480Slin wang - Sun Microsystems - Beijing China * (VALID/VALID_20/VALID_40) flags 604*c0c93480Slin wang - Sun Microsystems - Beijing China */ 605*c0c93480Slin wang - Sun Microsystems - Beijing China if (((rate & 0x7F) == (dot11rate & 0x7F)) && 606*c0c93480Slin wang - Sun Microsystems - Beijing China ((valid & WLAN_RC_CAP_MODE(capflag)) == 607*c0c93480Slin wang - Sun Microsystems - Beijing China WLAN_RC_CAP_MODE(capflag)) && 608*c0c93480Slin wang - Sun Microsystems - Beijing China !WLAN_RC_PHY_HT(phy)) { 609*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t valid_rate_count = 0; 610*c0c93480Slin wang - Sun Microsystems - Beijing China 611*c0c93480Slin wang - Sun Microsystems - Beijing China if (!arn_rc_valid_phyrate(phy, capflag, 0)) 612*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 613*c0c93480Slin wang - Sun Microsystems - Beijing China 614*c0c93480Slin wang - Sun Microsystems - Beijing China valid_rate_count = 615*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_ratecnt[phy]; 616*c0c93480Slin wang - Sun Microsystems - Beijing China 617*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_rateidx[phy] 618*c0c93480Slin wang - Sun Microsystems - Beijing China [valid_rate_count] = j; 619*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_ratecnt[phy] += 1; 620*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_set_valid_txmask(ath_rc_priv, j, 1); 621*c0c93480Slin wang - Sun Microsystems - Beijing China hi = A_MAX(hi, j); 622*c0c93480Slin wang - Sun Microsystems - Beijing China } 623*c0c93480Slin wang - Sun Microsystems - Beijing China } 624*c0c93480Slin wang - Sun Microsystems - Beijing China } 625*c0c93480Slin wang - Sun Microsystems - Beijing China 626*c0c93480Slin wang - Sun Microsystems - Beijing China return (hi); 627*c0c93480Slin wang - Sun Microsystems - Beijing China } 628*c0c93480Slin wang - Sun Microsystems - Beijing China 629*c0c93480Slin wang - Sun Microsystems - Beijing China static uint8_t 630*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, 631*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, 632*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t *mcs_set, uint32_t capflag) 633*c0c93480Slin wang - Sun Microsystems - Beijing China { 634*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rateset *rateset = (struct ath_rateset *)mcs_set; 635*c0c93480Slin wang - Sun Microsystems - Beijing China 636*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i, j, hi = 0; 637*c0c93480Slin wang - Sun Microsystems - Beijing China 638*c0c93480Slin wang - Sun Microsystems - Beijing China /* Use intersection of working rates and valid rates */ 639*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < rateset->rs_nrates; i++) { 640*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = 0; j < rate_table->rate_cnt; j++) { 641*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t phy = rate_table->info[j].phy; 642*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t valid = (ath_rc_priv->single_stream ? 643*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[j].valid_single_stream : 644*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[j].valid); 645*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t rate = rateset->rs_rates[i]; 646*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t dot11rate = rate_table->info[j].dot11rate; 647*c0c93480Slin wang - Sun Microsystems - Beijing China 648*c0c93480Slin wang - Sun Microsystems - Beijing China if (((rate & 0x7F) != (dot11rate & 0x7F)) || 649*c0c93480Slin wang - Sun Microsystems - Beijing China !WLAN_RC_PHY_HT(phy) || 650*c0c93480Slin wang - Sun Microsystems - Beijing China !WLAN_RC_PHY_HT_VALID(valid, capflag)) 651*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 652*c0c93480Slin wang - Sun Microsystems - Beijing China 653*c0c93480Slin wang - Sun Microsystems - Beijing China if (!arn_rc_valid_phyrate(phy, capflag, 0)) 654*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 655*c0c93480Slin wang - Sun Microsystems - Beijing China 656*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_rateidx[phy] 657*c0c93480Slin wang - Sun Microsystems - Beijing China [ath_rc_priv->valid_phy_ratecnt[phy]] = j; 658*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_ratecnt[phy] += 1; 659*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_set_valid_txmask(ath_rc_priv, j, 1); 660*c0c93480Slin wang - Sun Microsystems - Beijing China hi = A_MAX(hi, j); 661*c0c93480Slin wang - Sun Microsystems - Beijing China } 662*c0c93480Slin wang - Sun Microsystems - Beijing China } 663*c0c93480Slin wang - Sun Microsystems - Beijing China 664*c0c93480Slin wang - Sun Microsystems - Beijing China return (hi); 665*c0c93480Slin wang - Sun Microsystems - Beijing China } 666*c0c93480Slin wang - Sun Microsystems - Beijing China 667*c0c93480Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 668*c0c93480Slin wang - Sun Microsystems - Beijing China static uint8_t 669*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_ratefind_ht(struct arn_softc *sc, 670*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 671*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, 672*c0c93480Slin wang - Sun Microsystems - Beijing China int probe_allowed, int *is_probing, 673*c0c93480Slin wang - Sun Microsystems - Beijing China int is_retry) 674*c0c93480Slin wang - Sun Microsystems - Beijing China { 675*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t dt, best_thruput, this_thruput, now_msec; 676*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t rate, next_rate, best_rate, maxindex, minindex; 677*c0c93480Slin wang - Sun Microsystems - Beijing China int8_t rssi_last, rssi_reduce = 0, index = 0; 678*c0c93480Slin wang - Sun Microsystems - Beijing China 679*c0c93480Slin wang - Sun Microsystems - Beijing China *is_probing = 0; 680*c0c93480Slin wang - Sun Microsystems - Beijing China 681*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_last = median(ath_rc_priv->rssi_last, 682*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last_prev, 683*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last_prev2); 684*c0c93480Slin wang - Sun Microsystems - Beijing China 685*c0c93480Slin wang - Sun Microsystems - Beijing China /* 686*c0c93480Slin wang - Sun Microsystems - Beijing China * Age (reduce) last ack rssi based on how old it is. 687*c0c93480Slin wang - Sun Microsystems - Beijing China * The bizarre numbers are so the delta is 160msec, 688*c0c93480Slin wang - Sun Microsystems - Beijing China * meaning we divide by 16. 689*c0c93480Slin wang - Sun Microsystems - Beijing China * 0msec <= dt <= 25msec: don't derate 690*c0c93480Slin wang - Sun Microsystems - Beijing China * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB 691*c0c93480Slin wang - Sun Microsystems - Beijing China * 185msec <= dt: derate by 10dB 692*c0c93480Slin wang - Sun Microsystems - Beijing China */ 693*c0c93480Slin wang - Sun Microsystems - Beijing China 694*c0c93480Slin wang - Sun Microsystems - Beijing China /* now_msec = jiffies_to_msecs(jiffies); */ 695*c0c93480Slin wang - Sun Microsystems - Beijing China now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */ 696*c0c93480Slin wang - Sun Microsystems - Beijing China dt = now_msec - ath_rc_priv->rssi_time; 697*c0c93480Slin wang - Sun Microsystems - Beijing China 698*c0c93480Slin wang - Sun Microsystems - Beijing China if (dt >= 185) 699*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_reduce = 10; 700*c0c93480Slin wang - Sun Microsystems - Beijing China else if (dt >= 25) 701*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_reduce = (uint8_t)((dt - 25) >> 4); 702*c0c93480Slin wang - Sun Microsystems - Beijing China 703*c0c93480Slin wang - Sun Microsystems - Beijing China /* Now reduce rssi_last by rssi_reduce */ 704*c0c93480Slin wang - Sun Microsystems - Beijing China if (rssi_last < rssi_reduce) 705*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_last = 0; 706*c0c93480Slin wang - Sun Microsystems - Beijing China else 707*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_last -= rssi_reduce; 708*c0c93480Slin wang - Sun Microsystems - Beijing China 709*c0c93480Slin wang - Sun Microsystems - Beijing China /* 710*c0c93480Slin wang - Sun Microsystems - Beijing China * Now look up the rate in the rssi table and return it. 711*c0c93480Slin wang - Sun Microsystems - Beijing China * If no rates match then we return 0 (lowest rate) 712*c0c93480Slin wang - Sun Microsystems - Beijing China */ 713*c0c93480Slin wang - Sun Microsystems - Beijing China 714*c0c93480Slin wang - Sun Microsystems - Beijing China best_thruput = 0; 715*c0c93480Slin wang - Sun Microsystems - Beijing China maxindex = ath_rc_priv->max_valid_rate-1; 716*c0c93480Slin wang - Sun Microsystems - Beijing China 717*c0c93480Slin wang - Sun Microsystems - Beijing China minindex = 0; 718*c0c93480Slin wang - Sun Microsystems - Beijing China best_rate = minindex; 719*c0c93480Slin wang - Sun Microsystems - Beijing China 720*c0c93480Slin wang - Sun Microsystems - Beijing China /* 721*c0c93480Slin wang - Sun Microsystems - Beijing China * Try the higher rate first. It will reduce memory moving time 722*c0c93480Slin wang - Sun Microsystems - Beijing China * if we have very good channel characteristics. 723*c0c93480Slin wang - Sun Microsystems - Beijing China */ 724*c0c93480Slin wang - Sun Microsystems - Beijing China for (index = maxindex; index >= minindex; index--) { 725*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t per_thres; 726*c0c93480Slin wang - Sun Microsystems - Beijing China 727*c0c93480Slin wang - Sun Microsystems - Beijing China rate = ath_rc_priv->valid_rate_index[index]; 728*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate > ath_rc_priv->rate_max_phy) 729*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 730*c0c93480Slin wang - Sun Microsystems - Beijing China 731*c0c93480Slin wang - Sun Microsystems - Beijing China /* 732*c0c93480Slin wang - Sun Microsystems - Beijing China * For TCP the average collision rate is around 11%, 733*c0c93480Slin wang - Sun Microsystems - Beijing China * so we ignore PERs less than this. This is to 734*c0c93480Slin wang - Sun Microsystems - Beijing China * prevent the rate we are currently using (whose 735*c0c93480Slin wang - Sun Microsystems - Beijing China * PER might be in the 10-15 range because of TCP 736*c0c93480Slin wang - Sun Microsystems - Beijing China * collisions) looking worse than the next lower 737*c0c93480Slin wang - Sun Microsystems - Beijing China * rate whose PER has decayed close to 0. If we 738*c0c93480Slin wang - Sun Microsystems - Beijing China * used to next lower rate, its PER would grow to 739*c0c93480Slin wang - Sun Microsystems - Beijing China * 10-15 and we would be worse off then staying 740*c0c93480Slin wang - Sun Microsystems - Beijing China * at the current rate. 741*c0c93480Slin wang - Sun Microsystems - Beijing China */ 742*c0c93480Slin wang - Sun Microsystems - Beijing China per_thres = ath_rc_priv->state[rate].per; 743*c0c93480Slin wang - Sun Microsystems - Beijing China if (per_thres < 12) 744*c0c93480Slin wang - Sun Microsystems - Beijing China per_thres = 12; 745*c0c93480Slin wang - Sun Microsystems - Beijing China 746*c0c93480Slin wang - Sun Microsystems - Beijing China this_thruput = rate_table->info[rate].user_ratekbps * 747*c0c93480Slin wang - Sun Microsystems - Beijing China (100 - per_thres); 748*c0c93480Slin wang - Sun Microsystems - Beijing China 749*c0c93480Slin wang - Sun Microsystems - Beijing China if (best_thruput <= this_thruput) { 750*c0c93480Slin wang - Sun Microsystems - Beijing China best_thruput = this_thruput; 751*c0c93480Slin wang - Sun Microsystems - Beijing China best_rate = rate; 752*c0c93480Slin wang - Sun Microsystems - Beijing China } 753*c0c93480Slin wang - Sun Microsystems - Beijing China } 754*c0c93480Slin wang - Sun Microsystems - Beijing China 755*c0c93480Slin wang - Sun Microsystems - Beijing China rate = best_rate; 756*c0c93480Slin wang - Sun Microsystems - Beijing China 757*c0c93480Slin wang - Sun Microsystems - Beijing China /* 758*c0c93480Slin wang - Sun Microsystems - Beijing China * if we are retrying for more than half the number 759*c0c93480Slin wang - Sun Microsystems - Beijing China * of max retries, use the min rate for the next retry 760*c0c93480Slin wang - Sun Microsystems - Beijing China */ 761*c0c93480Slin wang - Sun Microsystems - Beijing China if (is_retry) 762*c0c93480Slin wang - Sun Microsystems - Beijing China rate = ath_rc_priv->valid_rate_index[minindex]; 763*c0c93480Slin wang - Sun Microsystems - Beijing China 764*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last_lookup = rssi_last; 765*c0c93480Slin wang - Sun Microsystems - Beijing China 766*c0c93480Slin wang - Sun Microsystems - Beijing China /* 767*c0c93480Slin wang - Sun Microsystems - Beijing China * Must check the actual rate (ratekbps) to account for 768*c0c93480Slin wang - Sun Microsystems - Beijing China * non-monoticity of 11g's rate table 769*c0c93480Slin wang - Sun Microsystems - Beijing China */ 770*c0c93480Slin wang - Sun Microsystems - Beijing China 771*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) { 772*c0c93480Slin wang - Sun Microsystems - Beijing China rate = ath_rc_priv->rate_max_phy; 773*c0c93480Slin wang - Sun Microsystems - Beijing China 774*c0c93480Slin wang - Sun Microsystems - Beijing China /* Probe the next allowed phy state */ 775*c0c93480Slin wang - Sun Microsystems - Beijing China /* FIXME:XXXX Check to make sure ratMax is checked properly */ 776*c0c93480Slin wang - Sun Microsystems - Beijing China if (arn_rc_get_nextvalid_txrate(rate_table, 777*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, rate, &next_rate) && 778*c0c93480Slin wang - Sun Microsystems - Beijing China (now_msec - ath_rc_priv->probe_time > 779*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->probe_interval) && 780*c0c93480Slin wang - Sun Microsystems - Beijing China (ath_rc_priv->hw_maxretry_pktcnt >= 1)) { 781*c0c93480Slin wang - Sun Microsystems - Beijing China rate = next_rate; 782*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate = rate; 783*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_time = now_msec; 784*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->hw_maxretry_pktcnt = 0; 785*c0c93480Slin wang - Sun Microsystems - Beijing China *is_probing = 1; 786*c0c93480Slin wang - Sun Microsystems - Beijing China } 787*c0c93480Slin wang - Sun Microsystems - Beijing China } 788*c0c93480Slin wang - Sun Microsystems - Beijing China 789*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate > (ath_rc_priv->rate_table_size - 1)) 790*c0c93480Slin wang - Sun Microsystems - Beijing China rate = ath_rc_priv->rate_table_size - 1; 791*c0c93480Slin wang - Sun Microsystems - Beijing China 792*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || 793*c0c93480Slin wang - Sun Microsystems - Beijing China (rate_table->info[rate].valid_single_stream && 794*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->single_stream)); 795*c0c93480Slin wang - Sun Microsystems - Beijing China 796*c0c93480Slin wang - Sun Microsystems - Beijing China return (rate); 797*c0c93480Slin wang - Sun Microsystems - Beijing China } 798*c0c93480Slin wang - Sun Microsystems - Beijing China 799*c0c93480Slin wang - Sun Microsystems - Beijing China static void 800*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_set_series(struct ath_rate_table *rate_table, 801*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath9k_tx_rate *rate, 802*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t tries, 803*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t rix, 804*c0c93480Slin wang - Sun Microsystems - Beijing China int rtsctsenable) 805*c0c93480Slin wang - Sun Microsystems - Beijing China { 806*c0c93480Slin wang - Sun Microsystems - Beijing China #if 0 807*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_node *in; 808*c0c93480Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 809*c0c93480Slin wang - Sun Microsystems - Beijing China #endif 810*c0c93480Slin wang - Sun Microsystems - Beijing China rate->count = tries; 811*c0c93480Slin wang - Sun Microsystems - Beijing China rate->idx = rix; 812*c0c93480Slin wang - Sun Microsystems - Beijing China 813*c0c93480Slin wang - Sun Microsystems - Beijing China if (rtsctsenable) 814*c0c93480Slin wang - Sun Microsystems - Beijing China rate->flags |= ATH9K_TX_RC_USE_RTS_CTS; 815*c0c93480Slin wang - Sun Microsystems - Beijing China #if 0 816*c0c93480Slin wang - Sun Microsystems - Beijing China if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && 817*c0c93480Slin wang - Sun Microsystems - Beijing China (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 818*c0c93480Slin wang - Sun Microsystems - Beijing China rate->flags |= ATH9K_TX_RC_USE_SHORT_PREAMBLE; 819*c0c93480Slin wang - Sun Microsystems - Beijing China } 820*c0c93480Slin wang - Sun Microsystems - Beijing China #endif 821*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 822*c0c93480Slin wang - Sun Microsystems - Beijing China rate->flags |= ATH9K_TX_RC_40_MHZ_WIDTH; 823*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) 824*c0c93480Slin wang - Sun Microsystems - Beijing China rate->flags |= ATH9K_TX_RC_SHORT_GI; 825*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) 826*c0c93480Slin wang - Sun Microsystems - Beijing China rate->flags |= ATH9K_TX_RC_MCS; 827*c0c93480Slin wang - Sun Microsystems - Beijing China } 828*c0c93480Slin wang - Sun Microsystems - Beijing China 829*c0c93480Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 830*c0c93480Slin wang - Sun Microsystems - Beijing China static uint8_t 831*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_getidx(struct arn_softc *sc, 832*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 833*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, 834*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t rix, uint16_t stepdown, 835*c0c93480Slin wang - Sun Microsystems - Beijing China uint16_t min_rate) 836*c0c93480Slin wang - Sun Microsystems - Beijing China { 837*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t j; 838*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t nextindex; 839*c0c93480Slin wang - Sun Microsystems - Beijing China 840*c0c93480Slin wang - Sun Microsystems - Beijing China if (min_rate) { 841*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = RATE_TABLE_SIZE; j > 0; j--) { 842*c0c93480Slin wang - Sun Microsystems - Beijing China if (arn_rc_get_nextlowervalid_txrate(rate_table, 843*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, rix, &nextindex)) 844*c0c93480Slin wang - Sun Microsystems - Beijing China rix = nextindex; 845*c0c93480Slin wang - Sun Microsystems - Beijing China else 846*c0c93480Slin wang - Sun Microsystems - Beijing China break; 847*c0c93480Slin wang - Sun Microsystems - Beijing China } 848*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 849*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = stepdown; j > 0; j--) { 850*c0c93480Slin wang - Sun Microsystems - Beijing China if (arn_rc_get_nextlowervalid_txrate(rate_table, 851*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, rix, &nextindex)) 852*c0c93480Slin wang - Sun Microsystems - Beijing China rix = nextindex; 853*c0c93480Slin wang - Sun Microsystems - Beijing China else 854*c0c93480Slin wang - Sun Microsystems - Beijing China break; 855*c0c93480Slin wang - Sun Microsystems - Beijing China } 856*c0c93480Slin wang - Sun Microsystems - Beijing China } 857*c0c93480Slin wang - Sun Microsystems - Beijing China return (rix); 858*c0c93480Slin wang - Sun Microsystems - Beijing China } 859*c0c93480Slin wang - Sun Microsystems - Beijing China 860*c0c93480Slin wang - Sun Microsystems - Beijing China static void 861*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_ratefind(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv, 862*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_buf *bf, int num_tries, int num_rates, int *is_probe, 863*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t is_retry) 864*c0c93480Slin wang - Sun Microsystems - Beijing China { 865*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t try_per_rate = 0, i = 0, rix, nrix; 866*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table; 867*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath9k_tx_rate *rates = bf->rates; 868*c0c93480Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 869*c0c93480Slin wang - Sun Microsystems - Beijing China 870*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table = sc->sc_currates; 871*c0c93480Slin wang - Sun Microsystems - Beijing China rix = arn_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1, 872*c0c93480Slin wang - Sun Microsystems - Beijing China is_probe, is_retry); 873*c0c93480Slin wang - Sun Microsystems - Beijing China nrix = rix; 874*c0c93480Slin wang - Sun Microsystems - Beijing China 875*c0c93480Slin wang - Sun Microsystems - Beijing China if (*is_probe) { 876*c0c93480Slin wang - Sun Microsystems - Beijing China /* 877*c0c93480Slin wang - Sun Microsystems - Beijing China * set one try for probe rates. For the 878*c0c93480Slin wang - Sun Microsystems - Beijing China * probes don't enable rts 879*c0c93480Slin wang - Sun Microsystems - Beijing China */ 880*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_set_series(rate_table, 881*c0c93480Slin wang - Sun Microsystems - Beijing China &rates[i++], 1, nrix, 0); 882*c0c93480Slin wang - Sun Microsystems - Beijing China 883*c0c93480Slin wang - Sun Microsystems - Beijing China try_per_rate = (num_tries/num_rates); 884*c0c93480Slin wang - Sun Microsystems - Beijing China /* 885*c0c93480Slin wang - Sun Microsystems - Beijing China * Get the next tried/allowed rate. No RTS for the next series 886*c0c93480Slin wang - Sun Microsystems - Beijing China * after the probe rate 887*c0c93480Slin wang - Sun Microsystems - Beijing China */ 888*c0c93480Slin wang - Sun Microsystems - Beijing China nrix = arn_rc_rate_getidx(sc, 889*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, rate_table, nrix, 1, 0); 890*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_set_series(rate_table, 891*c0c93480Slin wang - Sun Microsystems - Beijing China &rates[i++], try_per_rate, nrix, 0); 892*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 893*c0c93480Slin wang - Sun Microsystems - Beijing China try_per_rate = (num_tries/num_rates); 894*c0c93480Slin wang - Sun Microsystems - Beijing China /* Set the choosen rate. No RTS for first series entry. */ 895*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_set_series(rate_table, 896*c0c93480Slin wang - Sun Microsystems - Beijing China &rates[i++], try_per_rate, nrix, 0); 897*c0c93480Slin wang - Sun Microsystems - Beijing China } 898*c0c93480Slin wang - Sun Microsystems - Beijing China 899*c0c93480Slin wang - Sun Microsystems - Beijing China /* Fill in the other rates for multirate retry */ 900*c0c93480Slin wang - Sun Microsystems - Beijing China for (; i < num_rates; i++) { 901*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t try_num; 902*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t min_rate; 903*c0c93480Slin wang - Sun Microsystems - Beijing China 904*c0c93480Slin wang - Sun Microsystems - Beijing China try_num = ((i + 1) == num_rates) ? 905*c0c93480Slin wang - Sun Microsystems - Beijing China num_tries - (try_per_rate * i) : try_per_rate; 906*c0c93480Slin wang - Sun Microsystems - Beijing China /* LINTED E_FALSE_LOGICAL_EXPR */ 907*c0c93480Slin wang - Sun Microsystems - Beijing China min_rate = (((i + 1) == num_rates) && 0); 908*c0c93480Slin wang - Sun Microsystems - Beijing China 909*c0c93480Slin wang - Sun Microsystems - Beijing China nrix = arn_rc_rate_getidx(sc, ath_rc_priv, 910*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table, nrix, 1, min_rate); 911*c0c93480Slin wang - Sun Microsystems - Beijing China /* All other rates in the series have RTS enabled */ 912*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_rate_set_series(rate_table, &rates[i], try_num, nrix, 1); 913*c0c93480Slin wang - Sun Microsystems - Beijing China } 914*c0c93480Slin wang - Sun Microsystems - Beijing China 915*c0c93480Slin wang - Sun Microsystems - Beijing China /* 916*c0c93480Slin wang - Sun Microsystems - Beijing China * NB:Change rate series to enable aggregation when operating 917*c0c93480Slin wang - Sun Microsystems - Beijing China * at lower MCS rates. When first rate in series is MCS2 918*c0c93480Slin wang - Sun Microsystems - Beijing China * in HT40 @ 2.4GHz, series should look like: 919*c0c93480Slin wang - Sun Microsystems - Beijing China * 920*c0c93480Slin wang - Sun Microsystems - Beijing China * {MCS2, MCS1, MCS0, MCS0}. 921*c0c93480Slin wang - Sun Microsystems - Beijing China * 922*c0c93480Slin wang - Sun Microsystems - Beijing China * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should 923*c0c93480Slin wang - Sun Microsystems - Beijing China * look like: 924*c0c93480Slin wang - Sun Microsystems - Beijing China * 925*c0c93480Slin wang - Sun Microsystems - Beijing China * {MCS3, MCS2, MCS1, MCS1} 926*c0c93480Slin wang - Sun Microsystems - Beijing China * 927*c0c93480Slin wang - Sun Microsystems - Beijing China * So, set fourth rate in series to be same as third one for 928*c0c93480Slin wang - Sun Microsystems - Beijing China * above conditions. 929*c0c93480Slin wang - Sun Microsystems - Beijing China */ 930*c0c93480Slin wang - Sun Microsystems - Beijing China 931*c0c93480Slin wang - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_HTG(ic->ic_curchan)) { 932*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t dot11rate = rate_table->info[rix].dot11rate; 933*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t phy = rate_table->info[rix].phy; 934*c0c93480Slin wang - Sun Microsystems - Beijing China if (i == 4 && 935*c0c93480Slin wang - Sun Microsystems - Beijing China ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || 936*c0c93480Slin wang - Sun Microsystems - Beijing China (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { 937*c0c93480Slin wang - Sun Microsystems - Beijing China rates[3].idx = rates[2].idx; 938*c0c93480Slin wang - Sun Microsystems - Beijing China rates[3].flags = rates[2].flags; 939*c0c93480Slin wang - Sun Microsystems - Beijing China } 940*c0c93480Slin wang - Sun Microsystems - Beijing China } 941*c0c93480Slin wang - Sun Microsystems - Beijing China } 942*c0c93480Slin wang - Sun Microsystems - Beijing China 943*c0c93480Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 944*c0c93480Slin wang - Sun Microsystems - Beijing China static boolean_t 945*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_update_per(struct arn_softc *sc, 946*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table, 947*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 948*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_tx_info_priv *tx_info_priv, 949*c0c93480Slin wang - Sun Microsystems - Beijing China int tx_rate, int xretries, int retries, 950*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t now_msec) 951*c0c93480Slin wang - Sun Microsystems - Beijing China { 952*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t state_change = B_FALSE; 953*c0c93480Slin wang - Sun Microsystems - Beijing China int count; 954*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t last_per; 955*c0c93480Slin wang - Sun Microsystems - Beijing China static uint32_t nretry_to_per_lookup[10] = { 956*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 0 / 1, 957*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 1 / 4, 958*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 1 / 2, 959*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 3 / 4, 960*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 4 / 5, 961*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 5 / 6, 962*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 6 / 7, 963*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 7 / 8, 964*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 8 / 9, 965*c0c93480Slin wang - Sun Microsystems - Beijing China 100 * 9 / 10 966*c0c93480Slin wang - Sun Microsystems - Beijing China }; 967*c0c93480Slin wang - Sun Microsystems - Beijing China 968*c0c93480Slin wang - Sun Microsystems - Beijing China last_per = ath_rc_priv->state[tx_rate].per; 969*c0c93480Slin wang - Sun Microsystems - Beijing China 970*c0c93480Slin wang - Sun Microsystems - Beijing China if (xretries) { 971*c0c93480Slin wang - Sun Microsystems - Beijing China if (xretries == 1) { 972*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].per += 30; 973*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[tx_rate].per > 100) 974*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].per = 100; 975*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 976*c0c93480Slin wang - Sun Microsystems - Beijing China /* xretries == 2 */ 977*c0c93480Slin wang - Sun Microsystems - Beijing China count = ARRAY_SIZE(nretry_to_per_lookup); 978*c0c93480Slin wang - Sun Microsystems - Beijing China if (retries >= count) 979*c0c93480Slin wang - Sun Microsystems - Beijing China retries = count - 1; 980*c0c93480Slin wang - Sun Microsystems - Beijing China 981*c0c93480Slin wang - Sun Microsystems - Beijing China /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 982*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].per = 983*c0c93480Slin wang - Sun Microsystems - Beijing China (uint8_t)(last_per - (last_per >> 3) + (100 >> 3)); 984*c0c93480Slin wang - Sun Microsystems - Beijing China } 985*c0c93480Slin wang - Sun Microsystems - Beijing China 986*c0c93480Slin wang - Sun Microsystems - Beijing China /* xretries == 1 or 2 */ 987*c0c93480Slin wang - Sun Microsystems - Beijing China 988*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->probe_rate == tx_rate) 989*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate = 0; 990*c0c93480Slin wang - Sun Microsystems - Beijing China 991*c0c93480Slin wang - Sun Microsystems - Beijing China } else { /* xretries == 0 */ 992*c0c93480Slin wang - Sun Microsystems - Beijing China count = ARRAY_SIZE(nretry_to_per_lookup); 993*c0c93480Slin wang - Sun Microsystems - Beijing China if (retries >= count) 994*c0c93480Slin wang - Sun Microsystems - Beijing China retries = count - 1; 995*c0c93480Slin wang - Sun Microsystems - Beijing China 996*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_info_priv->n_bad_frames) { 997*c0c93480Slin wang - Sun Microsystems - Beijing China /* 998*c0c93480Slin wang - Sun Microsystems - Beijing China * new_PER = 7/8*old_PER + 1/8*(currentPER) 999*c0c93480Slin wang - Sun Microsystems - Beijing China * Assuming that n_frames is not 0. The current PER 1000*c0c93480Slin wang - Sun Microsystems - Beijing China * from the retries is 100 * retries / (retries+1), 1001*c0c93480Slin wang - Sun Microsystems - Beijing China * since the first retries attempts failed, and the 1002*c0c93480Slin wang - Sun Microsystems - Beijing China * next one worked. For the one that worked, 1003*c0c93480Slin wang - Sun Microsystems - Beijing China * n_bad_frames subframes out of n_frames wored, 1004*c0c93480Slin wang - Sun Microsystems - Beijing China * so the PER for that part is 1005*c0c93480Slin wang - Sun Microsystems - Beijing China * 100 * n_bad_frames / n_frames, and it contributes 1006*c0c93480Slin wang - Sun Microsystems - Beijing China * 100 * n_bad_frames / (n_frames * (retries+1)) to 1007*c0c93480Slin wang - Sun Microsystems - Beijing China * the above PER. The expression below is a 1008*c0c93480Slin wang - Sun Microsystems - Beijing China * simplified version of the sum of these two terms. 1009*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1010*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_info_priv->n_frames > 0) { 1011*c0c93480Slin wang - Sun Microsystems - Beijing China int n_frames, n_bad_frames; 1012*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t cur_per, new_per; 1013*c0c93480Slin wang - Sun Microsystems - Beijing China 1014*c0c93480Slin wang - Sun Microsystems - Beijing China n_bad_frames = retries * 1015*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->n_frames + 1016*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->n_bad_frames; 1017*c0c93480Slin wang - Sun Microsystems - Beijing China n_frames = 1018*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->n_frames * (retries + 1); 1019*c0c93480Slin wang - Sun Microsystems - Beijing China cur_per = 1020*c0c93480Slin wang - Sun Microsystems - Beijing China (100 * n_bad_frames / n_frames) >> 3; 1021*c0c93480Slin wang - Sun Microsystems - Beijing China new_per = (uint8_t) 1022*c0c93480Slin wang - Sun Microsystems - Beijing China (last_per - (last_per >> 3) + cur_per); 1023*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].per = new_per; 1024*c0c93480Slin wang - Sun Microsystems - Beijing China } 1025*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 1026*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].per = 1027*c0c93480Slin wang - Sun Microsystems - Beijing China (uint8_t)(last_per - (last_per >> 3) + 1028*c0c93480Slin wang - Sun Microsystems - Beijing China (nretry_to_per_lookup[retries] >> 3)); 1029*c0c93480Slin wang - Sun Microsystems - Beijing China } 1030*c0c93480Slin wang - Sun Microsystems - Beijing China 1031*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev; 1032*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last_prev = ath_rc_priv->rssi_last; 1033*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi; 1034*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_time = now_msec; 1035*c0c93480Slin wang - Sun Microsystems - Beijing China 1036*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1037*c0c93480Slin wang - Sun Microsystems - Beijing China * If we got at most one retry then increase the max rate if 1038*c0c93480Slin wang - Sun Microsystems - Beijing China * this was a probe. Otherwise, ignore the probe. 1039*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1040*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->probe_rate && 1041*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate == tx_rate) { 1042*c0c93480Slin wang - Sun Microsystems - Beijing China if (retries > 0 || 2 * tx_info_priv->n_bad_frames > 1043*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->n_frames) { 1044*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1045*c0c93480Slin wang - Sun Microsystems - Beijing China * Since we probed with just a single attempt, 1046*c0c93480Slin wang - Sun Microsystems - Beijing China * any retries means the probe failed. Also, 1047*c0c93480Slin wang - Sun Microsystems - Beijing China * if the attempt worked, but more than half 1048*c0c93480Slin wang - Sun Microsystems - Beijing China * the subframes were bad then also consider 1049*c0c93480Slin wang - Sun Microsystems - Beijing China * the probe a failure. 1050*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1051*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate = 0; 1052*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 1053*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t probe_rate = 0; 1054*c0c93480Slin wang - Sun Microsystems - Beijing China 1055*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_max_phy = 1056*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate; 1057*c0c93480Slin wang - Sun Microsystems - Beijing China probe_rate = ath_rc_priv->probe_rate; 1058*c0c93480Slin wang - Sun Microsystems - Beijing China 1059*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[probe_rate].per > 30) 1060*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[probe_rate].per = 20; 1061*c0c93480Slin wang - Sun Microsystems - Beijing China 1062*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_rate = 0; 1063*c0c93480Slin wang - Sun Microsystems - Beijing China 1064*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1065*c0c93480Slin wang - Sun Microsystems - Beijing China * Since this probe succeeded, we allow the next 1066*c0c93480Slin wang - Sun Microsystems - Beijing China * probe twice as soon. This allows the maxRate 1067*c0c93480Slin wang - Sun Microsystems - Beijing China * to move up faster if the probes are 1068*c0c93480Slin wang - Sun Microsystems - Beijing China * succesful. 1069*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1070*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_time = 1071*c0c93480Slin wang - Sun Microsystems - Beijing China now_msec - rate_table->probe_interval / 2; 1072*c0c93480Slin wang - Sun Microsystems - Beijing China } 1073*c0c93480Slin wang - Sun Microsystems - Beijing China } 1074*c0c93480Slin wang - Sun Microsystems - Beijing China 1075*c0c93480Slin wang - Sun Microsystems - Beijing China if (retries > 0) { 1076*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1077*c0c93480Slin wang - Sun Microsystems - Beijing China * Don't update anything. We don't know if 1078*c0c93480Slin wang - Sun Microsystems - Beijing China * this was because of collisions or poor signal. 1079*c0c93480Slin wang - Sun Microsystems - Beijing China * 1080*c0c93480Slin wang - Sun Microsystems - Beijing China * Later: if rssi_ack is close to 1081*c0c93480Slin wang - Sun Microsystems - Beijing China * ath_rc_priv->state[txRate].rssi_thres and we see lots 1082*c0c93480Slin wang - Sun Microsystems - Beijing China * of retries, then we could increase 1083*c0c93480Slin wang - Sun Microsystems - Beijing China * ath_rc_priv->state[txRate].rssi_thres. 1084*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1085*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->hw_maxretry_pktcnt = 0; 1086*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 1087*c0c93480Slin wang - Sun Microsystems - Beijing China int32_t rssi_ackAvg; 1088*c0c93480Slin wang - Sun Microsystems - Beijing China int8_t rssi_thres; 1089*c0c93480Slin wang - Sun Microsystems - Beijing China int8_t rssi_ack_vmin; 1090*c0c93480Slin wang - Sun Microsystems - Beijing China 1091*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1092*c0c93480Slin wang - Sun Microsystems - Beijing China * It worked with no retries. First ignore bogus (small) 1093*c0c93480Slin wang - Sun Microsystems - Beijing China * rssi_ack values. 1094*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1095*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_rate == ath_rc_priv->rate_max_phy && 1096*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->hw_maxretry_pktcnt < 255) { 1097*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->hw_maxretry_pktcnt++; 1098*c0c93480Slin wang - Sun Microsystems - Beijing China } 1099*c0c93480Slin wang - Sun Microsystems - Beijing China 1100*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_info_priv->tx.ts_rssi < 1101*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].rssi_ack_validmin) 1102*c0c93480Slin wang - Sun Microsystems - Beijing China goto exit; 1103*c0c93480Slin wang - Sun Microsystems - Beijing China 1104*c0c93480Slin wang - Sun Microsystems - Beijing China /* Average the rssi */ 1105*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_rate != ath_rc_priv->rssi_sum_rate) { 1106*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum_rate = tx_rate; 1107*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum = 1108*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum_cnt = 0; 1109*c0c93480Slin wang - Sun Microsystems - Beijing China } 1110*c0c93480Slin wang - Sun Microsystems - Beijing China 1111*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi; 1112*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum_cnt++; 1113*c0c93480Slin wang - Sun Microsystems - Beijing China 1114*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->rssi_sum_cnt < 4) 1115*c0c93480Slin wang - Sun Microsystems - Beijing China goto exit; 1116*c0c93480Slin wang - Sun Microsystems - Beijing China 1117*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_ackAvg = 1118*c0c93480Slin wang - Sun Microsystems - Beijing China (ath_rc_priv->rssi_sum + 2) / 4; 1119*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_thres = 1120*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].rssi_thres; 1121*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_ack_vmin = 1122*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].rssi_ack_validmin; 1123*c0c93480Slin wang - Sun Microsystems - Beijing China 1124*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum = 1125*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_sum_cnt = 0; 1126*c0c93480Slin wang - Sun Microsystems - Beijing China 1127*c0c93480Slin wang - Sun Microsystems - Beijing China /* Now reduce the current rssi threshold */ 1128*c0c93480Slin wang - Sun Microsystems - Beijing China if ((rssi_ackAvg < rssi_thres + 2) && 1129*c0c93480Slin wang - Sun Microsystems - Beijing China (rssi_thres > rssi_ack_vmin)) { 1130*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[tx_rate].rssi_thres--; 1131*c0c93480Slin wang - Sun Microsystems - Beijing China } 1132*c0c93480Slin wang - Sun Microsystems - Beijing China 1133*c0c93480Slin wang - Sun Microsystems - Beijing China state_change = B_TRUE; 1134*c0c93480Slin wang - Sun Microsystems - Beijing China } 1135*c0c93480Slin wang - Sun Microsystems - Beijing China } 1136*c0c93480Slin wang - Sun Microsystems - Beijing China exit: 1137*c0c93480Slin wang - Sun Microsystems - Beijing China return (state_change); 1138*c0c93480Slin wang - Sun Microsystems - Beijing China } 1139*c0c93480Slin wang - Sun Microsystems - Beijing China 1140*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1141*c0c93480Slin wang - Sun Microsystems - Beijing China * Update PER, RSSI and whatever else that the code thinks 1142*c0c93480Slin wang - Sun Microsystems - Beijing China * it is doing. If you can make sense of all this, you really 1143*c0c93480Slin wang - Sun Microsystems - Beijing China * need to go out more. 1144*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1145*c0c93480Slin wang - Sun Microsystems - Beijing China static void 1146*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_update_ht(struct arn_softc *sc, 1147*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 1148*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_tx_info_priv *tx_info_priv, 1149*c0c93480Slin wang - Sun Microsystems - Beijing China int tx_rate, int xretries, int retries) 1150*c0c93480Slin wang - Sun Microsystems - Beijing China { 1151*c0c93480Slin wang - Sun Microsystems - Beijing China #define CHK_RSSI(rate) \ 1152*c0c93480Slin wang - Sun Microsystems - Beijing China ((ath_rc_priv->state[(rate)].rssi_thres + \ 1153*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[(rate)].rssi_ack_deltamin) > \ 1154*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[(rate)+1].rssi_thres) 1155*c0c93480Slin wang - Sun Microsystems - Beijing China 1156*c0c93480Slin wang - Sun Microsystems - Beijing China /* u32 now_msec = jiffies_to_msecs(jiffies); */ 1157*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */ 1158*c0c93480Slin wang - Sun Microsystems - Beijing China int rate; 1159*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t last_per; 1160*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t state_change = B_FALSE; 1161*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table = sc->sc_currates; 1162*c0c93480Slin wang - Sun Microsystems - Beijing China int size = ath_rc_priv->rate_table_size; 1163*c0c93480Slin wang - Sun Microsystems - Beijing China 1164*c0c93480Slin wang - Sun Microsystems - Beijing China if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) 1165*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1166*c0c93480Slin wang - Sun Microsystems - Beijing China 1167*c0c93480Slin wang - Sun Microsystems - Beijing China /* To compensate for some imbalance between ctrl and ext. channel */ 1168*c0c93480Slin wang - Sun Microsystems - Beijing China 1169*c0c93480Slin wang - Sun Microsystems - Beijing China if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy)) 1170*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->tx.ts_rssi = 1171*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->tx.ts_rssi < 3 ? 0 : 1172*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv->tx.ts_rssi - 3; 1173*c0c93480Slin wang - Sun Microsystems - Beijing China 1174*c0c93480Slin wang - Sun Microsystems - Beijing China last_per = ath_rc_priv->state[tx_rate].per; 1175*c0c93480Slin wang - Sun Microsystems - Beijing China 1176*c0c93480Slin wang - Sun Microsystems - Beijing China /* Update PER first */ 1177*c0c93480Slin wang - Sun Microsystems - Beijing China state_change = arn_rc_update_per(sc, rate_table, ath_rc_priv, 1178*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv, tx_rate, xretries, 1179*c0c93480Slin wang - Sun Microsystems - Beijing China retries, now_msec); 1180*c0c93480Slin wang - Sun Microsystems - Beijing China 1181*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1182*c0c93480Slin wang - Sun Microsystems - Beijing China * If this rate looks bad (high PER) then stop using it for 1183*c0c93480Slin wang - Sun Microsystems - Beijing China * a while (except if we are probing). 1184*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1185*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 && 1186*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].ratekbps <= 1187*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { 1188*c0c93480Slin wang - Sun Microsystems - Beijing China (void) arn_rc_get_nextlowervalid_txrate(rate_table, 1189*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, 1190*c0c93480Slin wang - Sun Microsystems - Beijing China (uint8_t)tx_rate, 1191*c0c93480Slin wang - Sun Microsystems - Beijing China &ath_rc_priv->rate_max_phy); 1192*c0c93480Slin wang - Sun Microsystems - Beijing China 1193*c0c93480Slin wang - Sun Microsystems - Beijing China /* Don't probe for a little while. */ 1194*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->probe_time = now_msec; 1195*c0c93480Slin wang - Sun Microsystems - Beijing China } 1196*c0c93480Slin wang - Sun Microsystems - Beijing China 1197*c0c93480Slin wang - Sun Microsystems - Beijing China if (state_change) { 1198*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1199*c0c93480Slin wang - Sun Microsystems - Beijing China * Make sure the rates above this have higher rssi thresholds. 1200*c0c93480Slin wang - Sun Microsystems - Beijing China * (Note: Monotonicity is kept within the OFDM rates and 1201*c0c93480Slin wang - Sun Microsystems - Beijing China * within the CCK rates. However, no adjustment is 1202*c0c93480Slin wang - Sun Microsystems - Beijing China * made to keep the rssi thresholds monotonically 1203*c0c93480Slin wang - Sun Microsystems - Beijing China * increasing between the CCK and OFDM rates.) 1204*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1205*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = tx_rate; rate < size - 1; rate++) { 1206*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate_table->info[rate+1].phy != 1207*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].phy) 1208*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1209*c0c93480Slin wang - Sun Microsystems - Beijing China 1210*c0c93480Slin wang - Sun Microsystems - Beijing China if (CHK_RSSI(rate)) { 1211*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate+1].rssi_thres = 1212*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].rssi_thres + 1213*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate].rssi_ack_deltamin; 1214*c0c93480Slin wang - Sun Microsystems - Beijing China } 1215*c0c93480Slin wang - Sun Microsystems - Beijing China } 1216*c0c93480Slin wang - Sun Microsystems - Beijing China 1217*c0c93480Slin wang - Sun Microsystems - Beijing China /* Make sure the rates below this have lower rssi thresholds. */ 1218*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = tx_rate - 1; rate >= 0; rate--) { 1219*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate_table->info[rate].phy != 1220*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].phy) 1221*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1222*c0c93480Slin wang - Sun Microsystems - Beijing China 1223*c0c93480Slin wang - Sun Microsystems - Beijing China if (CHK_RSSI(rate)) { 1224*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[rate+1].rssi_thres < 1225*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate].rssi_ack_deltamin) 1226*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].rssi_thres = 0; 1227*c0c93480Slin wang - Sun Microsystems - Beijing China else { 1228*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].rssi_thres = 1229*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate+1]. 1230*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_thres - 1231*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate]. 1232*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_ack_deltamin; 1233*c0c93480Slin wang - Sun Microsystems - Beijing China } 1234*c0c93480Slin wang - Sun Microsystems - Beijing China 1235*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[rate].rssi_thres < 1236*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate].rssi_ack_validmin) { 1237*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].rssi_thres = 1238*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate]. 1239*c0c93480Slin wang - Sun Microsystems - Beijing China rssi_ack_validmin; 1240*c0c93480Slin wang - Sun Microsystems - Beijing China } 1241*c0c93480Slin wang - Sun Microsystems - Beijing China } 1242*c0c93480Slin wang - Sun Microsystems - Beijing China } 1243*c0c93480Slin wang - Sun Microsystems - Beijing China } 1244*c0c93480Slin wang - Sun Microsystems - Beijing China 1245*c0c93480Slin wang - Sun Microsystems - Beijing China /* Make sure the rates below this have lower PER */ 1246*c0c93480Slin wang - Sun Microsystems - Beijing China /* Monotonicity is kept only for rates below the current rate. */ 1247*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[tx_rate].per < last_per) { 1248*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = tx_rate - 1; rate >= 0; rate--) { 1249*c0c93480Slin wang - Sun Microsystems - Beijing China if (rate_table->info[rate].phy != 1250*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[tx_rate].phy) 1251*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1252*c0c93480Slin wang - Sun Microsystems - Beijing China 1253*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[rate].per > 1254*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate+1].per) { 1255*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].per = 1256*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate+1].per; 1257*c0c93480Slin wang - Sun Microsystems - Beijing China } 1258*c0c93480Slin wang - Sun Microsystems - Beijing China } 1259*c0c93480Slin wang - Sun Microsystems - Beijing China } 1260*c0c93480Slin wang - Sun Microsystems - Beijing China 1261*c0c93480Slin wang - Sun Microsystems - Beijing China /* Maintain monotonicity for rates above the current rate */ 1262*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = tx_rate; rate < size - 1; rate++) { 1263*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[rate+1].per < 1264*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].per) 1265*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate+1].per = 1266*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].per; 1267*c0c93480Slin wang - Sun Microsystems - Beijing China } 1268*c0c93480Slin wang - Sun Microsystems - Beijing China 1269*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1270*c0c93480Slin wang - Sun Microsystems - Beijing China * Every so often, we reduce the thresholds and 1271*c0c93480Slin wang - Sun Microsystems - Beijing China * PER (different for CCK and OFDM). 1272*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1273*c0c93480Slin wang - Sun Microsystems - Beijing China if (now_msec - ath_rc_priv->rssi_down_time >= 1274*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->rssi_reduce_interval) { 1275*c0c93480Slin wang - Sun Microsystems - Beijing China 1276*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = 0; rate < size; rate++) { 1277*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->state[rate].rssi_thres > 1278*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[rate].rssi_ack_validmin) 1279*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].rssi_thres -= 1; 1280*c0c93480Slin wang - Sun Microsystems - Beijing China } 1281*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_down_time = now_msec; 1282*c0c93480Slin wang - Sun Microsystems - Beijing China } 1283*c0c93480Slin wang - Sun Microsystems - Beijing China 1284*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1285*c0c93480Slin wang - Sun Microsystems - Beijing China * Every so often, we reduce the thresholds 1286*c0c93480Slin wang - Sun Microsystems - Beijing China * and PER (different for CCK and OFDM). 1287*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1288*c0c93480Slin wang - Sun Microsystems - Beijing China if (now_msec - ath_rc_priv->per_down_time >= 1289*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->rssi_reduce_interval) { 1290*c0c93480Slin wang - Sun Microsystems - Beijing China for (rate = 0; rate < size; rate++) { 1291*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[rate].per = 1292*c0c93480Slin wang - Sun Microsystems - Beijing China 7 * ath_rc_priv->state[rate].per / 8; 1293*c0c93480Slin wang - Sun Microsystems - Beijing China } 1294*c0c93480Slin wang - Sun Microsystems - Beijing China 1295*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->per_down_time = now_msec; 1296*c0c93480Slin wang - Sun Microsystems - Beijing China } 1297*c0c93480Slin wang - Sun Microsystems - Beijing China 1298*c0c93480Slin wang - Sun Microsystems - Beijing China #undef CHK_RSSI 1299*c0c93480Slin wang - Sun Microsystems - Beijing China } 1300*c0c93480Slin wang - Sun Microsystems - Beijing China 1301*c0c93480Slin wang - Sun Microsystems - Beijing China static int 1302*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_get_rateindex(struct ath_rate_table *rate_table, 1303*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath9k_tx_rate *rate) 1304*c0c93480Slin wang - Sun Microsystems - Beijing China { 1305*c0c93480Slin wang - Sun Microsystems - Beijing China int rix; 1306*c0c93480Slin wang - Sun Microsystems - Beijing China 1307*c0c93480Slin wang - Sun Microsystems - Beijing China if ((rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1308*c0c93480Slin wang - Sun Microsystems - Beijing China (rate->flags & ATH9K_TX_RC_SHORT_GI)) 1309*c0c93480Slin wang - Sun Microsystems - Beijing China rix = rate_table->info[rate->idx].ht_index; 1310*c0c93480Slin wang - Sun Microsystems - Beijing China else if (rate->flags & ATH9K_TX_RC_SHORT_GI) 1311*c0c93480Slin wang - Sun Microsystems - Beijing China rix = rate_table->info[rate->idx].sgi_index; 1312*c0c93480Slin wang - Sun Microsystems - Beijing China else if (rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH) 1313*c0c93480Slin wang - Sun Microsystems - Beijing China rix = rate_table->info[rate->idx].cw40index; 1314*c0c93480Slin wang - Sun Microsystems - Beijing China else 1315*c0c93480Slin wang - Sun Microsystems - Beijing China rix = rate_table->info[rate->idx].base_index; 1316*c0c93480Slin wang - Sun Microsystems - Beijing China 1317*c0c93480Slin wang - Sun Microsystems - Beijing China return (rix); 1318*c0c93480Slin wang - Sun Microsystems - Beijing China } 1319*c0c93480Slin wang - Sun Microsystems - Beijing China 1320*c0c93480Slin wang - Sun Microsystems - Beijing China static void 1321*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_tx_status(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv, 1322*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_buf *bf, int final_ts_idx, int xretries, int long_retry) 1323*c0c93480Slin wang - Sun Microsystems - Beijing China { 1324*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_tx_info_priv *tx_info_priv = 1325*c0c93480Slin wang - Sun Microsystems - Beijing China (struct ath_tx_info_priv *)&bf->tx_info_priv; 1326*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath9k_tx_rate *rates = bf->rates; 1327*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table; 1328*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t i = 0, rix; 1329*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t flags; 1330*c0c93480Slin wang - Sun Microsystems - Beijing China 1331*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table = sc->sc_currates; 1332*c0c93480Slin wang - Sun Microsystems - Beijing China 1333*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1334*c0c93480Slin wang - Sun Microsystems - Beijing China * If the first rate is not the final index, there 1335*c0c93480Slin wang - Sun Microsystems - Beijing China * are intermediate rate failures to be processed. 1336*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1337*c0c93480Slin wang - Sun Microsystems - Beijing China if (final_ts_idx != 0) { 1338*c0c93480Slin wang - Sun Microsystems - Beijing China /* Process intermediate rates that failed. */ 1339*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < final_ts_idx; i++) { 1340*c0c93480Slin wang - Sun Microsystems - Beijing China if (rates[i].count != 0 && (rates[i].idx >= 0)) { 1341*c0c93480Slin wang - Sun Microsystems - Beijing China flags = rates[i].flags; 1342*c0c93480Slin wang - Sun Microsystems - Beijing China 1343*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1344*c0c93480Slin wang - Sun Microsystems - Beijing China * If HT40 and we have switched mode from 1345*c0c93480Slin wang - Sun Microsystems - Beijing China * 40 to 20 => don't update 1346*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1347*c0c93480Slin wang - Sun Microsystems - Beijing China 1348*c0c93480Slin wang - Sun Microsystems - Beijing China if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1349*c0c93480Slin wang - Sun Microsystems - Beijing China (ath_rc_priv->rc_phy_mode != 1350*c0c93480Slin wang - Sun Microsystems - Beijing China WLAN_RC_40_FLAG)) 1351*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1352*c0c93480Slin wang - Sun Microsystems - Beijing China 1353*c0c93480Slin wang - Sun Microsystems - Beijing China rix = 1354*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_get_rateindex(rate_table, &rates[i]); 1355*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_update_ht(sc, ath_rc_priv, 1356*c0c93480Slin wang - Sun Microsystems - Beijing China tx_info_priv, rix, 1357*c0c93480Slin wang - Sun Microsystems - Beijing China xretries ? 1 : 2, 1358*c0c93480Slin wang - Sun Microsystems - Beijing China rates[i].count); 1359*c0c93480Slin wang - Sun Microsystems - Beijing China } 1360*c0c93480Slin wang - Sun Microsystems - Beijing China } 1361*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 1362*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1363*c0c93480Slin wang - Sun Microsystems - Beijing China * Handle the special case of MIMO PS burst, where the second 1364*c0c93480Slin wang - Sun Microsystems - Beijing China * aggregate is sent out with only one rate and one try. 1365*c0c93480Slin wang - Sun Microsystems - Beijing China * Treating it as an excessive retry penalizes the rate 1366*c0c93480Slin wang - Sun Microsystems - Beijing China * inordinately. 1367*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1368*c0c93480Slin wang - Sun Microsystems - Beijing China if (rates[0].count == 1 && xretries == 1) 1369*c0c93480Slin wang - Sun Microsystems - Beijing China xretries = 2; 1370*c0c93480Slin wang - Sun Microsystems - Beijing China } 1371*c0c93480Slin wang - Sun Microsystems - Beijing China 1372*c0c93480Slin wang - Sun Microsystems - Beijing China flags = rates[i].flags; 1373*c0c93480Slin wang - Sun Microsystems - Beijing China 1374*c0c93480Slin wang - Sun Microsystems - Beijing China /* If HT40 and we have switched mode from 40 to 20 => don't update */ 1375*c0c93480Slin wang - Sun Microsystems - Beijing China if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1376*c0c93480Slin wang - Sun Microsystems - Beijing China (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { 1377*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1378*c0c93480Slin wang - Sun Microsystems - Beijing China } 1379*c0c93480Slin wang - Sun Microsystems - Beijing China 1380*c0c93480Slin wang - Sun Microsystems - Beijing China rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1381*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, 1382*c0c93480Slin wang - Sun Microsystems - Beijing China xretries, long_retry); 1383*c0c93480Slin wang - Sun Microsystems - Beijing China } 1384*c0c93480Slin wang - Sun Microsystems - Beijing China 1385*c0c93480Slin wang - Sun Microsystems - Beijing China static struct ath_rate_table * 1386*c0c93480Slin wang - Sun Microsystems - Beijing China arn_choose_rate_table(struct arn_softc *sc, uint32_t cur_mode, 1387*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t is_ht, boolean_t is_cw_40) 1388*c0c93480Slin wang - Sun Microsystems - Beijing China { 1389*c0c93480Slin wang - Sun Microsystems - Beijing China int ath9k_mode; 1390*c0c93480Slin wang - Sun Microsystems - Beijing China switch (cur_mode) { 1391*c0c93480Slin wang - Sun Microsystems - Beijing China case IEEE80211_MODE_11A: 1392*c0c93480Slin wang - Sun Microsystems - Beijing China case IEEE80211_MODE_11NA: 1393*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11A; 1394*c0c93480Slin wang - Sun Microsystems - Beijing China if (is_ht) 1395*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11NA_HT20; 1396*c0c93480Slin wang - Sun Microsystems - Beijing China if (is_cw_40) 1397*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11NA_HT40PLUS; 1398*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1399*c0c93480Slin wang - Sun Microsystems - Beijing China case IEEE80211_MODE_11B: 1400*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11B; 1401*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1402*c0c93480Slin wang - Sun Microsystems - Beijing China case IEEE80211_MODE_11G: 1403*c0c93480Slin wang - Sun Microsystems - Beijing China case IEEE80211_MODE_11NG: 1404*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11G; 1405*c0c93480Slin wang - Sun Microsystems - Beijing China if (is_ht) 1406*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11NG_HT20; 1407*c0c93480Slin wang - Sun Microsystems - Beijing China if (is_cw_40) 1408*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode = ATH9K_MODE_11NG_HT40PLUS; 1409*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1410*c0c93480Slin wang - Sun Microsystems - Beijing China default: 1411*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "Invalid band\n")); 1412*c0c93480Slin wang - Sun Microsystems - Beijing China return (NULL); 1413*c0c93480Slin wang - Sun Microsystems - Beijing China } 1414*c0c93480Slin wang - Sun Microsystems - Beijing China 1415*c0c93480Slin wang - Sun Microsystems - Beijing China switch (ath9k_mode) { 1416*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11A: 1417*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11A\n")); 1418*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1419*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11B: 1420*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11B\n")); 1421*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1422*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11G: 1423*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11G\n")); 1424*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1425*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NA_HT20: 1426*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, 1427*c0c93480Slin wang - Sun Microsystems - Beijing China "choose rate table:ATH9K_MODE_11NA_HT20\n")); 1428*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1429*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NA_HT40PLUS: 1430*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, 1431*c0c93480Slin wang - Sun Microsystems - Beijing China "choose rate table:ATH9K_MODE_11NA_HT40PLUS\n")); 1432*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1433*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NG_HT20: 1434*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, 1435*c0c93480Slin wang - Sun Microsystems - Beijing China "choose rate table:ATH9K_MODE_11NG_HT20\n")); 1436*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1437*c0c93480Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NG_HT40PLUS: 1438*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, 1439*c0c93480Slin wang - Sun Microsystems - Beijing China "choose rate table:ATH9K_MODE_11NG_HT40PLUS\n")); 1440*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1441*c0c93480Slin wang - Sun Microsystems - Beijing China default: 1442*c0c93480Slin wang - Sun Microsystems - Beijing China arn_problem("Invalid band\n"); 1443*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1444*c0c93480Slin wang - Sun Microsystems - Beijing China } 1445*c0c93480Slin wang - Sun Microsystems - Beijing China 1446*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "Choosing rate table for mode: %d\n", 1447*c0c93480Slin wang - Sun Microsystems - Beijing China ath9k_mode)); 1448*c0c93480Slin wang - Sun Microsystems - Beijing China return (sc->hw_rate_table[ath9k_mode]); 1449*c0c93480Slin wang - Sun Microsystems - Beijing China } 1450*c0c93480Slin wang - Sun Microsystems - Beijing China 1451*c0c93480Slin wang - Sun Microsystems - Beijing China /* Private rate contral initialization */ 1452*c0c93480Slin wang - Sun Microsystems - Beijing China static void 1453*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_init(struct arn_softc *sc, 1454*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv, 1455*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_node *in) 1456*c0c93480Slin wang - Sun Microsystems - Beijing China { 1457*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table = NULL; 1458*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rateset *rateset = &ath_rc_priv->neg_rates; 1459*c0c93480Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 1460*c0c93480Slin wang - Sun Microsystems - Beijing China uint32_t cur_mode = ic->ic_curmode; 1461*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t *ht_mcs = (uint8_t *)&ath_rc_priv->neg_ht_rates; 1462*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i, j, k, hi = 0, hthi = 0; 1463*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t is_rc_ds; 1464*c0c93480Slin wang - Sun Microsystems - Beijing China 1465*c0c93480Slin wang - Sun Microsystems - Beijing China /* FIXME: Adhoc */ 1466*c0c93480Slin wang - Sun Microsystems - Beijing China if ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || 1467*c0c93480Slin wang - Sun Microsystems - Beijing China (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) { 1468*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t is_ht = in->in_flags & IEEE80211_NODE_HT; 1469*c0c93480Slin wang - Sun Microsystems - Beijing China /* 20/40 support */ 1470*c0c93480Slin wang - Sun Microsystems - Beijing China boolean_t is_cw_40 = 1471*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_htcap & IEEE80211_HTCAP_CHWIDTH40; 1472*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table = 1473*c0c93480Slin wang - Sun Microsystems - Beijing China arn_choose_rate_table(sc, cur_mode, is_ht, is_cw_40); 1474*c0c93480Slin wang - Sun Microsystems - Beijing China } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { 1475*c0c93480Slin wang - Sun Microsystems - Beijing China /* cur_rate_table would be set on init */ 1476*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table = sc->sc_currates; 1477*c0c93480Slin wang - Sun Microsystems - Beijing China } 1478*c0c93480Slin wang - Sun Microsystems - Beijing China 1479*c0c93480Slin wang - Sun Microsystems - Beijing China if (!rate_table) { 1480*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_FATAL, "Rate table not initialized\n")); 1481*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1482*c0c93480Slin wang - Sun Microsystems - Beijing China } 1483*c0c93480Slin wang - Sun Microsystems - Beijing China 1484*c0c93480Slin wang - Sun Microsystems - Beijing China if (in->in_flags & IEEE80211_NODE_HT) { 1485*c0c93480Slin wang - Sun Microsystems - Beijing China /* 2.6.30 */ 1486*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG; 1487*c0c93480Slin wang - Sun Microsystems - Beijing China is_rc_ds = (AR_SREV_9280_20_OR_LATER(sc->sc_ah) && 1488*c0c93480Slin wang - Sun Microsystems - Beijing China (ath9k_hw_get_eeprom(sc->sc_ah, EEP_RC_CHAIN_MASK) == 1)) ? 1489*c0c93480Slin wang - Sun Microsystems - Beijing China B_FALSE: B_TRUE; 1490*c0c93480Slin wang - Sun Microsystems - Beijing China if (sc->sc_ah->ah_caps.tx_chainmask != 1 && is_rc_ds) { 1491*c0c93480Slin wang - Sun Microsystems - Beijing China if (sc->sc_ht_conf.rx_mcs_mask[1]) { 1492*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG; 1493*c0c93480Slin wang - Sun Microsystems - Beijing China } 1494*c0c93480Slin wang - Sun Microsystems - Beijing China } 1495*c0c93480Slin wang - Sun Microsystems - Beijing China 1496*c0c93480Slin wang - Sun Microsystems - Beijing China if (in->in_htcap & IEEE80211_HTCAP_CHWIDTH40) 1497*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; 1498*c0c93480Slin wang - Sun Microsystems - Beijing China if (in->in_htcap & IEEE80211_HTCAP_SHORTGI40) 1499*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap |= WLAN_RC_SGI_FLAG; 1500*c0c93480Slin wang - Sun Microsystems - Beijing China } 1501*c0c93480Slin wang - Sun Microsystems - Beijing China 1502*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1503*c0c93480Slin wang - Sun Microsystems - Beijing China * Initial rate table size. Will change depending 1504*c0c93480Slin wang - Sun Microsystems - Beijing China * on the working rate set 1505*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1506*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1507*c0c93480Slin wang - Sun Microsystems - Beijing China 1508*c0c93480Slin wang - Sun Microsystems - Beijing China /* Initialize thresholds according to the global rate table */ 1509*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ath_rc_priv->rate_table_size; i++) { 1510*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[i].rssi_thres = 1511*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table->info[i].rssi_ack_validmin; 1512*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->state[i].per = 0; 1513*c0c93480Slin wang - Sun Microsystems - Beijing China } 1514*c0c93480Slin wang - Sun Microsystems - Beijing China 1515*c0c93480Slin wang - Sun Microsystems - Beijing China /* Determine the valid rates */ 1516*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_init_valid_txmask(ath_rc_priv); 1517*c0c93480Slin wang - Sun Microsystems - Beijing China 1518*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < WLAN_RC_PHY_MAX; i++) { 1519*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = 0; j < MAX_TX_RATE_PHY; j++) 1520*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_rateidx[i][j] = 0; 1521*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_ratecnt[i] = 0; 1522*c0c93480Slin wang - Sun Microsystems - Beijing China } 1523*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG); 1524*c0c93480Slin wang - Sun Microsystems - Beijing China 1525*c0c93480Slin wang - Sun Microsystems - Beijing China /* Set stream capability */ 1526*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->single_stream = 1527*c0c93480Slin wang - Sun Microsystems - Beijing China (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1; 1528*c0c93480Slin wang - Sun Microsystems - Beijing China 1529*c0c93480Slin wang - Sun Microsystems - Beijing China if (!rateset->rs_nrates) { 1530*c0c93480Slin wang - Sun Microsystems - Beijing China /* No working rate, just initialize valid rates */ 1531*c0c93480Slin wang - Sun Microsystems - Beijing China hi = arn_rc_init_validrates(ath_rc_priv, rate_table, 1532*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap); 1533*c0c93480Slin wang - Sun Microsystems - Beijing China } else { 1534*c0c93480Slin wang - Sun Microsystems - Beijing China /* Use intersection of working rates and valid rates */ 1535*c0c93480Slin wang - Sun Microsystems - Beijing China hi = arn_rc_setvalid_rates(ath_rc_priv, rate_table, 1536*c0c93480Slin wang - Sun Microsystems - Beijing China rateset, ath_rc_priv->ht_cap); 1537*c0c93480Slin wang - Sun Microsystems - Beijing China if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { 1538*c0c93480Slin wang - Sun Microsystems - Beijing China hthi = arn_rc_setvalid_htrates(ath_rc_priv, 1539*c0c93480Slin wang - Sun Microsystems - Beijing China rate_table, 1540*c0c93480Slin wang - Sun Microsystems - Beijing China ht_mcs, 1541*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->ht_cap); 1542*c0c93480Slin wang - Sun Microsystems - Beijing China } 1543*c0c93480Slin wang - Sun Microsystems - Beijing China hi = A_MAX(hi, hthi); 1544*c0c93480Slin wang - Sun Microsystems - Beijing China } 1545*c0c93480Slin wang - Sun Microsystems - Beijing China 1546*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_table_size = hi + 1; 1547*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_max_phy = 0; 1548*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1549*c0c93480Slin wang - Sun Microsystems - Beijing China 1550*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { 1551*c0c93480Slin wang - Sun Microsystems - Beijing China for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { 1552*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_rate_index[k++] = 1553*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_rateidx[i][j]; 1554*c0c93480Slin wang - Sun Microsystems - Beijing China } 1555*c0c93480Slin wang - Sun Microsystems - Beijing China 1556*c0c93480Slin wang - Sun Microsystems - Beijing China if (!arn_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) || 1557*c0c93480Slin wang - Sun Microsystems - Beijing China !ath_rc_priv->valid_phy_ratecnt[i]) 1558*c0c93480Slin wang - Sun Microsystems - Beijing China continue; 1559*c0c93480Slin wang - Sun Microsystems - Beijing China 1560*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_max_phy = 1561*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->valid_phy_rateidx[i][j-1]; 1562*c0c93480Slin wang - Sun Microsystems - Beijing China } 1563*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1564*c0c93480Slin wang - Sun Microsystems - Beijing China ASSERT(k <= RATE_TABLE_SIZE); 1565*c0c93480Slin wang - Sun Microsystems - Beijing China 1566*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->max_valid_rate = k; 1567*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_sort_validrates(rate_table, ath_rc_priv); 1568*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1569*c0c93480Slin wang - Sun Microsystems - Beijing China sc->sc_currates = rate_table; 1570*c0c93480Slin wang - Sun Microsystems - Beijing China } 1571*c0c93480Slin wang - Sun Microsystems - Beijing China 1572*c0c93480Slin wang - Sun Microsystems - Beijing China void 1573*c0c93480Slin wang - Sun Microsystems - Beijing China arn_tx_status(struct arn_softc *sc, struct ath_buf *bf, boolean_t is_data) 1574*c0c93480Slin wang - Sun Microsystems - Beijing China { 1575*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in); 1576*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_node *an = ATH_NODE(in); 1577*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv = 1578*c0c93480Slin wang - Sun Microsystems - Beijing China (struct ath_rate_priv *)&an->rate_priv; 1579*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_tx_info_priv *tx_info_priv = 1580*c0c93480Slin wang - Sun Microsystems - Beijing China (struct ath_tx_info_priv *)&bf->tx_info_priv; 1581*c0c93480Slin wang - Sun Microsystems - Beijing China int final_ts_idx, tx_status = 0, is_underrun = 0; 1582*c0c93480Slin wang - Sun Microsystems - Beijing China 1583*c0c93480Slin wang - Sun Microsystems - Beijing China final_ts_idx = tx_info_priv->tx.ts_rateindex; 1584*c0c93480Slin wang - Sun Microsystems - Beijing China 1585*c0c93480Slin wang - Sun Microsystems - Beijing China if (!is_data || !tx_info_priv->update_rc) 1586*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1587*c0c93480Slin wang - Sun Microsystems - Beijing China 1588*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) 1589*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1590*c0c93480Slin wang - Sun Microsystems - Beijing China 1591*c0c93480Slin wang - Sun Microsystems - Beijing China /* 1592*c0c93480Slin wang - Sun Microsystems - Beijing China * If underrun error is seen assume it as an excessive retry only 1593*c0c93480Slin wang - Sun Microsystems - Beijing China * if prefetch trigger level have reached the max (0x3f for 5416) 1594*c0c93480Slin wang - Sun Microsystems - Beijing China * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY 1595*c0c93480Slin wang - Sun Microsystems - Beijing China * times. This affects how ratectrl updates PER for the failed rate. 1596*c0c93480Slin wang - Sun Microsystems - Beijing China */ 1597*c0c93480Slin wang - Sun Microsystems - Beijing China if (tx_info_priv->tx.ts_flags & 1598*c0c93480Slin wang - Sun Microsystems - Beijing China (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && 1599*c0c93480Slin wang - Sun Microsystems - Beijing China ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) { 1600*c0c93480Slin wang - Sun Microsystems - Beijing China tx_status = 1; 1601*c0c93480Slin wang - Sun Microsystems - Beijing China is_underrun = 1; 1602*c0c93480Slin wang - Sun Microsystems - Beijing China } 1603*c0c93480Slin wang - Sun Microsystems - Beijing China 1604*c0c93480Slin wang - Sun Microsystems - Beijing China if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || 1605*c0c93480Slin wang - Sun Microsystems - Beijing China (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) 1606*c0c93480Slin wang - Sun Microsystems - Beijing China tx_status = 1; 1607*c0c93480Slin wang - Sun Microsystems - Beijing China 1608*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_tx_status(sc, 1609*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv, 1610*c0c93480Slin wang - Sun Microsystems - Beijing China bf, 1611*c0c93480Slin wang - Sun Microsystems - Beijing China final_ts_idx, 1612*c0c93480Slin wang - Sun Microsystems - Beijing China tx_status, 1613*c0c93480Slin wang - Sun Microsystems - Beijing China (is_underrun) ? ATH_11N_TXMAXTRY : tx_info_priv->tx.ts_longretry); 1614*c0c93480Slin wang - Sun Microsystems - Beijing China } 1615*c0c93480Slin wang - Sun Microsystems - Beijing China 1616*c0c93480Slin wang - Sun Microsystems - Beijing China void 1617*c0c93480Slin wang - Sun Microsystems - Beijing China arn_get_rate(struct arn_softc *sc, struct ath_buf *bf, 1618*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_frame *wh) 1619*c0c93480Slin wang - Sun Microsystems - Beijing China { 1620*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in); 1621*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_node *an = ATH_NODE(in); 1622*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv = 1623*c0c93480Slin wang - Sun Microsystems - Beijing China (struct ath_rate_priv *)&an->rate_priv; 1624*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rt = sc->sc_currates; 1625*c0c93480Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 1626*c0c93480Slin wang - Sun Microsystems - Beijing China int is_probe = 0; 1627*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t i; 1628*c0c93480Slin wang - Sun Microsystems - Beijing China 1629*c0c93480Slin wang - Sun Microsystems - Beijing China /* lowest rate for management and multicast/broadcast frames */ 1630*c0c93480Slin wang - Sun Microsystems - Beijing China if (!IEEE80211_IS_DATA(wh) || IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1631*c0c93480Slin wang - Sun Microsystems - Beijing China bf->rates[0].idx = 0; /* xxx Fix me */ 1632*c0c93480Slin wang - Sun Microsystems - Beijing China bf->rates[0].count = 1633*c0c93480Slin wang - Sun Microsystems - Beijing China IEEE80211_IS_MULTICAST(wh->i_addr1) ? 1634*c0c93480Slin wang - Sun Microsystems - Beijing China 1 : ATH_MGT_TXMAXTRY; 1635*c0c93480Slin wang - Sun Microsystems - Beijing China return; 1636*c0c93480Slin wang - Sun Microsystems - Beijing China } 1637*c0c93480Slin wang - Sun Microsystems - Beijing China 1638*c0c93480Slin wang - Sun Microsystems - Beijing China /* Find tx rate for unicast frames */ 1639*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_ratefind(sc, ath_rc_priv, bf, ATH_11N_TXMAXTRY, 4, 1640*c0c93480Slin wang - Sun Microsystems - Beijing China &is_probe, B_FALSE); 1641*c0c93480Slin wang - Sun Microsystems - Beijing China 1642*c0c93480Slin wang - Sun Microsystems - Beijing China /* Temporary workaround for 'dladm show-wifi' */ 1643*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < in->in_rates.ir_nrates; i++) { 1644*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn: arn_get_rate(): " 1645*c0c93480Slin wang - Sun Microsystems - Beijing China "in->in_rates.ir_rates[%d] = %d," 1646*c0c93480Slin wang - Sun Microsystems - Beijing China "bf->rates[0].idx = %d," 1647*c0c93480Slin wang - Sun Microsystems - Beijing China "rt->info[bf->rates[0].idx].dot11rate = %d\n", 1648*c0c93480Slin wang - Sun Microsystems - Beijing China i, 1649*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_rates.ir_rates[i], 1650*c0c93480Slin wang - Sun Microsystems - Beijing China bf->rates[0].idx, 1651*c0c93480Slin wang - Sun Microsystems - Beijing China rt->info[bf->rates[0].idx].dot11rate)); 1652*c0c93480Slin wang - Sun Microsystems - Beijing China if (rt->info[bf->rates[0].idx].dot11rate == 1653*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_rates.ir_rates[i]) 1654*c0c93480Slin wang - Sun Microsystems - Beijing China break; 1655*c0c93480Slin wang - Sun Microsystems - Beijing China } 1656*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_txrate = i; 1657*c0c93480Slin wang - Sun Microsystems - Beijing China if (ic->ic_curmode == IEEE80211_MODE_11NA || 1658*c0c93480Slin wang - Sun Microsystems - Beijing China ic->ic_curmode == IEEE80211_MODE_11NG) 1659*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_txrate = in->in_rates.ir_nrates - 1; 1660*c0c93480Slin wang - Sun Microsystems - Beijing China 1661*c0c93480Slin wang - Sun Microsystems - Beijing China /* Check if aggregation has to be enabled for this tid */ 1662*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_TX_AGGREGATION 1663*c0c93480Slin wang - Sun Microsystems - Beijing China /* should check if enabled, not supported */ 1664*c0c93480Slin wang - Sun Microsystems - Beijing China if (sc->sc_ht_conf.ht_supported) { 1665*c0c93480Slin wang - Sun Microsystems - Beijing China if (ieee80211_is_data_qos(wh)) { 1666*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t *qc, tid; 1667*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_node *an; 1668*c0c93480Slin wang - Sun Microsystems - Beijing China struct ieee80211_qosframe *qwh = NULL; 1669*c0c93480Slin wang - Sun Microsystems - Beijing China 1670*c0c93480Slin wang - Sun Microsystems - Beijing China qwh = (struct ieee80211_qosframe *)wh; 1671*c0c93480Slin wang - Sun Microsystems - Beijing China tid = qc[0] & 0xf; 1672*c0c93480Slin wang - Sun Microsystems - Beijing China an = (struct ath_node *)sta->drv_priv; 1673*c0c93480Slin wang - Sun Microsystems - Beijing China 1674*c0c93480Slin wang - Sun Microsystems - Beijing China if (arn_tx_aggr_check(sc, an, tid)) 1675*c0c93480Slin wang - Sun Microsystems - Beijing China /* to do */ 1676*c0c93480Slin wang - Sun Microsystems - Beijing China } 1677*c0c93480Slin wang - Sun Microsystems - Beijing China } 1678*c0c93480Slin wang - Sun Microsystems - Beijing China #endif /* ARN_TX_AGGREGATION */ 1679*c0c93480Slin wang - Sun Microsystems - Beijing China } 1680*c0c93480Slin wang - Sun Microsystems - Beijing China 1681*c0c93480Slin wang - Sun Microsystems - Beijing China void 1682*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rate_init(struct arn_softc *sc, struct ieee80211_node *in) 1683*c0c93480Slin wang - Sun Microsystems - Beijing China { 1684*c0c93480Slin wang - Sun Microsystems - Beijing China int i; 1685*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_node *an = ATH_NODE(in); 1686*c0c93480Slin wang - Sun Microsystems - Beijing China struct ath_rate_priv *ath_rc_priv = 1687*c0c93480Slin wang - Sun Microsystems - Beijing China (struct ath_rate_priv *)&an->rate_priv; 1688*c0c93480Slin wang - Sun Microsystems - Beijing China 1689*c0c93480Slin wang - Sun Microsystems - Beijing China /* should be moved to arn_node_init later */ 1690*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->rssi_down_time = 1691*c0c93480Slin wang - Sun Microsystems - Beijing China drv_hztousec(ddi_get_lbolt())/1000; /* mesc */ 1692*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->tx_triglevel_max = 1693*c0c93480Slin wang - Sun Microsystems - Beijing China sc->sc_ah->ah_caps.tx_triglevel_max; 1694*c0c93480Slin wang - Sun Microsystems - Beijing China 1695*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < in->in_rates.ir_nrates; i++) { 1696*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->neg_rates.rs_rates[i] = in->in_rates.ir_rates[i]; 1697*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()" 1698*c0c93480Slin wang - Sun Microsystems - Beijing China "ath_rc_priv->neg_rates.rs_rates[%d] = %d\n", 1699*c0c93480Slin wang - Sun Microsystems - Beijing China i, ath_rc_priv->neg_rates.rs_rates[i])); 1700*c0c93480Slin wang - Sun Microsystems - Beijing China } 1701*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->neg_rates.rs_nrates = in->in_rates.ir_nrates; 1702*c0c93480Slin wang - Sun Microsystems - Beijing China 1703*c0c93480Slin wang - Sun Microsystems - Beijing China /* negotiated ht rate set ??? */ 1704*c0c93480Slin wang - Sun Microsystems - Beijing China if (in->in_flags & IEEE80211_NODE_HT) { 1705*c0c93480Slin wang - Sun Microsystems - Beijing China for (i = 0; i < in->in_htrates.rs_nrates; i++) { 1706*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->neg_ht_rates.rs_rates[i] = 1707*c0c93480Slin wang - Sun Microsystems - Beijing China in->in_htrates.rs_rates[i]; 1708*c0c93480Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()" 1709*c0c93480Slin wang - Sun Microsystems - Beijing China "ath_rc_priv->neg_ht_rates.rs_rates[%d] = %d\n", 1710*c0c93480Slin wang - Sun Microsystems - Beijing China i, ath_rc_priv->neg_ht_rates.rs_rates[i])); 1711*c0c93480Slin wang - Sun Microsystems - Beijing China } 1712*c0c93480Slin wang - Sun Microsystems - Beijing China ath_rc_priv->neg_ht_rates.rs_nrates = in->in_htrates.rs_nrates; 1713*c0c93480Slin wang - Sun Microsystems - Beijing China 1714*c0c93480Slin wang - Sun Microsystems - Beijing China /* arn_update_chainmask(sc); */ 1715*c0c93480Slin wang - Sun Microsystems - Beijing China } 1716*c0c93480Slin wang - Sun Microsystems - Beijing China 1717*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_TX_AGGREGATION 1718*c0c93480Slin wang - Sun Microsystems - Beijing China /* Temply put the following ht info init here */ 1719*c0c93480Slin wang - Sun Microsystems - Beijing China uint8_t ampdu_factor, ampdu_density; 1720*c0c93480Slin wang - Sun Microsystems - Beijing China if (sc->sc_ht_conf.ht_support && 1721*c0c93480Slin wang - Sun Microsystems - Beijing China (in->in_htcap_ie != NULL) && 1722*c0c93480Slin wang - Sun Microsystems - Beijing China (in->in_htcap != 0) && 1723*c0c93480Slin wang - Sun Microsystems - Beijing China (in->in_htparam != 0)) { 1724*c0c93480Slin wang - Sun Microsystems - Beijing China ampdu_factor = in->in_htparam & HT_RX_AMPDU_FACTOR_MSK; 1725*c0c93480Slin wang - Sun Microsystems - Beijing China ampdu_density = (in->in_htparam & HT_MPDU_DENSITY_MSK) >> 1726*c0c93480Slin wang - Sun Microsystems - Beijing China HT_MPDU_DENSITY_POS; 1727*c0c93480Slin wang - Sun Microsystems - Beijing China an->maxampdu = 1728*c0c93480Slin wang - Sun Microsystems - Beijing China 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + ampdu_factor); 1729*c0c93480Slin wang - Sun Microsystems - Beijing China an->mpdudensity = parse_mpdudensity(ampdu_density); 1730*c0c93480Slin wang - Sun Microsystems - Beijing China } 1731*c0c93480Slin wang - Sun Microsystems - Beijing China /* end */ 1732*c0c93480Slin wang - Sun Microsystems - Beijing China #endif /* ARN_TX_AGGREGATION */ 1733*c0c93480Slin wang - Sun Microsystems - Beijing China 1734*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rc_init(sc, ath_rc_priv, in); 1735*c0c93480Slin wang - Sun Microsystems - Beijing China } 1736*c0c93480Slin wang - Sun Microsystems - Beijing China 1737dd1de374Slin wang - Sun Microsystems - Beijing China static void 1738dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(struct arn_softc *sc, 1739dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_rate_table *rate_table) 1740dd1de374Slin wang - Sun Microsystems - Beijing China { 1741dd1de374Slin wang - Sun Microsystems - Beijing China int i; 1742dd1de374Slin wang - Sun Microsystems - Beijing China 1743dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < 256; i++) 1744dd1de374Slin wang - Sun Microsystems - Beijing China rate_table->rateCodeToIndex[i] = (uint8_t)-1; 1745dd1de374Slin wang - Sun Microsystems - Beijing China 1746dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < rate_table->rate_cnt; i++) { 1747dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t code = rate_table->info[i].ratecode; 1748dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t cix = rate_table->info[i].ctrl_rate; 1749dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t sh = rate_table->info[i].short_preamble; 1750dd1de374Slin wang - Sun Microsystems - Beijing China 1751dd1de374Slin wang - Sun Microsystems - Beijing China rate_table->rateCodeToIndex[code] = (int)i; 1752dd1de374Slin wang - Sun Microsystems - Beijing China rate_table->rateCodeToIndex[code | sh] = (int)i; 1753dd1de374Slin wang - Sun Microsystems - Beijing China 1754dd1de374Slin wang - Sun Microsystems - Beijing China rate_table->info[i].lpAckDuration = 1755dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_computetxtime(sc->sc_ah, rate_table, 1756dd1de374Slin wang - Sun Microsystems - Beijing China WLAN_CTRL_FRAME_SIZE, 1757dd1de374Slin wang - Sun Microsystems - Beijing China cix, 1758dd1de374Slin wang - Sun Microsystems - Beijing China B_FALSE); 1759dd1de374Slin wang - Sun Microsystems - Beijing China rate_table->info[i].spAckDuration = 1760dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_computetxtime(sc->sc_ah, rate_table, 1761dd1de374Slin wang - Sun Microsystems - Beijing China WLAN_CTRL_FRAME_SIZE, 1762dd1de374Slin wang - Sun Microsystems - Beijing China cix, 1763dd1de374Slin wang - Sun Microsystems - Beijing China B_TRUE); 1764dd1de374Slin wang - Sun Microsystems - Beijing China } 1765dd1de374Slin wang - Sun Microsystems - Beijing China } 1766dd1de374Slin wang - Sun Microsystems - Beijing China 1767dd1de374Slin wang - Sun Microsystems - Beijing China void 1768dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_attach(struct arn_softc *sc) 1769dd1de374Slin wang - Sun Microsystems - Beijing China { 1770dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11B] = 1771dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11b_ratetable; 1772dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11A] = 1773dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11a_ratetable; 1774dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11G] = 1775dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11g_ratetable; 1776dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = 1777dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11na_ratetable; 1778dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = 1779dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11ng_ratetable; 1780dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] = 1781dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11na_ratetable; 1782dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] = 1783dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11na_ratetable; 1784dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] = 1785dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11ng_ratetable; 1786dd1de374Slin wang - Sun Microsystems - Beijing China sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = 1787dd1de374Slin wang - Sun Microsystems - Beijing China &ar5416_11ng_ratetable; 1788dd1de374Slin wang - Sun Microsystems - Beijing China 1789dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(sc, &ar5416_11b_ratetable); 1790dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(sc, &ar5416_11a_ratetable); 1791dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(sc, &ar5416_11g_ratetable); 1792dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(sc, &ar5416_11na_ratetable); 1793dd1de374Slin wang - Sun Microsystems - Beijing China arn_setup_rate_table(sc, &ar5416_11ng_ratetable); 1794dd1de374Slin wang - Sun Microsystems - Beijing China } 1795dd1de374Slin wang - Sun Microsystems - Beijing China 1796*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_LEGACY_RC 1797dd1de374Slin wang - Sun Microsystems - Beijing China void 1798dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in, int32_t rate) 1799dd1de374Slin wang - Sun Microsystems - Beijing China { 1800dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_node *an = ATH_NODE(in); 1801dd1de374Slin wang - Sun Microsystems - Beijing China const struct ath_rate_table *rt = sc->sc_currates; 1802dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t rix; 1803dd1de374Slin wang - Sun Microsystems - Beijing China 1804dd1de374Slin wang - Sun Microsystems - Beijing China ASSERT(rt != NULL); 1805dd1de374Slin wang - Sun Microsystems - Beijing China 1806dd1de374Slin wang - Sun Microsystems - Beijing China in->in_txrate = rate; 1807dd1de374Slin wang - Sun Microsystems - Beijing China 1808dd1de374Slin wang - Sun Microsystems - Beijing China /* management/control frames always go at the lowest speed */ 1809dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_mgtrate = rt->info[0].ratecode; 1810dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].short_preamble; 1811dd1de374Slin wang - Sun Microsystems - Beijing China 1812dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_update(): " 1813dd1de374Slin wang - Sun Microsystems - Beijing China "mgtrate=%d mgtratesp=%d\n", 1814dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_mgtrate, an->an_tx_mgtratesp)); 1815dd1de374Slin wang - Sun Microsystems - Beijing China 1816dd1de374Slin wang - Sun Microsystems - Beijing China /* 1817dd1de374Slin wang - Sun Microsystems - Beijing China * Before associating a node has no rate set setup 1818dd1de374Slin wang - Sun Microsystems - Beijing China * so we can't calculate any transmit codes to use. 1819dd1de374Slin wang - Sun Microsystems - Beijing China * This is ok since we should never be sending anything 1820dd1de374Slin wang - Sun Microsystems - Beijing China * but management frames and those always go at the 1821dd1de374Slin wang - Sun Microsystems - Beijing China * lowest hardware rate. 1822dd1de374Slin wang - Sun Microsystems - Beijing China */ 1823dd1de374Slin wang - Sun Microsystems - Beijing China if (in->in_rates.ir_nrates == 0) 1824dd1de374Slin wang - Sun Microsystems - Beijing China goto done; 1825dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rix0 = sc->asc_rixmap[ 1826dd1de374Slin wang - Sun Microsystems - Beijing China in->in_rates.ir_rates[rate] & IEEE80211_RATE_VAL]; 1827dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate0 = rt->info[an->an_tx_rix0].ratecode; 1828dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate0sp = an->an_tx_rate0 | 1829dd1de374Slin wang - Sun Microsystems - Beijing China rt->info[an->an_tx_rix0].short_preamble; 1830dd1de374Slin wang - Sun Microsystems - Beijing China if (sc->sc_mrretry) { 1831dd1de374Slin wang - Sun Microsystems - Beijing China /* 1832dd1de374Slin wang - Sun Microsystems - Beijing China * Hardware supports multi-rate retry; setup two 1833dd1de374Slin wang - Sun Microsystems - Beijing China * step-down retry rates and make the lowest rate 1834dd1de374Slin wang - Sun Microsystems - Beijing China * be the ``last chance''. We use 4, 2, 2, 2 tries 1835dd1de374Slin wang - Sun Microsystems - Beijing China * respectively (4 is set here, the rest are fixed 1836dd1de374Slin wang - Sun Microsystems - Beijing China * in the xmit routine). 1837dd1de374Slin wang - Sun Microsystems - Beijing China */ 1838dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_try0 = 1 + 3; /* 4 tries at rate 0 */ 1839dd1de374Slin wang - Sun Microsystems - Beijing China if (--rate >= 0) { 1840dd1de374Slin wang - Sun Microsystems - Beijing China rix = sc->asc_rixmap[ 1841dd1de374Slin wang - Sun Microsystems - Beijing China in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 1842dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate1 = rt->info[rix].ratecode; 1843dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate1sp = an->an_tx_rate1 | 1844dd1de374Slin wang - Sun Microsystems - Beijing China rt->info[rix].short_preamble; 1845dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1846dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate1 = an->an_tx_rate1sp = 0; 1847dd1de374Slin wang - Sun Microsystems - Beijing China } 1848dd1de374Slin wang - Sun Microsystems - Beijing China if (--rate >= 0) { 1849dd1de374Slin wang - Sun Microsystems - Beijing China rix = sc->asc_rixmap[ 1850dd1de374Slin wang - Sun Microsystems - Beijing China in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 1851dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate2 = rt->info[rix].ratecode; 1852dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate2sp = an->an_tx_rate2 | 1853dd1de374Slin wang - Sun Microsystems - Beijing China rt->info[rix].short_preamble; 1854dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1855dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate2 = an->an_tx_rate2sp = 0; 1856dd1de374Slin wang - Sun Microsystems - Beijing China } 1857dd1de374Slin wang - Sun Microsystems - Beijing China if (rate > 0) { 1858dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate3 = rt->info[0].ratecode; 1859dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate3sp = 1860dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_mgtrate | rt->info[0].short_preamble; 1861dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1862dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate3 = an->an_tx_rate3sp = 0; 1863dd1de374Slin wang - Sun Microsystems - Beijing China } 1864dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1865dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_try0 = ATH_TXMAXTRY; /* max tries at rate 0 */ 1866dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate1 = an->an_tx_rate1sp = 0; 1867dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate2 = an->an_tx_rate2sp = 0; 1868dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_rate3 = an->an_tx_rate3sp = 0; 1869dd1de374Slin wang - Sun Microsystems - Beijing China } 1870dd1de374Slin wang - Sun Microsystems - Beijing China done: 1871dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0; 1872dd1de374Slin wang - Sun Microsystems - Beijing China } 1873dd1de374Slin wang - Sun Microsystems - Beijing China 1874dd1de374Slin wang - Sun Microsystems - Beijing China /* 1875dd1de374Slin wang - Sun Microsystems - Beijing China * Set the starting transmit rate for a node. 1876dd1de374Slin wang - Sun Microsystems - Beijing China */ 1877dd1de374Slin wang - Sun Microsystems - Beijing China void 1878dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in) 1879dd1de374Slin wang - Sun Microsystems - Beijing China { 1880dd1de374Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 1881dd1de374Slin wang - Sun Microsystems - Beijing China int32_t srate; 1882dd1de374Slin wang - Sun Microsystems - Beijing China 1883dd1de374Slin wang - Sun Microsystems - Beijing China if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { 1884dd1de374Slin wang - Sun Microsystems - Beijing China /* 1885dd1de374Slin wang - Sun Microsystems - Beijing China * No fixed rate is requested. For 11b start with 1886dd1de374Slin wang - Sun Microsystems - Beijing China * the highest negotiated rate; otherwise, for 11g 1887dd1de374Slin wang - Sun Microsystems - Beijing China * and 11a, we start "in the middle" at 24Mb or 36Mb. 1888dd1de374Slin wang - Sun Microsystems - Beijing China */ 1889dd1de374Slin wang - Sun Microsystems - Beijing China srate = in->in_rates.ir_nrates - 1; 1890dd1de374Slin wang - Sun Microsystems - Beijing China if (sc->sc_curmode != IEEE80211_MODE_11B) { 1891dd1de374Slin wang - Sun Microsystems - Beijing China /* 1892dd1de374Slin wang - Sun Microsystems - Beijing China * Scan the negotiated rate set to find the 1893dd1de374Slin wang - Sun Microsystems - Beijing China * closest rate. 1894dd1de374Slin wang - Sun Microsystems - Beijing China */ 1895dd1de374Slin wang - Sun Microsystems - Beijing China /* NB: the rate set is assumed sorted */ 1896dd1de374Slin wang - Sun Microsystems - Beijing China for (; srate >= 0 && IEEE80211_RATE(srate) > 72; 1897dd1de374Slin wang - Sun Microsystems - Beijing China srate--) {} 1898dd1de374Slin wang - Sun Microsystems - Beijing China } 1899dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1900dd1de374Slin wang - Sun Microsystems - Beijing China /* 1901dd1de374Slin wang - Sun Microsystems - Beijing China * A fixed rate is to be used; We know the rate is 1902dd1de374Slin wang - Sun Microsystems - Beijing China * there because the rate set is checked when the 1903dd1de374Slin wang - Sun Microsystems - Beijing China * station associates. 1904dd1de374Slin wang - Sun Microsystems - Beijing China */ 1905dd1de374Slin wang - Sun Microsystems - Beijing China /* NB: the rate set is assumed sorted */ 1906dd1de374Slin wang - Sun Microsystems - Beijing China srate = in->in_rates.ir_nrates - 1; 1907dd1de374Slin wang - Sun Microsystems - Beijing China for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate; 1908dd1de374Slin wang - Sun Microsystems - Beijing China srate--) {} 1909dd1de374Slin wang - Sun Microsystems - Beijing China } 1910dd1de374Slin wang - Sun Microsystems - Beijing China 1911dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl_start(): " 1912dd1de374Slin wang - Sun Microsystems - Beijing China "srate=%d rate=%d\n", srate, IEEE80211_RATE(srate))); 1913dd1de374Slin wang - Sun Microsystems - Beijing China 1914dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_update(sc, in, srate); 1915dd1de374Slin wang - Sun Microsystems - Beijing China } 1916dd1de374Slin wang - Sun Microsystems - Beijing China 1917dd1de374Slin wang - Sun Microsystems - Beijing China void 1918dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_cb(void *arg, struct ieee80211_node *in) 1919dd1de374Slin wang - Sun Microsystems - Beijing China { 1920dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_update((struct arn_softc *)arg, in, 0); 1921dd1de374Slin wang - Sun Microsystems - Beijing China } 1922*c0c93480Slin wang - Sun Microsystems - Beijing China #endif /* ARN_LEGACY_RC */ 1923dd1de374Slin wang - Sun Microsystems - Beijing China /* 1924dd1de374Slin wang - Sun Microsystems - Beijing China * Reset the rate control state for each 802.11 state transition. 1925dd1de374Slin wang - Sun Microsystems - Beijing China */ 1926dd1de374Slin wang - Sun Microsystems - Beijing China void 1927dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state) 1928dd1de374Slin wang - Sun Microsystems - Beijing China { 1929dd1de374Slin wang - Sun Microsystems - Beijing China ieee80211com_t *ic = (ieee80211com_t *)sc; 1930dd1de374Slin wang - Sun Microsystems - Beijing China struct ieee80211_node *in; 1931dd1de374Slin wang - Sun Microsystems - Beijing China 1932dd1de374Slin wang - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_STA) { 1933dd1de374Slin wang - Sun Microsystems - Beijing China /* 1934dd1de374Slin wang - Sun Microsystems - Beijing China * Reset local xmit state; this is really only 1935dd1de374Slin wang - Sun Microsystems - Beijing China * meaningful when operating in station mode. 1936dd1de374Slin wang - Sun Microsystems - Beijing China */ 1937dd1de374Slin wang - Sun Microsystems - Beijing China in = (struct ieee80211_node *)ic->ic_bss; 1938*c0c93480Slin wang - Sun Microsystems - Beijing China 1939*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_LEGACY_RC 1940dd1de374Slin wang - Sun Microsystems - Beijing China if (state == IEEE80211_S_RUN) { 1941dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_ctl_start(sc, in); 1942dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1943dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_update(sc, in, 0); 1944dd1de374Slin wang - Sun Microsystems - Beijing China } 1945*c0c93480Slin wang - Sun Microsystems - Beijing China #else 1946*c0c93480Slin wang - Sun Microsystems - Beijing China if (state == IEEE80211_S_RUN) 1947*c0c93480Slin wang - Sun Microsystems - Beijing China arn_rate_init(sc, in); 1948*c0c93480Slin wang - Sun Microsystems - Beijing China #endif 1949*c0c93480Slin wang - Sun Microsystems - Beijing China /* LINTED E_NOP_ELSE_STMT */ 1950dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1951dd1de374Slin wang - Sun Microsystems - Beijing China /* 1952dd1de374Slin wang - Sun Microsystems - Beijing China * When operating as a station the node table holds 1953dd1de374Slin wang - Sun Microsystems - Beijing China * the AP's that were discovered during scanning. 1954dd1de374Slin wang - Sun Microsystems - Beijing China * For any other operating mode we want to reset the 1955dd1de374Slin wang - Sun Microsystems - Beijing China * tx rate state of each node. 1956dd1de374Slin wang - Sun Microsystems - Beijing China */ 1957*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_LEGACY_RC 1958dd1de374Slin wang - Sun Microsystems - Beijing China ieee80211_iterate_nodes(&ic->ic_sta, arn_rate_cb, sc); 1959*c0c93480Slin wang - Sun Microsystems - Beijing China #endif 1960dd1de374Slin wang - Sun Microsystems - Beijing China } 1961dd1de374Slin wang - Sun Microsystems - Beijing China } 1962dd1de374Slin wang - Sun Microsystems - Beijing China 1963*c0c93480Slin wang - Sun Microsystems - Beijing China #ifdef ARN_LEGACY_RC 1964dd1de374Slin wang - Sun Microsystems - Beijing China /* 1965dd1de374Slin wang - Sun Microsystems - Beijing China * Examine and potentially adjust the transmit rate. 1966dd1de374Slin wang - Sun Microsystems - Beijing China */ 1967dd1de374Slin wang - Sun Microsystems - Beijing China void 1968dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_ctl(void *arg, struct ieee80211_node *in) 1969dd1de374Slin wang - Sun Microsystems - Beijing China { 1970dd1de374Slin wang - Sun Microsystems - Beijing China struct arn_softc *sc = arg; 1971dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_node *an = ATH_NODE(in); 1972dd1de374Slin wang - Sun Microsystems - Beijing China struct ieee80211_rateset *rs = &in->in_rates; 1973dd1de374Slin wang - Sun Microsystems - Beijing China int32_t mod = 0, nrate, enough; 1974dd1de374Slin wang - Sun Microsystems - Beijing China 1975dd1de374Slin wang - Sun Microsystems - Beijing China /* 1976dd1de374Slin wang - Sun Microsystems - Beijing China * Rate control(very primitive version). 1977dd1de374Slin wang - Sun Microsystems - Beijing China */ 1978dd1de374Slin wang - Sun Microsystems - Beijing China sc->sc_stats.ast_rate_calls++; 1979dd1de374Slin wang - Sun Microsystems - Beijing China 1980dd1de374Slin wang - Sun Microsystems - Beijing China enough = (an->an_tx_ok + an->an_tx_err >= 10); 1981dd1de374Slin wang - Sun Microsystems - Beijing China 1982dd1de374Slin wang - Sun Microsystems - Beijing China /* no packet reached -> down */ 1983dd1de374Slin wang - Sun Microsystems - Beijing China if (an->an_tx_err > 0 && an->an_tx_ok == 0) 1984dd1de374Slin wang - Sun Microsystems - Beijing China mod = -1; 1985dd1de374Slin wang - Sun Microsystems - Beijing China 1986dd1de374Slin wang - Sun Microsystems - Beijing China /* all packets needs retry in average -> down */ 1987dd1de374Slin wang - Sun Microsystems - Beijing China if (enough && an->an_tx_ok < an->an_tx_retr) 1988dd1de374Slin wang - Sun Microsystems - Beijing China mod = -1; 1989dd1de374Slin wang - Sun Microsystems - Beijing China 1990dd1de374Slin wang - Sun Microsystems - Beijing China /* no error and less than 10% of packets needs retry -> up */ 1991dd1de374Slin wang - Sun Microsystems - Beijing China if (enough && an->an_tx_err == 0 && an->an_tx_ok > an->an_tx_retr * 10) 1992dd1de374Slin wang - Sun Microsystems - Beijing China mod = 1; 1993dd1de374Slin wang - Sun Microsystems - Beijing China 1994dd1de374Slin wang - Sun Microsystems - Beijing China nrate = in->in_txrate; 1995dd1de374Slin wang - Sun Microsystems - Beijing China switch (mod) { 1996dd1de374Slin wang - Sun Microsystems - Beijing China case 0: 1997dd1de374Slin wang - Sun Microsystems - Beijing China if (enough && an->an_tx_upper > 0) 1998dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_upper--; 1999dd1de374Slin wang - Sun Microsystems - Beijing China break; 2000dd1de374Slin wang - Sun Microsystems - Beijing China case -1: 2001dd1de374Slin wang - Sun Microsystems - Beijing China if (nrate > 0) { 2002dd1de374Slin wang - Sun Microsystems - Beijing China nrate--; 2003dd1de374Slin wang - Sun Microsystems - Beijing China sc->sc_stats.ast_rate_drop++; 2004dd1de374Slin wang - Sun Microsystems - Beijing China } 2005dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_upper = 0; 2006dd1de374Slin wang - Sun Microsystems - Beijing China break; 2007dd1de374Slin wang - Sun Microsystems - Beijing China case 1: 2008dd1de374Slin wang - Sun Microsystems - Beijing China if (++an->an_tx_upper < 10) 2009dd1de374Slin wang - Sun Microsystems - Beijing China break; 2010dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_upper = 0; 2011dd1de374Slin wang - Sun Microsystems - Beijing China if (nrate + 1 < rs->ir_nrates) { 2012dd1de374Slin wang - Sun Microsystems - Beijing China nrate++; 2013dd1de374Slin wang - Sun Microsystems - Beijing China sc->sc_stats.ast_rate_raise++; 2014dd1de374Slin wang - Sun Microsystems - Beijing China } 2015dd1de374Slin wang - Sun Microsystems - Beijing China break; 2016dd1de374Slin wang - Sun Microsystems - Beijing China } 2017dd1de374Slin wang - Sun Microsystems - Beijing China 2018dd1de374Slin wang - Sun Microsystems - Beijing China if (nrate != in->in_txrate) { 2019dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl(): %dM -> %dM " 2020dd1de374Slin wang - Sun Microsystems - Beijing China "(%d ok, %d err, %d retr)\n", 2021dd1de374Slin wang - Sun Microsystems - Beijing China (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2, 2022dd1de374Slin wang - Sun Microsystems - Beijing China (rs->ir_rates[nrate] & IEEE80211_RATE_VAL) / 2, 2023dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_ok, an->an_tx_err, an->an_tx_retr)); 2024dd1de374Slin wang - Sun Microsystems - Beijing China arn_rate_update(sc, in, nrate); 2025dd1de374Slin wang - Sun Microsystems - Beijing China } else if (enough) 2026dd1de374Slin wang - Sun Microsystems - Beijing China an->an_tx_ok = an->an_tx_err = an->an_tx_retr = 0; 2027dd1de374Slin wang - Sun Microsystems - Beijing China } 2028*c0c93480Slin wang - Sun Microsystems - Beijing China #endif /* ARN_LEGACY_RC */ 2029