aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/Kconfig0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/Makefile0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/ath.h0
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/Kconfig9
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/Makefile4
-rw-r--r--drivers/net/wireless/ath/ath6kl/c210.c8
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/cfg80211.c82
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/core.h2
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/debug.c143
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/debug.h4
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/hif.c59
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/htc.c4
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/init.c167
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/main.c35
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/sdio.c16
-rw-r--r--drivers/net/wireless/ath/ath6kl/softmac.c12
-rw-r--r--[-rwxr-xr-x]drivers/net/wireless/ath/ath6kl/txrx.c26
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/wmi.c139
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/wmi.h27
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/debug.c0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/hw.c0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/key.c0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/main.c0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/regd.c0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/regd.h0
-rwxr-xr-x[-rw-r--r--]drivers/net/wireless/ath/regd_common.h0
26 files changed, 652 insertions, 85 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 3945707..3945707 100644..100755
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 214def7..214def7 100644..100755
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 4596c33..4596c33 100644..100755
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index d755a5e..f8965d0 100755
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -30,3 +30,12 @@ config ATH6KL_DEBUG
depends on ATH6KL
---help---
Enables debug support
+
+config ATH6KL_LOCALE_USA
+ bool "Atheros regulatory domain as USA"
+ depends on ATH6KL
+
+config 5GH_WLAN_COUNTRY_CODE
+ bool "Atheros WiFi Driver for 5GH channel setting"
+ default y
+
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index dcf2db9..b8b22e5 100755
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -64,3 +64,7 @@ ath6kl_usb-y += wmiconfig.o
ath6kl_usb-$(CONFIG_NL80211_TESTMODE) += testmode.o
ccflags-y += -D__CHECK_ENDIAN__
+# 5GHz channels setting
+ifeq ($(CONFIG_5GH_WLAN_COUNTRY_CODE),y)
+ccflags-y += -DGLOBALCONFIG_WLAN_COUNTRY_CODE
+endif
diff --git a/drivers/net/wireless/ath/ath6kl/c210.c b/drivers/net/wireless/ath/ath6kl/c210.c
index 4ae23ac..bb5f189 100644
--- a/drivers/net/wireless/ath/ath6kl/c210.c
+++ b/drivers/net/wireless/ath/ath6kl/c210.c
@@ -68,7 +68,7 @@ int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *w
inode = GET_INODE_FROM_FILEP(filp);
if (!inode) {
- printk(KERN_ERR "android_readwrite_file: Error 2\n");
+ printk(KERN_INFO "android_readwrite_file: Error 2\n");
ret = -ENOENT;
break;
}
@@ -78,12 +78,12 @@ int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *w
if (wbuf) {
if ((ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_ERR "android_readwrite_file: Error 3\n");
+ printk(KERN_INFO "android_readwrite_file: Error 3\n");
break;
}
} else {
if ((ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_ERR "android_readwrite_file: Error 4\n");
+ printk(KERN_INFO "android_readwrite_file: Error 4\n");
break;
}
}
@@ -94,7 +94,7 @@ int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *w
}
set_fs(oldfs);
- printk(KERN_ERR "android_readwrite_file: ret=%d\n", ret);
+ printk(KERN_INFO "android_readwrite_file: ret=%d\n", ret);
return ret;
}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index d4b000c..cceb9fd 100755
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -872,6 +872,33 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
vif->sme_state = SME_DISCONNECTED;
}
+static int ath6kl_set_probed_ssids(struct ath6kl *ar,
+ struct ath6kl_vif *vif,
+ struct cfg80211_ssid *ssids, int n_ssids)
+{
+ u8 i;
+
+ if (n_ssids > MAX_PROBED_SSIDS)
+ return -EINVAL;
+
+ for (i = 0; i < n_ssids; i++) {
+ ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
+ ssids[i].ssid_len ?
+ SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
+ ssids[i].ssid_len,
+ ssids[i].ssid);
+ }
+
+ /* Make sure no old entries are left behind */
+ for (i = n_ssids; i < MAX_PROBED_SSIDS; i++) {
+ ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
+ DISABLE_SSID_FLAG, 0, NULL);
+ }
+
+ return 0;
+}
+
+
static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request)
{
@@ -899,18 +926,10 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
}
}
- if (request->n_ssids && request->ssids[0].ssid_len) {
- u8 i;
-
- if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
- request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
-
- for (i = 0; i < request->n_ssids; i++)
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
- i + 1, SPECIFIC_SSID_FLAG,
- request->ssids[i].ssid_len,
- request->ssids[i].ssid);
- }
+ ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
+ request->n_ssids);
+ if (ret < 0)
+ return ret;
/* this also clears IE in fw if it's not set */
ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
@@ -946,6 +965,9 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
}
for (i = 0; i < n_channels; i++) {
+#if 0
+ ath6kl_err("scanning channel %d\n",request->channels[i]->center_freq);
+#endif
if (ath6kl_first_2g_only
&& request->channels[i]->center_freq > 5000) {
ath6kl_err("skip 5ghz channel %d %d\n",
@@ -2115,7 +2137,10 @@ skip_arp:
if (ret)
return ret;
- return 0;
+
+ ret = ath6kl_hif_wait_for_pending_recv(ar);
+
+ return ret;
}
static int ath6kl_wow_resume(struct ath6kl *ar)
@@ -2203,7 +2228,10 @@ static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
if (ret)
return ret;
- return 0;
+
+ ret = ath6kl_hif_wait_for_pending_recv(ar);
+
+ return ret;
}
static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
@@ -3128,7 +3156,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
struct ath6kl_vif *vif = netdev_priv(dev);
u16 interval;
int ret;
- u8 i;
if (ar->state != ATH6KL_STATE_ON)
return -EIO;
@@ -3138,11 +3165,11 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
ath6kl_cfg80211_scan_complete_event(vif, true);
- for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
- i, DISABLE_SSID_FLAG,
- 0, NULL);
- }
+ ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
+ request->n_ssids);
+ if (ret < 0)
+ return ret;
+
/* fw uses seconds, also make sure that it's >0 */
interval = max_t(u16, 1, request->interval / 1000);
@@ -3151,15 +3178,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
interval, interval,
10, 0, 0, 0, 3, 0, 0, 0);
- if (request->n_ssids && request->ssids[0].ssid_len) {
- for (i = 0; i < request->n_ssids; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
- i, SPECIFIC_SSID_FLAG,
- request->ssids[i].ssid_len,
- request->ssids[i].ssid);
- }
- }
-
ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_WOW_MODE_ENABLE,
WOW_FILTER_SSID,
@@ -3441,7 +3459,7 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
}
/* max num of ssids that can be probed during scanning */
- wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+ wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
@@ -3460,7 +3478,7 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
wiphy->wowlan.pattern_min_len = 1;
wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
- wiphy->max_sched_scan_ssids = 10;
+ wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
ath6kl_setup_android_resource(ar);
@@ -3551,6 +3569,8 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
vif->pspoll_num = WLAN_CONFIG_PSPOLL_NUM;
vif->mcastrate = WLAN_CONFIG_MCAST_RATE;
+ vif->force_reload = false;
+ vif->sdio_remove = false;
memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
if (fw_vif_idx != 0)
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 8ee906d..97c1ae5 100755
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -609,6 +609,8 @@ struct ath6kl_vif {
struct wmi_scan_params_cmd scparams;
unsigned int pspoll_num;
u16 mcastrate;
+ bool force_reload;
+ bool sdio_remove;
};
#define WOW_LIST_ID 0
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 8fd6d1f..28b3e77 100755
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -400,8 +400,10 @@ static ssize_t ath6kl_fwlog_block_read(struct file *file,
ret = wait_for_completion_interruptible(
&ar->debug.fwlog_completion);
- if (ret == -ERESTARTSYS)
+ if (ret == -ERESTARTSYS) {
+ vfree(buf);
return ret;
+ }
spin_lock(&ar->debug.fwlog_queue.lock);
}
@@ -1787,6 +1789,139 @@ static const struct file_operations fops_power_params = {
.llseek = default_llseek,
};
+static ssize_t ath6kl_lrssi_roam_config_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ struct low_rssi_scan_params lrssi_params;
+ char buf[32];
+ ssize_t len;
+ char *sptr, *token;
+ u16 val16;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou16(token, 0, &val16))
+ return -EINVAL;
+ lrssi_params.lrssi_scan_period = cpu_to_le16(val16);
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou16(token, 0, &val16))
+ return -EINVAL;
+ lrssi_params.lrssi_scan_threshold = cpu_to_le16(val16);
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou16(token, 0, &val16))
+ return -EINVAL;
+ lrssi_params.lrssi_roam_threshold = cpu_to_le16(val16);
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &lrssi_params.roam_rssi_floor))
+ return -EINVAL;
+
+ ath6kl_wmi_set_roam_lrssi_config_cmd(ar->wmi, &lrssi_params);
+
+ return count;
+}
+
+static const struct file_operations fops_lrssi_roam_config = {
+ .write = ath6kl_lrssi_roam_config_write,
+ .open = ath6kl_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t ath6kl_ht_cap_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ struct ath6kl_vif *vif;
+ struct wmi_set_ht_cap_cmd ht_cap;
+ char buf[32];
+ ssize_t len;
+ char *sptr, *token;
+
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.band))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.enable))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.chan_width_40m_supported))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.short_gi_20mhz))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.short_gi_40mhz))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.intolerance_40mhz))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &ht_cap.max_ampdu_len_exp))
+ return -EINVAL;
+
+ ath6kl_wmi_set_ht_cap_cmd(ar->wmi, vif->fw_vif_idx, &ht_cap);
+
+ return count;
+}
+
+static const struct file_operations fops_ht_cap = {
+ .write = ath6kl_ht_cap_write,
+ .open = ath6kl_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
int ath6kl_debug_init(struct ath6kl *ar)
{
skb_queue_head_init(&ar->debug.fwlog_queue);
@@ -1869,6 +2004,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
&fops_power_params);
+ debugfs_create_file("lrssi_roam_config", S_IRUSR, ar->debugfs_phy, ar,
+ &fops_lrssi_roam_config);
+
+ debugfs_create_file("ht_cap", S_IRUSR, ar->debugfs_phy, ar,
+ &fops_ht_cap);
+
return ath6kl_init_debugfs_pri(ar);
}
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 83a7322..aaecb5d 100755
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -54,9 +54,9 @@ char *sec_conv_mac(const u8 *mac);
#define ath6kl_info(fmt, ...) \
ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
#define ath6kl_err(fmt, ...) \
- ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
+ ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
#define ath6kl_warn(fmt, ...) \
- ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
+ ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index ca910a1..2793ab6 100755
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -118,6 +118,9 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
{
u32 dummy;
int ret;
+ struct ath6kl_vif *vif;
+
+ vif = ath6kl_vif_first(dev->ar);
ath6kl_warn("firmware crashed\n");
@@ -133,6 +136,8 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
ath6kl_hif_dump_fw_crash(dev->ar);
ath6kl_read_fwlogs(dev->ar);
+ cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
+
return ret;
}
@@ -393,7 +398,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
u8 host_int_status = 0;
u32 lk_ahd = 0;
u8 htc_mbox = 1 << HTC_MAILBOX;
-
+ struct ath6kl_vif *vif;
+ vif = ath6kl_vif_first(dev->ar);
ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);
/*
@@ -402,7 +408,12 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
* sleep or call any API that can block or switch thread/task
* contexts. This is a fully schedulable context.
*/
-
+#ifdef CONFIG_MACH_PX
+ if (vif->sdio_remove == true) {
+ *done = true;
+ goto out;
+ }
+#endif
/*
* Process pending intr only when int_status_en is clear, it may
* result in unnecessary bus transaction otherwise. Target may be
@@ -450,8 +461,19 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
htc_mbox) {
rg = &dev->irq_proc_reg;
lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
- if (!lk_ahd)
- ath6kl_err("lookAhead is zero!\n");
+
+ if (vif->force_reload == true) {
+ lk_ahd = 0;
+ }
+ if (!lk_ahd) {
+ ath6kl_err("lookAhead is zero! force_reload = %d\n", vif->force_reload);
+#ifdef CONFIG_MACH_PX
+ cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
+ ath6kl_hif_rx_control(dev, false);
+ ssleep(3);
+ status = -ENOMEM;
+#endif
+ }
}
}
}
@@ -476,9 +498,17 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
*/
status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt,
lk_ahd, &fetched);
+#ifdef CONFIG_MACH_PX
+ if (status && status != -ECANCELED) {
+ cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
+ ath6kl_hif_rx_control(dev, false);
+ ssleep(3);
+ goto out;
+ }
+#else
if (status)
goto out;
-
+#endif
if (!fetched)
/*
* HTC could not pull any messages out due to lack
@@ -539,10 +569,22 @@ out:
/* interrupt handler, kicks off all interrupt processing */
int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
{
+#ifdef CONFIG_MACH_PX
+ struct ath6kl_device *dev;
+ unsigned long timeout;
+ int status = 0;
+ bool done = false;
+
+ if ((ar != NULL) && (ar->htc_target != NULL) && (ar->htc_target->dev != NULL))
+ dev = ar->htc_target->dev;
+ else
+ return status;
+#else
struct ath6kl_device *dev = ar->htc_target->dev;
unsigned long timeout;
int status = 0;
bool done = false;
+#endif
/*
* Reset counter used to flag a re-scan of IRQ status registers on
@@ -555,7 +597,12 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
* re-read.
*/
timeout = jiffies + msecs_to_jiffies(ATH6KL_HIF_COMMUNICATION_TIMEOUT);
- while (time_before(jiffies, timeout) && !done) {
+#ifdef CONFIG_MACH_PX
+ while (time_before(jiffies, timeout) && !done && (dev != NULL))
+#else
+ while (time_before(jiffies, timeout) && !done)
+#endif
+ {
status = proc_pending_irqs(dev, &done);
if (status)
break;
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 402e1c5..16729fb 100755
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -1451,6 +1451,8 @@ static int ath6kl_htc_rx_alloc(struct htc_target *target,
struct htc_packet *packet, *tmp_pkt;
struct htc_frame_hdr *htc_hdr;
int i, n_msg;
+ struct ath6kl_vif *vif;
+ vif = ath6kl_vif_first(target->dev->ar);
spin_lock_bh(&target->rx_lock);
@@ -2128,6 +2130,8 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
int num_look_ahead = 1;
enum htc_endpoint_id id;
int n_fetched = 0;
+ struct ath6kl_vif *vif;
+ vif = ath6kl_vif_first(target->dev->ar);
INIT_LIST_HEAD(&comp_pktq);
*num_pkts = 0;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 76a1d64..ba587f9 100755
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -46,7 +46,13 @@ static unsigned int ar6k_clock = 26000000;
#else
static unsigned int ar6k_clock = 19200000;
#endif
+
+#ifdef CONFIG_ATH6KL_LOCALE_USA
+static unsigned short reg_domain = 0x8348;
+#else
static unsigned short reg_domain = 0xffff;
+#endif
+
static unsigned short lrssi = 10;
static unsigned short en_ani = 1;
@@ -481,7 +487,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
{
int status = 0;
int ret;
-#if CONFIG_MACH_PX
+#ifdef CONFIG_MACH_PX
struct ath6kl_vif *vif = ath6kl_get_vif_by_index(ar, idx);
#endif
/*
@@ -496,7 +502,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
}
-#if CONFIG_MACH_PX
+#ifdef CONFIG_MACH_PX
if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) {
if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx,
0, vif->pspoll_num, 0, 0, 1,
@@ -1528,6 +1534,157 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
return 0;
}
+#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
+#define COUNTRY_MAX 76
+struct channels {
+ char country[30];
+ char ccode[6];
+ unsigned short reg_dmn_code;
+}
+pArray[COUNTRY_MAX] = {
+ {"Afghanistan", "AF 0", 0x406a},
+ {"Albania", "AL 0", 0x8008},
+ {"Algeria", "DZ 0", 0x800c},
+ {"Angola", "AD 0", 0x406a},
+ {"Austria", "AT 0", 0x8028},
+ {"Australia", "AU 0", 0x8024},
+ {"Bangladesh", "BD 0", 0x8032},
+ {"Belgium", "BE 0", 0x8038},
+ {"Bosnia", "BA 0", 0x8046},
+ {"Bulgaria", "BG 0", 0x8064},
+ {"Croatia", "HR 0", 0x80bf},
+ {"Greece", "GR 0", 0x812c},
+ {"Czech Republic", "CZ 0", 0x80cb},
+ {"Egypt", "EG 0", 0x8332},
+ {"Nordic", "FI 0", 0x80f6},
+ {"Finland", "FI 0", 0x80f6},
+ {"France", "FR 0", 0x80FA},
+ {"Gabon", "GA 0", 0x406a},
+ {"Germany", "DE 0", 0x8114},
+ {"Ghana", "GH 0", 0x406a},
+ {"Greece", "GR 0", 0x812c},
+ {"Hungary", "HU 0", 0x815c},
+ {"Iceland", "IS 0", 0x8160},
+ {"India", "IN 0", 0x8164},
+ {"Indonesia", "ID 0", 0x8168},
+ {"Iraq", "IQ 0", 0x406a},
+ {"IE", "IE 0", 0x8174},
+ {"Ireland", "IE 0", 0x8174},
+ {"Israel", "IL 0", 0x8178},
+ {"Italy", "IT 0", 0x817c},
+ {"Jamaica", "JM 0", 0x8184},
+ {"Jordan", "JO 0", 0x8190},
+ {"Central Asia", "KZ 0", 0x818e},
+ {"Kazakhstan", "KZ 0", 0x818e},
+ {"Kenya", "KE 0", 0x8198},
+ {"BALTIC", "LV 0", 0x81ac},
+ {"Libya", "LY 0", 0x406a},
+ {"Lithuania", "LT 0", 0x81b8},
+ {"Luxemburg", "LU 0", 0x81ba},
+ {"Macedonia", "MK 0", 0x8327},
+ {"Malaysia", "MY 0", 0x81ca},
+ {"Mongolia", "MN 0", 0x406a},
+ {"Montenegro", "ME 0", 0x837b},
+ {"Morocco", "MA 0", 0x81f8},
+ {"Nepal", "NP 0", 0x820c},
+ {"Netherlands", "NL 0", 0x8210},
+ {"The Netherlands", "NL 0", 0x8210},
+ {"New Zealand", "NZ 0", 0x822a},
+ {"Nigeria", "NG 0", 0x406a},
+ {"Norway", "NO 0", 0x8242},
+ {"Pakistan", "PK 0", 0x824a},
+ {"Philippines", "PH 0", 0x8260},
+ {"Poland", "PL 0", 0x8268},
+ {"Portugal", "PT 0", 0x826c},
+ {"Romania", "RO 0", 0x8282},
+ {"Russia", "RU 0", 0x8283},
+ {"KSA", "SA 0", 0x82aa},
+ {"Senegal", "SN 0", 0x406a},
+ {"Serbia", "RS 0", 0x8114},
+ {"Singapore", "SG 0", 0x82be},
+ {"Slovakia", "SK 0", 0x82bf},
+ {"Slovenia", "SI 0", 0x82c1},
+ {"South Africa", "ZA 0", 0x82c6},
+ {"Spain", "ES 0", 0x82D4},
+ {"Sri Lanka", "LK 0", 0x8090},
+ {"Sweden", "SE 0", 0x82f0},
+ {"Switzerland", "CH 0", 0x82f4},
+ {"Thailand", "TH 0", 0x82fc},
+ {"Tunisia", "TN 0", 0x8314},
+ {"Turkey", "TR 0", 0x8318},
+ {"Ukraine", "UA 0", 0x8324},
+ {"UK", "GB 0", 0x833A},
+ {"UK &IRE", "GB 0", 0x833A},
+ {"United Kingdom", "GB 0", 0x833A},
+ {"Uzbekistan", "UZ 0", 0x835c},
+ {"Vietnam", "VN 0", 0x82c0}
+};
+
+static unsigned short ath6kl_get_reg_dmn_code(u8 *ccode)
+{
+ int i = 0;
+
+ for (i = 0; i < COUNTRY_MAX; i++) {
+ if (strncmp(ccode, pArray[i].ccode, 2) == 0) {
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "%s: %s %s 0x%x",
+ __func__, pArray[i].country, pArray[i].ccode,
+ pArray[i].reg_dmn_code);
+ return pArray[i].reg_dmn_code;
+ }
+ }
+
+ ath6kl_err("%s() Failed to find reg_domain code for %s\n",
+ __func__, ccode);
+
+ return 0xffff;
+}
+
+static void ath6kl_update_ccodeinfo(struct ath6kl *ar)
+{
+ char ccode_filename[32];
+
+ do {
+ int ret = 0;
+ size_t length;
+ u8 *pdata = NULL;
+
+ snprintf(ccode_filename, sizeof(ccode_filename),
+ "/data/.ccode.info");
+
+ ret = android_readwrite_file(ccode_filename, NULL, NULL, 0);
+
+ if (ret < 0)
+ break;
+ else
+ length = ret;
+
+ pdata = vmalloc(length + 1);
+
+ if (!pdata) {
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "%s: Cannot allocate buffer for ccode_info (%d)\n",
+ __func__, length);
+ break;
+ }
+
+ if (android_readwrite_file(ccode_filename,
+ (char *)pdata, NULL, length) != length) {
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "%s: file read error, length %d\n",
+ __func__, length);
+ vfree(pdata);
+ break;
+ }
+ pdata[length] = '\0';
+
+ if (reg_domain == 0xffff)
+ reg_domain = ath6kl_get_reg_dmn_code(pdata);
+
+
+ vfree(pdata);
+ } while (0);
+}
+#endif
static void ath6kl_update_psminfo(struct ath6kl *ar)
{
@@ -1859,6 +2016,9 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
}
ar->state = ATH6KL_STATE_ON;
+#ifdef CONFIG_MACH_PX
+ wake_up(&ar->event_wq);
+#endif
return 0;
@@ -1941,6 +2101,9 @@ int ath6kl_core_init(struct ath6kl *ar)
ath6kl_mangle_mac_address(ar);
ath6kl_update_psminfo(ar);
+#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
+ ath6kl_update_ccodeinfo(ar);
+#endif
/* FIXME: we should free all firmwares in the error cases below */
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 2b1a37b..9c674e6 100755
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -343,6 +343,7 @@ out:
#ifdef CONFIG_MACH_PX
void ath6kl_print_ar6k_registers(struct ath6kl *ar)
{
+#if 0
u32 reg_addr;
u32 epc_addr1, epc_addr2, epc_addr3, epc_addr4;
u32 epc1, epc2, epc3, epc4;
@@ -417,7 +418,7 @@ void ath6kl_print_ar6k_registers(struct ath6kl *ar)
else
ath6kl_dbg(ATH6KL_DBG_TRC,
"ath6kl:reg_dump system sleep: %x\n", ssleep);
-
+#endif
}
#endif
@@ -1267,20 +1268,26 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
goto out;
}
- memcpy(mc_filter->hw_addr, ha->addr,
- ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
- /* Set the multicast filter */
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "Adding %s to multicast filter list\n",
- sec_conv_mac(mc_filter->hw_addr));
- ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
- vif->fw_vif_idx, mc_filter->hw_addr,
- true);
- if (ret) {
- ath6kl_warn("Failed to add multicast filter :%s\n",
- sec_conv_mac(mc_filter->hw_addr));
+ if (memcmp(ha->addr, "\x33\x33\x00\x00\x00\x01", ETH_ALEN) == 0) {
+ ath6kl_warn("Skipped : %s\n", sec_conv_mac(ha->addr));
kfree(mc_filter);
- goto out;
+ continue;
+ } else {
+ memcpy(mc_filter->hw_addr, ha->addr,
+ ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
+ /* Set the multicast filter */
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "Adding %s to multicast filter list\n",
+ sec_conv_mac(mc_filter->hw_addr));
+ ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
+ vif->fw_vif_idx, mc_filter->hw_addr,
+ true);
+ if (ret) {
+ ath6kl_warn("Failed to add multicast filter :%s\n",
+ sec_conv_mac(mc_filter->hw_addr));
+ kfree(mc_filter);
+ goto out;
+ }
}
list_add_tail(&mc_filter->list, &mc_filter_new);
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 52f56ab..d4ea7ad 100755
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -926,7 +926,9 @@ cut_pwr:
static int ath6kl_sdio_resume(struct ath6kl *ar)
{
+#if !defined(CONFIG_MACH_P8LTE)
ath6kl_sdio_setup_irq_mode(ar);
+#endif
switch (ar->state) {
case ATH6KL_STATE_OFF:
@@ -1288,7 +1290,7 @@ static int ath6kl_sdio_pm_suspend(struct device *device)
struct sdio_func *func;
struct ath6kl_sdio *ar_sdio;
int ret;
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm resume\n");
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm suspend\n");
func = dev_to_sdio_func(device);
ar_sdio = sdio_get_drvdata(func);
@@ -1433,12 +1435,24 @@ err_hif:
static void ath6kl_sdio_remove(struct sdio_func *func)
{
struct ath6kl_sdio *ar_sdio;
+ struct ath6kl_vif *vif;
+ long timeleft;
ath6kl_dbg(ATH6KL_DBG_BOOT,
"sdio removed func %d vendor 0x%x device 0x%x\n",
func->num, func->vendor, func->device);
ar_sdio = sdio_get_drvdata(func);
+#ifdef CONFIG_MACH_PX
+ vif = ath6kl_vif_first(ar_sdio->ar);
+ /* Wait for Wmi event to be ready */
+ timeleft = wait_event_interruptible_timeout(ar_sdio->ar->event_wq,
+ ar_sdio->ar->state == ATH6KL_STATE_ON,
+ WMI_TIMEOUT);
+
+ ath6kl_hif_rx_control(ar_sdio->ar->htc_target->dev, false);
+ vif->sdio_remove = true;
+#endif
ath6kl_stop_txrx(ar_sdio->ar);
cancel_work_sync(&ar_sdio->wr_async_work);
diff --git a/drivers/net/wireless/ath/ath6kl/softmac.c b/drivers/net/wireless/ath/ath6kl/softmac.c
index d26e9e8..3725871 100644
--- a/drivers/net/wireless/ath/ath6kl/softmac.c
+++ b/drivers/net/wireless/ath/ath6kl/softmac.c
@@ -78,13 +78,15 @@ static int ath6kl_fetch_nvmac_info(struct ath6kl *ar)
char *softmac_old_filename = "/data/.mac.info";
do {
+ /*
isnvmac_imei = android_readwrite_file(nvfilepath_imei,
NULL, NULL, 0);
isnvmac_wifi = android_readwrite_file(nvfilepath_wifi,
- NULL, NULL, 0);
+ NULL, NULL, 0); */
ismac_file = android_readwrite_file(softmac_filename,
NULL, NULL, 0);
+ /*
if (isnvmac_imei >= 16 && isnvmac_wifi >= 16) {
strcpy(nvfilepath, nvfilepath_wifi);
isnvmac_file = isnvmac_wifi;
@@ -94,10 +96,11 @@ static int ath6kl_fetch_nvmac_info(struct ath6kl *ar)
} else if (isnvmac_imei >= 16) {
strcpy(nvfilepath, nvfilepath_imei);
isnvmac_file = isnvmac_imei;
- }
+ } */
/* copy .nvmac.info file to .mac.info
wifi driver will use .mac.info finally */
+ /*
if (isnvmac_file >= 16) {
ret = android_readwrite_file(nvfilepath,
(char *)softmac_temp, NULL, isnvmac_file);
@@ -111,9 +114,10 @@ static int ath6kl_fetch_nvmac_info(struct ath6kl *ar)
__func__, ret);
ret = android_readwrite_file(softmac_old_filename,
NULL, (char *)softmac_temp, ret);
- }
+ } */
- if (isnvmac_file < 16 && ismac_file < 16) {
+ //if (isnvmac_file < 16 && ismac_file < 16) {
+ if (ismac_file < 16) {
snprintf(softmac_temp, sizeof(softmac_temp),
"00:12:34:%02x:%02x:%02x",
random32() & 0xff,
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index ff32b70..b8924dd 100755..100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -286,6 +286,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
struct ath6kl *ar = devt;
int status = 0;
struct ath6kl_cookie *cookie = NULL;
+ struct ath6kl_vif *vif;
+ vif = ath6kl_vif_first(ar);
if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
goto fail_ctrl_tx;
@@ -308,7 +310,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
skb, skb->len);
#ifdef CONFIG_MACH_PX
- ath6kl_print_ar6k_registers(ar);
+ if (vif->nw_type == INFRA_NETWORK)
+ vif->force_reload = true;
#endif
} else
cookie = ath6kl_alloc_cookie(ar);
@@ -362,8 +365,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
u32 flags = 0;
ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
- "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
- skb, skb->data, skb->len);
+ "%s: skb=0x%p, data=0x%p, len=0x%x, actual_len=0x%x\n", __func__,
+ skb, skb->data, skb->len, skb->tail - skb->data);
/* If target is not associated */
if (!test_bit(CONNECTED, &vif->flags)) {
@@ -394,7 +397,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
csum_dest = skb->csum_offset + csum_start;
}
- if (skb_headroom(skb) < dev->needed_headroom) {
+ if (skb_headroom(skb) < dev->needed_headroom)
+ {
struct sk_buff *tmp_skb = skb;
skb = skb_realloc_headroom(skb, dev->needed_headroom);
@@ -476,13 +480,8 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
spin_unlock_bh(&ar->lock);
-#ifdef CONFIG_MACH_PX
- if (false && !IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
- skb_cloned(skb)) {
-#else
if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
skb_cloned(skb)) {
-#endif
/*
* We will touch (move the buffer data to align it. Since the
* skb buffer is cloned and not only the header is changed, we
@@ -506,7 +505,6 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ",
skb->data, skb->len);
-
/*
* HTC interface is asynchronous, if this fails, cleanup will
* happen in the ath6kl_tx_complete callback.
@@ -836,6 +834,10 @@ static void ath6kl_deliver_frames_to_nw_stack(struct net_device *dev,
skb->protocol = eth_type_trans(skb, skb->dev);
+#ifdef CONFIG_MACH_PX
+ skb->len = skb->tail - skb->data;
+#endif
+
netif_rx_ni(skb);
}
@@ -1344,8 +1346,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
spin_unlock_bh(&vif->if_lock);
- ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
- skb->data, skb->len);
+ //ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
+ // skb->data, skb->len);
skb->dev = vif->ndev;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 6fbf4a9..f7afb1d 100755
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -291,6 +291,13 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
layer2_priority);
} else
usr_pri = layer2_priority & 0x7;
+
+ /*
+ * Queue the EAPOL frames in the same WMM_AC_VO queue
+ * as that of management frames.
+ */
+ if (skb->protocol == cpu_to_be16(ETH_P_PAE))
+ usr_pri = WMI_VOICE_USER_PRIORITY;
}
/*
@@ -526,6 +533,8 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
id = le32_to_cpu(ev->id);
ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
id, ev->ack_status);
+
+ mutex_lock(&wmi->lock_mgmt);
if (wmi->last_mgmt_tx_frame) {
cfg80211_mgmt_tx_status(vif->ndev, id,
wmi->last_mgmt_tx_frame,
@@ -535,6 +544,7 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
wmi->last_mgmt_tx_frame = NULL;
wmi->last_mgmt_tx_frame_len = 0;
}
+ mutex_unlock(&wmi->lock_mgmt);
return 0;
}
@@ -712,13 +722,57 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
cmd = (struct roam_ctrl_cmd *) skb->data;
+#ifdef CONFIG_MACH_PX
+ if (wmi->parent_dev->psminfo == 0)
+ cmd->info.params.lrssi_scan_period = 0xFFFF;
+ else
+ cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
+#else
cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
+#endif
+
cmd->info.params.lrssi_scan_threshold = a_cpu_to_sle16(lrssi +
DEF_SCAN_FOR_ROAM_INTVL);
cmd->info.params.lrssi_roam_threshold = a_cpu_to_sle16(lrssi);
cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
+ "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
+ cmd->info.params.lrssi_scan_period, cmd->info.params.lrssi_scan_threshold,
+ cmd->info.params.lrssi_roam_threshold, cmd->info.params.roam_rssi_floor);
+
+ ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return 0;
+}
+
+int ath6kl_wmi_set_roam_lrssi_config_cmd(struct wmi *wmi,
+ struct low_rssi_scan_params *params)
+{
+ struct sk_buff *skb;
+ struct roam_ctrl_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct roam_ctrl_cmd *) skb->data;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
+ "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
+ params->lrssi_scan_period, params->lrssi_scan_threshold,
+ params->lrssi_roam_threshold, params->roam_rssi_floor);
+
+ if (params->lrssi_scan_period == 0)
+ cmd->info.params.lrssi_scan_period = 0xFFFF;
+ else
+ cmd->info.params.lrssi_scan_period = params->lrssi_scan_period;
+ cmd->info.params.lrssi_scan_threshold = params->lrssi_scan_threshold;
+ cmd->info.params.lrssi_roam_threshold = params->lrssi_roam_threshold;
+ cmd->info.params.roam_rssi_floor = params->roam_rssi_floor;
+ cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
+
ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
NO_SYNC_WMIFLAG);
@@ -1823,7 +1877,11 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
{
struct sk_buff *skb;
struct wmi_begin_scan_cmd *sc;
+#ifdef CONFIG_MACH_PX
+ unsigned int size;
+#else
s8 size;
+#endif
int i, band, ret;
struct ath6kl *ar = wmi->parent_dev;
int num_rates;
@@ -1989,7 +2047,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
struct wmi_probed_ssid_cmd *cmd;
int ret;
- if (index > MAX_PROBED_SSID_INDEX)
+ if (index > MAX_PROBED_SSIDS)
return -EINVAL;
if (ssid_len > sizeof(cmd->ssid))
@@ -2047,7 +2105,7 @@ int ath6kl_wmi_mcastrate_cmd(struct wmi *wmi, u8 if_idx,
struct wmi_set_mcastrate_cmd *cmd;
int ret;
- printk(KERN_ERR "\tmcastrate = %d\n", bitrate);
+ printk(KERN_INFO "\tmcastrate = %d\n", bitrate);
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
if (!skb)
@@ -2988,6 +3046,61 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
return ret;
}
+int ath6kl_wmi_set_ht_cap_cmd(struct wmi *wmi, u8 if_idx,
+ struct wmi_set_ht_cap_cmd *params)
+{
+ struct sk_buff *skb;
+ struct wmi_set_ht_cap_cmd *cmd;
+ struct ath6kl *ar = wmi->parent_dev;
+ struct ieee80211_supported_band *sband;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_ht_cap_cmd *) skb->data;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "bands %d, ht_supported = %d, "
+ "chan_width_40m_supported %d, short_gi_20mhz = %d, "
+ "short_gi_40mhz = %d, intolerance_40mhz = %d\n",
+ params->band, params->enable,
+ params->chan_width_40m_supported, params->short_gi_20mhz,
+ params->short_gi_40mhz, params->intolerance_40mhz);
+ memcpy(cmd, params, sizeof(*cmd));
+
+ sband = ar->wiphy->bands[params->band];
+ sband->ht_cap.ht_supported = params->enable;
+ if (params->chan_width_40m_supported)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if (params->short_gi_20mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
+
+ if (params->short_gi_40mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
+
+ if (params->intolerance_40mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+
+ if (params->max_ampdu_len_exp)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HT_CAP_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+
s32 ath6kl_wmi_get_rate(s8 rate_index)
{
u32 sgi;
@@ -3311,6 +3424,7 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
struct sk_buff *skb;
struct wmi_send_action_cmd *p;
u8 *buf;
+ int ret;
if (wait)
return -EINVAL; /* Offload for wait not supported */
@@ -3325,7 +3439,10 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
return -ENOMEM;
}
- kfree(wmi->last_mgmt_tx_frame);
+ mutex_lock(&wmi->lock_mgmt);
+ if (wmi->last_mgmt_tx_frame)
+ kfree(wmi->last_mgmt_tx_frame);
+
memcpy(buf, data, data_len);
wmi->last_mgmt_tx_frame = buf;
wmi->last_mgmt_tx_frame_len = data_len;
@@ -3338,8 +3455,10 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
p->wait = cpu_to_le32(wait);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
NO_SYNC_WMIFLAG);
+ mutex_unlock(&wmi->lock_mgmt);
+ return ret;
}
static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
@@ -3349,6 +3468,7 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
struct sk_buff *skb;
struct wmi_send_mgmt_cmd *p;
u8 *buf;
+ int ret;
if (wait)
return -EINVAL; /* Offload for wait not supported */
@@ -3363,7 +3483,10 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
return -ENOMEM;
}
- kfree(wmi->last_mgmt_tx_frame);
+ mutex_lock(&wmi->lock_mgmt);
+ if (wmi->last_mgmt_tx_frame)
+ kfree(wmi->last_mgmt_tx_frame);
+
memcpy(buf, data, data_len);
wmi->last_mgmt_tx_frame = buf;
wmi->last_mgmt_tx_frame_len = data_len;
@@ -3377,8 +3500,11 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
p->no_cck = cpu_to_le32(no_cck);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID,
NO_SYNC_WMIFLAG);
+ mutex_unlock(&wmi->lock_mgmt);
+
+ return ret;
}
int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
@@ -3800,6 +3926,7 @@ void *ath6kl_wmi_init(struct ath6kl *dev)
return NULL;
spin_lock_init(&wmi->lock);
+ mutex_init(&wmi->lock_mgmt);
wmi->parent_dev = dev;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index a9458e2..1e6c48d 100755
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -106,12 +106,15 @@ struct wmi_data_sync_bufs {
#define WMM_AC_VI 2 /* video */
#define WMM_AC_VO 3 /* voice */
+#define WMI_VOICE_USER_PRIORITY 0x7
+
struct wmi {
u16 stream_exist_for_ac[WMM_NUM_AC];
u8 fat_pipe_exist;
struct ath6kl *parent_dev;
u8 pwr_mode;
spinlock_t lock;
+ struct mutex lock_mgmt;
enum htc_endpoint_id ep_id;
struct sq_threshold_params
sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX];
@@ -972,7 +975,7 @@ struct wmi_bss_filter_cmd {
} __packed;
/* WMI_SET_PROBED_SSID_CMDID */
-#define MAX_PROBED_SSID_INDEX 9
+#define MAX_PROBED_SSIDS 16
enum wmi_ssid_flag {
/* disables entry */
@@ -986,7 +989,7 @@ enum wmi_ssid_flag {
};
struct wmi_probed_ssid_cmd {
- /* 0 to MAX_PROBED_SSID_INDEX */
+ /* 0 to MAX_PROBED_SSIDS - 1 */
u8 entry_index;
/* see, enum wmi_ssid_flg */
@@ -1487,7 +1490,11 @@ enum wmi_bi_ftype {
PROBEREQ_FTYPE,
};
+#ifdef CONFIG_MACH_PX
+#define DEF_LRSSI_SCAN_PERIOD ( 5 * 1000 )
+#else
#define DEF_LRSSI_SCAN_PERIOD 5
+#endif
#define DEF_LRSSI_ROAM_THRESHOLD 20
#define DEF_LRSSI_ROAM_FLOOR 60
#ifdef CONFIG_MACH_PX
@@ -2308,6 +2315,17 @@ struct wmi_p2p_probe_response_cmd {
u8 data[0];
} __packed;
+struct wmi_set_ht_cap_cmd {
+ u8 band;
+ u8 enable;
+ u8 chan_width_40m_supported;
+ u8 short_gi_20mhz;
+ u8 short_gi_40mhz;
+ u8 intolerance_40mhz;
+ u8 max_ampdu_len_exp;
+} __packed;
+
+
/* Extended WMI (WMIX)
*
* Extended WMIX commands are encapsulated in a WMI message with
@@ -2507,11 +2525,16 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
u16 list_id, u16 filter_id);
int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
+int ath6kl_wmi_set_roam_lrssi_config_cmd(struct wmi *wmi,
+ struct low_rssi_scan_params *params);
int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
u8 *filter, bool add_filter);
+int ath6kl_wmi_set_ht_cap_cmd(struct wmi *wmi, u8 if_idx,
+ struct wmi_set_ht_cap_cmd *params);
+
/* AP mode uAPSD */
int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index 508eccf..508eccf 100644..100755
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index 19befb3..19befb3 100644..100755
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 4cf7c5e..4cf7c5e 100644..100755
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 947ef45..947ef45 100644..100755
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 65ecb5b..65ecb5b 100644..100755
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 03a8268..03a8268 100644..100755
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index bdd2b4d..bdd2b4d 100644..100755
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h