📄 wvlan_cs.c
字号:
// Re-Enable hardware rc = hcf_action(&local->ifb, HCF_ACT_INT_ON); DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_INT_ON) returned 0x%x\n", dev_info, rc); rc = hcf_enable(&local->ifb, 0); DEBUG(DEBUG_NOISY, "%s: hcf_enable(0) returned 0x%x\n", dev_info, rc); DEBUG(DEBUG_CALLTRACE, "<- wvlan_hw_reset()\n"); return rc;}/******************************************************************** * NET STATS / IOCTL */struct net_device_stats *wvlan_get_stats (struct net_device *dev){ DEBUG(DEBUG_CALLTRACE, "<> wvlan_get_stats(%s)\n", dev->name); return(&((struct net_local *) dev->priv)->stats);}#ifdef WIRELESS_EXTint wvlan_ioctl (struct net_device *dev, struct ifreq *rq, int cmd){ struct net_local *local = (struct net_local *) dev->priv; struct iwreq *wrq = (struct iwreq *) rq; unsigned long flags; int rc = 0; DEBUG(DEBUG_CALLTRACE, "-> wvlan_ioctl(%s, cmd=0x%x)\n", dev->name, cmd); // Disable interrupts wv_driver_lock(local, &flags); switch (cmd) { // Get name case SIOCGIWNAME: strcpy(wrq->u.name, "IEEE 802.11-DS"); break; // Set frequency/channel case SIOCSIWFREQ: // If setting by frequency, convert to a channel if((wrq->u.freq.e == 1) && (wrq->u.freq.m >= (int) 2.412e8) && (wrq->u.freq.m <= (int) 2.487e8)) { int f = wrq->u.freq.m / 100000; int c = 0; while((c < 14) && (f != frequency_list[c])) c++; // Hack to fall through... wrq->u.freq.e = 0; wrq->u.freq.m = c + 1; } // Setting by channel number if (((local->port_type != 3) && (!local->allow_ibss)) || (wrq->u.freq.m > 1000) || (wrq->u.freq.e > 0)) rc = -EOPNOTSUPP; else { int channel = wrq->u.freq.m; int chlist = wvlan_hw_getchannellist(&local->ifb); if (channel<1 || channel>16 || !(1<<(channel-1) & chlist)) { DEBUG(DEBUG_INFO, "%s: New channel value of %d for %s is invalid!\n", dev_info, wrq->u.freq.m, dev->name); rc = -EINVAL; } else { local->channel = wrq->u.freq.m; local->need_commit = 1; } } break; // Get frequency/channel case SIOCGIWFREQ:#ifdef WEXT_USECHANNELS wrq->u.freq.m = wvlan_hw_getcurrentchannel(&local->ifb); wrq->u.freq.e = 0;#else { int f = wvlan_hw_getcurrentchannel(&local->ifb); wrq->u.freq.m = frequency_list[f-1] * 100000; wrq->u.freq.e = 1; }#endif break; // Set desired network name (ESSID) case SIOCSIWESSID: if (wrq->u.data.pointer) { char essid[IW_ESSID_MAX_SIZE + 1]; /* Check if we asked for `any' */ if(wrq->u.data.flags == 0) { essid[0] = '\0'; } else { /* Check the size of the string */ if(wrq->u.data.length > IW_ESSID_MAX_SIZE + 1) { rc = -E2BIG; break; } wv_driver_unlock(local, &flags); rc = copy_from_user(essid, wrq->u.data.pointer, wrq->u.data.length); wv_driver_lock(local, &flags); if (rc) { rc = -EFAULT; break; } essid[IW_ESSID_MAX_SIZE] = '\0'; } strncpy(local->network_name, essid, sizeof(local->network_name)-1); local->need_commit = 1; } break; // Get current network name (ESSID) case SIOCGIWESSID: if (wrq->u.data.pointer) { char essid[IW_ESSID_MAX_SIZE + 1]; /* Get the essid that was set */ wvlan_hw_getssid(&local->ifb, essid, IW_ESSID_MAX_SIZE, WVLAN_DESIRED, local->port_type); /* If it was set to any, get the current one */ if(strlen(essid) == 0) wvlan_hw_getssid(&local->ifb, essid, IW_ESSID_MAX_SIZE, WVLAN_CURRENT, local->port_type); /* Push it out ! */ wrq->u.data.length = strlen(essid) + 1; wrq->u.data.flags = 1; /* active */ wv_driver_unlock(local, &flags); rc = copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)); wv_driver_lock(local, &flags); if (rc) rc = -EFAULT; } break; // Get current Access Point (BSSID) case SIOCGIWAP: wvlan_hw_getbssid(&local->ifb, wrq->u.ap_addr.sa_data, ETH_ALEN); wrq->u.ap_addr.sa_family = ARPHRD_ETHER; break;#if WIRELESS_EXT > 7 // Set desired station name case SIOCSIWNICKN: if (wrq->u.data.pointer) { char name[IW_ESSID_MAX_SIZE + 1]; /* Check the size of the string */ if(wrq->u.data.length > IW_ESSID_MAX_SIZE + 1) { rc = -E2BIG; break; } wv_driver_unlock(local, &flags); rc = copy_from_user(name, wrq->u.data.pointer, wrq->u.data.length); wv_driver_lock(local, &flags); if (rc) { rc = -EFAULT; break; } name[IW_ESSID_MAX_SIZE] = '\0'; strncpy(local->station_name, name, sizeof(local->station_name)-1); local->need_commit = 1; } break; // Get current station name case SIOCGIWNICKN: if (wrq->u.data.pointer) { char name[IW_ESSID_MAX_SIZE + 1]; wvlan_hw_getstationname(&local->ifb, name, IW_ESSID_MAX_SIZE); wrq->u.data.length = strlen(name) + 1; wv_driver_unlock(local, &flags); rc = copy_to_user(wrq->u.data.pointer, name, sizeof(name)); wv_driver_lock(local, &flags); if (rc) rc = -EFAULT; } break; // Set the desired bit-rate case SIOCSIWRATE: { // Start the magic... char brlist[9]; int brnum = wvlan_hw_getratelist(&local->ifb, brlist, sizeof(brlist)); int brate = wrq->u.bitrate.value/500000; int wvrate = 0; // Auto or fixed ? if(wrq->u.bitrate.fixed == 0) { // Is there a valid value ? if(wrq->u.bitrate.value == -1) wvrate = 3; else { // Setting by rate value // Find index in magic table while((rate_list[wvrate] != -brate) && (wvrate < (brnum * 2))) wvrate++; } } else if((wrq->u.bitrate.value <= (brnum * 2 - 1)) && (wrq->u.bitrate.value > 0)) { // Setting by rate index wvrate = wrq->u.bitrate.value; } else { // Setting by rate value // Find index in magic table while((rate_list[wvrate] != brate) && (wvrate < (brnum * 2))) wvrate++; } // Check if in range if((wvrate < 1) || (wvrate >= (brnum * 2))) { rc = -EINVAL; break; } local->transmit_rate = wvrate; local->need_commit = 1; break; } // Get the current bit-rate case SIOCGIWRATE: { int wvrate = wvlan_hw_getbitrate(&local->ifb, WVLAN_DESIRED); int brate = rate_list[wvrate]; // Auto ? if (brate < 0) { wrq->u.bitrate.fixed = 0; wvrate = wvlan_hw_getbitrate(&local->ifb, WVLAN_CURRENT); brate = 2 * wvrate; // Mandatory kludge! if (wvrate == 6) brate = 11; } else wrq->u.bitrate.fixed = 1; wrq->u.bitrate.value = brate * 500000;#if WIRELESS_EXT > 8 wrq->u.bitrate.disabled = 0;#endif } break; // Set the desired AP density case SIOCSIWSENS: { int dens = wrq->u.sens.value; if((dens < 1) || (dens > 3)) { rc = -EINVAL; break; } local->ap_density = dens; local->need_commit = 1; } break; // Get the current AP density case SIOCGIWSENS: wrq->u.sens.value = wvlan_hw_getthreshold(&local->ifb, CFG_CNF_SYSTEM_SCALE); wrq->u.sens.fixed = 0; /* auto */ break;#endif /* WIRELESS_EXT > 7 */#if WIRELESS_EXT > 8 // Set the desired RTS threshold case SIOCSIWRTS: { int rthr = wrq->u.rts.value; // if(wrq->u.rts.fixed == 0) we should complain if(wrq->u.rts.disabled) rthr = 2347; if((rthr < 0) || (rthr > 2347)) { rc = -EINVAL; break; } local->medium_reservation = rthr; local->need_commit = 1; } break; // Get the current RTS threshold case SIOCGIWRTS: wrq->u.rts.value = wvlan_hw_getthreshold(&local->ifb, CFG_RTS_THRH); wrq->u.rts.disabled = (wrq->u.rts.value == 2347); wrq->u.rts.fixed = 1; break; // Set the desired fragmentation threshold case SIOCSIWFRAG: /* Check if firmware v4 or v6 */ if(local->has_mwo) { int fthr = wrq->u.frag.value; /* v6 : fragmentation is now controlled by * MWO robust setting */ // if(wrq->u.frag.fixed == 1) should complain if(wrq->u.frag.disabled) fthr = 0; if((fthr < 0) || (fthr > 2347)) { rc = -EINVAL; } else { local->mwo_robust = (fthr > 0); local->need_commit = 1; } } else { int fthr = wrq->u.frag.value; /* v4 : we can set frag threshold */ // if(wrq->u.frag.fixed == 0) should complain if(wrq->u.frag.disabled) fthr = 2346; if((fthr < 256) || (fthr > 2346)) { rc = -EINVAL; } else { fthr &= ~0x1; // Get an even value local->frag_threshold = fthr; local->need_commit = 1; } } break; // Get the current fragmentation threshold case SIOCGIWFRAG: /* Check if firmware v4 or v6 */ if(local->has_mwo) { if(wvlan_hw_getthreshold(&local->ifb, CFG_CNF_MICRO_WAVE)) wrq->u.frag.value = 2347; else wrq->u.frag.value = 0; wrq->u.frag.disabled = !(wrq->u.frag.value); wrq->u.frag.fixed = 0; } else { wrq->u.frag.value = wvlan_hw_getthreshold(&local->ifb, CFG_FRAGMENTATION_THRH); wrq->u.frag.disabled = (wrq->u.frag.value >= 2346); wrq->u.frag.fixed = 1; } break; // Set port type case SIOCSIWMODE: /* Big firmware trouble here ! * In v4 and v6.04, the ad-hoc mode supported is the * Lucent proprietary Ad-Hoc demo mode. * Starting with v6.06, the ad-hoc mode supported is * the standard 802.11 IBSS Ad-Hoc mode. * Jean II */ if(local->has_ibssid) { /* v6 : set the IBSS flag */ char ibss = 0; /* Paranoia */ if(local->port_type != 1) local->port_type = 1; switch (wrq->u.mode) { case IW_MODE_ADHOC: ibss = 1; // Fall through case IW_MODE_INFRA: local->allow_ibss = ibss; local->need_commit = 1; break; default: rc = -EINVAL; } } else { /* v4 : set the correct port type */ char ptype = 1; /* Note : this now works properly with * all firmware ;-) */ /* Paranoia */ if(local->allow_ibss) local->allow_ibss = 0; switch (wrq->u.mode) { case IW_MODE_ADHOC: ptype = 3; // Fall through case IW_MODE_INFRA: local->port_type = ptype; local->need_commit = 1; break; default: rc = -EINVAL; } } break; // Get port type case SIOCGIWMODE: /* Check for proprietary Ad-Hoc demo mode */ if (wvlan_hw_getporttype(&local->ifb) == 1) wrq->u.mode = IW_MODE_INFRA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -