source: trunk/package/mac80211/patches/300-pending_work.patch @ 29438

Last change on this file since 29438 was 29438, checked in by nbd, 5 years ago

ath9k: fix antenna configuration on ar9285 for devices without antenna diversity

File size: 33.1 KB
  • drivers/net/wireless/ath/ath9k/ar9002_calib.c

    a b static void ar9002_hw_iqcalibrate(struct 
    203203                        i); 
    204204 
    205205                ath_dbg(common, ATH_DBG_CALIBRATE, 
    206                         "Orignal: Chn %diq_corr_meas = 0x%08x\n", 
     206                        "Original: Chn %d iq_corr_meas = 0x%08x\n", 
    207207                        i, ah->totalIqCorrMeas[i]); 
    208208 
    209209                iqCorrNeg = 0; 
  • drivers/net/wireless/ath/ath9k/ar9003_calib.c

    a b static void ar9003_hw_iqcalibrate(struct 
    226226                        i); 
    227227 
    228228                ath_dbg(common, ATH_DBG_CALIBRATE, 
    229                         "Orignal: Chn %diq_corr_meas = 0x%08x\n", 
     229                        "Original: Chn %d iq_corr_meas = 0x%08x\n", 
    230230                        i, ah->totalIqCorrMeas[i]); 
    231231 
    232232                iqCorrNeg = 0; 
  • drivers/net/wireless/ath/ath9k/htc_drv_main.c

    a b void ath9k_htc_ani_work(struct work_stru 
    808808        } 
    809809 
    810810        /* Verify whether we must check ANI */ 
    811         if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { 
     811        if (ah->config.enable_ani && 
     812            (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { 
    812813                aniflag = true; 
    813814                common->ani.checkani_timer = timestamp; 
    814815        } 
  • drivers/net/wireless/ath/ath9k/hw.c

    a b static int ath9k_hw_post_init(struct ath 
    504504                return ecode; 
    505505        } 
    506506 
    507         if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { 
     507        if (ah->config.enable_ani) { 
    508508                ath9k_hw_ani_setup(ah); 
    509509                ath9k_hw_ani_init(ah); 
    510510        } 
    static int __ath9k_hw_init(struct ath_hw 
    610610        if (!AR_SREV_9300_20_OR_LATER(ah)) 
    611611                ah->ani_function &= ~ATH9K_ANI_MRC_CCK; 
    612612 
     613        /* disable ANI for 9340 */ 
     614        if (AR_SREV_9340(ah)) 
     615                ah->config.enable_ani = false; 
     616 
    613617        ath9k_hw_init_mode_regs(ah); 
    614618 
    615619        if (!ah->is_pciexpress) 
  • drivers/net/wireless/ath/ath9k/main.c

    a b void ath9k_ps_restore(struct ath_softc * 
    118118        if (--sc->ps_usecount != 0) 
    119119                goto unlock; 
    120120 
    121         if (sc->ps_idle) 
     121        if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) 
    122122                mode = ATH9K_PM_FULL_SLEEP; 
    123123        else if (sc->ps_enabled && 
    124124                 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 
    static bool ath_complete_reset(struct at 
    286286                        ath_start_ani(common); 
    287287        } 
    288288 
    289         if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { 
     289        if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { 
    290290                struct ath_hw_antcomb_conf div_ant_conf; 
    291291                u8 lna_conf; 
    292292 
    static int ath_reset_internal(struct ath 
    332332                hchan = ah->curchan; 
    333333        } 
    334334 
    335         if (fastcc && !ath9k_hw_check_alive(ah)) 
     335        if (fastcc && (ah->chip_fullsleep || 
     336            !ath9k_hw_check_alive(ah))) 
    336337                fastcc = false; 
    337338 
    338339        if (!ath_prepare_reset(sc, retry_tx, flush)) 
    void ath_ani_calibrate(unsigned long dat 
    561562        /* Long calibration runs independently of short calibration. */ 
    562563        if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { 
    563564                longcal = true; 
    564                 ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); 
    565565                common->ani.longcal_timer = timestamp; 
    566566        } 
    567567 
    void ath_ani_calibrate(unsigned long dat 
    569569        if (!common->ani.caldone) { 
    570570                if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { 
    571571                        shortcal = true; 
    572                         ath_dbg(common, ATH_DBG_ANI, 
    573                                 "shortcal @%lu\n", jiffies); 
    574572                        common->ani.shortcal_timer = timestamp; 
    575573                        common->ani.resetcal_timer = timestamp; 
    576574                } 
    void ath_ani_calibrate(unsigned long dat 
    584582        } 
    585583 
    586584        /* Verify whether we must check ANI */ 
    587         if ((timestamp - common->ani.checkani_timer) >= 
    588              ah->config.ani_poll_interval) { 
     585        if (sc->sc_ah->config.enable_ani 
     586            && (timestamp - common->ani.checkani_timer) >= 
     587            ah->config.ani_poll_interval) { 
    589588                aniflag = true; 
    590589                common->ani.checkani_timer = timestamp; 
    591590        } 
    void ath_ani_calibrate(unsigned long dat 
    605604                                                ah->rxchainmask, longcal); 
    606605        } 
    607606 
     607        ath_dbg(common, ATH_DBG_ANI, 
     608                "Calibration @%lu finished: %s %s %s, caldone: %s\n", jiffies, 
     609                longcal ? "long" : "", shortcal ? "short" : "", 
     610                aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); 
     611 
    608612        ath9k_ps_restore(sc); 
    609613 
    610614set_timer: 
    chip_reset: 
    886890#undef SCHED_INTR 
    887891} 
    888892 
    889 static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) 
    890 { 
    891         struct ath_hw *ah = sc->sc_ah; 
    892         struct ath_common *common = ath9k_hw_common(ah); 
    893         struct ieee80211_channel *channel = hw->conf.channel; 
    894         int r; 
    895  
    896         ath9k_ps_wakeup(sc); 
    897         spin_lock_bh(&sc->sc_pcu_lock); 
    898         atomic_set(&ah->intr_ref_cnt, -1); 
    899  
    900         ath9k_hw_configpcipowersave(ah, false); 
    901  
    902         if (!ah->curchan) 
    903                 ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah); 
    904  
    905         r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 
    906         if (r) { 
    907                 ath_err(common, 
    908                         "Unable to reset channel (%u MHz), reset status %d\n", 
    909                         channel->center_freq, r); 
    910         } 
    911  
    912         ath_complete_reset(sc, true); 
    913  
    914         /* Enable LED */ 
    915         ath9k_hw_cfg_output(ah, ah->led_pin, 
    916                             AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 
    917         ath9k_hw_set_gpio(ah, ah->led_pin, 0); 
    918  
    919         spin_unlock_bh(&sc->sc_pcu_lock); 
    920  
    921         ath9k_ps_restore(sc); 
    922 } 
    923  
    924 void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) 
    925 { 
    926         struct ath_hw *ah = sc->sc_ah; 
    927         struct ieee80211_channel *channel = hw->conf.channel; 
    928         int r; 
    929  
    930         ath9k_ps_wakeup(sc); 
    931  
    932         ath_cancel_work(sc); 
    933  
    934         spin_lock_bh(&sc->sc_pcu_lock); 
    935  
    936         /* 
    937          * Keep the LED on when the radio is disabled 
    938          * during idle unassociated state. 
    939          */ 
    940         if (!sc->ps_idle) { 
    941                 ath9k_hw_set_gpio(ah, ah->led_pin, 1); 
    942                 ath9k_hw_cfg_gpio_input(ah, ah->led_pin); 
    943         } 
    944  
    945         ath_prepare_reset(sc, false, true); 
    946  
    947         if (!ah->curchan) 
    948                 ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 
    949  
    950         r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 
    951         if (r) { 
    952                 ath_err(ath9k_hw_common(sc->sc_ah), 
    953                         "Unable to reset channel (%u MHz), reset status %d\n", 
    954                         channel->center_freq, r); 
    955         } 
    956  
    957         ath9k_hw_phy_disable(ah); 
    958  
    959         ath9k_hw_configpcipowersave(ah, true); 
    960  
    961         spin_unlock_bh(&sc->sc_pcu_lock); 
    962         ath9k_ps_restore(sc); 
    963 } 
    964  
    965893static int ath_reset(struct ath_softc *sc, bool retry_tx) 
    966894{ 
    967895        int r; 
    static int ath9k_start(struct ieee80211_ 
    10971025         * and then setup of the interrupt mask. 
    10981026         */ 
    10991027        spin_lock_bh(&sc->sc_pcu_lock); 
     1028 
     1029        atomic_set(&ah->intr_ref_cnt, -1); 
     1030 
    11001031        r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); 
    11011032        if (r) { 
    11021033                ath_err(common, 
    static int ath9k_start(struct ieee80211_ 
    11381069                goto mutex_unlock; 
    11391070        } 
    11401071 
     1072        if (ah->led_pin >= 0) { 
     1073                ath9k_hw_cfg_output(ah, ah->led_pin, 
     1074                                    AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 
     1075                ath9k_hw_set_gpio(ah, ah->led_pin, 0); 
     1076        } 
     1077 
     1078        /* 
     1079         * Reset key cache to sane defaults (all entries cleared) instead of 
     1080         * semi-random values after suspend/resume. 
     1081         */ 
     1082        ath9k_cmn_init_crypto(sc->sc_ah); 
     1083 
    11411084        spin_unlock_bh(&sc->sc_pcu_lock); 
    11421085 
    11431086        if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && 
    static void ath9k_tx(struct ieee80211_hw 
    11831126                } 
    11841127        } 
    11851128 
     1129        /* 
     1130         * Cannot tx while the hardware is in full sleep, it first needs a full 
     1131         * chip reset to recover from that 
     1132         */ 
     1133        if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) 
     1134                goto exit; 
     1135 
    11861136        if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) { 
    11871137                /* 
    11881138                 * We are using PS-Poll and mac80211 can request TX while in 
    static void ath9k_stop(struct ieee80211_ 
    12291179        struct ath_softc *sc = hw->priv; 
    12301180        struct ath_hw *ah = sc->sc_ah; 
    12311181        struct ath_common *common = ath9k_hw_common(ah); 
     1182        bool prev_idle; 
    12321183 
    12331184        mutex_lock(&sc->mutex); 
    12341185 
    static void ath9k_stop(struct ieee80211_ 
    12591210         * before setting the invalid flag. */ 
    12601211        ath9k_hw_disable_interrupts(ah); 
    12611212 
    1262         if (!(sc->sc_flags & SC_OP_INVALID)) { 
    1263                 ath_drain_all_txq(sc, false); 
    1264                 ath_stoprecv(sc); 
    1265                 ath9k_hw_phy_disable(ah); 
    1266         } else 
    1267                 sc->rx.rxlink = NULL; 
     1213        spin_unlock_bh(&sc->sc_pcu_lock); 
     1214 
     1215        /* we can now sync irq and kill any running tasklets, since we already 
     1216         * disabled interrupts and not holding a spin lock */ 
     1217        synchronize_irq(sc->irq); 
     1218        tasklet_kill(&sc->intr_tq); 
     1219        tasklet_kill(&sc->bcon_tasklet); 
     1220 
     1221        prev_idle = sc->ps_idle; 
     1222        sc->ps_idle = true; 
     1223 
     1224        spin_lock_bh(&sc->sc_pcu_lock); 
     1225 
     1226        if (ah->led_pin >= 0) { 
     1227                ath9k_hw_set_gpio(ah, ah->led_pin, 1); 
     1228                ath9k_hw_cfg_gpio_input(ah, ah->led_pin); 
     1229        } 
     1230 
     1231        ath_prepare_reset(sc, false, true); 
    12681232 
    12691233        if (sc->rx.frag) { 
    12701234                dev_kfree_skb_any(sc->rx.frag); 
    12711235                sc->rx.frag = NULL; 
    12721236        } 
    12731237 
    1274         /* disable HAL and put h/w to sleep */ 
    1275         ath9k_hw_disable(ah); 
     1238        if (!ah->curchan) 
     1239                ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 
    12761240 
    1277         spin_unlock_bh(&sc->sc_pcu_lock); 
     1241        ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 
     1242        ath9k_hw_phy_disable(ah); 
    12781243 
    1279         /* we can now sync irq and kill any running tasklets, since we already 
    1280          * disabled interrupts and not holding a spin lock */ 
    1281         synchronize_irq(sc->irq); 
    1282         tasklet_kill(&sc->intr_tq); 
    1283         tasklet_kill(&sc->bcon_tasklet); 
     1244        ath9k_hw_configpcipowersave(ah, true); 
    12841245 
    1285         ath9k_ps_restore(sc); 
     1246        spin_unlock_bh(&sc->sc_pcu_lock); 
    12861247 
    1287         sc->ps_idle = true; 
    1288         ath_radio_disable(sc, hw); 
     1248        ath9k_ps_restore(sc); 
    12891249 
    12901250        sc->sc_flags |= SC_OP_INVALID; 
     1251        sc->ps_idle = prev_idle; 
    12911252 
    12921253        mutex_unlock(&sc->mutex); 
    12931254 
    static int ath9k_config(struct ieee80211 
    16271588        struct ath_hw *ah = sc->sc_ah; 
    16281589        struct ath_common *common = ath9k_hw_common(ah); 
    16291590        struct ieee80211_conf *conf = &hw->conf; 
    1630         bool disable_radio = false; 
    16311591 
     1592        ath9k_ps_wakeup(sc); 
    16321593        mutex_lock(&sc->mutex); 
    16331594 
    16341595        /* 
    static int ath9k_config(struct ieee80211 
    16391600         */ 
    16401601        if (changed & IEEE80211_CONF_CHANGE_IDLE) { 
    16411602                sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); 
    1642                 if (!sc->ps_idle) { 
    1643                         ath_radio_enable(sc, hw); 
    1644                         ath_dbg(common, ATH_DBG_CONFIG, 
    1645                                 "not-idle: enabling radio\n"); 
    1646                 } else { 
    1647                         disable_radio = true; 
    1648                 } 
     1603                if (sc->ps_idle) 
     1604                        ath_cancel_work(sc); 
    16491605        } 
    16501606 
    16511607        /* 
    static int ath9k_config(struct ieee80211 
    17521708                ath_dbg(common, ATH_DBG_CONFIG, 
    17531709                        "Set power: %d\n", conf->power_level); 
    17541710                sc->config.txpowlimit = 2 * conf->power_level; 
    1755                 ath9k_ps_wakeup(sc); 
    17561711                ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    17571712                                       sc->config.txpowlimit, &sc->curtxpow); 
    1758                 ath9k_ps_restore(sc); 
    1759         } 
    1760  
    1761         if (disable_radio) { 
    1762                 ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); 
    1763                 ath_radio_disable(sc, hw); 
    17641713        } 
    17651714 
    17661715        mutex_unlock(&sc->mutex); 
     1716        ath9k_ps_restore(sc); 
    17671717 
    17681718        return 0; 
    17691719} 
    static void ath9k_flush(struct ieee80211 
    23312281                return; 
    23322282        } 
    23332283 
    2334         if (drop) 
    2335                 timeout = 1; 
    2336  
    23372284        for (j = 0; j < timeout; j++) { 
    23382285                bool npend = false; 
    23392286 
    static void ath9k_flush(struct ieee80211 
    23512298                } 
    23522299 
    23532300                if (!npend) 
    2354                     goto out; 
     2301                    break; 
    23552302        } 
    23562303 
    2357         ath9k_ps_wakeup(sc); 
    2358         spin_lock_bh(&sc->sc_pcu_lock); 
    2359         drain_txq = ath_drain_all_txq(sc, false); 
    2360         spin_unlock_bh(&sc->sc_pcu_lock); 
     2304        if (drop) { 
     2305                ath9k_ps_wakeup(sc); 
     2306                spin_lock_bh(&sc->sc_pcu_lock); 
     2307                drain_txq = ath_drain_all_txq(sc, false); 
     2308                spin_unlock_bh(&sc->sc_pcu_lock); 
    23612309 
    2362         if (!drain_txq) 
    2363                 ath_reset(sc, false); 
     2310                if (!drain_txq) 
     2311                        ath_reset(sc, false); 
    23642312 
    2365         ath9k_ps_restore(sc); 
    2366         ieee80211_wake_queues(hw); 
     2313                ath9k_ps_restore(sc); 
     2314                ieee80211_wake_queues(hw); 
     2315        } 
    23672316 
    2368 out: 
    23692317        ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); 
    23702318        mutex_unlock(&sc->mutex); 
    23712319} 
  • drivers/net/wireless/ath/ath9k/pci.c

    a b static int ath_pci_suspend(struct device 
    307307        struct ieee80211_hw *hw = pci_get_drvdata(pdev); 
    308308        struct ath_softc *sc = hw->priv; 
    309309 
    310         ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 
    311  
    312310        /* The device has to be moved to FULLSLEEP forcibly. 
    313311         * Otherwise the chip never moved to full sleep, 
    314312         * when no interface is up. 
    315313         */ 
     314        ath9k_hw_disable(sc->sc_ah); 
    316315        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); 
    317316 
    318317        return 0; 
    static int ath_pci_resume(struct device  
    334333        if ((val & 0x0000ff00) != 0) 
    335334                pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); 
    336335 
    337         ath9k_ps_wakeup(sc); 
    338         /* Enable LED */ 
    339         ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, 
    340                             AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 
    341         ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); 
    342  
    343           /* 
    344            * Reset key cache to sane defaults (all entries cleared) instead of 
    345            * semi-random values after suspend/resume. 
    346            */ 
    347         ath9k_cmn_init_crypto(sc->sc_ah); 
    348         ath9k_ps_restore(sc); 
    349  
    350         sc->ps_idle = true; 
    351         ath_radio_disable(sc, hw); 
    352  
    353336        return 0; 
    354337} 
    355338 
  • drivers/net/wireless/ath/ath9k/xmit.c

    a b static void ath_tx_complete(struct ath_s 
    19541954                skb_pull(skb, padsize); 
    19551955        } 
    19561956 
    1957         if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { 
     1957        if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { 
    19581958                sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; 
    19591959                ath_dbg(common, ATH_DBG_PS, 
    19601960                        "Going back to sleep after having received TX status (0x%lx)\n", 
  • include/linux/nl80211.h

    a b enum nl80211_ap_sme_features { 
    27852785 * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back 
    27862786 *      TX status to the socket error queue when requested with the 
    27872787 *      socket option. 
     2788 * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. 
    27882789 */ 
    27892790enum nl80211_feature_flags { 
    27902791        NL80211_FEATURE_SK_TX_STATUS    = 1 << 0, 
     2792        NL80211_FEATURE_HT_IBSS         = 1 << 1, 
    27912793}; 
    27922794 
    27932795/** 
  • include/net/cfg80211.h

    a b struct cfg80211_ibss_params { 
    11491149        u8 *ssid; 
    11501150        u8 *bssid; 
    11511151        struct ieee80211_channel *channel; 
     1152        enum nl80211_channel_type channel_type; 
    11521153        u8 *ie; 
    11531154        u8 ssid_len, ie_len; 
    11541155        u16 beacon_interval; 
    void cfg80211_report_obss_beacon(struct  
    32703271                                 const u8 *frame, size_t len, 
    32713272                                 int freq, gfp_t gfp); 
    32723273 
     3274/* 
     3275 * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used 
     3276 * @wiphy: the wiphy 
     3277 * @chan: main channel 
     3278 * @channel_type: HT mode 
     3279 */ 
     3280int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 
     3281                                 struct ieee80211_channel *chan, 
     3282                                 enum nl80211_channel_type channel_type); 
     3283 
    32733284/* Logging, debugging and troubleshooting/diagnostic helpers. */ 
    32743285 
    32753286/* wiphy_printk helpers, similar to dev_printk */ 
  • net/mac80211/agg-rx.c

    a b static void ieee80211_send_addba_resp(st 
    185185                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 
    186186        else if (sdata->vif.type == NL80211_IFTYPE_STATION) 
    187187                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 
     188        else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 
     189                memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); 
     190        else if (sdata->vif.type == NL80211_IFTYPE_WDS) 
     191                memcpy(mgmt->bssid, da, ETH_ALEN); 
    188192 
    189193        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
    190194                                          IEEE80211_STYPE_ACTION); 
  • net/mac80211/agg-tx.c

    a b static void ieee80211_send_addba_request 
    7979        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 
    8080        if (sdata->vif.type == NL80211_IFTYPE_AP || 
    8181            sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 
    82             sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 
     82            sdata->vif.type == NL80211_IFTYPE_MESH_POINT || 
     83            sdata->vif.type == NL80211_IFTYPE_WDS) 
    8384                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 
    8485        else if (sdata->vif.type == NL80211_IFTYPE_STATION) 
    8586                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 
     87        else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 
     88                memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); 
    8689 
    8790        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
    8891                                          IEEE80211_STYPE_ACTION); 
    int ieee80211_start_tx_ba_session(struct 
    437440        if (sdata->vif.type != NL80211_IFTYPE_STATION && 
    438441            sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 
    439442            sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 
    440             sdata->vif.type != NL80211_IFTYPE_AP) 
     443            sdata->vif.type != NL80211_IFTYPE_AP && 
     444            sdata->vif.type != NL80211_IFTYPE_WDS && 
     445            sdata->vif.type != NL80211_IFTYPE_ADHOC) 
    441446                return -EINVAL; 
    442447 
    443448        if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { 
    int ieee80211_start_tx_ba_session(struct 
    448453                return -EINVAL; 
    449454        } 
    450455 
     456        /* 
     457         * 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a 
     458         * member of an IBSS, and has no other existing Block Ack agreement 
     459         * with the recipient STA, then the initiating STA shall transmit a 
     460         * Probe Request frame to the recipient STA and shall not transmit an 
     461         * ADDBA Request frame unless it receives a Probe Response frame 
     462         * from the recipient within dot11ADDBAFailureTimeout. 
     463         * 
     464         * The probe request mechanism for ADDBA is currently not implemented, 
     465         * but we only build up Block Ack session with HT STAs. This information 
     466         * is set when we receive a bss info from a probe response or a beacon. 
     467         */ 
     468        if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && 
     469            !sta->sta.ht_cap.ht_supported) { 
     470#ifdef CONFIG_MAC80211_HT_DEBUG 
     471                printk(KERN_DEBUG "BA request denied - IBSS STA %pM" 
     472                       "does not advertise HT support\n", pubsta->addr); 
     473#endif /* CONFIG_MAC80211_HT_DEBUG */ 
     474                return -EINVAL; 
     475        } 
     476 
    451477        spin_lock_bh(&sta->lock); 
    452478 
    453479        /* we have tried too many times, receiver does not want A-MPDU */ 
  • net/mac80211/debugfs_sta.c

    a b static ssize_t sta_flags_read(struct fil 
    6363        test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" 
    6464 
    6565        int res = scnprintf(buf, sizeof(buf), 
    66                             "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 
     66                            "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 
    6767                            TEST(AUTH), TEST(ASSOC), TEST(PS_STA), 
    6868                            TEST(PS_DRIVER), TEST(AUTHORIZED), 
    6969                            TEST(SHORT_PREAMBLE), 
    70                             TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), 
     70                            TEST(WME), TEST(CLEAR_PS_FILT), 
    7171                            TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), 
    7272                            TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), 
    7373                            TEST(TDLS_PEER_AUTH)); 
  • net/mac80211/ht.c

    a b void ieee80211_send_delba(struct ieee802 
    282282                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 
    283283        else if (sdata->vif.type == NL80211_IFTYPE_STATION) 
    284284                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 
     285        else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 
     286                memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); 
    285287 
    286288        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
    287289                                          IEEE80211_STYPE_ACTION); 
  • net/mac80211/ibss.c

    a b static void __ieee80211_sta_join_ibss(st 
    7777        struct cfg80211_bss *bss; 
    7878        u32 bss_change; 
    7979        u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 
     80        enum nl80211_channel_type channel_type; 
    8081 
    8182        lockdep_assert_held(&ifibss->mtx); 
    8283 
    static void __ieee80211_sta_join_ibss(st 
    105106 
    106107        sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 
    107108 
    108         local->oper_channel = chan; 
    109         WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); 
     109        channel_type = ifibss->channel_type; 
     110        if (channel_type > NL80211_CHAN_HT20 && 
     111            !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) 
     112                channel_type = NL80211_CHAN_HT20; 
     113        if (!ieee80211_set_channel_type(local, sdata, channel_type)) { 
     114                /* can only fail due to HT40+/- mismatch */ 
     115                channel_type = NL80211_CHAN_HT20; 
     116                WARN_ON(!ieee80211_set_channel_type(local, sdata, 
     117                                                    NL80211_CHAN_HT20)); 
     118        } 
    110119        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 
    111120 
    112121        sband = local->hw.wiphy->bands[chan->band]; 
    static void __ieee80211_sta_join_ibss(st 
    172181                memcpy(skb_put(skb, ifibss->ie_len), 
    173182                       ifibss->ie, ifibss->ie_len); 
    174183 
     184        /* add HT capability and information IEs */ 
     185        if (channel_type && sband->ht_cap.ht_supported) { 
     186                pos = skb_put(skb, 4 + 
     187                                   sizeof(struct ieee80211_ht_cap) + 
     188                                   sizeof(struct ieee80211_ht_info)); 
     189                pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 
     190                                                sband->ht_cap.cap); 
     191                pos = ieee80211_ie_build_ht_info(pos, 
     192                                                 &sband->ht_cap, 
     193                                                 chan, 
     194                                                 channel_type); 
     195        } 
     196 
    175197        if (local->hw.queues >= 4) { 
    176198                pos = skb_put(skb, 9); 
    177199                *pos++ = WLAN_EID_VENDOR_SPECIFIC; 
    static void __ieee80211_sta_join_ibss(st 
    195217        bss_change |= BSS_CHANGED_BEACON; 
    196218        bss_change |= BSS_CHANGED_BEACON_ENABLED; 
    197219        bss_change |= BSS_CHANGED_BASIC_RATES; 
     220        bss_change |= BSS_CHANGED_HT; 
    198221        bss_change |= BSS_CHANGED_IBSS; 
    199222        sdata->vif.bss_conf.ibss_joined = true; 
    200223        ieee80211_bss_info_change_notify(sdata, bss_change); 
    static void ieee80211_rx_bss_info(struct 
    268291        u64 beacon_timestamp, rx_timestamp; 
    269292        u32 supp_rates = 0; 
    270293        enum ieee80211_band band = rx_status->band; 
     294        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 
     295        bool rates_updated = false; 
    271296 
    272297        if (elems->ds_params && elems->ds_params_len == 1) 
    273298                freq = ieee80211_channel_to_frequency(elems->ds_params[0], 
    static void ieee80211_rx_bss_info(struct 
    307332                                                prev_rates, 
    308333                                                sta->sta.supp_rates[band]); 
    309334#endif 
    310                                         rate_control_rate_init(sta); 
     335                                        rates_updated = true; 
    311336                                } 
    312337                        } else 
    313338                                sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, 
    static void ieee80211_rx_bss_info(struct 
    318343                if (sta && elems->wmm_info) 
    319344                        set_sta_flag(sta, WLAN_STA_WME); 
    320345 
     346                if (sta && elems->ht_info_elem && elems->ht_cap_elem && 
     347                    sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { 
     348                        /* we both use HT */ 
     349                        struct ieee80211_sta_ht_cap sta_ht_cap_new; 
     350                        enum nl80211_channel_type channel_type = 
     351                                ieee80211_ht_info_to_channel_type( 
     352                                                        elems->ht_info_elem); 
     353 
     354                        ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 
     355                                                          elems->ht_cap_elem, 
     356                                                          &sta_ht_cap_new); 
     357 
     358                        /* 
     359                         * fall back to HT20 if we don't use or use 
     360                         * the other extension channel 
     361                         */ 
     362                        if ((channel_type == NL80211_CHAN_HT40MINUS || 
     363                             channel_type == NL80211_CHAN_HT40PLUS) && 
     364                            channel_type != sdata->u.ibss.channel_type) 
     365                                sta_ht_cap_new.cap &= 
     366                                        ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 
     367 
     368                        if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new, 
     369                                   sizeof(sta_ht_cap_new))) { 
     370                                memcpy(&sta->sta.ht_cap, &sta_ht_cap_new, 
     371                                       sizeof(sta_ht_cap_new)); 
     372                                rates_updated = true; 
     373                        } 
     374                } 
     375 
     376                if (sta && rates_updated) 
     377                        rate_control_rate_init(sta); 
     378 
    321379                rcu_read_unlock(); 
    322380        } 
    323381 
    int ieee80211_ibss_join(struct ieee80211 
    896954                        struct cfg80211_ibss_params *params) 
    897955{ 
    898956        struct sk_buff *skb; 
     957        u32 changed = 0; 
    899958 
    900959        skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + 
    901                             36 /* bitrates */ + 
    902                             34 /* SSID */ + 
    903                             3  /* DS params */ + 
    904                             4  /* IBSS params */ + 
     960                            sizeof(struct ieee80211_hdr_3addr) + 
     961                            12 /* struct ieee80211_mgmt.u.beacon */ + 
     962                            2 + IEEE80211_MAX_SSID_LEN /* max SSID */ + 
     963                            2 + 8 /* max Supported Rates */ + 
     964                            3 /* max DS params */ + 
     965                            4 /* IBSS params */ + 
     966                            2 + (IEEE80211_MAX_SUPP_RATES - 8) + 
     967                            2 + sizeof(struct ieee80211_ht_cap) + 
     968                            2 + sizeof(struct ieee80211_ht_info) + 
    905969                            params->ie_len); 
    906970        if (!skb) 
    907971                return -ENOMEM; 
    int ieee80211_ibss_join(struct ieee80211 
    922986        sdata->vif.bss_conf.beacon_int = params->beacon_interval; 
    923987 
    924988        sdata->u.ibss.channel = params->channel; 
     989        sdata->u.ibss.channel_type = params->channel_type; 
    925990        sdata->u.ibss.fixed_channel = params->channel_fixed; 
    926991 
    927992        /* fix ourselves to that channel now already */ 
    928993        if (params->channel_fixed) { 
    929994                sdata->local->oper_channel = params->channel; 
    930                 WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata, 
    931                                                     NL80211_CHAN_NO_HT)); 
     995                if (!ieee80211_set_channel_type(sdata->local, sdata, 
     996                                               params->channel_type)) 
     997                        return -EINVAL; 
    932998        } 
    933999 
    9341000        if (params->ie) { 
    int ieee80211_ibss_join(struct ieee80211 
    9511017        ieee80211_recalc_idle(sdata->local); 
    9521018        mutex_unlock(&sdata->local->mtx); 
    9531019 
     1020        /* 
     1021         * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 
     1022         * reserved, but an HT STA shall protect HT transmissions as though 
     1023         * the HT Protection field were set to non-HT mixed mode. 
     1024         * 
     1025         * In an IBSS, the RIFS Mode field of the HT Operation element is 
     1026         * also reserved, but an HT STA shall operate as though this field 
     1027         * were set to 1. 
     1028         */ 
     1029 
     1030        sdata->vif.bss_conf.ht_operation_mode |= 
     1031                  IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 
     1032                | IEEE80211_HT_PARAM_RIFS_MODE; 
     1033 
     1034        changed |= BSS_CHANGED_HT; 
     1035        ieee80211_bss_info_change_notify(sdata, changed); 
     1036 
    9541037        ieee80211_queue_work(&sdata->local->hw, &sdata->work); 
    9551038 
    9561039        return 0; 
  • net/mac80211/ieee80211_i.h

    a b struct ieee80211_if_ibss { 
    474474        u8 ssid_len, ie_len; 
    475475        u8 *ie; 
    476476        struct ieee80211_channel *channel; 
     477        enum nl80211_channel_type channel_type; 
    477478 
    478479        unsigned long ibss_join_req; 
    479480        /* probe response/beacon for IBSS */ 
  • net/mac80211/iface.c

    a b static int ieee80211_do_open(struct net_ 
    178178{ 
    179179        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 
    180180        struct ieee80211_local *local = sdata->local; 
    181         struct sta_info *sta; 
    182181        u32 changed = 0; 
    183182        int res; 
    184183        u32 hw_reconf_flags = 0; 
    static int ieee80211_do_open(struct net_ 
    309308 
    310309        set_bit(SDATA_STATE_RUNNING, &sdata->state); 
    311310 
    312         if (sdata->vif.type == NL80211_IFTYPE_WDS) { 
    313                 /* Create STA entry for the WDS peer */ 
    314                 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 
    315                                      GFP_KERNEL); 
    316                 if (!sta) { 
    317                         res = -ENOMEM; 
    318                         goto err_del_interface; 
    319                 } 
    320  
    321                 /* no atomic bitop required since STA is not live yet */ 
    322                 set_sta_flag(sta, WLAN_STA_AUTHORIZED); 
    323  
    324                 res = sta_info_insert(sta); 
    325                 if (res) { 
    326                         /* STA has been freed */ 
    327                         goto err_del_interface; 
    328                 } 
    329  
    330                 rate_control_rate_init(sta); 
    331         } 
    332  
    333311        /* 
    334312         * set_multicast_list will be invoked by the networking core 
    335313         * which will check whether any increments here were done in 
    static int ieee80211_do_open(struct net_ 
    356334        netif_tx_start_all_queues(dev); 
    357335 
    358336        return 0; 
    359  err_del_interface: 
    360         drv_remove_interface(local, sdata); 
     337 
    361338 err_stop: 
    362339        if (!local->open_count) 
    363340                drv_stop(local); 
    static void ieee80211_if_setup(struct ne 
    719696        dev->destructor = free_netdev; 
    720697} 
    721698 
     699static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 
     700                                         struct sk_buff *skb) 
     701{ 
     702        struct ieee80211_local *local = sdata->local; 
     703        struct ieee80211_rx_status *rx_status; 
     704        struct ieee802_11_elems elems; 
     705        struct ieee80211_mgmt *mgmt; 
     706        struct sta_info *sta; 
     707        size_t baselen; 
     708        u32 rates = 0; 
     709        u16 stype; 
     710        bool new = false; 
     711        enum ieee80211_band band = local->hw.conf.channel->band; 
     712        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 
     713 
     714        rx_status = IEEE80211_SKB_RXCB(skb); 
     715        mgmt = (struct ieee80211_mgmt *) skb->data; 
     716        stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 
     717 
     718        if (stype != IEEE80211_STYPE_BEACON) 
     719                return; 
     720 
     721        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 
     722        if (baselen > skb->len) 
     723                return; 
     724 
     725        ieee802_11_parse_elems(mgmt->u.probe_resp.variable, 
     726                               skb->len - baselen, &elems); 
     727 
     728        rates = ieee80211_sta_get_rates(local, &elems, band); 
     729 
     730        rcu_read_lock(); 
     731 
     732        sta = sta_info_get(sdata, sdata->u.wds.remote_addr); 
     733 
     734        if (!sta) { 
     735                rcu_read_unlock(); 
     736                sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 
     737                                     GFP_KERNEL); 
     738                if (!sta) 
     739                        return; 
     740 
     741                new = true; 
     742        } 
     743 
     744        sta->last_rx = jiffies; 
     745        sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 
     746 
     747        if (elems.ht_cap_elem) 
     748                ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 
     749                                elems.ht_cap_elem, &sta->sta.ht_cap); 
     750 
     751        if (elems.wmm_param) 
     752                set_sta_flag(sta, WLAN_STA_WME); 
     753 
     754        if (new) { 
     755                set_sta_flag(sta, WLAN_STA_AUTHORIZED); 
     756                rate_control_rate_init(sta); 
     757                sta_info_insert_rcu(sta); 
     758        } 
     759 
     760        rcu_read_unlock(); 
     761} 
     762 
    722763static void ieee80211_iface_work(struct work_struct *work) 
    723764{ 
    724765        struct ieee80211_sub_if_data *sdata = 
    static void ieee80211_iface_work(struct  
    823864                                break; 
    824865                        ieee80211_mesh_rx_queued_mgmt(sdata, skb); 
    825866                        break; 
     867                case NL80211_IFTYPE_WDS: 
     868                        ieee80211_wds_rx_queued_mgmt(sdata, skb); 
     869                        break; 
    826870                default: 
    827871                        WARN(1, "frame for unexpected interface type"); 
    828872                        break; 
  • net/mac80211/main.c

    a b struct ieee80211_hw *ieee80211_alloc_hw( 
    574574                        WIPHY_FLAG_OFFCHAN_TX | 
    575575                        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 
    576576 
    577         wiphy->features = NL80211_FEATURE_SK_TX_STATUS; 
     577        wiphy->features = NL80211_FEATURE_SK_TX_STATUS | 
     578                          NL80211_FEATURE_HT_IBSS; 
    578579 
    579580        if (!ops->set_key) 
    580581                wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 
  • net/mac80211/rx.c

    a b ieee80211_rx_h_action(struct ieee80211_r 
    22372237                if (sdata->vif.type != NL80211_IFTYPE_STATION && 
    22382238                    sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 
    22392239                    sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 
    2240                     sdata->vif.type != NL80211_IFTYPE_AP) 
     2240                    sdata->vif.type != NL80211_IFTYPE_AP && 
     2241                    sdata->vif.type != NL80211_IFTYPE_WDS && 
     2242                    sdata->vif.type != NL80211_IFTYPE_ADHOC) 
    22412243                        break; 
    22422244 
    22432245                /* verify action_code is present */ 
    ieee80211_rx_h_mgmt(struct ieee80211_rx_ 
    24522454 
    24532455        if (!ieee80211_vif_is_mesh(&sdata->vif) && 
    24542456            sdata->vif.type != NL80211_IFTYPE_ADHOC && 
    2455             sdata->vif.type != NL80211_IFTYPE_STATION) 
     2457            sdata->vif.type != NL80211_IFTYPE_STATION && 
     2458            sdata->vif.type != NL80211_IFTYPE_WDS) 
    24562459                return RX_DROP_MONITOR; 
    24572460 
    24582461        switch (stype) { 
    24592462        case cpu_to_le16(IEEE80211_STYPE_BEACON): 
    24602463        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): 
    2461                 /* process for all: mesh, mlme, ibss */ 
     2464                /* process for all: mesh, mlme, ibss, wds */ 
    24622465                break; 
    24632466        case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 
    24642467        case cpu_to_le16(IEEE80211_STYPE_DISASSOC): 
    static int prepare_for_handlers(struct i 
    28052808                } 
    28062809                break; 
    28072810        case NL80211_IFTYPE_WDS: 
    2808                 if (bssid || !ieee80211_is_data(hdr->frame_control)) 
    2809                         return 0; 
    28102811                if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 
    28112812                        return 0; 
     2813 
     2814                if (ieee80211_is_data(hdr->frame_control) || 
     2815                    ieee80211_is_action(hdr->frame_control)) { 
     2816                        if (compare_ether_addr(sdata->vif.addr, hdr->addr1)) 
     2817                                return 0; 
     2818                } else if (!ieee80211_is_beacon(hdr->frame_control)) 
     2819                        return 0; 
     2820 
    28122821                break; 
    28132822        default: 
    28142823                /* should never get here */ 
  • net/mac80211/sta_info.h

    a b  
    3131 * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble 
    3232 *      frames. 
    3333 * @WLAN_STA_WME: Station is a QoS-STA. 
    34  * @WLAN_STA_WDS: Station is one of our WDS peers. 
    3534 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the 
    3635 *      IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next 
    3736 *      frame to this station is transmitted. 
    enum ieee80211_sta_info_flags { 
    6059        WLAN_STA_AUTHORIZED, 
    6160        WLAN_STA_SHORT_PREAMBLE, 
    6261        WLAN_STA_WME, 
    63         WLAN_STA_WDS, 
    6462        WLAN_STA_CLEAR_PS_FILT, 
    6563        WLAN_STA_MFP, 
    6664        WLAN_STA_BLOCK_BA, 
  • net/mac80211/util.c

    a b u8 *ieee80211_ie_build_ht_info(u8 *pos, 
    16121612        } 
    16131613        if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 
    16141614                ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 
     1615 
     1616        /* 
     1617         * Note: According to 802.11n-2009 9.13.3.1, HT Protection field and 
     1618         * RIFS Mode are reserved in IBSS mode, therefore keep them at 0 
     1619         */ 
    16151620        ht_info->operation_mode = 0x0000; 
    16161621        ht_info->stbc_param = 0x0000; 
    16171622 
  • net/wireless/chan.c

    a b  
    66 * Copyright 2009       Johannes Berg <johannes@sipsolutions.net> 
    77 */ 
    88 
     9#include <linux/export.h> 
    910#include <net/cfg80211.h> 
    1011#include "core.h" 
    1112 
    rdev_freq_to_chan(struct cfg80211_regist 
    4445        return chan; 
    4546} 
    4647 
    47 static bool can_beacon_sec_chan(struct wiphy *wiphy, 
    48                                 struct ieee80211_channel *chan, 
    49                                 enum nl80211_channel_type channel_type) 
     48int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 
     49                                  struct ieee80211_channel *chan, 
     50                                  enum nl80211_channel_type channel_type) 
    5051{ 
    5152        struct ieee80211_channel *sec_chan; 
    5253        int diff; 
    static bool can_beacon_sec_chan(struct w 
    7576 
    7677        return true; 
    7778} 
     79EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); 
    7880 
    7981int cfg80211_set_freq(struct cfg80211_registered_device *rdev, 
    8082                      struct wireless_dev *wdev, int freq, 
    int cfg80211_set_freq(struct cfg80211_re 
    109111                switch (channel_type) { 
    110112                case NL80211_CHAN_HT40PLUS: 
    111113                case NL80211_CHAN_HT40MINUS: 
    112                         if (!can_beacon_sec_chan(&rdev->wiphy, chan, 
    113                                                 channel_type)) { 
     114                        if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, 
     115                                                          channel_type)) { 
    114116                                printk(KERN_DEBUG 
    115117                                       "cfg80211: Secondary channel not " 
    116118                                       "allowed to initiate communication\n"); 
  • net/wireless/nl80211.c

    a b static int nl80211_join_ibss(struct sk_b 
    46844684                ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 
    46854685        } 
    46864686 
    4687         ibss.channel = ieee80211_get_channel(wiphy, 
    4688                 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 
     4687        if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 
     4688                enum nl80211_channel_type channel_type; 
     4689 
     4690                channel_type = nla_get_u32( 
     4691                                info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); 
     4692                if (channel_type != NL80211_CHAN_NO_HT && 
     4693                    channel_type != NL80211_CHAN_HT20 && 
     4694                    channel_type != NL80211_CHAN_HT40MINUS && 
     4695                    channel_type != NL80211_CHAN_HT40PLUS) 
     4696                        return -EINVAL; 
     4697 
     4698                if (channel_type != NL80211_CHAN_NO_HT && 
     4699                    !(wiphy->features & NL80211_FEATURE_HT_IBSS)) 
     4700                        return -EINVAL; 
     4701 
     4702                ibss.channel_type = channel_type; 
     4703        } else { 
     4704                ibss.channel_type = NL80211_CHAN_NO_HT; 
     4705        } 
     4706 
     4707        ibss.channel = rdev_freq_to_chan(rdev, 
     4708                nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]), 
     4709                ibss.channel_type); 
    46894710        if (!ibss.channel || 
    46904711            ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || 
    46914712            ibss.channel->flags & IEEE80211_CHAN_DISABLED) 
    46924713                return -EINVAL; 
    46934714 
     4715        /* Both channels should be able to initiate communication */ 
     4716        if ((ibss.channel_type == NL80211_CHAN_HT40PLUS || 
     4717             ibss.channel_type == NL80211_CHAN_HT40MINUS) && 
     4718            !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel, 
     4719                                          ibss.channel_type)) 
     4720                return -EINVAL; 
     4721 
    46944722        ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 
    46954723        ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 
    46964724 
Note: See TracBrowser for help on using the repository browser.