📄 bcm43xx_wx.c
字号:
data->txpower.disabled = !(radio->enabled); err = 0;out_unlock: bcm43xx_unlock(bcm, flags); return err;}static int bcm43xx_wx_set_retry(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ /*TODO*/ return 0;}static int bcm43xx_wx_get_retry(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ /*TODO*/ return 0;}static int bcm43xx_wx_set_encoding(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err; err = ieee80211_wx_set_encode(bcm->ieee, info, data, extra); return err;}static int bcm43xx_wx_set_encodingext(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err; err = ieee80211_wx_set_encodeext(bcm->ieee, info, data, extra); return err;}static int bcm43xx_wx_get_encoding(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err; err = ieee80211_wx_get_encode(bcm->ieee, info, data, extra); return err;}static int bcm43xx_wx_get_encodingext(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err; err = ieee80211_wx_get_encodeext(bcm->ieee, info, data, extra); return err;}static int bcm43xx_wx_set_power(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ /*TODO*/ return 0;}static int bcm43xx_wx_get_power(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ /*TODO*/ return 0;}static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int mode, err = 0; mode = *((int *)extra); switch (mode) { case 0: mode = BCM43xx_RADIO_INTERFMODE_NONE; break; case 1: mode = BCM43xx_RADIO_INTERFMODE_NONWLAN; break; case 2: mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; break; case 3: mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN; break; default: printk(KERN_ERR PFX "set_interfmode allowed parameters are: " "0 => None, 1 => Non-WLAN, 2 => WLAN, " "3 => Auto-WLAN\n"); return -EINVAL; } bcm43xx_lock_mmio(bcm, flags); if (bcm->initialized) { err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " "supported by device\n"); } } else { if (mode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN) { printk(KERN_ERR PFX "Interference Mitigation mode Auto-WLAN " "not supported while the interface is down.\n"); err = -ENODEV; } else bcm->current_core->radio->interfmode = mode; } bcm43xx_unlock_mmio(bcm, flags); return err;}static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int mode; bcm43xx_lock(bcm, flags); mode = bcm->current_core->radio->interfmode; bcm43xx_unlock(bcm, flags); switch (mode) { case BCM43xx_RADIO_INTERFMODE_NONE: strncpy(extra, "0 (No Interference Mitigation)", MAX_WX_STRING); break; case BCM43xx_RADIO_INTERFMODE_NONWLAN: strncpy(extra, "1 (Non-WLAN Interference Mitigation)", MAX_WX_STRING); break; case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: strncpy(extra, "2 (WLAN Interference Mitigation)", MAX_WX_STRING); break; default: assert(0); } data->data.length = strlen(extra) + 1; return 0;}static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int on; on = *((int *)extra); bcm43xx_lock(bcm, flags); bcm->short_preamble = !!on; bcm43xx_unlock(bcm, flags); return 0;}static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int on; bcm43xx_lock(bcm, flags); on = bcm->short_preamble; bcm43xx_unlock(bcm, flags); if (on) strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); else strncpy(extra, "0 (Short Preamble disabled)", MAX_WX_STRING); data->data.length = strlen(extra) + 1; return 0;}static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int on; on = *((int *)extra); bcm43xx_lock(bcm, flags); bcm->ieee->host_encrypt = !!on; bcm->ieee->host_decrypt = !!on; bcm->ieee->host_build_iv = !on; bcm43xx_unlock(bcm, flags); return 0;}static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; int on; bcm43xx_lock(bcm, flags); on = bcm->ieee->host_encrypt; bcm43xx_unlock(bcm, flags); if (on) strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); else strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING); data->data.length = strlen(extra + 1); return 0;}/* Enough buffer to hold a hexdump of the sprom data. */#define SPROM_BUFFERSIZE 512static int sprom2hex(const u16 *sprom, char *dump){ int i, pos = 0; for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { pos += snprintf(dump + pos, SPROM_BUFFERSIZE - pos - 1, "%04X", swab16(sprom[i]) & 0xFFFF); } return pos + 1;}static int hex2sprom(u16 *sprom, const char *dump, unsigned int len){ char tmp[5] = { 0 }; int cnt = 0; unsigned long parsed; if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) return -EINVAL; while (cnt < BCM43xx_SPROM_SIZE) { memcpy(tmp, dump, 4); dump += 4; parsed = simple_strtoul(tmp, NULL, 16); sprom[cnt++] = swab16((u16)parsed); } return 0;}static int bcm43xx_wx_sprom_read(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err = -EPERM; u16 *sprom; unsigned long flags; if (!capable(CAP_SYS_RAWIO)) goto out; err = -ENOMEM; sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), GFP_KERNEL); if (!sprom) goto out; bcm43xx_lock_mmio(bcm, flags); err = -ENODEV; if (bcm->initialized) err = bcm43xx_sprom_read(bcm, sprom); bcm43xx_unlock_mmio(bcm, flags); if (!err) data->data.length = sprom2hex(sprom, extra); kfree(sprom);out: return err;}static int bcm43xx_wx_sprom_write(struct net_device *net_dev, struct iw_request_info *info, union iwreq_data *data, char *extra){ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); int err = -EPERM; u16 *sprom; unsigned long flags; char *input; unsigned int len; if (!capable(CAP_SYS_RAWIO)) goto out; err = -ENOMEM; sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), GFP_KERNEL); if (!sprom) goto out; len = data->data.length; extra[len - 1] = '\0'; input = strchr(extra, ':'); if (input) { input++; len -= input - extra; } else input = extra; err = hex2sprom(sprom, input, len); if (err) goto out_kfree; bcm43xx_lock_mmio(bcm, flags); err = -ENODEV; if (bcm->initialized) err = bcm43xx_sprom_write(bcm, sprom); bcm43xx_unlock_mmio(bcm, flags);out_kfree: kfree(sprom);out: return err;}#ifdef WX# undef WX#endif#define WX(ioctl) [(ioctl) - SIOCSIWCOMMIT]static const iw_handler bcm43xx_wx_handlers[] = { /* Wireless Identification */ WX(SIOCGIWNAME) = bcm43xx_wx_get_name, /* Basic operations */ WX(SIOCSIWFREQ) = bcm43xx_wx_set_channelfreq, WX(SIOCGIWFREQ) = bcm43xx_wx_get_channelfreq, WX(SIOCSIWMODE) = bcm43xx_wx_set_mode, WX(SIOCGIWMODE) = bcm43xx_wx_get_mode, /* Informative stuff */ WX(SIOCGIWRANGE) = bcm43xx_wx_get_rangeparams, /* Access Point manipulation */ WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap, WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap, WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan, WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results, /* 802.11 specific support */ WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid, WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid, WX(SIOCSIWNICKN) = bcm43xx_wx_set_nick, WX(SIOCGIWNICKN) = bcm43xx_wx_get_nick, /* Other parameters */ WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate, WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate, WX(SIOCSIWRTS) = bcm43xx_wx_set_rts, WX(SIOCGIWRTS) = bcm43xx_wx_get_rts, WX(SIOCSIWFRAG) = bcm43xx_wx_set_frag, WX(SIOCGIWFRAG) = bcm43xx_wx_get_frag, WX(SIOCSIWTXPOW) = bcm43xx_wx_set_xmitpower, WX(SIOCGIWTXPOW) = bcm43xx_wx_get_xmitpower,//TODO WX(SIOCSIWRETRY) = bcm43xx_wx_set_retry,//TODO WX(SIOCGIWRETRY) = bcm43xx_wx_get_retry, /* Encoding */ WX(SIOCSIWENCODE) = bcm43xx_wx_set_encoding, WX(SIOCGIWENCODE) = bcm43xx_wx_get_encoding, WX(SIOCSIWENCODEEXT) = bcm43xx_wx_set_encodingext, WX(SIOCGIWENCODEEXT) = bcm43xx_wx_get_encodingext, /* Power saving *///TODO WX(SIOCSIWPOWER) = bcm43xx_wx_set_power,//TODO WX(SIOCGIWPOWER) = bcm43xx_wx_get_power, WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie, WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie, WX(SIOCSIWAUTH) = ieee80211_wx_set_auth, WX(SIOCGIWAUTH) = ieee80211_wx_get_auth,};#undef WXstatic const iw_handler bcm43xx_priv_wx_handlers[] = { /* Set Interference Mitigation Mode. */ bcm43xx_wx_set_interfmode, /* Get Interference Mitigation Mode. */ bcm43xx_wx_get_interfmode, /* Enable/Disable Short Preamble mode. */ bcm43xx_wx_set_shortpreamble, /* Get Short Preamble mode. */ bcm43xx_wx_get_shortpreamble, /* Enable/Disable Software Encryption mode */ bcm43xx_wx_set_swencryption, /* Get Software Encryption mode */ bcm43xx_wx_get_swencryption, /* Write SRPROM data. */ bcm43xx_wx_sprom_write, /* Read SPROM data. */ bcm43xx_wx_sprom_read,};#define PRIV_WX_SET_INTERFMODE (SIOCIWFIRSTPRIV + 0)#define PRIV_WX_GET_INTERFMODE (SIOCIWFIRSTPRIV + 1)#define PRIV_WX_SET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 2)#define PRIV_WX_GET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 3)#define PRIV_WX_SET_SWENCRYPTION (SIOCIWFIRSTPRIV + 4)#define PRIV_WX_GET_SWENCRYPTION (SIOCIWFIRSTPRIV + 5)#define PRIV_WX_SPROM_WRITE (SIOCIWFIRSTPRIV + 6)#define PRIV_WX_SPROM_READ (SIOCIWFIRSTPRIV + 7)#define PRIV_WX_DUMMY(ioctl) \ { \ .cmd = (ioctl), \ .name = "__unused" \ }static const struct iw_priv_args bcm43xx_priv_wx_args[] = { { .cmd = PRIV_WX_SET_INTERFMODE, .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, .name = "set_interfmode", }, { .cmd = PRIV_WX_GET_INTERFMODE, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, .name = "get_interfmode", }, { .cmd = PRIV_WX_SET_SHORTPREAMBLE, .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, .name = "set_shortpreambl", }, { .cmd = PRIV_WX_GET_SHORTPREAMBLE, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, .name = "get_shortpreambl", }, { .cmd = PRIV_WX_SET_SWENCRYPTION, .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, .name = "set_swencryption", }, { .cmd = PRIV_WX_GET_SWENCRYPTION, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, .name = "get_swencryption", }, { .cmd = PRIV_WX_SPROM_WRITE, .set_args = IW_PRIV_TYPE_CHAR | SPROM_BUFFERSIZE, .name = "write_sprom", }, { .cmd = PRIV_WX_SPROM_READ, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | SPROM_BUFFERSIZE, .name = "read_sprom", },};const struct iw_handler_def bcm43xx_wx_handlers_def = { .standard = bcm43xx_wx_handlers, .num_standard = ARRAY_SIZE(bcm43xx_wx_handlers), .num_private = ARRAY_SIZE(bcm43xx_priv_wx_handlers), .num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args), .private = bcm43xx_priv_wx_handlers, .private_args = bcm43xx_priv_wx_args,};/* vim: set ts=8 sw=8 sts=8: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -