···777777 acx->rate_policy.long_retry_limit = c->long_retry_limit;778778 acx->rate_policy.aflags = c->aflags;779779780780+ ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));781781+ if (ret < 0) {782782+ wl1271_warning("Setting of rate policies failed: %d", ret);783783+ goto out;784784+ }780785786786+ /*787787+ * configure one rate class for basic p2p operations.788788+ * (p2p packets should always go out with OFDM rates, even789789+ * if we are currently connected to 11b AP)790790+ */791791+ acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE_P2P);792792+ acx->rate_policy.enabled_rates =793793+ cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);794794+ acx->rate_policy.short_retry_limit = c->short_retry_limit;795795+ acx->rate_policy.long_retry_limit = c->long_retry_limit;796796+ acx->rate_policy.aflags = c->aflags;781797782798 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));783799 if (ret < 0) {
···134134 /* Override the REF CLK from the NVS with the one from platform data */135135 gen_parms->general_params.ref_clock = wl->ref_clock;136136137137- /* LPD mode enable (bits 6-7) in WL1271 AP mode only */138138- if (wl->quirks & WL12XX_QUIRK_LPD_MODE)139139- gen_parms->general_params.general_settings |=140140- GENERAL_SETTINGS_DRPW_LPD;141141-142137 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);143138 if (ret < 0) {144139 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");···16921697 goto out;1693169816941699 __clear_bit(role_id, wl->roc_map);17001700+out:17011701+ return ret;17021702+}17031703+17041704+int wl12xx_cmd_channel_switch(struct wl1271 *wl,17051705+ struct ieee80211_channel_switch *ch_switch)17061706+{17071707+ struct wl12xx_cmd_channel_switch *cmd;17081708+ int ret;17091709+17101710+ wl1271_debug(DEBUG_ACX, "cmd channel switch");17111711+17121712+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);17131713+ if (!cmd) {17141714+ ret = -ENOMEM;17151715+ goto out;17161716+ }17171717+17181718+ cmd->channel = ch_switch->channel->hw_value;17191719+ cmd->switch_time = ch_switch->count;17201720+ cmd->tx_suspend = ch_switch->block_tx;17211721+ cmd->flush = 0; /* this value is ignored by the FW */17221722+17231723+ ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);17241724+ if (ret < 0) {17251725+ wl1271_error("failed to send channel switch command");17261726+ goto out_free;17271727+ }17281728+17291729+out_free:17301730+ kfree(cmd);17311731+17321732+out:17331733+ return ret;17341734+}17351735+17361736+int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)17371737+{17381738+ struct wl12xx_cmd_stop_channel_switch *cmd;17391739+ int ret;17401740+17411741+ wl1271_debug(DEBUG_ACX, "cmd stop channel switch");17421742+17431743+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);17441744+ if (!cmd) {17451745+ ret = -ENOMEM;17461746+ goto out;17471747+ }17481748+17491749+ ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);17501750+ if (ret < 0) {17511751+ wl1271_error("failed to stop channel switch command");17521752+ goto out_free;17531753+ }17541754+17551755+out_free:17561756+ kfree(cmd);17571757+16951758out:16961759 return ret;16971760}
+20
drivers/net/wireless/wl12xx/cmd.h
···7979int wl12xx_cmd_config_fwlog(struct wl1271 *wl);8080int wl12xx_cmd_start_fwlog(struct wl1271 *wl);8181int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);8282+int wl12xx_cmd_channel_switch(struct wl1271 *wl,8383+ struct ieee80211_channel_switch *ch_switch);8484+int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);82858386enum wl1271_commands {8487 CMD_INTERROGATE = 1, /*use this to read information elements*/···677674} __packed;678675679676struct wl12xx_cmd_stop_fwlog {677677+ struct wl1271_cmd_header header;678678+} __packed;679679+680680+struct wl12xx_cmd_channel_switch {681681+ struct wl1271_cmd_header header;682682+683683+ /* The new serving channel */684684+ u8 channel;685685+ /* Relative time of the serving channel switch in TBTT units */686686+ u8 switch_time;687687+ /* 1: Suspend TX till switch time; 0: Do not suspend TX */688688+ u8 tx_suspend;689689+ /* 1: Flush TX at switch time; 0: Do not flush */690690+ u8 flush;691691+} __packed;692692+693693+struct wl12xx_cmd_stop_channel_switch {680694 struct wl1271_cmd_header header;681695} __packed;682696
+5-1
drivers/net/wireless/wl12xx/conf.h
···416416 u8 queue_type;417417};418418419419-#define CONF_TX_MAX_RATE_CLASSES 8419419+#define CONF_TX_MAX_RATE_CLASSES 10420420421421#define CONF_TX_RATE_MASK_UNSPECIFIED 0422422#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \423423 CONF_HW_BIT_RATE_2MBPS)424424#define CONF_TX_RATE_RETRY_LIMIT 10425425+426426+/* basic rates for p2p operations (probe req/resp, etc.) */427427+#define CONF_TX_RATE_MASK_BASIC_P2P (CONF_HW_BIT_RATE_6MBPS | \428428+ CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS)425429426430/*427431 * Rates supported for data packets when operating as AP. Note the absence
+15
drivers/net/wireless/wl12xx/event.c
···300300 wl1271_stop_ba_event(wl);301301 }302302303303+ if ((vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) && !is_ap) {304304+ wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. "305305+ "status = 0x%x",306306+ mbox->channel_switch_status);307307+ /*308308+ * That event uses for two cases:309309+ * 1) channel switch complete with status=0310310+ * 2) channel switch failed status=1311311+ */312312+ if (test_and_clear_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags) &&313313+ (wl->vif))314314+ ieee80211_chswitch_done(wl->vif,315315+ mbox->channel_switch_status ? false : true);316316+ }317317+303318 if ((vector & DUMMY_PACKET_EVENT_ID)) {304319 wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");305320 if (wl->vif)
+40-8
drivers/net/wireless/wl12xx/main.c
···13331333 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",13341334 wl->chip.id);1335133513361336- /*13371337- * 'end-of-transaction flag' and 'LPD mode flag'13381338- * should be set in wl127x AP mode only13391339- */13401340- if (wl->bss_type == BSS_TYPE_AP_BSS)13411341- wl->quirks |= (WL12XX_QUIRK_END_OF_TRANSACTION |13421342- WL12XX_QUIRK_LPD_MODE);13431343-13441336 ret = wl1271_setup(wl);13451337 if (ret < 0)13461338 goto out;···22132221static int wl1271_unjoin(struct wl1271 *wl)22142222{22152223 int ret;22242224+22252225+ if (test_and_clear_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags)) {22262226+ wl12xx_cmd_stop_channel_switch(wl);22272227+ ieee80211_chswitch_done(wl->vif, false);22282228+ }2216222922172230 /* to stop listening to a channel, we disconnect */22182231 ret = wl12xx_cmd_role_stop_sta(wl);···41274130 return 0;41284131}4129413241334133+static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,41344134+ struct ieee80211_channel_switch *ch_switch)41354135+{41364136+ struct wl1271 *wl = hw->priv;41374137+ int ret;41384138+41394139+ wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");41404140+41414141+ mutex_lock(&wl->mutex);41424142+41434143+ if (unlikely(wl->state == WL1271_STATE_OFF)) {41444144+ mutex_unlock(&wl->mutex);41454145+ ieee80211_chswitch_done(wl->vif, false);41464146+ return;41474147+ }41484148+41494149+ ret = wl1271_ps_elp_wakeup(wl);41504150+ if (ret < 0)41514151+ goto out;41524152+41534153+ ret = wl12xx_cmd_channel_switch(wl, ch_switch);41544154+41554155+ if (!ret)41564156+ set_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags);41574157+41584158+ wl1271_ps_elp_sleep(wl);41594159+41604160+out:41614161+ mutex_unlock(&wl->mutex);41624162+}41634163+41304164static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)41314165{41324166 struct wl1271 *wl = hw->priv;···44344406 .ampdu_action = wl1271_op_ampdu_action,44354407 .tx_frames_pending = wl1271_tx_frames_pending,44364408 .set_bitrate_mask = wl12xx_set_bitrate_mask,44094409+ .channel_switch = wl12xx_op_channel_switch,44374410 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)44384411};44394412···47074678 */47084679 wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -47094680 sizeof(struct ieee80211_header);46814681+46824682+ wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -46834683+ sizeof(struct ieee80211_header);4710468447114685 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;47124686
+1-6
drivers/net/wireless/wl12xx/wl12xx.h
···348348 WL1271_FLAG_SOFT_GEMINI,349349 WL1271_FLAG_RX_STREAMING_STARTED,350350 WL1271_FLAG_RECOVERY_IN_PROGRESS,351351+ WL1271_FLAG_CS_PROGRESS,351352};352353353354struct wl1271_link {···671670672671/* WL128X requires aggregated packets to be aligned to the SDIO block size */673672#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)674674-675675-/*676676- * WL127X AP mode requires Low Power DRPw (LPD) enable to reduce power677677- * consumption678678- */679679-#define WL12XX_QUIRK_LPD_MODE BIT(3)680673681674/* Older firmwares did not implement the FW logger over bus feature */682675#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)