Commit 8cb652bb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes from Greg KH:
 "Here are a few staging driver fixes for issues that have been reported
  for 3.15-rc2.

  Also dominating the diffstat for the pull request is the removal of
  the rtl8187se driver.  It's no longer needed in staging as a "real"
  driver for this hardware is now merged in the tree in the "correct"
  location in drivers/net/

  All of these patches have been tested in linux-next"

* tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: r8188eu: Fix case where ethtype was never obtained and always be checked against 0
  staging: r8712u: Fix case where ethtype was never obtained and always be checked against 0
  staging: r8188eu: Calling rtw_get_stainfo() with a NULL sta_addr will return NULL
  staging: comedi: fix circular locking dependency in comedi_mmap()
  staging: r8723au: Add missing initialization of change_inx in sort algorithm
  Staging: unisys: use after free in list_for_each()
  staging: unisys: use after free in error messages
  staging: speakup: fix misuse of kstrtol() in handle_goto()
  staging: goldfish: Call free_irq in error path
  staging: delete rtl8187se wireless driver
  staging: rtl8723au: Fix buffer overflow in rtw_get_wfd_ie()
  staging: gs_fpgaboot: remove __TIMESTAMP__ macro
  staging: vme: fix memory leak in vme_user_probe()
  staging: fpgaboot: clean up Makefile
  staging/usbip: fix store_attach() sscanf return value check
  staging/usbip: userspace - fix usbipd SIGSEGV from refresh_exported_devices()
  staging: rtl8188eu: remove spaces, correct counts to unbreak P2P ioctls
  staging/rtl8821ae: Fix OOM handling in _rtl_init_deferred_work()
