📄 wavelan.c
字号:
update_psa_checksum(dev, ioaddr, lp->hacr); /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : get NWID */static int wavelan_get_nwid(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Read the NWID. */ psa_read(ioaddr, lp->hacr, (char *) psa.psa_nwid - (char *) &psa, (unsigned char *) psa.psa_nwid, 3); wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1]; wrqu->nwid.disabled = !(psa.psa_nwid_select); wrqu->nwid.fixed = 1; /* Superfluous */ /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : set frequency */static int wavelan_set_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ unsigned long flags; int ret; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) ret = wv_set_frequency(ioaddr, &(wrqu->freq)); else ret = -EOPNOTSUPP; /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : get frequency */static int wavelan_get_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). * Does it work for everybody, especially old cards? */ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { unsigned short freq; /* Ask the EEPROM to read the frequency from the first area. */ fee_read(ioaddr, 0x00, &freq, 1); wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000; wrqu->freq.e = 1; } else { psa_read(ioaddr, lp->hacr, (char *) &psa.psa_subband - (char *) &psa, (unsigned char *) &psa.psa_subband, 1); if (psa.psa_subband <= 4) { wrqu->freq.m = fixed_bands[psa.psa_subband]; wrqu->freq.e = (psa.psa_subband != 0); } else ret = -EOPNOTSUPP; } /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : set level threshold */static int wavelan_set_sens(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Set the level threshold. */ /* We should complain loudly if wrqu->sens.fixed = 0, because we * can't set auto mode... */ psa.psa_thr_pre_set = wrqu->sens.value & 0x3F; psa_write(ioaddr, lp->hacr, (char *) &psa.psa_thr_pre_set - (char *) &psa, (unsigned char *) &psa.psa_thr_pre_set, 1); /* update the Wavelan checksum */ update_psa_checksum(dev, ioaddr, lp->hacr); mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set); /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : get level threshold */static int wavelan_get_sens(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Read the level threshold. */ psa_read(ioaddr, lp->hacr, (char *) &psa.psa_thr_pre_set - (char *) &psa, (unsigned char *) &psa.psa_thr_pre_set, 1); wrqu->sens.value = psa.psa_thr_pre_set & 0x3F; wrqu->sens.fixed = 1; /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : set encryption key */static int wavelan_set_encode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ unsigned long flags; psa_t psa; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Check if capable of encryption */ if (!mmc_encr(ioaddr)) { ret = -EOPNOTSUPP; } /* Check the size of the key */ if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) { ret = -EINVAL; } if(!ret) { /* Basic checking... */ if (wrqu->encoding.length == 8) { /* Copy the key in the driver */ memcpy(psa.psa_encryption_key, extra, wrqu->encoding.length); psa.psa_encryption_select = 1; psa_write(ioaddr, lp->hacr, (char *) &psa.psa_encryption_select - (char *) &psa, (unsigned char *) &psa. psa_encryption_select, 8 + 1); mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE); mmc_write(ioaddr, mmwoff(0, mmw_encr_key), (unsigned char *) &psa. psa_encryption_key, 8); } /* disable encryption */ if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { psa.psa_encryption_select = 0; psa_write(ioaddr, lp->hacr, (char *) &psa.psa_encryption_select - (char *) &psa, (unsigned char *) &psa. psa_encryption_select, 1); mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0); } /* update the Wavelan checksum */ update_psa_checksum(dev, ioaddr, lp->hacr); } /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : get encryption key */static int wavelan_get_encode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; int ret = 0; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Check if encryption is available */ if (!mmc_encr(ioaddr)) { ret = -EOPNOTSUPP; } else { /* Read the encryption key */ psa_read(ioaddr, lp->hacr, (char *) &psa.psa_encryption_select - (char *) &psa, (unsigned char *) &psa. psa_encryption_select, 1 + 8); /* encryption is enabled ? */ if (psa.psa_encryption_select) wrqu->encoding.flags = IW_ENCODE_ENABLED; else wrqu->encoding.flags = IW_ENCODE_DISABLED; wrqu->encoding.flags |= mmc_encr(ioaddr); /* Copy the key to the user buffer */ wrqu->encoding.length = 8; memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length); } /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Handler : get range info */static int wavelan_get_range(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ struct iw_range *range = (struct iw_range *) extra; unsigned long flags; int ret = 0; /* Set the length (very important for backward compatibility) */ wrqu->data.length = sizeof(struct iw_range); /* Set all the info we don't care or don't know about to zero */ memset(range, 0, sizeof(struct iw_range)); /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; range->we_version_source = 9; /* Set information in the range struct. */ range->throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */ range->min_nwid = 0x0000; range->max_nwid = 0xFFFF; range->sensitivity = 0x3F; range->max_qual.qual = MMR_SGNL_QUAL; range->max_qual.level = MMR_SIGNAL_LVL; range->max_qual.noise = MMR_SILENCE_LVL; range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */ /* Need to get better values for those two */ range->avg_qual.level = 30; range->avg_qual.noise = 8; range->num_bitrates = 1; range->bitrate[0] = 2000000; /* 2 Mb/s */ /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { range->num_channels = 10; range->num_frequency = wv_frequency_list(ioaddr, range->freq, IW_MAX_FREQUENCIES); } else range->num_channels = range->num_frequency = 0; /* Encryption supported ? */ if (mmc_encr(ioaddr)) { range->encoding_size[0] = 8; /* DES = 64 bits key */ range->num_encoding_sizes = 1; range->max_encoding_tokens = 1; /* Only one key possible */ } else { range->num_encoding_sizes = 0; range->max_encoding_tokens = 0; } /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return ret;}/*------------------------------------------------------------------*//* * Wireless Private Handler : set quality threshold */static int wavelan_set_qthr(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); psa.psa_quality_thr = *(extra) & 0x0F; psa_write(ioaddr, lp->hacr, (char *) &psa.psa_quality_thr - (char *) &psa, (unsigned char *) &psa.psa_quality_thr, 1); /* update the Wavelan checksum */ update_psa_checksum(dev, ioaddr, lp->hacr); mmc_out(ioaddr, mmwoff(0, mmw_quality_thr), psa.psa_quality_thr); /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return 0;}/*------------------------------------------------------------------*//* * Wireless Private Handler : get quality threshold */static int wavelan_get_qthr(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ unsigned long ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; /* lp is not unused */ psa_t psa; unsigned long flags; /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); psa_read(ioaddr, lp->hacr, (char *) &psa.psa_quality_thr - (char *) &psa, (unsigned char *) &psa.psa_quality_thr, 1); *(extra) = psa.psa_quality_thr & 0x0F; /* Enable interrupts and restore flags. */ spin_unlock_irqrestore(&lp->spinlock, flags); return 0;}#ifdef HISTOGRAM/*------------------------------------------------------------------*//* * Wireless Private Handler : set histogram */static int wavelan_set_histo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ net_local *lp = (net_local *) dev->priv; /* lp is not unused */ /* Check the number of intervals. */ if (wrqu->data.length > 16) { return(-E2BIG); } /* Disable histo while we copy the addresses. * As we don't disable interrupts, we need to do this */ lp->his_number = 0; /* Are there ranges to copy? */ if (wrqu->data.length > 0) { /* Copy interval ranges to the driver */ memcpy(lp->his_range, extra, wrqu->data.length); {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -