aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/wlags49_h2/wl_wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/wlags49_h2/wl_wext.c')
-rw-r--r--drivers/staging/wlags49_h2/wl_wext.c1184
1 files changed, 524 insertions, 660 deletions
diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c
index 522a310..8ac5e10 100644
--- a/drivers/staging/wlags49_h2/wl_wext.c
+++ b/drivers/staging/wlags49_h2/wl_wext.c
@@ -75,20 +75,6 @@
#include <wl_wext.h>
#include <wl_priv.h>
-
-
-/* If WIRELESS_EXT is not defined (as a result of HAS_WIRELESS_EXTENSIONS
- #including linux/wireless.h), then these functions do not need to be included
- in the build. */
-#ifdef WIRELESS_EXT
-
-#define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \
- iwe_stream_add_event(info, buf, end, iwe, len)
-#define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \
- iwe_stream_add_point(info, buf, end, iwe, msg)
-
-
-
/*******************************************************************************
* global definitions
******************************************************************************/
@@ -97,7 +83,223 @@ extern dbg_info_t *DbgInfo;
#endif // DBG
+/* Set up the LTV to program the appropriate key */
+static int hermes_set_tkip_keys(ltv_t *ltv, u16 key_idx, u8 *addr,
+ int set_tx, u8 *seq, u8 *key, size_t key_len)
+{
+ int ret = -EINVAL;
+ int buf_idx = 0;
+ hcf_8 tsc[IW_ENCODE_SEQ_MAX_SIZE] =
+ { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 };
+
+ DBG_ENTER(DbgInfo);
+
+ /*
+ * Check the key index here; if 0, load as Pairwise Key, otherwise,
+ * load as a group key. Note that for the Hermes, the RIDs for
+ * group/pairwise keys are different from each other and different
+ * than the default WEP keys as well.
+ */
+ switch (key_idx) {
+ case 0:
+ ltv->len = 28;
+ ltv->typ = CFG_ADD_TKIP_MAPPED_KEY;
+
+ /* Load the BSSID */
+ memcpy(&ltv->u.u8[buf_idx], addr, ETH_ALEN);
+ buf_idx += ETH_ALEN;
+
+ /* Load the TKIP key */
+ memcpy(&ltv->u.u8[buf_idx], &key[0], 16);
+ buf_idx += 16;
+
+ /* Load the TSC */
+ memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
+ buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+ /* Load the RSC */
+ memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
+ buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+ /* Load the TxMIC key */
+ memcpy(&ltv->u.u8[buf_idx], &key[16], 8);
+ buf_idx += 8;
+
+ /* Load the RxMIC key */
+ memcpy(&ltv->u.u8[buf_idx], &key[24], 8);
+
+ ret = 0;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ ltv->len = 26;
+ ltv->typ = CFG_ADD_TKIP_DEFAULT_KEY;
+
+ /* Load the key Index */
+
+ /* If this is a Tx Key, set bit 8000 */
+ if (set_tx)
+ key_idx |= 0x8000;
+ ltv->u.u16[buf_idx] = cpu_to_le16(key_idx);
+ buf_idx += 2;
+
+ /* Load the RSC */
+ memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
+ buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+ /* Load the TKIP, TxMIC, and RxMIC keys in one shot, because in
+ CFG_ADD_TKIP_DEFAULT_KEY they are back-to-back */
+ memcpy(&ltv->u.u8[buf_idx], key, key_len);
+ buf_idx += key_len;
+
+ /* Load the TSC */
+ memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
+
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ DBG_LEAVE(DbgInfo);
+ return ret;
+}
+
+/* Set up the LTV to clear the appropriate key */
+static int hermes_clear_tkip_keys(ltv_t *ltv, u16 key_idx, u8 *addr)
+{
+ int ret;
+
+ switch (key_idx) {
+ case 0:
+ if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) {
+ ltv->len = 7;
+ ltv->typ = CFG_REMOVE_TKIP_MAPPED_KEY;
+ memcpy(&ltv->u.u8[0], addr, ETH_ALEN);
+ ret = 0;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ /* Clear the Group TKIP keys by index */
+ ltv->len = 2;
+ ltv->typ = CFG_REMOVE_TKIP_DEFAULT_KEY;
+ ltv->u.u16[0] = cpu_to_le16(key_idx);
+
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/* Set the WEP keys in the wl_private structure */
+static int hermes_set_wep_keys(struct wl_private *lp, u16 key_idx,
+ u8 *key, size_t key_len,
+ bool enable, bool set_tx)
+{
+ hcf_8 encryption_state = lp->EnableEncryption;
+ int tk = lp->TransmitKeyID - 1; /* current key */
+ int ret = 0;
+
+ /* Is encryption supported? */
+ if (!wl_has_wep(&(lp->hcfCtx))) {
+ DBG_WARNING(DbgInfo, "WEP not supported on this device\n");
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+ DBG_NOTICE(DbgInfo, "pointer: %p, length: %d\n",
+ key, key_len);
+
+ /* Check the size of the key */
+ switch (key_len) {
+ case MIN_KEY_SIZE:
+ case MAX_KEY_SIZE:
+
+ /* Check the index */
+ if ((key_idx < 0) || (key_idx >= MAX_KEYS))
+ key_idx = tk;
+
+ /* Cleanup */
+ memset(lp->DefaultKeys.key[key_idx].key, 0, MAX_KEY_SIZE);
+
+ /* Copy the key in the driver */
+ memcpy(lp->DefaultKeys.key[key_idx].key, key, key_len);
+
+ /* Set the length */
+ lp->DefaultKeys.key[key_idx].len = key_len;
+
+ DBG_NOTICE(DbgInfo, "encoding.length: %d\n", key_len);
+ DBG_NOTICE(DbgInfo, "set key: %s(%d) [%d]\n",
+ lp->DefaultKeys.key[key_idx].key,
+ lp->DefaultKeys.key[key_idx].len, key_idx);
+
+ /* Enable WEP (if possible) */
+ if ((key_idx == tk) && (lp->DefaultKeys.key[tk].len > 0))
+ lp->EnableEncryption = 1;
+
+ break;
+
+ case 0:
+ /* Do we want to just set the current transmit key? */
+ if (set_tx && (key_idx >= 0) && (key_idx < MAX_KEYS)) {
+ DBG_NOTICE(DbgInfo, "index: %d; len: %d\n", key_idx,
+ lp->DefaultKeys.key[key_idx].len);
+
+ if (lp->DefaultKeys.key[key_idx].len > 0) {
+ lp->TransmitKeyID = key_idx + 1;
+ lp->EnableEncryption = 1;
+ } else {
+ DBG_WARNING(DbgInfo, "Problem setting the current TxKey\n");
+ ret = -EINVAL;
+ }
+ }
+ break;
+
+ default:
+ DBG_WARNING(DbgInfo, "Invalid Key length\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Read the flags */
+ if (enable) {
+ lp->EnableEncryption = 1;
+ lp->wext_enc = IW_ENCODE_ALG_WEP;
+ } else {
+ lp->EnableEncryption = 0; /* disable encryption */
+ lp->wext_enc = IW_ENCODE_ALG_NONE;
+ }
+
+ DBG_TRACE(DbgInfo, "encryption_state : %d\n", encryption_state);
+ DBG_TRACE(DbgInfo, "lp->EnableEncryption : %d\n", lp->EnableEncryption);
+ DBG_TRACE(DbgInfo, "erq->length : %d\n", key_len);
+
+ /* Write the changes to the card */
+ if (ret == 0) {
+ DBG_NOTICE(DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption,
+ lp->TransmitKeyID);
+
+ if (lp->EnableEncryption == encryption_state) {
+ if (key_len != 0) {
+ /* Dynamic WEP key update */
+ wl_set_wep_keys(lp);
+ }
+ } else {
+ /* To switch encryption on/off, soft reset is
+ * required */
+ wl_apply(lp);
+ }
+ }
+
+out:
+ return ret;
+}
/*******************************************************************************
* wireless_commit()
@@ -324,16 +526,8 @@ static int wireless_get_frequency(struct net_device *dev, struct iw_request_info
if( ret == HCF_SUCCESS ) {
hcf_16 channel = CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] );
-#ifdef USE_FREQUENCY
-
freq->m = wl_get_freq_from_chan( channel ) * 100000;
freq->e = 1;
-#else
-
- freq->m = channel;
- freq->e = 0;
-
-#endif /* USE_FREQUENCY */
}
wl_act_int_on( lp );
@@ -460,8 +654,6 @@ retry:
/* Link quality */
-#ifdef USE_DBM
-
range->max_qual.qual = (u_char)HCF_MAX_COMM_QUALITY;
/* If the value returned in /proc/net/wireless is greater than the maximum range,
@@ -470,13 +662,6 @@ retry:
range->max_qual.level = (u_char)( dbm( HCF_MIN_SIGNAL_LEVEL ) - 1 );
range->max_qual.noise = (u_char)( dbm( HCF_MIN_NOISE_LEVEL ) - 1 );
-#else
-
- range->max_qual.qual = 100;
- range->max_qual.level = 100;
- range->max_qual.noise = 100;
-
-#endif /* USE_DBM */
/* Set available rates */
@@ -508,8 +693,6 @@ retry:
/* Encryption */
-#if WIRELESS_EXT > 8
-
/* Holding the lock too long, make a gap to allow other processes */
wl_unlock(lp, &flags);
wl_lock( lp, &flags );
@@ -526,26 +709,17 @@ retry:
range->max_encoding_tokens = MAX_KEYS;
}
-#endif /* WIRELESS_EXT > 8 */
-
/* Tx Power Info */
range->txpower_capa = IW_TXPOW_MWATT;
range->num_txpower = 1;
range->txpower[0] = RADIO_TX_POWER_MWATT;
-#if WIRELESS_EXT > 10
-
/* Wireless Extension Info */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = WIRELESS_SUPPORT;
// Retry Limits and Lifetime - NOT SUPPORTED
-#endif
-
-
-#if WIRELESS_EXT > 11
-
/* Holding the lock too long, make a gap to allow other processes */
wl_unlock(lp, &flags);
wl_lock( lp, &flags );
@@ -555,18 +729,18 @@ retry:
range->avg_qual = lp->wstats.qual;
DBG_TRACE( DbgInfo, "wl_wireless_stats done\n" );
-#endif
-
/* Event capability (kernel + driver) */
- range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
- IW_EVENT_CAPA_MASK(SIOCGIWAP) |
- IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
- range->event_capa[1] = IW_EVENT_CAPA_K_1;
- range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
- IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
- IW_EVENT_CAPA_MASK(IWEVEXPIRED));
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVREGISTERED);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVEXPIRED);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE);
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+ range->scan_capa = IW_SCAN_CAPA_NONE;
out_unlock:
wl_act_int_on( lp );
@@ -1075,9 +1249,6 @@ static int wireless_get_essid(struct net_device *dev, struct iw_request_info *in
/* Copy the information into the user buffer */
data->length = pName->length;
- /* NOTE: Null terminating is necessary for proper display of the SSID in
- the wireless tools */
- data->length = pName->length + 1;
if( pName->length < HCF_MAX_NAME_LEN ) {
pName->name[pName->length] = '\0';
}
@@ -1087,7 +1258,6 @@ static int wireless_get_essid(struct net_device *dev, struct iw_request_info *in
#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
//;?should we return an error status in AP mode
-#ifdef RETURN_CURRENT_NETWORKNAME
/* if desired is null ("any"), return current or "any" */
if( pName->name[0] == '\0' ) {
@@ -1104,11 +1274,7 @@ static int wireless_get_essid(struct net_device *dev, struct iw_request_info *in
pName->length = CNV_LITTLE_TO_INT( pName->length );
/* Copy the information into the user buffer */
- data->length = pName->length + 1;
- if( pName->length < HCF_MAX_NAME_LEN ) {
- pName->name[pName->length] = '\0';
- }
-
+ data->length = pName->length;
data->flags = 1;
} else {
ret = -EFAULT;
@@ -1116,11 +1282,8 @@ static int wireless_get_essid(struct net_device *dev, struct iw_request_info *in
}
}
-#endif // RETURN_CURRENT_NETWORKNAME
#endif // HCF_STA
- data->length--;
-
if (pName->length > IW_ESSID_MAX_SIZE) {
ret = -EFAULT;
goto out_unlock;
@@ -1169,156 +1332,39 @@ static int wireless_set_encode(struct net_device *dev, struct iw_request_info *i
{
struct wl_private *lp = wl_priv(dev);
unsigned long flags;
- int ret = 0;
-
-#if 1 //;? #if WIRELESS_EXT > 8 - used unconditionally in the rest of the code...
- hcf_8 encryption_state;
-#endif // WIRELESS_EXT > 8
- /*------------------------------------------------------------------------*/
-
+ int key_idx = (erq->flags & IW_ENCODE_INDEX) - 1;
+ int ret = 0;
+ bool enable = true;
- DBG_FUNC( "wireless_set_encode" );
- DBG_ENTER( DbgInfo );
+ DBG_ENTER(DbgInfo);
- if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+ if (lp->portState == WVLAN_PORT_STATE_DISABLED) {
ret = -EBUSY;
goto out;
}
- wl_lock( lp, &flags );
-
- wl_act_int_off( lp );
-
- /* Is encryption supported? */
- if( !wl_has_wep( &( lp->hcfCtx ))) {
- DBG_WARNING( DbgInfo, "WEP not supported on this device\n" );
- ret = -EOPNOTSUPP;
- goto out_unlock;
- }
-
- DBG_NOTICE( DbgInfo, "pointer: %p, length: %d, flags: %#x\n",
- keybuf, erq->length,
- erq->flags);
-
- /* Save state of Encryption switch */
- encryption_state = lp->EnableEncryption;
-
- /* Basic checking: do we have a key to set? */
- if((erq->length) != 0) {
- int index = ( erq->flags & IW_ENCODE_INDEX ) - 1;
- int tk = lp->TransmitKeyID - 1; // current key
-
-
- /* Check the size of the key */
- switch(erq->length) {
- case 0:
- break;
-
- case MIN_KEY_SIZE:
- case MAX_KEY_SIZE:
-
- /* Check the index */
- if(( index < 0 ) || ( index >= MAX_KEYS )) {
- index = tk;
- }
-
- /* Cleanup */
- memset( lp->DefaultKeys.key[index].key, 0, MAX_KEY_SIZE );
-
- /* Copy the key in the driver */
- memcpy( lp->DefaultKeys.key[index].key, keybuf, erq->length);
-
- /* Set the length */
- lp->DefaultKeys.key[index].len = erq->length;
-
- DBG_NOTICE( DbgInfo, "encoding.length: %d\n", erq->length );
- DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[index].key,
- lp->DefaultKeys.key[index].len, index );
-
- /* Enable WEP (if possible) */
- if(( index == tk ) && ( lp->DefaultKeys.key[tk].len > 0 )) {
- lp->EnableEncryption = 1;
- }
-
- break;
-
- default:
- DBG_WARNING( DbgInfo, "Invalid Key length\n" );
- ret = -EINVAL;
- goto out_unlock;
- }
- } else {
- int index = ( erq->flags & IW_ENCODE_INDEX ) - 1;
-
-
- /* Do we want to just set the current transmit key? */
- if(( index >= 0 ) && ( index < MAX_KEYS )) {
- DBG_NOTICE( DbgInfo, "index: %d; len: %d\n", index,
- lp->DefaultKeys.key[index].len );
-
- if( lp->DefaultKeys.key[index].len > 0 ) {
- lp->TransmitKeyID = index + 1;
- lp->EnableEncryption = 1;
- } else {
- DBG_WARNING( DbgInfo, "Problem setting the current TxKey\n" );
- DBG_LEAVE( DbgInfo );
- ret = -EINVAL;
- }
- }
- }
-
- /* Read the flags */
- if( erq->flags & IW_ENCODE_DISABLED ) {
- lp->EnableEncryption = 0; // disable encryption
- } else {
- lp->EnableEncryption = 1;
- }
-
- if( erq->flags & IW_ENCODE_RESTRICTED ) {
- DBG_WARNING( DbgInfo, "IW_ENCODE_RESTRICTED invalid\n" );
- ret = -EINVAL; // Invalid
- }
+ if (erq->flags & IW_ENCODE_DISABLED)
+ enable = false;
- DBG_TRACE( DbgInfo, "encryption_state : %d\n", encryption_state );
- DBG_TRACE( DbgInfo, "lp->EnableEncryption : %d\n", lp->EnableEncryption );
- DBG_TRACE( DbgInfo, "erq->length : %d\n",
- erq->length);
- DBG_TRACE( DbgInfo, "erq->flags : 0x%x\n",
- erq->flags);
+ wl_lock(lp, &flags);
- /* Write the changes to the card */
- if( ret == 0 ) {
- DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption,
- lp->TransmitKeyID );
+ wl_act_int_off(lp);
- if( lp->EnableEncryption == encryption_state ) {
- if( erq->length != 0 ) {
- /* Dynamic WEP key update */
- wl_set_wep_keys( lp );
- }
- } else {
- /* To switch encryption on/off, soft reset is required */
- wl_apply( lp );
- }
- }
+ ret = hermes_set_wep_keys(lp, key_idx, keybuf, erq->length,
+ enable, true);
/* Send an event that Encryption has been set */
- wl_wext_event_encode( dev );
-
-out_unlock:
+ if (ret == 0)
+ wl_wext_event_encode(dev);
- wl_act_int_on( lp );
+ wl_act_int_on(lp);
wl_unlock(lp, &flags);
out:
- DBG_LEAVE( DbgInfo );
+ DBG_LEAVE(DbgInfo);
return ret;
-} // wireless_set_encode
-/*============================================================================*/
-
-
-
+}
/*******************************************************************************
* wireless_get_encode()
@@ -2023,11 +2069,9 @@ static int wireless_set_rts_threshold (struct net_device *dev, struct iw_request
goto out;
}
-#if WIRELESS_EXT > 8
if( rts->disabled ) {
rthr = 2347;
}
-#endif /* WIRELESS_EXT > 8 */
if(( rthr < 256 ) || ( rthr > 2347 )) {
ret = -EINVAL;
@@ -2095,12 +2139,8 @@ static int wireless_get_rts_threshold (struct net_device *dev, struct iw_request
rts->value = lp->RTSThreshold;
-#if WIRELESS_EXT > 8
-
rts->disabled = ( rts->value == 2347 );
-#endif /* WIRELESS_EXT > 8 */
-
rts->fixed = 1;
wl_act_int_on( lp );
@@ -2527,8 +2567,6 @@ out:
-#if WIRELESS_EXT > 13
-
/*******************************************************************************
* wireless_set_scan()
*******************************************************************************
@@ -2737,8 +2775,8 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
memcpy( iwe.u.ap_addr.sa_data, probe_resp->BSSID, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
- buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_ADDR_LEN);
-
+ buf = iwe_stream_add_event(info, buf, buf_end,
+ &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or AP */
/* Won't always be an AP if in IBSS mode */
@@ -2754,8 +2792,8 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
iwe.len = IW_EV_UINT_LEN;
- buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_UINT_LEN);
-
+ buf = iwe_stream_add_event(info, buf, buf_end,
+ &iwe, IW_EV_UINT_LEN);
/* Any quality information */
memset(&iwe, 0, sizeof(iwe));
@@ -2767,7 +2805,8 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
iwe.u.qual.updated = lp->probe_results.scan_complete | IW_QUAL_DBM;
iwe.len = IW_EV_QUAL_LEN;
- buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_QUAL_LEN);
+ buf = iwe_stream_add_event(info, buf, buf_end,
+ &iwe, IW_EV_QUAL_LEN);
/* ESSID information */
@@ -2778,7 +2817,8 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
iwe.u.data.length = probe_resp->rawData[1];
iwe.u.data.flags = 1;
- buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, &probe_resp->rawData[2]);
+ buf = iwe_stream_add_point(info, buf, buf_end,
+ &iwe, &probe_resp->rawData[2]);
}
@@ -2796,7 +2836,7 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
iwe.u.data.flags |= IW_ENCODE_DISABLED;
}
- buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, NULL);
+ buf = iwe_stream_add_point(info, buf, buf_end, &iwe, NULL);
/* Frequency Info */
@@ -2807,10 +2847,10 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
iwe.u.freq.m = wl_parse_ds_ie( probe_resp );
iwe.u.freq.e = 0;
- buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_FREQ_LEN);
+ buf = iwe_stream_add_event(info, buf, buf_end,
+ &iwe, IW_EV_FREQ_LEN);
-#if WIRELESS_EXT > 14
/* Custom info (Beacon Interval) */
memset( &iwe, 0, sizeof( iwe ));
memset( msg, 0, sizeof( msg ));
@@ -2819,27 +2859,25 @@ static int wireless_get_scan(struct net_device *dev, struct iw_request_info *inf
sprintf( msg, "beacon_interval=%d", probe_resp->beaconInterval );
iwe.u.data.length = strlen( msg );
- buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
+ buf = iwe_stream_add_point(info, buf, buf_end, &iwe, msg);
- /* Custom info (WPA-IE) */
+ /* WPA-IE */
wpa_ie = NULL;
wpa_ie_len = 0;
wpa_ie = wl_parse_wpa_ie( probe_resp, &wpa_ie_len );
if( wpa_ie != NULL ) {
- memset( &iwe, 0, sizeof( iwe ));
- memset( msg, 0, sizeof( msg ));
+ memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- sprintf( msg, "wpa_ie=%s", wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
- iwe.u.data.length = strlen( msg );
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = wpa_ie_len;
- buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
+ buf = iwe_stream_add_point(info, buf, buf_end,
+ &iwe, wpa_ie);
}
/* Add other custom info in formatted string format as needed... */
-#endif
}
data->length = buf - extra;
@@ -2856,10 +2894,24 @@ out:
} // wireless_get_scan
/*============================================================================*/
-#endif // WIRELESS_EXT > 13
-
-
-#if WIRELESS_EXT > 17
+#if DBG
+static const char * const auth_names[] = {
+ "IW_AUTH_WPA_VERSION",
+ "IW_AUTH_CIPHER_PAIRWISE",
+ "IW_AUTH_CIPHER_GROUP",
+ "IW_AUTH_KEY_MGMT",
+ "IW_AUTH_TKIP_COUNTERMEASURES",
+ "IW_AUTH_DROP_UNENCRYPTED",
+ "IW_AUTH_80211_AUTH_ALG",
+ "IW_AUTH_WPA_ENABLED",
+ "IW_AUTH_RX_UNENCRYPTED_EAPOL",
+ "IW_AUTH_ROAMING_CONTROL",
+ "IW_AUTH_PRIVACY_INVOKED",
+ "IW_AUTH_CIPHER_GROUP_MGMT",
+ "IW_AUTH_MFP",
+ "Unsupported"
+};
+#endif
static int wireless_set_auth(struct net_device *dev,
struct iw_request_info *info,
@@ -2867,14 +2919,15 @@ static int wireless_set_auth(struct net_device *dev,
{
struct wl_private *lp = wl_priv(dev);
unsigned long flags;
- int ret;
- int iwa_idx = data->flags & IW_AUTH_INDEX;
- int iwa_val = data->value;
+ ltv_t ltv;
+ int ret;
+ int iwa_idx = data->flags & IW_AUTH_INDEX;
+ int iwa_val = data->value;
DBG_FUNC( "wireless_set_auth" );
DBG_ENTER( DbgInfo );
- if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+ if (lp->portState == WVLAN_PORT_STATE_DISABLED) {
ret = -EBUSY;
goto out;
}
@@ -2883,89 +2936,102 @@ static int wireless_set_auth(struct net_device *dev,
wl_act_int_off( lp );
+ if (iwa_idx > IW_AUTH_MFP)
+ iwa_idx = IW_AUTH_MFP + 1;
+ DBG_TRACE(DbgInfo, "%s\n", auth_names[iwa_idx]);
switch (iwa_idx) {
- case IW_AUTH_WPA_VERSION:
- DBG_TRACE( DbgInfo, "IW_AUTH_WPA_VERSION\n");
- /* We do support WPA only; how should DISABLED be treated? */
- if (iwa_val == IW_AUTH_WPA_VERSION_WPA)
- ret = 0;
- else
- ret = -EINVAL;
- break;
-
- case IW_AUTH_WPA_ENABLED:
- DBG_TRACE( DbgInfo, "IW_AUTH_WPA_ENABLED: val = %d\n", iwa_val);
- if (iwa_val)
- lp->EnableEncryption = 2;
- else
- lp->EnableEncryption = 0;
+ case IW_AUTH_WPA_VERSION:
+ /* We do support WPA */
+ if ((iwa_val == IW_AUTH_WPA_VERSION_WPA) ||
+ (iwa_val == IW_AUTH_WPA_VERSION_DISABLED))
ret = 0;
- break;
+ else
+ ret = -EINVAL;
+ break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- DBG_TRACE( DbgInfo, "IW_AUTH_TKIP_COUNTERMEASURES\n");
- lp->driverEnable = !iwa_val;
- if(lp->driverEnable)
- hcf_cntl(&(lp->hcfCtx), HCF_CNTL_ENABLE | HCF_PORT_0);
- else
- hcf_cntl(&(lp->hcfCtx), HCF_CNTL_DISABLE | HCF_PORT_0);
- ret = 0;
- break;
+ case IW_AUTH_WPA_ENABLED:
+ DBG_TRACE(DbgInfo, "val = %d\n", iwa_val);
+ if (iwa_val)
+ lp->EnableEncryption = 2;
+ else
+ lp->EnableEncryption = 0;
- case IW_AUTH_DROP_UNENCRYPTED:
- DBG_TRACE( DbgInfo, "IW_AUTH_DROP_UNENCRYPTED\n");
- /* We do not actually do anything here, just to silence
- * wpa_supplicant */
- ret = 0;
- break;
+ /* Write straight to the card */
+ ltv.len = 2;
+ ltv.typ = CFG_CNF_ENCRYPTION;
+ ltv.u.u16[0] = cpu_to_le16(lp->EnableEncryption);
+ ret = hcf_put_info(&lp->hcfCtx, (LTVP)&ltv);
- case IW_AUTH_CIPHER_PAIRWISE:
- DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_PAIRWISE\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ break;
- case IW_AUTH_CIPHER_GROUP:
- DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_GROUP\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
- case IW_AUTH_KEY_MGMT:
- DBG_TRACE( DbgInfo, "IW_AUTH_KEY_MGMT\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ /* Immediately disable card */
+ lp->driverEnable = !iwa_val;
+ if (lp->driverEnable)
+ hcf_cntl(&(lp->hcfCtx), HCF_CNTL_ENABLE | HCF_PORT_0);
+ else
+ hcf_cntl(&(lp->hcfCtx), HCF_CNTL_DISABLE | HCF_PORT_0);
+ ret = 0;
+ break;
- case IW_AUTH_80211_AUTH_ALG:
- DBG_TRACE( DbgInfo, "IW_AUTH_80211_AUTH_ALG\n");
- /* not implemented, return an error */
+ case IW_AUTH_MFP:
+ /* Management Frame Protection not supported.
+ * Only fail if set to required.
+ */
+ if (iwa_val == IW_AUTH_MFP_REQUIRED)
ret = -EINVAL;
- break;
+ else
+ ret = 0;
+ break;
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- DBG_TRACE( DbgInfo, "IW_AUTH_RX_UNENCRYPTED_EAPOL\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ case IW_AUTH_KEY_MGMT:
- case IW_AUTH_ROAMING_CONTROL:
- DBG_TRACE( DbgInfo, "IW_AUTH_ROAMING_CONTROL\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ /* Record required management suite.
+ * Will take effect on next commit */
+ if (iwa_val != 0)
+ lp->AuthKeyMgmtSuite = 4;
+ else
+ lp->AuthKeyMgmtSuite = 0;
- case IW_AUTH_PRIVACY_INVOKED:
- DBG_TRACE( DbgInfo, "IW_AUTH_PRIVACY_INVOKED\n");
- /* not implemented, return an error */
- ret = -EINVAL;
- break;
+ ret = -EINPROGRESS;
+ break;
- default:
- DBG_TRACE( DbgInfo, "IW_AUTH_?? (%d) unknown\n", iwa_idx);
- /* return an error */
+ case IW_AUTH_80211_AUTH_ALG:
+
+ /* Just record whether open or shared is required.
+ * Will take effect on next commit */
+ ret = -EINPROGRESS;
+
+ if (iwa_val & IW_AUTH_ALG_SHARED_KEY)
+ lp->authentication = 1;
+ else if (iwa_val & IW_AUTH_ALG_OPEN_SYSTEM)
+ lp->authentication = 0;
+ else
ret = -EINVAL;
- break;
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /* Only needed for AP */
+ lp->ExcludeUnencrypted = iwa_val;
+ ret = -EINPROGRESS;
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ case IW_AUTH_ROAMING_CONTROL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ /* Not used. May need to do something with
+ * CIPHER_PAIRWISE and CIPHER_GROUP*/
+ ret = -EINPROGRESS;
+ break;
+
+ default:
+ DBG_TRACE(DbgInfo, "IW_AUTH_?? (%d) unknown\n", iwa_idx);
+ /* return an error */
+ ret = -EOPNOTSUPP;
+ break;
}
wl_act_int_on( lp );
@@ -2979,290 +3045,176 @@ out:
/*============================================================================*/
-
-static int hermes_set_key(ltv_t *ltv, int alg, int key_idx, u8 *addr,
- int set_tx, u8 *seq, u8 *key, size_t key_len)
+static void flush_tx(struct wl_private *lp)
{
- int ret = -EINVAL;
- // int count = 0;
- int buf_idx = 0;
- hcf_8 tsc[IW_ENCODE_SEQ_MAX_SIZE] =
- { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 };
-
- DBG_FUNC( "hermes_set_key" );
- DBG_ENTER( DbgInfo );
+ ltv_t ltv;
+ int count;
/*
- * Check the key index here; if 0, load as Pairwise Key, otherwise,
- * load as a group key. Note that for the Hermes, the RIDs for
- * group/pariwise keys are different from each other and different
- * than the default WEP keys as well.
- */
- switch (alg)
- {
- case IW_ENCODE_ALG_TKIP:
- DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_TKIP: key(%d)\n", key_idx);
-#if 0
- /*
- * Make sure that there is no data queued up in the firmware
- * before setting the TKIP keys. If this check is not
- * performed, some data may be sent out with incorrect MIC
- * and cause synchronizarion errors with the AP
- */
- /* Check every 1ms for 100ms */
- for( count = 0; count < 100; count++ )
- {
- usleep( 1000 );
+ * Make sure that there is no data queued up in the firmware
+ * before setting the TKIP keys. If this check is not
+ * performed, some data may be sent out with incorrect MIC
+ * and cause synchronizarion errors with the AP
+ */
+ /* Check every 1ms for 100ms */
+ for (count = 0; count < 100; count++) {
+ udelay(1000);
+
+ ltv.len = 2;
+ ltv.typ = 0xFD91; /* This RID not defined in HCF yet!!! */
+ ltv.u.u16[0] = 0;
+
+ hcf_get_info(&(lp->hcfCtx), (LTVP)&ltv);
+
+ if (ltv.u.u16[0] == 0)
+ break;
+ }
+
+ if (count >= 100)
+ DBG_TRACE(DbgInfo, "Timed out waiting for TxQ flush!\n");
- ltv.len = 2;
- ltv.typ = 0xFD91; // This RID not defined in HCF yet!!!
- ltv.u.u16[0] = 0;
+}
- wl_get_info( sock, &ltv, ifname );
+static int wireless_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf)
+{
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
+ int ret;
+ int key_idx = (erq->flags & IW_ENCODE_INDEX) - 1;
+ ltv_t ltv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)keybuf;
+ bool enable = true;
+ bool set_tx = false;
- if( ltv.u.u16[0] == 0 )
- {
- break;
- }
- }
+ DBG_ENTER(DbgInfo);
- if( count == 100 )
- {
- wpa_printf( MSG_DEBUG, "Timed out waiting for TxQ!" );
- }
-#endif
+ if (lp->portState == WVLAN_PORT_STATE_DISABLED) {
+ ret = -EBUSY;
+ goto out;
+ }
- switch (key_idx) {
- case 0:
- ltv->len = 28;
- ltv->typ = CFG_ADD_TKIP_MAPPED_KEY;
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ ext->alg = IW_ENCODE_ALG_NONE;
+ enable = false;
+ }
- /* Load the BSSID */
- memcpy(&ltv->u.u8[buf_idx], addr, ETH_ALEN);
- buf_idx += ETH_ALEN;
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ set_tx = true;
- /* Load the TKIP key */
- memcpy(&ltv->u.u8[buf_idx], &key[0], 16);
- buf_idx += 16;
+ wl_lock(lp, &flags);
- /* Load the TSC */
- memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
- buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+ wl_act_int_off(lp);
- /* Load the RSC */
- memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
- buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+ memset(&ltv, 0, sizeof(ltv));
- /* Load the TxMIC key */
- memcpy(&ltv->u.u8[buf_idx], &key[16], 8);
- buf_idx += 8;
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_TKIP:
+ DBG_TRACE(DbgInfo, "IW_ENCODE_ALG_TKIP: key(%d)\n", key_idx);
- /* Load the RxMIC key */
- memcpy(&ltv->u.u8[buf_idx], &key[24], 8);
+ if (sizeof(ext->rx_seq) != 8) {
+ DBG_TRACE(DbgInfo, "rx_seq size mismatch\n");
+ DBG_LEAVE(DbgInfo);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
- ret = 0;
- break;
- case 1:
- case 2:
- case 3:
- ltv->len = 26;
- ltv->typ = CFG_ADD_TKIP_DEFAULT_KEY;
+ ret = hermes_set_tkip_keys(&ltv, key_idx, ext->addr.sa_data,
+ set_tx,
+ ext->rx_seq, ext->key, ext->key_len);
- /* Load the key Index */
- ltv->u.u16[buf_idx] = key_idx;
- /* If this is a Tx Key, set bit 8000 */
- if(set_tx)
- ltv->u.u16[buf_idx] |= 0x8000;
- buf_idx += 2;
+ if (ret != 0) {
+ DBG_TRACE(DbgInfo, "hermes_set_tkip_keys returned != 0, key not set\n");
+ goto out_unlock;
+ }
- /* Load the RSC */
- memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
- buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+ flush_tx(lp);
- /* Load the TKIP, TxMIC, and RxMIC keys in one shot, because in
- CFG_ADD_TKIP_DEFAULT_KEY they are back-to-back */
- memcpy(&ltv->u.u8[buf_idx], key, key_len);
- buf_idx += key_len;
+ lp->wext_enc = IW_ENCODE_ALG_TKIP;
- /* Load the TSC */
- memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
+ /* Write the key */
+ ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
+ break;
- ltv->u.u16[0] = CNV_INT_TO_LITTLE(ltv->u.u16[0]);
+ case IW_ENCODE_ALG_WEP:
+ DBG_TRACE(DbgInfo, "IW_ENCODE_ALG_WEP: key(%d)\n", key_idx);
- ret = 0;
- break;
- default:
- break;
+ if (erq->flags & IW_ENCODE_RESTRICTED) {
+ DBG_WARNING(DbgInfo, "IW_ENCODE_RESTRICTED invalid\n");
+ ret = -EINVAL;
+ goto out_unlock;
}
- break;
+ ret = hermes_set_wep_keys(lp, key_idx, ext->key, ext->key_len,
+ enable, set_tx);
- case IW_ENCODE_ALG_WEP:
- DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_WEP: key(%d)\n", key_idx);
break;
case IW_ENCODE_ALG_CCMP:
- DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_CCMP: key(%d)\n", key_idx);
+ DBG_TRACE(DbgInfo, "IW_ENCODE_ALG_CCMP: key(%d)\n", key_idx);
+ ret = -EOPNOTSUPP;
break;
case IW_ENCODE_ALG_NONE:
- DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_NONE: key(%d)\n", key_idx);
- switch (key_idx) {
- case 0:
- if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) {
- //if (addr != NULL) {
- ltv->len = 7;
- ltv->typ = CFG_REMOVE_TKIP_MAPPED_KEY;
- memcpy(&ltv->u.u8[0], addr, ETH_ALEN);
- ret = 0;
- }
- break;
- case 1:
- case 2:
- case 3:
- /* Clear the Group TKIP keys by index */
- ltv->len = 2;
- ltv->typ = CFG_REMOVE_TKIP_DEFAULT_KEY;
- ltv->u.u16[0] = key_idx;
-
+ DBG_TRACE(DbgInfo, "IW_ENCODE_ALG_NONE: key(%d)\n", key_idx);
+
+ if (lp->wext_enc == IW_ENCODE_ALG_TKIP) {
+ ret = hermes_clear_tkip_keys(&ltv, key_idx,
+ ext->addr.sa_data);
+ flush_tx(lp);
+ lp->wext_enc = IW_ENCODE_ALG_NONE;
+ ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
+
+ } else if (lp->wext_enc == IW_ENCODE_ALG_WEP) {
+ ret = hermes_set_wep_keys(lp, key_idx,
+ ext->key, ext->key_len,
+ false, false);
+ } else {
ret = 0;
- break;
- default:
- break;
}
+
break;
+
default:
DBG_TRACE( DbgInfo, "IW_ENCODE_??: key(%d)\n", key_idx);
+ ret = -EOPNOTSUPP;
break;
}
- DBG_LEAVE( DbgInfo );
- return ret;
-} // hermes_set_key
-/*============================================================================*/
-
-
-
-static int wireless_set_encodeext (struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *keybuf)
-{
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
- int ret;
- int key_idx = (erq->flags&IW_ENCODE_INDEX) - 1;
- ltv_t ltv;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)keybuf;
-
- DBG_FUNC( "wireless_set_encodeext" );
- DBG_ENTER( DbgInfo );
-
- if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
- ret = -EBUSY;
- goto out;
- }
-
- if (sizeof(ext->rx_seq) != 8) {
- DBG_TRACE(DbgInfo, "rz_seq size mismatch\n");
- DBG_LEAVE(DbgInfo);
- return -EINVAL;
- }
-
- /* Handle WEP keys via the old set encode procedure */
- if(ext->alg == IW_ENCODE_ALG_WEP) {
- struct iw_point wep_erq;
- char *wep_keybuf;
-
- /* Build request structure */
- wep_erq.flags = erq->flags; // take over flags with key index
- wep_erq.length = ext->key_len; // take length from extended key info
- wep_keybuf = ext->key; // pointer to the key text
-
- /* Call wireless_set_encode tot handle the WEP key */
- ret = wireless_set_encode(dev, info, &wep_erq, wep_keybuf);
- goto out;
- }
-
- /* Proceed for extended encode functions for WAP and NONE */
- wl_lock( lp, &flags );
-
- wl_act_int_off( lp );
-
- memset(&ltv, 0, sizeof(ltv));
- ret = hermes_set_key(&ltv, ext->alg, key_idx, ext->addr.sa_data,
- ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
- ext->rx_seq, ext->key, ext->key_len);
-
- if (ret != 0) {
- DBG_TRACE( DbgInfo, "hermes_set_key returned != 0, key not set\n");
- goto out_unlock;
- }
-
- /* Put the key in HCF */
- ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
-
out_unlock:
- if(ret == HCF_SUCCESS) {
- DBG_TRACE( DbgInfo, "Put key info succes\n");
- } else {
- DBG_TRACE( DbgInfo, "Put key info failed, key not set\n");
- }
- wl_act_int_on( lp );
+ wl_act_int_on(lp);
wl_unlock(lp, &flags);
out:
- DBG_LEAVE( DbgInfo );
+ DBG_LEAVE(DbgInfo);
return ret;
-} // wireless_set_encodeext
+}
/*============================================================================*/
-static int wireless_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int wireless_set_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
int ret = 0;
- ltv_t ltv;
-
- DBG_FUNC( "wireless_get_genie" );
- DBG_ENTER( DbgInfo );
-
- if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
- ret = -EBUSY;
- goto out;
- }
-
- wl_lock( lp, &flags );
-
- wl_act_int_off( lp );
-
- memset(&ltv, 0, sizeof(ltv));
- ltv.len = 2;
- ltv.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
- lp->AuthKeyMgmtSuite = ltv.u.u16[0] = 4;
- ltv.u.u16[0] = CNV_INT_TO_LITTLE(ltv.u.u16[0]);
- ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
-
- wl_act_int_on( lp );
+ DBG_ENTER(DbgInfo);
- wl_unlock(lp, &flags);
+ /* We can't write this to the card, but apparently this
+ * operation needs to succeed */
+ ret = 0;
-out:
- DBG_LEAVE( DbgInfo );
+ DBG_LEAVE(DbgInfo);
return ret;
}
/*============================================================================*/
-#endif // WIRELESS_EXT > 17
-
/*******************************************************************************
* wl_wireless_stats()
*******************************************************************************
@@ -3316,7 +3268,6 @@ struct iw_statistics * wl_wireless_stats( struct net_device *dev )
if( status == HCF_SUCCESS ) {
pQual = (CFG_COMMS_QUALITY_STRCT *)&( lp->ltvRecord );
-#ifdef USE_DBM
pStats->qual.qual = (u_char) CNV_LITTLE_TO_INT( pQual->coms_qual );
pStats->qual.level = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->signal_lvl ));
pStats->qual.noise = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->noise_lvl ));
@@ -3325,23 +3276,6 @@ struct iw_statistics * wl_wireless_stats( struct net_device *dev )
IW_QUAL_LEVEL_UPDATED |
IW_QUAL_NOISE_UPDATED |
IW_QUAL_DBM);
-#else
- pStats->qual.qual = percent( CNV_LITTLE_TO_INT( pQual->coms_qual ),
- HCF_MIN_COMM_QUALITY,
- HCF_MAX_COMM_QUALITY );
-
- pStats->qual.level = percent( CNV_LITTLE_TO_INT( pQual->signal_lvl ),
- HCF_MIN_SIGNAL_LEVEL,
- HCF_MAX_SIGNAL_LEVEL );
-
- pStats->qual.noise = percent( CNV_LITTLE_TO_INT( pQual->noise_lvl ),
- HCF_MIN_NOISE_LEVEL,
- HCF_MAX_NOISE_LEVEL );
-
- pStats->qual.updated |= (IW_QUAL_QUAL_UPDATED |
- IW_QUAL_LEVEL_UPDATED |
- IW_QUAL_NOISE_UPDATED);
-#endif /* USE_DBM */
} else {
memset( &( pStats->qual ), 0, sizeof( pStats->qual ));
}
@@ -3512,7 +3446,6 @@ inline void wl_spy_gather( struct net_device *dev, u_char *mac )
******************************************************************************/
void wl_wext_event_freq( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
/*------------------------------------------------------------------------*/
@@ -3524,7 +3457,6 @@ void wl_wext_event_freq( struct net_device *dev )
wrqu.freq.e = 0;
wireless_send_event( dev, SIOCSIWFREQ, &wrqu, NULL );
-#endif /* WIRELESS_EXT > 13 */
return;
} // wl_wext_event_freq
@@ -3554,7 +3486,6 @@ void wl_wext_event_freq( struct net_device *dev )
******************************************************************************/
void wl_wext_event_mode( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
/*------------------------------------------------------------------------*/
@@ -3569,7 +3500,6 @@ void wl_wext_event_mode( struct net_device *dev )
}
wireless_send_event( dev, SIOCSIWMODE, &wrqu, NULL );
-#endif /* WIRELESS_EXT > 13 */
return;
} // wl_wext_event_mode
@@ -3599,7 +3529,6 @@ void wl_wext_event_mode( struct net_device *dev )
******************************************************************************/
void wl_wext_event_essid( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
/*------------------------------------------------------------------------*/
@@ -3616,7 +3545,6 @@ void wl_wext_event_essid( struct net_device *dev )
wrqu.essid.flags = 1;
wireless_send_event( dev, SIOCSIWESSID, &wrqu, lp->NetworkName );
-#endif /* WIRELESS_EXT > 13 */
return;
} // wl_wext_event_essid
@@ -3646,7 +3574,6 @@ void wl_wext_event_essid( struct net_device *dev )
******************************************************************************/
void wl_wext_event_encode( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
int index = 0;
@@ -3688,7 +3615,6 @@ void wl_wext_event_encode( struct net_device *dev )
wireless_send_event( dev, SIOCSIWENCODE, &wrqu,
lp->DefaultKeys.key[index].key );
-#endif /* WIRELESS_EXT > 13 */
return;
} // wl_wext_event_encode
@@ -3718,7 +3644,6 @@ void wl_wext_event_encode( struct net_device *dev )
******************************************************************************/
void wl_wext_event_ap( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
int status;
@@ -3747,8 +3672,6 @@ void wl_wext_event_ap( struct net_device *dev )
wireless_send_event( dev, SIOCGIWAP, &wrqu, NULL );
}
-#endif /* WIRELESS_EXT > 13 */
-
return;
} // wl_wext_event_ap
/*============================================================================*/
@@ -3776,7 +3699,6 @@ void wl_wext_event_ap( struct net_device *dev )
******************************************************************************/
void wl_wext_event_scan_complete( struct net_device *dev )
{
-#if WIRELESS_EXT > 13
union iwreq_data wrqu;
/*------------------------------------------------------------------------*/
@@ -3785,7 +3707,6 @@ void wl_wext_event_scan_complete( struct net_device *dev )
wrqu.addr.sa_family = ARPHRD_ETHER;
wireless_send_event( dev, SIOCGIWSCAN, &wrqu, NULL );
-#endif /* WIRELESS_EXT > 13 */
return;
} // wl_wext_event_scan_complete
@@ -3815,7 +3736,6 @@ void wl_wext_event_scan_complete( struct net_device *dev )
******************************************************************************/
void wl_wext_event_new_sta( struct net_device *dev )
{
-#if WIRELESS_EXT > 14
union iwreq_data wrqu;
/*------------------------------------------------------------------------*/
@@ -3826,7 +3746,6 @@ void wl_wext_event_new_sta( struct net_device *dev )
memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
wrqu.addr.sa_family = ARPHRD_ETHER;
wireless_send_event( dev, IWEVREGISTERED, &wrqu, NULL );
-#endif /* WIRELESS_EXT > 14 */
return;
} // wl_wext_event_new_sta
@@ -3856,7 +3775,6 @@ void wl_wext_event_new_sta( struct net_device *dev )
******************************************************************************/
void wl_wext_event_expired_sta( struct net_device *dev )
{
-#if WIRELESS_EXT > 14
union iwreq_data wrqu;
/*------------------------------------------------------------------------*/
@@ -3866,7 +3784,6 @@ void wl_wext_event_expired_sta( struct net_device *dev )
memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
wrqu.addr.sa_family = ARPHRD_ETHER;
wireless_send_event( dev, IWEVEXPIRED, &wrqu, NULL );
-#endif /* WIRELESS_EXT > 14 */
return;
} // wl_wext_event_expired_sta
@@ -3895,10 +3812,9 @@ void wl_wext_event_expired_sta( struct net_device *dev )
******************************************************************************/
void wl_wext_event_mic_failed( struct net_device *dev )
{
-#if WIRELESS_EXT > 14
- char msg[512];
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
+ struct iw_michaelmicfailure wxmic;
int key_idx;
char *addr1;
char *addr2;
@@ -3920,31 +3836,17 @@ void wl_wext_event_mic_failed( struct net_device *dev )
DBG_PRINT( "MIC FAIL - KEY USED : %d, STATUS : 0x%04x\n", key_idx,
hdr->status );
- memset( &wrqu, 0, sizeof( wrqu ));
- memset( msg, 0, sizeof( msg ));
-
-
- /* Because MIC failures are not part of the Wireless Extensions yet, they
- must be passed as a string using an IWEVCUSTOM event. In order for the
- event to be effective, the string format must be known by both the
- driver and the supplicant. The following is the string format used by the
- hostap project's WPA supplicant, and will be used here until the Wireless
- Extensions interface adds this support:
+ memset(&wrqu, 0, sizeof(wrqu));
+ memset(&wxmic, 0, sizeof(wxmic));
- MLME-MICHAELMICFAILURE.indication(keyid=# broadcast/unicast addr=addr2)
- */
+ wxmic.flags = key_idx & IW_MICFAILURE_KEY_ID;
+ wxmic.flags |= (addr1[0] & 1) ?
+ IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
+ wxmic.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wxmic.src_addr.sa_data, addr2, ETH_ALEN);
- /* NOTE: Format of MAC address (using colons to separate bytes) may cause
- a problem in future versions of the supplicant, if they ever
- actually parse these parameters */
-#if DBG
- sprintf(msg, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast "
- "addr=%pM)", key_idx, addr1[0] & 0x01 ? "broad" : "uni",
- addr2);
-#endif
- wrqu.data.length = strlen( msg );
- wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
-#endif /* WIRELESS_EXT > 14 */
+ wrqu.data.length = sizeof(wxmic);
+ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&wxmic);
return;
} // wl_wext_event_mic_failed
@@ -3974,8 +3876,6 @@ void wl_wext_event_mic_failed( struct net_device *dev )
******************************************************************************/
void wl_wext_event_assoc_ie( struct net_device *dev )
{
-#if WIRELESS_EXT > 14
- char msg[512];
union iwreq_data wrqu;
struct wl_private *lp = wl_priv(dev);
int status;
@@ -3986,7 +3886,6 @@ void wl_wext_event_assoc_ie( struct net_device *dev )
memset( &wrqu, 0, sizeof( wrqu ));
- memset( msg, 0, sizeof( msg ));
/* Retrieve the Association Request IE */
lp->ltvRecord.len = 45;
@@ -3999,24 +3898,18 @@ void wl_wext_event_assoc_ie( struct net_device *dev )
memcpy( &data.rawData, &( lp->ltvRecord.u.u8[1] ), 88 );
wpa_ie = wl_parse_wpa_ie( &data, &length );
- /* Because this event (Association WPA-IE) is not part of the Wireless
- Extensions yet, it must be passed as a string using an IWEVCUSTOM event.
- In order for the event to be effective, the string format must be known
- by both the driver and the supplicant. The following is the string format
- used by the hostap project's WPA supplicant, and will be used here until
- the Wireless Extensions interface adds this support:
-
- ASSOCINFO(ReqIEs=WPA-IE RespIEs=WPA-IE)
- */
-
if( length != 0 )
{
- sprintf( msg, "ASSOCINFO(ReqIEs=%s)", wl_print_wpa_ie( wpa_ie, length ));
- wrqu.data.length = strlen( msg );
- wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
+ wrqu.data.length = wpa_ie[1] + 2;
+ wireless_send_event(dev, IWEVASSOCREQIE,
+ &wrqu, wpa_ie);
+
+ /* This bit is a hack. We send the respie
+ * event at the same time */
+ wireless_send_event(dev, IWEVASSOCRESPIE,
+ &wrqu, wpa_ie);
}
}
-#endif /* WIRELESS_EXT > 14 */
return;
} // wl_wext_event_assoc_ie
@@ -4025,66 +3918,39 @@ void wl_wext_event_assoc_ie( struct net_device *dev )
static const iw_handler wl_handler[] =
{
- (iw_handler) wireless_commit, /* SIOCSIWCOMMIT */
- (iw_handler) wireless_get_protocol, /* SIOCGIWNAME */
- (iw_handler) NULL, /* SIOCSIWNWID */
- (iw_handler) NULL, /* SIOCGIWNWID */
- (iw_handler) wireless_set_frequency, /* SIOCSIWFREQ */
- (iw_handler) wireless_get_frequency, /* SIOCGIWFREQ */
- (iw_handler) wireless_set_porttype, /* SIOCSIWMODE */
- (iw_handler) wireless_get_porttype, /* SIOCGIWMODE */
- (iw_handler) wireless_set_sensitivity, /* SIOCSIWSENS */
- (iw_handler) wireless_get_sensitivity, /* SIOCGIWSENS */
- (iw_handler) NULL , /* SIOCSIWRANGE */
- (iw_handler) wireless_get_range, /* SIOCGIWRANGE */
- (iw_handler) NULL , /* SIOCSIWPRIV */
- (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
- (iw_handler) NULL , /* SIOCSIWSTATS */
- (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
- iw_handler_set_spy, /* SIOCSIWSPY */
- iw_handler_get_spy, /* SIOCGIWSPY */
- NULL, /* SIOCSIWTHRSPY */
- NULL, /* SIOCGIWTHRSPY */
- (iw_handler) NULL, /* SIOCSIWAP */
+ IW_HANDLER(SIOCSIWCOMMIT, (iw_handler) wireless_commit),
+ IW_HANDLER(SIOCGIWNAME, (iw_handler) wireless_get_protocol),
+ IW_HANDLER(SIOCSIWFREQ, (iw_handler) wireless_set_frequency),
+ IW_HANDLER(SIOCGIWFREQ, (iw_handler) wireless_get_frequency),
+ IW_HANDLER(SIOCSIWMODE, (iw_handler) wireless_set_porttype),
+ IW_HANDLER(SIOCGIWMODE, (iw_handler) wireless_get_porttype),
+ IW_HANDLER(SIOCSIWSENS, (iw_handler) wireless_set_sensitivity),
+ IW_HANDLER(SIOCGIWSENS, (iw_handler) wireless_get_sensitivity),
+ IW_HANDLER(SIOCGIWRANGE, (iw_handler) wireless_get_range),
+ IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
+ IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
- (iw_handler) wireless_get_bssid, /* SIOCGIWAP */
-#else
- (iw_handler) NULL, /* SIOCGIWAP */
+ IW_HANDLER(SIOCGIWAP, (iw_handler) wireless_get_bssid),
#endif
- (iw_handler) NULL, /* SIOCSIWMLME */
- (iw_handler) wireless_get_ap_list, /* SIOCGIWAPLIST */
- (iw_handler) wireless_set_scan, /* SIOCSIWSCAN */
- (iw_handler) wireless_get_scan, /* SIOCGIWSCAN */
- (iw_handler) wireless_set_essid, /* SIOCSIWESSID */
- (iw_handler) wireless_get_essid, /* SIOCGIWESSID */
- (iw_handler) wireless_set_nickname, /* SIOCSIWNICKN */
- (iw_handler) wireless_get_nickname, /* SIOCGIWNICKN */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) wireless_set_rate, /* SIOCSIWRATE */
- (iw_handler) wireless_get_rate, /* SIOCGIWRATE */
- (iw_handler) wireless_set_rts_threshold,/* SIOCSIWRTS */
- (iw_handler) wireless_get_rts_threshold,/* SIOCGIWRTS */
- (iw_handler) NULL, /* SIOCSIWFRAG */
- (iw_handler) NULL, /* SIOCGIWFRAG */
- (iw_handler) NULL, /* SIOCSIWTXPOW */
- (iw_handler) wireless_get_tx_power, /* SIOCGIWTXPOW */
- (iw_handler) NULL, /* SIOCSIWRETRY */
- (iw_handler) NULL, /* SIOCGIWRETRY */
- (iw_handler) wireless_set_encode, /* SIOCSIWENCODE */
- (iw_handler) wireless_get_encode, /* SIOCGIWENCODE */
- (iw_handler) wireless_set_power, /* SIOCSIWPOWER */
- (iw_handler) wireless_get_power, /* SIOCGIWPOWER */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) wireless_get_genie, /* SIOCSIWGENIE */
- (iw_handler) NULL, /* SIOCGIWGENIE */
- (iw_handler) wireless_set_auth, /* SIOCSIWAUTH */
- (iw_handler) NULL, /* SIOCGIWAUTH */
- (iw_handler) wireless_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) NULL, /* SIOCGIWENCODEEXT */
- (iw_handler) NULL, /* SIOCSIWPMKSA */
- (iw_handler) NULL, /* -- hole -- */
+ IW_HANDLER(SIOCGIWAPLIST, (iw_handler) wireless_get_ap_list),
+ IW_HANDLER(SIOCSIWSCAN, (iw_handler) wireless_set_scan),
+ IW_HANDLER(SIOCGIWSCAN, (iw_handler) wireless_get_scan),
+ IW_HANDLER(SIOCSIWESSID, (iw_handler) wireless_set_essid),
+ IW_HANDLER(SIOCGIWESSID, (iw_handler) wireless_get_essid),
+ IW_HANDLER(SIOCSIWNICKN, (iw_handler) wireless_set_nickname),
+ IW_HANDLER(SIOCGIWNICKN, (iw_handler) wireless_get_nickname),
+ IW_HANDLER(SIOCSIWRATE, (iw_handler) wireless_set_rate),
+ IW_HANDLER(SIOCGIWRATE, (iw_handler) wireless_get_rate),
+ IW_HANDLER(SIOCSIWRTS, (iw_handler) wireless_set_rts_threshold),
+ IW_HANDLER(SIOCGIWRTS, (iw_handler) wireless_get_rts_threshold),
+ IW_HANDLER(SIOCGIWTXPOW, (iw_handler) wireless_get_tx_power),
+ IW_HANDLER(SIOCSIWENCODE, (iw_handler) wireless_set_encode),
+ IW_HANDLER(SIOCGIWENCODE, (iw_handler) wireless_get_encode),
+ IW_HANDLER(SIOCSIWPOWER, (iw_handler) wireless_set_power),
+ IW_HANDLER(SIOCGIWPOWER, (iw_handler) wireless_get_power),
+ IW_HANDLER(SIOCSIWGENIE, (iw_handler) wireless_set_genie),
+ IW_HANDLER(SIOCSIWAUTH, (iw_handler) wireless_set_auth),
+ IW_HANDLER(SIOCSIWENCODEEXT, (iw_handler) wireless_set_encodeext),
};
static const iw_handler wl_private_handler[] =
@@ -4120,5 +3986,3 @@ const struct iw_handler_def wl_iw_handler_def =
.standard = (iw_handler *) wl_handler,
.get_wireless_stats = wl_get_wireless_stats,
};
-
-#endif // WIRELESS_EXT