Commit 7d2d8259 authored by Jeff Garzik's avatar Jeff Garzik
Browse files

Merge branch 'upstream' of...

parents a47e9209 8f0f850e
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -2594,6 +2594,18 @@ P: Nicolas Pitre
M:	nico@cam.org
S:	Maintained

SOFTMAC LAYER (IEEE 802.11)
P:	Johannes Berg
M:	johannes@sipsolutions.net
P:	Joe Jezak
M:	josejx@gentoo.org
P:	Daniel Drake
M:	dsd@gentoo.org
W:	http://softmac.sipsolutions.net/
L:	softmac-dev@sipsolutions.net
L:	netdev@vger.kernel.org
S:	Maintained

SOFTWARE RAID (Multiple Disks) SUPPORT
P:	Ingo Molnar
M:	mingo@redhat.com
@@ -3302,6 +3314,15 @@ W: http://www.qsl.net/dl1bke/
L:	linux-hams@vger.kernel.org
S:	Maintained

ZD1211RW WIRELESS DRIVER
P:	Daniel Drake
M:	dsd@gentoo.org
P:	Ulrich Kunitz
M:	kune@deine-taler.de
W:	http://zd1211.ath.cx/wiki/DriverRewrite
L:	zd1211-devs@lists.sourceforge.net (subscribers-only)
S:	Maintained

ZF MACHZ WATCHDOG
P:	Fernando Fuganti
M:	fuganti@netbank.com.br
+5 −7
Original line number Diff line number Diff line
@@ -3950,13 +3950,11 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
	pRsp->rsp0 = IN4500(ai, RESP0);
	pRsp->rsp1 = IN4500(ai, RESP1);
	pRsp->rsp2 = IN4500(ai, RESP2);
	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
		airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd);
		airo_print_err(ai->dev->name, "status= %x\n", pRsp->status);
		airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0);
		airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1);
		airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2);
	}
	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
		airo_print_err(ai->dev->name,
			"cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
			pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
			pRsp->rsp2);

	// clear stuck command busy if necessary
	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
+4 −25
Original line number Diff line number Diff line
@@ -2667,7 +2667,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)

	IPW_DEBUG_FW(">> :\n");

	//set the Stop and Abort bit
	/* set the Stop and Abort bit */
	control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
	ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
	priv->sram_desc.last_cb_index = 0;
@@ -3002,8 +3002,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
	if (rc < 0)
		return rc;

//      spin_lock_irqsave(&priv->lock, flags);

	for (addr = IPW_SHARED_LOWER_BOUND;
	     addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
		ipw_write32(priv, addr, 0);
@@ -3097,8 +3095,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
	   firmware have problem getting alive resp. */
	ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);

//      spin_unlock_irqrestore(&priv->lock, flags);

	return rc;
}

