mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-27 03:55:37 +08:00
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
This commit is contained in:
commit
057bd3bb1f
@ -24,8 +24,6 @@ menuconfig STAGING
|
||||
|
||||
if STAGING
|
||||
|
||||
source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/olpc_dcon/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192e/Kconfig"
|
||||
|
@ -2,7 +2,6 @@
|
||||
# Makefile for staging directory
|
||||
|
||||
obj-y += media/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
|
||||
|
@ -144,7 +144,7 @@ static struct attribute *gb_audio_module_default_attrs[] = {
|
||||
};
|
||||
ATTRIBUTE_GROUPS(gb_audio_module_default);
|
||||
|
||||
static struct kobj_type gb_audio_module_type = {
|
||||
static const struct kobj_type gb_audio_module_type = {
|
||||
.sysfs_ops = &gb_audio_module_sysfs_ops,
|
||||
.release = gb_audio_module_release,
|
||||
.default_groups = gb_audio_module_default_groups,
|
||||
|
@ -142,6 +142,9 @@ static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
|
||||
channel = get_channel_from_mode(channel->light,
|
||||
GB_CHANNEL_MODE_TORCH);
|
||||
|
||||
if (!channel)
|
||||
return -EINVAL;
|
||||
|
||||
/* For not flash we need to convert brightness to intensity */
|
||||
intensity = channel->intensity_uA.min +
|
||||
(channel->intensity_uA.step * channel->led->brightness);
|
||||
@ -528,7 +531,10 @@ static int gb_lights_light_v4l2_register(struct gb_light *light)
|
||||
}
|
||||
|
||||
channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH);
|
||||
WARN_ON(!channel_flash);
|
||||
if (!channel_flash) {
|
||||
dev_err(dev, "failed to get flash channel from mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fled = &channel_flash->fled;
|
||||
|
||||
|
@ -101,6 +101,7 @@ struct gb_loopback {
|
||||
static struct class loopback_class = {
|
||||
.name = "gb_loopback",
|
||||
};
|
||||
|
||||
static DEFINE_IDA(loopback_ida);
|
||||
|
||||
/* Min/max values in jiffies */
|
||||
|
@ -10,7 +10,7 @@
|
||||
* devices, basing on HopeRfs rf69.
|
||||
*
|
||||
* The driver can also be extended, to support other modules of
|
||||
* HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ...
|
||||
* HopeRf with a similar interface - e. g. RFM69HCW, RFM12, RFM95, ...
|
||||
*
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
@ -68,7 +68,7 @@ static const struct class pi433_class = {
|
||||
*/
|
||||
/*
|
||||
* rx config is device specific
|
||||
* so we have just one rx config, ebedded in device struct
|
||||
* so we have just one rx config, embedded in device struct
|
||||
*/
|
||||
struct pi433_device {
|
||||
/* device handling related values */
|
||||
@ -647,7 +647,7 @@ static int pi433_tx_thread(void *data)
|
||||
|
||||
/*
|
||||
* prevent race conditions
|
||||
* irq will be reenabled after tx config is set
|
||||
* irq will be re-enabled after tx config is set
|
||||
*/
|
||||
disable_irq(device->irq_num[DIO0]);
|
||||
device->tx_active = true;
|
||||
@ -923,7 +923,7 @@ static long pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
case PI433_IOC_WR_RX_CFG:
|
||||
mutex_lock(&device->rx_lock);
|
||||
|
||||
/* during pendig read request, change of config not allowed */
|
||||
/* during pending read request, change of config not allowed */
|
||||
if (device->rx_active) {
|
||||
mutex_unlock(&device->rx_lock);
|
||||
return -EAGAIN;
|
||||
|
@ -11,7 +11,6 @@
|
||||
bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
|
||||
u32 len)
|
||||
{
|
||||
bool rt_status = true;
|
||||
struct r8192_priv *priv = rtllib_priv(dev);
|
||||
u16 frag_length = 0, frag_offset = 0;
|
||||
struct sk_buff *skb;
|
||||
@ -37,10 +36,8 @@ bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
|
||||
else
|
||||
skb = dev_alloc_skb(frag_length + 4);
|
||||
|
||||
if (!skb) {
|
||||
rt_status = false;
|
||||
goto Failed;
|
||||
}
|
||||
if (!skb)
|
||||
return false;
|
||||
|
||||
memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
|
||||
tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
@ -77,6 +74,6 @@ bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
|
||||
} while (frag_offset < len);
|
||||
|
||||
rtl92e_writeb(dev, TP_POLL, TP_POLL_CQ);
|
||||
Failed:
|
||||
return rt_status;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
|
||||
&priv->rtllib->current_network.qos_data.parameters;
|
||||
|
||||
u1bAIFS = qop->aifs[pAcParam] *
|
||||
((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + aSifsTime;
|
||||
((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + asifs_time;
|
||||
|
||||
rtl92e_dm_init_edca_turbo(dev);
|
||||
|
||||
@ -702,17 +702,17 @@ void rtl92e_link_change(struct net_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92e_set_monitor_mode(struct net_device *dev, bool bAllowAllDA,
|
||||
bool WriteIntoReg)
|
||||
void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da,
|
||||
bool write_into_reg)
|
||||
{
|
||||
struct r8192_priv *priv = rtllib_priv(dev);
|
||||
|
||||
if (bAllowAllDA)
|
||||
if (allow_all_da)
|
||||
priv->receive_config |= RCR_AAP;
|
||||
else
|
||||
priv->receive_config &= ~RCR_AAP;
|
||||
|
||||
if (WriteIntoReg)
|
||||
if (write_into_reg)
|
||||
rtl92e_writel(dev, RCR, priv->receive_config);
|
||||
}
|
||||
|
||||
@ -900,7 +900,7 @@ void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
|
||||
pTxFwInfo->RtsBandwidth = 0;
|
||||
pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC;
|
||||
pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ?
|
||||
(cb_desc->bRTSUseShortPreamble ? 1 : 0) :
|
||||
(cb_desc->rts_use_short_preamble ? 1 : 0) :
|
||||
(cb_desc->bRTSUseShortGI ? 1 : 0);
|
||||
if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20_40) {
|
||||
if (cb_desc->bPacketBW) {
|
||||
@ -1659,8 +1659,8 @@ bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats,
|
||||
stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) &&
|
||||
(pDrvInfo->FirstAGGR == 1);
|
||||
|
||||
stats->TimeStampLow = pDrvInfo->TSFL;
|
||||
stats->TimeStampHigh = rtl92e_readl(dev, TSFR + 4);
|
||||
stats->time_stamp_low = pDrvInfo->TSFL;
|
||||
stats->time_stamp_high = rtl92e_readl(dev, TSFR + 4);
|
||||
|
||||
_rtl92e_translate_rx_signal_stats(dev, skb, stats, pdesc, pDrvInfo);
|
||||
skb_trim(skb, skb->len - S_CRC_LEN);
|
||||
|
@ -21,8 +21,8 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val);
|
||||
void rtl92e_get_eeprom_size(struct net_device *dev);
|
||||
bool rtl92e_start_adapter(struct net_device *dev);
|
||||
void rtl92e_link_change(struct net_device *dev);
|
||||
void rtl92e_set_monitor_mode(struct net_device *dev, bool bAllowAllDA,
|
||||
bool WriteIntoReg);
|
||||
void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da,
|
||||
bool write_into_reg);
|
||||
void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
|
||||
struct cb_desc *cb_desc, struct sk_buff *skb);
|
||||
void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry,
|
||||
|
@ -964,7 +964,7 @@ static void _rtl92e_watchdog_wq_cb(void *data)
|
||||
MAC80211_NOLINK) &&
|
||||
(ieee->rf_power_state == rf_on) && !ieee->is_set_key &&
|
||||
(!ieee->proto_stoppping) && !ieee->wx_set_enc) {
|
||||
if (ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE)
|
||||
if (ieee->pwr_save_ctrl.return_point == IPS_CALLBACK_NONE)
|
||||
rtl92e_ips_enter(dev);
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8] = {
|
||||
/*------------------------Define global variable-----------------------------*/
|
||||
struct dig_t dm_digtable;
|
||||
|
||||
struct drx_path_sel dm_rx_path_sel_table;
|
||||
static struct drx_path_sel dm_rx_path_sel_table;
|
||||
/*------------------------Define global variable-----------------------------*/
|
||||
|
||||
|
||||
|
@ -235,7 +235,7 @@ void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap,
|
||||
|
||||
if (!pos_ht_cap || !ht) {
|
||||
netdev_warn(ieee->dev,
|
||||
"%s(): posHTCap and ht_info are null\n", __func__);
|
||||
"%s(): pos_ht_cap and ht_info are null\n", __func__);
|
||||
return;
|
||||
}
|
||||
memset(pos_ht_cap, 0, *len);
|
||||
@ -543,19 +543,19 @@ void ht_initialize_ht_info(struct rtllib_device *ieee)
|
||||
}
|
||||
}
|
||||
|
||||
void ht_initialize_bss_desc(struct bss_ht *pBssHT)
|
||||
void ht_initialize_bss_desc(struct bss_ht *bss_ht)
|
||||
{
|
||||
pBssHT->bd_support_ht = false;
|
||||
memset(pBssHT->bd_ht_cap_buf, 0, sizeof(pBssHT->bd_ht_cap_buf));
|
||||
pBssHT->bd_ht_cap_len = 0;
|
||||
memset(pBssHT->bd_ht_info_buf, 0, sizeof(pBssHT->bd_ht_info_buf));
|
||||
pBssHT->bd_ht_info_len = 0;
|
||||
bss_ht->bd_support_ht = false;
|
||||
memset(bss_ht->bd_ht_cap_buf, 0, sizeof(bss_ht->bd_ht_cap_buf));
|
||||
bss_ht->bd_ht_cap_len = 0;
|
||||
memset(bss_ht->bd_ht_info_buf, 0, sizeof(bss_ht->bd_ht_info_buf));
|
||||
bss_ht->bd_ht_info_len = 0;
|
||||
|
||||
pBssHT->bd_ht_spec_ver = HT_SPEC_VER_IEEE;
|
||||
bss_ht->bd_ht_spec_ver = HT_SPEC_VER_IEEE;
|
||||
|
||||
pBssHT->bd_rt2rt_aggregation = false;
|
||||
pBssHT->bd_rt2rt_long_slot_time = false;
|
||||
pBssHT->rt2rt_ht_mode = (enum rt_ht_capability)0;
|
||||
bss_ht->bd_rt2rt_aggregation = false;
|
||||
bss_ht->bd_rt2rt_long_slot_time = false;
|
||||
bss_ht->rt2rt_ht_mode = (enum rt_ht_capability)0;
|
||||
}
|
||||
|
||||
void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee,
|
||||
@ -625,7 +625,7 @@ EXPORT_SYMBOL(HT_update_self_and_peer_setting);
|
||||
u8 ht_c_check(struct rtllib_device *ieee, u8 *pFrame)
|
||||
{
|
||||
if (ieee->ht_info->current_ht_support) {
|
||||
if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
|
||||
if ((IsQoSDataFrame(pFrame) && frame_order(pFrame)) == 1) {
|
||||
netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
|
||||
return true;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ struct cb_desc {
|
||||
|
||||
u8 bRTSBW:1;
|
||||
u8 bPacketBW:1;
|
||||
u8 bRTSUseShortPreamble:1;
|
||||
u8 rts_use_short_preamble:1;
|
||||
u8 bRTSUseShortGI:1;
|
||||
u8 multicast:1;
|
||||
u8 bBroadcast:1;
|
||||
@ -299,7 +299,7 @@ enum rt_op_mode {
|
||||
RT_OP_MODE_NO_LINK,
|
||||
};
|
||||
|
||||
#define aSifsTime \
|
||||
#define asifs_time \
|
||||
((priv->rtllib->current_network.mode == WIRELESS_MODE_N_24G) ? 16 : 10)
|
||||
|
||||
#define MGMT_QUEUE_NUM 5
|
||||
@ -343,7 +343,7 @@ enum rt_op_mode {
|
||||
#define IsQoSDataFrame(pframe) \
|
||||
((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \
|
||||
(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA))
|
||||
#define Frame_Order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER)
|
||||
#define frame_order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER)
|
||||
#define SN_LESS(a, b) (((a-b)&0x800) != 0)
|
||||
#define SN_EQUAL(a, b) (a == b)
|
||||
#define MAX_DEV_ADDR_SIZE 8
|
||||
@ -482,8 +482,8 @@ struct rtllib_rx_stats {
|
||||
u16 bCRC:1;
|
||||
u16 bICV:1;
|
||||
u16 Decrypted:1;
|
||||
u32 TimeStampLow;
|
||||
u32 TimeStampHigh;
|
||||
u32 time_stamp_low;
|
||||
u32 time_stamp_high;
|
||||
|
||||
u8 RxDrvInfoSize;
|
||||
u8 RxBufShift;
|
||||
@ -1051,7 +1051,7 @@ enum rt_rf_power_state {
|
||||
struct rt_pwr_save_ctrl {
|
||||
bool bSwRfProcessing;
|
||||
enum rt_rf_power_state eInactivePowerState;
|
||||
enum ips_callback_function ReturnPoint;
|
||||
enum ips_callback_function return_point;
|
||||
|
||||
bool bLeisurePs;
|
||||
u8 lps_idle_count;
|
||||
@ -1477,8 +1477,8 @@ struct rtllib_device {
|
||||
void (*set_hw_reg_handler)(struct net_device *dev, u8 variable, u8 *val);
|
||||
|
||||
void (*allow_all_dest_addr_handler)(struct net_device *dev,
|
||||
bool bAllowAllDA,
|
||||
bool WriteIntoReg);
|
||||
bool allow_all_da,
|
||||
bool write_into_reg);
|
||||
|
||||
void (*rtllib_ips_leave_wq)(struct net_device *dev);
|
||||
void (*rtllib_ips_leave)(struct net_device *dev);
|
||||
@ -1736,13 +1736,13 @@ void ht_set_connect_bw_mode(struct rtllib_device *ieee,
|
||||
enum ht_extchnl_offset Offset);
|
||||
void ht_update_default_setting(struct rtllib_device *ieee);
|
||||
void ht_construct_capability_element(struct rtllib_device *ieee,
|
||||
u8 *posHTCap, u8 *len,
|
||||
u8 *pos_ht_cap, u8 *len,
|
||||
u8 isEncrypt, bool bAssoc);
|
||||
void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee,
|
||||
u8 *posRT2RTAgg, u8 *len);
|
||||
void ht_on_assoc_rsp(struct rtllib_device *ieee);
|
||||
void ht_initialize_ht_info(struct rtllib_device *ieee);
|
||||
void ht_initialize_bss_desc(struct bss_ht *pBssHT);
|
||||
void ht_initialize_bss_desc(struct bss_ht *bss_ht);
|
||||
void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee,
|
||||
struct rtllib_network *pNetwork);
|
||||
void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
|
||||
|
@ -84,11 +84,11 @@ void r8712_os_indicate_connect(struct _adapter *adapter)
|
||||
netif_carrier_on(adapter->pnetdev);
|
||||
}
|
||||
|
||||
static struct RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE];
|
||||
static struct RT_PMKID_LIST backup_PMKID_list[NUM_PMKID_CACHE];
|
||||
void r8712_os_indicate_disconnect(struct _adapter *adapter)
|
||||
{
|
||||
u8 backupPMKIDIndex = 0;
|
||||
u8 backupTKIPCountermeasure = 0x00;
|
||||
u8 backup_PMKID_index = 0;
|
||||
u8 backup_TKIP_countermeasure = 0x00;
|
||||
|
||||
r8712_indicate_wx_disassoc_event(adapter);
|
||||
netif_carrier_off(adapter->pnetdev);
|
||||
@ -99,11 +99,11 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter)
|
||||
* disconnect with AP for 60 seconds.
|
||||
*/
|
||||
|
||||
memcpy(&backupPMKIDList[0],
|
||||
memcpy(&backup_PMKID_list[0],
|
||||
&adapter->securitypriv.PMKIDList[0],
|
||||
sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
|
||||
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
|
||||
backupTKIPCountermeasure =
|
||||
backup_PMKID_index = adapter->securitypriv.PMKIDIndex;
|
||||
backup_TKIP_countermeasure =
|
||||
adapter->securitypriv.btkip_countermeasure;
|
||||
memset((unsigned char *)&adapter->securitypriv, 0,
|
||||
sizeof(struct security_priv));
|
||||
@ -113,11 +113,11 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter)
|
||||
* for the following connection.
|
||||
*/
|
||||
memcpy(&adapter->securitypriv.PMKIDList[0],
|
||||
&backupPMKIDList[0],
|
||||
&backup_PMKID_list[0],
|
||||
sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
|
||||
adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
|
||||
adapter->securitypriv.PMKIDIndex = backup_PMKID_index;
|
||||
adapter->securitypriv.btkip_countermeasure =
|
||||
backupTKIPCountermeasure;
|
||||
backup_TKIP_countermeasure;
|
||||
} else { /*reset values in securitypriv*/
|
||||
struct security_priv *sec_priv = &adapter->securitypriv;
|
||||
|
||||
|
@ -221,7 +221,8 @@ struct net_device *r8712_init_netdev(void)
|
||||
|
||||
static u32 start_drv_threads(struct _adapter *padapter)
|
||||
{
|
||||
padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s", padapter->pnetdev->name);
|
||||
padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s",
|
||||
padapter->pnetdev->name);
|
||||
if (IS_ERR(padapter->cmd_thread))
|
||||
return _FAIL;
|
||||
return _SUCCESS;
|
||||
|
@ -107,7 +107,7 @@ static void DeInitLed871x(struct LED_871x *pLed)
|
||||
*/
|
||||
static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed)
|
||||
{
|
||||
u8 LedCfg;
|
||||
u8 LedCfg;
|
||||
|
||||
if (padapter->surprise_removed || padapter->driver_stopped)
|
||||
return;
|
||||
|
@ -861,7 +861,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
|
||||
static void process_link_qual(struct _adapter *padapter,
|
||||
union recv_frame *prframe)
|
||||
{
|
||||
u32 last_evm = 0, tmpVal;
|
||||
u32 last_evm = 0, avg_val;
|
||||
struct rx_pkt_attrib *pattrib;
|
||||
struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data;
|
||||
|
||||
@ -883,8 +883,8 @@ static void process_link_qual(struct _adapter *padapter,
|
||||
sqd->index = 0;
|
||||
|
||||
/* <1> Showed on UI for user, in percentage. */
|
||||
tmpVal = sqd->total_val / sqd->total_num;
|
||||
padapter->recvpriv.signal = (u8)tmpVal;
|
||||
avg_val = sqd->total_val / sqd->total_num;
|
||||
padapter->recvpriv.signal = (u8)avg_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ struct phy_stat {
|
||||
|
||||
union recvstat {
|
||||
struct recv_stat recv_stat;
|
||||
unsigned int value[RXDESC_SIZE>>2];
|
||||
unsigned int value[RXDESC_SIZE >> 2];
|
||||
};
|
||||
|
||||
struct recv_buf {
|
||||
|
@ -16,13 +16,6 @@ some of the ones we want:
|
||||
to manage these buffers as dmabufs so that we can zero-copy import
|
||||
camera images into vc4 for rendering/display.
|
||||
|
||||
* Fix kernel module support
|
||||
|
||||
Even the VPU firmware doesn't support a VCHI re-connect, the driver
|
||||
should properly handle a module unload. This also includes that all
|
||||
resources must be freed (kthreads, debugfs entries, ...) and global
|
||||
variables avoided.
|
||||
|
||||
* Documentation
|
||||
|
||||
A short top-down description of this driver's architecture (function of
|
||||
|
@ -690,7 +690,6 @@ int vchiq_initialise(struct vchiq_instance **instance_out)
|
||||
|
||||
instance = kzalloc(sizeof(*instance), GFP_KERNEL);
|
||||
if (!instance) {
|
||||
dev_err(state->dev, "core: %s: Cannot allocate vchiq instance\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
@ -727,8 +726,9 @@ void free_bulk_waiter(struct vchiq_instance *instance)
|
||||
|
||||
int vchiq_shutdown(struct vchiq_instance *instance)
|
||||
{
|
||||
int status = 0;
|
||||
struct vchiq_state *state = instance->state;
|
||||
struct vchiq_arm_state *arm_state;
|
||||
int status = 0;
|
||||
|
||||
if (mutex_lock_killable(&state->mutex))
|
||||
return -EAGAIN;
|
||||
@ -740,6 +740,9 @@ int vchiq_shutdown(struct vchiq_instance *instance)
|
||||
|
||||
dev_dbg(state->dev, "core: (%p): returning %d\n", instance, status);
|
||||
|
||||
arm_state = vchiq_platform_get_arm_state(state);
|
||||
kthread_stop(arm_state->ka_thread);
|
||||
|
||||
free_bulk_waiter(instance);
|
||||
kfree(instance);
|
||||
|
||||
@ -956,10 +959,8 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl
|
||||
}
|
||||
} else {
|
||||
waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
|
||||
if (!waiter) {
|
||||
dev_err(service->state->dev, "core: %s: - Out of memory\n", __func__);
|
||||
if (!waiter)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
status = vchiq_bulk_transfer(instance, handle, data, NULL, size,
|
||||
@ -1313,11 +1314,11 @@ vchiq_keepalive_thread_func(void *v)
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (!kthread_should_stop()) {
|
||||
long rc = 0, uc = 0;
|
||||
|
||||
if (wait_for_completion_interruptible(&arm_state->ka_evt)) {
|
||||
dev_err(state->dev, "suspend: %s: interrupted\n", __func__);
|
||||
dev_dbg(state->dev, "suspend: %s: interrupted\n", __func__);
|
||||
flush_signals(current);
|
||||
continue;
|
||||
}
|
||||
@ -1753,7 +1754,7 @@ static int vchiq_probe(struct platform_device *pdev)
|
||||
*/
|
||||
err = vchiq_register_chrdev(&pdev->dev);
|
||||
if (err) {
|
||||
dev_warn(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
|
||||
dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
@ -1763,7 +1764,7 @@ static int vchiq_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
failed_platform_init:
|
||||
dev_warn(&pdev->dev, "arm: Could not initialize vchiq platform\n");
|
||||
dev_err(&pdev->dev, "arm: Could not initialize vchiq platform\n");
|
||||
error_exit:
|
||||
return err;
|
||||
}
|
||||
|
@ -37,11 +37,21 @@ static int vchiq_bus_probe(struct device *dev)
|
||||
return driver->probe(device);
|
||||
}
|
||||
|
||||
static void vchiq_bus_remove(struct device *dev)
|
||||
{
|
||||
struct vchiq_device *device = to_vchiq_device(dev);
|
||||
struct vchiq_driver *driver = to_vchiq_driver(dev->driver);
|
||||
|
||||
if (driver->remove)
|
||||
driver->remove(device);
|
||||
}
|
||||
|
||||
const struct bus_type vchiq_bus_type = {
|
||||
.name = "vchiq-bus",
|
||||
.match = vchiq_bus_type_match,
|
||||
.uevent = vchiq_bus_uevent,
|
||||
.probe = vchiq_bus_probe,
|
||||
.remove = vchiq_bus_remove,
|
||||
};
|
||||
|
||||
static void vchiq_device_release(struct device *dev)
|
||||
|
@ -1936,7 +1936,7 @@ slot_handler_func(void *v)
|
||||
|
||||
DEBUG_INITIALISE(local);
|
||||
|
||||
while (1) {
|
||||
while (!kthread_should_stop()) {
|
||||
DEBUG_COUNT(SLOT_HANDLER_COUNT);
|
||||
DEBUG_TRACE(SLOT_HANDLER_LINE);
|
||||
remote_event_wait(&state->trigger_event, &local->trigger);
|
||||
@ -1978,7 +1978,7 @@ recycle_func(void *v)
|
||||
if (!found)
|
||||
return -ENOMEM;
|
||||
|
||||
while (1) {
|
||||
while (!kthread_should_stop()) {
|
||||
remote_event_wait(&state->recycle_event, &local->recycle);
|
||||
|
||||
process_free_queue(state, found, length);
|
||||
@ -1997,7 +1997,7 @@ sync_func(void *v)
|
||||
state->remote->slot_sync);
|
||||
int svc_fourcc;
|
||||
|
||||
while (1) {
|
||||
while (!kthread_should_stop()) {
|
||||
struct vchiq_service *service;
|
||||
int msgid, size;
|
||||
int type;
|
||||
@ -2844,6 +2844,10 @@ vchiq_shutdown_internal(struct vchiq_state *state, struct vchiq_instance *instan
|
||||
(void)vchiq_remove_service(instance, service->handle);
|
||||
vchiq_service_put(service);
|
||||
}
|
||||
|
||||
kthread_stop(state->sync_thread);
|
||||
kthread_stop(state->recycle_thread);
|
||||
kthread_stop(state->slot_handler_thread);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -470,12 +470,6 @@ vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *
|
||||
extern void
|
||||
vchiq_dump_state(struct seq_file *f, struct vchiq_state *state);
|
||||
|
||||
extern void
|
||||
vchiq_loud_error_header(void);
|
||||
|
||||
extern void
|
||||
vchiq_loud_error_footer(void);
|
||||
|
||||
extern void
|
||||
request_poll(struct vchiq_state *state, struct vchiq_service *service,
|
||||
int poll_type);
|
||||
|
@ -68,8 +68,4 @@ bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr,
|
||||
void RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI,
|
||||
long *pldBm);
|
||||
|
||||
/* {{ RobertYu: 20050104 */
|
||||
bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv, u16 byOldChannel, u16 byNewChannel);
|
||||
/* }} RobertYu */
|
||||
|
||||
#endif /* __RF_H__ */
|
||||
|
@ -1,13 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config PRISM2_USB
|
||||
tristate "Prism2.5/3 USB driver"
|
||||
depends on WLAN && USB && CFG80211
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
select CRC32
|
||||
help
|
||||
This is the wlan-ng prism 2.5/3 USB driver for a wide range of
|
||||
old USB wireless devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called prism2_usb.
|
@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PRISM2_USB) += prism2_usb.o
|
||||
|
||||
prism2_usb-y := prism2usb.o \
|
||||
p80211conv.o \
|
||||
p80211req.o \
|
||||
p80211wep.o \
|
||||
p80211netdev.o
|
@ -1,8 +0,0 @@
|
||||
TODO:
|
||||
- checkpatch.pl cleanups
|
||||
- sparse warnings
|
||||
- move to use the in-kernel wireless stack
|
||||
|
||||
Please send any patches or complaints about this driver to Greg
|
||||
Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
|
||||
kernel developers about it, they want nothing to do with it.
|
@ -1,16 +0,0 @@
|
||||
To-do list:
|
||||
|
||||
* Correct the coding style according to Linux guidelines; please read the document
|
||||
at https://www.kernel.org/doc/html/latest/process/coding-style.html.
|
||||
* Remove unnecessary debugging/printing macros; for those that are still needed
|
||||
use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
|
||||
* Remove dead code such as unusued functions, variables, fields, etc..
|
||||
* Use in-kernel API and remove unnecessary wrappers where possible.
|
||||
* Fix bugs due to code that sleeps in atomic context.
|
||||
* Remove the HAL layer and migrate its functionality into the relevant parts of
|
||||
the driver.
|
||||
* Switch to use LIB80211.
|
||||
* Switch to use MAC80211.
|
||||
* Switch to use CFG80211.
|
||||
* Improve the error handling of various functions, particularly those that use
|
||||
existing kernel APIs.
|
@ -1,718 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* cfg80211 Interface for prism2_usb module */
|
||||
#include "hfa384x.h"
|
||||
#include "prism2mgmt.h"
|
||||
|
||||
/* Prism2 channel/frequency/bitrate declarations */
|
||||
static const struct ieee80211_channel prism2_channels[] = {
|
||||
{ .center_freq = 2412 },
|
||||
{ .center_freq = 2417 },
|
||||
{ .center_freq = 2422 },
|
||||
{ .center_freq = 2427 },
|
||||
{ .center_freq = 2432 },
|
||||
{ .center_freq = 2437 },
|
||||
{ .center_freq = 2442 },
|
||||
{ .center_freq = 2447 },
|
||||
{ .center_freq = 2452 },
|
||||
{ .center_freq = 2457 },
|
||||
{ .center_freq = 2462 },
|
||||
{ .center_freq = 2467 },
|
||||
{ .center_freq = 2472 },
|
||||
{ .center_freq = 2484 },
|
||||
};
|
||||
|
||||
static const struct ieee80211_rate prism2_rates[] = {
|
||||
{ .bitrate = 10 },
|
||||
{ .bitrate = 20 },
|
||||
{ .bitrate = 55 },
|
||||
{ .bitrate = 110 }
|
||||
};
|
||||
|
||||
#define PRISM2_NUM_CIPHER_SUITES 2
|
||||
static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
|
||||
WLAN_CIPHER_SUITE_WEP40,
|
||||
WLAN_CIPHER_SUITE_WEP104
|
||||
};
|
||||
|
||||
/* prism2 device private data */
|
||||
struct prism2_wiphy_private {
|
||||
struct wlandevice *wlandev;
|
||||
|
||||
struct ieee80211_supported_band band;
|
||||
struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
|
||||
struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)];
|
||||
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
};
|
||||
|
||||
static const void * const prism2_wiphy_privid = &prism2_wiphy_privid;
|
||||
|
||||
/* Helper Functions */
|
||||
static int prism2_result2err(int prism2_result)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (prism2_result) {
|
||||
case P80211ENUM_resultcode_invalid_parameters:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
case P80211ENUM_resultcode_implementation_failure:
|
||||
err = -EIO;
|
||||
break;
|
||||
case P80211ENUM_resultcode_not_supported:
|
||||
err = -EOPNOTSUPP;
|
||||
break;
|
||||
default:
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_domibset_uint32(struct wlandevice *wlandev,
|
||||
u32 did, u32 data)
|
||||
{
|
||||
struct p80211msg_dot11req_mibset msg;
|
||||
struct p80211item_uint32 *mibitem =
|
||||
(struct p80211item_uint32 *)&msg.mibattribute.data;
|
||||
|
||||
msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
|
||||
mibitem->did = did;
|
||||
mibitem->data = data;
|
||||
|
||||
return p80211req_dorequest(wlandev, (u8 *)&msg);
|
||||
}
|
||||
|
||||
static int prism2_domibset_pstr32(struct wlandevice *wlandev,
|
||||
u32 did, u8 len, const u8 *data)
|
||||
{
|
||||
struct p80211msg_dot11req_mibset msg;
|
||||
struct p80211item_pstr32 *mibitem =
|
||||
(struct p80211item_pstr32 *)&msg.mibattribute.data;
|
||||
|
||||
msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
|
||||
mibitem->did = did;
|
||||
mibitem->data.len = len;
|
||||
memcpy(mibitem->data.data, data, len);
|
||||
|
||||
return p80211req_dorequest(wlandev, (u8 *)&msg);
|
||||
}
|
||||
|
||||
/* The interface functions, called by the cfg80211 layer */
|
||||
static int prism2_change_virtual_intf(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
enum nl80211_iftype type,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
u32 data;
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
if (wlandev->macmode == WLAN_MACMODE_IBSS_STA)
|
||||
goto exit;
|
||||
wlandev->macmode = WLAN_MACMODE_IBSS_STA;
|
||||
data = 0;
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (wlandev->macmode == WLAN_MACMODE_ESS_STA)
|
||||
goto exit;
|
||||
wlandev->macmode = WLAN_MACMODE_ESS_STA;
|
||||
data = 1;
|
||||
break;
|
||||
default:
|
||||
netdev_warn(dev, "Operation mode: %d not support\n", type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Set Operation mode to the PORT TYPE RID */
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_P2_STATIC_CNFPORTTYPE,
|
||||
data);
|
||||
|
||||
if (result)
|
||||
err = -EFAULT;
|
||||
|
||||
dev->ieee80211_ptr->iftype = type;
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
int link_id, u8 key_index, bool pairwise,
|
||||
const u8 *mac_addr, struct key_params *params)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
u32 did;
|
||||
|
||||
if (key_index >= NUM_WEPKEYS)
|
||||
return -EINVAL;
|
||||
|
||||
if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
|
||||
params->cipher != WLAN_CIPHER_SUITE_WEP104) {
|
||||
pr_debug("Unsupported cipher suite\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
|
||||
key_index))
|
||||
return -EFAULT;
|
||||
|
||||
/* send key to driver */
|
||||
did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
|
||||
|
||||
if (prism2_domibset_pstr32(wlandev, did, params->key_len, params->key))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
int link_id, u8 key_index, bool pairwise,
|
||||
const u8 *mac_addr, void *cookie,
|
||||
void (*callback)(void *cookie, struct key_params*))
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
struct key_params params;
|
||||
int len;
|
||||
|
||||
if (key_index >= NUM_WEPKEYS)
|
||||
return -EINVAL;
|
||||
|
||||
len = wlandev->wep_keylens[key_index];
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
if (len == 13)
|
||||
params.cipher = WLAN_CIPHER_SUITE_WEP104;
|
||||
else if (len == 5)
|
||||
params.cipher = WLAN_CIPHER_SUITE_WEP104;
|
||||
else
|
||||
return -ENOENT;
|
||||
params.key_len = len;
|
||||
params.key = wlandev->wep_keys[key_index];
|
||||
params.seq_len = 0;
|
||||
|
||||
callback(cookie, ¶ms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
int link_id, u8 key_index, bool pairwise,
|
||||
const u8 *mac_addr)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
u32 did;
|
||||
int err = 0;
|
||||
int result = 0;
|
||||
|
||||
/* There is no direct way in the hardware (AFAIK) of removing
|
||||
* a key, so we will cheat by setting the key to a bogus value
|
||||
*/
|
||||
|
||||
if (key_index >= NUM_WEPKEYS)
|
||||
return -EINVAL;
|
||||
|
||||
/* send key to driver */
|
||||
did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
|
||||
result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
|
||||
|
||||
if (result)
|
||||
err = -EFAULT;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
int link_id, u8 key_index, bool unicast,
|
||||
bool multicast)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
|
||||
return prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
|
||||
key_index);
|
||||
}
|
||||
|
||||
static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *mac, struct station_info *sinfo)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
struct p80211msg_lnxreq_commsquality quality;
|
||||
int result;
|
||||
|
||||
memset(sinfo, 0, sizeof(*sinfo));
|
||||
|
||||
if (!wlandev || (wlandev->msdstate != WLAN_MSD_RUNNING))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* build request message */
|
||||
quality.msgcode = DIDMSG_LNXREQ_COMMSQUALITY;
|
||||
quality.dbm.data = P80211ENUM_truth_true;
|
||||
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
|
||||
|
||||
/* send message to nsd */
|
||||
if (!wlandev->mlmerequest)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
result = wlandev->mlmerequest(wlandev, (struct p80211msg *)&quality);
|
||||
|
||||
if (result == 0) {
|
||||
sinfo->txrate.legacy = quality.txrate.data;
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
|
||||
sinfo->signal = quality.level.data;
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int prism2_scan(struct wiphy *wiphy,
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||
struct wlandevice *wlandev;
|
||||
struct p80211msg_dot11req_scan msg1;
|
||||
struct p80211msg_dot11req_scan_results *msg2;
|
||||
struct cfg80211_bss *bss;
|
||||
struct cfg80211_scan_info info = {};
|
||||
|
||||
int result;
|
||||
int err = 0;
|
||||
int numbss = 0;
|
||||
int i = 0;
|
||||
u8 ie_buf[46];
|
||||
int ie_len;
|
||||
|
||||
if (!request)
|
||||
return -EINVAL;
|
||||
|
||||
dev = request->wdev->netdev;
|
||||
wlandev = dev->ml_priv;
|
||||
|
||||
if (priv->scan_request && priv->scan_request != request)
|
||||
return -EBUSY;
|
||||
|
||||
if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
|
||||
netdev_err(dev, "Can't scan in AP mode\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
msg2 = kzalloc(sizeof(*msg2), GFP_KERNEL);
|
||||
if (!msg2)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->scan_request = request;
|
||||
|
||||
memset(&msg1, 0x00, sizeof(msg1));
|
||||
msg1.msgcode = DIDMSG_DOT11REQ_SCAN;
|
||||
msg1.bsstype.data = P80211ENUM_bsstype_any;
|
||||
|
||||
memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data));
|
||||
msg1.bssid.data.len = 6;
|
||||
|
||||
if (request->n_ssids > 0) {
|
||||
msg1.scantype.data = P80211ENUM_scantype_active;
|
||||
msg1.ssid.data.len = request->ssids->ssid_len;
|
||||
memcpy(msg1.ssid.data.data,
|
||||
request->ssids->ssid, request->ssids->ssid_len);
|
||||
} else {
|
||||
msg1.scantype.data = 0;
|
||||
}
|
||||
msg1.probedelay.data = 0;
|
||||
|
||||
for (i = 0;
|
||||
(i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
|
||||
i++)
|
||||
msg1.channellist.data.data[i] =
|
||||
ieee80211_frequency_to_channel(request->channels[i]->center_freq);
|
||||
msg1.channellist.data.len = request->n_channels;
|
||||
|
||||
msg1.maxchanneltime.data = 250;
|
||||
msg1.minchanneltime.data = 200;
|
||||
|
||||
result = p80211req_dorequest(wlandev, (u8 *)&msg1);
|
||||
if (result) {
|
||||
err = prism2_result2err(msg1.resultcode.data);
|
||||
goto exit;
|
||||
}
|
||||
/* Now retrieve scan results */
|
||||
numbss = msg1.numbss.data;
|
||||
|
||||
for (i = 0; i < numbss; i++) {
|
||||
int freq;
|
||||
|
||||
msg2->msgcode = DIDMSG_DOT11REQ_SCAN_RESULTS;
|
||||
msg2->bssindex.data = i;
|
||||
|
||||
result = p80211req_dorequest(wlandev, (u8 *)&msg2);
|
||||
if ((result != 0) ||
|
||||
(msg2->resultcode.data != P80211ENUM_resultcode_success)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ie_buf[0] = WLAN_EID_SSID;
|
||||
ie_buf[1] = msg2->ssid.data.len;
|
||||
ie_len = ie_buf[1] + 2;
|
||||
memcpy(&ie_buf[2], &msg2->ssid.data.data, msg2->ssid.data.len);
|
||||
freq = ieee80211_channel_to_frequency(msg2->dschannel.data,
|
||||
NL80211_BAND_2GHZ);
|
||||
bss = cfg80211_inform_bss(wiphy,
|
||||
ieee80211_get_channel(wiphy, freq),
|
||||
CFG80211_BSS_FTYPE_UNKNOWN,
|
||||
(const u8 *)&msg2->bssid.data.data,
|
||||
msg2->timestamp.data, msg2->capinfo.data,
|
||||
msg2->beaconperiod.data,
|
||||
ie_buf,
|
||||
ie_len,
|
||||
(msg2->signal.data - 65536) * 100, /* Conversion to signed type */
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!bss) {
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
}
|
||||
|
||||
if (result)
|
||||
err = prism2_result2err(msg2->resultcode.data);
|
||||
|
||||
exit:
|
||||
info.aborted = !!(err);
|
||||
cfg80211_scan_done(request, &info);
|
||||
priv->scan_request = NULL;
|
||||
kfree(msg2);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
{
|
||||
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||
struct wlandevice *wlandev = priv->wlandev;
|
||||
u32 data;
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
|
||||
if (wiphy->rts_threshold == -1)
|
||||
data = 2347;
|
||||
else
|
||||
data = wiphy->rts_threshold;
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
|
||||
data);
|
||||
if (result) {
|
||||
err = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
|
||||
if (wiphy->frag_threshold == -1)
|
||||
data = 2346;
|
||||
else
|
||||
data = wiphy->frag_threshold;
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
|
||||
data);
|
||||
if (result) {
|
||||
err = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_connect_params *sme)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
struct ieee80211_channel *channel = sme->channel;
|
||||
struct p80211msg_lnxreq_autojoin msg_join;
|
||||
u32 did;
|
||||
int length = sme->ssid_len;
|
||||
int chan = -1;
|
||||
int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||
|
||||
(sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
/* Set the channel */
|
||||
if (channel) {
|
||||
chan = ieee80211_frequency_to_channel(channel->center_freq);
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
|
||||
chan);
|
||||
if (result)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Set the authorization */
|
||||
if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
|
||||
((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
|
||||
msg_join.authtype.data = P80211ENUM_authalg_opensystem;
|
||||
else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
|
||||
((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
|
||||
msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
|
||||
else
|
||||
netdev_warn(dev,
|
||||
"Unhandled authorisation type for connect (%d)\n",
|
||||
sme->auth_type);
|
||||
|
||||
/* Set the encryption - we only support wep */
|
||||
if (is_wep) {
|
||||
if (sme->key) {
|
||||
if (sme->key_idx >= NUM_WEPKEYS)
|
||||
return -EINVAL;
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
|
||||
sme->key_idx);
|
||||
if (result)
|
||||
goto exit;
|
||||
|
||||
/* send key to driver */
|
||||
did = didmib_dot11smt_wepdefaultkeystable_key(sme->key_idx + 1);
|
||||
result = prism2_domibset_pstr32(wlandev,
|
||||
did, sme->key_len,
|
||||
(u8 *)sme->key);
|
||||
if (result)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Assume we should set privacy invoked and exclude unencrypted
|
||||
* We could possible use sme->privacy here, but the assumption
|
||||
* seems reasonable anyways
|
||||
*/
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
|
||||
P80211ENUM_truth_true);
|
||||
if (result)
|
||||
goto exit;
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
|
||||
P80211ENUM_truth_true);
|
||||
if (result)
|
||||
goto exit;
|
||||
|
||||
} else {
|
||||
/* Assume we should unset privacy invoked
|
||||
* and exclude unencrypted
|
||||
*/
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
|
||||
P80211ENUM_truth_false);
|
||||
if (result)
|
||||
goto exit;
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
|
||||
P80211ENUM_truth_false);
|
||||
if (result)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Now do the actual join. Note there is no way that I can
|
||||
* see to request a specific bssid
|
||||
*/
|
||||
msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
|
||||
|
||||
memcpy(msg_join.ssid.data.data, sme->ssid, length);
|
||||
msg_join.ssid.data.len = length;
|
||||
|
||||
result = p80211req_dorequest(wlandev, (u8 *)&msg_join);
|
||||
|
||||
exit:
|
||||
if (result)
|
||||
err = -EFAULT;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||
u16 reason_code)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
struct p80211msg_lnxreq_autojoin msg_join;
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
/* Do a join, with a bogus ssid. Thats the only way I can think of */
|
||||
msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
|
||||
|
||||
memcpy(msg_join.ssid.data.data, "---", 3);
|
||||
msg_join.ssid.data.len = 3;
|
||||
|
||||
result = p80211req_dorequest(wlandev, (u8 *)&msg_join);
|
||||
|
||||
if (result)
|
||||
err = -EFAULT;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
enum nl80211_tx_power_setting type, int mbm)
|
||||
{
|
||||
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||
struct wlandevice *wlandev = priv->wlandev;
|
||||
u32 data;
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
if (type == NL80211_TX_POWER_AUTOMATIC)
|
||||
data = 30;
|
||||
else
|
||||
data = MBM_TO_DBM(mbm);
|
||||
|
||||
result = prism2_domibset_uint32(wlandev,
|
||||
DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
|
||||
data);
|
||||
|
||||
if (result) {
|
||||
err = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
int *dbm)
|
||||
{
|
||||
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
|
||||
struct wlandevice *wlandev = priv->wlandev;
|
||||
struct p80211msg_dot11req_mibget msg;
|
||||
struct p80211item_uint32 *mibitem;
|
||||
int result;
|
||||
int err = 0;
|
||||
|
||||
mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data;
|
||||
msg.msgcode = DIDMSG_DOT11REQ_MIBGET;
|
||||
mibitem->did = DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL;
|
||||
|
||||
result = p80211req_dorequest(wlandev, (u8 *)&msg);
|
||||
|
||||
if (result) {
|
||||
err = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*dbm = mibitem->data;
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Interface callback functions, passing data back up to the cfg80211 layer */
|
||||
void prism2_connect_result(struct wlandevice *wlandev, u8 failed)
|
||||
{
|
||||
u16 status = failed ?
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS;
|
||||
|
||||
cfg80211_connect_result(wlandev->netdev, wlandev->bssid,
|
||||
NULL, 0, NULL, 0, status, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void prism2_disconnected(struct wlandevice *wlandev)
|
||||
{
|
||||
cfg80211_disconnected(wlandev->netdev, 0, NULL,
|
||||
0, false, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void prism2_roamed(struct wlandevice *wlandev)
|
||||
{
|
||||
struct cfg80211_roam_info roam_info = {
|
||||
.links[0].bssid = wlandev->bssid,
|
||||
};
|
||||
|
||||
cfg80211_roamed(wlandev->netdev, &roam_info, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/* Structures for declaring wiphy interface */
|
||||
static const struct cfg80211_ops prism2_usb_cfg_ops = {
|
||||
.change_virtual_intf = prism2_change_virtual_intf,
|
||||
.add_key = prism2_add_key,
|
||||
.get_key = prism2_get_key,
|
||||
.del_key = prism2_del_key,
|
||||
.set_default_key = prism2_set_default_key,
|
||||
.get_station = prism2_get_station,
|
||||
.scan = prism2_scan,
|
||||
.set_wiphy_params = prism2_set_wiphy_params,
|
||||
.connect = prism2_connect,
|
||||
.disconnect = prism2_disconnect,
|
||||
.join_ibss = prism2_join_ibss,
|
||||
.leave_ibss = prism2_leave_ibss,
|
||||
.set_tx_power = prism2_set_tx_power,
|
||||
.get_tx_power = prism2_get_tx_power,
|
||||
};
|
||||
|
||||
/* Functions to create/free wiphy interface */
|
||||
static struct wiphy *wlan_create_wiphy(struct device *dev,
|
||||
struct wlandevice *wlandev)
|
||||
{
|
||||
struct wiphy *wiphy;
|
||||
struct prism2_wiphy_private *priv;
|
||||
|
||||
wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv));
|
||||
if (!wiphy)
|
||||
return NULL;
|
||||
|
||||
priv = wiphy_priv(wiphy);
|
||||
priv->wlandev = wlandev;
|
||||
memcpy(priv->channels, prism2_channels, sizeof(prism2_channels));
|
||||
memcpy(priv->rates, prism2_rates, sizeof(prism2_rates));
|
||||
priv->band.channels = priv->channels;
|
||||
priv->band.n_channels = ARRAY_SIZE(prism2_channels);
|
||||
priv->band.bitrates = priv->rates;
|
||||
priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
|
||||
priv->band.band = NL80211_BAND_2GHZ;
|
||||
priv->band.ht_cap.ht_supported = false;
|
||||
wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
|
||||
|
||||
set_wiphy_dev(wiphy, dev);
|
||||
wiphy->privid = prism2_wiphy_privid;
|
||||
wiphy->max_scan_ssids = 1;
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_ADHOC);
|
||||
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES;
|
||||
wiphy->cipher_suites = prism2_cipher_suites;
|
||||
|
||||
if (wiphy_register(wiphy) < 0) {
|
||||
wiphy_free(wiphy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wiphy;
|
||||
}
|
||||
|
||||
static void wlan_free_wiphy(struct wiphy *wiphy)
|
||||
{
|
||||
wiphy_unregister(wiphy);
|
||||
wiphy_free(wiphy);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,643 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
|
||||
/*
|
||||
*
|
||||
* Ether/802.11 conversions and packet buffer routines
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file defines the functions that perform Ethernet to/from
|
||||
* 802.11 frame conversions.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
*================================================================
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "p80211types.h"
|
||||
#include "p80211hdr.h"
|
||||
#include "p80211conv.h"
|
||||
#include "p80211mgmt.h"
|
||||
#include "p80211msg.h"
|
||||
#include "p80211netdev.h"
|
||||
#include "p80211ioctl.h"
|
||||
#include "p80211req.h"
|
||||
|
||||
static const u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 };
|
||||
static const u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211pb_ether_to_80211
|
||||
*
|
||||
* Uses the contents of the ether frame and the etherconv setting
|
||||
* to build the elements of the 802.11 frame.
|
||||
*
|
||||
* We don't actually set
|
||||
* up the frame header here. That's the MAC's job. We're only handling
|
||||
* conversion of DIXII or 802.3+LLC frames to something that works
|
||||
* with 802.11.
|
||||
*
|
||||
* Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11
|
||||
* FCS is also not present and will need to be added elsewhere.
|
||||
*
|
||||
* Arguments:
|
||||
* ethconv Conversion type to perform
|
||||
* skb skbuff containing the ether frame
|
||||
* p80211_hdr 802.11 header
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, non-zero otherwise
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
|
||||
struct sk_buff *skb, struct p80211_hdr *p80211_hdr,
|
||||
struct p80211_metawep *p80211_wep)
|
||||
{
|
||||
__le16 fc;
|
||||
u16 proto;
|
||||
struct wlan_ethhdr e_hdr;
|
||||
struct wlan_llc *e_llc;
|
||||
struct wlan_snap *e_snap;
|
||||
int foo;
|
||||
|
||||
memcpy(&e_hdr, skb->data, sizeof(e_hdr));
|
||||
|
||||
if (skb->len <= 0) {
|
||||
pr_debug("zero-length skb!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */
|
||||
pr_debug("ENCAP len: %d\n", skb->len);
|
||||
/* here, we don't care what kind of ether frm. Just stick it */
|
||||
/* in the 80211 payload */
|
||||
/* which is to say, leave the skb alone. */
|
||||
} else {
|
||||
/* step 1: classify ether frame, DIX or 802.3? */
|
||||
proto = ntohs(e_hdr.type);
|
||||
if (proto <= ETH_DATA_LEN) {
|
||||
pr_debug("802.3 len: %d\n", skb->len);
|
||||
/* codes <= 1500 reserved for 802.3 lengths */
|
||||
/* it's 802.3, pass ether payload unchanged, */
|
||||
|
||||
/* trim off ethernet header */
|
||||
skb_pull(skb, ETH_HLEN);
|
||||
|
||||
/* leave off any PAD octets. */
|
||||
skb_trim(skb, proto);
|
||||
} else {
|
||||
pr_debug("DIXII len: %d\n", skb->len);
|
||||
/* it's DIXII, time for some conversion */
|
||||
|
||||
/* trim off ethernet header */
|
||||
skb_pull(skb, ETH_HLEN);
|
||||
|
||||
/* tack on SNAP */
|
||||
e_snap = skb_push(skb, sizeof(struct wlan_snap));
|
||||
e_snap->type = htons(proto);
|
||||
if (ethconv == WLAN_ETHCONV_8021h &&
|
||||
p80211_stt_findproto(proto)) {
|
||||
memcpy(e_snap->oui, oui_8021h,
|
||||
WLAN_IEEE_OUI_LEN);
|
||||
} else {
|
||||
memcpy(e_snap->oui, oui_rfc1042,
|
||||
WLAN_IEEE_OUI_LEN);
|
||||
}
|
||||
|
||||
/* tack on llc */
|
||||
e_llc = skb_push(skb, sizeof(struct wlan_llc));
|
||||
e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */
|
||||
e_llc->ssap = 0xAA;
|
||||
e_llc->ctl = 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the 802.11 header */
|
||||
/* It's a data frame */
|
||||
fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
|
||||
WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
|
||||
|
||||
switch (wlandev->macmode) {
|
||||
case WLAN_MACMODE_IBSS_STA:
|
||||
memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address3, wlandev->bssid, ETH_ALEN);
|
||||
break;
|
||||
case WLAN_MACMODE_ESS_STA:
|
||||
fc |= cpu_to_le16(WLAN_SET_FC_TODS(1));
|
||||
memcpy(p80211_hdr->address1, wlandev->bssid, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address3, &e_hdr.daddr, ETH_ALEN);
|
||||
break;
|
||||
case WLAN_MACMODE_ESS_AP:
|
||||
fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1));
|
||||
memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address2, wlandev->bssid, ETH_ALEN);
|
||||
memcpy(p80211_hdr->address3, &e_hdr.saddr, ETH_ALEN);
|
||||
break;
|
||||
default:
|
||||
netdev_err(wlandev->netdev,
|
||||
"Error: Converting eth to wlan in unknown mode.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
p80211_wep->data = NULL;
|
||||
|
||||
if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) &&
|
||||
(wlandev->hostwep & HOSTWEP_ENCRYPT)) {
|
||||
/* XXXX need to pick keynum other than default? */
|
||||
|
||||
p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
|
||||
if (!p80211_wep->data)
|
||||
return -ENOMEM;
|
||||
foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
|
||||
skb->len,
|
||||
wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK,
|
||||
p80211_wep->iv, p80211_wep->icv);
|
||||
if (foo) {
|
||||
netdev_warn(wlandev->netdev,
|
||||
"Host en-WEP failed, dropping frame (%d).\n",
|
||||
foo);
|
||||
kfree(p80211_wep->data);
|
||||
return 2;
|
||||
}
|
||||
fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
|
||||
}
|
||||
|
||||
/* skb->nh.raw = skb->data; */
|
||||
|
||||
p80211_hdr->frame_control = fc;
|
||||
p80211_hdr->duration_id = 0;
|
||||
p80211_hdr->sequence_control = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* jkriegl: from orinoco, modified */
|
||||
static void orinoco_spy_gather(struct wlandevice *wlandev, char *mac,
|
||||
struct p80211_rxmeta *rxmeta)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Gather wireless spy statistics: for each packet, compare the
|
||||
* source address with out list, and if match, get the stats...
|
||||
*/
|
||||
|
||||
for (i = 0; i < wlandev->spy_number; i++) {
|
||||
if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
|
||||
wlandev->spy_stat[i].level = rxmeta->signal;
|
||||
wlandev->spy_stat[i].noise = rxmeta->noise;
|
||||
wlandev->spy_stat[i].qual =
|
||||
(rxmeta->signal >
|
||||
rxmeta->noise) ? (rxmeta->signal -
|
||||
rxmeta->noise) : 0;
|
||||
wlandev->spy_stat[i].updated = 0x7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211pb_80211_to_ether
|
||||
*
|
||||
* Uses the contents of a received 802.11 frame and the etherconv
|
||||
* setting to build an ether frame.
|
||||
*
|
||||
* This function extracts the src and dest address from the 802.11
|
||||
* frame to use in the construction of the eth frame.
|
||||
*
|
||||
* Arguments:
|
||||
* ethconv Conversion type to perform
|
||||
* skb Packet buffer containing the 802.11 frame
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, non-zero otherwise
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *netdev = wlandev->netdev;
|
||||
u16 fc;
|
||||
unsigned int payload_length;
|
||||
unsigned int payload_offset;
|
||||
u8 daddr[ETH_ALEN];
|
||||
u8 saddr[ETH_ALEN];
|
||||
struct p80211_hdr *w_hdr;
|
||||
struct wlan_ethhdr *e_hdr;
|
||||
struct wlan_llc *e_llc;
|
||||
struct wlan_snap *e_snap;
|
||||
|
||||
int foo;
|
||||
|
||||
payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
|
||||
payload_offset = WLAN_HDR_A3_LEN;
|
||||
|
||||
w_hdr = (struct p80211_hdr *)skb->data;
|
||||
|
||||
/* setup some vars for convenience */
|
||||
fc = le16_to_cpu(w_hdr->frame_control);
|
||||
if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
|
||||
ether_addr_copy(daddr, w_hdr->address1);
|
||||
ether_addr_copy(saddr, w_hdr->address2);
|
||||
} else if ((WLAN_GET_FC_TODS(fc) == 0) &&
|
||||
(WLAN_GET_FC_FROMDS(fc) == 1)) {
|
||||
ether_addr_copy(daddr, w_hdr->address1);
|
||||
ether_addr_copy(saddr, w_hdr->address3);
|
||||
} else if ((WLAN_GET_FC_TODS(fc) == 1) &&
|
||||
(WLAN_GET_FC_FROMDS(fc) == 0)) {
|
||||
ether_addr_copy(daddr, w_hdr->address3);
|
||||
ether_addr_copy(saddr, w_hdr->address2);
|
||||
} else {
|
||||
payload_offset = WLAN_HDR_A4_LEN;
|
||||
if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) {
|
||||
netdev_err(netdev, "A4 frame too short!\n");
|
||||
return 1;
|
||||
}
|
||||
payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
|
||||
ether_addr_copy(daddr, w_hdr->address3);
|
||||
ether_addr_copy(saddr, w_hdr->address4);
|
||||
}
|
||||
|
||||
/* perform de-wep if necessary.. */
|
||||
if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) &&
|
||||
WLAN_GET_FC_ISWEP(fc) &&
|
||||
(wlandev->hostwep & HOSTWEP_DECRYPT)) {
|
||||
if (payload_length <= 8) {
|
||||
netdev_err(netdev,
|
||||
"WEP frame too short (%u).\n", skb->len);
|
||||
return 1;
|
||||
}
|
||||
foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
|
||||
payload_length - 8, -1,
|
||||
skb->data + payload_offset,
|
||||
skb->data + payload_offset +
|
||||
payload_length - 4);
|
||||
if (foo) {
|
||||
/* de-wep failed, drop skb. */
|
||||
netdev_dbg(netdev, "Host de-WEP failed, dropping frame (%d).\n",
|
||||
foo);
|
||||
wlandev->rx.decrypt_err++;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* subtract the IV+ICV length off the payload */
|
||||
payload_length -= 8;
|
||||
/* chop off the IV */
|
||||
skb_pull(skb, 4);
|
||||
/* chop off the ICV. */
|
||||
skb_trim(skb, skb->len - 4);
|
||||
|
||||
wlandev->rx.decrypt++;
|
||||
}
|
||||
|
||||
e_hdr = (struct wlan_ethhdr *)(skb->data + payload_offset);
|
||||
|
||||
e_llc = (struct wlan_llc *)(skb->data + payload_offset);
|
||||
e_snap =
|
||||
(struct wlan_snap *)(skb->data + payload_offset +
|
||||
sizeof(struct wlan_llc));
|
||||
|
||||
/* Test for the various encodings */
|
||||
if ((payload_length >= sizeof(struct wlan_ethhdr)) &&
|
||||
(e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) &&
|
||||
((!ether_addr_equal_unaligned(daddr, e_hdr->daddr)) ||
|
||||
(!ether_addr_equal_unaligned(saddr, e_hdr->saddr)))) {
|
||||
netdev_dbg(netdev, "802.3 ENCAP len: %d\n", payload_length);
|
||||
/* 802.3 Encapsulated */
|
||||
/* Test for an overlength frame */
|
||||
if (payload_length > (netdev->mtu + ETH_HLEN)) {
|
||||
/* A bogus length ethfrm has been encap'd. */
|
||||
/* Is someone trying an oflow attack? */
|
||||
netdev_err(netdev, "ENCAP frame too large (%d > %d)\n",
|
||||
payload_length, netdev->mtu + ETH_HLEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Chop off the 802.11 header. it's already sane. */
|
||||
skb_pull(skb, payload_offset);
|
||||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
|
||||
} else if ((payload_length >= sizeof(struct wlan_llc) +
|
||||
sizeof(struct wlan_snap)) &&
|
||||
(e_llc->dsap == 0xaa) &&
|
||||
(e_llc->ssap == 0xaa) &&
|
||||
(e_llc->ctl == 0x03) &&
|
||||
(((memcmp(e_snap->oui, oui_rfc1042,
|
||||
WLAN_IEEE_OUI_LEN) == 0) &&
|
||||
(ethconv == WLAN_ETHCONV_8021h) &&
|
||||
(p80211_stt_findproto(be16_to_cpu(e_snap->type)))) ||
|
||||
(memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) !=
|
||||
0))) {
|
||||
netdev_dbg(netdev, "SNAP+RFC1042 len: %d\n", payload_length);
|
||||
/* it's a SNAP + RFC1042 frame && protocol is in STT */
|
||||
/* build 802.3 + RFC1042 */
|
||||
|
||||
/* Test for an overlength frame */
|
||||
if (payload_length > netdev->mtu) {
|
||||
/* A bogus length ethfrm has been sent. */
|
||||
/* Is someone trying an oflow attack? */
|
||||
netdev_err(netdev, "SNAP frame too large (%d > %d)\n",
|
||||
payload_length, netdev->mtu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* chop 802.11 header from skb. */
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* create 802.3 header at beginning of skb. */
|
||||
e_hdr = skb_push(skb, ETH_HLEN);
|
||||
ether_addr_copy(e_hdr->daddr, daddr);
|
||||
ether_addr_copy(e_hdr->saddr, saddr);
|
||||
e_hdr->type = htons(payload_length);
|
||||
|
||||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
|
||||
} else if ((payload_length >= sizeof(struct wlan_llc) +
|
||||
sizeof(struct wlan_snap)) &&
|
||||
(e_llc->dsap == 0xaa) &&
|
||||
(e_llc->ssap == 0xaa) &&
|
||||
(e_llc->ctl == 0x03)) {
|
||||
netdev_dbg(netdev, "802.1h/RFC1042 len: %d\n", payload_length);
|
||||
/* it's an 802.1h frame || (an RFC1042 && protocol not in STT)
|
||||
* build a DIXII + RFC894
|
||||
*/
|
||||
|
||||
/* Test for an overlength frame */
|
||||
if ((payload_length - sizeof(struct wlan_llc) -
|
||||
sizeof(struct wlan_snap))
|
||||
> netdev->mtu) {
|
||||
/* A bogus length ethfrm has been sent. */
|
||||
/* Is someone trying an oflow attack? */
|
||||
netdev_err(netdev, "DIXII frame too large (%ld > %d)\n",
|
||||
(long)(payload_length -
|
||||
sizeof(struct wlan_llc) -
|
||||
sizeof(struct wlan_snap)), netdev->mtu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* chop 802.11 header from skb. */
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* chop llc header from skb. */
|
||||
skb_pull(skb, sizeof(struct wlan_llc));
|
||||
|
||||
/* chop snap header from skb. */
|
||||
skb_pull(skb, sizeof(struct wlan_snap));
|
||||
|
||||
/* create 802.3 header at beginning of skb. */
|
||||
e_hdr = skb_push(skb, ETH_HLEN);
|
||||
e_hdr->type = e_snap->type;
|
||||
ether_addr_copy(e_hdr->daddr, daddr);
|
||||
ether_addr_copy(e_hdr->saddr, saddr);
|
||||
|
||||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
} else {
|
||||
netdev_dbg(netdev, "NON-ENCAP len: %d\n", payload_length);
|
||||
/* any NON-ENCAP */
|
||||
/* it's a generic 80211+LLC or IPX 'Raw 802.3' */
|
||||
/* build an 802.3 frame */
|
||||
/* allocate space and setup hostbuf */
|
||||
|
||||
/* Test for an overlength frame */
|
||||
if (payload_length > netdev->mtu) {
|
||||
/* A bogus length ethfrm has been sent. */
|
||||
/* Is someone trying an oflow attack? */
|
||||
netdev_err(netdev, "OTHER frame too large (%d > %d)\n",
|
||||
payload_length, netdev->mtu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Chop off the 802.11 header. */
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* create 802.3 header at beginning of skb. */
|
||||
e_hdr = skb_push(skb, ETH_HLEN);
|
||||
ether_addr_copy(e_hdr->daddr, daddr);
|
||||
ether_addr_copy(e_hdr->saddr, saddr);
|
||||
e_hdr->type = htons(payload_length);
|
||||
|
||||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that eth_type_trans() expects an skb w/ skb->data pointing
|
||||
* at the MAC header, it then sets the following skb members:
|
||||
* skb->mac_header,
|
||||
* skb->data, and
|
||||
* skb->pkt_type.
|
||||
* It then _returns_ the value that _we're_ supposed to stuff in
|
||||
* skb->protocol. This is nuts.
|
||||
*/
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
|
||||
/* jkriegl: process signal and noise as set in hfa384x_int_rx() */
|
||||
/* jkriegl: only process signal/noise if requested by iwspy */
|
||||
if (wlandev->spy_number)
|
||||
orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source,
|
||||
p80211skb_rxmeta(skb));
|
||||
|
||||
/* Free the metadata */
|
||||
p80211skb_rxmeta_detach(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211_stt_findproto
|
||||
*
|
||||
* Searches the 802.1h Selective Translation Table for a given
|
||||
* protocol.
|
||||
*
|
||||
* Arguments:
|
||||
* proto protocol number (in host order) to search for.
|
||||
*
|
||||
* Returns:
|
||||
* 1 - if the table is empty or a match is found.
|
||||
* 0 - if the table is non-empty and a match is not found.
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int p80211_stt_findproto(u16 proto)
|
||||
{
|
||||
/* Always return found for now. This is the behavior used by the */
|
||||
/* Zoom Win95 driver when 802.1h mode is selected */
|
||||
/* TODO: If necessary, add an actual search we'll probably
|
||||
* need this to match the CMAC's way of doing things.
|
||||
* Need to do some testing to confirm.
|
||||
*/
|
||||
|
||||
if (proto == ETH_P_AARP) /* APPLETALK */
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211skb_rxmeta_detach
|
||||
*
|
||||
* Disconnects the frmmeta and rxmeta from an skb.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev The wlandev this skb belongs to.
|
||||
* skb The skb we're attaching to.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, non-zero otherwise
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
void p80211skb_rxmeta_detach(struct sk_buff *skb)
|
||||
{
|
||||
struct p80211_rxmeta *rxmeta;
|
||||
struct p80211_frmmeta *frmmeta;
|
||||
|
||||
/* Sanity checks */
|
||||
if (!skb) { /* bad skb */
|
||||
pr_debug("Called w/ null skb.\n");
|
||||
return;
|
||||
}
|
||||
frmmeta = p80211skb_frmmeta(skb);
|
||||
if (!frmmeta) { /* no magic */
|
||||
pr_debug("Called w/ bad frmmeta magic.\n");
|
||||
return;
|
||||
}
|
||||
rxmeta = frmmeta->rx;
|
||||
if (!rxmeta) { /* bad meta ptr */
|
||||
pr_debug("Called w/ bad rxmeta ptr.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free rxmeta */
|
||||
kfree(rxmeta);
|
||||
|
||||
/* Clear skb->cb */
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211skb_rxmeta_attach
|
||||
*
|
||||
* Allocates a p80211rxmeta structure, initializes it, and attaches
|
||||
* it to an skb.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev The wlandev this skb belongs to.
|
||||
* skb The skb we're attaching to.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, non-zero otherwise
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
|
||||
{
|
||||
int result = 0;
|
||||
struct p80211_rxmeta *rxmeta;
|
||||
struct p80211_frmmeta *frmmeta;
|
||||
|
||||
/* If these already have metadata, we error out! */
|
||||
if (p80211skb_rxmeta(skb)) {
|
||||
netdev_err(wlandev->netdev,
|
||||
"%s: RXmeta already attached!\n", wlandev->name);
|
||||
result = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Allocate the rxmeta */
|
||||
rxmeta = kzalloc(sizeof(*rxmeta), GFP_ATOMIC);
|
||||
|
||||
if (!rxmeta) {
|
||||
result = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Initialize the rxmeta */
|
||||
rxmeta->wlandev = wlandev;
|
||||
rxmeta->hosttime = jiffies;
|
||||
|
||||
/* Overlay a frmmeta_t onto skb->cb */
|
||||
memset(skb->cb, 0, sizeof(struct p80211_frmmeta));
|
||||
frmmeta = (struct p80211_frmmeta *)(skb->cb);
|
||||
frmmeta->magic = P80211_FRMMETA_MAGIC;
|
||||
frmmeta->rx = rxmeta;
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211skb_free
|
||||
*
|
||||
* Frees an entire p80211skb by checking and freeing the meta struct
|
||||
* and then freeing the skb.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev The wlandev this skb belongs to.
|
||||
* skb The skb we're attaching to.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, non-zero otherwise
|
||||
*
|
||||
* Call context:
|
||||
* May be called in interrupt or non-interrupt context
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
|
||||
{
|
||||
struct p80211_frmmeta *meta;
|
||||
|
||||
meta = p80211skb_frmmeta(skb);
|
||||
if (meta && meta->rx)
|
||||
p80211skb_rxmeta_detach(skb);
|
||||
else
|
||||
netdev_err(wlandev->netdev,
|
||||
"Freeing an skb (%p) w/ no frmmeta.\n", skb);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Ether/802.11 conversions and packet buffer routines
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file declares the functions, types and macros that perform
|
||||
* Ethernet to/from 802.11 frame conversions.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_P80211CONV_H
|
||||
#define _LINUX_P80211CONV_H
|
||||
|
||||
#define WLAN_IEEE_OUI_LEN 3
|
||||
|
||||
#define WLAN_ETHCONV_ENCAP 1
|
||||
#define WLAN_ETHCONV_8021h 3
|
||||
|
||||
#define P80211CAPTURE_VERSION 0x80211001
|
||||
|
||||
#define P80211_FRMMETA_MAGIC 0x802110
|
||||
|
||||
struct p80211_rxmeta {
|
||||
struct wlandevice *wlandev;
|
||||
|
||||
u64 mactime; /* Hi-rez MAC-supplied time value */
|
||||
u64 hosttime; /* Best-rez host supplied time value */
|
||||
|
||||
unsigned int rxrate; /* Receive data rate in 100kbps */
|
||||
unsigned int priority; /* 0-15, 0=contention, 6=CF */
|
||||
int signal; /* An SSI, see p80211netdev.h */
|
||||
int noise; /* An SSI, see p80211netdev.h */
|
||||
unsigned int channel; /* Receive channel (mostly for snifs) */
|
||||
unsigned int preamble; /* P80211ENUM_preambletype_* */
|
||||
unsigned int encoding; /* P80211ENUM_encoding_* */
|
||||
|
||||
};
|
||||
|
||||
struct p80211_frmmeta {
|
||||
unsigned int magic;
|
||||
struct p80211_rxmeta *rx;
|
||||
};
|
||||
|
||||
void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
|
||||
int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
|
||||
void p80211skb_rxmeta_detach(struct sk_buff *skb);
|
||||
|
||||
static inline struct p80211_frmmeta *p80211skb_frmmeta(struct sk_buff *skb)
|
||||
{
|
||||
struct p80211_frmmeta *frmmeta = (struct p80211_frmmeta *)skb->cb;
|
||||
|
||||
return frmmeta->magic == P80211_FRMMETA_MAGIC ? frmmeta : NULL;
|
||||
}
|
||||
|
||||
static inline struct p80211_rxmeta *p80211skb_rxmeta(struct sk_buff *skb)
|
||||
{
|
||||
struct p80211_frmmeta *frmmeta = p80211skb_frmmeta(skb);
|
||||
|
||||
return frmmeta ? frmmeta->rx : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frame capture header. (See doc/capturefrm.txt)
|
||||
*/
|
||||
struct p80211_caphdr {
|
||||
__be32 version;
|
||||
__be32 length;
|
||||
__be64 mactime;
|
||||
__be64 hosttime;
|
||||
__be32 phytype;
|
||||
__be32 channel;
|
||||
__be32 datarate;
|
||||
__be32 antenna;
|
||||
__be32 priority;
|
||||
__be32 ssi_type;
|
||||
__be32 ssi_signal;
|
||||
__be32 ssi_noise;
|
||||
__be32 preamble;
|
||||
__be32 encoding;
|
||||
};
|
||||
|
||||
struct p80211_metawep {
|
||||
void *data;
|
||||
u8 iv[4];
|
||||
u8 icv[4];
|
||||
};
|
||||
|
||||
/* local ether header type */
|
||||
struct wlan_ethhdr {
|
||||
u8 daddr[ETH_ALEN];
|
||||
u8 saddr[ETH_ALEN];
|
||||
__be16 type;
|
||||
} __packed;
|
||||
|
||||
/* local llc header type */
|
||||
struct wlan_llc {
|
||||
u8 dsap;
|
||||
u8 ssap;
|
||||
u8 ctl;
|
||||
} __packed;
|
||||
|
||||
/* local snap header type */
|
||||
struct wlan_snap {
|
||||
u8 oui[WLAN_IEEE_OUI_LEN];
|
||||
__be16 type;
|
||||
} __packed;
|
||||
|
||||
/* Circular include trick */
|
||||
struct wlandevice;
|
||||
|
||||
int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
|
||||
struct sk_buff *skb);
|
||||
int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
|
||||
struct sk_buff *skb, struct p80211_hdr *p80211_hdr,
|
||||
struct p80211_metawep *p80211_wep);
|
||||
|
||||
int p80211_stt_findproto(u16 proto);
|
||||
|
||||
#endif
|
@ -1,189 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Macros, types, and functions for handling 802.11 MAC headers
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file declares the constants and types used in the interface
|
||||
* between a wlan driver and the user mode utilities.
|
||||
*
|
||||
* Note:
|
||||
* - Constant values are always in HOST byte order. To assign
|
||||
* values to multi-byte fields they _must_ be converted to
|
||||
* ieee byte order. To retrieve multi-byte values from incoming
|
||||
* frames, they must be converted to host order.
|
||||
*
|
||||
* All functions declared here are implemented in p80211.c
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211HDR_H
|
||||
#define _P80211HDR_H
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
/*--- Sizes -----------------------------------------------*/
|
||||
#define WLAN_CRC_LEN 4
|
||||
#define WLAN_BSSID_LEN 6
|
||||
#define WLAN_HDR_A3_LEN 24
|
||||
#define WLAN_HDR_A4_LEN 30
|
||||
#define WLAN_SSID_MAXLEN 32
|
||||
#define WLAN_DATA_MAXLEN 2312
|
||||
#define WLAN_WEP_IV_LEN 4
|
||||
#define WLAN_WEP_ICV_LEN 4
|
||||
|
||||
/*--- Frame Control Field -------------------------------------*/
|
||||
/* Frame Types */
|
||||
#define WLAN_FTYPE_MGMT 0x00
|
||||
#define WLAN_FTYPE_CTL 0x01
|
||||
#define WLAN_FTYPE_DATA 0x02
|
||||
|
||||
/* Frame subtypes */
|
||||
/* Management */
|
||||
#define WLAN_FSTYPE_ASSOCREQ 0x00
|
||||
#define WLAN_FSTYPE_ASSOCRESP 0x01
|
||||
#define WLAN_FSTYPE_REASSOCREQ 0x02
|
||||
#define WLAN_FSTYPE_REASSOCRESP 0x03
|
||||
#define WLAN_FSTYPE_PROBEREQ 0x04
|
||||
#define WLAN_FSTYPE_PROBERESP 0x05
|
||||
#define WLAN_FSTYPE_BEACON 0x08
|
||||
#define WLAN_FSTYPE_ATIM 0x09
|
||||
#define WLAN_FSTYPE_DISASSOC 0x0a
|
||||
#define WLAN_FSTYPE_AUTHEN 0x0b
|
||||
#define WLAN_FSTYPE_DEAUTHEN 0x0c
|
||||
|
||||
/* Control */
|
||||
#define WLAN_FSTYPE_BLOCKACKREQ 0x8
|
||||
#define WLAN_FSTYPE_BLOCKACK 0x9
|
||||
#define WLAN_FSTYPE_PSPOLL 0x0a
|
||||
#define WLAN_FSTYPE_RTS 0x0b
|
||||
#define WLAN_FSTYPE_CTS 0x0c
|
||||
#define WLAN_FSTYPE_ACK 0x0d
|
||||
#define WLAN_FSTYPE_CFEND 0x0e
|
||||
#define WLAN_FSTYPE_CFENDCFACK 0x0f
|
||||
|
||||
/* Data */
|
||||
#define WLAN_FSTYPE_DATAONLY 0x00
|
||||
#define WLAN_FSTYPE_DATA_CFACK 0x01
|
||||
#define WLAN_FSTYPE_DATA_CFPOLL 0x02
|
||||
#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03
|
||||
#define WLAN_FSTYPE_NULL 0x04
|
||||
#define WLAN_FSTYPE_CFACK 0x05
|
||||
#define WLAN_FSTYPE_CFPOLL 0x06
|
||||
#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
|
||||
|
||||
/*--- FC Macros ----------------------------------------------*/
|
||||
/* Macros to get/set the bitfields of the Frame Control Field */
|
||||
/* GET_FC_??? - takes the host byte-order value of an FC */
|
||||
/* and retrieves the value of one of the */
|
||||
/* bitfields and moves that value so its lsb is */
|
||||
/* in bit 0. */
|
||||
/* SET_FC_??? - takes a host order value for one of the FC */
|
||||
/* bitfields and moves it to the proper bit */
|
||||
/* location for ORing into a host order FC. */
|
||||
/* To send the FC produced from SET_FC_???, */
|
||||
/* one must put the bytes in IEEE order. */
|
||||
/* e.g. */
|
||||
/* printf("the frame subtype is %x", */
|
||||
/* GET_FC_FTYPE( ieee2host( rx.fc ))) */
|
||||
/* */
|
||||
/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */
|
||||
/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */
|
||||
/*------------------------------------------------------------*/
|
||||
|
||||
#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & GENMASK(3, 2)) >> 2)
|
||||
#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & GENMASK(7, 4)) >> 4)
|
||||
#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT(8))) >> 8)
|
||||
#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT(9))) >> 9)
|
||||
#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT(14))) >> 14)
|
||||
|
||||
#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2)
|
||||
#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4)
|
||||
#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8)
|
||||
#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9)
|
||||
#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14)
|
||||
|
||||
#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT(7))
|
||||
|
||||
/* Generic 802.11 Header types */
|
||||
|
||||
struct p80211_hdr {
|
||||
__le16 frame_control;
|
||||
u16 duration_id;
|
||||
u8 address1[ETH_ALEN];
|
||||
u8 address2[ETH_ALEN];
|
||||
u8 address3[ETH_ALEN];
|
||||
u16 sequence_control;
|
||||
u8 address4[ETH_ALEN];
|
||||
} __packed;
|
||||
|
||||
/* Frame and header length macros */
|
||||
|
||||
static inline u16 wlan_ctl_framelen(u16 fstype)
|
||||
{
|
||||
switch (fstype) {
|
||||
case WLAN_FSTYPE_BLOCKACKREQ:
|
||||
return 24;
|
||||
case WLAN_FSTYPE_BLOCKACK:
|
||||
return 152;
|
||||
case WLAN_FSTYPE_PSPOLL:
|
||||
case WLAN_FSTYPE_RTS:
|
||||
case WLAN_FSTYPE_CFEND:
|
||||
case WLAN_FSTYPE_CFENDCFACK:
|
||||
return 20;
|
||||
case WLAN_FSTYPE_CTS:
|
||||
case WLAN_FSTYPE_ACK:
|
||||
return 14;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
#define WLAN_FCS_LEN 4
|
||||
|
||||
/* ftcl in HOST order */
|
||||
static inline u16 p80211_headerlen(u16 fctl)
|
||||
{
|
||||
u16 hdrlen = 0;
|
||||
|
||||
switch (WLAN_GET_FC_FTYPE(fctl)) {
|
||||
case WLAN_FTYPE_MGMT:
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
break;
|
||||
case WLAN_FTYPE_DATA:
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
if (WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl))
|
||||
hdrlen += ETH_ALEN;
|
||||
break;
|
||||
case WLAN_FTYPE_CTL:
|
||||
hdrlen = wlan_ctl_framelen(WLAN_GET_FC_FSTYPE(fctl)) -
|
||||
WLAN_FCS_LEN;
|
||||
break;
|
||||
default:
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
}
|
||||
|
||||
return hdrlen;
|
||||
}
|
||||
|
||||
#endif /* _P80211HDR_H */
|
@ -1,69 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Declares constants and types for the p80211 ioctls
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* While this file is called 'ioctl' is purpose goes a little beyond
|
||||
* that. This file defines the types and contants used to implement
|
||||
* the p80211 request/confirm/indicate interfaces on Linux. The
|
||||
* request/confirm interface is, in fact, normally implemented as an
|
||||
* ioctl. The indicate interface on the other hand, is implemented
|
||||
* using the Linux 'netlink' interface.
|
||||
*
|
||||
* The reason I say that request/confirm is 'normally' implemented
|
||||
* via ioctl is that we're reserving the right to be able to send
|
||||
* request commands via the netlink interface. This will be necessary
|
||||
* if we ever need to send request messages when there aren't any
|
||||
* wlan network devices present (i.e. sending a message that only p80211
|
||||
* cares about.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211IOCTL_H
|
||||
#define _P80211IOCTL_H
|
||||
|
||||
/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */
|
||||
|
||||
#define P80211_IFTEST (SIOCDEVPRIVATE + 0)
|
||||
#define P80211_IFREQ (SIOCDEVPRIVATE + 1)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* Magic number, a quick test to see we're getting the desired struct */
|
||||
|
||||
#define P80211_IOCTL_MAGIC (0x4a2d464dUL)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* A ptr to the following structure type is passed as the third */
|
||||
/* argument to the ioctl system call when issuing a request to */
|
||||
/* the p80211 module. */
|
||||
|
||||
struct p80211ioctl_req {
|
||||
char name[WLAN_DEVNAMELEN_MAX];
|
||||
char __user *data;
|
||||
u32 magic;
|
||||
u16 len;
|
||||
u32 result;
|
||||
} __packed;
|
||||
|
||||
#endif /* _P80211IOCTL_H */
|
@ -1,227 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/* --------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211MKMETADEF_H
|
||||
#define _P80211MKMETADEF_H
|
||||
|
||||
#define DIDMSG_DOT11REQ_MIBGET \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMSG_DOT11REQ_MIBGET_MIBATTRIBUTE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(1) | 0x00000000)
|
||||
#define DIDMSG_DOT11REQ_MIBGET_RESULTCODE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(2) | 0x00000000)
|
||||
#define DIDMSG_DOT11REQ_MIBSET \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(2))
|
||||
#define DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(2) | \
|
||||
P80211DID_MKITEM(1) | 0x00000000)
|
||||
#define DIDMSG_DOT11REQ_MIBSET_RESULTCODE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(2) | \
|
||||
P80211DID_MKITEM(2) | 0x00000000)
|
||||
#define DIDMSG_DOT11REQ_SCAN \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(4))
|
||||
#define DIDMSG_DOT11REQ_SCAN_RESULTS \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(5))
|
||||
#define DIDMSG_DOT11REQ_START \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(13))
|
||||
#define DIDMSG_DOT11IND_AUTHENTICATE \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMSG_DOT11IND_ASSOCIATE \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(3))
|
||||
#define DIDMSG_LNXREQ_IFSTATE \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMSG_LNXREQ_WLANSNIFF \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(2))
|
||||
#define DIDMSG_LNXREQ_HOSTWEP \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(3))
|
||||
#define DIDMSG_LNXREQ_COMMSQUALITY \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(4))
|
||||
#define DIDMSG_LNXREQ_AUTOJOIN \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(5))
|
||||
#define DIDMSG_P2REQ_READPDA \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(2))
|
||||
#define DIDMSG_P2REQ_READPDA_PDA \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(2) | \
|
||||
P80211DID_MKITEM(1) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_READPDA_RESULTCODE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(2) | \
|
||||
P80211DID_MKITEM(2) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_STATE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(11))
|
||||
#define DIDMSG_P2REQ_RAMDL_STATE_ENABLE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(11) | \
|
||||
P80211DID_MKITEM(1) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_STATE_EXEADDR \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(11) | \
|
||||
P80211DID_MKITEM(2) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_STATE_RESULTCODE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(11) | \
|
||||
P80211DID_MKITEM(3) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_WRITE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(12))
|
||||
#define DIDMSG_P2REQ_RAMDL_WRITE_ADDR \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(12) | \
|
||||
P80211DID_MKITEM(1) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_WRITE_LEN \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(12) | \
|
||||
P80211DID_MKITEM(2) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_WRITE_DATA \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(12) | \
|
||||
P80211DID_MKITEM(3) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_RAMDL_WRITE_RESULTCODE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(12) | \
|
||||
P80211DID_MKITEM(4) | 0x00000000)
|
||||
#define DIDMSG_P2REQ_FLASHDL_STATE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(13))
|
||||
#define DIDMSG_P2REQ_FLASHDL_WRITE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(14))
|
||||
#define DIDMIB_CAT_DOT11SMT \
|
||||
P80211DID_MKSECTION(1)
|
||||
#define DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(4))
|
||||
#define didmib_dot11smt_wepdefaultkeystable_key(_i) \
|
||||
(DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE | \
|
||||
P80211DID_MKITEM(_i) | 0x0c000000)
|
||||
#define DIDMIB_DOT11SMT_PRIVACYTABLE \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(6))
|
||||
#define DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(6) | \
|
||||
P80211DID_MKITEM(1) | 0x18000000)
|
||||
#define DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(6) | \
|
||||
P80211DID_MKITEM(2) | 0x18000000)
|
||||
#define DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED \
|
||||
(P80211DID_MKSECTION(1) | \
|
||||
P80211DID_MKGROUP(6) | \
|
||||
P80211DID_MKITEM(4) | 0x18000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(1) | 0x18000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(2) | 0x18000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(3) | 0x10000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(4) | 0x10000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(5) | 0x18000000)
|
||||
#define DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME \
|
||||
(P80211DID_MKSECTION(2) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(6) | 0x10000000)
|
||||
#define DIDMIB_CAT_DOT11PHY \
|
||||
P80211DID_MKSECTION(3)
|
||||
#define DIDMIB_DOT11PHY_OPERATIONTABLE \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(3) | \
|
||||
P80211DID_MKITEM(10) | 0x18000000)
|
||||
#define DIDMIB_DOT11PHY_DSSSTABLE \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(5))
|
||||
#define DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL \
|
||||
(P80211DID_MKSECTION(3) | \
|
||||
P80211DID_MKGROUP(5) | \
|
||||
P80211DID_MKITEM(1) | 0x10000000)
|
||||
#define DIDMIB_CAT_LNX \
|
||||
P80211DID_MKSECTION(4)
|
||||
#define DIDMIB_LNX_CONFIGTABLE \
|
||||
(P80211DID_MKSECTION(4) | \
|
||||
P80211DID_MKGROUP(1))
|
||||
#define DIDMIB_LNX_CONFIGTABLE_RSNAIE \
|
||||
(P80211DID_MKSECTION(4) | \
|
||||
P80211DID_MKGROUP(1) | \
|
||||
P80211DID_MKITEM(1) | 0x18000000)
|
||||
#define DIDMIB_CAT_P2 \
|
||||
P80211DID_MKSECTION(5)
|
||||
#define DIDMIB_P2_STATIC \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(2))
|
||||
#define DIDMIB_P2_STATIC_CNFPORTTYPE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(2) | \
|
||||
P80211DID_MKITEM(1) | 0x18000000)
|
||||
#define DIDMIB_P2_NIC_PRISUPRANGE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(5) | \
|
||||
P80211DID_MKITEM(6) | 0x10000000)
|
||||
#define DIDMIB_P2_MAC \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(6))
|
||||
#define DIDMIB_P2_MAC_CURRENTTXRATE \
|
||||
(P80211DID_MKSECTION(5) | \
|
||||
P80211DID_MKGROUP(6) | \
|
||||
P80211DID_MKITEM(12) | 0x10000000)
|
||||
#endif
|
@ -1,236 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/* --------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211MKMETASTRUCT_H
|
||||
#define _P80211MKMETASTRUCT_H
|
||||
|
||||
struct p80211msg_dot11req_mibget {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_unk392 mibattribute;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_dot11req_mibset {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_unk392 mibattribute;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_dot11req_scan {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 bsstype;
|
||||
struct p80211item_pstr6 bssid;
|
||||
u8 pad_0C[1];
|
||||
struct p80211item_pstr32 ssid;
|
||||
u8 pad_1D[3];
|
||||
struct p80211item_uint32 scantype;
|
||||
struct p80211item_uint32 probedelay;
|
||||
struct p80211item_pstr14 channellist;
|
||||
u8 pad_2C[1];
|
||||
struct p80211item_uint32 minchanneltime;
|
||||
struct p80211item_uint32 maxchanneltime;
|
||||
struct p80211item_uint32 resultcode;
|
||||
struct p80211item_uint32 numbss;
|
||||
struct p80211item_uint32 append;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_dot11req_scan_results {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 bssindex;
|
||||
struct p80211item_uint32 resultcode;
|
||||
struct p80211item_uint32 signal;
|
||||
struct p80211item_uint32 noise;
|
||||
struct p80211item_pstr6 bssid;
|
||||
u8 pad_3C[1];
|
||||
struct p80211item_pstr32 ssid;
|
||||
u8 pad_4D[3];
|
||||
struct p80211item_uint32 bsstype;
|
||||
struct p80211item_uint32 beaconperiod;
|
||||
struct p80211item_uint32 dtimperiod;
|
||||
struct p80211item_uint32 timestamp;
|
||||
struct p80211item_uint32 localtime;
|
||||
struct p80211item_uint32 fhdwelltime;
|
||||
struct p80211item_uint32 fhhopset;
|
||||
struct p80211item_uint32 fhhoppattern;
|
||||
struct p80211item_uint32 fhhopindex;
|
||||
struct p80211item_uint32 dschannel;
|
||||
struct p80211item_uint32 cfpcount;
|
||||
struct p80211item_uint32 cfpperiod;
|
||||
struct p80211item_uint32 cfpmaxduration;
|
||||
struct p80211item_uint32 cfpdurremaining;
|
||||
struct p80211item_uint32 ibssatimwindow;
|
||||
struct p80211item_uint32 cfpollable;
|
||||
struct p80211item_uint32 cfpollreq;
|
||||
struct p80211item_uint32 privacy;
|
||||
struct p80211item_uint32 capinfo;
|
||||
struct p80211item_uint32 basicrate[8];
|
||||
struct p80211item_uint32 supprate[8];
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_dot11req_start {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_pstr32 ssid;
|
||||
u8 pad_12D[3];
|
||||
struct p80211item_uint32 bsstype;
|
||||
struct p80211item_uint32 beaconperiod;
|
||||
struct p80211item_uint32 dtimperiod;
|
||||
struct p80211item_uint32 cfpperiod;
|
||||
struct p80211item_uint32 cfpmaxduration;
|
||||
struct p80211item_uint32 fhdwelltime;
|
||||
struct p80211item_uint32 fhhopset;
|
||||
struct p80211item_uint32 fhhoppattern;
|
||||
struct p80211item_uint32 dschannel;
|
||||
struct p80211item_uint32 ibssatimwindow;
|
||||
struct p80211item_uint32 probedelay;
|
||||
struct p80211item_uint32 cfpollable;
|
||||
struct p80211item_uint32 cfpollreq;
|
||||
struct p80211item_uint32 basicrate1;
|
||||
struct p80211item_uint32 basicrate2;
|
||||
struct p80211item_uint32 basicrate3;
|
||||
struct p80211item_uint32 basicrate4;
|
||||
struct p80211item_uint32 basicrate5;
|
||||
struct p80211item_uint32 basicrate6;
|
||||
struct p80211item_uint32 basicrate7;
|
||||
struct p80211item_uint32 basicrate8;
|
||||
struct p80211item_uint32 operationalrate1;
|
||||
struct p80211item_uint32 operationalrate2;
|
||||
struct p80211item_uint32 operationalrate3;
|
||||
struct p80211item_uint32 operationalrate4;
|
||||
struct p80211item_uint32 operationalrate5;
|
||||
struct p80211item_uint32 operationalrate6;
|
||||
struct p80211item_uint32 operationalrate7;
|
||||
struct p80211item_uint32 operationalrate8;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_lnxreq_ifstate {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 ifstate;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_lnxreq_wlansniff {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 enable;
|
||||
struct p80211item_uint32 channel;
|
||||
struct p80211item_uint32 prismheader;
|
||||
struct p80211item_uint32 wlanheader;
|
||||
struct p80211item_uint32 keepwepflags;
|
||||
struct p80211item_uint32 stripfcs;
|
||||
struct p80211item_uint32 packet_trunc;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_lnxreq_hostwep {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 resultcode;
|
||||
struct p80211item_uint32 decrypt;
|
||||
struct p80211item_uint32 encrypt;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_lnxreq_commsquality {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 resultcode;
|
||||
struct p80211item_uint32 dbm;
|
||||
struct p80211item_uint32 link;
|
||||
struct p80211item_uint32 level;
|
||||
struct p80211item_uint32 noise;
|
||||
struct p80211item_uint32 txrate;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_lnxreq_autojoin {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_pstr32 ssid;
|
||||
u8 pad_19D[3];
|
||||
struct p80211item_uint32 authtype;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_p2req_readpda {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_unk1024 pda;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_p2req_ramdl_state {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 enable;
|
||||
struct p80211item_uint32 exeaddr;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_p2req_ramdl_write {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 addr;
|
||||
struct p80211item_uint32 len;
|
||||
struct p80211item_unk4096 data;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_p2req_flashdl_state {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 enable;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
struct p80211msg_p2req_flashdl_write {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
struct p80211item_uint32 addr;
|
||||
struct p80211item_uint32 len;
|
||||
struct p80211item_unk4096 data;
|
||||
struct p80211item_uint32 resultcode;
|
||||
} __packed;
|
||||
|
||||
#endif
|
@ -1,199 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Macros, types, and functions to handle 802.11 mgmt frames
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file declares the constants and types used in the interface
|
||||
* between a wlan driver and the user mode utilities.
|
||||
*
|
||||
* Notes:
|
||||
* - Constant values are always in HOST byte order. To assign
|
||||
* values to multi-byte fields they _must_ be converted to
|
||||
* ieee byte order. To retrieve multi-byte values from incoming
|
||||
* frames, they must be converted to host order.
|
||||
*
|
||||
* - The len member of the frame structure does NOT!!! include
|
||||
* the MAC CRC. Therefore, the len field on rx'd frames should
|
||||
* have 4 subtracted from it.
|
||||
*
|
||||
* All functions declared here are implemented in p80211.c
|
||||
*
|
||||
* The types, macros, and functions defined here are primarily
|
||||
* used for encoding and decoding management frames. They are
|
||||
* designed to follow these patterns of use:
|
||||
*
|
||||
* DECODE:
|
||||
* 1) a frame of length len is received into buffer b
|
||||
* 2) using the hdr structure and macros, we determine the type
|
||||
* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed
|
||||
* 4) mf.hdr = b
|
||||
* mf.buf = b
|
||||
* mf.len = len
|
||||
* 5) call mgmt_decode( mf )
|
||||
* 6) the frame field pointers in mf are now set. Note that any
|
||||
* multi-byte frame field values accessed using the frame field
|
||||
* pointers are in ieee byte order and will have to be converted
|
||||
* to host order.
|
||||
*
|
||||
* ENCODE:
|
||||
* 1) Library client allocates buffer space for maximum length
|
||||
* frame of the desired type
|
||||
* 2) Library client allocates a mgmt frame structure, called mf,
|
||||
* of the desired type
|
||||
* 3) Set the following:
|
||||
* mf.type = <desired type>
|
||||
* mf.buf = <allocated buffer address>
|
||||
* 4) call mgmt_encode( mf )
|
||||
* 5) all of the fixed field pointers and fixed length information element
|
||||
* pointers in mf are now set to their respective locations in the
|
||||
* allocated space (fortunately, all variable length information elements
|
||||
* fall at the end of their respective frames).
|
||||
* 5a) The length field is set to include the last of the fixed and fixed
|
||||
* length fields. It may have to be updated for optional or variable
|
||||
* length information elements.
|
||||
* 6) Optional and variable length information elements are special cases
|
||||
* and must be handled individually by the client code.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211MGMT_H
|
||||
#define _P80211MGMT_H
|
||||
|
||||
#ifndef _P80211HDR_H
|
||||
#include "p80211hdr.h"
|
||||
#endif
|
||||
|
||||
/*-- Information Element IDs --------------------*/
|
||||
#define WLAN_EID_SSID 0
|
||||
#define WLAN_EID_SUPP_RATES 1
|
||||
#define WLAN_EID_FH_PARMS 2
|
||||
#define WLAN_EID_DS_PARMS 3
|
||||
#define WLAN_EID_CF_PARMS 4
|
||||
#define WLAN_EID_TIM 5
|
||||
#define WLAN_EID_IBSS_PARMS 6
|
||||
/*-- values 7-15 reserved --*/
|
||||
#define WLAN_EID_CHALLENGE 16
|
||||
/*-- values 17-31 reserved for challenge text extension --*/
|
||||
/*-- values 32-255 reserved --*/
|
||||
|
||||
/*-- Reason Codes -------------------------------*/
|
||||
#define WLAN_MGMT_REASON_RSVD 0
|
||||
#define WLAN_MGMT_REASON_UNSPEC 1
|
||||
#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
|
||||
#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
|
||||
#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
|
||||
#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
|
||||
#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
|
||||
#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
|
||||
#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
|
||||
#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
|
||||
|
||||
/*-- Status Codes -------------------------------*/
|
||||
#define WLAN_MGMT_STATUS_SUCCESS 0
|
||||
#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
|
||||
#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
|
||||
#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
|
||||
#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
|
||||
#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
|
||||
#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
|
||||
#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
|
||||
/* p80211b additions */
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20
|
||||
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21
|
||||
|
||||
/*-- Auth Algorithm Field ---------------------------*/
|
||||
#define WLAN_AUTH_ALG_OPENSYSTEM 0
|
||||
#define WLAN_AUTH_ALG_SHAREDKEY 1
|
||||
|
||||
/*-- Management Frame Field Offsets -------------*/
|
||||
/* Note: Not all fields are listed because of variable lengths, */
|
||||
/* see the code in p80211.c to see how we search for fields */
|
||||
/* Note: These offsets are from the start of the frame data */
|
||||
|
||||
#define WLAN_BEACON_OFF_TS 0
|
||||
#define WLAN_BEACON_OFF_BCN_int 8
|
||||
#define WLAN_BEACON_OFF_CAPINFO 10
|
||||
#define WLAN_BEACON_OFF_SSID 12
|
||||
|
||||
#define WLAN_DISASSOC_OFF_REASON 0
|
||||
|
||||
#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
|
||||
#define WLAN_ASSOCREQ_OFF_LISTEN_int 2
|
||||
#define WLAN_ASSOCREQ_OFF_SSID 4
|
||||
|
||||
#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
|
||||
#define WLAN_ASSOCRESP_OFF_STATUS 2
|
||||
#define WLAN_ASSOCRESP_OFF_AID 4
|
||||
#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
|
||||
|
||||
#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
|
||||
#define WLAN_REASSOCREQ_OFF_LISTEN_int 2
|
||||
#define WLAN_REASSOCREQ_OFF_CURR_AP 4
|
||||
#define WLAN_REASSOCREQ_OFF_SSID 10
|
||||
|
||||
#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
|
||||
#define WLAN_REASSOCRESP_OFF_STATUS 2
|
||||
#define WLAN_REASSOCRESP_OFF_AID 4
|
||||
#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
|
||||
|
||||
#define WLAN_PROBEREQ_OFF_SSID 0
|
||||
|
||||
#define WLAN_PROBERESP_OFF_TS 0
|
||||
#define WLAN_PROBERESP_OFF_BCN_int 8
|
||||
#define WLAN_PROBERESP_OFF_CAP_INFO 10
|
||||
#define WLAN_PROBERESP_OFF_SSID 12
|
||||
|
||||
#define WLAN_AUTHEN_OFF_AUTH_ALG 0
|
||||
#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
|
||||
#define WLAN_AUTHEN_OFF_STATUS 4
|
||||
#define WLAN_AUTHEN_OFF_CHALLENGE 6
|
||||
|
||||
#define WLAN_DEAUTHEN_OFF_REASON 0
|
||||
|
||||
/*-- Capability Field ---------------------------*/
|
||||
#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT(0))
|
||||
#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT(1)) >> 1)
|
||||
#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT(2)) >> 2)
|
||||
#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT(3)) >> 3)
|
||||
#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT(4)) >> 4)
|
||||
/* p80211b additions */
|
||||
#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT(5)) >> 5)
|
||||
#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT(6)) >> 6)
|
||||
#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT(7)) >> 7)
|
||||
|
||||
#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4)
|
||||
/* p80211b additions */
|
||||
#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6)
|
||||
#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7)
|
||||
|
||||
#endif /* _P80211MGMT_H */
|
@ -1,39 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Macros, constants, types, and funcs for req and ind messages
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211MSG_H
|
||||
#define _P80211MSG_H
|
||||
|
||||
#define WLAN_DEVNAMELEN_MAX 16
|
||||
|
||||
struct p80211msg {
|
||||
u32 msgcode;
|
||||
u32 msglen;
|
||||
u8 devname[WLAN_DEVNAMELEN_MAX];
|
||||
} __packed;
|
||||
|
||||
#endif /* _P80211MSG_H */
|
@ -1,988 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
|
||||
/*
|
||||
*
|
||||
* Linux Kernel net device interface
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* The functions required for a Linux network device are defined here.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef SIOCETHTOOL
|
||||
#include <linux/ethtool.h>
|
||||
#endif
|
||||
|
||||
#include <net/iw_handler.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include "p80211types.h"
|
||||
#include "p80211hdr.h"
|
||||
#include "p80211conv.h"
|
||||
#include "p80211mgmt.h"
|
||||
#include "p80211msg.h"
|
||||
#include "p80211netdev.h"
|
||||
#include "p80211ioctl.h"
|
||||
#include "p80211req.h"
|
||||
#include "p80211metastruct.h"
|
||||
#include "p80211metadef.h"
|
||||
|
||||
#include "cfg80211.c"
|
||||
|
||||
/* netdevice method functions */
|
||||
static int p80211knetdev_init(struct net_device *netdev);
|
||||
static int p80211knetdev_open(struct net_device *netdev);
|
||||
static int p80211knetdev_stop(struct net_device *netdev);
|
||||
static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *netdev);
|
||||
static void p80211knetdev_set_multicast_list(struct net_device *dev);
|
||||
static int p80211knetdev_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
|
||||
void __user *data, int cmd);
|
||||
static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr);
|
||||
static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue);
|
||||
static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc);
|
||||
|
||||
int wlan_watchdog = 5000;
|
||||
module_param(wlan_watchdog, int, 0644);
|
||||
MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
|
||||
|
||||
int wlan_wext_write = 1;
|
||||
module_param(wlan_wext_write, int, 0644);
|
||||
MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_init
|
||||
*
|
||||
* Init method for a Linux netdevice. Called in response to
|
||||
* register_netdev.
|
||||
*
|
||||
* Arguments:
|
||||
* none
|
||||
*
|
||||
* Returns:
|
||||
* nothing
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211knetdev_init(struct net_device *netdev)
|
||||
{
|
||||
/* Called in response to register_netdev */
|
||||
/* This is usually the probe function, but the probe has */
|
||||
/* already been done by the MSD and the create_kdev */
|
||||
/* function. All we do here is return success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_open
|
||||
*
|
||||
* Linux netdevice open method. Following a successful call here,
|
||||
* the device is supposed to be ready for tx and rx. In our
|
||||
* situation that may not be entirely true due to the state of the
|
||||
* MAC below.
|
||||
*
|
||||
* Arguments:
|
||||
* netdev Linux network device structure
|
||||
*
|
||||
* Returns:
|
||||
* zero on success, non-zero otherwise
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211knetdev_open(struct net_device *netdev)
|
||||
{
|
||||
int result = 0; /* success */
|
||||
struct wlandevice *wlandev = netdev->ml_priv;
|
||||
|
||||
/* Check to make sure the MSD is running */
|
||||
if (wlandev->msdstate != WLAN_MSD_RUNNING)
|
||||
return -ENODEV;
|
||||
|
||||
/* Tell the MSD to open */
|
||||
if (wlandev->open) {
|
||||
result = wlandev->open(wlandev);
|
||||
if (result == 0) {
|
||||
netif_start_queue(wlandev->netdev);
|
||||
wlandev->state = WLAN_DEVICE_OPEN;
|
||||
}
|
||||
} else {
|
||||
result = -EAGAIN;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_stop
|
||||
*
|
||||
* Linux netdevice stop (close) method. Following this call,
|
||||
* no frames should go up or down through this interface.
|
||||
*
|
||||
* Arguments:
|
||||
* netdev Linux network device structure
|
||||
*
|
||||
* Returns:
|
||||
* zero on success, non-zero otherwise
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211knetdev_stop(struct net_device *netdev)
|
||||
{
|
||||
int result = 0;
|
||||
struct wlandevice *wlandev = netdev->ml_priv;
|
||||
|
||||
if (wlandev->close)
|
||||
result = wlandev->close(wlandev);
|
||||
|
||||
netif_stop_queue(wlandev->netdev);
|
||||
wlandev->state = WLAN_DEVICE_CLOSED;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211netdev_rx
|
||||
*
|
||||
* Frame receive function called by the mac specific driver.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev WLAN network device structure
|
||||
* skb skbuff containing a full 802.11 frame.
|
||||
* Returns:
|
||||
* nothing
|
||||
* Side effects:
|
||||
*
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb)
|
||||
{
|
||||
/* Enqueue for post-irq processing */
|
||||
skb_queue_tail(&wlandev->nsd_rxq, skb);
|
||||
tasklet_schedule(&wlandev->rx_bh);
|
||||
}
|
||||
|
||||
#define CONV_TO_ETHER_SKIPPED 0x01
|
||||
#define CONV_TO_ETHER_FAILED 0x02
|
||||
|
||||
/**
|
||||
* p80211_convert_to_ether - conversion from 802.11 frame to ethernet frame
|
||||
* @wlandev: pointer to WLAN device
|
||||
* @skb: pointer to socket buffer
|
||||
*
|
||||
* Returns: 0 if conversion succeeded
|
||||
* CONV_TO_ETHER_FAILED if conversion failed
|
||||
* CONV_TO_ETHER_SKIPPED if frame is ignored
|
||||
*/
|
||||
static int p80211_convert_to_ether(struct wlandevice *wlandev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct p80211_hdr *hdr;
|
||||
|
||||
hdr = (struct p80211_hdr *)skb->data;
|
||||
if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->frame_control)))
|
||||
return CONV_TO_ETHER_SKIPPED;
|
||||
|
||||
/* perform mcast filtering: allow my local address through but reject
|
||||
* anything else that isn't multicast
|
||||
*/
|
||||
if (wlandev->netdev->flags & IFF_ALLMULTI) {
|
||||
if (!ether_addr_equal_unaligned(wlandev->netdev->dev_addr,
|
||||
hdr->address1)) {
|
||||
if (!is_multicast_ether_addr(hdr->address1))
|
||||
return CONV_TO_ETHER_SKIPPED;
|
||||
}
|
||||
}
|
||||
|
||||
if (skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0) {
|
||||
wlandev->netdev->stats.rx_packets++;
|
||||
wlandev->netdev->stats.rx_bytes += skb->len;
|
||||
netif_rx(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
netdev_dbg(wlandev->netdev, "%s failed.\n", __func__);
|
||||
return CONV_TO_ETHER_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* p80211netdev_rx_bh - deferred processing of all received frames
|
||||
*
|
||||
* @t: pointer to the tasklet associated with this handler
|
||||
*/
|
||||
static void p80211netdev_rx_bh(struct tasklet_struct *t)
|
||||
{
|
||||
struct wlandevice *wlandev = from_tasklet(wlandev, t, rx_bh);
|
||||
struct sk_buff *skb = NULL;
|
||||
struct net_device *dev = wlandev->netdev;
|
||||
|
||||
/* Let's empty our queue */
|
||||
while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
|
||||
if (wlandev->state == WLAN_DEVICE_OPEN) {
|
||||
if (dev->type != ARPHRD_ETHER) {
|
||||
/* RAW frame; we shouldn't convert it */
|
||||
/* XXX Append the Prism Header here instead. */
|
||||
|
||||
/* set up various data fields */
|
||||
skb->dev = dev;
|
||||
skb_reset_mac_header(skb);
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
skb->protocol = htons(ETH_P_80211_RAW);
|
||||
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += skb->len;
|
||||
netif_rx(skb);
|
||||
continue;
|
||||
} else {
|
||||
if (!p80211_convert_to_ether(wlandev, skb))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_hard_start_xmit
|
||||
*
|
||||
* Linux netdevice method for transmitting a frame.
|
||||
*
|
||||
* Arguments:
|
||||
* skb Linux sk_buff containing the frame.
|
||||
* netdev Linux netdevice.
|
||||
*
|
||||
* Side effects:
|
||||
* If the lower layers report that buffers are full. netdev->tbusy
|
||||
* will be set to prevent higher layers from sending more traffic.
|
||||
*
|
||||
* Note: If this function returns non-zero, higher layers retain
|
||||
* ownership of the skb.
|
||||
*
|
||||
* Returns:
|
||||
* zero on success, non-zero on failure.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
int result = 0;
|
||||
int txresult;
|
||||
struct wlandevice *wlandev = netdev->ml_priv;
|
||||
struct p80211_hdr p80211_hdr;
|
||||
struct p80211_metawep p80211_wep;
|
||||
|
||||
p80211_wep.data = NULL;
|
||||
|
||||
if (!skb)
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
if (wlandev->state != WLAN_DEVICE_OPEN) {
|
||||
result = 1;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
memset(&p80211_hdr, 0, sizeof(p80211_hdr));
|
||||
memset(&p80211_wep, 0, sizeof(p80211_wep));
|
||||
|
||||
if (netif_queue_stopped(netdev)) {
|
||||
netdev_dbg(netdev, "called when queue stopped.\n");
|
||||
result = 1;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
/* Check to see that a valid mode is set */
|
||||
switch (wlandev->macmode) {
|
||||
case WLAN_MACMODE_IBSS_STA:
|
||||
case WLAN_MACMODE_ESS_STA:
|
||||
case WLAN_MACMODE_ESS_AP:
|
||||
break;
|
||||
default:
|
||||
/* Mode isn't set yet, just drop the frame
|
||||
* and return success .
|
||||
* TODO: we need a saner way to handle this
|
||||
*/
|
||||
if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) {
|
||||
netif_start_queue(wlandev->netdev);
|
||||
netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n");
|
||||
netdev->stats.tx_dropped++;
|
||||
result = 0;
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for raw transmits */
|
||||
if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) {
|
||||
if (!capable(CAP_NET_ADMIN)) {
|
||||
result = 1;
|
||||
goto failed;
|
||||
}
|
||||
/* move the header over */
|
||||
memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr));
|
||||
skb_pull(skb, sizeof(p80211_hdr));
|
||||
} else {
|
||||
if (skb_ether_to_p80211
|
||||
(wlandev, wlandev->ethconv, skb, &p80211_hdr,
|
||||
&p80211_wep) != 0) {
|
||||
/* convert failed */
|
||||
netdev_dbg(netdev, "ether_to_80211(%d) failed.\n",
|
||||
wlandev->ethconv);
|
||||
result = 1;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
if (!wlandev->txframe) {
|
||||
result = 1;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
netif_trans_update(netdev);
|
||||
|
||||
netdev->stats.tx_packets++;
|
||||
/* count only the packet payload */
|
||||
netdev->stats.tx_bytes += skb->len;
|
||||
|
||||
txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
|
||||
|
||||
if (txresult == 0) {
|
||||
/* success and more buf */
|
||||
/* avail, re: hw_txdata */
|
||||
netif_wake_queue(wlandev->netdev);
|
||||
result = NETDEV_TX_OK;
|
||||
} else if (txresult == 1) {
|
||||
/* success, no more avail */
|
||||
netdev_dbg(netdev, "txframe success, no more bufs\n");
|
||||
/* netdev->tbusy = 1; don't set here, irqhdlr */
|
||||
/* may have already cleared it */
|
||||
result = NETDEV_TX_OK;
|
||||
} else if (txresult == 2) {
|
||||
/* alloc failure, drop frame */
|
||||
netdev_dbg(netdev, "txframe returned alloc_fail\n");
|
||||
result = NETDEV_TX_BUSY;
|
||||
} else {
|
||||
/* buffer full or queue busy, drop frame. */
|
||||
netdev_dbg(netdev, "txframe returned full or busy\n");
|
||||
result = NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
failed:
|
||||
/* Free up the WEP buffer if it's not the same as the skb */
|
||||
if ((p80211_wep.data) && (p80211_wep.data != skb->data))
|
||||
kfree_sensitive(p80211_wep.data);
|
||||
|
||||
/* we always free the skb here, never in a lower level. */
|
||||
if (!result)
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_set_multicast_list
|
||||
*
|
||||
* Called from higher layers whenever there's a need to set/clear
|
||||
* promiscuous mode or rewrite the multicast list.
|
||||
*
|
||||
* Arguments:
|
||||
* none
|
||||
*
|
||||
* Returns:
|
||||
* nothing
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static void p80211knetdev_set_multicast_list(struct net_device *dev)
|
||||
{
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
|
||||
/* TODO: real multicast support as well */
|
||||
|
||||
if (wlandev->set_multicast_list)
|
||||
wlandev->set_multicast_list(wlandev, dev);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_siocdevprivate
|
||||
*
|
||||
* Handle an ioctl call on one of our devices. Everything Linux
|
||||
* ioctl specific is done here. Then we pass the contents of the
|
||||
* ifr->data to the request message handler.
|
||||
*
|
||||
* Arguments:
|
||||
* dev Linux kernel netdevice
|
||||
* ifr Our private ioctl request structure, typed for the
|
||||
* generic struct ifreq so we can use ptr to func
|
||||
* w/o cast.
|
||||
*
|
||||
* Returns:
|
||||
* zero on success, a negative errno on failure. Possible values:
|
||||
* -ENETDOWN Device isn't up.
|
||||
* -EBUSY cmd already in progress
|
||||
* -ETIME p80211 cmd timed out (MSD may have its own timers)
|
||||
* -EFAULT memory fault copying msg from user buffer
|
||||
* -ENOMEM unable to allocate kernel msg buffer
|
||||
* -EINVAL bad magic, it the cmd really for us?
|
||||
* -EintR sleeping on cmd, awakened by signal, cmd cancelled.
|
||||
*
|
||||
* Call Context:
|
||||
* Process thread (ioctl caller). TODO: SMP support may require
|
||||
* locks.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211knetdev_siocdevprivate(struct net_device *dev,
|
||||
struct ifreq *ifr,
|
||||
void __user *data, int cmd)
|
||||
{
|
||||
int result = 0;
|
||||
struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr;
|
||||
struct wlandevice *wlandev = dev->ml_priv;
|
||||
u8 *msgbuf;
|
||||
|
||||
netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
|
||||
|
||||
if (in_compat_syscall())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Test the magic, assume ifr is good if it's there */
|
||||
if (req->magic != P80211_IOCTL_MAGIC) {
|
||||
result = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (cmd == P80211_IFTEST) {
|
||||
result = 0;
|
||||
goto bail;
|
||||
} else if (cmd != P80211_IFREQ) {
|
||||
result = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
msgbuf = memdup_user(data, req->len);
|
||||
if (IS_ERR(msgbuf)) {
|
||||
result = PTR_ERR(msgbuf);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
result = p80211req_dorequest(wlandev, msgbuf);
|
||||
|
||||
if (result == 0) {
|
||||
if (copy_to_user(data, msgbuf, req->len))
|
||||
result = -EFAULT;
|
||||
}
|
||||
kfree(msgbuf);
|
||||
|
||||
bail:
|
||||
/* If allocate,copyfrom or copyto fails, return errno */
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211knetdev_set_mac_address
|
||||
*
|
||||
* Handles the ioctl for changing the MACAddress of a netdevice
|
||||
*
|
||||
* references: linux/netdevice.h and drivers/net/net_init.c
|
||||
*
|
||||
* NOTE: [MSM] We only prevent address changes when the netdev is
|
||||
* up. We don't control anything based on dot11 state. If the
|
||||
* address is changed on a STA that's currently associated, you
|
||||
* will probably lose the ability to send and receive data frames.
|
||||
* Just be aware. Therefore, this should usually only be done
|
||||
* prior to scan/join/auth/assoc.
|
||||
*
|
||||
* Arguments:
|
||||
* dev netdevice struct
|
||||
* addr the new MACAddress (a struct)
|
||||
*
|
||||
* Returns:
|
||||
* zero on success, a negative errno on failure. Possible values:
|
||||
* -EBUSY device is bussy (cmd not possible)
|
||||
* -and errors returned by: p80211req_dorequest(..)
|
||||
*
|
||||
* by: Collin R. Mulliner <collin@mulliner.org>
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
|
||||
{
|
||||
struct sockaddr *new_addr = addr;
|
||||
struct p80211msg_dot11req_mibset dot11req;
|
||||
struct p80211item_unk392 *mibattr;
|
||||
struct p80211item_pstr6 *macaddr;
|
||||
struct p80211item_uint32 *resultcode;
|
||||
int result;
|
||||
|
||||
/* If we're running, we don't allow MAC address changes */
|
||||
if (netif_running(dev))
|
||||
return -EBUSY;
|
||||
|
||||
/* Set up some convenience pointers. */
|
||||
mibattr = &dot11req.mibattribute;
|
||||
macaddr = (struct p80211item_pstr6 *)&mibattr->data;
|
||||
resultcode = &dot11req.resultcode;
|
||||
|
||||
/* Set up a dot11req_mibset */
|
||||
memset(&dot11req, 0, sizeof(dot11req));
|
||||
dot11req.msgcode = DIDMSG_DOT11REQ_MIBSET;
|
||||
dot11req.msglen = sizeof(dot11req);
|
||||
memcpy(dot11req.devname,
|
||||
((struct wlandevice *)dev->ml_priv)->name,
|
||||
WLAN_DEVNAMELEN_MAX - 1);
|
||||
|
||||
/* Set up the mibattribute argument */
|
||||
mibattr->did = DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE;
|
||||
mibattr->status = P80211ENUM_msgitem_status_data_ok;
|
||||
mibattr->len = sizeof(mibattr->data);
|
||||
|
||||
macaddr->did = DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS;
|
||||
macaddr->status = P80211ENUM_msgitem_status_data_ok;
|
||||
macaddr->len = sizeof(macaddr->data);
|
||||
macaddr->data.len = ETH_ALEN;
|
||||
memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
|
||||
|
||||
/* Set up the resultcode argument */
|
||||
resultcode->did = DIDMSG_DOT11REQ_MIBSET_RESULTCODE;
|
||||
resultcode->status = P80211ENUM_msgitem_status_no_value;
|
||||
resultcode->len = sizeof(resultcode->data);
|
||||
resultcode->data = 0;
|
||||
|
||||
/* now fire the request */
|
||||
result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req);
|
||||
|
||||
/* If the request wasn't successful, report an error and don't
|
||||
* change the netdev address
|
||||
*/
|
||||
if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
|
||||
netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
|
||||
result = -EADDRNOTAVAIL;
|
||||
} else {
|
||||
/* everything's ok, change the addr in netdev */
|
||||
eth_hw_addr_set(dev, new_addr->sa_data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct net_device_ops p80211_netdev_ops = {
|
||||
.ndo_init = p80211knetdev_init,
|
||||
.ndo_open = p80211knetdev_open,
|
||||
.ndo_stop = p80211knetdev_stop,
|
||||
.ndo_start_xmit = p80211knetdev_hard_start_xmit,
|
||||
.ndo_set_rx_mode = p80211knetdev_set_multicast_list,
|
||||
.ndo_siocdevprivate = p80211knetdev_siocdevprivate,
|
||||
.ndo_set_mac_address = p80211knetdev_set_mac_address,
|
||||
.ndo_tx_timeout = p80211knetdev_tx_timeout,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlan_setup
|
||||
*
|
||||
* Roughly matches the functionality of ether_setup. Here
|
||||
* we set up any members of the wlandevice structure that are common
|
||||
* to all devices. Additionally, we allocate a linux 'struct device'
|
||||
* and perform the same setup as ether_setup.
|
||||
*
|
||||
* Note: It's important that the caller have setup the wlandev->name
|
||||
* ptr prior to calling this function.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev ptr to the wlandev structure for the
|
||||
* interface.
|
||||
* physdev ptr to usb device
|
||||
* Returns:
|
||||
* zero on success, non-zero otherwise.
|
||||
* Call Context:
|
||||
* Should be process thread. We'll assume it might be
|
||||
* interrupt though. When we add support for statically
|
||||
* compiled drivers, this function will be called in the
|
||||
* context of the kernel startup code.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
|
||||
{
|
||||
int result = 0;
|
||||
struct net_device *netdev;
|
||||
struct wiphy *wiphy;
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
/* Set up the wlandev */
|
||||
wlandev->state = WLAN_DEVICE_CLOSED;
|
||||
wlandev->ethconv = WLAN_ETHCONV_8021h;
|
||||
wlandev->macmode = WLAN_MACMODE_NONE;
|
||||
|
||||
/* Set up the rx queue */
|
||||
skb_queue_head_init(&wlandev->nsd_rxq);
|
||||
tasklet_setup(&wlandev->rx_bh, p80211netdev_rx_bh);
|
||||
|
||||
/* Allocate and initialize the wiphy struct */
|
||||
wiphy = wlan_create_wiphy(physdev, wlandev);
|
||||
if (!wiphy) {
|
||||
dev_err(physdev, "Failed to alloc wiphy.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the struct device */
|
||||
netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d",
|
||||
NET_NAME_UNKNOWN, ether_setup);
|
||||
if (!netdev) {
|
||||
dev_err(physdev, "Failed to alloc netdev.\n");
|
||||
wlan_free_wiphy(wiphy);
|
||||
result = 1;
|
||||
} else {
|
||||
wlandev->netdev = netdev;
|
||||
netdev->ml_priv = wlandev;
|
||||
netdev->netdev_ops = &p80211_netdev_ops;
|
||||
wdev = netdev_priv(netdev);
|
||||
wdev->wiphy = wiphy;
|
||||
wdev->iftype = NL80211_IFTYPE_STATION;
|
||||
netdev->ieee80211_ptr = wdev;
|
||||
netdev->min_mtu = 68;
|
||||
/* 2312 is max 802.11 payload, 20 is overhead,
|
||||
* (ether + llc + snap) and another 8 for wep.
|
||||
*/
|
||||
netdev->max_mtu = (2312 - 20 - 8);
|
||||
|
||||
netif_stop_queue(netdev);
|
||||
netif_carrier_off(netdev);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlan_unsetup
|
||||
*
|
||||
* This function is paired with the wlan_setup routine. It should
|
||||
* be called after unregister_wlandev. Basically, all it does is
|
||||
* free the 'struct device' that's associated with the wlandev.
|
||||
* We do it here because the 'struct device' isn't allocated
|
||||
* explicitly in the driver code, it's done in wlan_setup. To
|
||||
* do the free in the driver might seem like 'magic'.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev ptr to the wlandev structure for the
|
||||
* interface.
|
||||
* Call Context:
|
||||
* Should be process thread. We'll assume it might be
|
||||
* interrupt though. When we add support for statically
|
||||
* compiled drivers, this function will be called in the
|
||||
* context of the kernel startup code.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
void wlan_unsetup(struct wlandevice *wlandev)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
tasklet_kill(&wlandev->rx_bh);
|
||||
|
||||
if (wlandev->netdev) {
|
||||
wdev = netdev_priv(wlandev->netdev);
|
||||
if (wdev->wiphy)
|
||||
wlan_free_wiphy(wdev->wiphy);
|
||||
free_netdev(wlandev->netdev);
|
||||
wlandev->netdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* register_wlandev
|
||||
*
|
||||
* Roughly matches the functionality of register_netdev. This function
|
||||
* is called after the driver has successfully probed and set up the
|
||||
* resources for the device. It's now ready to become a named device
|
||||
* in the Linux system.
|
||||
*
|
||||
* First we allocate a name for the device (if not already set), then
|
||||
* we call the Linux function register_netdevice.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev ptr to the wlandev structure for the
|
||||
* interface.
|
||||
* Returns:
|
||||
* zero on success, non-zero otherwise.
|
||||
* Call Context:
|
||||
* Can be either interrupt or not.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int register_wlandev(struct wlandevice *wlandev)
|
||||
{
|
||||
return register_netdev(wlandev->netdev);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* unregister_wlandev
|
||||
*
|
||||
* Roughly matches the functionality of unregister_netdev. This
|
||||
* function is called to remove a named device from the system.
|
||||
*
|
||||
* First we tell linux that the device should no longer exist.
|
||||
* Then we remove it from the list of known wlan devices.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev ptr to the wlandev structure for the
|
||||
* interface.
|
||||
* Returns:
|
||||
* zero on success, non-zero otherwise.
|
||||
* Call Context:
|
||||
* Can be either interrupt or not.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int unregister_wlandev(struct wlandevice *wlandev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
unregister_netdev(wlandev->netdev);
|
||||
|
||||
/* Now to clean out the rx queue */
|
||||
while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211netdev_hwremoved
|
||||
*
|
||||
* Hardware removed notification. This function should be called
|
||||
* immediately after an MSD has detected that the underlying hardware
|
||||
* has been yanked out from under us. The primary things we need
|
||||
* to do are:
|
||||
* - Mark the wlandev
|
||||
* - Prevent any further traffic from the knetdev i/f
|
||||
* - Prevent any further requests from mgmt i/f
|
||||
* - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
|
||||
* shut them down.
|
||||
* - Call the MSD hwremoved function.
|
||||
*
|
||||
* The remainder of the cleanup will be handled by unregister().
|
||||
* Our primary goal here is to prevent as much tickling of the MSD
|
||||
* as possible since the MSD is already in a 'wounded' state.
|
||||
*
|
||||
* TODO: As new features are added, this function should be
|
||||
* updated.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev WLAN network device structure
|
||||
* Returns:
|
||||
* nothing
|
||||
* Side effects:
|
||||
*
|
||||
* Call context:
|
||||
* Usually interrupt.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
void p80211netdev_hwremoved(struct wlandevice *wlandev)
|
||||
{
|
||||
wlandev->hwremoved = 1;
|
||||
if (wlandev->state == WLAN_DEVICE_OPEN)
|
||||
netif_stop_queue(wlandev->netdev);
|
||||
|
||||
netif_device_detach(wlandev->netdev);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211_rx_typedrop
|
||||
*
|
||||
* Classifies the frame, increments the appropriate counter, and
|
||||
* returns 0|1|2 indicating whether the driver should handle, ignore, or
|
||||
* drop the frame
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev wlan device structure
|
||||
* fc frame control field
|
||||
*
|
||||
* Returns:
|
||||
* zero if the frame should be handled by the driver,
|
||||
* one if the frame should be ignored
|
||||
* anything else means we drop it.
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Call context:
|
||||
* interrupt
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
|
||||
{
|
||||
u16 ftype;
|
||||
u16 fstype;
|
||||
int drop = 0;
|
||||
/* Classify frame, increment counter */
|
||||
ftype = WLAN_GET_FC_FTYPE(fc);
|
||||
fstype = WLAN_GET_FC_FSTYPE(fc);
|
||||
switch (ftype) {
|
||||
case WLAN_FTYPE_MGMT:
|
||||
if ((wlandev->netdev->flags & IFF_PROMISC) ||
|
||||
(wlandev->netdev->flags & IFF_ALLMULTI)) {
|
||||
drop = 1;
|
||||
break;
|
||||
}
|
||||
netdev_dbg(wlandev->netdev, "rx'd mgmt:\n");
|
||||
wlandev->rx.mgmt++;
|
||||
switch (fstype) {
|
||||
case WLAN_FSTYPE_ASSOCREQ:
|
||||
wlandev->rx.assocreq++;
|
||||
break;
|
||||
case WLAN_FSTYPE_ASSOCRESP:
|
||||
wlandev->rx.assocresp++;
|
||||
break;
|
||||
case WLAN_FSTYPE_REASSOCREQ:
|
||||
wlandev->rx.reassocreq++;
|
||||
break;
|
||||
case WLAN_FSTYPE_REASSOCRESP:
|
||||
wlandev->rx.reassocresp++;
|
||||
break;
|
||||
case WLAN_FSTYPE_PROBEREQ:
|
||||
wlandev->rx.probereq++;
|
||||
break;
|
||||
case WLAN_FSTYPE_PROBERESP:
|
||||
wlandev->rx.proberesp++;
|
||||
break;
|
||||
case WLAN_FSTYPE_BEACON:
|
||||
wlandev->rx.beacon++;
|
||||
break;
|
||||
case WLAN_FSTYPE_ATIM:
|
||||
wlandev->rx.atim++;
|
||||
break;
|
||||
case WLAN_FSTYPE_DISASSOC:
|
||||
wlandev->rx.disassoc++;
|
||||
break;
|
||||
case WLAN_FSTYPE_AUTHEN:
|
||||
wlandev->rx.authen++;
|
||||
break;
|
||||
case WLAN_FSTYPE_DEAUTHEN:
|
||||
wlandev->rx.deauthen++;
|
||||
break;
|
||||
default:
|
||||
wlandev->rx.mgmt_unknown++;
|
||||
break;
|
||||
}
|
||||
drop = 2;
|
||||
break;
|
||||
|
||||
case WLAN_FTYPE_CTL:
|
||||
if ((wlandev->netdev->flags & IFF_PROMISC) ||
|
||||
(wlandev->netdev->flags & IFF_ALLMULTI)) {
|
||||
drop = 1;
|
||||
break;
|
||||
}
|
||||
netdev_dbg(wlandev->netdev, "rx'd ctl:\n");
|
||||
wlandev->rx.ctl++;
|
||||
switch (fstype) {
|
||||
case WLAN_FSTYPE_PSPOLL:
|
||||
wlandev->rx.pspoll++;
|
||||
break;
|
||||
case WLAN_FSTYPE_RTS:
|
||||
wlandev->rx.rts++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CTS:
|
||||
wlandev->rx.cts++;
|
||||
break;
|
||||
case WLAN_FSTYPE_ACK:
|
||||
wlandev->rx.ack++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CFEND:
|
||||
wlandev->rx.cfend++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CFENDCFACK:
|
||||
wlandev->rx.cfendcfack++;
|
||||
break;
|
||||
default:
|
||||
wlandev->rx.ctl_unknown++;
|
||||
break;
|
||||
}
|
||||
drop = 2;
|
||||
break;
|
||||
|
||||
case WLAN_FTYPE_DATA:
|
||||
wlandev->rx.data++;
|
||||
switch (fstype) {
|
||||
case WLAN_FSTYPE_DATAONLY:
|
||||
wlandev->rx.dataonly++;
|
||||
break;
|
||||
case WLAN_FSTYPE_DATA_CFACK:
|
||||
wlandev->rx.data_cfack++;
|
||||
break;
|
||||
case WLAN_FSTYPE_DATA_CFPOLL:
|
||||
wlandev->rx.data_cfpoll++;
|
||||
break;
|
||||
case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
|
||||
wlandev->rx.data__cfack_cfpoll++;
|
||||
break;
|
||||
case WLAN_FSTYPE_NULL:
|
||||
netdev_dbg(wlandev->netdev, "rx'd data:null\n");
|
||||
wlandev->rx.null++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CFACK:
|
||||
netdev_dbg(wlandev->netdev, "rx'd data:cfack\n");
|
||||
wlandev->rx.cfack++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CFPOLL:
|
||||
netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n");
|
||||
wlandev->rx.cfpoll++;
|
||||
break;
|
||||
case WLAN_FSTYPE_CFACK_CFPOLL:
|
||||
netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n");
|
||||
wlandev->rx.cfack_cfpoll++;
|
||||
break;
|
||||
default:
|
||||
wlandev->rx.data_unknown++;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return drop;
|
||||
}
|
||||
|
||||
static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue)
|
||||
{
|
||||
struct wlandevice *wlandev = netdev->ml_priv;
|
||||
|
||||
if (wlandev->tx_timeout) {
|
||||
wlandev->tx_timeout(wlandev);
|
||||
} else {
|
||||
netdev_warn(netdev, "Implement tx_timeout for %s\n",
|
||||
wlandev->nsdname);
|
||||
netif_wake_queue(wlandev->netdev);
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* WLAN net device structure and functions
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file declares the structure type that represents each wlan
|
||||
* interface.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_P80211NETDEV_H
|
||||
#define _LINUX_P80211NETDEV_H
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#define WLAN_RELEASE "0.3.0-staging"
|
||||
|
||||
#define WLAN_DEVICE_CLOSED 0
|
||||
#define WLAN_DEVICE_OPEN 1
|
||||
|
||||
#define WLAN_MACMODE_NONE 0
|
||||
#define WLAN_MACMODE_IBSS_STA 1
|
||||
#define WLAN_MACMODE_ESS_STA 2
|
||||
#define WLAN_MACMODE_ESS_AP 3
|
||||
|
||||
/* MSD States */
|
||||
#define WLAN_MSD_HWPRESENT_PENDING 1
|
||||
#define WLAN_MSD_HWFAIL 2
|
||||
#define WLAN_MSD_HWPRESENT 3
|
||||
#define WLAN_MSD_FWLOAD_PENDING 4
|
||||
#define WLAN_MSD_FWLOAD 5
|
||||
#define WLAN_MSD_RUNNING_PENDING 6
|
||||
#define WLAN_MSD_RUNNING 7
|
||||
|
||||
#ifndef ETH_P_ECONET
|
||||
#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
|
||||
#endif
|
||||
|
||||
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
|
||||
|
||||
#ifndef ARPHRD_IEEE80211
|
||||
#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
|
||||
#endif
|
||||
|
||||
#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
|
||||
#define ARPHRD_IEEE80211_PRISM 802
|
||||
#endif
|
||||
|
||||
/*--- NSD Capabilities Flags ------------------------------*/
|
||||
#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
|
||||
#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
|
||||
#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */
|
||||
#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */
|
||||
#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
|
||||
|
||||
/* Received frame statistics */
|
||||
struct p80211_frmrx {
|
||||
u32 mgmt;
|
||||
u32 assocreq;
|
||||
u32 assocresp;
|
||||
u32 reassocreq;
|
||||
u32 reassocresp;
|
||||
u32 probereq;
|
||||
u32 proberesp;
|
||||
u32 beacon;
|
||||
u32 atim;
|
||||
u32 disassoc;
|
||||
u32 authen;
|
||||
u32 deauthen;
|
||||
u32 mgmt_unknown;
|
||||
u32 ctl;
|
||||
u32 pspoll;
|
||||
u32 rts;
|
||||
u32 cts;
|
||||
u32 ack;
|
||||
u32 cfend;
|
||||
u32 cfendcfack;
|
||||
u32 ctl_unknown;
|
||||
u32 data;
|
||||
u32 dataonly;
|
||||
u32 data_cfack;
|
||||
u32 data_cfpoll;
|
||||
u32 data__cfack_cfpoll;
|
||||
u32 null;
|
||||
u32 cfack;
|
||||
u32 cfpoll;
|
||||
u32 cfack_cfpoll;
|
||||
u32 data_unknown;
|
||||
u32 decrypt;
|
||||
u32 decrypt_err;
|
||||
};
|
||||
|
||||
/* WEP stuff */
|
||||
#define NUM_WEPKEYS 4
|
||||
#define MAX_KEYLEN 32
|
||||
|
||||
#define HOSTWEP_DEFAULTKEY_MASK GENMASK(1, 0)
|
||||
#define HOSTWEP_SHAREDKEY BIT(3)
|
||||
#define HOSTWEP_DECRYPT BIT(4)
|
||||
#define HOSTWEP_ENCRYPT BIT(5)
|
||||
#define HOSTWEP_PRIVACYINVOKED BIT(6)
|
||||
#define HOSTWEP_EXCLUDEUNENCRYPTED BIT(7)
|
||||
|
||||
extern int wlan_watchdog;
|
||||
extern int wlan_wext_write;
|
||||
|
||||
/* WLAN device type */
|
||||
struct wlandevice {
|
||||
void *priv; /* private data for MSD */
|
||||
|
||||
/* Subsystem State */
|
||||
char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev() */
|
||||
char *nsdname;
|
||||
|
||||
u32 state; /* Device I/F state (open/closed) */
|
||||
u32 msdstate; /* state of underlying driver */
|
||||
u32 hwremoved; /* Has the hw been yanked out? */
|
||||
|
||||
/* Hardware config */
|
||||
unsigned int irq;
|
||||
unsigned int iobase;
|
||||
unsigned int membase;
|
||||
u32 nsdcaps; /* NSD Capabilities flags */
|
||||
|
||||
/* Config vars */
|
||||
unsigned int ethconv;
|
||||
|
||||
/* device methods (init by MSD, used by p80211 */
|
||||
int (*open)(struct wlandevice *wlandev);
|
||||
int (*close)(struct wlandevice *wlandev);
|
||||
void (*reset)(struct wlandevice *wlandev);
|
||||
int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb,
|
||||
struct p80211_hdr *p80211_hdr,
|
||||
struct p80211_metawep *p80211_wep);
|
||||
int (*mlmerequest)(struct wlandevice *wlandev, struct p80211msg *msg);
|
||||
int (*set_multicast_list)(struct wlandevice *wlandev,
|
||||
struct net_device *dev);
|
||||
void (*tx_timeout)(struct wlandevice *wlandev);
|
||||
|
||||
/* 802.11 State */
|
||||
u8 bssid[WLAN_BSSID_LEN];
|
||||
struct p80211pstr32 ssid;
|
||||
u32 macmode;
|
||||
int linkstatus;
|
||||
|
||||
/* WEP State */
|
||||
u8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
|
||||
u8 wep_keylens[NUM_WEPKEYS];
|
||||
int hostwep;
|
||||
|
||||
/* Request/Confirm i/f state (used by p80211) */
|
||||
unsigned long request_pending; /* flag, access atomically */
|
||||
|
||||
/* netlink socket */
|
||||
/* queue for indications waiting for cmd completion */
|
||||
/* Linux netdevice and support */
|
||||
struct net_device *netdev; /* ptr to linux netdevice */
|
||||
|
||||
/* Rx bottom half */
|
||||
struct tasklet_struct rx_bh;
|
||||
|
||||
struct sk_buff_head nsd_rxq;
|
||||
|
||||
/* 802.11 device statistics */
|
||||
struct p80211_frmrx rx;
|
||||
|
||||
struct iw_statistics wstats;
|
||||
|
||||
/* jkriegl: iwspy fields */
|
||||
u8 spy_number;
|
||||
char spy_address[IW_MAX_SPY][ETH_ALEN];
|
||||
struct iw_quality spy_stat[IW_MAX_SPY];
|
||||
};
|
||||
|
||||
/* WEP stuff */
|
||||
int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen);
|
||||
int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override,
|
||||
u8 *iv, u8 *icv);
|
||||
int wep_encrypt(struct wlandevice *wlandev, u8 *buf, u8 *dst, u32 len,
|
||||
int keynum, u8 *iv, u8 *icv);
|
||||
|
||||
int wlan_setup(struct wlandevice *wlandev, struct device *physdev);
|
||||
void wlan_unsetup(struct wlandevice *wlandev);
|
||||
int register_wlandev(struct wlandevice *wlandev);
|
||||
int unregister_wlandev(struct wlandevice *wlandev);
|
||||
void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb);
|
||||
void p80211netdev_hwremoved(struct wlandevice *wlandev);
|
||||
#endif
|
@ -1,223 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
|
||||
/*
|
||||
*
|
||||
* Request/Indication/MacMgmt interface handling functions
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file contains the functions, types, and macros to support the
|
||||
* MLME request interface that's implemented via the device ioctls.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#include "p80211types.h"
|
||||
#include "p80211hdr.h"
|
||||
#include "p80211mgmt.h"
|
||||
#include "p80211conv.h"
|
||||
#include "p80211msg.h"
|
||||
#include "p80211netdev.h"
|
||||
#include "p80211ioctl.h"
|
||||
#include "p80211metadef.h"
|
||||
#include "p80211metastruct.h"
|
||||
#include "p80211req.h"
|
||||
|
||||
static void p80211req_handlemsg(struct wlandevice *wlandev,
|
||||
struct p80211msg *msg);
|
||||
static void p80211req_mibset_mibget(struct wlandevice *wlandev,
|
||||
struct p80211msg_dot11req_mibget *mib_msg,
|
||||
int isget);
|
||||
|
||||
static void p80211req_handle_action(struct wlandevice *wlandev, u32 *data,
|
||||
int isget, u32 flag)
|
||||
{
|
||||
if (isget) {
|
||||
if (wlandev->hostwep & flag)
|
||||
*data = P80211ENUM_truth_true;
|
||||
else
|
||||
*data = P80211ENUM_truth_false;
|
||||
} else {
|
||||
wlandev->hostwep &= ~flag;
|
||||
if (*data == P80211ENUM_truth_true)
|
||||
wlandev->hostwep |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211req_dorequest
|
||||
*
|
||||
* Handles an MLME request/confirm message.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev WLAN device struct
|
||||
* msgbuf Buffer containing a request message
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, an errno otherwise
|
||||
*
|
||||
* Call context:
|
||||
* Potentially blocks the caller, so it's a good idea to
|
||||
* not call this function from an interrupt context.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf)
|
||||
{
|
||||
struct p80211msg *msg = (struct p80211msg *)msgbuf;
|
||||
|
||||
/* Check to make sure the MSD is running */
|
||||
if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
|
||||
msg->msgcode == DIDMSG_LNXREQ_IFSTATE) ||
|
||||
wlandev->msdstate == WLAN_MSD_RUNNING ||
|
||||
wlandev->msdstate == WLAN_MSD_FWLOAD)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Check Permissions */
|
||||
if (!capable(CAP_NET_ADMIN) &&
|
||||
(msg->msgcode != DIDMSG_DOT11REQ_MIBGET)) {
|
||||
netdev_err(wlandev->netdev,
|
||||
"%s: only dot11req_mibget allowed for non-root.\n",
|
||||
wlandev->name);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Check for busy status */
|
||||
if (test_and_set_bit(1, &wlandev->request_pending))
|
||||
return -EBUSY;
|
||||
|
||||
/* Allow p80211 to look at msg and handle if desired. */
|
||||
/* So far, all p80211 msgs are immediate, no waitq/timer necessary */
|
||||
/* This may change. */
|
||||
p80211req_handlemsg(wlandev, msg);
|
||||
|
||||
/* Pass it down to wlandev via wlandev->mlmerequest */
|
||||
if (wlandev->mlmerequest)
|
||||
wlandev->mlmerequest(wlandev, msg);
|
||||
|
||||
clear_bit(1, &wlandev->request_pending);
|
||||
return 0; /* if result==0, msg->status still may contain an err */
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211req_handlemsg
|
||||
*
|
||||
* p80211 message handler. Primarily looks for messages that
|
||||
* belong to p80211 and then dispatches the appropriate response.
|
||||
* TODO: we don't do anything yet. Once the linuxMIB is better
|
||||
* defined we'll need a get/set handler.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev WLAN device struct
|
||||
* msg message structure
|
||||
*
|
||||
* Returns:
|
||||
* nothing (any results are set in the status field of the msg)
|
||||
*
|
||||
* Call context:
|
||||
* Process thread
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
static void p80211req_handlemsg(struct wlandevice *wlandev,
|
||||
struct p80211msg *msg)
|
||||
{
|
||||
switch (msg->msgcode) {
|
||||
case DIDMSG_LNXREQ_HOSTWEP: {
|
||||
struct p80211msg_lnxreq_hostwep *req =
|
||||
(struct p80211msg_lnxreq_hostwep *)msg;
|
||||
wlandev->hostwep &=
|
||||
~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT);
|
||||
if (req->decrypt.data == P80211ENUM_truth_true)
|
||||
wlandev->hostwep |= HOSTWEP_DECRYPT;
|
||||
if (req->encrypt.data == P80211ENUM_truth_true)
|
||||
wlandev->hostwep |= HOSTWEP_ENCRYPT;
|
||||
|
||||
break;
|
||||
}
|
||||
case DIDMSG_DOT11REQ_MIBGET:
|
||||
case DIDMSG_DOT11REQ_MIBSET: {
|
||||
int isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
|
||||
struct p80211msg_dot11req_mibget *mib_msg =
|
||||
(struct p80211msg_dot11req_mibget *)msg;
|
||||
p80211req_mibset_mibget(wlandev, mib_msg, isget);
|
||||
break;
|
||||
}
|
||||
} /* switch msg->msgcode */
|
||||
}
|
||||
|
||||
static void p80211req_mibset_mibget(struct wlandevice *wlandev,
|
||||
struct p80211msg_dot11req_mibget *mib_msg,
|
||||
int isget)
|
||||
{
|
||||
struct p80211itemd *mibitem =
|
||||
(struct p80211itemd *)mib_msg->mibattribute.data;
|
||||
struct p80211pstrd *pstr = (struct p80211pstrd *)mibitem->data;
|
||||
u8 *key = mibitem->data + sizeof(struct p80211pstrd);
|
||||
|
||||
switch (mibitem->did) {
|
||||
case didmib_dot11smt_wepdefaultkeystable_key(1):
|
||||
case didmib_dot11smt_wepdefaultkeystable_key(2):
|
||||
case didmib_dot11smt_wepdefaultkeystable_key(3):
|
||||
case didmib_dot11smt_wepdefaultkeystable_key(4):
|
||||
if (!isget)
|
||||
wep_change_key(wlandev,
|
||||
P80211DID_ITEM(mibitem->did) - 1,
|
||||
key, pstr->len);
|
||||
break;
|
||||
|
||||
case DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID: {
|
||||
u32 *data = (u32 *)mibitem->data;
|
||||
|
||||
if (isget) {
|
||||
*data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
|
||||
} else {
|
||||
wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
|
||||
wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED: {
|
||||
u32 *data = (u32 *)mibitem->data;
|
||||
|
||||
p80211req_handle_action(wlandev, data, isget,
|
||||
HOSTWEP_PRIVACYINVOKED);
|
||||
break;
|
||||
}
|
||||
case DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED: {
|
||||
u32 *data = (u32 *)mibitem->data;
|
||||
|
||||
p80211req_handle_action(wlandev, data, isget,
|
||||
HOSTWEP_EXCLUDEUNENCRYPTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Request handling functions
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_P80211REQ_H
|
||||
#define _LINUX_P80211REQ_H
|
||||
|
||||
int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf);
|
||||
|
||||
#endif
|
@ -1,292 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Macros, constants, types, and funcs for p80211 data types
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file declares some of the constants and types used in various
|
||||
* parts of the linux-wlan system.
|
||||
*
|
||||
* Notes:
|
||||
* - Constant values are always in HOST byte order.
|
||||
*
|
||||
* All functions and statics declared here are implemented in p80211types.c
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _P80211TYPES_H
|
||||
#define _P80211TYPES_H
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* The following constants are indexes into the Mib Category List */
|
||||
/* and the Message Category List */
|
||||
|
||||
/* Mib Category List */
|
||||
#define P80211_MIB_CAT_DOT11SMT 1
|
||||
#define P80211_MIB_CAT_DOT11MAC 2
|
||||
#define P80211_MIB_CAT_DOT11PHY 3
|
||||
|
||||
#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT
|
||||
#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC
|
||||
#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY
|
||||
|
||||
/* Message Category List */
|
||||
#define P80211_MSG_CAT_DOT11REQ 1
|
||||
#define P80211_MSG_CAT_DOT11IND 2
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* p80211 enumeration constants. The value to text mappings for */
|
||||
/* these is in p80211types.c. These defines were generated */
|
||||
/* from the mappings. */
|
||||
|
||||
/* error codes for lookups */
|
||||
|
||||
#define P80211ENUM_truth_false 0
|
||||
#define P80211ENUM_truth_true 1
|
||||
#define P80211ENUM_ifstate_disable 0
|
||||
#define P80211ENUM_ifstate_fwload 1
|
||||
#define P80211ENUM_ifstate_enable 2
|
||||
#define P80211ENUM_bsstype_infrastructure 1
|
||||
#define P80211ENUM_bsstype_independent 2
|
||||
#define P80211ENUM_bsstype_any 3
|
||||
#define P80211ENUM_authalg_opensystem 1
|
||||
#define P80211ENUM_authalg_sharedkey 2
|
||||
#define P80211ENUM_scantype_active 1
|
||||
#define P80211ENUM_resultcode_success 1
|
||||
#define P80211ENUM_resultcode_invalid_parameters 2
|
||||
#define P80211ENUM_resultcode_not_supported 3
|
||||
#define P80211ENUM_resultcode_refused 6
|
||||
#define P80211ENUM_resultcode_cant_set_readonly_mib 10
|
||||
#define P80211ENUM_resultcode_implementation_failure 11
|
||||
#define P80211ENUM_resultcode_cant_get_writeonly_mib 12
|
||||
#define P80211ENUM_status_successful 0
|
||||
#define P80211ENUM_status_unspec_failure 1
|
||||
#define P80211ENUM_status_ap_full 17
|
||||
#define P80211ENUM_msgitem_status_data_ok 0
|
||||
#define P80211ENUM_msgitem_status_no_value 1
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* p80211 max length constants for the different pascal strings. */
|
||||
|
||||
#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */
|
||||
#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */
|
||||
#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */
|
||||
#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */
|
||||
#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */
|
||||
/* where the size of the DATA itself */
|
||||
/* is a DID-LEN-DATA triple */
|
||||
/* with a max size of 4+4+384 */
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* The following constants and macros are used to construct and
|
||||
* deconstruct the Data ID codes. The coding is as follows:
|
||||
*
|
||||
* ...rwtnnnnnnnniiiiiiggggggssssss s - Section
|
||||
* g - Group
|
||||
* i - Item
|
||||
* n - Index
|
||||
* t - Table flag
|
||||
* w - Write flag
|
||||
* r - Read flag
|
||||
* . - Unused
|
||||
*/
|
||||
|
||||
#define P80211DID_LSB_SECTION (0)
|
||||
#define P80211DID_LSB_GROUP (6)
|
||||
#define P80211DID_LSB_ITEM (12)
|
||||
#define P80211DID_LSB_INDEX (18)
|
||||
#define P80211DID_LSB_ISTABLE (26)
|
||||
#define P80211DID_LSB_ACCESS (27)
|
||||
|
||||
#define P80211DID_MASK_SECTION (0x0000003fUL)
|
||||
#define P80211DID_MASK_GROUP (0x0000003fUL)
|
||||
#define P80211DID_MASK_ITEM (0x0000003fUL)
|
||||
#define P80211DID_MASK_INDEX (0x000000ffUL)
|
||||
#define P80211DID_MASK_ISTABLE (0x00000001UL)
|
||||
#define P80211DID_MASK_ACCESS (0x00000003UL)
|
||||
|
||||
#define P80211DID_MK(a, m, l) ((((u32)(a)) & (m)) << (l))
|
||||
|
||||
#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
|
||||
P80211DID_MASK_SECTION, \
|
||||
P80211DID_LSB_SECTION)
|
||||
#define P80211DID_MKGROUP(a) P80211DID_MK(a, \
|
||||
P80211DID_MASK_GROUP, \
|
||||
P80211DID_LSB_GROUP)
|
||||
#define P80211DID_MKITEM(a) P80211DID_MK(a, \
|
||||
P80211DID_MASK_ITEM, \
|
||||
P80211DID_LSB_ITEM)
|
||||
#define P80211DID_MKINDEX(a) P80211DID_MK(a, \
|
||||
P80211DID_MASK_INDEX, \
|
||||
P80211DID_LSB_INDEX)
|
||||
#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
|
||||
P80211DID_MASK_ISTABLE, \
|
||||
P80211DID_LSB_ISTABLE)
|
||||
|
||||
#define P80211DID_MKID(s, g, i, n, t, a) (P80211DID_MKSECTION(s) | \
|
||||
P80211DID_MKGROUP(g) | \
|
||||
P80211DID_MKITEM(i) | \
|
||||
P80211DID_MKINDEX(n) | \
|
||||
P80211DID_MKISTABLE(t) | \
|
||||
(a))
|
||||
|
||||
#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m))
|
||||
|
||||
#define P80211DID_SECTION(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_SECTION, \
|
||||
P80211DID_LSB_SECTION)
|
||||
#define P80211DID_GROUP(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_GROUP, \
|
||||
P80211DID_LSB_GROUP)
|
||||
#define P80211DID_ITEM(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_ITEM, \
|
||||
P80211DID_LSB_ITEM)
|
||||
#define P80211DID_INDEX(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_INDEX, \
|
||||
P80211DID_LSB_INDEX)
|
||||
#define P80211DID_ISTABLE(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_ISTABLE, \
|
||||
P80211DID_LSB_ISTABLE)
|
||||
#define P80211DID_ACCESS(a) P80211DID_GET(a, \
|
||||
P80211DID_MASK_ACCESS, \
|
||||
P80211DID_LSB_ACCESS)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/* The following structure types are used to store data items in */
|
||||
/* messages. */
|
||||
|
||||
/* Template pascal string */
|
||||
struct p80211pstr {
|
||||
u8 len;
|
||||
} __packed;
|
||||
|
||||
struct p80211pstrd {
|
||||
u8 len;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/* Maximum pascal string */
|
||||
struct p80211pstr255 {
|
||||
u8 len;
|
||||
u8 data[MAXLEN_PSTR255];
|
||||
} __packed;
|
||||
|
||||
/* pascal string for macaddress and bssid */
|
||||
struct p80211pstr6 {
|
||||
u8 len;
|
||||
u8 data[MAXLEN_PSTR6];
|
||||
} __packed;
|
||||
|
||||
/* pascal string for channel list */
|
||||
struct p80211pstr14 {
|
||||
u8 len;
|
||||
u8 data[MAXLEN_PSTR14];
|
||||
} __packed;
|
||||
|
||||
/* pascal string for ssid */
|
||||
struct p80211pstr32 {
|
||||
u8 len;
|
||||
u8 data[MAXLEN_PSTR32];
|
||||
} __packed;
|
||||
|
||||
/* prototype template */
|
||||
struct p80211item {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
} __packed;
|
||||
|
||||
/* prototype template w/ data item */
|
||||
struct p80211itemd {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/* message data item for int, BOUNDEDINT, ENUMINT */
|
||||
struct p80211item_uint32 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
u32 data;
|
||||
} __packed;
|
||||
|
||||
/* message data item for OCTETSTR, DISPLAYSTR */
|
||||
struct p80211item_pstr6 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
struct p80211pstr6 data;
|
||||
} __packed;
|
||||
|
||||
/* message data item for OCTETSTR, DISPLAYSTR */
|
||||
struct p80211item_pstr14 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
struct p80211pstr14 data;
|
||||
} __packed;
|
||||
|
||||
/* message data item for OCTETSTR, DISPLAYSTR */
|
||||
struct p80211item_pstr32 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
struct p80211pstr32 data;
|
||||
} __packed;
|
||||
|
||||
/* message data item for OCTETSTR, DISPLAYSTR */
|
||||
struct p80211item_pstr255 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
struct p80211pstr255 data;
|
||||
} __packed;
|
||||
|
||||
/* message data item for UNK 392, namely mib items */
|
||||
struct p80211item_unk392 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
u8 data[MAXLEN_MIBATTRIBUTE];
|
||||
} __packed;
|
||||
|
||||
/* message data item for UNK 1025, namely p2 pdas */
|
||||
struct p80211item_unk1024 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
u8 data[1024];
|
||||
} __packed;
|
||||
|
||||
/* message data item for UNK 4096, namely p2 download chunks */
|
||||
struct p80211item_unk4096 {
|
||||
u32 did;
|
||||
u16 status;
|
||||
u16 len;
|
||||
u8 data[4096];
|
||||
} __packed;
|
||||
|
||||
#endif /* _P80211TYPES_H */
|
@ -1,207 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
|
||||
/*
|
||||
*
|
||||
* WEP encode/decode for P80211.
|
||||
*
|
||||
* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*================================================================*/
|
||||
/* System Includes */
|
||||
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "p80211hdr.h"
|
||||
#include "p80211types.h"
|
||||
#include "p80211msg.h"
|
||||
#include "p80211conv.h"
|
||||
#include "p80211netdev.h"
|
||||
|
||||
#define WEP_KEY(x) (((x) & 0xC0) >> 6)
|
||||
|
||||
/* keylen in bytes! */
|
||||
|
||||
int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen)
|
||||
{
|
||||
if (keylen < 0)
|
||||
return -1;
|
||||
if (keylen >= MAX_KEYLEN)
|
||||
return -1;
|
||||
if (!key)
|
||||
return -1;
|
||||
if (keynum < 0)
|
||||
return -1;
|
||||
if (keynum >= NUM_WEPKEYS)
|
||||
return -1;
|
||||
|
||||
wlandev->wep_keylens[keynum] = keylen;
|
||||
memcpy(wlandev->wep_keys[keynum], key, keylen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 4-byte IV at start of buffer, 4-byte ICV at end of buffer.
|
||||
* if successful, buf start is payload begin, length -= 8;
|
||||
*/
|
||||
int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override,
|
||||
u8 *iv, u8 *icv)
|
||||
{
|
||||
u32 i, j, k, crc, keylen;
|
||||
u8 s[256], key[64], c_crc[4];
|
||||
u8 keyidx;
|
||||
|
||||
/* Needs to be at least 8 bytes of payload */
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
|
||||
/* initialize the first bytes of the key from the IV */
|
||||
key[0] = iv[0];
|
||||
key[1] = iv[1];
|
||||
key[2] = iv[2];
|
||||
keyidx = WEP_KEY(iv[3]);
|
||||
|
||||
if (key_override >= 0)
|
||||
keyidx = key_override;
|
||||
|
||||
if (keyidx >= NUM_WEPKEYS)
|
||||
return -2;
|
||||
|
||||
keylen = wlandev->wep_keylens[keyidx];
|
||||
|
||||
if (keylen == 0)
|
||||
return -3;
|
||||
|
||||
/* copy the rest of the key over from the designated key */
|
||||
memcpy(key + 3, wlandev->wep_keys[keyidx], keylen);
|
||||
|
||||
keylen += 3; /* add in IV bytes */
|
||||
|
||||
/* set up the RC4 state */
|
||||
for (i = 0; i < 256; i++)
|
||||
s[i] = i;
|
||||
j = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
j = (j + s[i] + key[i % keylen]) & 0xff;
|
||||
swap(i, j);
|
||||
}
|
||||
|
||||
/* Apply the RC4 to the data, update the CRC32 */
|
||||
i = 0;
|
||||
j = 0;
|
||||
for (k = 0; k < len; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + s[i]) & 0xff;
|
||||
swap(i, j);
|
||||
buf[k] ^= s[(s[i] + s[j]) & 0xff];
|
||||
}
|
||||
crc = ~crc32_le(~0, buf, len);
|
||||
|
||||
/* now let's check the crc */
|
||||
c_crc[0] = crc;
|
||||
c_crc[1] = crc >> 8;
|
||||
c_crc[2] = crc >> 16;
|
||||
c_crc[3] = crc >> 24;
|
||||
|
||||
for (k = 0; k < 4; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + s[i]) & 0xff;
|
||||
swap(i, j);
|
||||
if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
|
||||
return -(4 | (k << 4)); /* ICV mismatch */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encrypts in-place. */
|
||||
int wep_encrypt(struct wlandevice *wlandev, u8 *buf,
|
||||
u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv)
|
||||
{
|
||||
u32 i, j, k, crc, keylen;
|
||||
u8 s[256], key[64];
|
||||
|
||||
/* no point in WEPping an empty frame */
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
|
||||
/* we need to have a real key.. */
|
||||
if (keynum >= NUM_WEPKEYS)
|
||||
return -2;
|
||||
keylen = wlandev->wep_keylens[keynum];
|
||||
if (keylen <= 0)
|
||||
return -3;
|
||||
|
||||
/* use a random IV. And skip known weak ones. */
|
||||
get_random_bytes(iv, 3);
|
||||
while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen))
|
||||
get_random_bytes(iv, 3);
|
||||
|
||||
iv[3] = (keynum & 0x03) << 6;
|
||||
|
||||
key[0] = iv[0];
|
||||
key[1] = iv[1];
|
||||
key[2] = iv[2];
|
||||
|
||||
/* copy the rest of the key over from the designated key */
|
||||
memcpy(key + 3, wlandev->wep_keys[keynum], keylen);
|
||||
|
||||
keylen += 3; /* add in IV bytes */
|
||||
|
||||
/* set up the RC4 state */
|
||||
for (i = 0; i < 256; i++)
|
||||
s[i] = i;
|
||||
j = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
j = (j + s[i] + key[i % keylen]) & 0xff;
|
||||
swap(i, j);
|
||||
}
|
||||
|
||||
/* Update CRC32 then apply RC4 to the data */
|
||||
i = 0;
|
||||
j = 0;
|
||||
for (k = 0; k < len; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + s[i]) & 0xff;
|
||||
swap(i, j);
|
||||
dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
|
||||
}
|
||||
crc = ~crc32_le(~0, buf, len);
|
||||
|
||||
/* now let's encrypt the crc */
|
||||
icv[0] = crc;
|
||||
icv[1] = crc >> 8;
|
||||
icv[2] = crc >> 16;
|
||||
icv[3] = crc >> 24;
|
||||
|
||||
for (k = 0; k < 4; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + s[i]) & 0xff;
|
||||
swap(i, j);
|
||||
icv[k] ^= s[(s[i] + s[j]) & 0xff];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
|
||||
/*
|
||||
*
|
||||
* Declares the mgmt command handler functions
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This file contains the constants and data structures for interaction
|
||||
* with the hfa384x Wireless LAN (WLAN) Media Access Controller (MAC).
|
||||
* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
|
||||
*
|
||||
* [Implementation and usage notes]
|
||||
*
|
||||
* [References]
|
||||
* CW10 Programmer's Manual v1.5
|
||||
* IEEE 802.11 D10.0
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _PRISM2MGMT_H
|
||||
#define _PRISM2MGMT_H
|
||||
|
||||
extern int prism2_reset_holdtime;
|
||||
extern int prism2_reset_settletime;
|
||||
|
||||
u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate);
|
||||
|
||||
void prism2sta_ev_info(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf);
|
||||
void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status);
|
||||
void prism2sta_ev_alloc(struct wlandevice *wlandev);
|
||||
|
||||
int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_start(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp);
|
||||
int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
* conversion functions going between wlan message data types and
|
||||
* Prism2 data types
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* byte area conversion functions*/
|
||||
void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len);
|
||||
|
||||
/* byte string conversion functions*/
|
||||
void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
|
||||
struct p80211pstrd *pstr);
|
||||
void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
|
||||
struct p80211pstrd *pstr);
|
||||
|
||||
void prism2sta_processing_defer(struct work_struct *data);
|
||||
|
||||
void prism2sta_commsqual_defer(struct work_struct *data);
|
||||
void prism2sta_commsqual_timer(struct timer_list *t);
|
||||
|
||||
/* Interface callback functions, passing data back up to the cfg80211 layer */
|
||||
void prism2_connect_result(struct wlandevice *wlandev, u8 failed);
|
||||
void prism2_disconnected(struct wlandevice *wlandev);
|
||||
void prism2_roamed(struct wlandevice *wlandev);
|
||||
|
||||
#endif
|
@ -1,742 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
|
||||
/*
|
||||
*
|
||||
* Management request for mibset/mibget
|
||||
*
|
||||
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* linux-wlan
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Inquiries regarding the linux-wlan Open Source project can be
|
||||
* made directly to:
|
||||
*
|
||||
* AbsoluteValue Systems Inc.
|
||||
* info@linux-wlan.com
|
||||
* http://www.linux-wlan.com
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Portions of the development of this software were funded by
|
||||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* The functions in this file handle the mibset/mibget management
|
||||
* functions.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "p80211types.h"
|
||||
#include "p80211hdr.h"
|
||||
#include "p80211mgmt.h"
|
||||
#include "p80211conv.h"
|
||||
#include "p80211msg.h"
|
||||
#include "p80211netdev.h"
|
||||
#include "p80211metadef.h"
|
||||
#include "p80211metastruct.h"
|
||||
#include "hfa384x.h"
|
||||
#include "prism2mgmt.h"
|
||||
|
||||
#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
|
||||
|
||||
#define F_STA 0x1 /* MIB is supported on stations. */
|
||||
#define F_READ 0x2 /* MIB may be read. */
|
||||
#define F_WRITE 0x4 /* MIB may be written. */
|
||||
|
||||
struct mibrec {
|
||||
u32 did;
|
||||
u16 flag;
|
||||
u16 parm1;
|
||||
u16 parm2;
|
||||
u16 parm3;
|
||||
int (*func)(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data);
|
||||
};
|
||||
|
||||
static int prism2mib_bytearea2pstr(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data);
|
||||
|
||||
static int prism2mib_uint32(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data);
|
||||
|
||||
static int prism2mib_flag(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data);
|
||||
|
||||
static int prism2mib_wepdefaultkey(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data);
|
||||
|
||||
static int prism2mib_privacyinvoked(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data);
|
||||
|
||||
static int
|
||||
prism2mib_fragmentationthreshold(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data);
|
||||
|
||||
static int prism2mib_priv(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data);
|
||||
|
||||
static struct mibrec mibtab[] = {
|
||||
/* dot11smt MIB's */
|
||||
{didmib_dot11smt_wepdefaultkeystable_key(1),
|
||||
F_STA | F_WRITE,
|
||||
HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
|
||||
prism2mib_wepdefaultkey},
|
||||
{didmib_dot11smt_wepdefaultkeystable_key(2),
|
||||
F_STA | F_WRITE,
|
||||
HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
|
||||
prism2mib_wepdefaultkey},
|
||||
{didmib_dot11smt_wepdefaultkeystable_key(3),
|
||||
F_STA | F_WRITE,
|
||||
HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
|
||||
prism2mib_wepdefaultkey},
|
||||
{didmib_dot11smt_wepdefaultkeystable_key(4),
|
||||
F_STA | F_WRITE,
|
||||
HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
|
||||
prism2mib_wepdefaultkey},
|
||||
{DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
|
||||
prism2mib_privacyinvoked},
|
||||
{DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
|
||||
prism2mib_uint32},
|
||||
{DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
|
||||
prism2mib_flag},
|
||||
|
||||
/* dot11mac MIB's */
|
||||
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
|
||||
prism2mib_bytearea2pstr},
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_RTSTHRESH, 0, 0,
|
||||
prism2mib_uint32},
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT,
|
||||
F_STA | F_READ,
|
||||
HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
|
||||
prism2mib_uint32},
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT,
|
||||
F_STA | F_READ,
|
||||
HFA384x_RID_LONGRETRYLIMIT, 0, 0,
|
||||
prism2mib_uint32},
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_FRAGTHRESH, 0, 0,
|
||||
prism2mib_fragmentationthreshold},
|
||||
{DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME,
|
||||
F_STA | F_READ,
|
||||
HFA384x_RID_MAXTXLIFETIME, 0, 0,
|
||||
prism2mib_uint32},
|
||||
|
||||
/* dot11phy MIB's */
|
||||
|
||||
{DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
|
||||
F_STA | F_READ,
|
||||
HFA384x_RID_CURRENTCHANNEL, 0, 0,
|
||||
prism2mib_uint32},
|
||||
{DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_TXPOWERMAX, 0, 0,
|
||||
prism2mib_uint32},
|
||||
|
||||
/* p2Static MIB's */
|
||||
|
||||
{DIDMIB_P2_STATIC_CNFPORTTYPE,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFPORTTYPE, 0, 0,
|
||||
prism2mib_uint32},
|
||||
|
||||
/* p2MAC MIB's */
|
||||
|
||||
{DIDMIB_P2_MAC_CURRENTTXRATE,
|
||||
F_STA | F_READ,
|
||||
HFA384x_RID_CURRENTTXRATE, 0, 0,
|
||||
prism2mib_uint32},
|
||||
|
||||
/* And finally, lnx mibs */
|
||||
{DIDMIB_LNX_CONFIGTABLE_RSNAIE,
|
||||
F_STA | F_READ | F_WRITE,
|
||||
HFA384x_RID_CNFWPADATA, 0, 0,
|
||||
prism2mib_priv},
|
||||
{0, 0, 0, 0, 0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* prism2mgmt_mibset_mibget
|
||||
*
|
||||
* Set the value of a mib item.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev wlan device structure
|
||||
* msgp ptr to msg buffer
|
||||
*
|
||||
* Returns:
|
||||
* 0 success and done
|
||||
* <0 success, but we're waiting for something to finish.
|
||||
* >0 an error occurred while handling the message.
|
||||
* Side effects:
|
||||
*
|
||||
* Call context:
|
||||
* process thread (usually)
|
||||
* interrupt
|
||||
*/
|
||||
|
||||
int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp)
|
||||
{
|
||||
struct hfa384x *hw = wlandev->priv;
|
||||
int result, isget;
|
||||
struct mibrec *mib;
|
||||
|
||||
u16 which;
|
||||
|
||||
struct p80211msg_dot11req_mibset *msg = msgp;
|
||||
struct p80211itemd *mibitem;
|
||||
|
||||
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
|
||||
msg->resultcode.data = P80211ENUM_resultcode_success;
|
||||
|
||||
/*
|
||||
** Determine if this is an Access Point or a station.
|
||||
*/
|
||||
|
||||
which = F_STA;
|
||||
|
||||
/*
|
||||
** Find the MIB in the MIB table. Note that a MIB may be in the
|
||||
** table twice...once for an AP and once for a station. Make sure
|
||||
** to get the correct one. Note that DID=0 marks the end of the
|
||||
** MIB table.
|
||||
*/
|
||||
|
||||
mibitem = (struct p80211itemd *)msg->mibattribute.data;
|
||||
|
||||
for (mib = mibtab; mib->did != 0; mib++)
|
||||
if (mib->did == mibitem->did && (mib->flag & which))
|
||||
break;
|
||||
|
||||
if (mib->did == 0) {
|
||||
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine if this is a "mibget" or a "mibset". If this is a
|
||||
** "mibget", then make sure that the MIB may be read. Otherwise,
|
||||
** this is a "mibset" so make sure that the MIB may be written.
|
||||
*/
|
||||
|
||||
isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
|
||||
|
||||
if (isget) {
|
||||
if (!(mib->flag & F_READ)) {
|
||||
msg->resultcode.data =
|
||||
P80211ENUM_resultcode_cant_get_writeonly_mib;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (!(mib->flag & F_WRITE)) {
|
||||
msg->resultcode.data =
|
||||
P80211ENUM_resultcode_cant_set_readonly_mib;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Execute the MIB function. If things worked okay, then make
|
||||
** sure that the MIB function also worked okay. If so, and this
|
||||
** is a "mibget", then the status value must be set for both the
|
||||
** "mibattribute" parameter and the mib item within the data
|
||||
** portion of the "mibattribute".
|
||||
*/
|
||||
|
||||
result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data);
|
||||
|
||||
if (msg->resultcode.data == P80211ENUM_resultcode_success) {
|
||||
if (result != 0) {
|
||||
pr_debug("get/set failure, result=%d\n", result);
|
||||
msg->resultcode.data =
|
||||
P80211ENUM_resultcode_implementation_failure;
|
||||
} else {
|
||||
if (isget) {
|
||||
msg->mibattribute.status =
|
||||
P80211ENUM_msgitem_status_data_ok;
|
||||
mibitem->status =
|
||||
P80211ENUM_msgitem_status_data_ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_bytearea2pstr
|
||||
*
|
||||
* Get/set pstr data to/from a byte area.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Number of bytes of RID data.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_bytearea2pstr(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data)
|
||||
{
|
||||
int result;
|
||||
struct p80211pstrd *pstr = data;
|
||||
u8 bytebuf[MIB_TMP_MAXLEN];
|
||||
|
||||
if (isget) {
|
||||
result =
|
||||
hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
|
||||
prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
|
||||
} else {
|
||||
memset(bytebuf, 0, mib->parm2);
|
||||
memcpy(bytebuf, pstr->data, pstr->len);
|
||||
result =
|
||||
hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_uint32
|
||||
*
|
||||
* Get/set uint32 data.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Not used.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_uint32(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data)
|
||||
{
|
||||
int result;
|
||||
u32 *uint32 = data;
|
||||
u8 bytebuf[MIB_TMP_MAXLEN];
|
||||
u16 *wordbuf = (u16 *)bytebuf;
|
||||
|
||||
if (isget) {
|
||||
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
|
||||
*uint32 = *wordbuf;
|
||||
} else {
|
||||
*wordbuf = *uint32;
|
||||
result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_flag
|
||||
*
|
||||
* Get/set a flag.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Bit to get/set.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_flag(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data)
|
||||
{
|
||||
int result;
|
||||
u32 *uint32 = data;
|
||||
u8 bytebuf[MIB_TMP_MAXLEN];
|
||||
u16 *wordbuf = (u16 *)bytebuf;
|
||||
u32 flags;
|
||||
|
||||
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
|
||||
if (result == 0) {
|
||||
flags = *wordbuf;
|
||||
if (isget) {
|
||||
*uint32 = (flags & mib->parm2) ?
|
||||
P80211ENUM_truth_true : P80211ENUM_truth_false;
|
||||
} else {
|
||||
if ((*uint32) == P80211ENUM_truth_true)
|
||||
flags |= mib->parm2;
|
||||
else
|
||||
flags &= ~mib->parm2;
|
||||
*wordbuf = flags;
|
||||
result =
|
||||
hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_wepdefaultkey
|
||||
*
|
||||
* Get/set WEP default keys.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Number of bytes of RID data.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_wepdefaultkey(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data)
|
||||
{
|
||||
int result;
|
||||
struct p80211pstrd *pstr = data;
|
||||
u8 bytebuf[MIB_TMP_MAXLEN];
|
||||
u16 len;
|
||||
|
||||
if (isget) {
|
||||
result = 0; /* Should never happen. */
|
||||
} else {
|
||||
len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
|
||||
HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
|
||||
memset(bytebuf, 0, len);
|
||||
memcpy(bytebuf, pstr->data, pstr->len);
|
||||
result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_privacyinvoked
|
||||
*
|
||||
* Get/set the dot11PrivacyInvoked value.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Bit value for PrivacyInvoked flag.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_privacyinvoked(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data)
|
||||
{
|
||||
if (wlandev->hostwep & HOSTWEP_DECRYPT) {
|
||||
if (wlandev->hostwep & HOSTWEP_DECRYPT)
|
||||
mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
|
||||
if (wlandev->hostwep & HOSTWEP_ENCRYPT)
|
||||
mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT;
|
||||
}
|
||||
|
||||
return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_fragmentationthreshold
|
||||
*
|
||||
* Get/set the fragmentation threshold.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Prism2 RID value.
|
||||
* parm2 Not used.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
prism2mib_fragmentationthreshold(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg,
|
||||
void *data)
|
||||
{
|
||||
u32 *uint32 = data;
|
||||
|
||||
if (!isget)
|
||||
if ((*uint32) % 2) {
|
||||
netdev_warn(wlandev->netdev,
|
||||
"Attempt to set odd number FragmentationThreshold\n");
|
||||
msg->resultcode.data =
|
||||
P80211ENUM_resultcode_not_supported;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mib_priv
|
||||
*
|
||||
* Get/set values in the "priv" data structure.
|
||||
*
|
||||
* MIB record parameters:
|
||||
* parm1 Not used.
|
||||
* parm2 Not used.
|
||||
* parm3 Not used.
|
||||
*
|
||||
* Arguments:
|
||||
* mib MIB record.
|
||||
* isget MIBGET/MIBSET flag.
|
||||
* wlandev wlan device structure.
|
||||
* priv "priv" structure.
|
||||
* hw "hw" structure.
|
||||
* msg Message structure.
|
||||
* data Data buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Success.
|
||||
* ~0 - Error.
|
||||
*
|
||||
*/
|
||||
|
||||
static int prism2mib_priv(struct mibrec *mib,
|
||||
int isget,
|
||||
struct wlandevice *wlandev,
|
||||
struct hfa384x *hw,
|
||||
struct p80211msg_dot11req_mibset *msg, void *data)
|
||||
{
|
||||
struct p80211pstrd *pstr = data;
|
||||
|
||||
switch (mib->did) {
|
||||
case DIDMIB_LNX_CONFIGTABLE_RSNAIE: {
|
||||
/*
|
||||
* This can never work: wpa is on the stack
|
||||
* and has no bytes allocated in wpa.data.
|
||||
*/
|
||||
struct hfa384x_wpa_data wpa;
|
||||
|
||||
if (isget) {
|
||||
hfa384x_drvr_getconfig(hw,
|
||||
HFA384x_RID_CNFWPADATA,
|
||||
(u8 *)&wpa,
|
||||
sizeof(wpa));
|
||||
pstr->len = 0;
|
||||
} else {
|
||||
wpa.datalen = 0;
|
||||
|
||||
hfa384x_drvr_setconfig(hw,
|
||||
HFA384x_RID_CNFWPADATA,
|
||||
(u8 *)&wpa,
|
||||
sizeof(wpa));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
netdev_err(wlandev->netdev, "Unhandled DID 0x%08x\n", mib->did);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mgmt_pstr2bytestr
|
||||
*
|
||||
* Convert the pstr data in the WLAN message structure into an hfa384x
|
||||
* byte string format.
|
||||
*
|
||||
* Arguments:
|
||||
* bytestr hfa384x byte string data type
|
||||
* pstr wlan message data
|
||||
*
|
||||
* Returns:
|
||||
* Nothing
|
||||
*
|
||||
*/
|
||||
|
||||
void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
|
||||
struct p80211pstrd *pstr)
|
||||
{
|
||||
bytestr->len = cpu_to_le16((u16)(pstr->len));
|
||||
memcpy(bytestr->data, pstr->data, pstr->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mgmt_bytestr2pstr
|
||||
*
|
||||
* Convert the data in an hfa384x byte string format into a
|
||||
* pstr in the WLAN message.
|
||||
*
|
||||
* Arguments:
|
||||
* bytestr hfa384x byte string data type
|
||||
* msg wlan message
|
||||
*
|
||||
* Returns:
|
||||
* Nothing
|
||||
*
|
||||
*/
|
||||
|
||||
void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
|
||||
struct p80211pstrd *pstr)
|
||||
{
|
||||
pstr->len = (u8)(le16_to_cpu(bytestr->len));
|
||||
memcpy(pstr->data, bytestr->data, pstr->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* prism2mgmt_bytearea2pstr
|
||||
*
|
||||
* Convert the data in an hfa384x byte area format into a pstr
|
||||
* in the WLAN message.
|
||||
*
|
||||
* Arguments:
|
||||
* bytearea hfa384x byte area data type
|
||||
* msg wlan message
|
||||
*
|
||||
* Returns:
|
||||
* Nothing
|
||||
*
|
||||
*/
|
||||
|
||||
void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len)
|
||||
{
|
||||
pstr->len = (u8)len;
|
||||
memcpy(pstr->data, bytearea, len);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,299 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "hfa384x_usb.c"
|
||||
#include "prism2mgmt.c"
|
||||
#include "prism2mib.c"
|
||||
#include "prism2sta.c"
|
||||
#include "prism2fw.c"
|
||||
|
||||
#define PRISM_DEV(vid, pid, name) \
|
||||
{ USB_DEVICE(vid, pid), \
|
||||
.driver_info = (unsigned long)name }
|
||||
|
||||
static const struct usb_device_id usb_prism_tbl[] = {
|
||||
PRISM_DEV(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS"),
|
||||
PRISM_DEV(0x07aa, 0x0012, "Corega USB Wireless LAN Stick-11"),
|
||||
PRISM_DEV(0x09aa, 0x3642, "Prism2.x 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter"),
|
||||
PRISM_DEV(0x08de, 0x7a01, "PRISM25 USB IEEE 802.11 Mini Adapter"),
|
||||
PRISM_DEV(0x8086, 0x1111, "Intel PRO/Wireless 2011B USB LAN Adapter"),
|
||||
PRISM_DEV(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"),
|
||||
PRISM_DEV(0x045e, 0x006e, "Microsoft MN510 USB Wireless Adapter"),
|
||||
PRISM_DEV(0x0967, 0x0204, "Acer Warplink USB Adapter"),
|
||||
PRISM_DEV(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated"),
|
||||
PRISM_DEV(0x0cde, 0x0005, "Z-Com Xl735 USB Wireless 802.11b Adapter"),
|
||||
PRISM_DEV(0x413c, 0x8100, "Dell TrueMobile 1180 USB Wireless Adapter"),
|
||||
PRISM_DEV(0x0b3b, 0x1601, "ALLNET 0193 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 USB Wireless Adapter"),
|
||||
PRISM_DEV(0x0baf, 0x00eb, "USRobotics USR1120 USB Wireless Adapter"),
|
||||
PRISM_DEV(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter"),
|
||||
PRISM_DEV(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter"),
|
||||
PRISM_DEV(0x0846, 0x4110, "NetGear MA111"),
|
||||
PRISM_DEV(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter"),
|
||||
PRISM_DEV(0x2821, 0x3300, "ASUS-WL140 / Hawking HighDB USB Wireless Adapter"),
|
||||
PRISM_DEV(0x2001, 0x3700, "DWL-122 USB Wireless Adapter"),
|
||||
PRISM_DEV(0x2001, 0x3702, "DWL-120 Rev F USB Wireless Adapter"),
|
||||
PRISM_DEV(0x50c2, 0x4013, "Averatec USB WLAN Adapter"),
|
||||
PRISM_DEV(0x2c02, 0x14ea, "Planex GW-US11H USB WLAN Adapter"),
|
||||
PRISM_DEV(0x124a, 0x168b, "Airvast PRISM3 USB WLAN Adapter"),
|
||||
PRISM_DEV(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter"),
|
||||
PRISM_DEV(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter"),
|
||||
PRISM_DEV(0x1668, 0x6106, "ROPEX FreeLan USB 802.11b Adapter"),
|
||||
PRISM_DEV(0x124a, 0x4017, "Pheenet WL-503IA USB 802.11b Adapter"),
|
||||
PRISM_DEV(0x0bb2, 0x0302, "Ambit Microsystems Corp."),
|
||||
PRISM_DEV(0x9016, 0x182d, "Sitecom WL-022 USB 802.11b Adapter"),
|
||||
PRISM_DEV(0x0543, 0x0f01,
|
||||
"ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)"),
|
||||
PRISM_DEV(0x067c, 0x1022,
|
||||
"Siemens SpeedStream 1022 11Mbps USB WLAN Adapter"),
|
||||
PRISM_DEV(0x049f, 0x0033,
|
||||
"Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"),
|
||||
{ } /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
|
||||
|
||||
static int prism2sta_probe_usb(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *dev;
|
||||
struct usb_endpoint_descriptor *bulk_in, *bulk_out;
|
||||
struct usb_host_interface *iface_desc = interface->cur_altsetting;
|
||||
struct wlandevice *wlandev = NULL;
|
||||
struct hfa384x *hw = NULL;
|
||||
int result = 0;
|
||||
|
||||
result = usb_find_common_endpoints(iface_desc, &bulk_in, &bulk_out, NULL, NULL);
|
||||
if (result)
|
||||
goto failed;
|
||||
|
||||
dev = interface_to_usbdev(interface);
|
||||
wlandev = create_wlan();
|
||||
if (!wlandev) {
|
||||
dev_err(&interface->dev, "Memory allocation failure.\n");
|
||||
result = -EIO;
|
||||
goto failed;
|
||||
}
|
||||
hw = wlandev->priv;
|
||||
|
||||
if (wlan_setup(wlandev, &interface->dev) != 0) {
|
||||
dev_err(&interface->dev, "wlan_setup() failed.\n");
|
||||
result = -EIO;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Initialize the hw data */
|
||||
hw->endp_in = usb_rcvbulkpipe(dev, bulk_in->bEndpointAddress);
|
||||
hw->endp_out = usb_sndbulkpipe(dev, bulk_out->bEndpointAddress);
|
||||
hfa384x_create(hw, dev);
|
||||
hw->wlandev = wlandev;
|
||||
|
||||
/* Register the wlandev, this gets us a name and registers the
|
||||
* linux netdevice.
|
||||
*/
|
||||
SET_NETDEV_DEV(wlandev->netdev, &interface->dev);
|
||||
|
||||
/* Do a chip-level reset on the MAC */
|
||||
if (prism2_doreset) {
|
||||
result = hfa384x_corereset(hw,
|
||||
prism2_reset_holdtime,
|
||||
prism2_reset_settletime, 0);
|
||||
if (result != 0) {
|
||||
result = -EIO;
|
||||
dev_err(&interface->dev,
|
||||
"hfa384x_corereset() failed.\n");
|
||||
goto failed_reset;
|
||||
}
|
||||
}
|
||||
|
||||
usb_get_dev(dev);
|
||||
|
||||
wlandev->msdstate = WLAN_MSD_HWPRESENT;
|
||||
|
||||
/* Try and load firmware, then enable card before we register */
|
||||
prism2_fwtry(dev, wlandev);
|
||||
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
|
||||
|
||||
if (register_wlandev(wlandev) != 0) {
|
||||
dev_err(&interface->dev, "register_wlandev() failed.\n");
|
||||
result = -EIO;
|
||||
goto failed_register;
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
failed_register:
|
||||
usb_put_dev(dev);
|
||||
failed_reset:
|
||||
wlan_unsetup(wlandev);
|
||||
failed:
|
||||
kfree(wlandev);
|
||||
kfree(hw);
|
||||
wlandev = NULL;
|
||||
|
||||
done:
|
||||
usb_set_intfdata(interface, wlandev);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void prism2sta_disconnect_usb(struct usb_interface *interface)
|
||||
{
|
||||
struct wlandevice *wlandev;
|
||||
|
||||
wlandev = usb_get_intfdata(interface);
|
||||
if (wlandev) {
|
||||
LIST_HEAD(cleanlist);
|
||||
struct hfa384x_usbctlx *ctlx, *temp;
|
||||
unsigned long flags;
|
||||
|
||||
struct hfa384x *hw = wlandev->priv;
|
||||
|
||||
if (!hw)
|
||||
goto exit;
|
||||
|
||||
spin_lock_irqsave(&hw->ctlxq.lock, flags);
|
||||
|
||||
p80211netdev_hwremoved(wlandev);
|
||||
list_splice_init(&hw->ctlxq.reapable, &cleanlist);
|
||||
list_splice_init(&hw->ctlxq.completing, &cleanlist);
|
||||
list_splice_init(&hw->ctlxq.pending, &cleanlist);
|
||||
list_splice_init(&hw->ctlxq.active, &cleanlist);
|
||||
|
||||
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
|
||||
|
||||
/* There's no hardware to shutdown, but the driver
|
||||
* might have some tasks that must be stopped before
|
||||
* we can tear everything down.
|
||||
*/
|
||||
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
|
||||
|
||||
timer_shutdown_sync(&hw->throttle);
|
||||
timer_shutdown_sync(&hw->reqtimer);
|
||||
timer_shutdown_sync(&hw->resptimer);
|
||||
|
||||
/* Unlink all the URBs. This "removes the wheels"
|
||||
* from the entire CTLX handling mechanism.
|
||||
*/
|
||||
usb_kill_urb(&hw->rx_urb);
|
||||
usb_kill_urb(&hw->tx_urb);
|
||||
usb_kill_urb(&hw->ctlx_urb);
|
||||
|
||||
cancel_work_sync(&hw->completion_bh);
|
||||
cancel_work_sync(&hw->reaper_bh);
|
||||
|
||||
cancel_work_sync(&hw->link_bh);
|
||||
cancel_work_sync(&hw->commsqual_bh);
|
||||
cancel_work_sync(&hw->usb_work);
|
||||
|
||||
/* Now we complete any outstanding commands
|
||||
* and tell everyone who is waiting for their
|
||||
* responses that we have shut down.
|
||||
*/
|
||||
list_for_each_entry(ctlx, &cleanlist, list)
|
||||
complete(&ctlx->done);
|
||||
|
||||
/* Give any outstanding synchronous commands
|
||||
* a chance to complete. All they need to do
|
||||
* is "wake up", so that's easy.
|
||||
* (I'd like a better way to do this, really.)
|
||||
*/
|
||||
msleep(100);
|
||||
|
||||
/* Now delete the CTLXs, because no-one else can now. */
|
||||
list_for_each_entry_safe(ctlx, temp, &cleanlist, list)
|
||||
kfree(ctlx);
|
||||
|
||||
/* Unhook the wlandev */
|
||||
unregister_wlandev(wlandev);
|
||||
wlan_unsetup(wlandev);
|
||||
|
||||
usb_put_dev(hw->usb);
|
||||
|
||||
hfa384x_destroy(hw);
|
||||
kfree(hw);
|
||||
|
||||
kfree(wlandev);
|
||||
}
|
||||
|
||||
exit:
|
||||
usb_set_intfdata(interface, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int prism2sta_suspend(struct usb_interface *interface,
|
||||
pm_message_t message)
|
||||
{
|
||||
struct hfa384x *hw = NULL;
|
||||
struct wlandevice *wlandev;
|
||||
|
||||
wlandev = usb_get_intfdata(interface);
|
||||
if (!wlandev)
|
||||
return -ENODEV;
|
||||
|
||||
hw = wlandev->priv;
|
||||
if (!hw)
|
||||
return -ENODEV;
|
||||
|
||||
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
|
||||
|
||||
usb_kill_urb(&hw->rx_urb);
|
||||
usb_kill_urb(&hw->tx_urb);
|
||||
usb_kill_urb(&hw->ctlx_urb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prism2sta_resume(struct usb_interface *interface)
|
||||
{
|
||||
int result = 0;
|
||||
struct hfa384x *hw = NULL;
|
||||
struct wlandevice *wlandev;
|
||||
|
||||
wlandev = usb_get_intfdata(interface);
|
||||
if (!wlandev)
|
||||
return -ENODEV;
|
||||
|
||||
hw = wlandev->priv;
|
||||
if (!hw)
|
||||
return -ENODEV;
|
||||
|
||||
/* Do a chip-level reset on the MAC */
|
||||
if (prism2_doreset) {
|
||||
result = hfa384x_corereset(hw,
|
||||
prism2_reset_holdtime,
|
||||
prism2_reset_settletime, 0);
|
||||
if (result != 0) {
|
||||
unregister_wlandev(wlandev);
|
||||
hfa384x_destroy(hw);
|
||||
dev_err(&interface->dev, "hfa384x_corereset() failed.\n");
|
||||
kfree(wlandev);
|
||||
kfree(hw);
|
||||
wlandev = NULL;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define prism2sta_suspend NULL
|
||||
#define prism2sta_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct usb_driver prism2_usb_driver = {
|
||||
.name = "prism2_usb",
|
||||
.probe = prism2sta_probe_usb,
|
||||
.disconnect = prism2sta_disconnect_usb,
|
||||
.id_table = usb_prism_tbl,
|
||||
.suspend = prism2sta_suspend,
|
||||
.resume = prism2sta_resume,
|
||||
.reset_resume = prism2sta_resume,
|
||||
/* fops, minor? */
|
||||
};
|
||||
|
||||
module_usb_driver(prism2_usb_driver);
|
Loading…
Reference in New Issue
Block a user