parents 575a2929 33c84bc1
...@@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig" ...@@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig"
source "drivers/staging/panel/Kconfig" source "drivers/staging/panel/Kconfig"
source "drivers/staging/rtl8187se/Kconfig"
source "drivers/staging/rtl8192u/Kconfig" source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8192e/Kconfig"
......
...@@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ ...@@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_PANEL) += panel/ obj-$(CONFIG_PANEL) += panel/
obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_R8712U) += rtl8712/
......
...@@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev, ...@@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
struct comedi_async *async = s->async; struct comedi_async *async = s->async;
struct comedi_buf_map *bm;
unsigned long flags;
if (async->prealloc_buf) { if (async->prealloc_buf) {
vunmap(async->prealloc_buf); vunmap(async->prealloc_buf);
...@@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev, ...@@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev,
async->prealloc_bufsz = 0; async->prealloc_bufsz = 0;
} }
comedi_buf_map_put(async->buf_map); spin_lock_irqsave(&s->spin_lock, flags);
bm = async->buf_map;
async->buf_map = NULL; async->buf_map = NULL;
spin_unlock_irqrestore(&s->spin_lock, flags);
comedi_buf_map_put(bm);
} }
static void __comedi_buf_alloc(struct comedi_device *dev, static void __comedi_buf_alloc(struct comedi_device *dev,
...@@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, ...@@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
struct page **pages = NULL; struct page **pages = NULL;
struct comedi_buf_map *bm; struct comedi_buf_map *bm;
struct comedi_buf_page *buf; struct comedi_buf_page *buf;
unsigned long flags;
unsigned i; unsigned i;
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) { if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
...@@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev, ...@@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
if (!bm) if (!bm)
return; return;
async->buf_map = bm;
kref_init(&bm->refcount); kref_init(&bm->refcount);
spin_lock_irqsave(&s->spin_lock, flags);
async->buf_map = bm;
spin_unlock_irqrestore(&s->spin_lock, flags);
bm->dma_dir = s->async_dma_dir; bm->dma_dir = s->async_dma_dir;
if (bm->dma_dir != DMA_NONE) if (bm->dma_dir != DMA_NONE)
/* Need ref to hardware device to free buffer later. */ /* Need ref to hardware device to free buffer later. */
...@@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev, ...@@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
pages[i] = virt_to_page(buf->virt_addr); pages[i] = virt_to_page(buf->virt_addr);
} }
spin_lock_irqsave(&s->spin_lock, flags);
bm->n_pages = i; bm->n_pages = i;
spin_unlock_irqrestore(&s->spin_lock, flags);
/* vmap the prealloc_buf if all the pages were allocated */ /* vmap the prealloc_buf if all the pages were allocated */
if (i == n_pages) if (i == n_pages)
...@@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm) ...@@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm)
return 1; return 1;
} }
/* returns s->async->buf_map and increments its kref refcount */
struct comedi_buf_map *
comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
struct comedi_buf_map *bm = NULL;
unsigned long flags;
if (!async)
return NULL;
spin_lock_irqsave(&s->spin_lock, flags);
bm = async->buf_map;
/* only want it if buffer pages allocated */
if (bm && bm->n_pages)
comedi_buf_map_get(bm);
else
bm = NULL;
spin_unlock_irqrestore(&s->spin_lock, flags);
return bm;
}
bool comedi_buf_is_mmapped(struct comedi_async *async) bool comedi_buf_is_mmapped(struct comedi_async *async)
{ {
struct comedi_buf_map *bm = async->buf_map; struct comedi_buf_map *bm = async->buf_map;
......
...@@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
struct comedi_device *dev = file->private_data; struct comedi_device *dev = file->private_data;
struct comedi_subdevice *s; struct comedi_subdevice *s;
struct comedi_async *async; struct comedi_async *async;
struct comedi_buf_map *bm; struct comedi_buf_map *bm = NULL;
unsigned long start = vma->vm_start; unsigned long start = vma->vm_start;
unsigned long size; unsigned long size;
int n_pages; int n_pages;
int i; int i;
int retval; int retval;
mutex_lock(&dev->mutex); /*
* 'trylock' avoids circular dependency with current->mm->mmap_sem
* and down-reading &dev->attach_lock should normally succeed without
* contention unless the device is in the process of being attached
* or detached.
*/
if (!down_read_trylock(&dev->attach_lock))
return -EAGAIN;
if (!dev->attached) { if (!dev->attached) {
dev_dbg(dev->class_dev, "no driver attached\n"); dev_dbg(dev->class_dev, "no driver attached\n");
...@@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
} }
n_pages = size >> PAGE_SHIFT; n_pages = size >> PAGE_SHIFT;
bm = async->buf_map;
/* get reference to current buf map (if any) */
bm = comedi_buf_map_from_subdev_get(s);
if (!bm || n_pages > bm->n_pages) { if (!bm || n_pages > bm->n_pages) {
retval = -EINVAL; retval = -EINVAL;
goto done; goto done;
...@@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
retval = 0; retval = 0;
done: done:
mutex_unlock(&dev->mutex); up_read(&dev->attach_lock);
comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
return retval; return retval;
} }
......
...@@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async); ...@@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async);
bool comedi_buf_is_mmapped(struct comedi_async *async); bool comedi_buf_is_mmapped(struct comedi_async *async);
void comedi_buf_map_get(struct comedi_buf_map *bm); void comedi_buf_map_get(struct comedi_buf_map *bm);
int comedi_buf_map_put(struct comedi_buf_map *bm); int comedi_buf_map_put(struct comedi_buf_map *bm);
struct comedi_buf_map *comedi_buf_map_from_subdev_get(
struct comedi_subdevice *s);
unsigned int comedi_buf_write_n_allocated(struct comedi_async *async); unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
void comedi_device_cancel_all(struct comedi_device *dev); void comedi_device_cancel_all(struct comedi_device *dev);
......
...@@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev) ...@@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev)
return 0; return 0;
err_misc_register_failed: err_misc_register_failed:
free_irq(data->irq, data);
err_request_irq_failed: err_request_irq_failed:
dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE, dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
data->buffer_virt, data->buffer_phys); data->buffer_virt, data->buffer_phys);
......
gs_fpga-y += gs_fpgaboot.o io.o gs_fpga-y += gs_fpgaboot.o io.o
obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o
ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG
...@@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void) ...@@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void)
r = -1; r = -1;
pr_info("FPGA DOWNLOAD --->\n"); pr_info("FPGA DOWNLOAD --->\n");
pr_info("built at %s UTC\n", __TIMESTAMP__);
pr_info("FPGA image file name: %s\n", file); pr_info("FPGA image file name: %s\n", file);
......
config R8187SE
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
depends on PCI && WLAN
depends on m
select WIRELESS_EXT
select WEXT_PRIV
select EEPROM_93CX6
select CRYPTO
---help---
If built as a module, it will be called r8187se.ko.
#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
#ccflags-y += -std=gnu89
#ccflags-y += -O2
#CC = gcc
ccflags-y := -DSW_ANTE
ccflags-y += -DTX_TRACK
ccflags-y += -DHIGH_POWER
ccflags-y += -DSW_DIG
ccflags-y += -DRATE_ADAPT
#enable it for legacy power save, disable it for leisure power save
ccflags-y += -DENABLE_LPS
#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
r8187se-y := \
r8180_core.o \
r8180_wx.o \
r8180_rtl8225z2.o \
r8185b_init.o \
r8180_dm.o \
ieee80211/dot11d.o \
ieee80211/ieee80211_softmac.o \
ieee80211/ieee80211_rx.o \
ieee80211/ieee80211_tx.o \
ieee80211/ieee80211_wx.o \
ieee80211/ieee80211_module.o \
ieee80211/ieee80211_softmac_wx.o \
ieee80211/ieee80211_crypt.o \
ieee80211/ieee80211_crypt_tkip.o \
ieee80211/ieee80211_crypt_ccmp.o \
ieee80211/ieee80211_crypt_wep.o
obj-$(CONFIG_R8187SE) += r8187se.o
TODO:
- prepare private ieee80211 stack for merge with rtl8192su's version:
- add hwsec_active flag to struct ieee80211_device
- add bHwSec flag to cb_desc structure
- switch to use shared "librtl" instead of private ieee80211 stack
- switch to use LIB80211
- switch to use MAC80211
- use kernel coding style
- checkpatch.pl fixes
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
#include "dot11d.h"
void Dot11d_Init(struct ieee80211_device *ieee)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
pDot11dInfo->bEnabled = 0;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
RESET_CIE_WATCHDOG(ieee);
netdev_info(ieee->dev, "Dot11d_Init()\n");
}
/* Reset to the state as we are just entering a regulatory domain. */
void Dot11d_Reset(struct ieee80211_device *ieee)
{
u32 i;
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
/* Clear old channel map */
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
/* Set new channel map */
for (i = 1; i <= 11; i++)
(pDot11dInfo->channel_map)[i] = 1;
for (i = 12; i <= 14; i++)
(pDot11dInfo->channel_map)[i] = 2;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
RESET_CIE_WATCHDOG(ieee);
}
/*
* Description:
* Update country IE from Beacon or Probe Response and configure PHY for
* operation in the regulatory domain.
*
* TODO:
* Configure Tx power.
*
* Assumption:
* 1. IS_DOT11D_ENABLE() is TRUE.
* 2. Input IE is an valid one.
*/
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 i, j, NumTriples, MaxChnlNum;
u8 index, MaxTxPowerInDbm;
PCHNL_TXPOWER_TRIPLE pTriple;
if ((CoutryIeLen - 3)%3 != 0) {
netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
Dot11d_Reset(dev);
return;
}
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
MaxChnlNum = 0;
NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
for (i = 0; i < NumTriples; i++) {
if (MaxChnlNum >= pTriple->FirstChnl) {
/*
* It is not in a monotonically increasing order,
* so stop processing.
*/
netdev_info(dev->dev,
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
Dot11d_Reset(dev);
return;
}
if (MAX_CHANNEL_NUMBER <
(pTriple->FirstChnl + pTriple->NumChnls)) {
/*
* It is not a valid set of channel id,
* so stop processing
*/
netdev_info(dev->dev,
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
Dot11d_Reset(dev);
return;
}
for (j = 0; j < pTriple->NumChnls; j++) {
index = pTriple->FirstChnl + j;
pDot11dInfo->channel_map[index] = 1;
MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
MaxChnlNum = pTriple->FirstChnl + j;
}
pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
}
#if 1
netdev_info(dev->dev, "Channel List:");
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
if (pDot11dInfo->channel_map[i] > 0)
netdev_info(dev->dev, " %d", i);
netdev_info(dev->dev, "\n");
#endif
UPDATE_CIE_SRC(dev, pTaddr);
pDot11dInfo->CountryIeLen = CoutryIeLen;
memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
pDot11dInfo->State = DOT11D_STATE_LEARNED;
}
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 MaxTxPwrInDbm = 255;
if (MAX_CHANNEL_NUMBER < Channel) {
netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
return MaxTxPwrInDbm;
}
if (pDot11dInfo->channel_map[Channel])
MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
return MaxTxPwrInDbm;
}
void DOT11D_ScanComplete(struct ieee80211_device *dev)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
switch (pDot11dInfo->State) {
case DOT11D_STATE_LEARNED:
pDot11dInfo->State = DOT11D_STATE_DONE;
break;
case DOT11D_STATE_DONE:
if (GET_CIE_WATCHDOG(dev) == 0) {
/* Reset country IE if previous one is gone. */
Dot11d_Reset(dev);
}
break;
case DOT11D_STATE_NONE:
break;
}
}
int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
if (MAX_CHANNEL_NUMBER < channel) {
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
return 0;
}
if (pDot11dInfo->channel_map[channel] > 0)
return 1;
return 0;
}
int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 default_chn = 0;
u32 i = 0;
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
if (pDot11dInfo->channel_map[i] > 0) {
default_chn = i;
break;
}
}
if (MAX_CHANNEL_NUMBER < channel) {
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
return default_chn;
}
if (pDot11dInfo->channel_map[channel] > 0)
return channel;
return default_chn;
}
#ifndef __INC_DOT11D_H
#define __INC_DOT11D_H
#include "ieee80211.h"
/* #define ENABLE_DOT11D */
/* #define DOT11D_MAX_CHNL_NUM 83 */
typedef struct _CHNL_TXPOWER_TRIPLE {
u8 FirstChnl;
u8 NumChnls;
u8 MaxTxPowerInDbm;
} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
typedef enum _DOT11D_STATE {
DOT11D_STATE_NONE = 0,
DOT11D_STATE_LEARNED,
DOT11D_STATE_DONE,
} DOT11D_STATE;
typedef struct _RT_DOT11D_INFO {
/* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
u8 CountryIeBuf[MAX_IE_LEN];
u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */
u8 CountryIeWatchdog;
u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
/* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */
/* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */
u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
DOT11D_STATE State;
} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
FALSE : \
(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
#define CIE_WATCHDOG_TH 1
#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
void Dot11d_Init(struct ieee80211_device *dev);
void Dot11d_Reset(struct ieee80211_device *dev);
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe);
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
void DOT11D_ScanComplete(struct ieee80211_device *dev);
int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
#endif /* #ifndef __INC_DOT11D_H */
This diff is collapsed.
/*
* Host AP crypto routines
*
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include "ieee80211.h"
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL");
struct ieee80211_crypto_alg {
struct list_head list;
struct ieee80211_crypto_ops *ops;
};
struct ieee80211_crypto {
struct list_head algs;
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
list_del(ptr);
if (entry->ops)
entry->ops->deinit(entry->priv);
kfree(entry);
}
}
void ieee80211_crypt_deinit_handler(unsigned long data)
{
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
if (!list_empty(&ieee->crypt_deinit_list)) {
pr_debug("entries remaining in delayed crypt deletion list\n");
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt)
{
struct ieee80211_crypt_data *tmp;
unsigned long flags;
if (*crypt == NULL)
return;
tmp = *crypt;
*crypt = NULL;
/* must not run ops->deinit() while there may be pending encrypt or
* decrypt operations. Use a list of delayed deinits to avoid needing
* locking. */
spin_lock_irqsave(&ieee->lock, flags);
list_add(&tmp->list, &ieee->crypt_deinit_list);
if (!timer_pending(&ieee->crypt_deinit_timer)) {
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
{
unsigned long flags;
struct ieee80211_crypto_alg *alg;
if (hcrypt == NULL)
return -1;
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL)
return -ENOMEM;
alg->ops = ops;
spin_lock_irqsave(&hcrypt->lock, flags);
list_add(&alg->list, &hcrypt->algs);
spin_unlock_irqrestore(&hcrypt->lock, flags);
pr_debug("registered algorithm '%s'\n", ops->name);
return 0;
}
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *del_alg = NULL;
if (hcrypt == NULL)
return -1;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
if (alg->ops == ops) {
list_del(&alg->list);
del_alg = alg;
break;
}
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (del_alg) {
pr_debug("unregistered algorithm '%s'\n", ops->name);
kfree(del_alg);
}
return del_alg ? 0 : -1;
}
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *found_alg = NULL;
if (hcrypt == NULL)
return NULL;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
if (strcmp(alg->ops->name, name) == 0) {
found_alg = alg;
break;
}
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (found_alg)
return found_alg->ops;
else
return NULL;
}
static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
static void ieee80211_crypt_null_deinit(void *priv) {}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.name = "NULL",
.init = ieee80211_crypt_null_init,
.deinit = ieee80211_crypt_null_deinit,
.encrypt_mpdu = NULL,
.decrypt_mpdu = NULL,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = NULL,
.get_key = NULL,
.extra_prefix_len = 0,
.extra_postfix_len = 0,
.owner = THIS_MODULE,
};
int ieee80211_crypto_init(void)
{
int ret = -ENOMEM;
hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
if (!hcrypt)
goto out;
INIT_LIST_HEAD(&hcrypt->algs);
spin_lock_init(&hcrypt->lock);
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
if (ret < 0) {
kfree(hcrypt);
hcrypt = NULL;
}
out:
return ret;
}
void ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
struct ieee80211_crypto_alg *alg = NULL;
if (hcrypt == NULL)
return;
list_for_each_safe(ptr, n, &hcrypt->algs) {
alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
if (alg) {
list_del(ptr);
pr_debug("unregistered algorithm '%s' (deinit)\n",
alg->ops->name);
kfree(alg);
}
}
kfree(hcrypt);
}
/*
* Original code based on Host AP (software wireless LAN access point) driver
* for Intersil Prism2/2.5/3.
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
*
* Copyright (c) 2004, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
/*
* This file defines the interface to the ieee80211 crypto module.
*/
#ifndef IEEE80211_CRYPT_H
#define IEEE80211_CRYPT_H
#include <linux/skbuff.h>
struct ieee80211_crypto_ops {
const char *name;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
* private data on success */
void * (*init)(int keyidx);
/* deinitialize crypto context and free allocated private data */
void (*deinit)(void *priv);
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
* value from decrypt_mpdu is passed as the keyidx value for
* decrypt_msdu. skb must have enough head and tail room for the
* encryption; if not, error will be returned; these functions are
* called for all MPDUs (i.e., fragments).
*/
int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
/* These functions are called for full MSDUs, i.e. full frames.
* These can be NULL if full MSDU operations are not needed. */
int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
void *priv);
int (*set_key)(void *key, int len, u8 *seq, void *priv);
int (*get_key)(void *key, int len, u8 *seq, void *priv);
/* procfs handler for printing out key information and possible
* statistics */
char * (*print_stats)(char *p, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and
* extra_postfix_len; encrypt need not use all this space, but
* the result must start at the beginning of the buffer and correct
* length must be returned */
int extra_prefix_len, extra_postfix_len;
struct module *owner;
};
struct ieee80211_crypt_data {
struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
void *priv;
atomic_t refcnt;
};
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
#endif
/*
* Host AP crypt: host-based WEP encryption implementation for Host AP driver
*
* Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include "ieee80211.h"
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/crc32.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: WEP");
MODULE_LICENSE("GPL");
struct prism2_wep_data {
u32 iv;
#define WEP_KEY_LEN 13
u8 key[WEP_KEY_LEN + 1];
u8 key_len;
u8 key_idx;
struct crypto_blkcipher *tx_tfm;
struct crypto_blkcipher *rx_tfm;
};
static void *prism2_wep_init(int keyidx)
{
struct prism2_wep_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
goto fail;
priv->key_idx = keyidx;
priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm)) {
pr_debug("could not allocate crypto API arc4\n");
priv->tx_tfm = NULL;
goto fail;
}
priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm)) {
pr_debug("could not allocate crypto API arc4\n");
priv->rx_tfm = NULL;
goto fail;
}
/* start WEP IV from a random value */
get_random_bytes(&priv->iv, 4);
return priv;
fail:
if (priv) {
if (priv->tx_tfm)
crypto_free_blkcipher(priv->tx_tfm);
if (priv->rx_tfm)
crypto_free_blkcipher(priv->rx_tfm);
kfree(priv);
}
return NULL;
}
static void prism2_wep_deinit(void *priv)
{
struct prism2_wep_data *_priv = priv;
if (_priv) {
if (_priv->tx_tfm)
crypto_free_blkcipher(_priv->tx_tfm);
if (_priv->rx_tfm)
crypto_free_blkcipher(_priv->rx_tfm);
}
kfree(priv);
}
/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
* for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
* so the payload length increases with 8 bytes.
*
* WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
*/
static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct prism2_wep_data *wep = priv;
struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
u32 klen, len;
u8 key[WEP_KEY_LEN + 3];
u8 *pos;
u32 crc;
u8 *icv;
struct scatterlist sg;
if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
skb->len < hdr_len)
return -1;
len = skb->len - hdr_len;
pos = skb_push(skb, 4);
memmove(pos, pos + 4, hdr_len);
pos += hdr_len;
klen = 3 + wep->key_len;
wep->iv++;
/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
* scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
* can be used to speedup attacks, so avoid using them. */
if ((wep->iv & 0xff00) == 0xff00) {
u8 B = (wep->iv >> 16) & 0xff;
if (B >= 3 && B < klen)
wep->iv += 0x0100;
}
/* Prepend 24-bit IV to RC4 key and TX frame */
*pos++ = key[0] = (wep->iv >> 16) & 0xff;
*pos++ = key[1] = (wep->iv >> 8) & 0xff;
*pos++ = key[2] = wep->iv & 0xff;
*pos++ = wep->key_idx << 6;
/* Copy rest of the WEP key (the secret part) */
memcpy(key + 3, wep->key, wep->key_len);
/* Append little-endian CRC32 and encrypt it to produce ICV */
crc = ~crc32_le(~0, pos, len);
icv = skb_put(skb, 4);
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
icv[3] = crc >> 24;
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
sg_init_one(&sg, pos, len + 4);
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
}
/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
* the frame: IV (4 bytes), encrypted payload (including SNAP header),
* ICV (4 bytes). len includes both IV and ICV.
*
* Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
* failure. If frame is OK, IV and ICV will be removed.
*/
static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct prism2_wep_data *wep = priv;
struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
u32 klen, plen;
u8 key[WEP_KEY_LEN + 3];
u8 keyidx, *pos;
u32 crc;
u8 icv[4];
struct scatterlist sg;
if (skb->len < hdr_len + 8)
return -1;
pos = skb->data + hdr_len;
key[0] = *pos++;
key[1] = *pos++;
key[2] = *pos++;
keyidx = *pos++ >> 6;
if (keyidx != wep->key_idx)
return -1;
klen = 3 + wep->key_len;
/* Copy rest of the WEP key (the secret part) */
memcpy(key + 3, wep->key, wep->key_len);
/* Apply RC4 to data and compute CRC32 over decrypted data */
plen = skb->len - hdr_len - 8;
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
sg_init_one(&sg, pos, plen + 4);
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
return -7;
crc = ~crc32_le(~0, pos, plen);
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
icv[3] = crc >> 24;
if (memcmp(icv, pos + plen, 4) != 0) {
/* ICV mismatch - drop frame */
return -2;
}
/* Remove IV and ICV */
memmove(skb->data + 4, skb->data, hdr_len);
skb_pull(skb, 4);
skb_trim(skb, skb->len - 4);
return 0;
}
static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
{
struct prism2_wep_data *wep = priv;
if (len < 0 || len > WEP_KEY_LEN)
return -1;
memcpy(wep->key, key, len);
wep->key_len = len;
return 0;
}
static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
{
struct prism2_wep_data *wep = priv;
if (len < wep->key_len)
return -1;
memcpy(key, wep->key, wep->key_len);
return wep->key_len;
}
static char *prism2_wep_print_stats(char *p, void *priv)
{
struct prism2_wep_data *wep = priv;
p += sprintf(p, "key[%d] alg=WEP len=%d\n",
wep->key_idx, wep->key_len);
return p;
}
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
.name = "WEP",
.init = prism2_wep_init,
.deinit = prism2_wep_deinit,
.encrypt_mpdu = prism2_wep_encrypt,
.decrypt_mpdu = prism2_wep_decrypt,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = prism2_wep_set_key,
.get_key = prism2_wep_get_key,
.print_stats = prism2_wep_print_stats,
.extra_prefix_len = 4, /* IV */
.extra_postfix_len = 4, /* ICV */
.owner = THIS_MODULE,
};
int ieee80211_crypto_wep_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
}
void ieee80211_crypto_wep_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
}
void ieee80211_wep_null(void)
{
return;
}
/*******************************************************************************
Copyright(c) 2004 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
<jkmaline@cc.hut.fi>
Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include <linux/compiler.h>
//#include <linux/config.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <linux/uaccess.h>
#include <net/arp.h>
#include <net/net_namespace.h>
#include "ieee80211.h"
MODULE_DESCRIPTION("802.11 data/management/control stack");
MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
MODULE_LICENSE("GPL");
#define DRV_NAME "ieee80211"
static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
{
if (ieee->networks)
return 0;
ieee->networks = kcalloc(
MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
GFP_KERNEL);
if (!ieee->networks)
return -ENOMEM;
return 0;
}
static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
{
if (!ieee->networks)
return;
kfree(ieee->networks);
ieee->networks = NULL;
}
static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
{
int i;
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
}
struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct ieee80211_device *ieee;
struct net_device *dev;
int i, err;
IEEE80211_DEBUG_INFO("Initializing...\n");
dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
if (!dev) {
IEEE80211_ERROR("Unable to network device.\n");
goto failed;
}
ieee = netdev_priv(dev);
ieee->dev = dev;
err = ieee80211_networks_allocate(ieee);
if (err) {
IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
err);
goto failed;
}
ieee80211_networks_initialize(ieee);
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
init_timer(&ieee->crypt_deinit_timer);
ieee->crypt_deinit_timer.data = (unsigned long)ieee;
ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
spin_lock_init(&ieee->lock);
spin_lock_init(&ieee->wpax_suitlist_lock);
ieee->wpax_type_set = 0;
ieee->wpa_enabled = 0;
ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
ieee->ieee802_1x = 1;
ieee->raw_tx = 0;
ieee80211_softmac_init(ieee);
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
for (i = 0; i < 17; i++) {
ieee->last_rxseq_num[i] = -1;
ieee->last_rxfrag_num[i] = -1;
ieee->last_packet_time[i] = 0;
}
//These function were added to load crypte module autoly
ieee80211_tkip_null();
ieee80211_wep_null();
ieee80211_ccmp_null();
return dev;
failed:
if (dev)
free_netdev(dev);
return NULL;
}
void free_ieee80211(struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
int i;
struct list_head *p, *q;
ieee80211_softmac_free(ieee);
del_timer_sync(&ieee->crypt_deinit_timer);
ieee80211_crypt_deinit_entries(ieee, 1);
for (i = 0; i < WEP_KEYS; i++) {
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
if (crypt->ops)
crypt->ops->deinit(crypt->priv);
kfree(crypt);
ieee->crypt[i] = NULL;
}
}
ieee80211_networks_free(ieee);
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
kfree(list_entry(p, struct ieee_ibss_seq, list));
list_del(p);
}
}
free_netdev(dev);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
This is part of rtl8180 OpenSource driver
Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
Released under the terms of GPL (General Public Licence)
Parts of this driver are based on the GPL part of the official realtek driver
Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
*/
/*This files contains card eeprom (93c46 or 93c56) programming routines*/
/*memory is addressed by WORDS*/
#include "r8180.h"
#include "r8180_hw.h"
#define EPROM_DELAY 10
#define EPROM_ANAPARAM_ADDRLWORD 0xd
#define EPROM_ANAPARAM_ADDRHWORD 0xe
#define RFCHIPID 0x6
#define RFCHIPID_INTERSIL 1
#define RFCHIPID_RFMD 2
#define RFCHIPID_PHILIPS 3
#define RFCHIPID_MAXIM 4
#define RFCHIPID_GCT 5
#define RFCHIPID_RTL8225 9
#define RF_ZEBRA2 11
#define EPROM_TXPW_BASE 0x05
#define RF_ZEBRA4 12
#define RFCHIPID_RTL8255 0xa
#define RF_PARAM 0x19
#define RF_PARAM_DIGPHY_SHIFT 0
#define RF_PARAM_ANTBDEFAULT_SHIFT 1
#define RF_PARAM_CARRIERSENSE_SHIFT 2
#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
#define ENERGY_TRESHOLD 0x17
#define EPROM_VERSION 0x1E
#define MAC_ADR 0x7
#define CIS 0x18
#define EPROM_TXPW_OFDM_CH1_2 0x20
#define EPROM_TXPW_CH1_2 0x30
#define RTL818X_EEPROM_CMD_READ (1 << 0)
#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
#define RTL818X_EEPROM_CMD_CK (1 << 2)
#define RTL818X_EEPROM_CMD_CS (1 << 3)
This diff is collapsed.
This diff is collapsed.
#ifndef R8180_DM_H
#define R8180_DM_H
#include "r8180.h"
/* #include "r8180_hw.h" */
/* #include "r8180_93cx6.h" */
void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
bool SwitchAntenna(struct net_device *dev);
void SwAntennaDiversity(struct net_device *dev);
void SwAntennaDiversityTimerCallback(struct net_device *dev);
bool CheckDig(struct net_device *dev);
bool CheckHighPower(struct net_device *dev);
void rtl8180_hw_dig_wq(struct work_struct *work);
void rtl8180_tx_pw_wq(struct work_struct *work);
void rtl8180_rate_adapter(struct work_struct *work);
void TxPwrTracking87SE(struct net_device *dev);
bool CheckTxPwrTracking(struct net_device *dev);
void rtl8180_rate_adapter(struct work_struct *work);
void timer_rate_adaptive(unsigned long data);
#endif
This diff is collapsed.
/*
* This is part of the rtl8180-sa2400 driver released under the GPL (See file
* COPYING for details).
*
* Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
*
* This files contains programming code for the rtl8225 radio frontend.
*
* *Many* thanks to Realtek Corp. for their great support!
*/
#include "r8180.h"
#define RTL8225_ANAPARAM_ON 0xa0000b59
#define RTL8225_ANAPARAM_OFF 0xa00beb59
#define RTL8225_ANAPARAM2_OFF 0x840dec11
#define RTL8225_ANAPARAM2_ON 0x860dec11
#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
void rtl8225z2_rf_init(struct net_device *dev);
void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
void rtl8225z2_rf_close(struct net_device *dev);
void RF_WriteReg(struct net_device *dev, u8 offset, u16 data);
u16 RF_ReadReg(struct net_device *dev, u8 offset);
void rtl8180_set_mode(struct net_device *dev, int mode);
void rtl8180_set_mode(struct net_device *dev, int mode);
bool SetZebraRFPowerState8185(struct net_device *dev,
enum rt_rf_power_state eRFPowerState);
void rtl8225z4_rf_sleep(struct net_device *dev);
void rtl8225z4_rf_wakeup(struct net_device *dev);
This diff is collapsed.
This diff is collapsed.
/*
This is part of rtl8180 OpenSource driver - v 0.3
Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com>
Released under the terms of GPL (General Public Licence)
Parts of this driver are based on the GPL part of the official realtek driver
Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
We want to thanks the Authors of such projects and the Ndiswrapper project Authors.
*/
/* this file (will) contains wireless extension handlers*/
#ifndef R8180_WX_H
#define R8180_WX_H
#include <linux/wireless.h>
#include "ieee80211/ieee80211.h"
extern struct iw_handler_def r8180_wx_handlers_def;
#endif
This diff is collapsed.
...@@ -545,20 +545,18 @@ static struct recv_frame *decryptor(struct adapter *padapter, ...@@ -545,20 +545,18 @@ static struct recv_frame *decryptor(struct adapter *padapter,
static struct recv_frame *portctrl(struct adapter *adapter, static struct recv_frame *portctrl(struct adapter *adapter,
struct recv_frame *precv_frame) struct recv_frame *precv_frame)
{ {
u8 *psta_addr = NULL, *ptr; u8 *psta_addr, *ptr;
uint auth_alg; uint auth_alg;
struct recv_frame *pfhdr; struct recv_frame *pfhdr;
struct sta_info *psta; struct sta_info *psta;
struct sta_priv *pstapriv; struct sta_priv *pstapriv;
struct recv_frame *prtnframe; struct recv_frame *prtnframe;
u16 ether_type = 0; u16 ether_type;
u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */ u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
struct rx_pkt_attrib *pattrib; struct rx_pkt_attrib *pattrib;
__be16 be_tmp;
pstapriv = &adapter->stapriv; pstapriv = &adapter->stapriv;
psta = rtw_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.dot11AuthAlgrthm; auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
...@@ -566,24 +564,23 @@ static struct recv_frame *portctrl(struct adapter *adapter, ...@@ -566,24 +564,23 @@ static struct recv_frame *portctrl(struct adapter *adapter,
pfhdr = precv_frame; pfhdr = precv_frame;
pattrib = &pfhdr->attrib; pattrib = &pfhdr->attrib;
psta_addr = pattrib->ta; psta_addr = pattrib->ta;
psta = rtw_get_stainfo(pstapriv, psta_addr);
prtnframe = NULL; prtnframe = NULL;
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm)); RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm));
if (auth_alg == 2) { if (auth_alg == 2) {
/* get ether_type */
ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
memcpy(&ether_type, ptr, 2);
ether_type = ntohs((unsigned short)ether_type);
if ((psta != NULL) && (psta->ieee8021x_blocked)) { if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked */ /* blocked */
/* only accept EAPOL frame */ /* only accept EAPOL frame */
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n")); RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n"));
prtnframe = precv_frame;
/* get ether_type */
ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
memcpy(&be_tmp, ptr, 2);
ether_type = ntohs(be_tmp);
if (ether_type == eapol_type) { if (ether_type == eapol_type) {
prtnframe = precv_frame; prtnframe = precv_frame;
} else { } else {
......
This diff is collapsed.
...@@ -1281,7 +1281,7 @@ unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *prec ...@@ -1281,7 +1281,7 @@ unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *prec
u8 p2p_status_code = P2P_STATUS_SUCCESS; u8 p2p_status_code = P2P_STATUS_SUCCESS;
u8 *p2pie; u8 *p2pie;
u32 p2pielen = 0; u32 p2pielen = 0;
u8 wfd_ie[ 128 ] = { 0x00 }; u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0; u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */ #endif /* CONFIG_8723AU_P2P */
......
...@@ -2535,7 +2535,7 @@ u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pfra ...@@ -2535,7 +2535,7 @@ u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pfra
u16 wps_devicepassword_id = 0x0000; u16 wps_devicepassword_id = 0x0000;
uint wps_devicepassword_id_len = 0; uint wps_devicepassword_id_len = 0;
#ifdef CONFIG_8723AU_P2P #ifdef CONFIG_8723AU_P2P
u8 wfd_ie[ 128 ] = { 0x00 }; u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0; u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */ #endif /* CONFIG_8723AU_P2P */
...@@ -2741,7 +2741,7 @@ u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pfr ...@@ -2741,7 +2741,7 @@ u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pfr
u32 ies_len; u32 ies_len;
u8 * p2p_ie; u8 * p2p_ie;
#ifdef CONFIG_8723AU_P2P #ifdef CONFIG_8723AU_P2P
u8 wfd_ie[ 128 ] = { 0x00 }; u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0; u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */ #endif /* CONFIG_8723AU_P2P */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment