Example #1
0
static void handle_info_queue_linkstatus(local_info_t *local)
{
	int val = local->prev_link_status;
	int connected;
	union iwreq_data wrqu;

	connected =
		val == HFA384X_LINKSTATUS_CONNECTED ||
		val == HFA384X_LINKSTATUS_AP_CHANGE ||
		val == HFA384X_LINKSTATUS_AP_IN_RANGE;

	if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID,
				 local->bssid, ETH_ALEN, 1) < 0) {
		printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
		       "LinkStatus event\n", local->dev->name);
	} else {
		PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=%pM\n",
		       local->dev->name,
		       (unsigned char *) local->bssid);
		if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
			hostap_add_sta(local->ap, local->bssid);
	}

	/* Get BSSID if we have a valid AP address */

	if ( val == HFA384X_LINKSTATUS_CONNECTED ||
	     val == HFA384X_LINKSTATUS_DISCONNECTED )
			hostap_restore_power(local->dev);

	if (connected) {
		netif_carrier_on(local->dev);
		netif_carrier_on(local->ddev);
		memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN);
	} else {
		netif_carrier_off(local->dev);
		netif_carrier_off(local->ddev);
		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
	}
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;

	/*
	 * Filter out sequential disconnect events in order not to cause a
	 * flood of SIOCGIWAP events that have a race condition with EAPOL
	 * frames and can confuse wpa_supplicant about the current association
	 * status.
	 */
	if (connected || local->prev_linkstatus_connected)
		wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
	local->prev_linkstatus_connected = connected;
}
Example #2
0
static void handle_info_queue_linkstatus(local_info_t *local)
{
	int val = local->prev_link_status;
	int connected;

	connected =
		val == HFA384X_LINKSTATUS_CONNECTED ||
		val == HFA384X_LINKSTATUS_AP_CHANGE ||
		val == HFA384X_LINKSTATUS_AP_IN_RANGE;

	if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID,
				 local->bssid, ETH_ALEN, 1) < 0) {
		printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
		       "LinkStatus event\n", local->dev->name);
	} else {
		PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n",
		       local->dev->name,
		       MAC2STR((unsigned char *) local->bssid));
		if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
			hostap_add_sta(local->ap, local->bssid);
	}

#if WIRELESS_EXT > 13
	{
		union iwreq_data wrqu;

		/* Get BSSID if we have a valid AP address */
		if (connected)
			memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN);
		else
			memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
		wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
	}
