Example #1
0
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);
        }
    }
}
Example #2
0
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;
}
Example #3
0
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);
    }
}