int rtllib_wx_set_wap(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *awrq, char *extra) { int ret = 0; u8 zero[] = {0, 0, 0, 0, 0, 0}; unsigned long flags; short ifup = ieee->proto_started; struct sockaddr *temp = (struct sockaddr *)awrq; rtllib_stop_scan_syncro(ieee); down(&ieee->wx_sem); /* use ifconfig hw ether */ if (ieee->iw_mode == IW_MODE_MASTER) { ret = -1; goto out; } if (temp->sa_family != ARPHRD_ETHER) { ret = -EINVAL; goto out; } if (memcmp(temp->sa_data, zero, ETH_ALEN) == 0) { spin_lock_irqsave(&ieee->lock, flags); memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); ieee->wap_set = 0; spin_unlock_irqrestore(&ieee->lock, flags); ret = -1; goto out; } if (ifup) rtllib_stop_protocol(ieee, true); /* just to avoid to give inconsistent infos in the * get wx method. not really needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); ieee->cannot_notify = false; memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); ieee->wap_set = (memcmp(temp->sa_data, zero, ETH_ALEN) != 0); spin_unlock_irqrestore(&ieee->lock, flags); if (ifup) rtllib_start_protocol(ieee); out: up(&ieee->wx_sem); return ret; }
int rtllib_wx_set_essid(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { int ret = 0, len, i; short proto_started; unsigned long flags; rtllib_stop_scan_syncro(ieee); mutex_lock(&ieee->wx_mutex); proto_started = ieee->proto_started; len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE); if (ieee->iw_mode == IW_MODE_MONITOR) { ret = -1; goto out; } for (i = 0; i < len; i++) { if (extra[i] < 0) { ret = -1; goto out; } } if (proto_started) rtllib_stop_protocol(ieee, true); /* this is just to be sure that the GET wx callback * has consistent infos. not needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); if (wrqu->essid.flags && wrqu->essid.length) { strncpy(ieee->current_network.ssid, extra, len); ieee->current_network.ssid_len = len; ieee->cannot_notify = false; ieee->ssid_set = 1; } else { ieee->ssid_set = 0; ieee->current_network.ssid[0] = '\0'; ieee->current_network.ssid_len = 0; } spin_unlock_irqrestore(&ieee->lock, flags); if (proto_started) rtllib_start_protocol(ieee); out: mutex_unlock(&ieee->wx_mutex); return ret; }
int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { int set_mode_status = 0; rtllib_stop_scan_syncro(ieee); mutex_lock(&ieee->wx_mutex); switch (wrqu->mode) { case IW_MODE_MONITOR: case IW_MODE_ADHOC: case IW_MODE_INFRA: break; case IW_MODE_AUTO: wrqu->mode = IW_MODE_INFRA; break; default: set_mode_status = -EINVAL; goto out; } if (wrqu->mode == ieee->iw_mode) goto out; if (wrqu->mode == IW_MODE_MONITOR) { ieee->dev->type = ARPHRD_IEEE80211; rtllib_EnableNetMonitorMode(ieee->dev, false); } else { ieee->dev->type = ARPHRD_ETHER; if (ieee->iw_mode == IW_MODE_MONITOR) rtllib_DisableNetMonitorMode(ieee->dev, false); } if (!ieee->proto_started) { ieee->iw_mode = wrqu->mode; } else { rtllib_stop_protocol(ieee, true); ieee->iw_mode = wrqu->mode; rtllib_start_protocol(ieee); } out: mutex_unlock(&ieee->wx_mutex); return set_mode_status; }