#endif /* WIRELESS_EXT > 13 */
}
Example #3
0
int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
{
	struct viawget_hostapd_param *param;
	int ret = 0;
	int ap_ioctl = 0;

	if (p->length < sizeof(struct viawget_hostapd_param) ||
	    p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
		return -EINVAL;

	param = kmalloc((int)p->length, (int)GFP_KERNEL);
	if (param == NULL)
		return -ENOMEM;

	if (copy_from_user(param, p->pointer, p->length)) {
		ret = -EFAULT;
		goto out;
	}

	switch (param->cmd) {
	case VIAWGET_HOSTAPD_SET_ENCRYPTION:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
        spin_lock_irq(&pDevice->lock);
		ret = hostap_set_encryption(pDevice, param, p->length);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_GET_ENCRYPTION:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
        spin_lock_irq(&pDevice->lock);
		ret = hostap_get_encryption(pDevice, param, p->length);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
		return -EOPNOTSUPP;
		break;
	case VIAWGET_HOSTAPD_FLUSH:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
        spin_lock_irq(&pDevice->lock);
    	hostap_flush_sta(pDevice);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_ADD_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
         spin_lock_irq(&pDevice->lock);
		 ret = hostap_add_sta(pDevice, param);
         spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_REMOVE_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
         spin_lock_irq(&pDevice->lock);
		 ret = hostap_remove_sta(pDevice, param);
         spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_GET_INFO_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
		 ret = hostap_get_info_sta(pDevice, param);
		 ap_ioctl = 1;
		break;
/*
	case VIAWGET_HOSTAPD_RESET_TXEXC_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
		 ret = hostap_reset_txexc_sta(pDevice, param);
		break;
*/
	case VIAWGET_HOSTAPD_SET_FLAGS_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
		 ret = hostap_set_flags_sta(pDevice, param);
		break;

	case VIAWGET_HOSTAPD_MLME:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
	    return -EOPNOTSUPP;

	case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
		ret = hostap_set_generic_element(pDevice, param);
		break;

	case VIAWGET_HOSTAPD_SCAN_REQ:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
	    return -EOPNOTSUPP;

	case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
	    return -EOPNOTSUPP;

	default:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n",
		       (int)param->cmd);
		return -EOPNOTSUPP;
		break;
	}


	if ((ret == 0) && ap_ioctl) {
		if (copy_to_user(p->pointer, param, p->length)) {
			ret = -EFAULT;
			goto out;
		}
	}

 out:
	if (param != NULL)
		kfree(param);

	return ret;
}
Example #4
0
static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
			  int rtnl_locked)
{
	prism2_wds_info_t *wds, *wds2 = NULL;
	unsigned long flags;
	int i, ret;

	spin_lock_irqsave(&local->wdslock, flags);
	wds = local->wds;
	while (wds != NULL &&
	       memcmp(wds->remote_addr, remote_addr, ETH_ALEN) != 0) {
		if (!wds2 && prism2_wds_special_addr(wds->remote_addr))
			wds2 = wds;
		wds = wds->next;
	}
	if (!wds && wds2) {
		/* take pre-allocated entry into use */
		memcpy(wds2->remote_addr, remote_addr, ETH_ALEN);
	}
	spin_unlock_irqrestore(&local->wdslock, flags);

	if (!prism2_wds_special_addr(remote_addr)) {
		if (wds)
			return -EEXIST;
		hostap_add_sta(local->ap, remote_addr);
	}

	if (!wds && wds2) {
		printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n",
		       local->dev->name, wds2->dev.name);
		return 0;
	}

	if (local->wds_connections >= local->wds_max_connections)
		return -ENOBUFS;

	/* verify that there is room for wds# postfix in the interface name */
	if (strlen(local->dev->name) > IFNAMSIZ - 5) {
		printk(KERN_DEBUG "'%s' too long base device name\n",
		       local->dev->name);
		return -EINVAL;
	}

	wds = (prism2_wds_info_t *) kmalloc(sizeof(*wds) + PRISM2_NETDEV_EXTRA,
					    GFP_ATOMIC);
	if (wds == NULL)
		return -ENOMEM;

	memset(wds, 0, sizeof(*wds) + PRISM2_NETDEV_EXTRA);
	prism2_set_dev_name(&wds->dev, wds + 1);

	memcpy(wds->remote_addr, remote_addr, ETH_ALEN);

	hostap_setup_dev(&wds->dev, local, 0);

	wds->dev.priv = local;
	memcpy(wds->dev.dev_addr, local->dev->dev_addr, ETH_ALEN);
	wds->dev.base_addr = local->dev->base_addr;
	wds->dev.irq = local->dev->irq;
	wds->dev.mem_start = local->dev->mem_start;
	wds->dev.mem_end = local->dev->mem_end;

	i = 0;
	do {
		sprintf(wds->dev.name, "%swds%d", local->dev->name, i++);
	} while (i < 10000 && dev_get(wds->dev.name));

	if (rtnl_locked)
		ret = register_netdevice(&wds->dev);
	else
		ret = register_netdev(&wds->dev);

	if (ret) {
		printk(KERN_WARNING "%s: registering WDS device '%s' failed\n",
		       local->dev->name, wds->dev.name);
		kfree(wds);
		return -EINVAL;
	}

	spin_lock_irqsave(&local->wdslock, flags);
	local->wds_connections++;
	wds->next = local->wds;
	local->wds = wds;
	spin_unlock_irqrestore(&local->wdslock, flags);

	printk(KERN_DEBUG "%s: registered WDS netdevice %s\n",
	       local->dev->name, wds->dev.name);

	return 0;
}