Skip to content

Commit

Permalink
orinoco: convert scanning to cfg80211
Browse files Browse the repository at this point in the history
This removes the custom scan cache used by orinoco.

We also have to avoid calling cfg80211_scan_done from the hard
interrupt, so we offload the entirety of scan processing to a workqueue.

This may behave strangely if you start scanning just prior to
suspending...

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
David Kilroy authored and John W. Linville committed Jul 10, 2009
1 parent 5217c57 commit c63cdbe
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 744 deletions.
20 changes: 20 additions & 0 deletions drivers/net/wireless/orinoco/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
return err;
}

static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request)
{
struct orinoco_private *priv = wiphy_priv(wiphy);
int err;

if (!request)
return -EINVAL;

if (priv->scan_request && priv->scan_request != request)
return -EBUSY;

priv->scan_request = request;

err = orinoco_hw_trigger_scan(priv, request->ssids);

return err;
}

const struct cfg80211_ops orinoco_cfg_ops = {
.change_virtual_intf = orinoco_change_vif,
.scan = orinoco_scan,
};
2 changes: 1 addition & 1 deletion drivers/net/wireless/orinoco/hermes.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ struct agere_ext_scan_info {
__le64 timestamp;
__le16 beacon_interval;
__le16 capabilities;
u8 data[316];
u8 data[0];
} __attribute__ ((packed));

#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
Expand Down
85 changes: 85 additions & 0 deletions drivers/net/wireless/orinoco/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1157,3 +1157,88 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,

return 0;
}

int orinoco_hw_trigger_scan(struct orinoco_private *priv,
const struct cfg80211_ssid *ssid)
{
struct net_device *dev = priv->ndev;
hermes_t *hw = &priv->hw;
unsigned long flags;
int err = 0;

if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;

/* Scanning with port 0 disabled would fail */
if (!netif_running(dev)) {
err = -ENETDOWN;
goto out;
}

/* In monitor mode, the scan results are always empty.
* Probe responses are passed to the driver as received
* frames and could be processed in software. */
if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
err = -EOPNOTSUPP;
goto out;
}

if (priv->has_hostscan) {
switch (priv->firmware_type) {
case FIRMWARE_TYPE_SYMBOL:
err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFHOSTSCAN_SYMBOL,
HERMES_HOSTSCAN_SYMBOL_ONCE |
HERMES_HOSTSCAN_SYMBOL_BCAST);
break;
case FIRMWARE_TYPE_INTERSIL: {
__le16 req[3];

req[0] = cpu_to_le16(0x3fff); /* All channels */
req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
req[2] = 0; /* Any ESSID */
err = HERMES_WRITE_RECORD(hw, USER_BAP,
HERMES_RID_CNFHOSTSCAN, &req);
break;
}
case FIRMWARE_TYPE_AGERE:
if (ssid->ssid_len > 0) {
struct hermes_idstring idbuf;
size_t len = ssid->ssid_len;

idbuf.len = cpu_to_le16(len);
memcpy(idbuf.val, ssid->ssid, len);

err = hermes_write_ltv(hw, USER_BAP,
HERMES_RID_CNFSCANSSID_AGERE,
HERMES_BYTES_TO_RECLEN(len + 2),
&idbuf);
} else
err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFSCANSSID_AGERE,
0); /* Any ESSID */
if (err)
break;

if (priv->has_ext_scan) {
err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFSCANCHANNELS2GHZ,
0x7FFF);
if (err)
goto out;

err = hermes_inquire(hw,
HERMES_INQ_CHANNELINFO);
} else
err = hermes_inquire(hw, HERMES_INQ_SCAN);

break;
}
} else
err = hermes_inquire(hw, HERMES_INQ_SCAN);

out:
orinoco_unlock(priv, &flags);

return err;
}
3 changes: 3 additions & 0 deletions drivers/net/wireless/orinoco/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <linux/types.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>

/* Hardware BAPs */
#define USER_BAP 0
Expand Down Expand Up @@ -47,5 +48,7 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
int orinoco_hw_get_freq(struct orinoco_private *priv);
int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
int *numrates, s32 *rates, int max);
int orinoco_hw_trigger_scan(struct orinoco_private *priv,
const struct cfg80211_ssid *ssid);

#endif /* _ORINOCO_HW_H_ */
Loading

0 comments on commit c63cdbe

Please sign in to comment.