@@ -6387,13 +6383,6 @@ static int ipw_wx_set_genie(struct net_device *dev,
	    (wrqu->data.length && extra == NULL))
		return -EINVAL;

	//mutex_lock(&priv->mutex);

	//if (!ieee->wpa_enabled) {
	//      err = -EOPNOTSUPP;
	//      goto out;
	//}

	if (wrqu->data.length) {
		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
		if (buf == NULL) {
@@ -6413,7 +6402,6 @@ static int ipw_wx_set_genie(struct net_device *dev,

	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
      out:
	//mutex_unlock(&priv->mutex);
	return err;
}

@@ -6426,13 +6414,6 @@ static int ipw_wx_get_genie(struct net_device *dev,
	struct ieee80211_device *ieee = priv->ieee;
	int err = 0;

	//mutex_lock(&priv->mutex);

	//if (!ieee->wpa_enabled) {
	//      err = -EOPNOTSUPP;
	//      goto out;
	//}

	if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
		wrqu->data.length = 0;
		goto out;
@@ -6447,7 +6428,6 @@ static int ipw_wx_get_genie(struct net_device *dev,
	memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);

      out:
	//mutex_unlock(&priv->mutex);
	return err;
}

@@ -6558,7 +6538,6 @@ static int ipw_wx_set_auth(struct net_device *dev,
		ieee->ieee802_1x = param->value;
		break;

		//case IW_AUTH_ROAMING_CONTROL:
	case IW_AUTH_PRIVACY_INVOKED:
		ieee->privacy_invoked = param->value;
		break;
@@ -6680,7 +6659,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,

	switch (mlme->cmd) {
	case IW_MLME_DEAUTH:
		// silently ignore
		/* silently ignore */
		break;

	case IW_MLME_DISASSOC:
@@ -9766,7 +9745,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
	return 0;
}

#endif				// CONFIG_IPW2200_MONITOR
#endif				/* CONFIG_IPW2200_MONITOR */

static int ipw_wx_reset(struct net_device *dev,
			struct iw_request_info *info,
@@ -10009,7 +9988,7 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
	sys_config->dot11g_auto_detection = 0;
	sys_config->enable_cts_to_self = 0;
	sys_config->bt_coexist_collision_thr = 0;
	sys_config->pass_noise_stats_to_host = 1;	//1 -- fix for 256
	sys_config->pass_noise_stats_to_host = 1;	/* 1 -- fix for 256 */
	sys_config->silence_threshold = 0x1e;
}

+536 −37
Original line number Diff line number Diff line
@@ -35,10 +35,14 @@

#include <net/iw_handler.h>	/* New driver API */

#define KEY_SIZE_WEP104 13	/* 104/128-bit WEP keys */
#define KEY_SIZE_WEP40  5	/* 40/64-bit WEP keys */
/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
#define KEY_SIZE_TKIP   32	/* TKIP keys */

static void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
				u8 *wpa_ie, size_t wpa_ie_len);
static size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
static int prism54_set_wpa(struct net_device *, struct iw_request_info *,
				__u32 *, char *);

@@ -468,6 +472,9 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
	range->event_capa[1] = IW_EVENT_CAPA_K_1;
	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);

	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
		IW_ENC_CAPA_CIPHER_TKIP;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

@@ -567,6 +574,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
	struct iw_event iwe;	/* Temporary buffer */
	short cap;
	islpci_private *priv = netdev_priv(ndev);
	u8 wpa_ie[MAX_WPA_IE_LEN];
	size_t wpa_ie_len;

	/* The first entry must be the MAC address */
	memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
@@ -627,27 +636,13 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
	current_ev =
	    iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);

	if (priv->wpa) {
		u8 wpa_ie[MAX_WPA_IE_LEN];
		char *buf, *p;
		size_t wpa_ie_len;
		int i;

		wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie);
		if (wpa_ie_len > 0 &&
		    (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) {
			p = buf;
			p += sprintf(p, "wpa_ie=");
			for (i = 0; i < wpa_ie_len; i++) {
				p += sprintf(p, "%02x", wpa_ie[i]);
			}
			memset(&iwe, 0, sizeof (iwe));
			iwe.cmd = IWEVCUSTOM;
			iwe.u.data.length = strlen(buf);
	/* Add WPA/RSN Information Element, if any */
	wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
	if (wpa_ie_len > 0) {
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
		current_ev = iwe_stream_add_point(current_ev, end_buf,
							  &iwe, buf);
			kfree(buf);
		}
				&iwe, wpa_ie);
	}
	return current_ev;
}
@@ -1051,12 +1046,24 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
		current_index = r.u;
		/* Verify that the key is not marked as invalid */
		if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
			key.length = dwrq->length > sizeof (key.key) ?
			    sizeof (key.key) : dwrq->length;
			memcpy(key.key, extra, key.length);
			if (key.length == 32)
				/* we want WPA-PSK */
			if (dwrq->length > KEY_SIZE_TKIP) {
				/* User-provided key data too big */
				return -EINVAL;
			}
			if (dwrq->length > KEY_SIZE_WEP104) {
				/* WPA-PSK TKIP */
				key.type = DOT11_PRIV_TKIP;
				key.length = KEY_SIZE_TKIP;
			} else if (dwrq->length > KEY_SIZE_WEP40) {
				/* WEP 104/128 */
				key.length = KEY_SIZE_WEP104;
			} else {
				/* WEP 40/64 */
				key.length = KEY_SIZE_WEP40;
			}
			memset(key.key, 0, sizeof (key.key));
			memcpy(key.key, extra, dwrq->length);

			if ((index < 0) || (index > 3))
				/* no index provided use the current one */
				index = current_index;
