Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
1f8fc993
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
1f8fc993
编写于
11月 18, 2005
作者:
J
Jeff Garzik
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'upstream-jgarzik' of
git://git.tuxdriver.com/git/netdev-jwl
上级
638cbac8
7635d345
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
784 addition
and
774 deletion
+784
-774
drivers/net/sk98lin/h/skdrv2nd.h
drivers/net/sk98lin/h/skdrv2nd.h
+0
-1
drivers/net/sk98lin/h/skvpd.h
drivers/net/sk98lin/h/skvpd.h
+0
-8
drivers/net/sk98lin/skge.c
drivers/net/sk98lin/skge.c
+21
-22
drivers/net/wan/lmc/lmc_prot.h
drivers/net/wan/lmc/lmc_prot.h
+0
-15
drivers/net/wireless/atmel.c
drivers/net/wireless/atmel.c
+762
-728
drivers/net/wireless/hostap/Makefile
drivers/net/wireless/hostap/Makefile
+1
-0
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/hostap/hostap_main.c
+0
-0
未找到文件。
drivers/net/sk98lin/h/skdrv2nd.h
浏览文件 @
1f8fc993
...
...
@@ -60,7 +60,6 @@ extern SK_U64 SkOsGetTime(SK_AC*);
extern
int
SkPciReadCfgDWord
(
SK_AC
*
,
int
,
SK_U32
*
);
extern
int
SkPciReadCfgWord
(
SK_AC
*
,
int
,
SK_U16
*
);
extern
int
SkPciReadCfgByte
(
SK_AC
*
,
int
,
SK_U8
*
);
extern
int
SkPciWriteCfgDWord
(
SK_AC
*
,
int
,
SK_U32
);
extern
int
SkPciWriteCfgWord
(
SK_AC
*
,
int
,
SK_U16
);
extern
int
SkPciWriteCfgByte
(
SK_AC
*
,
int
,
SK_U8
);
extern
int
SkDrvEvent
(
SK_AC
*
,
SK_IOC
IoC
,
SK_U32
,
SK_EVPARA
);
...
...
drivers/net/sk98lin/h/skvpd.h
浏览文件 @
1f8fc993
...
...
@@ -130,14 +130,12 @@ typedef struct s_vpd_key {
#ifndef VPD_DO_IO
#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
#define VPD_OUT32(pAC,IoC,Addr,Val) (void)SkPciWriteCfgDWord(pAC,Addr,Val)
#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
#else
/* VPD_DO_IO */
#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(Addr),Val)
#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
...
...
@@ -155,12 +153,6 @@ typedef struct s_vpd_key {
else \
SK_OUT16(pAC,PCI_C(Addr),Val); \
}
#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
if ((pAC)->DgT.DgUseCfgCycle) \
SkPciWriteCfgDWord(pAC,Addr,Val); \
else \
SK_OUT32(pAC,PCI_C(Addr),Val); \
}
#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
if ((pAC)->DgT.DgUseCfgCycle) \
SkPciReadCfgByte(pAC,Addr,pVal); \
...
...
drivers/net/sk98lin/skge.c
浏览文件 @
1f8fc993
...
...
@@ -277,6 +277,27 @@ extern struct ethtool_ops SkGeEthtoolOps;
static
uintptr_t
TxQueueAddr
[
SK_MAX_MACS
][
2
]
=
{{
0x680
,
0x600
},{
0x780
,
0x700
}};
static
uintptr_t
RxQueueAddr
[
SK_MAX_MACS
]
=
{
0x400
,
0x480
};
/*****************************************************************************
*
* SkPciWriteCfgDWord - write a 32 bit value to pci config space
*
* Description:
* This routine writes a 32 bit value to the pci configuration
* space.
*
* Returns:
* 0 - indicate everything worked ok.
* != 0 - error indication
*/
static
inline
int
SkPciWriteCfgDWord
(
SK_AC
*
pAC
,
/* Adapter Control structure pointer */
int
PciAddr
,
/* PCI register address */
SK_U32
Val
)
/* pointer to store the read value */
{
pci_write_config_dword
(
pAC
->
PciDev
,
PciAddr
,
Val
);
return
(
0
);
}
/* SkPciWriteCfgDWord */
/*****************************************************************************
*
* SkGeInitPCI - Init the PCI resources
...
...
@@ -4083,28 +4104,6 @@ SK_U8 *pVal) /* pointer to store the read value */
}
/* SkPciReadCfgByte */
/*****************************************************************************
*
* SkPciWriteCfgDWord - write a 32 bit value to pci config space
*
* Description:
* This routine writes a 32 bit value to the pci configuration
* space.
*
* Returns:
* 0 - indicate everything worked ok.
* != 0 - error indication
*/
int
SkPciWriteCfgDWord
(
SK_AC
*
pAC
,
/* Adapter Control structure pointer */
int
PciAddr
,
/* PCI register address */
SK_U32
Val
)
/* pointer to store the read value */
{
pci_write_config_dword
(
pAC
->
PciDev
,
PciAddr
,
Val
);
return
(
0
);
}
/* SkPciWriteCfgDWord */
/*****************************************************************************
*
* SkPciWriteCfgWord - write a 16 bit value to pci config space
...
...
drivers/net/wan/lmc/lmc_prot.h
已删除
100644 → 0
浏览文件 @
638cbac8
#ifndef _LMC_PROTO_H_
#define _LMC_PROTO_H_
void
lmc_proto_init
(
lmc_softc_t
*
const
)
void
lmc_proto_attach
(
lmc_softc_t
*
sc
const
)
void
lmc_proto_detach
(
lmc_softc
*
sc
const
)
void
lmc_proto_reopen
(
lmc_softc_t
*
sc
const
)
int
lmc_proto_ioctl
(
lmc_softc_t
*
sc
const
,
struct
ifreq
*
ifr
,
int
cmd
)
void
lmc_proto_open
(
lmc_softc_t
*
sc
const
)
void
lmc_proto_close
(
lmc_softc_t
*
sc
const
)
unsigned
short
lmc_proto_type
(
lmc_softc_t
*
sc
const
,
struct
skbuff
*
skb
)
#endif
drivers/net/wireless/atmel.c
浏览文件 @
1f8fc993
...
...
@@ -5,9 +5,9 @@
Copyright 2000-2001 ATMEL Corporation.
Copyright 2003-2004 Simon Kelley.
This code was developed from version 2.1.1 of the Atmel drivers,
released by Atmel corp. under the GPL in December 2002. It also
includes code from the Linux aironet drivers (C) Benjamin Reed,
This code was developed from version 2.1.1 of the Atmel drivers,
released by Atmel corp. under the GPL in December 2002. It also
includes code from the Linux aironet drivers (C) Benjamin Reed,
and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
extensions, (C) Jean Tourrilhes.
...
...
@@ -31,7 +31,7 @@
along with Atmel wireless lan drivers; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For all queries about this code, please contact the current author,
For all queries about this code, please contact the current author,
Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
...
...
@@ -79,13 +79,13 @@ MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.")
MODULE_LICENSE
(
"GPL"
);
MODULE_SUPPORTED_DEVICE
(
"Atmel at76c50x wireless cards"
);
/* The name of the firmware file to be loaded
/* The name of the firmware file to be loaded
over-rides any automatic selection */
static
char
*
firmware
=
NULL
;
module_param
(
firmware
,
charp
,
0
);
/* table of firmware file names */
static
struct
{
static
struct
{
AtmelFWType
fw_type
;
const
char
*
fw_file
;
const
char
*
fw_file_ext
;
...
...
@@ -104,17 +104,17 @@ static struct {
#define MAX_SSID_LENGTH 32
#define MGMT_JIFFIES (256 * HZ / 100)
#define MAX_BSS_ENTRIES 64
#define MAX_BSS_ENTRIES 64
/* registers */
#define GCR 0x00 // (SIR0) General Configuration Register
#define BSR 0x02 // (SIR1) Bank Switching Select Register
#define GCR 0x00 // (SIR0) General Configuration Register
#define BSR 0x02 // (SIR1) Bank Switching Select Register
#define AR 0x04
#define DR 0x08
#define MR1 0x12 // Mirror Register 1
#define MR2 0x14 // Mirror Register 2
#define MR3 0x16 // Mirror Register 3
#define MR4 0x18 // Mirror Register 4
#define MR1 0x12 // Mirror Register 1
#define MR2 0x14 // Mirror Register 2
#define MR3 0x16 // Mirror Register 3
#define MR4 0x18 // Mirror Register 4
#define GPR1 0x0c
#define GPR2 0x0e
...
...
@@ -123,9 +123,9 @@ static struct {
// Constants for the GCR register.
//
#define GCR_REMAP 0x0400 // Remap internal SRAM to 0
#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
#define GCR_CORES 0x0060 // Core Reset (ARM and PAI are reset)
#define GCR_ENINT 0x0002 // Enable Interrupts
#define GCR_ENINT 0x0002 // Enable Interrupts
#define GCR_ACKINT 0x0008 // Acknowledge Interrupts
#define BSS_SRAM 0x0200 // AMBA module selection --> SRAM
...
...
@@ -190,7 +190,7 @@ struct rx_desc {
u32
Next
;
u16
MsduPos
;
u16
MsduSize
;
u8
State
;
u8
Status
;
u8
Rate
;
...
...
@@ -199,7 +199,6 @@ struct rx_desc {
u8
PreambleType
;
u16
Duration
;
u32
RxTime
;
};
#define RX_DESC_FLAG_VALID 0x80
...
...
@@ -218,16 +217,15 @@ struct rx_desc {
#define RX_DESC_DURATION_OFFSET 14
#define RX_DESC_RX_TIME_OFFSET 16
struct
tx_desc
{
u32
NextDescriptor
;
u16
TxStartOfFrame
;
u16
TxLength
;
u8
TxState
;
u8
TxStatus
;
u8
RetryCount
;
u8
TxRate
;
u8
KeyIndex
;
...
...
@@ -238,10 +236,8 @@ struct tx_desc {
u8
Reserved
;
u8
PacketType
;
u16
HostTxLength
;
};
#define TX_DESC_NEXT_OFFSET 0
#define TX_DESC_POS_OFFSET 4
#define TX_DESC_SIZE_OFFSET 6
...
...
@@ -255,8 +251,6 @@ struct tx_desc {
#define TX_DESC_PACKET_TYPE_OFFSET 17
#define TX_DESC_HOST_LENGTH_OFFSET 18
///////////////////////////////////////////////////////
// Host-MAC interface
///////////////////////////////////////////////////////
...
...
@@ -266,7 +260,6 @@ struct tx_desc {
#define TX_FIRM_OWN 0x80
#define TX_DONE 0x40
#define TX_ERROR 0x01
#define TX_PACKET_TYPE_DATA 0x01
...
...
@@ -280,8 +273,7 @@ struct tx_desc {
#define ISR_COMMAND_COMPLETE 0x10 // command completed
#define ISR_OUT_OF_RANGE 0x20 // command completed
#define ISR_IBSS_MERGE 0x40 // (4.1.2.30): IBSS merge
#define ISR_GENERIC_IRQ 0x80
#define ISR_GENERIC_IRQ 0x80
#define Local_Mib_Type 0x01
#define Mac_Address_Mib_Type 0x02
...
...
@@ -317,7 +309,6 @@ struct tx_desc {
#define LOCAL_MIB_PREAMBLE_TYPE 9
#define MAC_ADDR_MIB_MAC_ADDR_POS 0
#define CMD_Set_MIB_Vars 0x01
#define CMD_Get_MIB_Vars 0x02
#define CMD_Scan 0x03
...
...
@@ -338,7 +329,6 @@ struct tx_desc {
#define CMD_STATUS_HOST_ERROR 0xFF
#define CMD_STATUS_BUSY 0xFE
#define CMD_BLOCK_COMMAND_OFFSET 0
#define CMD_BLOCK_STATUS_OFFSET 1
#define CMD_BLOCK_PARAMETERS_OFFSET 4
...
...
@@ -347,15 +337,15 @@ struct tx_desc {
#define MGMT_FRAME_BODY_OFFSET 24
#define MAX_AUTHENTICATION_RETRIES 3
#define MAX_ASSOCIATION_RETRIES
3
#define MAX_ASSOCIATION_RETRIES
3
#define AUTHENTICATION_RESPONSE_TIME_OUT 1000
#define MAX_WIRELESS_BODY 2316
/* mtu is 2312, CRC is 4 */
#define LOOP_RETRY_LIMIT 500000
#define ACTIVE_MODE
1
#define PS_MODE
2
#define ACTIVE_MODE 1
#define PS_MODE
2
#define MAX_ENCRYPTION_KEYS 4
#define MAX_ENCRYPTION_KEY_SIZE 40
...
...
@@ -377,7 +367,7 @@ struct tx_desc {
#define REG_DOMAIN_MKK1 0x41 //Channel 1-14 Japan(MKK1)
#define REG_DOMAIN_ISRAEL 0x50 //Channel 3-9 ISRAEL
#define BSS_TYPE_AD_HOC
1
#define BSS_TYPE_AD_HOC
1
#define BSS_TYPE_INFRASTRUCTURE 2
#define SCAN_TYPE_ACTIVE 0
...
...
@@ -389,7 +379,7 @@ struct tx_desc {
#define DATA_FRAME_WS_HEADER_SIZE 30
/* promiscuous mode control */
/* promiscuous mode control */
#define PROM_MODE_OFF 0x0
#define PROM_MODE_UNKNOWN 0x1
#define PROM_MODE_CRC_FAILED 0x2
...
...
@@ -398,8 +388,7 @@ struct tx_desc {
#define PROM_MODE_CTRL 0x10
#define PROM_MODE_BAD_PROTOCOL 0x20
#define IFACE_INT_STATUS_OFFSET 0
#define IFACE_INT_STATUS_OFFSET 0
#define IFACE_INT_MASK_OFFSET 1
#define IFACE_LOCKOUT_HOST_OFFSET 2
#define IFACE_LOCKOUT_MAC_OFFSET 3
...
...
@@ -407,7 +396,7 @@ struct tx_desc {
#define IFACE_MAC_STAT_OFFSET 30
#define IFACE_GENERIC_INT_TYPE_OFFSET 32
#define CIPHER_SUITE_NONE 0
#define CIPHER_SUITE_NONE 0
#define CIPHER_SUITE_WEP_64 1
#define CIPHER_SUITE_TKIP 2
#define CIPHER_SUITE_AES 3
...
...
@@ -419,11 +408,11 @@ struct tx_desc {
//
//
// FuncCtrl field:
// FuncCtrl field:
//
#define FUNC_CTRL_TxENABLE 0x10
#define FUNC_CTRL_RxENABLE 0x20
#define FUNC_CTRL_INIT_COMPLETE
0x01
#define FUNC_CTRL_INIT_COMPLETE
0x01
/* A stub firmware image which reads the MAC address from NVRAM on the card.
For copyright information and source see the end of this file. */
...
...
@@ -486,10 +475,10 @@ struct atmel_private {
struct
net_device_stats
stats
;
// device stats
spinlock_t
irqlock
,
timerlock
;
// spinlocks
enum
{
BUS_TYPE_PCCARD
,
BUS_TYPE_PCI
}
bus_type
;
enum
{
CARD_TYPE_PARALLEL_FLASH
,
enum
{
CARD_TYPE_PARALLEL_FLASH
,
CARD_TYPE_SPI_FLASH
,
CARD_TYPE_EEPROM
CARD_TYPE_EEPROM
}
card_type
;
int
do_rx_crc
;
/* If we need to CRC incoming packets */
int
probe_crc
;
/* set if we don't yet know */
...
...
@@ -497,18 +486,18 @@ struct atmel_private {
u16
rx_desc_head
;
u16
tx_desc_free
,
tx_desc_head
,
tx_desc_tail
,
tx_desc_previous
;
u16
tx_free_mem
,
tx_buff_head
,
tx_buff_tail
;
u16
frag_seq
,
frag_len
,
frag_no
;
u8
frag_source
[
6
];
u8
frag_source
[
6
];
u8
wep_is_on
,
default_key
,
exclude_unencrypted
,
encryption_level
;
u8
group_cipher_suite
,
pairwise_cipher_suite
;
u8
wep_keys
[
MAX_ENCRYPTION_KEYS
][
MAX_ENCRYPTION_KEY_SIZE
];
int
wep_key_len
[
MAX_ENCRYPTION_KEYS
];
int
wep_key_len
[
MAX_ENCRYPTION_KEYS
];
int
use_wpa
,
radio_on_broken
;
/* firmware dependent stuff. */
u16
host_info_base
;
struct
host_info_struct
{
struct
host_info_struct
{
/* NB this is matched to the hardware, don't change. */
u8
volatile
int_status
;
u8
volatile
int_mask
;
...
...
@@ -524,20 +513,20 @@ struct atmel_private {
u16
rx_buff_size
;
u16
rx_desc_pos
;
u16
rx_desc_count
;
u16
build_version
;
u16
command_pos
;
u16
command_pos
;
u16
major_version
;
u16
minor_version
;
u16
func_ctrl
;
u16
mac_status
;
u16
generic_IRQ_type
;
u8
reserved
[
2
];
}
host_info
;
enum
{
enum
{
STATION_STATE_SCANNING
,
STATION_STATE_JOINNING
,
STATION_STATE_AUTHENTICATING
,
...
...
@@ -547,7 +536,7 @@ struct atmel_private {
STATION_STATE_DOWN
,
STATION_STATE_MGMT_ERROR
}
station_state
;
int
operating_mode
,
power_mode
;
time_t
last_qual
;
int
beacons_this_sec
;
...
...
@@ -560,18 +549,18 @@ struct atmel_private {
int
long_retry
,
short_retry
;
int
preamble
;
int
default_beacon_period
,
beacon_period
,
listen_interval
;
int
CurrentAuthentTransactionSeqNum
,
ExpectedAuthentTransactionSeqNum
;
int
CurrentAuthentTransactionSeqNum
,
ExpectedAuthentTransactionSeqNum
;
int
AuthenticationRequestRetryCnt
,
AssociationRequestRetryCnt
,
ReAssociationRequestRetryCnt
;
enum
{
SITE_SURVEY_IDLE
,
SITE_SURVEY_IN_PROGRESS
,
SITE_SURVEY_COMPLETED
SITE_SURVEY_COMPLETED
}
site_survey_state
;
time_t
last_survey
;
int
station_was_associated
,
station_is_associated
;
int
fast_scan
;
struct
bss_info
{
int
channel
;
int
SSIDsize
;
...
...
@@ -584,13 +573,12 @@ struct atmel_private {
u8
SSID
[
MAX_SSID_LENGTH
];
}
BSSinfo
[
MAX_BSS_ENTRIES
];
int
BSS_list_entries
,
current_BSS
;
int
connect_to_any_BSS
;
int
connect_to_any_BSS
;
int
SSID_size
,
new_SSID_size
;
u8
CurrentBSSID
[
6
],
BSSID
[
6
];
u8
SSID
[
MAX_SSID_LENGTH
],
new_SSID
[
MAX_SSID_LENGTH
];
u64
last_beacon_timestamp
;
u8
rx_buf
[
MAX_WIRELESS_BODY
];
};
static
u8
atmel_basic_rates
[
4
]
=
{
0x82
,
0x84
,
0x0b
,
0x16
};
...
...
@@ -598,39 +586,49 @@ static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
static
const
struct
{
int
reg_domain
;
int
min
,
max
;
char
*
name
;
char
*
name
;
}
channel_table
[]
=
{
{
REG_DOMAIN_FCC
,
1
,
11
,
"USA"
},
{
REG_DOMAIN_DOC
,
1
,
11
,
"Canada"
},
{
REG_DOMAIN_ETSI
,
1
,
13
,
"Europe"
},
{
REG_DOMAIN_SPAIN
,
10
,
11
,
"Spain"
},
{
REG_DOMAIN_FRANCE
,
10
,
13
,
"France"
},
{
REG_DOMAIN_FRANCE
,
10
,
13
,
"France"
},
{
REG_DOMAIN_MKK
,
14
,
14
,
"MKK"
},
{
REG_DOMAIN_MKK1
,
1
,
14
,
"MKK1"
},
{
REG_DOMAIN_ISRAEL
,
3
,
9
,
"Israel"
}
};
static
void
build_wpa_mib
(
struct
atmel_private
*
priv
);
static
int
atmel_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
);
static
void
atmel_copy_to_card
(
struct
net_device
*
dev
,
u16
dest
,
unsigned
char
*
src
,
u16
len
);
static
void
atmel_copy_to_host
(
struct
net_device
*
dev
,
unsigned
char
*
dest
,
u16
src
,
u16
len
);
static
void
atmel_copy_to_card
(
struct
net_device
*
dev
,
u16
dest
,
unsigned
char
*
src
,
u16
len
);
static
void
atmel_copy_to_host
(
struct
net_device
*
dev
,
unsigned
char
*
dest
,
u16
src
,
u16
len
);
static
void
atmel_set_gcr
(
struct
net_device
*
dev
,
u16
mask
);
static
void
atmel_clear_gcr
(
struct
net_device
*
dev
,
u16
mask
);
static
int
atmel_lock_mac
(
struct
atmel_private
*
priv
);
static
void
atmel_wmem32
(
struct
atmel_private
*
priv
,
u16
pos
,
u32
data
);
static
void
atmel_command_irq
(
struct
atmel_private
*
priv
);
static
int
atmel_validate_channel
(
struct
atmel_private
*
priv
,
int
channel
);
static
void
atmel_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
static
void
atmel_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
frame_len
,
u8
rssi
);
static
void
atmel_management_timer
(
u_long
a
);
static
void
atmel_send_command
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
);
static
int
atmel_send_command_wait
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
);
static
void
atmel_transmit_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
static
void
atmel_send_command
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
);
static
int
atmel_send_command_wait
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
);
static
void
atmel_transmit_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u8
*
body
,
int
body_len
);
static
u8
atmel_get_mib8
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
);
static
void
atmel_set_mib8
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
data
);
static
void
atmel_set_mib16
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u16
data
);
static
void
atmel_set_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
);
static
void
atmel_get_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
);
static
void
atmel_set_mib8
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
data
);
static
void
atmel_set_mib16
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u16
data
);
static
void
atmel_set_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
);
static
void
atmel_get_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
);
static
void
atmel_scan
(
struct
atmel_private
*
priv
,
int
specific_ssid
);
static
void
atmel_join_bss
(
struct
atmel_private
*
priv
,
int
bss_index
);
static
void
atmel_smooth_qual
(
struct
atmel_private
*
priv
);
...
...
@@ -650,12 +648,12 @@ static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
return
priv
->
host_info
.
command_pos
+
offset
;
}
static
inline
u16
atmel_rx
(
struct
atmel_private
*
priv
,
u16
offset
,
u16
desc
)
static
inline
u16
atmel_rx
(
struct
atmel_private
*
priv
,
u16
offset
,
u16
desc
)
{
return
priv
->
host_info
.
rx_desc_pos
+
(
sizeof
(
struct
rx_desc
)
*
desc
)
+
offset
;
}
static
inline
u16
atmel_tx
(
struct
atmel_private
*
priv
,
u16
offset
,
u16
desc
)
static
inline
u16
atmel_tx
(
struct
atmel_private
*
priv
,
u16
offset
,
u16
desc
)
{
return
priv
->
host_info
.
tx_desc_pos
+
(
sizeof
(
struct
tx_desc
)
*
desc
)
+
offset
;
}
...
...
@@ -682,25 +680,25 @@ static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
static
inline
u8
atmel_rmem8
(
struct
atmel_private
*
priv
,
u16
pos
)
{
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_writeAR
(
priv
->
dev
,
pos
);
return
atmel_read8
(
priv
->
dev
,
DR
);
}
static
inline
void
atmel_wmem8
(
struct
atmel_private
*
priv
,
u16
pos
,
u16
data
)
{
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_write8
(
priv
->
dev
,
DR
,
data
);
}
static
inline
u16
atmel_rmem16
(
struct
atmel_private
*
priv
,
u16
pos
)
{
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_writeAR
(
priv
->
dev
,
pos
);
return
atmel_read16
(
priv
->
dev
,
DR
);
}
static
inline
void
atmel_wmem16
(
struct
atmel_private
*
priv
,
u16
pos
,
u16
data
)
{
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_write16
(
priv
->
dev
,
DR
,
data
);
}
...
...
@@ -710,11 +708,10 @@ static void tx_done_irq(struct atmel_private *priv)
{
int
i
;
for
(
i
=
0
;
for
(
i
=
0
;
atmel_rmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_FLAGS_OFFSET
,
priv
->
tx_desc_head
))
==
TX_DONE
&&
i
<
priv
->
host_info
.
tx_desc_count
;
i
++
)
{
u8
status
=
atmel_rmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_STATUS_OFFSET
,
priv
->
tx_desc_head
));
u16
msdu_size
=
atmel_rmem16
(
priv
,
atmel_tx
(
priv
,
TX_DESC_SIZE_OFFSET
,
priv
->
tx_desc_head
));
u8
type
=
atmel_rmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_PACKET_TYPE_OFFSET
,
priv
->
tx_desc_head
));
...
...
@@ -728,16 +725,16 @@ static void tx_done_irq(struct atmel_private *priv)
priv
->
tx_buff_head
=
0
;
else
priv
->
tx_buff_head
+=
msdu_size
;
if
(
priv
->
tx_desc_head
<
(
priv
->
host_info
.
tx_desc_count
-
1
))
priv
->
tx_desc_head
++
;
priv
->
tx_desc_head
++
;
else
priv
->
tx_desc_head
=
0
;
if
(
type
==
TX_PACKET_TYPE_DATA
)
{
if
(
status
==
TX_STATUS_SUCCESS
)
priv
->
stats
.
tx_packets
++
;
else
else
priv
->
stats
.
tx_errors
++
;
netif_wake_queue
(
priv
->
dev
);
}
...
...
@@ -748,21 +745,22 @@ static u16 find_tx_buff(struct atmel_private *priv, u16 len)
{
u16
bottom_free
=
priv
->
host_info
.
tx_buff_size
-
priv
->
tx_buff_tail
;
if
(
priv
->
tx_desc_free
==
3
||
priv
->
tx_free_mem
<
len
)
if
(
priv
->
tx_desc_free
==
3
||
priv
->
tx_free_mem
<
len
)
return
0
;
if
(
bottom_free
>=
len
)
return
priv
->
host_info
.
tx_buff_pos
+
priv
->
tx_buff_tail
;
if
(
priv
->
tx_free_mem
-
bottom_free
>=
len
)
{
priv
->
tx_buff_tail
=
0
;
return
priv
->
host_info
.
tx_buff_pos
;
}
return
0
;
}
static
void
tx_update_descriptor
(
struct
atmel_private
*
priv
,
int
is_bcast
,
u16
len
,
u16
buff
,
u8
type
)
static
void
tx_update_descriptor
(
struct
atmel_private
*
priv
,
int
is_bcast
,
u16
len
,
u16
buff
,
u8
type
)
{
atmel_wmem16
(
priv
,
atmel_tx
(
priv
,
TX_DESC_POS_OFFSET
,
priv
->
tx_desc_tail
),
buff
);
atmel_wmem16
(
priv
,
atmel_tx
(
priv
,
TX_DESC_SIZE_OFFSET
,
priv
->
tx_desc_tail
),
len
);
...
...
@@ -775,8 +773,8 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
int
cipher_type
,
cipher_length
;
if
(
is_bcast
)
{
cipher_type
=
priv
->
group_cipher_suite
;
if
(
cipher_type
==
CIPHER_SUITE_WEP_64
||
cipher_type
==
CIPHER_SUITE_WEP_128
)
if
(
cipher_type
==
CIPHER_SUITE_WEP_64
||
cipher_type
==
CIPHER_SUITE_WEP_128
)
cipher_length
=
8
;
else
if
(
cipher_type
==
CIPHER_SUITE_TKIP
)
cipher_length
=
12
;
...
...
@@ -790,8 +788,8 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
}
}
else
{
cipher_type
=
priv
->
pairwise_cipher_suite
;
if
(
cipher_type
==
CIPHER_SUITE_WEP_64
||
cipher_type
==
CIPHER_SUITE_WEP_128
)
if
(
cipher_type
==
CIPHER_SUITE_WEP_64
||
cipher_type
==
CIPHER_SUITE_WEP_128
)
cipher_length
=
8
;
else
if
(
cipher_type
==
CIPHER_SUITE_TKIP
)
cipher_length
=
12
;
...
...
@@ -804,9 +802,9 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
cipher_length
=
0
;
}
}
atmel_wmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_CIPHER_TYPE_OFFSET
,
priv
->
tx_desc_tail
),
cipher_type
);
cipher_type
);
atmel_wmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_CIPHER_LENGTH_OFFSET
,
priv
->
tx_desc_tail
),
cipher_length
);
}
...
...
@@ -815,46 +813,46 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
if
(
priv
->
tx_desc_previous
!=
priv
->
tx_desc_tail
)
atmel_wmem32
(
priv
,
atmel_tx
(
priv
,
TX_DESC_NEXT_OFFSET
,
priv
->
tx_desc_previous
),
0
);
priv
->
tx_desc_previous
=
priv
->
tx_desc_tail
;
if
(
priv
->
tx_desc_tail
<
(
priv
->
host_info
.
tx_desc_count
-
1
))
if
(
priv
->
tx_desc_tail
<
(
priv
->
host_info
.
tx_desc_count
-
1
))
priv
->
tx_desc_tail
++
;
else
priv
->
tx_desc_tail
=
0
;
priv
->
tx_desc_free
--
;
priv
->
tx_free_mem
-=
len
;
}
static
int
start_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
int
start_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
struct
ieee80211_hdr_4addr
header
;
unsigned
long
flags
;
u16
buff
,
frame_ctl
,
len
=
(
ETH_ZLEN
<
skb
->
len
)
?
skb
->
len
:
ETH_ZLEN
;
u8
SNAP_RFC1024
[
6
]
=
{
0xaa
,
0xaa
,
0x03
,
0x00
,
0x00
,
0x00
};
if
(
priv
->
card
&&
priv
->
present_callback
&&
if
(
priv
->
card
&&
priv
->
present_callback
&&
!
(
*
priv
->
present_callback
)(
priv
->
card
))
{
priv
->
stats
.
tx_errors
++
;
dev_kfree_skb
(
skb
);
return
0
;
}
if
(
priv
->
station_state
!=
STATION_STATE_READY
)
{
priv
->
stats
.
tx_errors
++
;
dev_kfree_skb
(
skb
);
return
0
;
}
/* first ensure the timer func cannot run */
spin_lock_bh
(
&
priv
->
timerlock
);
spin_lock_bh
(
&
priv
->
timerlock
);
/* then stop the hardware ISR */
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
/* nb doing the above in the opposite order will deadlock */
/* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
12 first bytes (containing DA/SA) and put them in the appropriate fields of
the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
12 first bytes (containing DA/SA) and put them in the appropriate
fields of the Wireless Header. Thus the packet length is then the
initial + 18 (+30-12) */
if
(
!
(
buff
=
find_tx_buff
(
priv
,
len
+
18
)))
{
priv
->
stats
.
tx_dropped
++
;
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
...
...
@@ -862,7 +860,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
return
1
;
}
frame_ctl
=
IEEE80211_FTYPE_DATA
;
header
.
duration_id
=
0
;
header
.
seq_ctl
=
0
;
...
...
@@ -878,7 +876,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
memcpy
(
&
header
.
addr2
,
dev
->
dev_addr
,
6
);
memcpy
(
&
header
.
addr3
,
skb
->
data
,
6
);
}
if
(
priv
->
use_wpa
)
memcpy
(
&
header
.
addr4
,
SNAP_RFC1024
,
6
);
...
...
@@ -888,27 +886,27 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
/* Copy the packet sans its 802.3 header addresses which have been replaced */
atmel_copy_to_card
(
dev
,
buff
+
DATA_FRAME_WS_HEADER_SIZE
,
skb
->
data
+
12
,
len
-
12
);
priv
->
tx_buff_tail
+=
len
-
12
+
DATA_FRAME_WS_HEADER_SIZE
;
/* low bit of first byte of destination tells us if broadcast */
tx_update_descriptor
(
priv
,
*
(
skb
->
data
)
&
0x01
,
len
+
18
,
buff
,
TX_PACKET_TYPE_DATA
);
dev
->
trans_start
=
jiffies
;
priv
->
stats
.
tx_bytes
+=
len
;
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
spin_unlock_bh
(
&
priv
->
timerlock
);
dev_kfree_skb
(
skb
);
return
0
;
return
0
;
}
static
void
atmel_transmit_management_frame
(
struct
atmel_private
*
priv
,
static
void
atmel_transmit_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u8
*
body
,
int
body_len
)
{
u16
buff
;
int
len
=
MGMT_FRAME_BODY_OFFSET
+
body_len
;
if
(
!
(
buff
=
find_tx_buff
(
priv
,
len
)))
int
len
=
MGMT_FRAME_BODY_OFFSET
+
body_len
;
if
(
!
(
buff
=
find_tx_buff
(
priv
,
len
)))
return
;
atmel_copy_to_card
(
priv
->
dev
,
buff
,
(
u8
*
)
header
,
MGMT_FRAME_BODY_OFFSET
);
...
...
@@ -916,24 +914,25 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
priv
->
tx_buff_tail
+=
len
;
tx_update_descriptor
(
priv
,
header
->
addr1
[
0
]
&
0x01
,
len
,
buff
,
TX_PACKET_TYPE_MGMT
);
}
static
void
fast_rx_path
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
static
void
fast_rx_path
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
msdu_size
,
u16
rx_packet_loc
,
u32
crc
)
{
/* fast path: unfragmented packet copy directly into skbuf */
u8
mac4
[
6
];
struct
sk_buff
*
skb
;
u8
mac4
[
6
];
struct
sk_buff
*
skb
;
unsigned
char
*
skbp
;
/* get the final, mac 4 header field, this tells us encapsulation */
atmel_copy_to_host
(
priv
->
dev
,
mac4
,
rx_packet_loc
+
24
,
6
);
msdu_size
-=
6
;
if
(
priv
->
do_rx_crc
)
{
crc
=
crc32_le
(
crc
,
mac4
,
6
);
msdu_size
-=
4
;
}
if
(
!
(
skb
=
dev_alloc_skb
(
msdu_size
+
14
)))
{
priv
->
stats
.
rx_dropped
++
;
return
;
...
...
@@ -942,7 +941,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
skb_reserve
(
skb
,
2
);
skbp
=
skb_put
(
skb
,
msdu_size
+
12
);
atmel_copy_to_host
(
priv
->
dev
,
skbp
+
12
,
rx_packet_loc
+
30
,
msdu_size
);
if
(
priv
->
do_rx_crc
)
{
u32
netcrc
;
crc
=
crc32_le
(
crc
,
skbp
+
12
,
msdu_size
);
...
...
@@ -953,24 +952,25 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
return
;
}
}
memcpy
(
skbp
,
header
->
addr1
,
6
);
/* destination address */
if
(
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_FROMDS
)
if
(
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_FROMDS
)
memcpy
(
&
skbp
[
6
],
header
->
addr3
,
6
);
else
memcpy
(
&
skbp
[
6
],
header
->
addr2
,
6
);
/* source address */
priv
->
dev
->
last_rx
=
jiffies
;
priv
->
dev
->
last_rx
=
jiffies
;
skb
->
dev
=
priv
->
dev
;
skb
->
protocol
=
eth_type_trans
(
skb
,
priv
->
dev
);
skb
->
ip_summed
=
CHECKSUM_NONE
;
skb
->
ip_summed
=
CHECKSUM_NONE
;
netif_rx
(
skb
);
priv
->
stats
.
rx_bytes
+=
12
+
msdu_size
;
priv
->
stats
.
rx_packets
++
;
}
/* Test to see if the packet in card memory at packet_loc has a valid CRC
It doesn't matter that this is slow: it is only used to proble the first few packets. */
It doesn't matter that this is slow: it is only used to proble the first few
packets. */
static
int
probe_crc
(
struct
atmel_private
*
priv
,
u16
packet_loc
,
u16
msdu_size
)
{
int
i
=
msdu_size
-
4
;
...
...
@@ -980,7 +980,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return
0
;
atmel_copy_to_host
(
priv
->
dev
,
(
void
*
)
&
netcrc
,
packet_loc
+
i
,
4
);
atmel_writeAR
(
priv
->
dev
,
packet_loc
);
while
(
i
--
)
{
u8
octet
=
atmel_read8
(
priv
->
dev
,
DR
);
...
...
@@ -990,20 +990,22 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return
(
crc
^
0xffffffff
)
==
netcrc
;
}
static
void
frag_rx_path
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
msdu_size
,
u16
rx_packet_loc
,
u32
crc
,
u16
seq_no
,
u8
frag_no
,
int
more_frags
)
static
void
frag_rx_path
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
msdu_size
,
u16
rx_packet_loc
,
u32
crc
,
u16
seq_no
,
u8
frag_no
,
int
more_frags
)
{
u8
mac4
[
6
];
u8
mac4
[
6
];
u8
source
[
6
];
struct
sk_buff
*
skb
;
if
(
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_FROMDS
)
if
(
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_FROMDS
)
memcpy
(
source
,
header
->
addr3
,
6
);
else
memcpy
(
source
,
header
->
addr2
,
6
);
memcpy
(
source
,
header
->
addr2
,
6
);
rx_packet_loc
+=
24
;
/* skip header */
if
(
priv
->
do_rx_crc
)
msdu_size
-=
4
;
...
...
@@ -1012,16 +1014,16 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
msdu_size
-=
6
;
rx_packet_loc
+=
6
;
if
(
priv
->
do_rx_crc
)
if
(
priv
->
do_rx_crc
)
crc
=
crc32_le
(
crc
,
mac4
,
6
);
priv
->
frag_seq
=
seq_no
;
priv
->
frag_no
=
1
;
priv
->
frag_len
=
msdu_size
;
memcpy
(
priv
->
frag_source
,
source
,
6
);
memcpy
(
priv
->
frag_source
,
source
,
6
);
memcpy
(
&
priv
->
rx_buf
[
6
],
source
,
6
);
memcpy
(
priv
->
rx_buf
,
header
->
addr1
,
6
);
atmel_copy_to_host
(
priv
->
dev
,
&
priv
->
rx_buf
[
12
],
rx_packet_loc
,
msdu_size
);
if
(
priv
->
do_rx_crc
)
{
...
...
@@ -1033,17 +1035,17 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
memset
(
priv
->
frag_source
,
0xff
,
6
);
}
}
}
else
if
(
priv
->
frag_no
==
frag_no
&&
priv
->
frag_seq
==
seq_no
&&
memcmp
(
priv
->
frag_source
,
source
,
6
)
==
0
)
{
atmel_copy_to_host
(
priv
->
dev
,
&
priv
->
rx_buf
[
12
+
priv
->
frag_len
],
atmel_copy_to_host
(
priv
->
dev
,
&
priv
->
rx_buf
[
12
+
priv
->
frag_len
],
rx_packet_loc
,
msdu_size
);
if
(
priv
->
do_rx_crc
)
{
u32
netcrc
;
crc
=
crc32_le
(
crc
,
&
priv
->
rx_buf
[
12
+
priv
->
frag_len
],
crc
=
crc32_le
(
crc
,
&
priv
->
rx_buf
[
12
+
priv
->
frag_len
],
msdu_size
);
atmel_copy_to_host
(
priv
->
dev
,
(
void
*
)
&
netcrc
,
rx_packet_loc
+
msdu_size
,
4
);
if
((
crc
^
0xffffffff
)
!=
netcrc
)
{
...
...
@@ -1052,7 +1054,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
more_frags
=
1
;
/* don't send broken assembly */
}
}
priv
->
frag_len
+=
msdu_size
;
priv
->
frag_no
++
;
...
...
@@ -1062,60 +1064,60 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
priv
->
stats
.
rx_dropped
++
;
}
else
{
skb_reserve
(
skb
,
2
);
memcpy
(
skb_put
(
skb
,
priv
->
frag_len
+
12
),
memcpy
(
skb_put
(
skb
,
priv
->
frag_len
+
12
),
priv
->
rx_buf
,
priv
->
frag_len
+
12
);
priv
->
dev
->
last_rx
=
jiffies
;
skb
->
dev
=
priv
->
dev
;
skb
->
protocol
=
eth_type_trans
(
skb
,
priv
->
dev
);
skb
->
ip_summed
=
CHECKSUM_NONE
;
skb
->
ip_summed
=
CHECKSUM_NONE
;
netif_rx
(
skb
);
priv
->
stats
.
rx_bytes
+=
priv
->
frag_len
+
12
;
priv
->
stats
.
rx_packets
++
;
}
}
}
else
priv
->
wstats
.
discard
.
fragment
++
;
}
static
void
rx_done_irq
(
struct
atmel_private
*
priv
)
{
int
i
;
struct
ieee80211_hdr_4addr
header
;
for
(
i
=
0
;
for
(
i
=
0
;
atmel_rmem8
(
priv
,
atmel_rx
(
priv
,
RX_DESC_FLAGS_OFFSET
,
priv
->
rx_desc_head
))
==
RX_DESC_FLAG_VALID
&&
i
<
priv
->
host_info
.
rx_desc_count
;
i
++
)
{
u16
msdu_size
,
rx_packet_loc
,
frame_ctl
,
seq_control
;
u8
status
=
atmel_rmem8
(
priv
,
atmel_rx
(
priv
,
RX_DESC_STATUS_OFFSET
,
priv
->
rx_desc_head
));
u32
crc
=
0xffffffff
;
if
(
status
!=
RX_STATUS_SUCCESS
)
{
if
(
status
==
0xc1
)
/* determined by experiment */
priv
->
wstats
.
discard
.
nwid
++
;
else
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_errors
++
;
goto
next
;
}
msdu_size
=
atmel_rmem16
(
priv
,
atmel_rx
(
priv
,
RX_DESC_MSDU_SIZE_OFFSET
,
priv
->
rx_desc_head
));
rx_packet_loc
=
atmel_rmem16
(
priv
,
atmel_rx
(
priv
,
RX_DESC_MSDU_POS_OFFSET
,
priv
->
rx_desc_head
));
if
(
msdu_size
<
30
)
{
priv
->
stats
.
rx_errors
++
;
priv
->
stats
.
rx_errors
++
;
goto
next
;
}
/* Get header as far as end of seq_ctl */
atmel_copy_to_host
(
priv
->
dev
,
(
char
*
)
&
header
,
rx_packet_loc
,
24
);
frame_ctl
=
le16_to_cpu
(
header
.
frame_ctl
);
seq_control
=
le16_to_cpu
(
header
.
seq_ctl
);
/* probe for CRC use here if needed once five packets have arrived with
the same crc status, we assume we know what's happening and stop probing */
/* probe for CRC use here if needed once five packets have
arrived with the same crc status, we assume we know what's
happening and stop probing */
if
(
priv
->
probe_crc
)
{
if
(
!
priv
->
wep_is_on
||
!
(
frame_ctl
&
IEEE80211_FCTL_PROTECTED
))
{
priv
->
do_rx_crc
=
probe_crc
(
priv
,
rx_packet_loc
,
msdu_size
);
...
...
@@ -1130,34 +1132,33 @@ static void rx_done_irq(struct atmel_private *priv)
priv
->
probe_crc
=
0
;
}
}
/* don't CRC header when WEP in use */
if
(
priv
->
do_rx_crc
&&
(
!
priv
->
wep_is_on
||
!
(
frame_ctl
&
IEEE80211_FCTL_PROTECTED
)))
{
crc
=
crc32_le
(
0xffffffff
,
(
unsigned
char
*
)
&
header
,
24
);
}
msdu_size
-=
24
;
/* header */
if
((
frame_ctl
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
)
{
if
((
frame_ctl
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
)
{
int
more_fragments
=
frame_ctl
&
IEEE80211_FCTL_MOREFRAGS
;
u8
packet_fragment_no
=
seq_control
&
IEEE80211_SCTL_FRAG
;
u16
packet_sequence_no
=
(
seq_control
&
IEEE80211_SCTL_SEQ
)
>>
4
;
if
(
!
more_fragments
&&
packet_fragment_no
==
0
)
{
if
(
!
more_fragments
&&
packet_fragment_no
==
0
)
{
fast_rx_path
(
priv
,
&
header
,
msdu_size
,
rx_packet_loc
,
crc
);
}
else
{
frag_rx_path
(
priv
,
&
header
,
msdu_size
,
rx_packet_loc
,
crc
,
packet_sequence_no
,
packet_fragment_no
,
more_fragments
);
}
}
if
((
frame_ctl
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_MGMT
)
{
/* copy rest of packet into buffer */
atmel_copy_to_host
(
priv
->
dev
,
(
unsigned
char
*
)
&
priv
->
rx_buf
,
rx_packet_loc
+
24
,
msdu_size
);
/* we use the same buffer for frag reassembly and control packets */
memset
(
priv
->
frag_source
,
0xff
,
6
);
if
(
priv
->
do_rx_crc
)
{
/* last 4 octets is crc */
msdu_size
-=
4
;
...
...
@@ -1170,18 +1171,18 @@ static void rx_done_irq(struct atmel_private *priv)
atmel_management_frame
(
priv
,
&
header
,
msdu_size
,
atmel_rmem8
(
priv
,
atmel_rx
(
priv
,
RX_DESC_RSSI_OFFSET
,
priv
->
rx_desc_head
)));
}
}
next:
next:
/* release descriptor */
atmel_wmem8
(
priv
,
atmel_rx
(
priv
,
RX_DESC_FLAGS_OFFSET
,
priv
->
rx_desc_head
),
RX_DESC_FLAG_CONSUMED
);
atmel_wmem8
(
priv
,
atmel_rx
(
priv
,
RX_DESC_FLAGS_OFFSET
,
priv
->
rx_desc_head
),
RX_DESC_FLAG_CONSUMED
);
if
(
priv
->
rx_desc_head
<
(
priv
->
host_info
.
rx_desc_count
-
1
))
priv
->
rx_desc_head
++
;
priv
->
rx_desc_head
++
;
else
priv
->
rx_desc_head
=
0
;
}
}
}
static
irqreturn_t
service_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
...
...
@@ -1189,7 +1190,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
u8
isr
;
int
i
=
-
1
;
static
u8
irq_order
[]
=
{
static
u8
irq_order
[]
=
{
ISR_OUT_OF_RANGE
,
ISR_RxCOMPLETE
,
ISR_TxCOMPLETE
,
...
...
@@ -1199,20 +1200,19 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
ISR_IBSS_MERGE
,
ISR_GENERIC_IRQ
};
if
(
priv
->
card
&&
priv
->
present_callback
&&
if
(
priv
->
card
&&
priv
->
present_callback
&&
!
(
*
priv
->
present_callback
)(
priv
->
card
))
return
IRQ_HANDLED
;
/* In this state upper-level code assumes it can mess with
the card unhampered by interrupts which may change register state.
Note that even though the card shouldn't generate interrupts
the inturrupt line may be shared. This allows card setup
the inturrupt line may be shared. This allows card setup
to go on without disabling interrupts for a long time. */
if
(
priv
->
station_state
==
STATION_STATE_DOWN
)
return
IRQ_NONE
;
atmel_clear_gcr
(
dev
,
GCR_ENINT
);
/* disable interrupts */
while
(
1
)
{
...
...
@@ -1221,36 +1221,36 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
printk
(
KERN_ALERT
"%s: failed to contact MAC.
\n
"
,
dev
->
name
);
return
IRQ_HANDLED
;
}
isr
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_INT_STATUS_OFFSET
));
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_LOCKOUT_MAC_OFFSET
),
0
);
if
(
!
isr
)
{
atmel_set_gcr
(
dev
,
GCR_ENINT
);
/* enable interrupts */
return
i
==
-
1
?
IRQ_NONE
:
IRQ_HANDLED
;
}
atmel_set_gcr
(
dev
,
GCR_ACKINT
);
/* acknowledge interrupt */
for
(
i
=
0
;
i
<
sizeof
(
irq_order
)
/
sizeof
(
u8
);
i
++
)
if
(
isr
&
irq_order
[
i
])
break
;
if
(
!
atmel_lock_mac
(
priv
))
{
/* failed to contact card */
printk
(
KERN_ALERT
"%s: failed to contact MAC.
\n
"
,
dev
->
name
);
return
IRQ_HANDLED
;
}
isr
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_INT_STATUS_OFFSET
));
isr
^=
irq_order
[
i
];
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_INT_STATUS_OFFSET
),
isr
);
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_LOCKOUT_MAC_OFFSET
),
0
);
switch
(
irq_order
[
i
])
{
case
ISR_OUT_OF_RANGE
:
if
(
priv
->
operating_mode
==
IW_MODE_INFRA
&&
case
ISR_OUT_OF_RANGE
:
if
(
priv
->
operating_mode
==
IW_MODE_INFRA
&&
priv
->
station_state
==
STATION_STATE_READY
)
{
priv
->
station_is_associated
=
0
;
atmel_scan
(
priv
,
1
);
...
...
@@ -1261,24 +1261,24 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
priv
->
wstats
.
discard
.
misc
++
;
/* fall through */
case
ISR_RxCOMPLETE
:
rx_done_irq
(
priv
);
rx_done_irq
(
priv
);
break
;
case
ISR_TxCOMPLETE
:
tx_done_irq
(
priv
);
tx_done_irq
(
priv
);
break
;
case
ISR_FATAL_ERROR
:
printk
(
KERN_ALERT
"%s: *** FATAL error interrupt ***
\n
"
,
dev
->
name
);
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
break
;
case
ISR_COMMAND_COMPLETE
:
case
ISR_COMMAND_COMPLETE
:
atmel_command_irq
(
priv
);
break
;
case
ISR_IBSS_MERGE
:
atmel_get_mib
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_CUR_BSSID_POS
,
atmel_get_mib
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_CUR_BSSID_POS
,
priv
->
CurrentBSSID
,
6
);
/* The WPA stuff cares about the current AP address */
if
(
priv
->
use_wpa
)
...
...
@@ -1288,24 +1288,23 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
printk
(
KERN_INFO
"%s: Generic_irq received.
\n
"
,
dev
->
name
);
break
;
}
}
}
}
static
struct
net_device_stats
*
atmel_get_stats
(
struct
net_device
*
dev
)
static
struct
net_device_stats
*
atmel_get_stats
(
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
return
&
priv
->
stats
;
}
static
struct
iw_statistics
*
atmel_get_wireless_stats
(
struct
net_device
*
dev
)
static
struct
iw_statistics
*
atmel_get_wireless_stats
(
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
/* update the link quality here in case we are seeing no beacons
/* update the link quality here in case we are seeing no beacons
at all to drive the process */
atmel_smooth_qual
(
priv
);
priv
->
wstats
.
status
=
priv
->
station_state
;
if
(
priv
->
operating_mode
==
IW_MODE_INFRA
)
{
...
...
@@ -1328,8 +1327,8 @@ static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
|
IW_QUAL_NOISE_INVALID
;
priv
->
wstats
.
miss
.
beacon
=
0
;
}
return
(
&
priv
->
wstats
)
;
return
&
priv
->
wstats
;
}
static
int
atmel_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
...
...
@@ -1343,21 +1342,21 @@ static int atmel_change_mtu(struct net_device *dev, int new_mtu)
static
int
atmel_set_mac_address
(
struct
net_device
*
dev
,
void
*
p
)
{
struct
sockaddr
*
addr
=
p
;
memcpy
(
dev
->
dev_addr
,
addr
->
sa_data
,
dev
->
addr_len
);
return
atmel_open
(
dev
);
}
EXPORT_SYMBOL
(
atmel_open
);
int
atmel_open
(
struct
net_device
*
dev
)
int
atmel_open
(
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
int
i
,
channel
;
/* any scheduled timer is no longer needed and might screw things up.. */
del_timer_sync
(
&
priv
->
management_timer
);
/* Interrupts will not touch the card once in this state... */
priv
->
station_state
=
STATION_STATE_DOWN
;
...
...
@@ -1377,7 +1376,7 @@ int atmel_open (struct net_device *dev)
priv
->
site_survey_state
=
SITE_SURVEY_IDLE
;
priv
->
station_is_associated
=
0
;
if
(
!
reset_atmel_card
(
dev
))
if
(
!
reset_atmel_card
(
dev
))
return
-
EAGAIN
;
if
(
priv
->
config_reg_domain
)
{
...
...
@@ -1391,26 +1390,26 @@ int atmel_open (struct net_device *dev)
if
(
i
==
sizeof
(
channel_table
)
/
sizeof
(
channel_table
[
0
]))
{
priv
->
reg_domain
=
REG_DOMAIN_MKK1
;
printk
(
KERN_ALERT
"%s: failed to get regulatory domain: assuming MKK1.
\n
"
,
dev
->
name
);
}
}
}
if
((
channel
=
atmel_validate_channel
(
priv
,
priv
->
channel
)))
priv
->
channel
=
channel
;
/* this moves station_state on.... */
atmel_scan
(
priv
,
1
);
/* this moves station_state on.... */
atmel_scan
(
priv
,
1
);
atmel_set_gcr
(
priv
->
dev
,
GCR_ENINT
);
/* enable interrupts */
return
0
;
}
static
int
atmel_close
(
struct
net_device
*
dev
)
static
int
atmel_close
(
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
atmel_enter_state
(
priv
,
STATION_STATE_DOWN
);
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
dev
,
GCR
,
0x0060
);
atmel_write16
(
dev
,
GCR
,
0x0040
);
return
0
;
...
...
@@ -1438,43 +1437,46 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
int
i
;
char
*
p
=
buf
;
char
*
s
,
*
r
,
*
c
;
p
+=
sprintf
(
p
,
"Driver version:
\t\t
%d.%d
\n
"
,
DRIVER_MAJOR
,
DRIVER_MINOR
);
p
+=
sprintf
(
p
,
"Driver version:
\t\t
%d.%d
\n
"
,
DRIVER_MAJOR
,
DRIVER_MINOR
);
if
(
priv
->
station_state
!=
STATION_STATE_DOWN
)
{
p
+=
sprintf
(
p
,
"Firmware version:
\t
%d.%d build %d
\n
Firmware location:
\t
"
,
p
+=
sprintf
(
p
,
"Firmware version:
\t
%d.%d build %d
\n
"
"Firmware location:
\t
"
,
priv
->
host_info
.
major_version
,
priv
->
host_info
.
minor_version
,
priv
->
host_info
.
build_version
);
if
(
priv
->
card_type
!=
CARD_TYPE_EEPROM
)
if
(
priv
->
card_type
!=
CARD_TYPE_EEPROM
)
p
+=
sprintf
(
p
,
"on card
\n
"
);
else
if
(
priv
->
firmware
)
p
+=
sprintf
(
p
,
"%s loaded by host
\n
"
,
priv
->
firmware_id
);
else
if
(
priv
->
firmware
)
p
+=
sprintf
(
p
,
"%s loaded by host
\n
"
,
priv
->
firmware_id
);
else
p
+=
sprintf
(
p
,
"%s loaded by hotplug
\n
"
,
priv
->
firmware_id
);
switch
(
priv
->
card_type
)
{
p
+=
sprintf
(
p
,
"%s loaded by hotplug
\n
"
,
priv
->
firmware_id
);
switch
(
priv
->
card_type
)
{
case
CARD_TYPE_PARALLEL_FLASH
:
c
=
"Parallel flash"
;
break
;
case
CARD_TYPE_SPI_FLASH
:
c
=
"SPI flash
\n
"
;
break
;
case
CARD_TYPE_EEPROM
:
c
=
"EEPROM"
;
break
;
default:
c
=
"<unknown>"
;
}
r
=
"<unknown>"
;
for
(
i
=
0
;
i
<
sizeof
(
channel_table
)
/
sizeof
(
channel_table
[
0
]);
i
++
)
if
(
priv
->
reg_domain
==
channel_table
[
i
].
reg_domain
)
r
=
channel_table
[
i
].
name
;
p
+=
sprintf
(
p
,
"MAC memory type:
\t
%s
\n
"
,
c
);
p
+=
sprintf
(
p
,
"Regulatory domain:
\t
%s
\n
"
,
r
);
p
+=
sprintf
(
p
,
"Host CRC checking:
\t
%s
\n
"
,
p
+=
sprintf
(
p
,
"Host CRC checking:
\t
%s
\n
"
,
priv
->
do_rx_crc
?
"On"
:
"Off"
);
p
+=
sprintf
(
p
,
"WPA-capable firmware:
\t
%s
\n
"
,
priv
->
use_wpa
?
"Yes"
:
"No"
);
}
switch
(
priv
->
station_state
)
{
case
STATION_STATE_SCANNING
:
s
=
"Scanning"
;
break
;
case
STATION_STATE_JOINNING
:
s
=
"Joining"
;
break
;
...
...
@@ -1486,9 +1488,9 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
case
STATION_STATE_DOWN
:
s
=
"Down"
;
break
;
default:
s
=
"<unknown>"
;
}
p
+=
sprintf
(
p
,
"Current state:
\t\t
%s
\n
"
,
s
);
return
p
-
buf
;
return
p
-
buf
;
}
static
int
atmel_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
...
...
@@ -1504,9 +1506,12 @@ static int atmel_read_proc(char *page, char **start, off_t off,
return
len
;
}
struct
net_device
*
init_atmel_card
(
unsigned
short
irq
,
unsigned
long
port
,
const
AtmelFWType
fw_type
,
struct
device
*
sys_dev
,
int
(
*
card_present
)(
void
*
),
void
*
card
)
struct
net_device
*
init_atmel_card
(
unsigned
short
irq
,
unsigned
long
port
,
const
AtmelFWType
fw_type
,
struct
device
*
sys_dev
,
int
(
*
card_present
)(
void
*
),
void
*
card
)
{
struct
proc_dir_entry
*
ent
;
struct
net_device
*
dev
;
struct
atmel_private
*
priv
;
int
rc
;
...
...
@@ -1514,11 +1519,11 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
/* Create the network device object. */
dev
=
alloc_etherdev
(
sizeof
(
*
priv
));
if
(
!
dev
)
{
printk
(
KERN_ERR
"atmel:
Couldn't alloc_etherdev
\n
"
);
printk
(
KERN_ERR
"atmel: Couldn't alloc_etherdev
\n
"
);
return
NULL
;
}
if
(
dev_alloc_name
(
dev
,
dev
->
name
)
<
0
)
{
printk
(
KERN_ERR
"atmel:
Couldn't get name!
\n
"
);
printk
(
KERN_ERR
"atmel: Couldn't get name!
\n
"
);
goto
err_out_free
;
}
...
...
@@ -1550,7 +1555,7 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
memset
(
priv
->
BSSID
,
0
,
6
);
priv
->
CurrentBSSID
[
0
]
=
0xFF
;
/* Initialize to something invalid.... */
priv
->
station_was_associated
=
0
;
priv
->
last_survey
=
jiffies
;
priv
->
preamble
=
LONG_PREAMBLE
;
priv
->
operating_mode
=
IW_MODE_INFRA
;
...
...
@@ -1586,7 +1591,7 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
spin_lock_init
(
&
priv
->
timerlock
);
priv
->
management_timer
.
function
=
atmel_management_timer
;
priv
->
management_timer
.
data
=
(
unsigned
long
)
dev
;
dev
->
open
=
atmel_open
;
dev
->
stop
=
atmel_close
;
dev
->
change_mtu
=
atmel_change_mtu
;
...
...
@@ -1597,44 +1602,46 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
dev
->
do_ioctl
=
atmel_ioctl
;
dev
->
irq
=
irq
;
dev
->
base_addr
=
port
;
SET_NETDEV_DEV
(
dev
,
sys_dev
);
if
((
rc
=
request_irq
(
dev
->
irq
,
service_interrupt
,
SA_SHIRQ
,
dev
->
name
,
dev
)))
{
printk
(
KERN_ERR
"%s: register interrupt %d failed, rc %d
\n
"
,
dev
->
name
,
irq
,
rc
);
printk
(
KERN_ERR
"%s: register interrupt %d failed, rc %d
\n
"
,
dev
->
name
,
irq
,
rc
);
goto
err_out_free
;
}
if
(
!
request_region
(
dev
->
base_addr
,
32
,
if
(
!
request_region
(
dev
->
base_addr
,
32
,
priv
->
bus_type
==
BUS_TYPE_PCCARD
?
"atmel_cs"
:
"atmel_pci"
))
{
goto
err_out_irq
;
}
if
(
register_netdev
(
dev
))
goto
err_out_res
;
if
(
!
probe_atmel_card
(
dev
)){
unregister_netdev
(
dev
);
goto
err_out_res
;
}
netif_carrier_off
(
dev
);
create_proc_read_entry
(
"driver/atmel"
,
0
,
NULL
,
atmel_read_proc
,
priv
);
ent
=
create_proc_read_entry
(
"driver/atmel"
,
0
,
NULL
,
atmel_read_proc
,
priv
);
if
(
!
ent
)
printk
(
KERN_WARNING
"atmel: unable to create /proc entry.
\n
"
);
printk
(
KERN_INFO
"%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x
\n
"
,
dev
->
name
,
DRIVER_MAJOR
,
DRIVER_MINOR
,
dev
->
dev_addr
[
0
],
dev
->
dev_addr
[
1
],
dev
->
dev_addr
[
2
],
dev
->
dev_addr
[
3
],
dev
->
dev_addr
[
4
],
dev
->
dev_addr
[
5
]
);
SET_MODULE_OWNER
(
dev
);
return
dev
;
err_out_res:
err_out_res:
release_region
(
dev
->
base_addr
,
32
);
err_out_irq:
err_out_irq:
free_irq
(
dev
->
irq
,
dev
);
err_out_free:
err_out_free:
free_netdev
(
dev
);
return
NULL
;
}
...
...
@@ -1644,12 +1651,12 @@ EXPORT_SYMBOL(init_atmel_card);
void
stop_atmel_card
(
struct
net_device
*
dev
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
/* put a brick on it... */
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
dev
,
GCR
,
0x0060
);
atmel_write16
(
dev
,
GCR
,
0x0040
);
del_timer_sync
(
&
priv
->
management_timer
);
unregister_netdev
(
dev
);
remove_proc_entry
(
"driver/atmel"
,
NULL
);
...
...
@@ -1675,13 +1682,13 @@ static int atmel_set_essid(struct net_device *dev,
int
index
=
(
dwrq
->
flags
&
IW_ENCODE_INDEX
)
-
1
;
priv
->
connect_to_any_BSS
=
0
;
/* Check the size of the string */
if
(
dwrq
->
length
>
MAX_SSID_LENGTH
+
1
)
return
-
E2BIG
;
return
-
E2BIG
;
if
(
index
!=
0
)
return
-
EINVAL
;
memcpy
(
priv
->
new_SSID
,
extra
,
dwrq
->
length
-
1
);
priv
->
new_SSID_size
=
dwrq
->
length
-
1
;
}
...
...
@@ -1706,7 +1713,7 @@ static int atmel_get_essid(struct net_device *dev,
extra
[
priv
->
SSID_size
]
=
'\0'
;
dwrq
->
length
=
priv
->
SSID_size
+
1
;
}
dwrq
->
flags
=
!
priv
->
connect_to_any_BSS
;
/* active */
return
0
;
...
...
@@ -1768,7 +1775,7 @@ static int atmel_set_encode(struct net_device *dev,
/* WE specify that if a valid key is set, encryption
* should be enabled (user may turn it off later)
* This is also how "iwconfig ethX key on" works */
if
(
index
==
current_index
&&
if
(
index
==
current_index
&&
priv
->
wep_key_len
[
index
]
>
0
)
{
priv
->
wep_is_on
=
1
;
priv
->
exclude_unencrypted
=
1
;
...
...
@@ -1783,18 +1790,18 @@ static int atmel_set_encode(struct net_device *dev,
}
else
{
/* Do we want to just set the transmit key index ? */
int
index
=
(
dwrq
->
flags
&
IW_ENCODE_INDEX
)
-
1
;
if
(
index
>=
0
&&
index
<
4
)
{
if
(
index
>=
0
&&
index
<
4
)
{
priv
->
default_key
=
index
;
}
else
/* Don't complain if only change the mode */
if
(
!
dwrq
->
flags
&
IW_ENCODE_MODE
)
{
if
(
!
dwrq
->
flags
&
IW_ENCODE_MODE
)
{
return
-
EINVAL
;
}
}
/* Read the flags */
if
(
dwrq
->
flags
&
IW_ENCODE_DISABLED
)
{
if
(
dwrq
->
flags
&
IW_ENCODE_DISABLED
)
{
priv
->
wep_is_on
=
0
;
priv
->
encryption_level
=
0
;
priv
->
encryption_level
=
0
;
priv
->
pairwise_cipher_suite
=
CIPHER_SUITE_NONE
;
}
else
{
priv
->
wep_is_on
=
1
;
...
...
@@ -1806,15 +1813,14 @@ static int atmel_set_encode(struct net_device *dev,
priv
->
encryption_level
=
1
;
}
}
if
(
dwrq
->
flags
&
IW_ENCODE_RESTRICTED
)
if
(
dwrq
->
flags
&
IW_ENCODE_RESTRICTED
)
priv
->
exclude_unencrypted
=
1
;
if
(
dwrq
->
flags
&
IW_ENCODE_OPEN
)
if
(
dwrq
->
flags
&
IW_ENCODE_OPEN
)
priv
->
exclude_unencrypted
=
0
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
atmel_get_encode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
dwrq
,
...
...
@@ -1822,7 +1828,7 @@ static int atmel_get_encode(struct net_device *dev,
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
int
index
=
(
dwrq
->
flags
&
IW_ENCODE_INDEX
)
-
1
;
if
(
!
priv
->
wep_is_on
)
dwrq
->
flags
=
IW_ENCODE_DISABLED
;
else
{
...
...
@@ -1843,7 +1849,7 @@ static int atmel_get_encode(struct net_device *dev,
memset
(
extra
,
0
,
16
);
memcpy
(
extra
,
priv
->
wep_keys
[
index
],
dwrq
->
length
);
}
return
0
;
}
...
...
@@ -1862,17 +1868,17 @@ static int atmel_set_rate(struct net_device *dev,
char
*
extra
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
if
(
vwrq
->
fixed
==
0
)
{
priv
->
tx_rate
=
3
;
priv
->
auto_tx_rate
=
1
;
}
else
{
priv
->
auto_tx_rate
=
0
;
/* Which type of value ? */
if
((
vwrq
->
value
<
4
)
&&
(
vwrq
->
value
>=
0
))
{
if
((
vwrq
->
value
<
4
)
&&
(
vwrq
->
value
>=
0
))
{
/* Setting by rate index */
priv
->
tx_rate
=
vwrq
->
value
;
priv
->
tx_rate
=
vwrq
->
value
;
}
else
{
/* Setting by frequency value */
switch
(
vwrq
->
value
)
{
...
...
@@ -1899,7 +1905,7 @@ static int atmel_set_mode(struct net_device *dev,
return
-
EINVAL
;
priv
->
operating_mode
=
*
uwrq
;
return
-
EINPROGRESS
;
return
-
EINPROGRESS
;
}
static
int
atmel_get_mode
(
struct
net_device
*
dev
,
...
...
@@ -1908,7 +1914,7 @@ static int atmel_get_mode(struct net_device *dev,
char
*
extra
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
*
uwrq
=
priv
->
operating_mode
;
return
0
;
}
...
...
@@ -1962,9 +1968,9 @@ static int atmel_set_retry(struct net_device *dev,
char
*
extra
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
if
(
!
vwrq
->
disabled
&&
(
vwrq
->
flags
&
IW_RETRY_LIMIT
))
{
if
(
vwrq
->
flags
&
IW_RETRY_MAX
)
if
(
!
vwrq
->
disabled
&&
(
vwrq
->
flags
&
IW_RETRY_LIMIT
))
{
if
(
vwrq
->
flags
&
IW_RETRY_MAX
)
priv
->
long_retry
=
vwrq
->
value
;
else
if
(
vwrq
->
flags
&
IW_RETRY_MIN
)
priv
->
short_retry
=
vwrq
->
value
;
...
...
@@ -1973,9 +1979,9 @@ static int atmel_set_retry(struct net_device *dev,
priv
->
long_retry
=
vwrq
->
value
;
priv
->
short_retry
=
vwrq
->
value
;
}
return
-
EINPROGRESS
;
return
-
EINPROGRESS
;
}
return
-
EINVAL
;
}
...
...
@@ -1989,13 +1995,13 @@ static int atmel_get_retry(struct net_device *dev,
vwrq
->
disabled
=
0
;
/* Can't be disabled */
/* Note : by default, display the min retry number */
if
((
vwrq
->
flags
&
IW_RETRY_MAX
)
)
{
if
(
vwrq
->
flags
&
IW_RETRY_MAX
)
{
vwrq
->
flags
=
IW_RETRY_LIMIT
|
IW_RETRY_MAX
;
vwrq
->
value
=
priv
->
long_retry
;
}
else
{
vwrq
->
flags
=
IW_RETRY_LIMIT
;
vwrq
->
value
=
priv
->
short_retry
;
if
(
priv
->
long_retry
!=
priv
->
short_retry
)
if
(
priv
->
long_retry
!=
priv
->
short_retry
)
vwrq
->
flags
|=
IW_RETRY_MIN
;
}
...
...
@@ -2010,13 +2016,13 @@ static int atmel_set_rts(struct net_device *dev,
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
int
rthr
=
vwrq
->
value
;
if
(
vwrq
->
disabled
)
if
(
vwrq
->
disabled
)
rthr
=
2347
;
if
((
rthr
<
0
)
||
(
rthr
>
2347
))
{
if
((
rthr
<
0
)
||
(
rthr
>
2347
))
{
return
-
EINVAL
;
}
priv
->
rts_threshold
=
rthr
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
...
...
@@ -2026,7 +2032,7 @@ static int atmel_get_rts(struct net_device *dev,
char
*
extra
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
vwrq
->
value
=
priv
->
rts_threshold
;
vwrq
->
disabled
=
(
vwrq
->
value
>=
2347
);
vwrq
->
fixed
=
1
;
...
...
@@ -2042,14 +2048,14 @@ static int atmel_set_frag(struct net_device *dev,
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
int
fthr
=
vwrq
->
value
;
if
(
vwrq
->
disabled
)
if
(
vwrq
->
disabled
)
fthr
=
2346
;
if
((
fthr
<
256
)
||
(
fthr
>
2346
))
{
if
((
fthr
<
256
)
||
(
fthr
>
2346
))
{
return
-
EINVAL
;
}
fthr
&=
~
0x1
;
/* Get an even value - is it really needed ??? */
priv
->
frag_threshold
=
fthr
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
...
...
@@ -2077,21 +2083,21 @@ static int atmel_set_freq(struct net_device *dev,
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
int
rc
=
-
EINPROGRESS
;
/* Call commit handler */
/* If setting by frequency, convert to a channel */
if
((
fwrq
->
e
==
1
)
&&
(
fwrq
->
m
>=
(
int
)
241200000
)
&&
(
fwrq
->
m
<=
(
int
)
248700000
))
{
if
((
fwrq
->
e
==
1
)
&&
(
fwrq
->
m
>=
(
int
)
241200000
)
&&
(
fwrq
->
m
<=
(
int
)
248700000
))
{
int
f
=
fwrq
->
m
/
100000
;
int
c
=
0
;
while
((
c
<
14
)
&&
(
f
!=
frequency_list
[
c
]))
while
((
c
<
14
)
&&
(
f
!=
frequency_list
[
c
]))
c
++
;
/* Hack to fall through... */
fwrq
->
e
=
0
;
fwrq
->
m
=
c
+
1
;
}
/* Setting by channel number */
if
((
fwrq
->
m
>
1000
)
||
(
fwrq
->
e
>
0
))
if
((
fwrq
->
m
>
1000
)
||
(
fwrq
->
e
>
0
))
rc
=
-
EOPNOTSUPP
;
else
{
int
channel
=
fwrq
->
m
;
...
...
@@ -2099,7 +2105,7 @@ static int atmel_set_freq(struct net_device *dev,
priv
->
channel
=
channel
;
}
else
{
rc
=
-
EINVAL
;
}
}
}
return
rc
;
}
...
...
@@ -2130,7 +2136,7 @@ static int atmel_set_scan(struct net_device *dev,
* This is not an error, while the device perform scanning,
* traffic doesn't flow, so it's a perfect DoS...
* Jean II */
if
(
priv
->
station_state
==
STATION_STATE_DOWN
)
return
-
EAGAIN
;
...
...
@@ -2142,15 +2148,15 @@ static int atmel_set_scan(struct net_device *dev,
/* Initiate a scan command */
if
(
priv
->
site_survey_state
==
SITE_SURVEY_IN_PROGRESS
)
return
-
EBUSY
;
del_timer_sync
(
&
priv
->
management_timer
);
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
priv
->
site_survey_state
=
SITE_SURVEY_IN_PROGRESS
;
priv
->
fast_scan
=
0
;
atmel_scan
(
priv
,
0
);
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
return
0
;
}
...
...
@@ -2163,11 +2169,11 @@ static int atmel_get_scan(struct net_device *dev,
int
i
;
char
*
current_ev
=
extra
;
struct
iw_event
iwe
;
if
(
priv
->
site_survey_state
!=
SITE_SURVEY_COMPLETED
)
return
-
EAGAIN
;
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
iwe
.
cmd
=
SIOCGIWAP
;
iwe
.
u
.
ap_addr
.
sa_family
=
ARPHRD_ETHER
;
memcpy
(
iwe
.
u
.
ap_addr
.
sa_data
,
priv
->
BSSinfo
[
i
].
BSSID
,
6
);
...
...
@@ -2179,16 +2185,16 @@ static int atmel_get_scan(struct net_device *dev,
iwe
.
cmd
=
SIOCGIWESSID
;
iwe
.
u
.
data
.
flags
=
1
;
current_ev
=
iwe_stream_add_point
(
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
&
iwe
,
priv
->
BSSinfo
[
i
].
SSID
);
iwe
.
cmd
=
SIOCGIWMODE
;
iwe
.
u
.
mode
=
priv
->
BSSinfo
[
i
].
BSStype
;
current_ev
=
iwe_stream_add_event
(
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
&
iwe
,
IW_EV_UINT_LEN
);
iwe
.
cmd
=
SIOCGIWFREQ
;
iwe
.
u
.
freq
.
m
=
priv
->
BSSinfo
[
i
].
channel
;
iwe
.
u
.
freq
.
e
=
0
;
current_ev
=
iwe_stream_add_event
(
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
&
iwe
,
IW_EV_FREQ_LEN
);
iwe
.
cmd
=
SIOCGIWENCODE
;
if
(
priv
->
BSSinfo
[
i
].
UsingWEP
)
iwe
.
u
.
data
.
flags
=
IW_ENCODE_ENABLED
|
IW_ENCODE_NOKEY
;
...
...
@@ -2196,13 +2202,12 @@ static int atmel_get_scan(struct net_device *dev,
iwe
.
u
.
data
.
flags
=
IW_ENCODE_DISABLED
;
iwe
.
u
.
data
.
length
=
0
;
current_ev
=
iwe_stream_add_point
(
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
&
iwe
,
NULL
);
}
/* Length of data */
dwrq
->
length
=
(
current_ev
-
extra
);
dwrq
->
flags
=
0
;
dwrq
->
flags
=
0
;
return
0
;
}
...
...
@@ -2213,7 +2218,7 @@ static int atmel_get_range(struct net_device *dev,
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
struct
iw_range
*
range
=
(
struct
iw_range
*
)
extra
;
int
k
,
i
,
j
;
int
k
,
i
,
j
;
dwrq
->
length
=
sizeof
(
struct
iw_range
);
memset
(
range
,
0
,
sizeof
(
struct
iw_range
));
...
...
@@ -2226,14 +2231,14 @@ static int atmel_get_range(struct net_device *dev,
break
;
}
if
(
range
->
num_channels
!=
0
)
{
for
(
k
=
0
,
i
=
channel_table
[
j
].
min
;
i
<=
channel_table
[
j
].
max
;
i
++
)
{
for
(
k
=
0
,
i
=
channel_table
[
j
].
min
;
i
<=
channel_table
[
j
].
max
;
i
++
)
{
range
->
freq
[
k
].
i
=
i
;
/* List index */
range
->
freq
[
k
].
m
=
frequency_list
[
i
-
1
]
*
100000
;
range
->
freq
[
k
].
m
=
frequency_list
[
i
-
1
]
*
100000
;
range
->
freq
[
k
++
].
e
=
1
;
/* Values in table in MHz -> * 10^5 * 10 */
}
range
->
num_frequency
=
k
;
}
range
->
max_qual
.
qual
=
100
;
range
->
max_qual
.
level
=
100
;
range
->
max_qual
.
noise
=
0
;
...
...
@@ -2261,11 +2266,11 @@ static int atmel_get_range(struct net_device *dev,
range
->
encoding_size
[
1
]
=
13
;
range
->
num_encoding_sizes
=
2
;
range
->
max_encoding_tokens
=
4
;
range
->
pmp_flags
=
IW_POWER_ON
;
range
->
pmt_flags
=
IW_POWER_ON
;
range
->
pm_capa
=
0
;
range
->
we_version_source
=
WIRELESS_EXT
;
range
->
we_version_compiled
=
WIRELESS_EXT
;
range
->
retry_capa
=
IW_RETRY_LIMIT
;
...
...
@@ -2289,7 +2294,7 @@ static int atmel_set_wap(struct net_device *dev,
if
(
awrq
->
sa_family
!=
ARPHRD_ETHER
)
return
-
EINVAL
;
if
(
memcmp
(
bcast
,
awrq
->
sa_data
,
6
)
==
0
)
{
del_timer_sync
(
&
priv
->
management_timer
);
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
...
...
@@ -2297,8 +2302,8 @@ static int atmel_set_wap(struct net_device *dev,
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
return
0
;
}
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
if
(
memcmp
(
priv
->
BSSinfo
[
i
].
BSSID
,
awrq
->
sa_data
,
6
)
==
0
)
{
if
(
!
priv
->
wep_is_on
&&
priv
->
BSSinfo
[
i
].
UsingWEP
)
{
return
-
EINVAL
;
...
...
@@ -2313,10 +2318,10 @@ static int atmel_set_wap(struct net_device *dev,
}
}
}
return
-
EINVAL
;
}
static
int
atmel_config_commit
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
/* NULL */
void
*
zwrq
,
/* NULL */
...
...
@@ -2325,18 +2330,18 @@ static int atmel_config_commit(struct net_device *dev,
return
atmel_open
(
dev
);
}
static
const
iw_handler
atmel_handler
[]
=
static
const
iw_handler
atmel_handler
[]
=
{
(
iw_handler
)
atmel_config_commit
,
/* SIOCSIWCOMMIT */
(
iw_handler
)
atmel_get_name
,
/* SIOCGIWNAME */
(
iw_handler
)
atmel_get_name
,
/* SIOCGIWNAME */
(
iw_handler
)
NULL
,
/* SIOCSIWNWID */
(
iw_handler
)
NULL
,
/* SIOCGIWNWID */
(
iw_handler
)
atmel_set_freq
,
/* SIOCSIWFREQ */
(
iw_handler
)
atmel_get_freq
,
/* SIOCGIWFREQ */
(
iw_handler
)
atmel_set_mode
,
/* SIOCSIWMODE */
(
iw_handler
)
atmel_get_mode
,
/* SIOCGIWMODE */
(
iw_handler
)
NULL
,
/* SIOCSIWSENS */
(
iw_handler
)
NULL
,
/* SIOCGIWSENS */
(
iw_handler
)
NULL
,
/* SIOCSIWSENS */
(
iw_handler
)
NULL
,
/* SIOCGIWSENS */
(
iw_handler
)
NULL
,
/* SIOCSIWRANGE */
(
iw_handler
)
atmel_get_range
,
/* SIOCGIWRANGE */
(
iw_handler
)
NULL
,
/* SIOCSIWPRIV */
...
...
@@ -2350,13 +2355,13 @@ static const iw_handler atmel_handler[] =
(
iw_handler
)
atmel_set_wap
,
/* SIOCSIWAP */
(
iw_handler
)
atmel_get_wap
,
/* SIOCGIWAP */
(
iw_handler
)
NULL
,
/* -- hole -- */
(
iw_handler
)
NULL
,
/* SIOCGIWAPLIST */
(
iw_handler
)
NULL
,
/* SIOCGIWAPLIST */
(
iw_handler
)
atmel_set_scan
,
/* SIOCSIWSCAN */
(
iw_handler
)
atmel_get_scan
,
/* SIOCGIWSCAN */
(
iw_handler
)
atmel_set_essid
,
/* SIOCSIWESSID */
(
iw_handler
)
atmel_get_essid
,
/* SIOCGIWESSID */
(
iw_handler
)
NULL
,
/* SIOCSIWNICKN */
(
iw_handler
)
NULL
,
/* SIOCGIWNICKN */
(
iw_handler
)
NULL
,
/* SIOCSIWNICKN */
(
iw_handler
)
NULL
,
/* SIOCGIWNICKN */
(
iw_handler
)
NULL
,
/* -- hole -- */
(
iw_handler
)
NULL
,
/* -- hole -- */
(
iw_handler
)
atmel_set_rate
,
/* SIOCSIWRATE */
...
...
@@ -2365,8 +2370,8 @@ static const iw_handler atmel_handler[] =
(
iw_handler
)
atmel_get_rts
,
/* SIOCGIWRTS */
(
iw_handler
)
atmel_set_frag
,
/* SIOCSIWFRAG */
(
iw_handler
)
atmel_get_frag
,
/* SIOCGIWFRAG */
(
iw_handler
)
NULL
,
/* SIOCSIWTXPOW */
(
iw_handler
)
NULL
,
/* SIOCGIWTXPOW */
(
iw_handler
)
NULL
,
/* SIOCSIWTXPOW */
(
iw_handler
)
NULL
,
/* SIOCGIWTXPOW */
(
iw_handler
)
atmel_set_retry
,
/* SIOCSIWRETRY */
(
iw_handler
)
atmel_get_retry
,
/* SIOCGIWRETRY */
(
iw_handler
)
atmel_set_encode
,
/* SIOCSIWENCODE */
...
...
@@ -2375,39 +2380,51 @@ static const iw_handler atmel_handler[] =
(
iw_handler
)
atmel_get_power
,
/* SIOCGIWPOWER */
};
static
const
iw_handler
atmel_private_handler
[]
=
static
const
iw_handler
atmel_private_handler
[]
=
{
NULL
,
/* SIOCIWFIRSTPRIV */
};
typedef
struct
atmel_priv_ioctl
{
char
id
[
32
];
unsigned
char
__user
*
data
;
unsigned
short
len
;
unsigned
char
__user
*
data
;
unsigned
short
len
;
}
atmel_priv_ioctl
;
#define ATMELFWL SIOCIWFIRSTPRIV
#define ATMELIDIFC ATMELFWL + 1
#define ATMELRD ATMELFWL + 2
#define ATMELMAGIC 0x51807
#define ATMELFWL SIOCIWFIRSTPRIV
#define ATMELIDIFC ATMELFWL + 1
#define ATMELRD ATMELFWL + 2
#define ATMELMAGIC 0x51807
#define REGDOMAINSZ 20
static
const
struct
iw_priv_args
atmel_private_args
[]
=
{
/*{ cmd, set_args, get_args, name } */
{
ATMELFWL
,
IW_PRIV_TYPE_BYTE
|
IW_PRIV_SIZE_FIXED
|
sizeof
(
atmel_priv_ioctl
),
IW_PRIV_TYPE_NONE
,
"atmelfwl"
},
{
ATMELIDIFC
,
IW_PRIV_TYPE_NONE
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"atmelidifc"
},
{
ATMELRD
,
IW_PRIV_TYPE_CHAR
|
REGDOMAINSZ
,
IW_PRIV_TYPE_NONE
,
"regdomain"
},
{
.
cmd
=
ATMELFWL
,
.
set_args
=
IW_PRIV_TYPE_BYTE
|
IW_PRIV_SIZE_FIXED
|
sizeof
(
atmel_priv_ioctl
),
.
get_args
=
IW_PRIV_TYPE_NONE
,
.
name
=
"atmelfwl"
},
{
.
cmd
=
ATMELIDIFC
,
.
set_args
=
IW_PRIV_TYPE_NONE
,
.
get_args
=
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
.
name
=
"atmelidifc"
},
{
.
cmd
=
ATMELRD
,
.
set_args
=
IW_PRIV_TYPE_CHAR
|
REGDOMAINSZ
,
.
get_args
=
IW_PRIV_TYPE_NONE
,
.
name
=
"regdomain"
},
};
static
const
struct
iw_handler_def
atmel_handler_def
=
static
const
struct
iw_handler_def
atmel_handler_def
=
{
.
num_standard
=
sizeof
(
atmel_handler
)
/
sizeof
(
iw_handler
),
.
num_private
=
sizeof
(
atmel_private_handler
)
/
sizeof
(
iw_handler
),
.
num_private_args
=
sizeof
(
atmel_private_args
)
/
sizeof
(
struct
iw_priv_args
),
.
num_private
=
sizeof
(
atmel_private_handler
)
/
sizeof
(
iw_handler
),
.
num_private_args
=
sizeof
(
atmel_private_args
)
/
sizeof
(
struct
iw_priv_args
),
.
standard
=
(
iw_handler
*
)
atmel_handler
,
.
private
=
(
iw_handler
*
)
atmel_private_handler
,
.
private
=
(
iw_handler
*
)
atmel_private_handler
,
.
private_args
=
(
struct
iw_priv_args
*
)
atmel_private_args
,
.
get_wireless_stats
=
atmel_get_wireless_stats
};
...
...
@@ -2419,13 +2436,13 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
atmel_priv_ioctl
com
;
struct
iwreq
*
wrq
=
(
struct
iwreq
*
)
rq
;
unsigned
char
*
new_firmware
;
char
domain
[
REGDOMAINSZ
+
1
];
char
domain
[
REGDOMAINSZ
+
1
];
switch
(
cmd
)
{
case
ATMELIDIFC
:
wrq
->
u
.
param
.
value
=
ATMELMAGIC
;
wrq
->
u
.
param
.
value
=
ATMELMAGIC
;
break
;
case
ATMELFWL
:
if
(
copy_from_user
(
&
com
,
rq
->
ifr_data
,
sizeof
(
com
)))
{
rc
=
-
EFAULT
;
...
...
@@ -2449,7 +2466,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
kfree
(
priv
->
firmware
);
priv
->
firmware
=
new_firmware
;
priv
->
firmware_length
=
com
.
len
;
strncpy
(
priv
->
firmware_id
,
com
.
id
,
31
);
...
...
@@ -2461,7 +2478,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
rc
=
-
EFAULT
;
break
;
}
if
(
!
capable
(
CAP_NET_ADMIN
))
{
rc
=
-
EPERM
;
break
;
...
...
@@ -2484,15 +2501,15 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
rc
=
0
;
}
}
if
(
rc
==
0
&&
priv
->
station_state
!=
STATION_STATE_DOWN
)
rc
=
atmel_open
(
dev
);
break
;
default:
rc
=
-
EOPNOTSUPP
;
}
return
rc
;
}
...
...
@@ -2503,17 +2520,17 @@ struct auth_body {
u8
el_id
;
u8
chall_text_len
;
u8
chall_text
[
253
];
};
};
static
void
atmel_enter_state
(
struct
atmel_private
*
priv
,
int
new_state
)
{
int
old_state
=
priv
->
station_state
;
if
(
new_state
==
old_state
)
return
;
priv
->
station_state
=
new_state
;
if
(
new_state
==
STATION_STATE_READY
)
{
netif_start_queue
(
priv
->
dev
);
netif_carrier_on
(
priv
->
dev
);
...
...
@@ -2540,7 +2557,7 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid)
u8
options
;
u8
SSID_size
;
}
cmd
;
memset
(
cmd
.
BSSID
,
0xff
,
6
);
if
(
priv
->
fast_scan
)
{
...
...
@@ -2554,17 +2571,17 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid)
cmd
.
min_channel_time
=
cpu_to_le16
(
10
);
cmd
.
max_channel_time
=
cpu_to_le16
(
120
);
}
cmd
.
options
=
0
;
if
(
!
specific_ssid
)
cmd
.
options
|=
SCAN_OPTIONS_SITE_SURVEY
;
cmd
.
channel
=
(
priv
->
channel
&
0x7f
);
cmd
.
channel
=
(
priv
->
channel
&
0x7f
);
cmd
.
scan_type
=
SCAN_TYPE_ACTIVE
;
cmd
.
BSS_type
=
cpu_to_le16
(
priv
->
operating_mode
==
IW_MODE_ADHOC
?
cmd
.
BSS_type
=
cpu_to_le16
(
priv
->
operating_mode
==
IW_MODE_ADHOC
?
BSS_TYPE_AD_HOC
:
BSS_TYPE_INFRASTRUCTURE
);
atmel_send_command
(
priv
,
CMD_Scan
,
&
cmd
,
sizeof
(
cmd
));
/* This must come after all hardware access to avoid being messed up
...
...
@@ -2591,16 +2608,15 @@ static void join(struct atmel_private *priv, int type)
cmd
.
BSS_type
=
type
;
cmd
.
timeout
=
cpu_to_le16
(
2000
);
atmel_send_command
(
priv
,
CMD_Join
,
&
cmd
,
sizeof
(
cmd
));
atmel_send_command
(
priv
,
CMD_Join
,
&
cmd
,
sizeof
(
cmd
));
}
static
void
start
(
struct
atmel_private
*
priv
,
int
type
)
{
struct
{
u8
BSSID
[
6
];
u8
SSID
[
MAX_SSID_LENGTH
];
u8
BSS_type
;
u8
BSS_type
;
u8
channel
;
u8
SSID_size
;
u8
reserved
[
3
];
...
...
@@ -2612,13 +2628,14 @@ static void start(struct atmel_private *priv, int type)
cmd
.
BSS_type
=
type
;
cmd
.
channel
=
(
priv
->
channel
&
0x7f
);
atmel_send_command
(
priv
,
CMD_Start
,
&
cmd
,
sizeof
(
cmd
));
atmel_send_command
(
priv
,
CMD_Start
,
&
cmd
,
sizeof
(
cmd
));
}
static
void
handle_beacon_probe
(
struct
atmel_private
*
priv
,
u16
capability
,
u8
channel
)
static
void
handle_beacon_probe
(
struct
atmel_private
*
priv
,
u16
capability
,
u8
channel
)
{
int
rejoin
=
0
;
int
new
=
capability
&
C80211_MGMT_CAPABILITY_ShortPreamble
?
int
new
=
capability
&
C80211_MGMT_CAPABILITY_ShortPreamble
?
SHORT_PREAMBLE
:
LONG_PREAMBLE
;
if
(
priv
->
preamble
!=
new
)
{
...
...
@@ -2626,48 +2643,48 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
rejoin
=
1
;
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_PREAMBLE_TYPE
,
new
);
}
if
(
priv
->
channel
!=
channel
)
{
priv
->
channel
=
channel
;
rejoin
=
1
;
atmel_set_mib8
(
priv
,
Phy_Mib_Type
,
PHY_MIB_CHANNEL_POS
,
channel
);
}
if
(
rejoin
)
{
priv
->
station_is_associated
=
0
;
atmel_enter_state
(
priv
,
STATION_STATE_JOINNING
);
if
(
priv
->
operating_mode
==
IW_MODE_INFRA
)
join
(
priv
,
BSS_TYPE_INFRASTRUCTURE
);
else
else
join
(
priv
,
BSS_TYPE_AD_HOC
);
}
}
}
static
void
send_authentication_request
(
struct
atmel_private
*
priv
,
u16
system
,
u8
*
challenge
,
int
challenge_len
)
static
void
send_authentication_request
(
struct
atmel_private
*
priv
,
u16
system
,
u8
*
challenge
,
int
challenge_len
)
{
struct
ieee80211_hdr_4addr
header
;
struct
auth_body
auth
;
header
.
frame_ctl
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
IEEE80211_STYPE_AUTH
);
header
.
duration_id
=
cpu_to_le16
(
0x8000
);
header
.
frame_ctl
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
IEEE80211_STYPE_AUTH
);
header
.
duration_id
=
cpu_to_le16
(
0x8000
);
header
.
seq_ctl
=
0
;
memcpy
(
header
.
addr1
,
priv
->
CurrentBSSID
,
6
);
memcpy
(
header
.
addr2
,
priv
->
dev
->
dev_addr
,
6
);
memcpy
(
header
.
addr3
,
priv
->
CurrentBSSID
,
6
);
if
(
priv
->
wep_is_on
&&
priv
->
CurrentAuthentTransactionSeqNum
!=
1
)
if
(
priv
->
wep_is_on
&&
priv
->
CurrentAuthentTransactionSeqNum
!=
1
)
/* no WEP for authentication frames with TrSeqNo 1 */
header
.
frame_ctl
|=
cpu_to_le16
(
IEEE80211_FCTL_PROTECTED
);
auth
.
alg
=
cpu_to_le16
(
system
);
auth
.
alg
=
cpu_to_le16
(
system
);
auth
.
status
=
0
;
auth
.
trans_seq
=
cpu_to_le16
(
priv
->
CurrentAuthentTransactionSeqNum
);
priv
->
ExpectedAuthentTransactionSeqNum
=
priv
->
CurrentAuthentTransactionSeqNum
+
1
;
priv
->
ExpectedAuthentTransactionSeqNum
=
priv
->
CurrentAuthentTransactionSeqNum
+
1
;
priv
->
CurrentAuthentTransactionSeqNum
+=
2
;
if
(
challenge_len
!=
0
)
{
auth
.
el_id
=
16
;
/* challenge_text */
auth
.
chall_text_len
=
challenge_len
;
...
...
@@ -2685,7 +2702,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
struct
ieee80211_hdr_4addr
header
;
struct
ass_req_format
{
u16
capability
;
u16
listen_interval
;
u16
listen_interval
;
u8
ap
[
6
];
/* nothing after here directly accessible */
u8
ssid_el_id
;
u8
ssid_len
;
...
...
@@ -2694,15 +2711,15 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
u8
sup_rates_len
;
u8
rates
[
4
];
}
body
;
header
.
frame_ctl
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
header
.
frame_ctl
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
(
is_reassoc
?
IEEE80211_STYPE_REASSOC_REQ
:
IEEE80211_STYPE_ASSOC_REQ
));
header
.
duration_id
=
cpu_to_le16
(
0x8000
);
header
.
seq_ctl
=
0
;
memcpy
(
header
.
addr1
,
priv
->
CurrentBSSID
,
6
);
memcpy
(
header
.
addr1
,
priv
->
CurrentBSSID
,
6
);
memcpy
(
header
.
addr2
,
priv
->
dev
->
dev_addr
,
6
);
memcpy
(
header
.
addr3
,
priv
->
CurrentBSSID
,
6
);
memcpy
(
header
.
addr3
,
priv
->
CurrentBSSID
,
6
);
body
.
capability
=
cpu_to_le16
(
C80211_MGMT_CAPABILITY_ESS
);
if
(
priv
->
wep_is_on
)
...
...
@@ -2711,18 +2728,18 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
body
.
capability
|=
cpu_to_le16
(
C80211_MGMT_CAPABILITY_ShortPreamble
);
body
.
listen_interval
=
cpu_to_le16
(
priv
->
listen_interval
*
priv
->
beacon_period
);
/* current AP address - only in reassoc frame */
if
(
is_reassoc
)
{
memcpy
(
body
.
ap
,
priv
->
CurrentBSSID
,
6
);
memcpy
(
body
.
ap
,
priv
->
CurrentBSSID
,
6
);
ssid_el_p
=
(
u8
*
)
&
body
.
ssid_el_id
;
bodysize
=
18
+
priv
->
SSID_size
;
}
else
{
ssid_el_p
=
(
u8
*
)
&
body
.
ap
[
0
];
bodysize
=
12
+
priv
->
SSID_size
;
}
ssid_el_p
[
0
]
=
C80211_MGMT_ElementID_SSID
;
ssid_el_p
[
0
]
=
C80211_MGMT_ElementID_SSID
;
ssid_el_p
[
1
]
=
priv
->
SSID_size
;
memcpy
(
ssid_el_p
+
2
,
priv
->
SSID
,
priv
->
SSID_size
);
ssid_el_p
[
2
+
priv
->
SSID_size
]
=
C80211_MGMT_ElementID_SupportedRates
;
...
...
@@ -2732,7 +2749,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
atmel_transmit_management_frame
(
priv
,
&
header
,
(
void
*
)
&
body
,
bodysize
);
}
static
int
is_frame_from_current_bss
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
)
static
int
is_frame_from_current_bss
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
)
{
if
(
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_FROMDS
)
return
memcmp
(
header
->
addr3
,
priv
->
CurrentBSSID
,
6
)
==
0
;
...
...
@@ -2745,29 +2763,29 @@ static int retrieve_bss(struct atmel_private *priv)
int
i
;
int
max_rssi
=
-
128
;
int
max_index
=
-
1
;
if
(
priv
->
BSS_list_entries
==
0
)
return
-
1
;
if
(
priv
->
connect_to_any_BSS
)
{
/* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
and that it is not marked as 'bad' (i.e. we had previously failed to connect to
this BSS with the settings that we currently use) */
/* Select a BSS with the max-RSSI but of the same type and of
the same WEP mode and that it is not marked as 'bad' (i.e.
we had previously failed to connect to this BSS with the
settings that we currently use) */
priv
->
current_BSS
=
0
;
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
if
(
priv
->
operating_mode
==
priv
->
BSSinfo
[
i
].
BSStype
&&
((
!
priv
->
wep_is_on
&&
!
priv
->
BSSinfo
[
i
].
UsingWEP
)
||
((
!
priv
->
wep_is_on
&&
!
priv
->
BSSinfo
[
i
].
UsingWEP
)
||
(
priv
->
wep_is_on
&&
priv
->
BSSinfo
[
i
].
UsingWEP
))
&&
!
(
priv
->
BSSinfo
[
i
].
channel
&
0x80
))
{
max_rssi
=
priv
->
BSSinfo
[
i
].
RSSI
;
priv
->
current_BSS
=
max_index
=
i
;
}
}
return
max_index
;
}
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
{
if
(
priv
->
SSID_size
==
priv
->
BSSinfo
[
i
].
SSIDsize
&&
memcmp
(
priv
->
SSID
,
priv
->
BSSinfo
[
i
].
SSID
,
priv
->
SSID_size
)
==
0
&&
priv
->
operating_mode
==
priv
->
BSSinfo
[
i
].
BSStype
&&
...
...
@@ -2781,19 +2799,19 @@ static int retrieve_bss(struct atmel_private *priv)
return
max_index
;
}
static
void
store_bss_info
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
capability
,
u16
beacon_period
,
u8
channel
,
u8
rssi
,
u8
ssid_len
,
u8
*
ssid
,
int
is_beacon
)
static
void
store_bss_info
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
capability
,
u16
beacon_period
,
u8
channel
,
u8
rssi
,
u8
ssid_len
,
u8
*
ssid
,
int
is_beacon
)
{
u8
*
bss
=
capability
&
C80211_MGMT_CAPABILITY_ESS
?
header
->
addr2
:
header
->
addr3
;
int
i
,
index
;
for
(
index
=
-
1
,
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
if
(
memcmp
(
bss
,
priv
->
BSSinfo
[
i
].
BSSID
,
6
)
==
0
)
for
(
index
=
-
1
,
i
=
0
;
i
<
priv
->
BSS_list_entries
;
i
++
)
if
(
memcmp
(
bss
,
priv
->
BSSinfo
[
i
].
BSSID
,
6
)
==
0
)
index
=
i
;
/* If we process a probe and an entry from this BSS exists
/* If we process a probe and an entry from this BSS exists
we will update the BSS entry with the info from this BSS.
If we process a beacon we will only update RSSI */
...
...
@@ -2820,8 +2838,8 @@ static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4add
priv
->
BSSinfo
[
index
].
BSStype
=
IW_MODE_ADHOC
;
else
if
(
capability
&
C80211_MGMT_CAPABILITY_ESS
)
priv
->
BSSinfo
[
index
].
BSStype
=
IW_MODE_INFRA
;
priv
->
BSSinfo
[
index
].
preamble
=
capability
&
C80211_MGMT_CAPABILITY_ShortPreamble
?
priv
->
BSSinfo
[
index
].
preamble
=
capability
&
C80211_MGMT_CAPABILITY_ShortPreamble
?
SHORT_PREAMBLE
:
LONG_PREAMBLE
;
}
...
...
@@ -2831,8 +2849,8 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
u16
status
=
le16_to_cpu
(
auth
->
status
);
u16
trans_seq_no
=
le16_to_cpu
(
auth
->
trans_seq
);
u16
system
=
le16_to_cpu
(
auth
->
alg
);
if
(
status
==
C80211_MGMT_SC_Success
&&
!
priv
->
wep_is_on
)
{
if
(
status
==
C80211_MGMT_SC_Success
&&
!
priv
->
wep_is_on
)
{
/* no WEP */
if
(
priv
->
station_was_associated
)
{
atmel_enter_state
(
priv
,
STATION_STATE_REASSOCIATING
);
...
...
@@ -2842,20 +2860,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
atmel_enter_state
(
priv
,
STATION_STATE_ASSOCIATING
);
send_association_request
(
priv
,
0
);
return
;
}
}
}
if
(
status
==
C80211_MGMT_SC_Success
&&
priv
->
wep_is_on
)
{
if
(
status
==
C80211_MGMT_SC_Success
&&
priv
->
wep_is_on
)
{
/* WEP */
if
(
trans_seq_no
!=
priv
->
ExpectedAuthentTransactionSeqNum
)
return
;
if
(
trans_seq_no
==
0x0002
&&
auth
->
el_id
==
C80211_MGMT_ElementID_ChallengeText
)
{
send_authentication_request
(
priv
,
system
,
auth
->
chall_text
,
auth
->
chall_text_len
);
return
;
}
if
(
trans_seq_no
==
0x0004
)
{
if
(
priv
->
station_was_associated
)
{
atmel_enter_state
(
priv
,
STATION_STATE_REASSOCIATING
);
...
...
@@ -2865,10 +2883,10 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
atmel_enter_state
(
priv
,
STATION_STATE_ASSOCIATING
);
send_association_request
(
priv
,
0
);
return
;
}
}
}
}
}
if
(
status
==
C80211_MGMT_SC_AuthAlgNotSupported
)
{
/* Do opensystem first, then try sharedkey */
if
(
system
==
C80211_MGMT_AAN_OPENSYSTEM
)
{
...
...
@@ -2876,17 +2894,16 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
send_authentication_request
(
priv
,
C80211_MGMT_AAN_SHAREDKEY
,
NULL
,
0
);
}
else
if
(
priv
->
connect_to_any_BSS
)
{
int
bss_index
;
priv
->
BSSinfo
[(
int
)(
priv
->
current_BSS
)].
channel
|=
0x80
;
if
((
bss_index
=
retrieve_bss
(
priv
))
!=
-
1
)
{
atmel_join_bss
(
priv
,
bss_index
);
return
;
}
}
}
priv
->
AuthenticationRequestRetryCnt
=
0
;
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
...
...
@@ -2902,38 +2919,44 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
u8
length
;
u8
rates
[
4
];
}
*
ass_resp
=
(
struct
ass_resp_format
*
)
priv
->
rx_buf
;
u16
status
=
le16_to_cpu
(
ass_resp
->
status
);
u16
status
=
le16_to_cpu
(
ass_resp
->
status
);
u16
ass_id
=
le16_to_cpu
(
ass_resp
->
ass_id
);
u16
rates_len
=
ass_resp
->
length
>
4
?
4
:
ass_resp
->
length
;
u16
rates_len
=
ass_resp
->
length
>
4
?
4
:
ass_resp
->
length
;
if
(
frame_len
<
8
+
rates_len
)
return
;
if
(
status
==
C80211_MGMT_SC_Success
)
{
if
(
subtype
==
C80211_SUBTYPE_MGMT_ASS_RESPONSE
)
priv
->
AssociationRequestRetryCnt
=
0
;
else
priv
->
ReAssociationRequestRetryCnt
=
0
;
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_STATION_ID_POS
,
ass_id
&
0x3fff
);
atmel_set_mib
(
priv
,
Phy_Mib_Type
,
PHY_MIB_RATE_SET_POS
,
ass_resp
->
rates
,
rates_len
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_STATION_ID_POS
,
ass_id
&
0x3fff
);
atmel_set_mib
(
priv
,
Phy_Mib_Type
,
PHY_MIB_RATE_SET_POS
,
ass_resp
->
rates
,
rates_len
);
if
(
priv
->
power_mode
==
0
)
{
priv
->
listen_interval
=
1
;
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
ACTIVE_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
1
);
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
ACTIVE_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
1
);
}
else
{
priv
->
listen_interval
=
2
;
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
PS_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
2
);
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
PS_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
2
);
}
priv
->
station_is_associated
=
1
;
priv
->
station_was_associated
=
1
;
atmel_enter_state
(
priv
,
STATION_STATE_READY
);
return
;
}
if
(
subtype
==
C80211_SUBTYPE_MGMT_ASS_RESPONSE
&&
status
!=
C80211_MGMT_SC_AssDeniedBSSRate
&&
status
!=
C80211_MGMT_SC_SupportCapabilities
&&
...
...
@@ -2943,7 +2966,7 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
send_association_request
(
priv
,
0
);
return
;
}
if
(
subtype
==
C80211_SUBTYPE_MGMT_REASS_RESPONSE
&&
status
!=
C80211_MGMT_SC_AssDeniedBSSRate
&&
status
!=
C80211_MGMT_SC_SupportCapabilities
&&
...
...
@@ -2953,17 +2976,16 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
send_association_request
(
priv
,
1
);
return
;
}
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
if
(
priv
->
connect_to_any_BSS
)
{
if
(
priv
->
connect_to_any_BSS
)
{
int
bss_index
;
priv
->
BSSinfo
[(
int
)(
priv
->
current_BSS
)].
channel
|=
0x80
;
if
((
bss_index
=
retrieve_bss
(
priv
))
!=
-
1
)
if
((
bss_index
=
retrieve_bss
(
priv
))
!=
-
1
)
atmel_join_bss
(
priv
,
bss_index
);
}
}
...
...
@@ -2977,7 +2999,7 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
/* The WPA stuff cares about the current AP address */
if
(
priv
->
use_wpa
)
build_wpa_mib
(
priv
);
/* When switching to AdHoc turn OFF Power Save if needed */
if
(
bss
->
BSStype
==
IW_MODE_ADHOC
&&
...
...
@@ -2985,25 +3007,28 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
priv
->
power_mode
)
{
priv
->
power_mode
=
0
;
priv
->
listen_interval
=
1
;
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
ACTIVE_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
1
);
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
ACTIVE_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
1
);
}
priv
->
operating_mode
=
bss
->
BSStype
;
priv
->
channel
=
bss
->
channel
&
0x7f
;
priv
->
channel
=
bss
->
channel
&
0x7f
;
priv
->
beacon_period
=
bss
->
beacon_period
;
if
(
priv
->
preamble
!=
bss
->
preamble
)
{
priv
->
preamble
=
bss
->
preamble
;
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_PREAMBLE_TYPE
,
bss
->
preamble
);
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_PREAMBLE_TYPE
,
bss
->
preamble
);
}
if
(
!
priv
->
wep_is_on
&&
bss
->
UsingWEP
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
return
;
}
if
(
priv
->
wep_is_on
&&
!
bss
->
UsingWEP
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
...
...
@@ -3011,30 +3036,28 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
}
atmel_enter_state
(
priv
,
STATION_STATE_JOINNING
);
if
(
priv
->
operating_mode
==
IW_MODE_INFRA
)
join
(
priv
,
BSS_TYPE_INFRASTRUCTURE
);
else
else
join
(
priv
,
BSS_TYPE_AD_HOC
);
}
static
void
restart_search
(
struct
atmel_private
*
priv
)
{
int
bss_index
;
if
(
!
priv
->
connect_to_any_BSS
)
{
atmel_scan
(
priv
,
1
);
}
else
{
priv
->
BSSinfo
[(
int
)(
priv
->
current_BSS
)].
channel
|=
0x80
;
if
((
bss_index
=
retrieve_bss
(
priv
))
!=
-
1
)
if
((
bss_index
=
retrieve_bss
(
priv
))
!=
-
1
)
atmel_join_bss
(
priv
,
bss_index
);
else
atmel_scan
(
priv
,
0
);
}
}
}
}
static
void
smooth_rssi
(
struct
atmel_private
*
priv
,
u8
rssi
)
{
...
...
@@ -3050,21 +3073,21 @@ static void smooth_rssi(struct atmel_private *priv, u8 rssi)
}
rssi
=
rssi
*
100
/
max_rssi
;
if
((
rssi
+
old
)
%
2
)
priv
->
wstats
.
qual
.
level
=
((
rssi
+
old
)
/
2
)
+
1
;
if
((
rssi
+
old
)
%
2
)
priv
->
wstats
.
qual
.
level
=
(
rssi
+
old
)
/
2
+
1
;
else
priv
->
wstats
.
qual
.
level
=
((
rssi
+
old
)
/
2
);
priv
->
wstats
.
qual
.
level
=
(
rssi
+
old
)
/
2
;
priv
->
wstats
.
qual
.
updated
|=
IW_QUAL_LEVEL_UPDATED
;
priv
->
wstats
.
qual
.
updated
&=
~
IW_QUAL_LEVEL_INVALID
;
}
static
void
atmel_smooth_qual
(
struct
atmel_private
*
priv
)
{
unsigned
long
time_diff
=
(
jiffies
-
priv
->
last_qual
)
/
HZ
;
unsigned
long
time_diff
=
(
jiffies
-
priv
->
last_qual
)
/
HZ
;
while
(
time_diff
--
)
{
priv
->
last_qual
+=
HZ
;
priv
->
wstats
.
qual
.
qual
=
priv
->
wstats
.
qual
.
qual
/
2
;
priv
->
wstats
.
qual
.
qual
+=
priv
->
wstats
.
qual
.
qual
=
priv
->
wstats
.
qual
.
qual
/
2
;
priv
->
wstats
.
qual
.
qual
+=
priv
->
beacons_this_sec
*
priv
->
beacon_period
*
(
priv
->
wstats
.
qual
.
level
+
100
)
/
4000
;
priv
->
beacons_this_sec
=
0
;
}
...
...
@@ -3073,15 +3096,17 @@ static void atmel_smooth_qual(struct atmel_private *priv)
}
/* deals with incoming managment frames. */
static
void
atmel_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
frame_len
,
u8
rssi
)
static
void
atmel_management_frame
(
struct
atmel_private
*
priv
,
struct
ieee80211_hdr_4addr
*
header
,
u16
frame_len
,
u8
rssi
)
{
u16
subtype
;
switch
(
subtype
=
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_STYPE
)
{
case
C80211_SUBTYPE_MGMT_BEACON
:
subtype
=
le16_to_cpu
(
header
->
frame_ctl
)
&
IEEE80211_FCTL_STYPE
;
switch
(
subtype
)
{
case
C80211_SUBTYPE_MGMT_BEACON
:
case
C80211_SUBTYPE_MGMT_ProbeResponse
:
/* beacon frame has multiple variable-length fields -
never let an engineer loose with a data structure design. */
{
...
...
@@ -3099,7 +3124,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
u8
ds_length
;
/* ds here */
}
*
beacon
=
(
struct
beacon_format
*
)
priv
->
rx_buf
;
u8
channel
,
rates_length
,
ssid_length
;
u64
timestamp
=
le64_to_cpu
(
beacon
->
timestamp
);
u16
beacon_interval
=
le16_to_cpu
(
beacon
->
interval
);
...
...
@@ -3107,7 +3132,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
u8
*
beaconp
=
priv
->
rx_buf
;
ssid_length
=
beacon
->
ssid_length
;
/* this blows chunks. */
if
(
frame_len
<
14
||
frame_len
<
ssid_length
+
15
)
if
(
frame_len
<
14
||
frame_len
<
ssid_length
+
15
)
return
;
rates_length
=
beaconp
[
beacon
->
ssid_length
+
15
];
if
(
frame_len
<
ssid_length
+
rates_length
+
18
)
...
...
@@ -3115,10 +3140,10 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
if
(
ssid_length
>
MAX_SSID_LENGTH
)
return
;
channel
=
beaconp
[
ssid_length
+
rates_length
+
18
];
if
(
priv
->
station_state
==
STATION_STATE_READY
)
{
smooth_rssi
(
priv
,
rssi
);
if
(
is_frame_from_current_bss
(
priv
,
header
))
{
if
(
is_frame_from_current_bss
(
priv
,
header
))
{
priv
->
beacons_this_sec
++
;
atmel_smooth_qual
(
priv
);
if
(
priv
->
last_beacon_timestamp
)
{
...
...
@@ -3132,41 +3157,43 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
handle_beacon_probe
(
priv
,
capability
,
channel
);
}
}
if
(
priv
->
station_state
==
STATION_STATE_SCANNING
)
store_bss_info
(
priv
,
header
,
capability
,
beacon_interval
,
channel
,
rssi
,
ssid_length
,
&
beacon
->
rates_el_id
,
subtype
==
C80211_SUBTYPE_MGMT_BEACON
)
;
if
(
priv
->
station_state
==
STATION_STATE_SCANNING
)
store_bss_info
(
priv
,
header
,
capability
,
beacon_interval
,
channel
,
rssi
,
ssid_length
,
&
beacon
->
rates_el_id
,
subtype
==
C80211_SUBTYPE_MGMT_BEACON
);
}
break
;
case
C80211_SUBTYPE_MGMT_Authentication
:
if
(
priv
->
station_state
==
STATION_STATE_AUTHENTICATING
)
authenticate
(
priv
,
frame_len
);
break
;
case
C80211_SUBTYPE_MGMT_ASS_RESPONSE
:
case
C80211_SUBTYPE_MGMT_REASS_RESPONSE
:
if
(
priv
->
station_state
==
STATION_STATE_ASSOCIATING
||
if
(
priv
->
station_state
==
STATION_STATE_ASSOCIATING
||
priv
->
station_state
==
STATION_STATE_REASSOCIATING
)
associate
(
priv
,
frame_len
,
subtype
);
break
;
case
C80211_SUBTYPE_MGMT_DISASSOSIATION
:
if
(
priv
->
station_is_associated
&&
priv
->
operating_mode
==
IW_MODE_INFRA
&&
if
(
priv
->
station_is_associated
&&
priv
->
operating_mode
==
IW_MODE_INFRA
&&
is_frame_from_current_bss
(
priv
,
header
))
{
priv
->
station_was_associated
=
0
;
priv
->
station_is_associated
=
0
;
atmel_enter_state
(
priv
,
STATION_STATE_JOINNING
);
join
(
priv
,
BSS_TYPE_INFRASTRUCTURE
);
}
break
;
case
C80211_SUBTYPE_MGMT_Deauthentication
:
...
...
@@ -3177,7 +3204,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
atmel_enter_state
(
priv
,
STATION_STATE_JOINNING
);
join
(
priv
,
BSS_TYPE_INFRASTRUCTURE
);
}
break
;
}
}
...
...
@@ -3185,76 +3212,73 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
/* run when timer expires */
static
void
atmel_management_timer
(
u_long
a
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
a
;
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
unsigned
long
flags
;
/* Check if the card has been yanked. */
if
(
priv
->
card
&&
priv
->
present_callback
&&
!
(
*
priv
->
present_callback
)(
priv
->
card
))
return
;
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
switch
(
priv
->
station_state
)
{
case
STATION_STATE_AUTHENTICATING
:
if
(
priv
->
AuthenticationRequestRetryCnt
>=
MAX_AUTHENTICATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
AuthenticationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
AuthenticationRequestRetryCnt
++
;
priv
->
CurrentAuthentTransactionSeqNum
=
0x0001
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_authentication_request
(
priv
,
C80211_MGMT_AAN_OPENSYSTEM
,
NULL
,
0
);
}
break
;
struct
net_device
*
dev
=
(
struct
net_device
*
)
a
;
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
unsigned
long
flags
;
case
STATION_STATE_ASSOCIATING
:
if
(
priv
->
AssociationRequestRetryCnt
==
MAX_ASSOCIATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
AssociationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
AssociationRequestRetryCnt
++
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_association_request
(
priv
,
0
);
}
/* Check if the card has been yanked. */
if
(
priv
->
card
&&
priv
->
present_callback
&&
!
(
*
priv
->
present_callback
)(
priv
->
card
))
return
;
break
;
case
STATION_STATE_REASSOCIATING
:
if
(
priv
->
ReAssociationRequestRetryCnt
==
MAX_ASSOCIATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
ReAssociationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
ReAssociationRequestRetryCnt
++
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_association_request
(
priv
,
1
);
}
spin_lock_irqsave
(
&
priv
->
irqlock
,
flags
);
switch
(
priv
->
station_state
)
{
case
STATION_STATE_AUTHENTICATING
:
if
(
priv
->
AuthenticationRequestRetryCnt
>=
MAX_AUTHENTICATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
AuthenticationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
AuthenticationRequestRetryCnt
++
;
priv
->
CurrentAuthentTransactionSeqNum
=
0x0001
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_authentication_request
(
priv
,
C80211_MGMT_AAN_OPENSYSTEM
,
NULL
,
0
);
}
break
;
default:
case
STATION_STATE_ASSOCIATING
:
if
(
priv
->
AssociationRequestRetryCnt
==
MAX_ASSOCIATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
AssociationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
AssociationRequestRetryCnt
++
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_association_request
(
priv
,
0
);
}
break
;
}
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
case
STATION_STATE_REASSOCIATING
:
if
(
priv
->
ReAssociationRequestRetryCnt
==
MAX_ASSOCIATION_RETRIES
)
{
atmel_enter_state
(
priv
,
STATION_STATE_MGMT_ERROR
);
priv
->
station_is_associated
=
0
;
priv
->
ReAssociationRequestRetryCnt
=
0
;
restart_search
(
priv
);
}
else
{
priv
->
ReAssociationRequestRetryCnt
++
;
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
send_association_request
(
priv
,
1
);
}
break
;
default:
break
;
}
spin_unlock_irqrestore
(
&
priv
->
irqlock
,
flags
);
}
static
void
atmel_command_irq
(
struct
atmel_private
*
priv
)
{
u8
status
=
atmel_rmem8
(
priv
,
atmel_co
(
priv
,
CMD_BLOCK_STATUS_OFFSET
));
u8
command
=
atmel_rmem8
(
priv
,
atmel_co
(
priv
,
CMD_BLOCK_COMMAND_OFFSET
));
int
fast_scan
;
if
(
status
==
CMD_STATUS_IDLE
||
if
(
status
==
CMD_STATUS_IDLE
||
status
==
CMD_STATUS_IN_PROGRESS
)
return
;
...
...
@@ -3266,20 +3290,20 @@ static void atmel_command_irq(struct atmel_private *priv)
atmel_get_mib
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_CUR_BSSID_POS
,
(
u8
*
)
priv
->
CurrentBSSID
,
6
);
atmel_enter_state
(
priv
,
STATION_STATE_READY
);
}
}
break
;
case
CMD_Scan
:
fast_scan
=
priv
->
fast_scan
;
priv
->
fast_scan
=
0
;
if
(
status
!=
CMD_STATUS_COMPLETE
)
{
atmel_scan
(
priv
,
1
);
}
else
{
int
bss_index
=
retrieve_bss
(
priv
);
if
(
bss_index
!=
-
1
)
{
atmel_join_bss
(
priv
,
bss_index
);
}
else
if
(
priv
->
operating_mode
==
IW_MODE_ADHOC
&&
}
else
if
(
priv
->
operating_mode
==
IW_MODE_ADHOC
&&
priv
->
SSID_size
!=
0
)
{
start
(
priv
,
BSS_TYPE_AD_HOC
);
}
else
{
...
...
@@ -3289,16 +3313,16 @@ static void atmel_command_irq(struct atmel_private *priv)
priv
->
site_survey_state
=
SITE_SURVEY_COMPLETED
;
}
break
;
case
CMD_SiteSurvey
:
priv
->
fast_scan
=
0
;
if
(
status
!=
CMD_STATUS_COMPLETE
)
return
;
priv
->
site_survey_state
=
SITE_SURVEY_COMPLETED
;
if
(
priv
->
station_is_associated
)
{
atmel_enter_state
(
priv
,
STATION_STATE_READY
);
atmel_enter_state
(
priv
,
STATION_STATE_READY
);
}
else
{
atmel_scan
(
priv
,
1
);
}
...
...
@@ -3312,16 +3336,15 @@ static void atmel_command_irq(struct atmel_private *priv)
}
else
{
priv
->
AuthenticationRequestRetryCnt
=
0
;
atmel_enter_state
(
priv
,
STATION_STATE_AUTHENTICATING
);
mod_timer
(
&
priv
->
management_timer
,
jiffies
+
MGMT_JIFFIES
);
priv
->
CurrentAuthentTransactionSeqNum
=
0x0001
;
send_authentication_request
(
priv
,
C80211_MGMT_AAN_SHAREDKEY
,
NULL
,
0
);
}
return
;
}
atmel_scan
(
priv
,
1
);
}
}
...
...
@@ -3333,20 +3356,20 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
if
(
priv
->
card_type
==
CARD_TYPE_SPI_FLASH
)
atmel_set_gcr
(
priv
->
dev
,
GCR_REMAP
);
/* wake up on-board processor */
atmel_clear_gcr
(
priv
->
dev
,
0x0040
);
atmel_write16
(
priv
->
dev
,
BSR
,
BSS_SRAM
);
if
(
priv
->
card_type
==
CARD_TYPE_SPI_FLASH
)
mdelay
(
100
);
/* and wait for it */
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
{
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
{
mr1
=
atmel_read16
(
priv
->
dev
,
MR1
);
mr3
=
atmel_read16
(
priv
->
dev
,
MR3
);
if
(
mr3
&
MAC_BOOT_COMPLETE
)
if
(
mr3
&
MAC_BOOT_COMPLETE
)
break
;
if
(
mr1
&
MAC_BOOT_COMPLETE
&&
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
...
...
@@ -3357,35 +3380,36 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
printk
(
KERN_ALERT
"%s: MAC failed to boot.
\n
"
,
priv
->
dev
->
name
);
return
0
;
}
if
((
priv
->
host_info_base
=
atmel_read16
(
priv
->
dev
,
MR2
))
==
0xffff
)
{
printk
(
KERN_ALERT
"%s: card missing.
\n
"
,
priv
->
dev
->
name
);
return
0
;
}
/* now check for completion of MAC initialization through
the FunCtrl field of the IFACE, poll MR1 to detect completion of
MAC initialization, check completion status, set interrupt mask,
enables interrupts and calls Tx and Rx initialization functions */
/* now check for completion of MAC initialization through
the FunCtrl field of the IFACE, poll MR1 to detect completion of
MAC initialization, check completion status, set interrupt mask,
enables interrupts and calls Tx and Rx initialization functions */
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
),
FUNC_CTRL_INIT_COMPLETE
);
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
{
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
{
mr1
=
atmel_read16
(
priv
->
dev
,
MR1
);
mr3
=
atmel_read16
(
priv
->
dev
,
MR3
);
if
(
mr3
&
MAC_INIT_COMPLETE
)
if
(
mr3
&
MAC_INIT_COMPLETE
)
break
;
if
(
mr1
&
MAC_INIT_COMPLETE
&&
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
break
;
}
if
(
i
==
0
)
{
printk
(
KERN_ALERT
"%s: MAC failed to initialise.
\n
"
,
priv
->
dev
->
name
);
printk
(
KERN_ALERT
"%s: MAC failed to initialise.
\n
"
,
priv
->
dev
->
name
);
return
0
;
}
/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
if
((
mr3
&
MAC_INIT_COMPLETE
)
&&
!
(
atmel_read16
(
priv
->
dev
,
MR3
)
&
MAC_INIT_OK
))
{
...
...
@@ -3398,9 +3422,9 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
return
0
;
}
atmel_copy_to_host
(
priv
->
dev
,
(
unsigned
char
*
)
iface
,
atmel_copy_to_host
(
priv
->
dev
,
(
unsigned
char
*
)
iface
,
priv
->
host_info_base
,
sizeof
(
*
iface
));
iface
->
tx_buff_pos
=
le16_to_cpu
(
iface
->
tx_buff_pos
);
iface
->
tx_buff_size
=
le16_to_cpu
(
iface
->
tx_buff_size
);
iface
->
tx_desc_pos
=
le16_to_cpu
(
iface
->
tx_desc_pos
);
...
...
@@ -3424,16 +3448,16 @@ static int probe_atmel_card(struct net_device *dev)
{
int
rc
=
0
;
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
/* reset pccard */
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
dev
,
GCR
,
0x0060
);
atmel_write16
(
dev
,
GCR
,
0x0040
);
mdelay
(
500
);
if
(
atmel_read16
(
dev
,
MR2
)
==
0
)
{
/* No stored firmware so load a small stub which just
/* No stored firmware so load a small stub which just
tells us the MAC address */
int
i
;
priv
->
card_type
=
CARD_TYPE_EEPROM
;
...
...
@@ -3442,7 +3466,7 @@ static int probe_atmel_card(struct net_device *dev)
atmel_set_gcr
(
dev
,
GCR_REMAP
);
atmel_clear_gcr
(
priv
->
dev
,
0x0040
);
atmel_write16
(
dev
,
BSR
,
BSS_SRAM
);
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
for
(
i
=
LOOP_RETRY_LIMIT
;
i
;
i
--
)
if
(
atmel_read16
(
dev
,
MR3
)
&
MAC_BOOT_COMPLETE
)
break
;
if
(
i
==
0
)
{
...
...
@@ -3451,7 +3475,7 @@ static int probe_atmel_card(struct net_device *dev)
atmel_copy_to_host
(
dev
,
dev
->
dev_addr
,
atmel_read16
(
dev
,
MR2
),
6
);
/* got address, now squash it again until the network
interface is opened */
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
dev
,
GCR
,
0x0060
);
atmel_write16
(
dev
,
GCR
,
0x0040
);
rc
=
1
;
...
...
@@ -3459,7 +3483,7 @@ static int probe_atmel_card(struct net_device *dev)
}
else
if
(
atmel_read16
(
dev
,
MR4
)
==
0
)
{
/* Mac address easy in this case. */
priv
->
card_type
=
CARD_TYPE_PARALLEL_FLASH
;
atmel_write16
(
dev
,
BSR
,
1
);
atmel_write16
(
dev
,
BSR
,
1
);
atmel_copy_to_host
(
dev
,
dev
->
dev_addr
,
0xc000
,
6
);
atmel_write16
(
dev
,
BSR
,
0x200
);
rc
=
1
;
...
...
@@ -3469,16 +3493,16 @@ static int probe_atmel_card(struct net_device *dev)
priv
->
card_type
=
CARD_TYPE_SPI_FLASH
;
if
(
atmel_wakeup_firmware
(
priv
))
{
atmel_get_mib
(
priv
,
Mac_Address_Mib_Type
,
0
,
dev
->
dev_addr
,
6
);
/* got address, now squash it again until the network
interface is opened */
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
dev
,
GCR
,
0x0060
);
atmel_write16
(
dev
,
GCR
,
0x0040
);
rc
=
1
;
}
}
if
(
rc
)
{
if
(
dev
->
dev_addr
[
0
]
==
0xFF
)
{
u8
default_mac
[]
=
{
0x00
,
0x04
,
0x25
,
0x00
,
0x00
,
0x00
};
...
...
@@ -3486,27 +3510,27 @@ static int probe_atmel_card(struct net_device *dev)
memcpy
(
dev
->
dev_addr
,
default_mac
,
6
);
}
}
return
rc
;
}
static
void
build_wep_mib
(
struct
atmel_private
*
priv
)
/* Move the encyption information on the MIB structure.
This routine is for the pre-WPA firmware: later firmware has
a different format MIB and a different routine. */
static
void
build_wep_mib
(
struct
atmel_private
*
priv
)
{
struct
{
/* NB this is matched to the hardware, don't change. */
u8
wep_is_on
;
u8
wep_is_on
;
u8
default_key
;
/* 0..3 */
u8
reserved
;
u8
exclude_unencrypted
;
u32
WEPICV_error_count
;
u32
WEP_excluded_count
;
u8
wep_keys
[
MAX_ENCRYPTION_KEYS
][
13
];
u8
encryption_level
;
/* 0, 1, 2 */
u8
reserved2
[
3
];
u8
encryption_level
;
/* 0, 1, 2 */
u8
reserved2
[
3
];
}
mib
;
int
i
;
...
...
@@ -3515,54 +3539,55 @@ static void build_wep_mib(struct atmel_private *priv)
if
(
priv
->
wep_key_len
[
priv
->
default_key
]
>
5
)
mib
.
encryption_level
=
2
;
else
mib
.
encryption_level
=
1
;
mib
.
encryption_level
=
1
;
}
else
{
mib
.
encryption_level
=
0
;
}
mib
.
default_key
=
priv
->
default_key
;
mib
.
exclude_unencrypted
=
priv
->
exclude_unencrypted
;
for
(
i
=
0
;
i
<
MAX_ENCRYPTION_KEYS
;
i
++
)
for
(
i
=
0
;
i
<
MAX_ENCRYPTION_KEYS
;
i
++
)
memcpy
(
mib
.
wep_keys
[
i
],
priv
->
wep_keys
[
i
],
13
);
atmel_set_mib
(
priv
,
Mac_Wep_Mib_Type
,
0
,
(
u8
*
)
&
mib
,
sizeof
(
mib
));
}
static
void
build_wpa_mib
(
struct
atmel_private
*
priv
)
{
/* This is for the later (WPA enabled) firmware. */
/* This is for the later (WPA enabled) firmware. */
struct
{
/* NB this is matched to the hardware, don't change. */
u8
cipher_default_key_value
[
MAX_ENCRYPTION_KEYS
][
MAX_ENCRYPTION_KEY_SIZE
];
u8
receiver_address
[
6
];
u8
wep_is_on
;
u8
wep_is_on
;
u8
default_key
;
/* 0..3 */
u8
group_key
;
u8
exclude_unencrypted
;
u8
encryption_type
;
u8
reserved
;
u32
WEPICV_error_count
;
u32
WEP_excluded_count
;
u8
key_RSC
[
4
][
8
];
}
mib
;
int
i
;
mib
.
wep_is_on
=
priv
->
wep_is_on
;
mib
.
exclude_unencrypted
=
priv
->
exclude_unencrypted
;
memcpy
(
mib
.
receiver_address
,
priv
->
CurrentBSSID
,
6
);
/* zero all the keys before adding in valid ones. */
memset
(
mib
.
cipher_default_key_value
,
0
,
sizeof
(
mib
.
cipher_default_key_value
));
if
(
priv
->
wep_is_on
)
{
/* There's a comment in the Atmel code to the effect that this is only valid
when still using WEP, it may need to be set to something to use WPA */
/* There's a comment in the Atmel code to the effect that this
is only valid when still using WEP, it may need to be set to
something to use WPA */
memset
(
mib
.
key_RSC
,
0
,
sizeof
(
mib
.
key_RSC
));
mib
.
default_key
=
mib
.
group_key
=
255
;
for
(
i
=
0
;
i
<
MAX_ENCRYPTION_KEYS
;
i
++
)
{
if
(
priv
->
wep_key_len
[
i
]
>
0
)
{
...
...
@@ -3570,12 +3595,12 @@ static void build_wpa_mib(struct atmel_private *priv)
if
(
i
==
priv
->
default_key
)
{
mib
.
default_key
=
i
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
1
]
=
7
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
2
]
=
priv
->
pairwise_cipher_suite
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
2
]
=
priv
->
pairwise_cipher_suite
;
}
else
{
mib
.
group_key
=
i
;
priv
->
group_cipher_suite
=
priv
->
pairwise_cipher_suite
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
1
]
=
1
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
2
]
=
priv
->
group_cipher_suite
;
mib
.
cipher_default_key_value
[
i
][
MAX_ENCRYPTION_KEY_SIZE
-
2
]
=
priv
->
group_cipher_suite
;
}
}
}
...
...
@@ -3583,47 +3608,47 @@ static void build_wpa_mib(struct atmel_private *priv)
mib
.
default_key
=
mib
.
group_key
!=
255
?
mib
.
group_key
:
0
;
if
(
mib
.
group_key
==
255
)
mib
.
group_key
=
mib
.
default_key
;
}
atmel_set_mib
(
priv
,
Mac_Wep_Mib_Type
,
0
,
(
u8
*
)
&
mib
,
sizeof
(
mib
));
}
static
int
reset_atmel_card
(
struct
net_device
*
dev
)
static
int
reset_atmel_card
(
struct
net_device
*
dev
)
{
/* do everything necessary to wake up the hardware, including
waiting for the lightning strike and throwing the knife switch....
set all the Mib values which matter in the card to match
set all the Mib values which matter in the card to match
their settings in the atmel_private structure. Some of these
can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
can only be changed by tearing down the world and coming back through
here.
This routine is also responsible for initialising some
hardware-specific fields in the atmel_private structure,
This routine is also responsible for initialising some
hardware-specific fields in the atmel_private structure,
including a copy of the firmware's hostinfo stucture
which is the route into the rest of the firmare datastructures. */
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
u8
configuration
;
/* data to add to the firmware names, in priority order
this implemenents firmware versioning */
static
char
*
firmware_modifier
[]
=
{
"-wpa"
,
""
,
NULL
};
/* reset pccard */
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
if
(
priv
->
bus_type
==
BUS_TYPE_PCCARD
)
atmel_write16
(
priv
->
dev
,
GCR
,
0x0060
);
/* stop card , disable interrupts */
atmel_write16
(
priv
->
dev
,
GCR
,
0x0040
);
if
(
priv
->
card_type
==
CARD_TYPE_EEPROM
)
{
/* copy in firmware if needed */
const
struct
firmware
*
fw_entry
=
NULL
;
...
...
@@ -3636,13 +3661,13 @@ static int reset_atmel_card(struct net_device *dev)
"%s: card type is unknown: assuming at76c502 firmware is OK.
\n
"
,
dev
->
name
);
printk
(
KERN_INFO
"%s: if not, use the firmware= module parameter.
\n
"
,
"%s: if not, use the firmware= module parameter.
\n
"
,
dev
->
name
);
strcpy
(
priv
->
firmware_id
,
"atmel_at76c502.bin"
);
}
if
(
request_firmware
(
&
fw_entry
,
priv
->
firmware_id
,
priv
->
sys_dev
)
!=
0
)
{
printk
(
KERN_ALERT
"%s: firmware %s is missing, cannot continue.
\n
"
,
printk
(
KERN_ALERT
"%s: firmware %s is missing, cannot continue.
\n
"
,
dev
->
name
,
priv
->
firmware_id
);
return
0
;
}
...
...
@@ -3654,7 +3679,7 @@ static int reset_atmel_card(struct net_device *dev)
while
(
fw_table
[
fw_index
].
fw_type
!=
priv
->
firmware_type
&&
fw_table
[
fw_index
].
fw_type
!=
ATMEL_FW_TYPE_NONE
)
fw_index
++
;
/* construct the actual firmware file name */
if
(
fw_table
[
fw_index
].
fw_type
!=
ATMEL_FW_TYPE_NONE
)
{
int
i
;
...
...
@@ -3669,24 +3694,24 @@ static int reset_atmel_card(struct net_device *dev)
}
}
if
(
!
success
)
{
printk
(
KERN_ALERT
"%s: firmware %s is missing, cannot start.
\n
"
,
printk
(
KERN_ALERT
"%s: firmware %s is missing, cannot start.
\n
"
,
dev
->
name
,
priv
->
firmware_id
);
priv
->
firmware_id
[
0
]
=
'\0'
;
return
0
;
return
0
;
}
}
fw
=
fw_entry
->
data
;
len
=
fw_entry
->
size
;
}
if
(
len
<=
0x6000
)
{
atmel_write16
(
priv
->
dev
,
BSR
,
BSS_IRAM
);
atmel_copy_to_card
(
priv
->
dev
,
0
,
fw
,
len
);
atmel_set_gcr
(
priv
->
dev
,
GCR_REMAP
);
}
else
{
/* Remap */
/* Remap */
atmel_set_gcr
(
priv
->
dev
,
GCR_REMAP
);
atmel_write16
(
priv
->
dev
,
BSR
,
BSS_IRAM
);
atmel_copy_to_card
(
priv
->
dev
,
0
,
fw
,
0x6000
);
...
...
@@ -3708,45 +3733,45 @@ static int reset_atmel_card(struct net_device *dev)
the 3com broken-ness filter. */
priv
->
use_wpa
=
(
priv
->
host_info
.
major_version
==
4
);
priv
->
radio_on_broken
=
(
priv
->
host_info
.
major_version
==
5
);
/* unmask all irq sources */
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_INT_MASK_OFFSET
),
0xff
);
/* int Tx system and enable Tx */
atmel_wmem8
(
priv
,
atmel_tx
(
priv
,
TX_DESC_FLAGS_OFFSET
,
0
),
0
);
atmel_wmem32
(
priv
,
atmel_tx
(
priv
,
TX_DESC_NEXT_OFFSET
,
0
),
0x80000000L
);
atmel_wmem16
(
priv
,
atmel_tx
(
priv
,
TX_DESC_POS_OFFSET
,
0
),
0
);
atmel_wmem16
(
priv
,
atmel_tx
(
priv
,
TX_DESC_SIZE_OFFSET
,
0
),
0
);
priv
->
tx_desc_free
=
priv
->
host_info
.
tx_desc_count
;
priv
->
tx_desc_head
=
0
;
priv
->
tx_desc_tail
=
0
;
priv
->
tx_desc_free
=
priv
->
host_info
.
tx_desc_count
;
priv
->
tx_desc_head
=
0
;
priv
->
tx_desc_tail
=
0
;
priv
->
tx_desc_previous
=
0
;
priv
->
tx_free_mem
=
priv
->
host_info
.
tx_buff_size
;
priv
->
tx_buff_head
=
0
;
priv
->
tx_buff_tail
=
0
;
configuration
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
));
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
),
priv
->
tx_buff_head
=
0
;
priv
->
tx_buff_tail
=
0
;
configuration
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
));
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
),
configuration
|
FUNC_CTRL_TxENABLE
);
/* init Rx system and enable */
priv
->
rx_desc_head
=
0
;
configuration
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
));
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
),
configuration
=
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
));
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_FUNC_CTRL_OFFSET
),
configuration
|
FUNC_CTRL_RxENABLE
);
if
(
!
priv
->
radio_on_broken
)
{
if
(
atmel_send_command_wait
(
priv
,
CMD_EnableRadio
,
NULL
,
0
)
==
if
(
atmel_send_command_wait
(
priv
,
CMD_EnableRadio
,
NULL
,
0
)
==
CMD_STATUS_REJECTED_RADIO_OFF
)
{
printk
(
KERN_INFO
printk
(
KERN_INFO
"%s: cannot turn the radio on. (Hey radio, you're beautiful!)
\n
"
,
dev
->
name
);
return
0
;
}
}
/* set up enough MIB values to run. */
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_AUTO_TX_RATE_POS
,
priv
->
auto_tx_rate
);
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_TX_PROMISCUOUS_POS
,
PROM_MODE_OFF
);
...
...
@@ -3755,7 +3780,7 @@ static int reset_atmel_card(struct net_device *dev)
atmel_set_mib8
(
priv
,
Mac_Mib_Type
,
MAC_MIB_SHORT_RETRY_POS
,
priv
->
short_retry
);
atmel_set_mib8
(
priv
,
Mac_Mib_Type
,
MAC_MIB_LONG_RETRY_POS
,
priv
->
long_retry
);
atmel_set_mib8
(
priv
,
Local_Mib_Type
,
LOCAL_MIB_PREAMBLE_TYPE
,
priv
->
preamble
);
atmel_set_mib
(
priv
,
Mac_Address_Mib_Type
,
MAC_ADDR_MIB_MAC_ADDR_POS
,
atmel_set_mib
(
priv
,
Mac_Address_Mib_Type
,
MAC_ADDR_MIB_MAC_ADDR_POS
,
priv
->
dev
->
dev_addr
,
6
);
atmel_set_mib8
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_PS_MODE_POS
,
ACTIVE_MODE
);
atmel_set_mib16
(
priv
,
Mac_Mgmt_Mib_Type
,
MAC_MGMT_MIB_LISTEN_INTERVAL_POS
,
1
);
...
...
@@ -3766,42 +3791,44 @@ static int reset_atmel_card(struct net_device *dev)
build_wpa_mib
(
priv
);
else
build_wep_mib
(
priv
);
return
1
;
}
static
void
atmel_send_command
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
)
static
void
atmel_send_command
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
)
{
if
(
cmd
)
atmel_copy_to_card
(
priv
->
dev
,
atmel_co
(
priv
,
CMD_BLOCK_PARAMETERS_OFFSET
),
atmel_copy_to_card
(
priv
->
dev
,
atmel_co
(
priv
,
CMD_BLOCK_PARAMETERS_OFFSET
),
cmd
,
cmd_size
);
atmel_wmem8
(
priv
,
atmel_co
(
priv
,
CMD_BLOCK_COMMAND_OFFSET
),
command
);
atmel_wmem8
(
priv
,
atmel_co
(
priv
,
CMD_BLOCK_STATUS_OFFSET
),
0
);
}
static
int
atmel_send_command_wait
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
)
static
int
atmel_send_command_wait
(
struct
atmel_private
*
priv
,
int
command
,
void
*
cmd
,
int
cmd_size
)
{
int
i
,
status
;
atmel_send_command
(
priv
,
command
,
cmd
,
cmd_size
);
for
(
i
=
5000
;
i
;
i
--
)
{
status
=
atmel_rmem8
(
priv
,
atmel_co
(
priv
,
CMD_BLOCK_STATUS_OFFSET
));
if
(
status
!=
CMD_STATUS_IDLE
&&
if
(
status
!=
CMD_STATUS_IDLE
&&
status
!=
CMD_STATUS_IN_PROGRESS
)
break
;
udelay
(
20
);
}
if
(
i
==
0
)
{
printk
(
KERN_ALERT
"%s: failed to contact MAC.
\n
"
,
priv
->
dev
->
name
);
status
=
CMD_STATUS_HOST_ERROR
;
}
else
{
}
else
{
if
(
command
!=
CMD_EnableRadio
)
status
=
CMD_STATUS_COMPLETE
;
}
return
status
;
}
...
...
@@ -3827,7 +3854,8 @@ static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 dat
atmel_send_command_wait
(
priv
,
CMD_Set_MIB_Vars
,
&
m
,
MIB_HEADER_SIZE
+
1
);
}
static
void
atmel_set_mib16
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u16
data
)
static
void
atmel_set_mib16
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u16
data
)
{
struct
get_set_mib
m
;
m
.
type
=
type
;
...
...
@@ -3839,7 +3867,8 @@ static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 d
atmel_send_command_wait
(
priv
,
CMD_Set_MIB_Vars
,
&
m
,
MIB_HEADER_SIZE
+
2
);
}
static
void
atmel_set_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
)
static
void
atmel_set_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
)
{
struct
get_set_mib
m
;
m
.
type
=
type
;
...
...
@@ -3848,23 +3877,24 @@ static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *dat
if
(
data_len
>
MIB_MAX_DATA_BYTES
)
printk
(
KERN_ALERT
"%s: MIB buffer too small.
\n
"
,
priv
->
dev
->
name
);
memcpy
(
m
.
data
,
data
,
data_len
);
atmel_send_command_wait
(
priv
,
CMD_Set_MIB_Vars
,
&
m
,
MIB_HEADER_SIZE
+
data_len
);
}
static
void
atmel_get_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
)
static
void
atmel_get_mib
(
struct
atmel_private
*
priv
,
u8
type
,
u8
index
,
u8
*
data
,
int
data_len
)
{
struct
get_set_mib
m
;
m
.
type
=
type
;
m
.
size
=
data_len
;
m
.
index
=
index
;
if
(
data_len
>
MIB_MAX_DATA_BYTES
)
printk
(
KERN_ALERT
"%s: MIB buffer too small.
\n
"
,
priv
->
dev
->
name
);
atmel_send_command_wait
(
priv
,
CMD_Get_MIB_Vars
,
&
m
,
MIB_HEADER_SIZE
+
data_len
);
atmel_copy_to_host
(
priv
->
dev
,
data
,
atmel_copy_to_host
(
priv
->
dev
,
data
,
atmel_co
(
priv
,
CMD_BLOCK_PARAMETERS_OFFSET
+
MIB_HEADER_SIZE
),
data_len
);
}
...
...
@@ -3873,11 +3903,12 @@ static void atmel_writeAR(struct net_device *dev, u16 data)
int
i
;
outw
(
data
,
dev
->
base_addr
+
AR
);
/* Address register appears to need some convincing..... */
for
(
i
=
0
;
data
!=
inw
(
dev
->
base_addr
+
AR
)
&&
i
<
10
;
i
++
)
for
(
i
=
0
;
data
!=
inw
(
dev
->
base_addr
+
AR
)
&&
i
<
10
;
i
++
)
outw
(
data
,
dev
->
base_addr
+
AR
);
}
static
void
atmel_copy_to_card
(
struct
net_device
*
dev
,
u16
dest
,
unsigned
char
*
src
,
u16
len
)
static
void
atmel_copy_to_card
(
struct
net_device
*
dev
,
u16
dest
,
unsigned
char
*
src
,
u16
len
)
{
int
i
;
atmel_writeAR
(
dev
,
dest
);
...
...
@@ -3894,7 +3925,8 @@ static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *
atmel_write8
(
dev
,
DR
,
*
src
);
}
static
void
atmel_copy_to_host
(
struct
net_device
*
dev
,
unsigned
char
*
dest
,
u16
src
,
u16
len
)
static
void
atmel_copy_to_host
(
struct
net_device
*
dev
,
unsigned
char
*
dest
,
u16
src
,
u16
len
)
{
int
i
;
atmel_writeAR
(
dev
,
src
);
...
...
@@ -3930,22 +3962,24 @@ static int atmel_lock_mac(struct atmel_private *priv)
break
;
udelay
(
20
);
}
if
(
!
i
)
return
0
;
/* timed out */
if
(
!
i
)
return
0
;
/* timed out */
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_LOCKOUT_MAC_OFFSET
),
1
);
if
(
atmel_rmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_LOCKOUT_HOST_OFFSET
)))
{
atmel_wmem8
(
priv
,
atmel_hi
(
priv
,
IFACE_LOCKOUT_MAC_OFFSET
),
0
);
if
(
!
j
--
)
return
0
;
/* timed out */
if
(
!
j
--
)
return
0
;
/* timed out */
goto
retry
;
}
return
1
;
}
static
void
atmel_wmem32
(
struct
atmel_private
*
priv
,
u16
pos
,
u32
data
)
{
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_writeAR
(
priv
->
dev
,
pos
);
atmel_write16
(
priv
->
dev
,
DR
,
data
);
/* card is little-endian */
atmel_write16
(
priv
->
dev
,
DR
,
data
>>
16
);
}
...
...
@@ -4017,9 +4051,9 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
serial output, since SO is normally high. But it
does cause 8 clock cycles and thus 8 bits to be
clocked in to the chip. See Atmel's SPI
controller (e.g. AT91M55800) timing and 4K
controller (e.g. AT91M55800) timing and 4K
SPI EEPROM manuals */
.set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
.set NVRAM_IMAGE, 0x02000200
.set NVRAM_LENGTH, 0x0200
...
...
@@ -4032,24 +4066,24 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
.set MR4, 0xC
RESET_VECTOR:
b RESET_HANDLER
UNDEF_VECTOR:
UNDEF_VECTOR:
b HALT1
SWI_VECTOR:
SWI_VECTOR:
b HALT1
IABORT_VECTOR:
IABORT_VECTOR:
b HALT1
DABORT_VECTOR:
RESERVED_VECTOR:
DABORT_VECTOR:
RESERVED_VECTOR:
b HALT1
IRQ_VECTOR:
IRQ_VECTOR:
b HALT1
FIQ_VECTOR:
FIQ_VECTOR:
b HALT1
HALT1: b HALT1
RESET_HANDLER:
mov r0, #CPSR_INITIAL
msr CPSR_c, r0 /* This is probably unnecessary */
/* I'm guessing this is initializing clock generator electronics for SPI */
ldr r0, =SPI_CGEN_BASE
mov r1, #0
...
...
@@ -4061,7 +4095,7 @@ HALT1: b HALT1
str r1, [r0, #28]
mov r1, #1
str r1, [r0, #8]
ldr r0, =MRBASE
mov r1, #0
strh r1, [r0, #MR1]
...
...
@@ -4094,7 +4128,7 @@ HALT2: b HALT2
ldmia sp!, {lr}
bx lr
.endfunc
.func Get_MAC_Addr, GET_MAC_ADDR
GET_MAC_ADDR:
stmdb sp!, {lr}
...
...
@@ -4110,13 +4144,13 @@ HALT2: b HALT2
.func Delay9, DELAY9
DELAY9:
adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
DELAYLOOP:
DELAYLOOP:
beq DELAY9_done
subs r0, r0, #1
b DELAYLOOP
DELAY9_done:
DELAY9_done:
bx lr
.endfunc
.endfunc
.func SP_Init, SP_INIT
SP_INIT:
...
...
@@ -4145,26 +4179,26 @@ HALT2: b HALT2
ldr r0, [r0, #SP_RDR]
bx lr
.endfunc
.func NVRAM_Init, NVRAM_INIT
.func NVRAM_Init, NVRAM_INIT
NVRAM_INIT:
ldr r1, =SP_BASE
ldr r0, [r1, #SP_RDR]
mov r0, #NVRAM_CMD_RDSR
str r0, [r1, #SP_TDR]
SP_loop1:
SP_loop1:
ldr r0, [r1, #SP_SR]
tst r0, #SP_TDRE
beq SP_loop1
mov r0, #SPI_8CLOCKS
str r0, [r1, #SP_TDR]
SP_loop2:
str r0, [r1, #SP_TDR]
SP_loop2:
ldr r0, [r1, #SP_SR]
tst r0, #SP_TDRE
beq SP_loop2
ldr r0, [r1, #SP_RDR]
SP_loop3:
SP_loop3:
ldr r0, [r1, #SP_SR]
tst r0, #SP_RDRF
beq SP_loop3
...
...
@@ -4173,7 +4207,7 @@ HALT2: b HALT2
and r0, r0, #255
bx lr
.endfunc
.func NVRAM_Xfer, NVRAM_XFER
/* r0 = dest address */
/* r1 = not used */
...
...
@@ -4185,11 +4219,11 @@ HALT2: b HALT2
mov r4, r3 /* save r3 (length) */
mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
and r0, r0, #8
add r0, r0, #NVRAM_CMD_READ
add r0, r0, #NVRAM_CMD_READ
ldr r1, =NVRAM_SCRATCH
strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
_local1:
_local1:
bl NVRAM_INIT
tst r0, #NVRAM_SR_RDY
bne _local1
...
...
@@ -4211,7 +4245,7 @@ HALT2: b HALT2
cmp r0, #0
bls _local2
ldr r5, =NVRAM_SCRATCH
_local4:
_local4:
ldrb r6, [r5, r3]
str r6, [r4, #SP_TDR]
_local3:
...
...
@@ -4225,7 +4259,7 @@ HALT2: b HALT2
mov r3, #SPI_8CLOCKS
str r3, [r4, #SP_TDR]
ldr r0, [r4, #SP_RDR]
_local5:
_local5:
ldr r0, [r4, #SP_SR]
tst r0, #SP_RDRF
beq _local5
...
...
@@ -4233,12 +4267,12 @@ HALT2: b HALT2
mov r0, #0
cmp r2, #0 /* r2 is # of bytes to copy in */
bls _local6
_local7:
_local7:
ldr r5, [r4, #SP_SR]
tst r5, #SP_TDRE
beq _local7
str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
_local8:
_local8:
ldr r5, [r4, #SP_SR]
tst r5, #SP_RDRF
beq _local8
...
...
drivers/net/wireless/hostap/Makefile
浏览文件 @
1f8fc993
hostap-y
:=
hostap_main.o
obj-$(CONFIG_HOSTAP)
+=
hostap.o
obj-$(CONFIG_HOSTAP_CS)
+=
hostap_cs.o
...
...
drivers/net/wireless/hostap/hostap.c
→
drivers/net/wireless/hostap/hostap
_main
.c
浏览文件 @
1f8fc993
文件已移动
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录