Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 224558
b: refs/heads/master
c: 5cb56af
h: refs/heads/master
v: v3
  • Loading branch information
Jussi Kivilinna authored and John W. Linville committed Nov 16, 2010
1 parent 23ad392 commit c13c2d0
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b5257c952dda24df7078c74b7b811b44c6e49206
refs/heads/master: 5cb56af29be8d12f74afcb2c1de91e51a577bd52
67 changes: 56 additions & 11 deletions trunk/drivers/net/wireless/rndis_wlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ MODULE_PARM_DESC(workaround_interval,
#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)


/* Known device types */
#define RNDIS_UNKNOWN 0
#define RNDIS_BCM4320A 1
#define RNDIS_BCM4320B 2


/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
* slightly modified for datatype endianess, etc
*/
Expand Down Expand Up @@ -478,6 +484,7 @@ struct rndis_wlan_private {
struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
u32 cipher_suites[ARRAY_SIZE(rndis_cipher_suites)];

int device_type;
int caps;
int multicast_size;

Expand Down Expand Up @@ -997,6 +1004,16 @@ static void restore_keys(struct usbnet *usbdev);
static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid,
bool *matched);

static int rndis_start_bssid_list_scan(struct usbnet *usbdev)
{
__le32 tmp;

/* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */
tmp = cpu_to_le32(1);
return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
}

static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
Expand Down Expand Up @@ -1905,7 +1922,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
struct usbnet *usbdev = netdev_priv(dev);
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret;
__le32 tmp;
int delay = SCAN_DELAY_JIFFIES;

netdev_dbg(usbdev->net, "cfg80211.scan\n");

Expand All @@ -1922,13 +1939,13 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,

priv->scan_request = request;

tmp = cpu_to_le32(1);
ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
ret = rndis_start_bssid_list_scan(usbdev);
if (ret == 0) {
if (priv->device_type == RNDIS_BCM4320A)
delay = HZ;

/* Wait before retrieving scan results from device */
queue_delayed_work(priv->workqueue, &priv->scan_work,
SCAN_DELAY_JIFFIES);
queue_delayed_work(priv->workqueue, &priv->scan_work, delay);
}

return ret;
Expand Down Expand Up @@ -3046,8 +3063,21 @@ static void rndis_device_poller(struct work_struct *work)
* also polls device with rndis_command() and catches for media link
* indications.
*/
if (!is_associated(usbdev))
if (!is_associated(usbdev)) {
/* Workaround bad scanning in BCM4320a devices with active
* background scanning when not associated.
*/
if (priv->device_type == RNDIS_BCM4320A && priv->radio_on &&
!priv->scan_request) {
/* Get previous scan results */
rndis_check_bssid_list(usbdev, NULL, NULL);

/* Initiate new scan */
rndis_start_bssid_list_scan(usbdev);
}

goto end;
}

len = sizeof(rssi);
ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
Expand Down Expand Up @@ -3104,10 +3134,12 @@ static void rndis_device_poller(struct work_struct *work)
/*
* driver/device initialization
*/
static void rndis_copy_module_params(struct usbnet *usbdev)
static void rndis_copy_module_params(struct usbnet *usbdev, int device_type)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);

priv->device_type = device_type;

priv->param_country[0] = modparam_country[0];
priv->param_country[1] = modparam_country[1];
priv->param_country[2] = 0;
Expand Down Expand Up @@ -3150,12 +3182,25 @@ static void rndis_copy_module_params(struct usbnet *usbdev)
priv->param_workaround_interval = modparam_workaround_interval;
}

static int unknown_early_init(struct usbnet *usbdev)
{
/* copy module parameters for unknown so that iwconfig reports txpower
* and workaround parameter is copied to private structure correctly.
*/
rndis_copy_module_params(usbdev, RNDIS_UNKNOWN);

/* This is unknown device, so do not try set configuration parameters.
*/

return 0;
}

static int bcm4320a_early_init(struct usbnet *usbdev)
{
/* copy module parameters for bcm4320a so that iwconfig reports txpower
* and workaround parameter is copied to private structure correctly.
*/
rndis_copy_module_params(usbdev);
rndis_copy_module_params(usbdev, RNDIS_BCM4320A);

/* bcm4320a doesn't handle configuration parameters well. Try
* set any and you get partially zeroed mac and broken device.
Expand All @@ -3169,7 +3214,7 @@ static int bcm4320b_early_init(struct usbnet *usbdev)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
char buf[8];

rndis_copy_module_params(usbdev);
rndis_copy_module_params(usbdev, RNDIS_BCM4320B);

/* Early initialization settings, setting these won't have effect
* if called after generic_rndis_bind().
Expand Down Expand Up @@ -3432,7 +3477,7 @@ static const struct driver_info rndis_wlan_info = {
.tx_fixup = rndis_tx_fixup,
.reset = rndis_wlan_reset,
.stop = rndis_wlan_stop,
.early_init = bcm4320a_early_init,
.early_init = unknown_early_init,
.indication = rndis_wlan_indication,
};

Expand Down

0 comments on commit c13c2d0

Please sign in to comment.