Staging: wlan-ng: Switch from wext to cfg80211
Switch driver over from wext to cfg80211 interface. Some Notes: - This patch moves the driver wholesale from wext to cfg80211. Wext support is still provided through the cfg80211 provided wext compatability layer. - Currently only infrastructure mode is implemented. Ad hoc mode is not yet implemented, but can be added. - It does not support connecting to a specified bssid, instead roaming is handled by the card itself. This matches the behaviour of the existing driver. - It has been tested using NetworkManager (via wpa_supplicant) configured to use the wext compatability layer, and then again with the native nl80211 layer. Signed-off-by: Karl Relton <karllinuxtest.relton@ntlworld.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
9c770f3b88
commit
cb3126e60f
|
@ -4,5 +4,4 @@ prism2_usb-objs := prism2usb.o \
|
||||||
p80211conv.o \
|
p80211conv.o \
|
||||||
p80211req.o \
|
p80211req.o \
|
||||||
p80211wep.o \
|
p80211wep.o \
|
||||||
p80211wext.o \
|
|
||||||
p80211netdev.o
|
p80211netdev.o
|
||||||
|
|
|
@ -0,0 +1,735 @@
|
||||||
|
/* cfg80211 Interface for prism2_usb module */
|
||||||
|
|
||||||
|
|
||||||
|
/* Prism2 channell/frequency/bitrate declarations */
|
||||||
|
static const struct ieee80211_channel prism2_channels[] = {
|
||||||
|
{ .center_freq = 2412 },
|
||||||
|
{ .center_freq = 2417 },
|
||||||
|
{ .center_freq = 2422 },
|
||||||
|
{ .center_freq = 2427 },
|
||||||
|
{ .center_freq = 2432 },
|
||||||
|
{ .center_freq = 2437 },
|
||||||
|
{ .center_freq = 2442 },
|
||||||
|
{ .center_freq = 2447 },
|
||||||
|
{ .center_freq = 2452 },
|
||||||
|
{ .center_freq = 2457 },
|
||||||
|
{ .center_freq = 2462 },
|
||||||
|
{ .center_freq = 2467 },
|
||||||
|
{ .center_freq = 2472 },
|
||||||
|
{ .center_freq = 2484 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ieee80211_rate prism2_rates[] = {
|
||||||
|
{ .bitrate = 10 },
|
||||||
|
{ .bitrate = 20 },
|
||||||
|
{ .bitrate = 55 },
|
||||||
|
{ .bitrate = 110 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PRISM2_NUM_CIPHER_SUITES 2
|
||||||
|
static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
|
||||||
|
WLAN_CIPHER_SUITE_WEP40,
|
||||||
|
WLAN_CIPHER_SUITE_WEP104
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* prism2 device private data */
|
||||||
|
struct prism2_wiphy_private {
|
||||||
|
wlandevice_t *wlandev;
|
||||||
|
|
||||||
|
struct ieee80211_supported_band band;
|
||||||
|
struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
|
||||||
|
struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)];
|
||||||
|
|
||||||
|
struct cfg80211_scan_request *scan_request;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const void * const prism2_wiphy_privid = &prism2_wiphy_privid;
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper Functions */
|
||||||
|
static int prism2_result2err(int prism2_result)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
switch (prism2_result) {
|
||||||
|
case P80211ENUM_resultcode_invalid_parameters:
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
case P80211ENUM_resultcode_implementation_failure:
|
||||||
|
err = -EIO;
|
||||||
|
break;
|
||||||
|
case P80211ENUM_resultcode_not_supported:
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data)
|
||||||
|
{
|
||||||
|
p80211msg_dot11req_mibset_t msg;
|
||||||
|
p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
|
||||||
|
|
||||||
|
msg.msgcode = DIDmsg_dot11req_mibset;
|
||||||
|
mibitem->did = did;
|
||||||
|
mibitem->data = data;
|
||||||
|
|
||||||
|
return p80211req_dorequest(wlandev, (u8 *) & msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prism2_domibset_pstr32(wlandevice_t *wlandev,
|
||||||
|
u32 did, u8 len, u8 *data)
|
||||||
|
{
|
||||||
|
p80211msg_dot11req_mibset_t msg;
|
||||||
|
p80211item_pstr32_t *mibitem = (p80211item_pstr32_t *) &msg.mibattribute.data;
|
||||||
|
|
||||||
|
msg.msgcode = DIDmsg_dot11req_mibset;
|
||||||
|
mibitem->did = did;
|
||||||
|
mibitem->data.len = len;
|
||||||
|
memcpy(mibitem->data.data, data, len);
|
||||||
|
|
||||||
|
return p80211req_dorequest(wlandev, (u8 *) & msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The interface functions, called by the cfg80211 layer */
|
||||||
|
int prism2_change_virtual_intf(struct wiphy *wiphy,
|
||||||
|
struct net_device *dev,
|
||||||
|
enum nl80211_iftype type, u32 *flags,
|
||||||
|
struct vif_params *params)
|
||||||
|
{
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
u32 data;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
if (wlandev->macmode == WLAN_MACMODE_IBSS_STA) goto exit;
|
||||||
|
wlandev->macmode = WLAN_MACMODE_IBSS_STA;
|
||||||
|
data = 0;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
if (wlandev->macmode == WLAN_MACMODE_ESS_STA) goto exit;
|
||||||
|
wlandev->macmode = WLAN_MACMODE_ESS_STA;
|
||||||
|
data = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_WARNING "Operation mode: %d not support\n", type);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Operation mode to the PORT TYPE RID */
|
||||||
|
result = prism2_domibset_uint32(wlandev, DIDmib_p2_p2Static_p2CnfPortType, data);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
err = -EFAULT;
|
||||||
|
|
||||||
|
dev->ieee80211_ptr->iftype = type;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 key_index, const u8 *mac_addr,
|
||||||
|
struct key_params *params) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
u32 did;
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
switch (params->cipher) {
|
||||||
|
case WLAN_CIPHER_SUITE_WEP40:
|
||||||
|
case WLAN_CIPHER_SUITE_WEP104:
|
||||||
|
result = prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
|
||||||
|
key_index);
|
||||||
|
if (result) goto exit;
|
||||||
|
|
||||||
|
/* send key to driver */
|
||||||
|
switch (key_index) {
|
||||||
|
case 0:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = prism2_domibset_pstr32(wlandev, did, params->key_len, params->key);
|
||||||
|
if (result) goto exit;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pr_debug("Unsupported cipher suite\n");
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (result) err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 key_index, const u8 *mac_addr, void *cookie,
|
||||||
|
void (*callback)(void *cookie, struct key_params*)) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
struct key_params params;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(key_index >= NUM_WEPKEYS) return -EINVAL;
|
||||||
|
|
||||||
|
len = wlandev->wep_keylens[key_index];
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
|
||||||
|
if (len == 13) {
|
||||||
|
params.cipher = WLAN_CIPHER_SUITE_WEP104;
|
||||||
|
} else if (len == 5) {
|
||||||
|
params.cipher = WLAN_CIPHER_SUITE_WEP104;
|
||||||
|
} else return -ENOENT;
|
||||||
|
params.key_len = len;
|
||||||
|
params.key = wlandev->wep_keys[key_index];
|
||||||
|
|
||||||
|
callback(cookie, ¶ms);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 key_index, const u8 *mac_addr) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
u32 did;
|
||||||
|
int err = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
/* There is no direct way in the hardware (AFAIK) of removing
|
||||||
|
a key, so we will cheat by setting the key to a bogus value */
|
||||||
|
/* send key to driver */
|
||||||
|
switch (key_index) {
|
||||||
|
case 0:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (result) err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 key_index) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
result = prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
|
||||||
|
key_index);
|
||||||
|
|
||||||
|
if (result) err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 *mac, struct station_info *sinfo) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
p80211msg_lnxreq_commsquality_t quality;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
memset(sinfo, 0, sizeof(*sinfo));
|
||||||
|
|
||||||
|
if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* build request message */
|
||||||
|
quality.msgcode = DIDmsg_lnxreq_commsquality;
|
||||||
|
quality.dbm.data = P80211ENUM_truth_true;
|
||||||
|
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
|
||||||
|
|
||||||
|
/* send message to nsd */
|
||||||
|
if (wlandev->mlmerequest == NULL)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
result = wlandev->mlmerequest(wlandev, (p80211msg_t *) & quality);
|
||||||
|
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
sinfo->txrate.legacy = quality.txrate.data;
|
||||||
|
sinfo->filled |= STATION_INFO_TX_BITRATE;
|
||||||
|
sinfo->signal = quality.level.data;
|
||||||
|
sinfo->filled |= STATION_INFO_SIGNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_scan(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
struct cfg80211_scan_request *request)
|
||||||
|
{
|
||||||
|
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
p80211msg_dot11req_scan_t msg1;
|
||||||
|
p80211msg_dot11req_scan_results_t msg2;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
int numbss = 0;
|
||||||
|
int i = 0;
|
||||||
|
u8 ie_buf[46];
|
||||||
|
int ie_len;
|
||||||
|
|
||||||
|
if (!request)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (priv->scan_request && priv->scan_request != request)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
|
||||||
|
printk(KERN_ERR "Can't scan in AP mode\n");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->scan_request = request;
|
||||||
|
|
||||||
|
memset(&msg1, 0x00, sizeof(p80211msg_dot11req_scan_t));
|
||||||
|
msg1.msgcode = DIDmsg_dot11req_scan;
|
||||||
|
msg1.bsstype.data = P80211ENUM_bsstype_any;
|
||||||
|
|
||||||
|
memset(&(msg1.bssid.data), 0xFF, sizeof(p80211item_pstr6_t));
|
||||||
|
msg1.bssid.data.len = 6;
|
||||||
|
|
||||||
|
if (request->n_ssids > 0) {
|
||||||
|
msg1.scantype.data = P80211ENUM_scantype_active;
|
||||||
|
msg1.ssid.data.len = request->ssids->ssid_len;
|
||||||
|
memcpy(msg1.ssid.data.data, request->ssids->ssid, request->ssids->ssid_len);
|
||||||
|
} else {
|
||||||
|
msg1.scantype.data = 0;
|
||||||
|
}
|
||||||
|
msg1.probedelay.data = 0;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
(i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
|
||||||
|
i++)
|
||||||
|
msg1.channellist.data.data[i] =
|
||||||
|
ieee80211_frequency_to_channel(request->channels[i]->center_freq);
|
||||||
|
msg1.channellist.data.len = request->n_channels;
|
||||||
|
|
||||||
|
msg1.maxchanneltime.data = 250;
|
||||||
|
msg1.minchanneltime.data = 200;
|
||||||
|
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) &msg1);
|
||||||
|
if (result) {
|
||||||
|
err = prism2_result2err(msg1.resultcode.data);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
/* Now retrieve scan results */
|
||||||
|
numbss = msg1.numbss.data;
|
||||||
|
|
||||||
|
for (i = 0; i < numbss; i++) {
|
||||||
|
memset(&msg2, 0, sizeof(msg2));
|
||||||
|
msg2.msgcode = DIDmsg_dot11req_scan_results;
|
||||||
|
msg2.bssindex.data = i;
|
||||||
|
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) &msg2);
|
||||||
|
if ((result != 0) ||
|
||||||
|
(msg2.resultcode.data != P80211ENUM_resultcode_success)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ie_buf[0] = WLAN_EID_SSID;
|
||||||
|
ie_buf[1] = msg2.ssid.data.len;
|
||||||
|
ie_len = ie_buf[1] + 2;
|
||||||
|
memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len);
|
||||||
|
cfg80211_inform_bss(wiphy,
|
||||||
|
ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)),
|
||||||
|
(const u8 *) &(msg2.bssid.data.data),
|
||||||
|
msg2.timestamp.data, msg2.capinfo.data,
|
||||||
|
msg2.beaconperiod.data,
|
||||||
|
ie_buf,
|
||||||
|
ie_len,
|
||||||
|
(msg2.signal.data - 65536) * 100, /* Conversion to signed type */
|
||||||
|
GFP_KERNEL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
err = prism2_result2err(msg2.resultcode.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
cfg80211_scan_done(request, err ? 1 : 0);
|
||||||
|
priv->scan_request = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed) {
|
||||||
|
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||||
|
wlandevice_t *wlandev = priv->wlandev;
|
||||||
|
u32 data;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
|
||||||
|
if (wiphy->rts_threshold == -1)
|
||||||
|
data = 2347;
|
||||||
|
else
|
||||||
|
data = wiphy->rts_threshold;
|
||||||
|
|
||||||
|
result =
|
||||||
|
prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
|
||||||
|
data);
|
||||||
|
if (result) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
|
||||||
|
|
||||||
|
if (wiphy->frag_threshold == -1)
|
||||||
|
data = 2346;
|
||||||
|
else
|
||||||
|
data = wiphy->frag_threshold;
|
||||||
|
|
||||||
|
result =
|
||||||
|
prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
|
||||||
|
data);
|
||||||
|
if (result) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
struct cfg80211_connect_params *sme) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
struct ieee80211_channel *channel = sme->channel;
|
||||||
|
p80211msg_lnxreq_autojoin_t msg_join;
|
||||||
|
u32 did;
|
||||||
|
int length = sme->ssid_len;
|
||||||
|
int chan = -1;
|
||||||
|
int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||
|
||||||
|
(sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
/* Set the channel */
|
||||||
|
if (channel) {
|
||||||
|
chan = ieee80211_frequency_to_channel(channel->center_freq);
|
||||||
|
|
||||||
|
result =
|
||||||
|
prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
|
||||||
|
chan);
|
||||||
|
|
||||||
|
if (result) goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the authorisation */
|
||||||
|
if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
|
||||||
|
((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
|
||||||
|
msg_join.authtype.data = P80211ENUM_authalg_opensystem;
|
||||||
|
else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
|
||||||
|
((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
|
||||||
|
msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
|
||||||
|
else printk(KERN_WARNING "Unhandled authorisation type for connect (%d)\n", sme->auth_type);
|
||||||
|
|
||||||
|
/* Set the encryption - we only support wep */
|
||||||
|
if (is_wep) {
|
||||||
|
|
||||||
|
if (sme->key) {
|
||||||
|
result = prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
|
||||||
|
sme->key_idx);
|
||||||
|
if (result) goto exit;
|
||||||
|
|
||||||
|
/* send key to driver */
|
||||||
|
switch (sme->key_idx) {
|
||||||
|
case 0:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
did =
|
||||||
|
DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *) sme->key);
|
||||||
|
if (result) goto exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume we should set privacy invoked and exclude unencrypted
|
||||||
|
We could possibly use sme->privacy here, but the assumption
|
||||||
|
seems reasonable anyway */
|
||||||
|
result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
|
||||||
|
P80211ENUM_truth_true);
|
||||||
|
if (result) goto exit;
|
||||||
|
result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
|
||||||
|
P80211ENUM_truth_true);
|
||||||
|
if (result) goto exit;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Assume we should unset privacy invoked and exclude unencrypted */
|
||||||
|
result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
|
||||||
|
P80211ENUM_truth_false);
|
||||||
|
if (result) goto exit;
|
||||||
|
result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
|
||||||
|
P80211ENUM_truth_false);
|
||||||
|
if (result) goto exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do the actual join. Note there is no way that I can
|
||||||
|
see to request a specific bssid */
|
||||||
|
msg_join.msgcode = DIDmsg_lnxreq_autojoin;
|
||||||
|
|
||||||
|
memcpy(msg_join.ssid.data.data, sme->ssid, length);
|
||||||
|
msg_join.ssid.data.len = length;
|
||||||
|
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) & msg_join);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (result) err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u16 reason_code) {
|
||||||
|
wlandevice_t *wlandev = dev->ml_priv;
|
||||||
|
p80211msg_lnxreq_autojoin_t msg_join;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Do a join, with a bogus ssid. Thats the only way I can think of */
|
||||||
|
msg_join.msgcode = DIDmsg_lnxreq_autojoin;
|
||||||
|
|
||||||
|
memcpy(msg_join.ssid.data.data, "---", 3);
|
||||||
|
msg_join.ssid.data.len = 3;
|
||||||
|
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) & msg_join);
|
||||||
|
|
||||||
|
if (result) err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
struct cfg80211_ibss_params *params) {
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev) {
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int prism2_set_tx_power(struct wiphy *wiphy,
|
||||||
|
enum tx_power_setting type, int dbm) {
|
||||||
|
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||||
|
wlandevice_t *wlandev = priv->wlandev;
|
||||||
|
u32 data;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (type == TX_POWER_AUTOMATIC)
|
||||||
|
data = 30;
|
||||||
|
else
|
||||||
|
data = dbm;
|
||||||
|
|
||||||
|
result = prism2_domibset_uint32(wlandev,
|
||||||
|
DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
|
||||||
|
data);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prism2_get_tx_power(struct wiphy *wiphy, int *dbm) {
|
||||||
|
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||||
|
wlandevice_t *wlandev = priv->wlandev;
|
||||||
|
p80211msg_dot11req_mibget_t msg;
|
||||||
|
p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
|
||||||
|
int result;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
msg.msgcode = DIDmsg_dot11req_mibget;
|
||||||
|
mibitem->did =
|
||||||
|
DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
|
||||||
|
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) & msg);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dbm = mibitem->data;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Interface callback functions, passing data back up to the cfg80211 layer */
|
||||||
|
void prism2_connect_result(wlandevice_t *wlandev, u8 failed) {
|
||||||
|
|
||||||
|
cfg80211_connect_result(wlandev->netdev, wlandev->bssid,
|
||||||
|
NULL, 0, NULL, 0,
|
||||||
|
failed ? WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prism2_disconnected(wlandevice_t *wlandev) {
|
||||||
|
|
||||||
|
cfg80211_disconnected(wlandev->netdev, 0, NULL,
|
||||||
|
0, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prism2_roamed(wlandevice_t *wlandev) {
|
||||||
|
|
||||||
|
cfg80211_roamed(wlandev->netdev, wlandev->bssid,
|
||||||
|
NULL, 0, NULL, 0, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Structures for declaring wiphy interface */
|
||||||
|
static const struct cfg80211_ops prism2_usb_cfg_ops = {
|
||||||
|
.change_virtual_intf = prism2_change_virtual_intf,
|
||||||
|
.add_key = prism2_add_key,
|
||||||
|
.get_key = prism2_get_key,
|
||||||
|
.del_key = prism2_del_key,
|
||||||
|
.set_default_key = prism2_set_default_key,
|
||||||
|
.get_station = prism2_get_station,
|
||||||
|
.scan = prism2_scan,
|
||||||
|
.set_wiphy_params = prism2_set_wiphy_params,
|
||||||
|
.connect = prism2_connect,
|
||||||
|
.disconnect = prism2_disconnect,
|
||||||
|
.join_ibss = prism2_join_ibss,
|
||||||
|
.leave_ibss = prism2_leave_ibss,
|
||||||
|
.set_tx_power = prism2_set_tx_power,
|
||||||
|
.get_tx_power = prism2_get_tx_power,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions to create/free wiphy interface */
|
||||||
|
struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev)
|
||||||
|
{
|
||||||
|
struct wiphy *wiphy;
|
||||||
|
struct prism2_wiphy_private *priv;
|
||||||
|
wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(struct prism2_wiphy_private));
|
||||||
|
if (!wiphy)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
priv = wiphy_priv(wiphy);
|
||||||
|
priv->wlandev = wlandev;
|
||||||
|
memcpy(priv->channels, prism2_channels, sizeof(prism2_channels));
|
||||||
|
memcpy(priv->rates, prism2_rates, sizeof(prism2_rates));
|
||||||
|
priv->band.channels = priv->channels;
|
||||||
|
priv->band.n_channels = ARRAY_SIZE(prism2_channels);
|
||||||
|
priv->band.bitrates = priv->rates;
|
||||||
|
priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
|
||||||
|
wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
|
||||||
|
|
||||||
|
set_wiphy_dev(wiphy, dev);
|
||||||
|
wiphy->privid = prism2_wiphy_privid;
|
||||||
|
wiphy->max_scan_ssids = 1;
|
||||||
|
wiphy->interface_modes =
|
||||||
|
BIT(NL80211_IFTYPE_STATION) |
|
||||||
|
BIT(NL80211_IFTYPE_ADHOC);
|
||||||
|
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||||
|
wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES;
|
||||||
|
wiphy->cipher_suites = prism2_cipher_suites;
|
||||||
|
|
||||||
|
if (wiphy_register(wiphy) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return wiphy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wlan_free_wiphy(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
wiphy_unregister(wiphy);
|
||||||
|
wiphy_free(wiphy);
|
||||||
|
}
|
|
@ -1284,6 +1284,8 @@ typedef struct hfa384x {
|
||||||
u16 link_status_new;
|
u16 link_status_new;
|
||||||
struct sk_buff_head authq;
|
struct sk_buff_head authq;
|
||||||
|
|
||||||
|
u32 txrate;
|
||||||
|
|
||||||
/* And here we have stuff that used to be in priv */
|
/* And here we have stuff that used to be in priv */
|
||||||
|
|
||||||
/* State variables */
|
/* State variables */
|
||||||
|
|
|
@ -113,6 +113,7 @@ typedef struct p80211msg_dot11req_scan_results {
|
||||||
p80211item_uint32_t cfpollable;
|
p80211item_uint32_t cfpollable;
|
||||||
p80211item_uint32_t cfpollreq;
|
p80211item_uint32_t cfpollreq;
|
||||||
p80211item_uint32_t privacy;
|
p80211item_uint32_t privacy;
|
||||||
|
p80211item_uint32_t capinfo;
|
||||||
p80211item_uint32_t basicrate1;
|
p80211item_uint32_t basicrate1;
|
||||||
p80211item_uint32_t basicrate2;
|
p80211item_uint32_t basicrate2;
|
||||||
p80211item_uint32_t basicrate3;
|
p80211item_uint32_t basicrate3;
|
||||||
|
@ -209,6 +210,7 @@ typedef struct p80211msg_lnxreq_commsquality {
|
||||||
p80211item_uint32_t link;
|
p80211item_uint32_t link;
|
||||||
p80211item_uint32_t level;
|
p80211item_uint32_t level;
|
||||||
p80211item_uint32_t noise;
|
p80211item_uint32_t noise;
|
||||||
|
p80211item_uint32_t txrate;
|
||||||
} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
|
} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
|
||||||
|
|
||||||
typedef struct p80211msg_lnxreq_autojoin {
|
typedef struct p80211msg_lnxreq_autojoin {
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
|
|
||||||
#include <net/iw_handler.h>
|
#include <net/iw_handler.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
|
#include <net/cfg80211.h>
|
||||||
|
|
||||||
#include "p80211types.h"
|
#include "p80211types.h"
|
||||||
#include "p80211hdr.h"
|
#include "p80211hdr.h"
|
||||||
|
@ -87,6 +88,8 @@
|
||||||
#include "p80211metastruct.h"
|
#include "p80211metastruct.h"
|
||||||
#include "p80211metadef.h"
|
#include "p80211metadef.h"
|
||||||
|
|
||||||
|
#include "cfg80211.c"
|
||||||
|
|
||||||
/* Support functions */
|
/* Support functions */
|
||||||
static void p80211netdev_rx_bh(unsigned long arg);
|
static void p80211netdev_rx_bh(unsigned long arg);
|
||||||
|
|
||||||
|
@ -732,6 +735,7 @@ static const struct net_device_ops p80211_netdev_ops = {
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* wlandev ptr to the wlandev structure for the
|
* wlandev ptr to the wlandev structure for the
|
||||||
* interface.
|
* interface.
|
||||||
|
* physdev ptr to usb device
|
||||||
* Returns:
|
* Returns:
|
||||||
* zero on success, non-zero otherwise.
|
* zero on success, non-zero otherwise.
|
||||||
* Call Context:
|
* Call Context:
|
||||||
|
@ -740,10 +744,12 @@ static const struct net_device_ops p80211_netdev_ops = {
|
||||||
* compiled drivers, this function will be called in the
|
* compiled drivers, this function will be called in the
|
||||||
* context of the kernel startup code.
|
* context of the kernel startup code.
|
||||||
----------------------------------------------------------------*/
|
----------------------------------------------------------------*/
|
||||||
int wlan_setup(wlandevice_t *wlandev)
|
int wlan_setup(wlandevice_t *wlandev, struct device *physdev)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
netdevice_t *dev;
|
netdevice_t *netdev;
|
||||||
|
struct wiphy *wiphy;
|
||||||
|
struct wireless_dev *wdev;
|
||||||
|
|
||||||
/* Set up the wlandev */
|
/* Set up the wlandev */
|
||||||
wlandev->state = WLAN_DEVICE_CLOSED;
|
wlandev->state = WLAN_DEVICE_CLOSED;
|
||||||
|
@ -755,20 +761,30 @@ int wlan_setup(wlandevice_t *wlandev)
|
||||||
tasklet_init(&wlandev->rx_bh,
|
tasklet_init(&wlandev->rx_bh,
|
||||||
p80211netdev_rx_bh, (unsigned long)wlandev);
|
p80211netdev_rx_bh, (unsigned long)wlandev);
|
||||||
|
|
||||||
|
/* Allocate and initialize the wiphy struct */
|
||||||
|
wiphy = wlan_create_wiphy(physdev, wlandev);
|
||||||
|
if (wiphy == NULL) {
|
||||||
|
printk(KERN_ERR "Failed to alloc wiphy.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and initialize the struct device */
|
/* Allocate and initialize the struct device */
|
||||||
dev = alloc_netdev(0, "wlan%d", ether_setup);
|
netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", ether_setup);
|
||||||
if (dev == NULL) {
|
if (netdev == NULL) {
|
||||||
printk(KERN_ERR "Failed to alloc netdev.\n");
|
printk(KERN_ERR "Failed to alloc netdev.\n");
|
||||||
|
wlan_free_wiphy(wiphy);
|
||||||
result = 1;
|
result = 1;
|
||||||
} else {
|
} else {
|
||||||
wlandev->netdev = dev;
|
wlandev->netdev = netdev;
|
||||||
dev->ml_priv = wlandev;
|
netdev->ml_priv = wlandev;
|
||||||
dev->netdev_ops = &p80211_netdev_ops;
|
netdev->netdev_ops = &p80211_netdev_ops;
|
||||||
|
wdev = netdev_priv(netdev);
|
||||||
|
wdev->wiphy = wiphy;
|
||||||
|
wdev->iftype = NL80211_IFTYPE_STATION;
|
||||||
|
netdev->ieee80211_ptr = wdev;
|
||||||
|
|
||||||
dev->wireless_handlers = &p80211wext_handler_def;
|
netif_stop_queue(netdev);
|
||||||
|
netif_carrier_off(netdev);
|
||||||
netif_stop_queue(dev);
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -797,14 +813,13 @@ int wlan_setup(wlandevice_t *wlandev)
|
||||||
----------------------------------------------------------------*/
|
----------------------------------------------------------------*/
|
||||||
int wlan_unsetup(wlandevice_t *wlandev)
|
int wlan_unsetup(wlandevice_t *wlandev)
|
||||||
{
|
{
|
||||||
int result = 0;
|
struct wireless_dev *wdev;
|
||||||
|
|
||||||
tasklet_kill(&wlandev->rx_bh);
|
tasklet_kill(&wlandev->rx_bh);
|
||||||
|
|
||||||
if (wlandev->netdev == NULL) {
|
if (wlandev->netdev) {
|
||||||
printk(KERN_ERR "called without wlandev->netdev set.\n");
|
wdev = netdev_priv(wlandev->netdev);
|
||||||
result = 1;
|
if(wdev->wiphy) wlan_free_wiphy(wdev->wiphy);
|
||||||
} else {
|
|
||||||
free_netdev(wlandev->netdev);
|
free_netdev(wlandev->netdev);
|
||||||
wlandev->netdev = NULL;
|
wlandev->netdev = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
|
||||||
#define MAX_KEYLEN 32
|
#define MAX_KEYLEN 32
|
||||||
|
|
||||||
#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
|
#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
|
||||||
|
#define HOSTWEP_SHAREDKEY BIT(3)
|
||||||
#define HOSTWEP_DECRYPT BIT(4)
|
#define HOSTWEP_DECRYPT BIT(4)
|
||||||
#define HOSTWEP_ENCRYPT BIT(5)
|
#define HOSTWEP_ENCRYPT BIT(5)
|
||||||
#define HOSTWEP_PRIVACYINVOKED BIT(6)
|
#define HOSTWEP_PRIVACYINVOKED BIT(6)
|
||||||
|
@ -233,7 +234,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
|
||||||
int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
|
int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
|
||||||
u8 *iv, u8 *icv);
|
u8 *iv, u8 *icv);
|
||||||
|
|
||||||
int wlan_setup(wlandevice_t *wlandev);
|
int wlan_setup(wlandevice_t *wlandev, struct device *physdev);
|
||||||
int wlan_unsetup(wlandevice_t *wlandev);
|
int wlan_unsetup(wlandevice_t *wlandev);
|
||||||
int register_wlandev(wlandevice_t *wlandev);
|
int register_wlandev(wlandevice_t *wlandev);
|
||||||
int unregister_wlandev(wlandevice_t *wlandev);
|
int unregister_wlandev(wlandevice_t *wlandev);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -463,6 +463,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
|
||||||
|
|
||||||
/* capinfo bits */
|
/* capinfo bits */
|
||||||
count = le16_to_cpu(item->capinfo);
|
count = le16_to_cpu(item->capinfo);
|
||||||
|
req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
|
||||||
|
req->capinfo.data = count;
|
||||||
|
|
||||||
/* privacy flag */
|
/* privacy flag */
|
||||||
req->privacy.status = P80211ENUM_msgitem_status_data_ok;
|
req->privacy.status = P80211ENUM_msgitem_status_data_ok;
|
||||||
|
|
|
@ -124,6 +124,10 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
|
||||||
|
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
|
void prism2_connect_result(wlandevice_t *wlandev, u8 failed);
|
||||||
|
void prism2_disconnected(wlandevice_t *wlandev);
|
||||||
|
void prism2_roamed(wlandevice_t *wlandev);
|
||||||
|
|
||||||
static int prism2sta_open(wlandevice_t *wlandev);
|
static int prism2sta_open(wlandevice_t *wlandev);
|
||||||
static int prism2sta_close(wlandevice_t *wlandev);
|
static int prism2sta_close(wlandevice_t *wlandev);
|
||||||
static void prism2sta_reset(wlandevice_t *wlandev);
|
static void prism2sta_reset(wlandevice_t *wlandev);
|
||||||
|
@ -401,6 +405,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
|
||||||
qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
|
qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
|
||||||
qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
|
qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
|
||||||
qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);
|
qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);
|
||||||
|
qualmsg->txrate.data = hw->txrate;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1300,6 +1305,9 @@ void prism2sta_processing_defer(struct work_struct *data)
|
||||||
(portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
|
(portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
|
||||||
WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
|
WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
|
||||||
|
|
||||||
|
/* signal back up to cfg80211 layer */
|
||||||
|
prism2_connect_result(wlandev, P80211ENUM_truth_false);
|
||||||
|
|
||||||
/* Get the ball rolling on the comms quality stuff */
|
/* Get the ball rolling on the comms quality stuff */
|
||||||
prism2sta_commsqual_defer(&hw->commsqual_bh);
|
prism2sta_commsqual_defer(&hw->commsqual_bh);
|
||||||
}
|
}
|
||||||
|
@ -1315,25 +1323,16 @@ void prism2sta_processing_defer(struct work_struct *data)
|
||||||
* Indicate Deauthentication
|
* Indicate Deauthentication
|
||||||
* Block Transmits, Ignore receives of data frames
|
* Block Transmits, Ignore receives of data frames
|
||||||
*/
|
*/
|
||||||
if (hw->join_ap == 2) {
|
if (wlandev->netdev->type == ARPHRD_ETHER)
|
||||||
hfa384x_JoinRequest_data_t joinreq;
|
|
||||||
joinreq = hw->joinreq;
|
|
||||||
/* Send the join request */
|
|
||||||
hfa384x_drvr_setconfig(hw,
|
|
||||||
HFA384x_RID_JOINREQUEST,
|
|
||||||
&joinreq,
|
|
||||||
HFA384x_RID_JOINREQUEST_LEN);
|
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"linkstatus=DISCONNECTED (re-submitting join)\n");
|
"linkstatus=DISCONNECTED (unhandled)\n");
|
||||||
} else {
|
|
||||||
if (wlandev->netdev->type == ARPHRD_ETHER)
|
|
||||||
printk(KERN_INFO
|
|
||||||
"linkstatus=DISCONNECTED (unhandled)\n");
|
|
||||||
}
|
|
||||||
wlandev->macmode = WLAN_MACMODE_NONE;
|
wlandev->macmode = WLAN_MACMODE_NONE;
|
||||||
|
|
||||||
netif_carrier_off(wlandev->netdev);
|
netif_carrier_off(wlandev->netdev);
|
||||||
|
|
||||||
|
/* signal back up to cfg80211 layer */
|
||||||
|
prism2_disconnected(wlandev);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HFA384x_LINK_AP_CHANGE:
|
case HFA384x_LINK_AP_CHANGE:
|
||||||
|
@ -1376,6 +1375,9 @@ void prism2sta_processing_defer(struct work_struct *data)
|
||||||
hw->link_status = HFA384x_LINK_CONNECTED;
|
hw->link_status = HFA384x_LINK_CONNECTED;
|
||||||
netif_carrier_on(wlandev->netdev);
|
netif_carrier_on(wlandev->netdev);
|
||||||
|
|
||||||
|
/* signal back up to cfg80211 layer */
|
||||||
|
prism2_roamed(wlandev);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HFA384x_LINK_AP_OUTOFRANGE:
|
case HFA384x_LINK_AP_OUTOFRANGE:
|
||||||
|
@ -1435,6 +1437,9 @@ void prism2sta_processing_defer(struct work_struct *data)
|
||||||
|
|
||||||
netif_carrier_off(wlandev->netdev);
|
netif_carrier_off(wlandev->netdev);
|
||||||
|
|
||||||
|
/* signal back up to cfg80211 layer */
|
||||||
|
prism2_connect_result(wlandev, P80211ENUM_truth_true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1446,7 +1451,6 @@ void prism2sta_processing_defer(struct work_struct *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
|
wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
|
||||||
p80211wext_event_associated(wlandev, wlandev->linkstatus);
|
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
return;
|
return;
|
||||||
|
@ -1985,6 +1989,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
|
||||||
hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
|
hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
|
||||||
wlandevice_t *wlandev = hw->wlandev;
|
wlandevice_t *wlandev = hw->wlandev;
|
||||||
hfa384x_bytestr32_t ssid;
|
hfa384x_bytestr32_t ssid;
|
||||||
|
p80211msg_dot11req_mibget_t msg;
|
||||||
|
p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (hw->wlandev->hwremoved)
|
if (hw->wlandev->hwremoved)
|
||||||
|
@ -2013,6 +2019,34 @@ void prism2sta_commsqual_defer(struct work_struct *data)
|
||||||
le16_to_cpu(hw->qual.ANL_currFC));
|
le16_to_cpu(hw->qual.ANL_currFC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the signal rate */
|
||||||
|
msg.msgcode = DIDmsg_dot11req_mibget;
|
||||||
|
mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
|
||||||
|
result = p80211req_dorequest(wlandev, (u8 *) & msg);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
pr_debug("get signal rate failed, result = %d\n",
|
||||||
|
result);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mibitem->data) {
|
||||||
|
case HFA384x_RATEBIT_1:
|
||||||
|
hw->txrate = 10;
|
||||||
|
break;
|
||||||
|
case HFA384x_RATEBIT_2:
|
||||||
|
hw->txrate = 20;
|
||||||
|
break;
|
||||||
|
case HFA384x_RATEBIT_5dot5:
|
||||||
|
hw->txrate = 55;
|
||||||
|
break;
|
||||||
|
case HFA384x_RATEBIT_11:
|
||||||
|
hw->txrate = 110;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_debug("Bad ratebit (%d)\n", mibitem->data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Lastly, we need to make sure the BSSID didn't change on us */
|
/* Lastly, we need to make sure the BSSID didn't change on us */
|
||||||
result = hfa384x_drvr_getconfig(hw,
|
result = hfa384x_drvr_getconfig(hw,
|
||||||
HFA384x_RID_CURRENTBSSID,
|
HFA384x_RID_CURRENTBSSID,
|
||||||
|
|
|
@ -119,7 +119,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
|
||||||
}
|
}
|
||||||
hw = wlandev->priv;
|
hw = wlandev->priv;
|
||||||
|
|
||||||
if (wlan_setup(wlandev) != 0) {
|
if (wlan_setup(wlandev, &(interface->dev)) != 0) {
|
||||||
printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
|
printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
|
||||||
result = -EIO;
|
result = -EIO;
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
Loading…
Reference in New Issue