@@ -1210,6 +1217,489 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
	}
}

static int prism54_set_genie(struct net_device *ndev,
			     struct iw_request_info *info,
			     struct iw_point *data, char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	int alen, ret = 0;
	struct obj_attachment *attach;

	if (data->length > MAX_WPA_IE_LEN ||
	    (data->length && extra == NULL))
		return -EINVAL;

	memcpy(priv->wpa_ie, extra, data->length);
	priv->wpa_ie_len = data->length;

	alen = sizeof(*attach) + priv->wpa_ie_len;
	attach = kzalloc(alen, GFP_KERNEL);
	if (attach == NULL)
		return -ENOMEM;

#define WLAN_FC_TYPE_MGMT 0
#define WLAN_FC_STYPE_ASSOC_REQ 0
#define WLAN_FC_STYPE_REASSOC_REQ 2

	/* Note: endianness is covered by mgt_set_varlen */
	attach->type = (WLAN_FC_TYPE_MGMT << 2) |
               (WLAN_FC_STYPE_ASSOC_REQ << 4);
	attach->id = -1;
	attach->size = priv->wpa_ie_len;
	memcpy(attach->data, extra, priv->wpa_ie_len);

	ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
		priv->wpa_ie_len);
	if (ret == 0) {
		attach->type = (WLAN_FC_TYPE_MGMT << 2) |
			(WLAN_FC_STYPE_REASSOC_REQ << 4);

		ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
			priv->wpa_ie_len);
		if (ret == 0)
			printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
				ndev->name);
	}

	kfree(attach);
	return ret;
}


static int prism54_get_genie(struct net_device *ndev,
			     struct iw_request_info *info,
			     struct iw_point *data, char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	int len = priv->wpa_ie_len;

	if (len <= 0) {
		data->length = 0;
		return 0;
	}

	if (data->length < len)
		return -E2BIG;

	data->length = len;
	memcpy(extra, priv->wpa_ie, len);

	return 0;
}

static int prism54_set_auth(struct net_device *ndev,
			       struct iw_request_info *info,
			       union iwreq_data *wrqu, char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	struct iw_param *param = &wrqu->param;
	u32 mlmelevel = 0, authen = 0, dot1x = 0;
	u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
	u32 old_wpa;
	int ret = 0;
	union oid_res_t r;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	/* first get the flags */
	down_write(&priv->mib_sem);
	wpa = old_wpa = priv->wpa;
	up_write(&priv->mib_sem);
	ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
	authen = r.u;
	ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
	privinvoked = r.u;
	ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
	exunencrypt = r.u;
	ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
	dot1x = r.u;
	ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
	mlmelevel = r.u;

	if (ret < 0)
		goto out;

	switch (param->flags & IW_AUTH_INDEX) {
	case IW_AUTH_CIPHER_PAIRWISE:
	case IW_AUTH_CIPHER_GROUP:
	case IW_AUTH_KEY_MGMT:
		break;

	case IW_AUTH_WPA_ENABLED:
		/* Do the same thing as IW_AUTH_WPA_VERSION */
		if (param->value) {
			wpa = 1;
			privinvoked = 1; /* For privacy invoked */
			exunencrypt = 1; /* Filter out all unencrypted frames */
			dot1x = 0x01; /* To enable eap filter */
			mlmelevel = DOT11_MLME_EXTENDED;
			authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
		} else {
			wpa = 0;
			privinvoked = 0;
			exunencrypt = 0; /* Do not filter un-encrypted data */
			dot1x = 0;
			mlmelevel = DOT11_MLME_AUTO;
		}
		break;

	case IW_AUTH_WPA_VERSION:
		if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
			wpa = 0;
			privinvoked = 0;
			exunencrypt = 0; /* Do not filter un-encrypted data */
			dot1x = 0;
			mlmelevel = DOT11_MLME_AUTO;
		} else {
			if (param->value & IW_AUTH_WPA_VERSION_WPA)
				wpa = 1;
			else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
				wpa = 2;
			privinvoked = 1; /* For privacy invoked */
			exunencrypt = 1; /* Filter out all unencrypted frames */
			dot1x = 0x01; /* To enable eap filter */
			mlmelevel = DOT11_MLME_EXTENDED;
			authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
		}
		break;

	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
		dot1x = param->value ? 1 : 0;
		break;

	case IW_AUTH_PRIVACY_INVOKED:
		privinvoked = param->value ? 1 : 0;

	case IW_AUTH_DROP_UNENCRYPTED:
		exunencrypt = param->value ? 1 : 0;
		break;

	case IW_AUTH_80211_AUTH_ALG:
		if (param->value & IW_AUTH_ALG_SHARED_KEY) {
			/* Only WEP uses _SK and _BOTH */
			if (wpa > 0) {
				ret = -EINVAL;
				goto out;
			}
			authen = DOT11_AUTH_SK;
		} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
			authen = DOT11_AUTH_OS;
		} else {
			ret = -EINVAL;
			goto out;
		}
		break;

	default:
		return -EOPNOTSUPP;
	}

	/* Set all the values */
	down_write(&priv->mib_sem);
	priv->wpa = wpa;
	up_write(&priv->mib_sem);
	mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
	mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
	mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
	mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
	mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);

