aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco/hw.c
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2009-06-18 18:21:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:46 -0400
commitc63cdbe8f80487c372fe0dfe460ed30467029f01 (patch)
treea981d5b052fc74b5f894775353a3e6e96591a1c7 /drivers/net/wireless/orinoco/hw.c
parent5217c571c898371c540e49671600d54346b2e123 (diff)
orinoco: convert scanning to cfg80211
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>
Diffstat (limited to 'drivers/net/wireless/orinoco/hw.c')
-rw-r--r--drivers/net/wireless/orinoco/hw.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 4600fe4a7e1..fa508af1a35 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -1157,3 +1157,88 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
1157 1157
1158 return 0; 1158 return 0;
1159} 1159}
1160
1161int orinoco_hw_trigger_scan(struct orinoco_private *priv,
1162 const struct cfg80211_ssid *ssid)
1163{
1164 struct net_device *dev = priv->ndev;
1165 hermes_t *hw = &priv->hw;
1166 unsigned long flags;
1167 int err = 0;
1168
1169 if (orinoco_lock(priv, &flags) != 0)
1170 return -EBUSY;
1171
1172 /* Scanning with port 0 disabled would fail */
1173 if (!netif_running(dev)) {
1174 err = -ENETDOWN;
1175 goto out;
1176 }
1177
1178 /* In monitor mode, the scan results are always empty.
1179 * Probe responses are passed to the driver as received
1180 * frames and could be processed in software. */
1181 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
1182 err = -EOPNOTSUPP;
1183 goto out;
1184 }
1185
1186 if (priv->has_hostscan) {
1187 switch (priv->firmware_type) {
1188 case FIRMWARE_TYPE_SYMBOL:
1189 err = hermes_write_wordrec(hw, USER_BAP,
1190 HERMES_RID_CNFHOSTSCAN_SYMBOL,
1191 HERMES_HOSTSCAN_SYMBOL_ONCE |
1192 HERMES_HOSTSCAN_SYMBOL_BCAST);
1193 break;
1194 case FIRMWARE_TYPE_INTERSIL: {
1195 __le16 req[3];
1196
1197 req[0] = cpu_to_le16(0x3fff); /* All channels */
1198 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
1199 req[2] = 0; /* Any ESSID */
1200 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1201 HERMES_RID_CNFHOSTSCAN, &req);
1202 break;
1203 }
1204 case FIRMWARE_TYPE_AGERE:
1205 if (ssid->ssid_len > 0) {
1206 struct hermes_idstring idbuf;
1207 size_t len = ssid->ssid_len;
1208
1209 idbuf.len = cpu_to_le16(len);
1210 memcpy(idbuf.val, ssid->ssid, len);
1211
1212 err = hermes_write_ltv(hw, USER_BAP,
1213 HERMES_RID_CNFSCANSSID_AGERE,
1214 HERMES_BYTES_TO_RECLEN(len + 2),
1215 &idbuf);
1216 } else
1217 err = hermes_write_wordrec(hw, USER_BAP,
1218 HERMES_RID_CNFSCANSSID_AGERE,
1219 0); /* Any ESSID */
1220 if (err)
1221 break;
1222
1223 if (priv->has_ext_scan) {
1224 err = hermes_write_wordrec(hw, USER_BAP,
1225 HERMES_RID_CNFSCANCHANNELS2GHZ,
1226 0x7FFF);
1227 if (err)
1228 goto out;
1229
1230 err = hermes_inquire(hw,
1231 HERMES_INQ_CHANNELINFO);
1232 } else
1233 err = hermes_inquire(hw, HERMES_INQ_SCAN);
1234
1235 break;
1236 }
1237 } else
1238 err = hermes_inquire(hw, HERMES_INQ_SCAN);
1239
1240 out:
1241 orinoco_unlock(priv, &flags);
1242
1243 return err;
1244}