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; }
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 */ }
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; }
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; }