out:
	return ret;
}

static int prism54_get_auth(struct net_device *ndev,
			    struct iw_request_info *info,
			    union iwreq_data *wrqu, char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	struct iw_param *param = &wrqu->param;
	u32 wpa = 0;
	int ret = 0;
	union oid_res_t r;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	/* first get the flags */
	down_write(&priv->mib_sem);
	wpa = priv->wpa;
	up_write(&priv->mib_sem);

	switch (param->flags & IW_AUTH_INDEX) {
	case IW_AUTH_CIPHER_PAIRWISE:
	case IW_AUTH_CIPHER_GROUP:
	case IW_AUTH_KEY_MGMT:
		/*
		 * wpa_supplicant will control these internally
		 */
		ret = -EOPNOTSUPP;
		break;

	case IW_AUTH_WPA_VERSION:
		switch (wpa) {
		case 1:
			param->value = IW_AUTH_WPA_VERSION_WPA;
			break;
		case 2:
			param->value = IW_AUTH_WPA_VERSION_WPA2;
			break;
		case 0:
		default:
			param->value = IW_AUTH_WPA_VERSION_DISABLED;
			break;
		}
		break;

	case IW_AUTH_DROP_UNENCRYPTED:
		ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
		if (ret >= 0)
			param->value = r.u > 0 ? 1 : 0;
		break;

	case IW_AUTH_80211_AUTH_ALG:
		ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
		if (ret >= 0) {
			switch (r.u) {
			case DOT11_AUTH_OS:
				param->value = IW_AUTH_ALG_OPEN_SYSTEM;
				break;
			case DOT11_AUTH_BOTH:
			case DOT11_AUTH_SK:
				param->value = IW_AUTH_ALG_SHARED_KEY;
			case DOT11_AUTH_NONE:
			default:
				param->value = 0;
				break;
			}
		}
		break;

	case IW_AUTH_WPA_ENABLED:
		param->value = wpa > 0 ? 1 : 0;
		break;

	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
		ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
		if (ret >= 0)
			param->value = r.u > 0 ? 1 : 0;
		break;

	case IW_AUTH_PRIVACY_INVOKED:
		ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
		if (ret >= 0)
			param->value = r.u > 0 ? 1 : 0;
		break;

	default:
		return -EOPNOTSUPP;
	}
	return ret;
}

