Commit 85a8eefd authored by John W. Linville's avatar John W. Linville

Merge branch 'for-linville' of git://github.com/lucacoelho/wl12xx

parents bb8f2cb2 6b661895
......@@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
/*
* We currently do not support hidden SSID. The real SSID
* should be fetched from mac80211 first.
*/
if (wl->ssid_len == 0) {
wl1271_warning("Hidden SSID currently not supported for AP");
/* trying to use hidden SSID with an old hostapd version */
if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) {
wl1271_error("got a null SSID from beacon/bss");
ret = -EINVAL;
goto out;
}
......@@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
cmd->ap.dtim_interval = bss_conf->dtim_period;
cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
cmd->channel = wl->channel;
cmd->ap.ssid_len = wl->ssid_len;
if (!bss_conf->hidden_ssid) {
/* take the SSID from the beacon for backward compatibility */
cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
cmd->ap.ssid_len = wl->ssid_len;
memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
} else {
cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
cmd->ap.ssid_len = bss_conf->ssid_len;
memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
}
cmd->ap.local_rates = cpu_to_le32(0xffffffff);
switch (wl->band) {
......@@ -1106,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
{
struct sk_buff *skb;
int ret;
u32 rate;
skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
ie, ie_len);
......@@ -1116,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
if (band == IEEE80211_BAND_2GHZ)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
skb->data, skb->len, 0,
wl->conf.tx.basic_rate);
skb->data, skb->len, 0, rate);
else
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
skb->data, skb->len, 0,
wl->conf.tx.basic_rate_5);
skb->data, skb->len, 0, rate);
out:
dev_kfree_skb(skb);
......@@ -1134,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
struct sk_buff *skb)
{
int ret;
u32 rate;
if (!skb)
skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
......@@ -1142,14 +1149,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]);
if (wl->band == IEEE80211_BAND_2GHZ)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
skb->data, skb->len, 0,
wl->conf.tx.basic_rate);
skb->data, skb->len, 0, rate);
else
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
skb->data, skb->len, 0,
wl->conf.tx.basic_rate_5);
skb->data, skb->len, 0, rate);
if (ret < 0)
wl1271_error("Unable to set ap probe request template.");
......@@ -1442,7 +1448,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
cmd->supported_rates =
cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates));
cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
wl->band));
wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
cmd->supported_rates, sta->uapsd_queues);
......
......@@ -454,12 +454,10 @@ struct conf_rx_settings {
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
/*
* Default rates for working as IBSS. use 11b rates
*/
/* default rates for working as IBSS (11b and OFDM) */
#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
CONF_HW_BIT_RATE_11MBPS);
CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES);
struct conf_tx_rate_class {
......
......@@ -181,7 +181,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl)
} else {
int i;
struct wl1271_link *lnk;
for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) {
for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) {
lnk = &wl->links[i];
if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap)
continue;
......
......@@ -103,6 +103,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
{
struct wl12xx_disconn_template *tmpl;
int ret;
u32 rate;
tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
if (!tmpl) {
......@@ -113,9 +114,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_DEAUTH);
rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
tmpl, sizeof(*tmpl), 0,
wl1271_tx_min_rate_get(wl));
tmpl, sizeof(*tmpl), 0, rate);
out:
kfree(tmpl);
......@@ -126,6 +127,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
{
struct ieee80211_hdr_3addr *nullfunc;
int ret;
u32 rate;
nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
if (!nullfunc) {
......@@ -142,9 +144,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl)
memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN);
rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
sizeof(*nullfunc), 0,
wl1271_tx_min_rate_get(wl));
sizeof(*nullfunc), 0, rate);
out:
kfree(nullfunc);
......@@ -155,6 +157,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
{
struct ieee80211_qos_hdr *qosnull;
int ret;
u32 rate;
qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
if (!qosnull) {
......@@ -171,9 +174,9 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN);
memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN);
rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
sizeof(*qosnull), 0,
wl1271_tx_min_rate_get(wl));
sizeof(*qosnull), 0, rate);
out:
kfree(qosnull);
......@@ -498,7 +501,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
return ret;
/* use the min basic rate for AP broadcast/multicast */
rc.enabled_rates = wl1271_tx_min_rate_get(wl);
rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
rc.short_retry_limit = 10;
rc.long_retry_limit = 10;
rc.aflags = 0;
......
This diff is collapsed.
......@@ -28,6 +28,7 @@
#include "scan.h"
#include "acx.h"
#include "ps.h"
#include "tx.h"
void wl1271_scan_complete_work(struct work_struct *work)
{
......@@ -99,14 +100,18 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
for (i = 0, j = 0;
i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
i++) {
flags = req->channels[i]->flags;
if (!test_bit(i, wl->scan.scanned_ch) &&
!(flags & IEEE80211_CHAN_DISABLED) &&
((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) &&
(req->channels[i]->band == band)) {
(req->channels[i]->band == band) &&
/*
* In passive scans, we scan all remaining
* channels, even if not marked as such.
* In active scans, we only scan channels not
* marked as passive.
*/
(passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
req->channels[i]->band,
req->channels[i]->center_freq);
......@@ -158,6 +163,10 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
int ret;
u16 scan_options = 0;
/* skip active scans if we don't have SSIDs */
if (!passive && wl->scan.req->n_ssids == 0)
return WL1271_NOTHING_TO_SCAN;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
if (!cmd || !trigger) {
......@@ -165,8 +174,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
goto out;
}
/* No SSIDs means that we have a forced passive scan */
if (passive || wl->scan.req->n_ssids == 0)
if (passive)
scan_options |= WL1271_SCAN_OPT_PASSIVE;
if (WARN_ON(wl->role_id == WL12XX_INVALID_ROLE_ID)) {
......@@ -236,14 +244,17 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
void wl1271_scan_stm(struct wl1271 *wl)
{
int ret = 0;
enum ieee80211_band band;
u32 rate;
switch (wl->scan.state) {
case WL1271_SCAN_STATE_IDLE:
break;
case WL1271_SCAN_STATE_2GHZ_ACTIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
wl->conf.tx.basic_rate);
band = IEEE80211_BAND_2GHZ;
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
ret = wl1271_scan_send(wl, band, false, rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
wl1271_scan_stm(wl);
......@@ -252,8 +263,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_2GHZ_PASSIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
wl->conf.tx.basic_rate);
band = IEEE80211_BAND_2GHZ;
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
ret = wl1271_scan_send(wl, band, true, rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
if (wl->enable_11a)
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
......@@ -265,8 +277,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_5GHZ_ACTIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
wl->conf.tx.basic_rate_5);
band = IEEE80211_BAND_5GHZ;
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
ret = wl1271_scan_send(wl, band, false, rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
wl1271_scan_stm(wl);
......@@ -275,8 +288,9 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_5GHZ_PASSIVE:
ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
wl->conf.tx.basic_rate_5);
band = IEEE80211_BAND_5GHZ;
rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
ret = wl1271_scan_send(wl, band, true, rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
wl->scan.state = WL1271_SCAN_STATE_DONE;
wl1271_scan_stm(wl);
......
......@@ -30,6 +30,7 @@
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/gpio.h>
#include <linux/wl12xx.h>
#include <linux/kthread.h>
......@@ -142,14 +143,23 @@ static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
ret = pm_runtime_get_sync(&func->dev);
if (ret < 0)
goto out;
/* Runtime PM might be disabled, power up the card manually */
ret = mmc_power_restore_host(func->card->host);
if (ret < 0)
goto out;
sdio_claim_host(func);
sdio_enable_func(func);
sdio_release_host(func);
} else {
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
/* Runtime PM might be disabled, power off the card manually */
ret = mmc_power_save_host(func->card->host);
if (ret < 0)
goto out;
/* Power down the card */
ret = pm_runtime_put_sync(&func->dev);
}
......@@ -433,7 +443,6 @@ static int __devinit wl1271_probe(struct sdio_func *func,
sdio_set_drvdata(func, wl_test);
/* power up the device */
ret = wl1271_chip_wakeup(wl);
if (ret) {
......
......@@ -81,8 +81,7 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
struct ieee80211_hdr *hdr;
int ret;
hdr = (struct ieee80211_hdr *)(skb->data +
sizeof(struct wl1271_tx_hw_descr));
hdr = (struct ieee80211_hdr *)skb->data;
/*
* stop bssid-based filtering before transmitting authentication
......@@ -181,14 +180,20 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb)
static u8 wl1271_tx_get_hlid(struct wl1271 *wl, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (wl12xx_is_dummy_packet(wl, skb))
return wl->system_hlid;
if (wl->bss_type == BSS_TYPE_AP_BSS)
return wl12xx_tx_get_hlid_ap(wl, skb);
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags))
wl1271_tx_update_filters(wl, skb);
if ((test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags)) &&
!ieee80211_is_auth(hdr->frame_control) &&
!ieee80211_is_assoc_req(hdr->frame_control))
return wl->sta_hlid;
else
return wl->dev_hlid;
......@@ -423,8 +428,6 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
if (wl->bss_type == BSS_TYPE_AP_BSS) {
wl1271_tx_ap_update_inconnection_sta(wl, skb);
wl1271_tx_regulate_link(wl, hlid);
} else {
wl1271_tx_update_filters(wl, skb);
}
/*
......@@ -447,13 +450,14 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
return total_len;
}
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
enum ieee80211_band rate_band)
{
struct ieee80211_supported_band *band;
u32 enabled_rates = 0;
int bit;
band = wl->hw->wiphy->bands[wl->band];
band = wl->hw->wiphy->bands[rate_band];
for (bit = 0; bit < band->n_bitrates; bit++) {
if (rate_set & 0x1)
enabled_rates |= band->bitrates[bit].hw_value;
......@@ -986,20 +990,10 @@ void wl1271_tx_flush(struct wl1271 *wl)
wl1271_warning("Unable to flush all TX buffers, timed out.");
}
u32 wl1271_tx_min_rate_get(struct wl1271 *wl)
u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
{
int i;
u32 rate = 0;
if (!wl->basic_rate_set) {
WARN_ON(1);
wl->basic_rate_set = wl->conf.tx.basic_rate;
}
for (i = 0; !rate; i++) {
if ((wl->basic_rate_set >> i) & 0x1)
rate = 1 << i;
}
if (WARN_ON(!rate_set))
return 0;
return rate;
return BIT(__ffs(rate_set));
}
......@@ -209,8 +209,9 @@ void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
void wl1271_tx_flush(struct wl1271 *wl);
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
enum ieee80211_band rate_band);
u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb);
void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
......
......@@ -138,7 +138,7 @@ extern u32 wl12xx_debug_level;
#define WL1271_DEFAULT_DTIM_PERIOD 1
#define WL12XX_MAX_ROLES 4
#define WL12XX_MAX_LINKS 8
#define WL12XX_MAX_LINKS 12
#define WL12XX_INVALID_ROLE_ID 0xff
#define WL12XX_INVALID_LINK_ID 0xff
......@@ -279,7 +279,7 @@ struct wl12xx_fw_status {
/* Cumulative counter of released Voice memory blocks */
u8 tx_voice_released_blks;
u8 padding_1[7];
u8 padding_1[3];
__le32 log_start_addr;
} __packed;
......@@ -526,6 +526,7 @@ struct wl1271 {
u32 basic_rate_set;
u32 basic_rate;
u32 rate_set;
u32 bitrate_masks[IEEE80211_NUM_BANDS];
/* The current band */
enum ieee80211_band band;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment