static void mlme_calculate_11n_connection_speed(struct ieee80211_node *ni, u_int32_t* rxlinkspeed, u_int32_t* txlinkspeed) { struct ieee80211com *ic = ni->ni_ic; u_int32_t linkspeed; /* bits/sec */ uint32_t shortgi; u_int8_t tx_streams = ieee80211_getstreams(ic, ic->ic_tx_chainmask); u_int8_t rx_streams = ieee80211_getstreams(ic, ic->ic_rx_chainmask); shortgi = ieee80211com_has_htflags(ic, IEEE80211_HTF_SHORTGI40 | IEEE80211_HTF_SHORTGI20); linkspeed = ic->ic_get_maxphyrate(ic, ni,shortgi) * 1000; if (linkspeed == 0) { *txlinkspeed = get_max_phyrate(ic); *rxlinkspeed = *txlinkspeed; } else { *txlinkspeed = linkspeed; ASSERT(tx_streams <= rx_streams); /* * WAR for HB95 (1x1) low DownLink throughput issue. Report higher rx link speed to increase TCP RWIN size. * For 1x1 and 1x2, we report the rxlinkspeed as double of the txlinkspeed. */ if((tx_streams == 1) && (rx_streams == 1)) { *rxlinkspeed = linkspeed * 2; } else { *rxlinkspeed = (linkspeed * rx_streams)/tx_streams; ASSERT(rx_streams <= 4); } } }
static u_int32_t get_max_phyrate(struct ieee80211com *ic) { u_int32_t linkspeed; /* bits/sec */ u_int8_t tx_streams = ieee80211_getstreams(ic, ic->ic_tx_chainmask); /* 11n card, report highest supported HT rate. */ switch (tx_streams) { default: /* Default to single stream */ case 1: linkspeed = 150000000; break; case 2: linkspeed = 300000000; break; case 3: linkspeed = 450000000; break; case 4: linkspeed = 600000000; break; } return linkspeed; }
static u_int32_t ol_ath_node_get_maxphyrate(struct ieee80211com *ic, struct ieee80211_node *ni) { u_int8_t mcs; u_int8_t bw; struct ieee80211vap *vap = ni->ni_vap; u_int8_t curr_phy_mode = wlan_get_current_phymode(vap); enum ieee80211_fixed_rate_mode rate_mode = vap->iv_fixed_rate.mode; u_int8_t nss = 0; u_int8_t sgi = 0; bw = wlan_get_param(vap, IEEE80211_CHWIDTH); if (ieee80211_vap_get_opmode(vap) == IEEE80211_M_STA) { if (((ni->ni_htcap & IEEE80211_HTCAP_C_SHORTGI40) && (bw == IEEE80211_CWM_WIDTH40)) || ((ni->ni_htcap & IEEE80211_HTCAP_C_SHORTGI20) && (bw == IEEE80211_CWM_WIDTH20)) || ((ni->ni_vhtcap & IEEE80211_VHTCAP_SHORTGI_80) && (bw == IEEE80211_CWM_WIDTH80))) { sgi = 1; } } else { sgi = wlan_get_param(vap, IEEE80211_SHORT_GI); } if (rate_mode != IEEE80211_FIXED_RATE_NONE) { /* Get rates for fixed rate */ u_int32_t nbps = 0; /*Number of bits per symbol*/ u_int32_t rc; /* rate code*/ u_int32_t i; /* For fixed rate ensure that SGI is enabled by user */ sgi = vap->iv_data_sgi; switch (rate_mode) { case IEEE80211_FIXED_RATE_MCS: nss = HT_RC_2_STREAMS(vap->iv_fixed_rateset); rc = wlan_get_param(vap, IEEE80211_FIXED_RATE); mcs = (rc & 0x07); for (i = 0; i < NUM_VHT_HT_RATES; i++) { if (vht_ht_tbl[i][BW_COL] == bw && vht_ht_tbl[i][MCS_COL] == mcs) { nbps = vht_ht_tbl[i][NBPS_COL]; } } break; case IEEE80211_FIXED_RATE_VHT: nss = vap->iv_nss; mcs = wlan_get_param(vap, IEEE80211_FIXED_VHT_MCS); for (i = 0; i < NUM_VHT_HT_RATES; i++) { if (vht_ht_tbl[i][BW_COL] == bw && vht_ht_tbl[i][MCS_COL] == mcs) { nbps = vht_ht_tbl[i][NBPS_COL]; } } break; case IEEE80211_FIXED_RATE_LEGACY: rc = wlan_get_param(vap, IEEE80211_FIXED_RATE); for (i = 0; i < NUM_LEGACY_RATES; i++) { if (legacy_rate_idx[i][L_RC_COL] == (rc & 0xff)) { return legacy_rate_idx[i][L_BPS_COL] * 1000; } } break; default: break; } if (sgi) { return (nbps * 5 * 1000 * nss / 18) ; } else { return (nbps * 1000 * nss / 4) ; } } else { /* Get rates for auto rate */ nss = ni->ni_streams; if(ieee80211_vap_get_opmode(vap) == IEEE80211_M_HOSTAP) { nss = (vap->iv_nss > ieee80211_getstreams(ic, ic->ic_tx_chainmask)) ? ieee80211_getstreams(ic, ic->ic_tx_chainmask) : vap->iv_nss; } if ((nss < 1) || (nss > 3)) { printk("%s : NSS greater than 3 or less than 1!(nss:%d)\n", __func__, nss); return 0; } } if(ieee80211_vap_256qam_is_set(ni->ni_vap) && (((ieee80211_vap_get_opmode(vap) == IEEE80211_M_HOSTAP) && (ic->ic_vhtcap)) || ((ieee80211_vap_get_opmode(vap) == IEEE80211_M_STA) && (ni->ni_vhtcap)))) { switch(curr_phy_mode) { case IEEE80211_MODE_11NG_HT20: if(((ieee80211_vap_get_opmode(vap) == IEEE80211_M_HOSTAP) && !ieee80211_vap_ldpc_is_set(ni->ni_vap)) || ((ieee80211_vap_get_opmode(vap) == IEEE80211_M_STA) && !((ni->ni_htcap & IEEE80211_HTCAP_C_ADVCODING) && (ni->ni_vhtcap & IEEE80211_VHTCAP_RX_LDPC)))) { /*256QAM 2G BCC rateset */ curr_phy_mode = IEEE80211_MODE_11AC_VHT80 + 1; } else { /*256 QAM 2G LDPC rateset */ curr_phy_mode = IEEE80211_MODE_11AC_VHT80 + 2; } break; case IEEE80211_MODE_11NG_HT40PLUS: case IEEE80211_MODE_11NG_HT40MINUS: case IEEE80211_MODE_11NG_HT40: /*256 QAM 2G */ curr_phy_mode = IEEE80211_MODE_11AC_VHT80 + 3; break; default: break; } } if (sgi) { return (max_rates[curr_phy_mode][(nss * 2) - 1] * 10); } else { return (max_rates[curr_phy_mode][(nss - 1) * 2] * 10); } }