static int prism54_set_encodeext(struct net_device *ndev,
				 struct iw_request_info *info,
				 union iwreq_data *wrqu,
				 char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	struct iw_point *encoding = &wrqu->encoding;
	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
	int idx, alg = ext->alg, set_key = 1;
	union oid_res_t r;
	int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
	int ret = 0;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	/* Determine and validate the key index */
	idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
	if (idx) {
		if (idx < 0 || idx > 3)
			return -EINVAL;
	} else {
		ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
		if (ret < 0)
			goto out;
		idx = r.u;
	}

	if (encoding->flags & IW_ENCODE_DISABLED)
		alg = IW_ENCODE_ALG_NONE;

	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
		/* Only set transmit key index here, actual
		 * key is set below if needed.
		 */
		ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
		set_key = ext->key_len > 0 ? 1 : 0;
	}

	if (set_key) {
		struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
		switch (alg) {
		case IW_ENCODE_ALG_NONE:
			break;
		case IW_ENCODE_ALG_WEP:
			if (ext->key_len > KEY_SIZE_WEP104) {
				ret = -EINVAL;
				goto out;
			}
			if (ext->key_len > KEY_SIZE_WEP40)
				key.length = KEY_SIZE_WEP104;
			else
				key.length = KEY_SIZE_WEP40;
			break;
		case IW_ENCODE_ALG_TKIP:
			if (ext->key_len > KEY_SIZE_TKIP) {
				ret = -EINVAL;
				goto out;
			}
			key.type = DOT11_PRIV_TKIP;
			key.length = KEY_SIZE_TKIP;
		default:
			return -EINVAL;
		}

		if (key.length) {
			memset(key.key, 0, sizeof(key.key));
			memcpy(key.key, ext->key, ext->key_len);
			ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
					    &key);
			if (ret < 0)
				goto out;
		}
	}

	/* Read the flags */
	if (encoding->flags & IW_ENCODE_DISABLED) {
		/* Encoding disabled,
		 * authen = DOT11_AUTH_OS;
		 * invoke = 0;
		 * exunencrypt = 0; */
	}
	if (encoding->flags & IW_ENCODE_OPEN) {
		/* Encode but accept non-encoded packets. No auth */
		invoke = 1;
	}
	if (encoding->flags & IW_ENCODE_RESTRICTED) {
		/* Refuse non-encoded packets. Auth */
		authen = DOT11_AUTH_BOTH;
		invoke = 1;
		exunencrypt = 1;
	}

	/* do the change if requested  */
	if (encoding->flags & IW_ENCODE_MODE) {
		ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
				      &authen);
		ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
				      &invoke);
		ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
				      &exunencrypt);
	}

out:
	return ret;
}


static int prism54_get_encodeext(struct net_device *ndev,
				 struct iw_request_info *info,
				 union iwreq_data *wrqu,
				 char *extra)
{
	islpci_private *priv = netdev_priv(ndev);
	struct iw_point *encoding = &wrqu->encoding;
	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
	int idx, max_key_len;
	union oid_res_t r;
	int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
	int ret = 0;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	/* first get the flags */
	ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
	authen = r.u;
	ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
	invoke = r.u;
	ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
	exunencrypt = r.u;
	if (ret < 0)
		goto out;

	max_key_len = encoding->length - sizeof(*ext);
	if (max_key_len < 0)
		return -EINVAL;

	idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
	if (idx) {
		if (idx < 0 || idx > 3)
			return -EINVAL;
	} else {
		ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
		if (ret < 0)
			goto out;
		idx = r.u;
	}

	encoding->flags = idx + 1;
	memset(ext, 0, sizeof(*ext));

	switch (authen) {
	case DOT11_AUTH_BOTH:
	case DOT11_AUTH_SK:
		wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
	case DOT11_AUTH_OS:
	default:
		wrqu->encoding.flags |= IW_ENCODE_OPEN;
		break;
	}

	down_write(&priv->mib_sem);
	wpa = priv->wpa;
	up_write(&priv->mib_sem);

	if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
		/* No encryption */
		ext->alg = IW_ENCODE_ALG_NONE;
		ext->key_len = 0;
		wrqu->encoding.flags |= IW_ENCODE_DISABLED;
	} else {
		struct obj_key *key;

		ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
		if (ret < 0)
			goto out;
		key = r.ptr;
		if (max_key_len < key->length) {
			ret = -E2BIG;
			goto out;
		}
		memcpy(ext->key, key->key, key->length);
		ext->key_len = key->length;

		switch (key->type) {
		case DOT11_PRIV_TKIP:
			ext->alg = IW_ENCODE_ALG_TKIP;
			break;
		default:
		case DOT11_PRIV_WEP:
			ext->alg = IW_ENCODE_ALG_WEP;
			break;
		}
		wrqu->encoding.flags |= IW_ENCODE_ENABLED;
	}

