* Check rate set suitability and return the best supported rate. * XXX inspect MCS for HT */
| 918 | * XXX inspect MCS for HT |
| 919 | */ |
| 920 | static int |
| 921 | check_rate(struct ieee80211vap *vap, const struct ieee80211_channel *chan, |
| 922 | const struct ieee80211_scan_entry *se) |
| 923 | { |
| 924 | const struct ieee80211_rateset *srs; |
| 925 | int i, j, nrs, r, okrate, badrate, fixedrate, ucastrate; |
| 926 | const uint8_t *rs; |
| 927 | |
| 928 | okrate = badrate = 0; |
| 929 | |
| 930 | srs = ieee80211_get_suprates(vap->iv_ic, chan); |
| 931 | nrs = se->se_rates[1]; |
| 932 | rs = se->se_rates+2; |
| 933 | /* XXX MCS */ |
| 934 | ucastrate = vap->iv_txparms[ieee80211_chan2mode(chan)].ucastrate; |
| 935 | fixedrate = IEEE80211_FIXED_RATE_NONE; |
| 936 | again: |
| 937 | for (i = 0; i < nrs; i++) { |
| 938 | r = IEEE80211_RV(rs[i]); |
| 939 | badrate = r; |
| 940 | /* |
| 941 | * Check any fixed rate is included. |
| 942 | */ |
| 943 | if (r == ucastrate) |
| 944 | fixedrate = r; |
| 945 | /* |
| 946 | * Check against our supported rates. |
| 947 | */ |
| 948 | for (j = 0; j < srs->rs_nrates; j++) |
| 949 | if (r == IEEE80211_RV(srs->rs_rates[j])) { |
| 950 | if (r > okrate) /* NB: track max */ |
| 951 | okrate = r; |
| 952 | break; |
| 953 | } |
| 954 | |
| 955 | if (j == srs->rs_nrates && (rs[i] & IEEE80211_RATE_BASIC)) { |
| 956 | /* |
| 957 | * Don't try joining a BSS, if we don't support |
| 958 | * one of its basic rates. |
| 959 | */ |
| 960 | okrate = 0; |
| 961 | goto back; |
| 962 | } |
| 963 | } |
| 964 | if (rs == se->se_rates+2) { |
| 965 | /* scan xrates too; sort of an algol68-style for loop */ |
| 966 | nrs = se->se_xrates[1]; |
| 967 | rs = se->se_xrates+2; |
| 968 | goto again; |
| 969 | } |
| 970 | |
| 971 | back: |
| 972 | if (okrate == 0 || ucastrate != fixedrate) |
| 973 | return badrate | IEEE80211_RATE_BASIC; |
| 974 | else |
| 975 | return IEEE80211_RV(okrate); |
| 976 | } |
| 977 |
no test coverage detected