prism2wext.c
来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 363 行
C
363 行
/* prism2wext.c -*- linux-c -*- * _ _ ___ _ _ _____ _ _ ___ __ _ * | | _ | | / _ \ | | | || ____|| |_| | / _ \ | \ | | * | || || || /_\ || | | || ___| | ___ || /_\ || \| | * | || || || ___ | \ | / | |___ | | | || ___ || |\ | * www.\_/ \_/ |_| |_| \_/ |_____||_| |_||_| |_||_| \__|.de * * Wireless Tools 10+ compatibility for linux-wlan-ng based on code * of wlancfg and orinoco_cs * * author: Reyk Floeter <reyk@synack.de> * home: https://www.wavehan.de/projekte/prism2/ * date: 10/04/2001 * version: 0.0.4 * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111 USA. *//*================================================================*//* System Includes */#define __NO_VERSION__#define WAVEHAN 23#define WLAN_DBVAR prism2_debug#include <prism2/prism2wext.h>/* compatibility to wireless extensions */#if defined(__LINUX_WLAN__) && defined (__KERNEL__)#if WIRELESS_EXT > 10/* taken from orinoco.c ;-) */const long prism2wext_channel_freq[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484};#define NUM_CHANNELS (sizeof(prism2wext_channel_freq) / sizeof(prism2wext_channel_freq[0])) /** function declarations =============== *//* called by p80211wstats_get_wireless_stats for /proc/net/wireless */ iw_stats* prism2wext_get_wireless_stats(struct net_device *dev) { wlandevice_t *wlandev = (wlandevice_t*)dev->priv; prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv; hfa384x_t *hw = priv->hw; hfa384x_CommTallies32_t tallies = priv->tallies; iw_stats* wstats; int result = 0; UINT8 bytebuf[HFA384x_CMD_ALLOC_LEN_MAX]; hfa384x_commsquality_t *qual = (hfa384x_commsquality_t*)bytebuf; DBFENTER; if (wlandev == (wlandevice_t*) NULL) return (iw_stats*) NULL; wstats = &wlandev->wstats; memset(&wstats->qual, 0, sizeof(hfa384x_commsquality_t)); /* get the qualitity settings from the RID and return them * into a struct... */ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_COMMSQUALITY, qual, HFA384x_RID_COMMSQUALITY_LEN); /* set stats for the wireless- stats struct. * we can't return any link quality, if we are in ap (accesspoint) - * mode! */ wstats->status = priv->ap; wstats->qual.qual = priv->ap ? 0L : qual->CQ_currBSS; #ifdef WEXT_IN_DB /* Intersil says : dBm = RSSI - 100 - remember that 0x100 == 0x0 */ /* Important : Wavelan/Orinoco driver do it differently, but I suspect * that they are broken. Somebody need to check that iwconfig * report the proper values before we enable that - Jean II */ wstats->qual.level = priv->ap ? 0L : (qual->ASL_currBSS + 0x100 - 100); wstats->qual.noise = priv->ap ? 0L : (qual->ANL_currFC + 0x100 - 100);#else /* WEXT_IN_DB */ wstats->qual.level = priv->ap ? 0L : qual->ASL_currBSS; wstats->qual.noise = priv->ap ? 0L : qual->ANL_currFC;#endif /* WEXT_IN_DB */ wstats->qual.updated = 7; wstats->discard.nwid = 0L; /* tallies.txdiscardswrongsa is wrong! */ wstats->discard.code = tallies.rxdiscardswepundecr; /* am i wrong?! */ wstats->discard.misc = tallies.txdiscards; /* am i wrong?! */ DBFEXIT; return &wlandev->wstats;}/* wireless extensions' ioctls */ int prism2wext_support_ioctl(struct net_device *dev, struct iwreq *iwr, int cmd){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv; hfa384x_t *hw = priv->hw; UINT8 bytebuf[HFA384x_BAP_DATALEN_MAX]; UINT16 *reqbuf = (UINT16*)bytebuf; int err = 0, intval = -1; DBFENTER; WLAN_LOG_DEBUG1(1, "received wireless extension- compatible ioctl #%d.\n", cmd); switch (cmd) { case SIOCSIWNAME: /* unused */ err = (-EOPNOTSUPP); break; case SIOCGIWNAME: /* get name == wireless protocol */ strcpy(iwr->u.name, "IEEE 802.11-b");/* IEEE 802.11-DS as in orinoco.c? */ break; case SIOCSIWNWID: case SIOCGIWNWID: err = (-EOPNOTSUPP); break; case SIOCSIWFREQ: /* set channel */ intval = prism2wext_get_channel(&(iwr->u.freq)); /* check for valid channels */ if ((!intval) || (intval > NUM_CHANNELS)) return (-EFAULT); /* Where's the difference between cnfOwnChannel and * CurrentChannel? */ err = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNCHANNEL, &intval, HFA384x_RID_CNFOWNCHANNEL_LEN); break; case SIOCGIWFREQ: /* get channel */ err = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNCHANNEL, reqbuf, HFA384x_RID_CNFOWNCHANNEL_LEN); /* check for valid channels */ if ((!*reqbuf) || (*reqbuf > NUM_CHANNELS)) return (-EFAULT); /* return the correct frequency instead of a channel */ iwr->u.freq.e = 1; iwr->u.freq.m = prism2wext_channel_freq[(*reqbuf)-1] * 100000; break; case SIOCSIWMODE: /* set operation mode */ err = (-EOPNOTSUPP); break; case SIOCGIWMODE: /* get operation mode */ err = priv->ap ? 0 : hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFPORTTYPE, reqbuf, HFA384x_RID_CNFPORTTYPE_LEN); /* Access Point, infrastructure or ADHOC? */ iwr->u.mode = priv->ap ? IW_MODE_MASTER : (*reqbuf ? IW_MODE_INFRA : IW_MODE_ADHOC); break; case SIOCSIWSENS: case SIOCGIWSENS: case SIOCSIWRANGE: case SIOCSIWPRIV: case SIOCSIWSPY: case SIOCGIWSPY: case SIOCSIWAP: /* set access point MAC addresses (BSSID) */ err = (-EOPNOTSUPP); break; case SIOCGIWAP: /* get access point MAC addresses (BSSID) */ err = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, &(iwr->u.ap_addr.sa_data), HFA384x_RID_CURRENTBSSID_LEN); /* it's an ARP- address */ iwr->u.ap_addr.sa_family = ARPHRD_ETHER; break; case SIOCGIWAPLIST: case SIOCSIWESSID: /* set ESSID (network name) */ err = (-EOPNOTSUPP); break; case SIOCGIWESSID: /* get ESSID */ if (!priv->ap) { err = prism2wext_get_string(hw, &(iwr->u.essid), HFA384x_RID_CURRENTSSID, HFA384x_RID_CURRENTSSID_LEN); } else { err = prism2wext_get_string(hw, &(iwr->u.essid), HFA384x_RID_CNFOWNSSID, HFA384x_RID_CNFOWNSSID_LEN); } break; case SIOCSIWNICKN: /* set node name/nickname */ err = (-EOPNOTSUPP); break; case SIOCGIWNICKN: /* get node name/nickname */ err = prism2wext_get_string(hw, &(iwr->u.data), HFA384x_RID_CNFOWNNAME, HFA384x_RID_CNFOWNNAME_LEN); break; case SIOCSIWRATE: /* set default bit rate (bps) */ case SIOCGIWRATE: /* get default bit rate (bps) */ case SIOCSIWRTS: case SIOCGIWRTS: case SIOCSIWFRAG: case SIOCGIWFRAG: case SIOCSIWTXPOW: case SIOCGIWTXPOW: case SIOCSIWRETRY: case SIOCGIWRETRY: case SIOCSIWENCODE: /* set encoding token & mode */ case SIOCGIWENCODE: /* get encoding token & mode */ err = (-EOPNOTSUPP); break; case SIOCSIWPOWER: case SIOCGIWPOWER: err = (-EOPNOTSUPP); break; case SIOCGIWRANGE: /* Static meta data about the other ioctls */ if(iwr->u.data.pointer != NULL) { struct iw_range range; iwr->u.data.length = sizeof(range); memset(&range, 0, sizeof(range));#if WIRELESS_EXT > 10 range.we_version_compiled = WIRELESS_EXT; range.we_version_source = 9;#endif /* WIRELESS_EXT > 10 */ /* Max of /proc/net/wireless */ range.max_qual.qual = 100; /* ??? */#ifdef WEXT_IN_DB range.max_qual.level = 0x100 - 108; /* -108 dBm */ range.max_qual.noise = 0x100 - 108; /* -108 dBm */#else /* WEXT_IN_DB */ range.max_qual.level = 100; /* ??? */ range.max_qual.noise = 100; /* ??? */#endif /* WEXT_IN_DB */ /* There are lots of other goodies that should go * in there, it will come in its own time - Jean II */ /* Push that up to the caller */ if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range))) err = -EFAULT; } break; case SIOCGIWPRIV: /* get private ioctls for iwpriv. This is not necessary and not implemented but i'll return a useless dummy for demonstration. */ WLAN_LOG_DEBUG1(1, "%s: SIOCGIWPRIV\n", dev->name); if (iwr->u.data.pointer) { struct iw_priv_args privtab[] = { { SIOCGIWPRIV, 0, 0, "DUMMY;-)" }, /* no action */ }; err = verify_area(VERIFY_WRITE, iwr->u.data.pointer, sizeof(privtab)); if (err) break; iwr->u.data.length = sizeof(privtab) / sizeof(privtab[0]); if (copy_to_user(iwr->u.data.pointer, privtab, sizeof(privtab))) err = -EFAULT; } break; default: err = (-EOPNOTSUPP); break; } DBFEXIT; return (err);}/* determine a channel */int prism2wext_get_channel(struct iw_freq *iwf) { int mult = 1, chan = -1, i; DBFENTER; if ( (iwf->e == 0) && (iwf->m <= 1000) ) { /* input is a channel number */ chan = iwf->m; } else { /* input is a frequency - search the table */ for (i = 0; i < (6 - iwf->e); i++) mult *= 10; for (i = 0; i < NUM_CHANNELS; i++) if (iwf->m == (prism2wext_channel_freq[i] * mult)) chan = i+1; } DBFEXIT; return chan;} /* return a string value to user space */int prism2wext_get_string(hfa384x_t *hw, struct iw_point *erq, UINT16 rid, UINT16 len) { UINT8 bytebuf[len]; UINT8 pstrbuf[len]; hfa384x_bytestr_t *bytestr = (hfa384x_bytestr_t*)bytebuf; p80211pstrd_t *pstr = (p80211pstrd_t*)pstrbuf; int err = 0; DBFENTER; err = hfa384x_drvr_getconfig(hw, rid, bytebuf, len); if (err) return (err); prism2mgmt_bytestr2pstr(bytestr, pstr); /* convert string to host format */ erq->flags = 1; erq->length = pstr->len; WLAN_LOG_DEBUG1(1, "returning bytestr of %d bytes\n", pstr->len); if(erq->pointer) { if(copy_to_user(erq->pointer, (char*)pstr->data, erq->length)) return (-EFAULT); } DBFEXIT; return (err);}#endif#endif /* compatibility to wireless extensions */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?