out:
	return ret;
}


static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
	      __u32 * uwrq, char *extra)
@@ -1591,7 +2081,7 @@ static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"

static void
prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
		       u8 *wpa_ie, size_t wpa_ie_len)
{
	struct list_head *ptr;
@@ -1658,7 +2148,7 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
}

static size_t
prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
{
	struct list_head *ptr;
	struct islpci_bss_wpa_ie *bss = NULL;
@@ -1683,14 +2173,14 @@ prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
}

void
prism54_wpa_ie_init(islpci_private *priv)
prism54_wpa_bss_ie_init(islpci_private *priv)
{
	INIT_LIST_HEAD(&priv->bss_wpa_list);
	sema_init(&priv->wpa_sem, 1);
}

void
prism54_wpa_ie_clean(islpci_private *priv)
prism54_wpa_bss_ie_clean(islpci_private *priv)
{
	struct list_head *ptr, *n;

@@ -1722,7 +2212,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
		}
		if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
		    memcmp(pos + 2, wpa_oid, 4) == 0) {
			prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2);
			prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
			return;
		}
		pos += 2 + pos[1];
@@ -1879,7 +2369,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
		send_formatted_event(priv, "Associate request (ex)", mlme, 1);

		if (priv->iw_mode != IW_MODE_MASTER 
				&& mlmeex->state != DOT11_STATE_AUTHING)
				&& mlmeex->state != DOT11_STATE_ASSOCING)
			break;
		
		confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
@@ -1893,7 +2383,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
		confirm->state = 0; /* not used */
		confirm->code = 0;

		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
		wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);

		if (!wpa_ie_len) {
			printk(KERN_DEBUG "No WPA IE found from "
@@ -1937,7 +2427,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
		confirm->state = 0; /* not used */
		confirm->code = 0;

		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
		wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);

		if (!wpa_ie_len) {
			printk(KERN_DEBUG "No WPA IE found from "
@@ -2553,6 +3043,15 @@ static const iw_handler prism54_handler[] = {
	(iw_handler) prism54_get_encode,	/* SIOCGIWENCODE */
	(iw_handler) NULL,	/* SIOCSIWPOWER */
	(iw_handler) NULL,	/* SIOCGIWPOWER */
	NULL,			/* -- hole -- */
	NULL,			/* -- hole -- */
	(iw_handler) prism54_set_genie,	/* SIOCSIWGENIE */
	(iw_handler) prism54_get_genie,	/* SIOCGIWGENIE */
	(iw_handler) prism54_set_auth,	/* SIOCSIWAUTH */
	(iw_handler) prism54_get_auth,	/* SIOCGIWAUTH */
	(iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
	(iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
	NULL,			/* SIOCSIWPMKSA */
};

/* The low order bit identify a SET (0) or a GET (1) ioctl.  */
+3 −3
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@

#include <net/iw_handler.h>	/* New driver API */

#define SUPPORTED_WIRELESS_EXT                  16
#define SUPPORTED_WIRELESS_EXT                  19

void prism54_mib_init(islpci_private *);

@@ -39,8 +39,8 @@ void prism54_acl_clean(struct islpci_acl *);

void prism54_process_trap(void *);

void prism54_wpa_ie_init(islpci_private *priv);
void prism54_wpa_ie_clean(islpci_private *priv);
void prism54_wpa_bss_ie_init(islpci_private *priv);
void prism54_wpa_bss_ie_clean(islpci_private *priv);

int prism54_set_mac_address(struct net_device *, void *);

Loading