2
0
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:
Stephen Rothwell 2024-03-28 14:09:01 +11:00
commit 057bd3bb1f
51 changed files with 94 additions and 15274 deletions

View File

@ -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"

View File

@ -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/

View File

@ -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,

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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-----------------------------*/

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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__ */

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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(&params, 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, &params);
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

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);