* [PATCH 2/7] rndis_wlan: do not set default_key if not WEP key
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 3/7] rndis_wlan: turn radio off before interface is bring up Jussi Kivilinna
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
rndis_set_default_key did call add_wep_key to set default key on device, even
if key is WPA. This caused rndis_wlan not work with wpa_supplicant in nl80211
mode (causing disconnect from AP).
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index de4c050..9e6105c 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2435,6 +2435,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
priv->encr_tx_key_index = key_index;
+ if (is_wpa_key(priv, key_index))
+ return 0;
+
key = priv->encr_keys[key_index];
return add_wep_key(usbdev, key.material, key.len, key_index);
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/7] rndis_wlan: turn radio off before interface is bring up
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 2/7] rndis_wlan: do not set default_key if not WEP key Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 4/7] rndis_wlan: constify rndis_config_ops Jussi Kivilinna
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Radio should be off when interface is down.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 9e6105c..42e19e8 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -3398,9 +3398,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
rndis_set_wiphy_params(wiphy,
WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
- /* turn radio on */
- priv->radio_on = true;
- disassociate(usbdev, true);
+ /* turn radio off on init */
+ priv->radio_on = false;
+ disassociate(usbdev, false);
netif_carrier_off(usbdev->net);
return 0;
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/7] rndis_wlan: constify rndis_config_ops
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 2/7] rndis_wlan: do not set default_key if not WEP key Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 3/7] rndis_wlan: turn radio off before interface is bring up Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 5/7] rndis_wlan: remove unused variable from priv structure Jussi Kivilinna
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 42e19e8..d0992fc 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -570,7 +570,7 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
-static struct cfg80211_ops rndis_config_ops = {
+static const struct cfg80211_ops rndis_config_ops = {
.change_virtual_intf = rndis_change_virtual_intf,
.scan = rndis_scan,
.set_wiphy_params = rndis_set_wiphy_params,
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/7] rndis_wlan: remove unused variable from priv structure
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
` (2 preceding siblings ...)
2010-12-21 20:44 ` [PATCH 4/7] rndis_wlan: constify rndis_config_ops Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 6/7] rndis_wlan: add support for set_cqm_rssi_config Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 7/7] rndis_wlan: add support for set_power_mgmt Jussi Kivilinna
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index d0992fc..aa21d86 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -503,7 +503,6 @@ struct rndis_wlan_private {
int infra_mode;
bool connected;
u8 bssid[ETH_ALEN];
- struct ndis_80211_ssid essid;
__le32 current_command_oid;
/* encryption stuff */
@@ -1026,7 +1025,6 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
return ret;
}
if (ret == 0) {
- memcpy(&priv->essid, ssid, sizeof(priv->essid));
priv->radio_on = true;
netdev_dbg(usbdev->net, "%s(): radio_on = true\n", __func__);
}
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 6/7] rndis_wlan: add support for set_cqm_rssi_config
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
` (3 preceding siblings ...)
2010-12-21 20:44 ` [PATCH 5/7] rndis_wlan: remove unused variable from priv structure Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
2010-12-21 20:44 ` [PATCH 7/7] rndis_wlan: add support for set_power_mgmt Jussi Kivilinna
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Device poller already reads current RSSI, so add support for
set_cqm_rssi_config there.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 51 ++++++++++++++++++++++++++++++++++++-
1 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index aa21d86..0cd971a 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -478,6 +478,9 @@ struct rndis_wlan_private {
struct mutex command_lock;
unsigned long work_pending;
int last_qual;
+ s32 cqm_rssi_thold;
+ u32 cqm_rssi_hyst;
+ int last_cqm_event_rssi;
struct ieee80211_supported_band band;
struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
@@ -569,6 +572,10 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
+static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev,
+ s32 rssi_thold, u32 rssi_hyst);
+
static const struct cfg80211_ops rndis_config_ops = {
.change_virtual_intf = rndis_change_virtual_intf,
.scan = rndis_scan,
@@ -588,6 +595,7 @@ static const struct cfg80211_ops rndis_config_ops = {
.set_pmksa = rndis_set_pmksa,
.del_pmksa = rndis_del_pmksa,
.flush_pmksa = rndis_flush_pmksa,
+ .set_cqm_rssi_config = rndis_set_cqm_rssi_config,
};
static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -2566,6 +2574,19 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
}
+static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev,
+ s32 rssi_thold, u32 rssi_hyst)
+{
+ struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+
+ priv->cqm_rssi_thold = rssi_thold;
+ priv->cqm_rssi_hyst = rssi_hyst;
+ priv->last_cqm_event_rssi = 0;
+
+ return 0;
+}
+
static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
struct ndis_80211_assoc_info *info)
{
@@ -3095,6 +3116,32 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
return retval;
}
+static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ enum nl80211_cqm_rssi_threshold_event event;
+ int thold, hyst, last_event;
+
+ if (priv->cqm_rssi_thold >= 0 || rssi >= 0)
+ return;
+ if (priv->infra_mode != NDIS_80211_INFRA_INFRA)
+ return;
+
+ last_event = priv->last_cqm_event_rssi;
+ thold = priv->cqm_rssi_thold;
+ hyst = priv->cqm_rssi_hyst;
+
+ if (rssi < thold && (last_event == 0 || rssi < last_event - hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
+ else if (rssi > thold && (last_event == 0 || rssi > last_event + hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+ else
+ return;
+
+ priv->last_cqm_event_rssi = rssi;
+ cfg80211_cqm_rssi_notify(usbdev->net, event, GFP_KERNEL);
+}
+
#define DEVICE_POLLER_JIFFIES (HZ)
static void rndis_device_poller(struct work_struct *work)
{
@@ -3129,8 +3176,10 @@ static void rndis_device_poller(struct work_struct *work)
len = sizeof(rssi);
ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
- if (ret == 0)
+ if (ret == 0) {
priv->last_qual = level_to_qual(le32_to_cpu(rssi));
+ rndis_do_cqm(usbdev, le32_to_cpu(rssi));
+ }
netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n",
ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 7/7] rndis_wlan: add support for set_power_mgmt
2010-12-21 20:44 [PATCH 1/7] [v2] rndis_wlan: scanning, workaround device returning incorrect bssid-list item count Jussi Kivilinna
` (4 preceding siblings ...)
2010-12-21 20:44 ` [PATCH 6/7] rndis_wlan: add support for set_cqm_rssi_config Jussi Kivilinna
@ 2010-12-21 20:44 ` Jussi Kivilinna
5 siblings, 0 replies; 7+ messages in thread
From: Jussi Kivilinna @ 2010-12-21 20:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 48 +++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 0cd971a..848cc2c 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -129,6 +129,7 @@ MODULE_PARM_DESC(workaround_interval,
#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
+#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216)
#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
@@ -239,6 +240,12 @@ enum ndis_80211_addwep_bits {
NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
};
+enum ndis_80211_power_mode {
+ NDIS_80211_POWER_MODE_CAM,
+ NDIS_80211_POWER_MODE_MAX_PSP,
+ NDIS_80211_POWER_MODE_FAST_PSP,
+};
+
struct ndis_80211_auth_request {
__le32 length;
u8 bssid[6];
@@ -503,6 +510,7 @@ struct rndis_wlan_private {
/* hardware state */
bool radio_on;
+ int power_mode;
int infra_mode;
bool connected;
u8 bssid[ETH_ALEN];
@@ -572,6 +580,9 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
+static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, int timeout);
+
static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
struct net_device *dev,
s32 rssi_thold, u32 rssi_hyst);
@@ -595,6 +606,7 @@ static const struct cfg80211_ops rndis_config_ops = {
.set_pmksa = rndis_set_pmksa,
.del_pmksa = rndis_del_pmksa,
.flush_pmksa = rndis_flush_pmksa,
+ .set_power_mgmt = rndis_set_power_mgmt,
.set_cqm_rssi_config = rndis_set_cqm_rssi_config,
};
@@ -694,6 +706,7 @@ static const char *oid_to_string(__le32 oid)
OID_STR(OID_802_11_ADD_KEY);
OID_STR(OID_802_11_REMOVE_KEY);
OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
+ OID_STR(OID_802_11_CAPABILITY);
OID_STR(OID_802_11_PMKID);
OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
@@ -704,6 +717,7 @@ static const char *oid_to_string(__le32 oid)
OID_STR(OID_802_11_RTS_THRESHOLD);
OID_STR(OID_802_11_SUPPORTED_RATES);
OID_STR(OID_802_11_CONFIGURATION);
+ OID_STR(OID_802_11_POWER_MODE);
OID_STR(OID_802_11_BSSID_LIST);
#undef OID_STR
}
@@ -2574,6 +2588,38 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
}
+static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, int timeout)
+{
+ struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+ struct usbnet *usbdev = priv->usbdev;
+ int power_mode;
+ __le32 mode;
+ int ret;
+
+ netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__,
+ enabled ? "enabled" : "disabled",
+ timeout);
+
+ if (enabled)
+ power_mode = NDIS_80211_POWER_MODE_FAST_PSP;
+ else
+ power_mode = NDIS_80211_POWER_MODE_CAM;
+
+ if (power_mode == priv->power_mode)
+ return 0;
+
+ priv->power_mode = power_mode;
+
+ mode = cpu_to_le32(power_mode);
+ ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode));
+
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
static int rndis_set_cqm_rssi_config(struct wiphy *wiphy,
struct net_device *dev,
s32 rssi_thold, u32 rssi_hyst)
@@ -3441,6 +3487,8 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
set_default_iw_params(usbdev);
+ priv->power_mode = -1;
+
/* set default rts/frag */
rndis_set_wiphy_params(wiphy,
WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
^ permalink raw reply related [flat|nested] 7+ messages in thread