Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
2e9ff56e
Commit
2e9ff56e
authored
Mar 20, 2006
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream' of
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
parents
d378aca6
cc8279f6
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
415 additions
and
375 deletions
+415
-375
Documentation/networking/README.ipw2100
Documentation/networking/README.ipw2100
+6
-6
Documentation/networking/README.ipw2200
Documentation/networking/README.ipw2200
+42
-2
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2100.c
+147
-73
drivers/net/wireless/ipw2100.h
drivers/net/wireless/ipw2100.h
+8
-3
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.c
+188
-262
drivers/net/wireless/ipw2200.h
drivers/net/wireless/ipw2200.h
+11
-28
net/ieee80211/ieee80211_rx.c
net/ieee80211/ieee80211_rx.c
+13
-1
No files found.
Documentation/networking/README.ipw2100
View file @
2e9ff56e
...
...
@@ -3,18 +3,18 @@ Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
Intel(R) PRO/Wireless 2100 Network Connection
Copyright (C) 2003-200
5
, Intel Corporation
Copyright (C) 2003-200
6
, Intel Corporation
README.ipw2100
Version:
1.1.3
Date :
October 17, 2005
Version:
git-1.1.5
Date :
January 25, 2006
Index
-----------------------------------------------
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Introduction
2. Release
1.1.3
Current Features
2. Release
git-1.1.5
Current Features
3. Command Line Parameters
4. Sysfs Helper Files
5. Radio Kill Switch
...
...
@@ -89,7 +89,7 @@ potential fixes and patches, as well as links to the development mailing list
for the driver project.
2. Release
1.1.3
Current Supported Features
2. Release
git-1.1.5
Current Supported Features
-----------------------------------------------
- Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open)
...
...
@@ -270,7 +270,7 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
9. License
-----------------------------------------------
Copyright(c) 2003 - 200
5
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License (version 2) as
...
...
Documentation/networking/README.ipw2200
View file @
2e9ff56e
...
...
@@ -10,7 +10,7 @@ both hardware adapters listed above. In this document the Intel(R)
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
unified driver.
Copyright (C) 2004-200
5
, Intel Corporation
Copyright (C) 2004-200
6
, Intel Corporation
README.ipw2200
...
...
@@ -26,9 +26,11 @@ Index
1.2. Module parameters
1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files
1.5. Supported channels
2. Ad-Hoc Networking
3. Interacting with Wireless Tools
3.1. iwconfig mode
3.2. iwconfig sens
4. About the Version Numbers
5. Firmware installation
6. Support
...
...
@@ -314,6 +316,35 @@ For the device level files, see /sys/bus/pci/drivers/ipw2200:
running ifconfig and is therefore disabled by default.
1.5. Supported channels
-----------------------------------------------
Upon loading the Intel(R) PRO/Wireless 2915ABG Driver for Linux, a
message stating the detected geography code and the number of 802.11
channels supported by the card will be displayed in the log.
The geography code corresponds to a regulatory domain as shown in the
table below.
Supported channels
Code Geography 802.11bg 802.11a
--- Restricted 11 0
ZZF Custom US/Canada 11 8
ZZD Rest of World 13 0
ZZA Custom USA & Europe & High 11 13
ZZB Custom NA & Europe 11 13
ZZC Custom Japan 11 4
ZZM Custom 11 0
ZZE Europe 13 19
ZZJ Custom Japan 14 4
ZZR Rest of World 14 0
ZZH High Band 13 4
ZZG Custom Europe 13 4
ZZK Europe 13 24
ZZL Europe 11 13
2. Ad-Hoc Networking
-----------------------------------------------
...
...
@@ -353,6 +384,15 @@ When configuring the mode of the adapter, all run-time configured parameters
are reset to the value used when the module was loaded. This includes
channels, rates, ESSID, etc.
3.2 iwconfig sens
-----------------------------------------------
The 'iwconfig ethX sens XX' command will not set the signal sensitivity
threshold, as described in iwconfig documentation, but rather the number
of consecutive missed beacons that will trigger handover, i.e. roaming
to another access point. At the same time, it will set the disassociation
threshold to 3 times the given value.
4. About the Version Numbers
-----------------------------------------------
...
...
@@ -408,7 +448,7 @@ For general information and support, go to:
7. License
-----------------------------------------------
Copyright(c) 2003 - 200
5
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
...
...
drivers/net/wireless/ipw2100.c
View file @
2e9ff56e
/******************************************************************************
Copyright(c) 2003 - 200
5
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
...
...
@@ -167,12 +167,12 @@ that only one external action is invoked at a time.
#include "ipw2100.h"
#define IPW2100_VERSION "git-1.
1.4
"
#define IPW2100_VERSION "git-1.
2.2
"
#define DRV_NAME "ipw2100"
#define DRV_VERSION IPW2100_VERSION
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 2003-200
5
Intel Corporation"
#define DRV_COPYRIGHT "Copyright(c) 2003-200
6
Intel Corporation"
/* Debugging stuff */
#ifdef CONFIG_IPW2100_DEBUG
...
...
@@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
if
(
priv
->
status
&
STATUS_ENABLED
)
return
0
;
down
(
&
priv
->
adapter_sem
);
mutex_lock
(
&
priv
->
adapter_mutex
);
if
(
rf_kill_active
(
priv
))
{
IPW_DEBUG_HC
(
"Command aborted due to RF kill active.
\n
"
);
...
...
@@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
}
fail_up:
up
(
&
priv
->
adapter_sem
);
mutex_unlock
(
&
priv
->
adapter_mutex
);
return
err
;
}
...
...
@@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
cancel_delayed_work
(
&
priv
->
hang_check
);
}
down
(
&
priv
->
adapter_sem
);
mutex_lock
(
&
priv
->
adapter_mutex
);
err
=
ipw2100_hw_send_command
(
priv
,
&
cmd
);
if
(
err
)
{
...
...
@@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
IPW_DEBUG_INFO
(
"TODO: implement scan state machine
\n
"
);
fail_up:
up
(
&
priv
->
adapter_sem
);
mutex_unlock
(
&
priv
->
adapter_mutex
);
return
err
;
}
...
...
@@ -1888,7 +1888,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
priv
->
status
|=
STATUS_RESET_PENDING
;
spin_unlock_irqrestore
(
&
priv
->
low_lock
,
flags
);
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
/* stop timed checks so that they don't interfere with reset */
priv
->
stop_hang_check
=
1
;
cancel_delayed_work
(
&
priv
->
hang_check
);
...
...
@@ -1898,7 +1898,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
wireless_send_event
(
priv
->
net_dev
,
SIOCGIWAP
,
&
wrqu
,
NULL
);
ipw2100_up
(
priv
,
0
);
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
}
...
...
@@ -2390,15 +2390,6 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
IPW_DEBUG_DROP
(
"Dropping packet while interface is not up.
\n
"
);
return
;
}
#ifdef CONFIG_IPW2100_MONITOR
if
(
unlikely
(
priv
->
ieee
->
iw_mode
==
IW_MODE_MONITOR
&&
priv
->
config
&
CFG_CRC_CHECK
&&
status
->
flags
&
IPW_STATUS_FLAG_CRC_ERROR
))
{
IPW_DEBUG_RX
(
"CRC error in packet. Dropping.
\n
"
);
priv
->
ieee
->
stats
.
rx_errors
++
;
return
;
}
#endif
if
(
unlikely
(
priv
->
ieee
->
iw_mode
!=
IW_MODE_MONITOR
&&
!
(
priv
->
status
&
STATUS_ASSOCIATED
)))
{
...
...
@@ -2446,6 +2437,89 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
priv
->
rx_queue
.
drv
[
i
].
host_addr
=
packet
->
dma_addr
;
}
#ifdef CONFIG_IPW2100_MONITOR
static
void
isr_rx_monitor
(
struct
ipw2100_priv
*
priv
,
int
i
,
struct
ieee80211_rx_stats
*
stats
)
{
struct
ipw2100_status
*
status
=
&
priv
->
status_queue
.
drv
[
i
];
struct
ipw2100_rx_packet
*
packet
=
&
priv
->
rx_buffers
[
i
];
/* Magic struct that slots into the radiotap header -- no reason
* to build this manually element by element, we can write it much
* more efficiently than we can parse it. ORDER MATTERS HERE */
struct
ipw_rt_hdr
{
struct
ieee80211_radiotap_header
rt_hdr
;
s8
rt_dbmsignal
;
/* signal in dbM, kluged to signed */
}
*
ipw_rt
;
IPW_DEBUG_RX
(
"Handler...
\n
"
);
if
(
unlikely
(
status
->
frame_size
>
skb_tailroom
(
packet
->
skb
)
-
sizeof
(
struct
ipw_rt_hdr
)))
{
IPW_DEBUG_INFO
(
"%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.
\n
"
,
priv
->
net_dev
->
name
,
status
->
frame_size
,
skb_tailroom
(
packet
->
skb
));
priv
->
ieee
->
stats
.
rx_errors
++
;
return
;
}
if
(
unlikely
(
!
netif_running
(
priv
->
net_dev
)))
{
priv
->
ieee
->
stats
.
rx_errors
++
;
priv
->
wstats
.
discard
.
misc
++
;
IPW_DEBUG_DROP
(
"Dropping packet while interface is not up.
\n
"
);
return
;
}
if
(
unlikely
(
priv
->
config
&
CFG_CRC_CHECK
&&
status
->
flags
&
IPW_STATUS_FLAG_CRC_ERROR
))
{
IPW_DEBUG_RX
(
"CRC error in packet. Dropping.
\n
"
);
priv
->
ieee
->
stats
.
rx_errors
++
;
return
;
}
pci_unmap_single
(
priv
->
pci_dev
,
packet
->
dma_addr
,
sizeof
(
struct
ipw2100_rx
),
PCI_DMA_FROMDEVICE
);
memmove
(
packet
->
skb
->
data
+
sizeof
(
struct
ipw_rt_hdr
),
packet
->
skb
->
data
,
status
->
frame_size
);
ipw_rt
=
(
struct
ipw_rt_hdr
*
)
packet
->
skb
->
data
;
ipw_rt
->
rt_hdr
.
it_version
=
PKTHDR_RADIOTAP_VERSION
;
ipw_rt
->
rt_hdr
.
it_pad
=
0
;
/* always good to zero */
ipw_rt
->
rt_hdr
.
it_len
=
sizeof
(
struct
ipw_rt_hdr
);
/* total hdr+data */
ipw_rt
->
rt_hdr
.
it_present
=
1
<<
IEEE80211_RADIOTAP_DBM_ANTSIGNAL
;
ipw_rt
->
rt_dbmsignal
=
status
->
rssi
+
IPW2100_RSSI_TO_DBM
;
skb_put
(
packet
->
skb
,
status
->
frame_size
+
sizeof
(
struct
ipw_rt_hdr
));
if
(
!
ieee80211_rx
(
priv
->
ieee
,
packet
->
skb
,
stats
))
{
priv
->
ieee
->
stats
.
rx_errors
++
;
/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any
(
packet
->
skb
);
packet
->
skb
=
NULL
;
}
/* We need to allocate a new SKB and attach it to the RDB. */
if
(
unlikely
(
ipw2100_alloc_skb
(
priv
,
packet
)))
{
IPW_DEBUG_WARNING
(
"%s: Unable to allocate SKB onto RBD ring - disabling "
"adapter.
\n
"
,
priv
->
net_dev
->
name
);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO
(
"TODO: Shutdown adapter...
\n
"
);
}
/* Update the RDB entry */
priv
->
rx_queue
.
drv
[
i
].
host_addr
=
packet
->
dma_addr
;
}
#endif
static
int
ipw2100_corruption_check
(
struct
ipw2100_priv
*
priv
,
int
i
)
{
struct
ipw2100_status
*
status
=
&
priv
->
status_queue
.
drv
[
i
];
...
...
@@ -2577,7 +2651,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
case
P8023_DATA_VAL
:
#ifdef CONFIG_IPW2100_MONITOR
if
(
priv
->
ieee
->
iw_mode
==
IW_MODE_MONITOR
)
{
isr_rx
(
priv
,
i
,
&
stats
);
isr_rx
_monitor
(
priv
,
i
,
&
stats
);
break
;
}
#endif
...
...
@@ -3882,7 +3956,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
#ifdef CONFIG_IPW2100_MONITOR
case
IW_MODE_MONITOR
:
priv
->
last_mode
=
priv
->
ieee
->
iw_mode
;
priv
->
net_dev
->
type
=
ARPHRD_IEEE80211
;
priv
->
net_dev
->
type
=
ARPHRD_IEEE80211
_RADIOTAP
;
break
;
#endif
/* CONFIG_IPW2100_MONITOR */
}
...
...
@@ -4138,7 +4212,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
IPW_DEBUG_RF_KILL
(
"Manual SW RF Kill set to: RADIO %s
\n
"
,
disable_radio
?
"OFF"
:
"ON"
);
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
disable_radio
)
{
priv
->
status
|=
STATUS_RF_KILL_SW
;
...
...
@@ -4156,7 +4230,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
schedule_reset
(
priv
);
}
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
1
;
}
...
...
@@ -5460,7 +5534,7 @@ static void shim__set_security(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
i
,
force_update
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
goto
done
;
...
...
@@ -5533,7 +5607,7 @@ static void shim__set_security(struct net_device *dev,
if
(
!
(
priv
->
status
&
(
STATUS_ASSOCIATED
|
STATUS_ASSOCIATING
)))
ipw2100_configure_security
(
priv
,
0
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
}
static
int
ipw2100_adapter_setup
(
struct
ipw2100_priv
*
priv
)
...
...
@@ -5657,7 +5731,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
if
(
!
is_valid_ether_addr
(
addr
->
sa_data
))
return
-
EADDRNOTAVAIL
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
priv
->
config
|=
CFG_CUSTOM_MAC
;
memcpy
(
priv
->
mac_addr
,
addr
->
sa_data
,
ETH_ALEN
);
...
...
@@ -5667,12 +5741,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
goto
done
;
priv
->
reset_backoff
=
0
;
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
ipw2100_reset_adapter
(
priv
);
return
0
;
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -6015,8 +6089,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
strcpy
(
priv
->
nick
,
"ipw2100"
);
spin_lock_init
(
&
priv
->
low_lock
);
sema_init
(
&
priv
->
action_sem
,
1
);
sema_init
(
&
priv
->
adapter_sem
,
1
);
mutex_init
(
&
priv
->
action_mutex
);
mutex_init
(
&
priv
->
adapter_mutex
);
init_waitqueue_head
(
&
priv
->
wait_command_queue
);
...
...
@@ -6181,7 +6255,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
* member to call a function that then just turns and calls ipw2100_up.
* net_dev->init is called after name allocation but before the
* notifier chain is called */
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
err
=
register_netdev
(
dev
);
if
(
err
)
{
printk
(
KERN_WARNING
DRV_NAME
...
...
@@ -6217,12 +6291,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
priv
->
status
|=
STATUS_INITIALIZED
;
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
0
;
fail_unlock:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
fail:
if
(
dev
)
{
...
...
@@ -6262,7 +6336,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
struct
net_device
*
dev
;
if
(
priv
)
{
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
priv
->
status
&=
~
STATUS_INITIALIZED
;
...
...
@@ -6277,9 +6351,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
/* Take down the hardware */
ipw2100_down
(
priv
);
/* Release the
semaphore
so that the network subsystem can
/* Release the
mutex
so that the network subsystem can
* complete any needed calls into the driver... */
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
/* Unregister the device first - this results in close()
* being called if the device is open. If we free storage
...
...
@@ -6318,7 +6392,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
IPW_DEBUG_INFO
(
"%s: Going into suspend...
\n
"
,
dev
->
name
);
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
priv
->
status
&
STATUS_INITIALIZED
)
{
/* Take down the device; powers it off, etc. */
ipw2100_down
(
priv
);
...
...
@@ -6331,7 +6405,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
pci_disable_device
(
pci_dev
);
pci_set_power_state
(
pci_dev
,
PCI_D3hot
);
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
0
;
}
...
...
@@ -6345,7 +6419,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
if
(
IPW2100_PM_DISABLED
)
return
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
IPW_DEBUG_INFO
(
"%s: Coming out of suspend...
\n
"
,
dev
->
name
);
...
...
@@ -6371,7 +6445,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
if
(
!
(
priv
->
status
&
STATUS_RF_KILL_SW
))
ipw2100_up
(
priv
,
0
);
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
0
;
}
...
...
@@ -6535,7 +6609,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
if
(
priv
->
ieee
->
iw_mode
==
IW_MODE_INFRA
)
return
-
EOPNOTSUPP
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -6566,7 +6640,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
}
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -6607,7 +6681,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
if
(
wrqu
->
mode
==
priv
->
ieee
->
iw_mode
)
return
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -6630,7 +6704,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
}
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -6812,7 +6886,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
if
(
wrqu
->
ap_addr
.
sa_family
!=
ARPHRD_ETHER
)
return
-
EINVAL
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -6841,7 +6915,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
wrqu
->
ap_addr
.
sa_data
[
5
]
&
0xff
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -6877,7 +6951,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
int
length
=
0
;
int
err
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -6914,7 +6988,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
err
=
ipw2100_set_essid
(
priv
,
essid
,
length
,
0
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -6995,7 +7069,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
u32
rate
;
int
err
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7022,7 +7096,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
IPW_DEBUG_WX
(
"SET Rate -> %04X
\n
"
,
rate
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7042,7 +7116,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
return
0
;
}
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7074,7 +7148,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
IPW_DEBUG_WX
(
"GET Rate -> %d
\n
"
,
wrqu
->
bitrate
.
value
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7089,7 +7163,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
if
(
wrqu
->
rts
.
fixed
==
0
)
return
-
EINVAL
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7109,7 +7183,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
IPW_DEBUG_WX
(
"SET RTS Threshold -> 0x%08X
\n
"
,
value
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7160,7 +7234,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
value
=
wrqu
->
txpower
.
value
;
}
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7171,7 +7245,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
IPW_DEBUG_WX
(
"SET TX Power -> %d
\n
"
,
value
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7263,7 +7337,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
if
(
!
(
wrqu
->
retry
.
flags
&
IW_RETRY_LIMIT
))
return
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7290,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
IPW_DEBUG_WX
(
"SET Both Retry Limits -> %d
\n
"
,
wrqu
->
retry
.
value
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7333,7 +7407,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7348,7 +7422,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
}
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7398,7 +7472,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7431,7 +7505,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
IPW_DEBUG_WX
(
"SET Power Management Mode -> 0x%02X
\n
"
,
priv
->
power_mode
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7735,7 +7809,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
int
enable
=
(
parms
[
0
]
>
0
);
int
err
=
0
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7753,7 +7827,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
err
=
ipw2100_switch_mode
(
priv
,
priv
->
last_mode
);
}
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7776,7 +7850,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
=
0
,
mode
=
*
(
int
*
)
extra
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7788,7 +7862,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
if
(
priv
->
power_mode
!=
mode
)
err
=
ipw2100_set_power_mode
(
priv
,
mode
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7840,7 +7914,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
,
mode
=
*
(
int
*
)
extra
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7858,7 +7932,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
err
=
ipw2100_system_config
(
priv
,
0
);
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -7888,7 +7962,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
struct
ipw2100_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
,
mode
=
*
(
int
*
)
extra
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
if
(
!
(
priv
->
status
&
STATUS_INITIALIZED
))
{
err
=
-
EIO
;
goto
done
;
...
...
@@ -7905,7 +7979,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
err
=
0
;
done:
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
return
err
;
}
...
...
@@ -8210,11 +8284,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
if
(
priv
->
status
&
STATUS_STOPPING
)
return
;
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
IPW_DEBUG_WX
(
"enter
\n
"
);
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
wrqu
.
ap_addr
.
sa_family
=
ARPHRD_ETHER
;
...
...
@@ -8237,7 +8311,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
if
(
!
(
priv
->
status
&
STATUS_ASSOCIATED
))
{
IPW_DEBUG_WX
(
"Configuring ESSID
\n
"
);
down
(
&
priv
->
action_sem
);
mutex_lock
(
&
priv
->
action_mutex
);
/* This is a disassociation event, so kick the firmware to
* look for another AP */
if
(
priv
->
config
&
CFG_STATIC_ESSID
)
...
...
@@ -8245,7 +8319,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
0
);
else
ipw2100_set_essid
(
priv
,
NULL
,
0
,
0
);
up
(
&
priv
->
action_sem
);
mutex_unlock
(
&
priv
->
action_mutex
);
}
wireless_send_event
(
priv
->
net_dev
,
SIOCGIWAP
,
&
wrqu
,
NULL
);
...
...
drivers/net/wireless/ipw2100.h
View file @
2e9ff56e
/******************************************************************************
Copyright(c) 2003 - 200
4
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
...
...
@@ -41,7 +41,12 @@
#include <net/ieee80211.h>
#ifdef CONFIG_IPW2100_MONITOR
#include <net/ieee80211_radiotap.h>
#endif
#include <linux/workqueue.h>
#include <linux/mutex.h>
struct
ipw2100_priv
;
struct
ipw2100_tx_packet
;
...
...
@@ -590,8 +595,8 @@ struct ipw2100_priv {
int
inta_other
;
spinlock_t
low_lock
;
struct
semaphore
action_sem
;
struct
semaphore
adapter_sem
;
struct
mutex
action_mutex
;
struct
mutex
adapter_mutex
;
wait_queue_head_t
wait_command_queue
;
};
...
...
drivers/net/wireless/ipw2200.c
View file @
2e9ff56e
/******************************************************************************
Copyright(c) 2003 - 200
5
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
802.11 status code portion of this file from ethereal-0.10.6:
Copyright 2000, Axis Communications AB
...
...
@@ -33,9 +33,9 @@
#include "ipw2200.h"
#include <linux/version.h>
#define IPW2200_VERSION "git-1.
0.10
"
#define IPW2200_VERSION "git-1.
1.1
"
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 2003-200
5
Intel Corporation"
#define DRV_COPYRIGHT "Copyright(c) 2003-200
6
Intel Corporation"
#define DRV_VERSION IPW2200_VERSION
#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
...
...
@@ -153,12 +153,6 @@ static int init_supported_rates(struct ipw_priv *priv,
static
void
ipw_set_hwcrypto_keys
(
struct
ipw_priv
*
);
static
void
ipw_send_wep_keys
(
struct
ipw_priv
*
,
int
);
static
int
ipw_is_valid_channel
(
struct
ieee80211_device
*
,
u8
);
static
int
ipw_channel_to_index
(
struct
ieee80211_device
*
,
u8
);
static
u8
ipw_freq_to_channel
(
struct
ieee80211_device
*
,
u32
);
static
int
ipw_set_geo
(
struct
ieee80211_device
*
,
const
struct
ieee80211_geo
*
);
static
const
struct
ieee80211_geo
*
ipw_get_geo
(
struct
ieee80211_device
*
);
static
int
snprint_line
(
char
*
buf
,
size_t
count
,
const
u8
*
data
,
u32
len
,
u32
ofs
)
{
...
...
@@ -1654,7 +1648,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
break
;
}
if
(
i
pw
_is_valid_channel
(
priv
->
ieee
,
channel
))
if
(
i
eee80211
_is_valid_channel
(
priv
->
ieee
,
channel
))
priv
->
speed_scan
[
pos
++
]
=
channel
;
else
IPW_WARNING
(
"Skipping invalid channel request: %d
\n
"
,
...
...
@@ -1802,9 +1796,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
}
if
(
inta
&
IPW_INTA_BIT_FATAL_ERROR
)
{
IPW_
ERROR
(
"Firmware error detected. Restarting.
\n
"
);
IPW_
WARNING
(
"Firmware error detected. Restarting.
\n
"
);
if
(
priv
->
error
)
{
IPW_
ERROR
(
"Sysfs 'error' log already exists.
\n
"
);
IPW_
DEBUG_FW
(
"Sysfs 'error' log already exists.
\n
"
);
#ifdef CONFIG_IPW2200_DEBUG
if
(
ipw_debug_level
&
IPW_DL_FW_ERRORS
)
{
struct
ipw_fw_error
*
error
=
...
...
@@ -1817,10 +1811,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
}
else
{
priv
->
error
=
ipw_alloc_error_log
(
priv
);
if
(
priv
->
error
)
IPW_
ERROR
(
"Sysfs 'error' log captured.
\n
"
);
IPW_
DEBUG_FW
(
"Sysfs 'error' log captured.
\n
"
);
else
IPW_
ERROR
(
"Error allocating sysfs 'error' "
"log.
\n
"
);
IPW_
DEBUG_FW
(
"Error allocating sysfs 'error' "
"log.
\n
"
);
#ifdef CONFIG_IPW2200_DEBUG
if
(
ipw_debug_level
&
IPW_DL_FW_ERRORS
)
ipw_dump_error_log
(
priv
,
priv
->
error
);
...
...
@@ -2222,7 +2216,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
static
int
ipw_set_tx_power
(
struct
ipw_priv
*
priv
)
{
const
struct
ieee80211_geo
*
geo
=
i
pw
_get_geo
(
priv
->
ieee
);
const
struct
ieee80211_geo
*
geo
=
i
eee80211
_get_geo
(
priv
->
ieee
);
struct
ipw_tx_power
tx_power
;
s8
max_power
;
int
i
;
...
...
@@ -2835,33 +2829,11 @@ static void ipw_arc_release(struct ipw_priv *priv)
mdelay
(
5
);
}
struct
fw_header
{
u32
version
;
u32
mode
;
};
struct
fw_chunk
{
u32
address
;
u32
length
;
};
#define IPW_FW_MAJOR_VERSION 2
#define IPW_FW_MINOR_VERSION 4
#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
#define IPW_FW_MAJOR(x) (x & 0xff)
#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
"." __stringify(IPW_FW_MINOR_VERSION) "-"
#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
#else
#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
#endif
static
int
ipw_load_ucode
(
struct
ipw_priv
*
priv
,
u8
*
data
,
size_t
len
)
{
int
rc
=
0
,
i
,
addr
;
...
...
@@ -3130,33 +3102,47 @@ static int ipw_reset_nic(struct ipw_priv *priv)
return
rc
;
}
struct
ipw_fw
{
u32
ver
;
u32
boot_size
;
u32
ucode_size
;
u32
fw_size
;
u8
data
[
0
];
};
static
int
ipw_get_fw
(
struct
ipw_priv
*
priv
,
const
struct
firmware
**
f
w
,
const
char
*
name
)
const
struct
firmware
**
ra
w
,
const
char
*
name
)
{
struct
fw_header
*
header
;
struct
ipw_fw
*
fw
;
int
rc
;
/* ask firmware_class module to get the boot firmware off disk */
rc
=
request_firmware
(
f
w
,
name
,
&
priv
->
pci_dev
->
dev
);
rc
=
request_firmware
(
ra
w
,
name
,
&
priv
->
pci_dev
->
dev
);
if
(
rc
<
0
)
{
IPW_ERROR
(
"%s
load
failed: Reason %d
\n
"
,
name
,
rc
);
IPW_ERROR
(
"%s
request_firmware
failed: Reason %d
\n
"
,
name
,
rc
);
return
rc
;
}
header
=
(
struct
fw_header
*
)(
*
fw
)
->
data
;
if
(
IPW_FW_MAJOR
(
le32_to_cpu
(
header
->
version
))
!=
IPW_FW_MAJOR_VERSION
)
{
IPW_ERROR
(
"'%s' firmware version not compatible (%d != %d)
\n
"
,
name
,
IPW_FW_MAJOR
(
le32_to_cpu
(
header
->
version
)),
IPW_FW_MAJOR_VERSION
);
if
((
*
raw
)
->
size
<
sizeof
(
*
fw
))
{
IPW_ERROR
(
"%s is too small (%zd)
\n
"
,
name
,
(
*
raw
)
->
size
);
return
-
EINVAL
;
}
IPW_DEBUG_INFO
(
"Loading firmware '%s' file v%d.%d (%zd bytes)
\n
"
,
fw
=
(
void
*
)(
*
raw
)
->
data
;
if
((
*
raw
)
->
size
<
sizeof
(
*
fw
)
+
fw
->
boot_size
+
fw
->
ucode_size
+
fw
->
fw_size
)
{
IPW_ERROR
(
"%s is too small or corrupt (%zd)
\n
"
,
name
,
(
*
raw
)
->
size
);
return
-
EINVAL
;
}
IPW_DEBUG_INFO
(
"Read firmware '%s' image v%d.%d (%zd bytes)
\n
"
,
name
,
IPW_FW_MAJOR
(
le32_to_cpu
(
header
->
version
))
,
IPW_FW_MINOR
(
le32_to_cpu
(
header
->
version
))
,
(
*
fw
)
->
size
-
sizeof
(
struct
fw_header
));
le32_to_cpu
(
fw
->
ver
)
>>
16
,
le32_to_cpu
(
fw
->
ver
)
&
0xff
,
(
*
raw
)
->
size
-
sizeof
(
*
fw
));
return
0
;
}
...
...
@@ -3196,17 +3182,13 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
#ifdef CONFIG_PM
static
int
fw_loaded
=
0
;
static
const
struct
firmware
*
bootfw
=
NULL
;
static
const
struct
firmware
*
firmware
=
NULL
;
static
const
struct
firmware
*
ucode
=
NULL
;
static
const
struct
firmware
*
raw
=
NULL
;
static
void
free_firmware
(
void
)
{
if
(
fw_loaded
)
{
release_firmware
(
bootfw
);
release_firmware
(
ucode
);
release_firmware
(
firmware
);
bootfw
=
ucode
=
firmware
=
NULL
;
release_firmware
(
raw
);
raw
=
NULL
;
fw_loaded
=
0
;
}
}
...
...
@@ -3217,32 +3199,46 @@ static void free_firmware(void)
static
int
ipw_load
(
struct
ipw_priv
*
priv
)
{
#ifndef CONFIG_PM
const
struct
firmware
*
bootfw
=
NULL
;
const
struct
firmware
*
firmware
=
NULL
;
const
struct
firmware
*
ucode
=
NULL
;
const
struct
firmware
*
raw
=
NULL
;
#endif
char
*
ucode_name
;
char
*
fw_name
;
struct
ipw_fw
*
fw
;
u8
*
boot_img
,
*
ucode_img
,
*
fw_img
;
u8
*
name
=
NULL
;
int
rc
=
0
,
retries
=
3
;
switch
(
priv
->
ieee
->
iw_mode
)
{
case
IW_MODE_ADHOC
:
ucode_name
=
IPW_FW_NAME
(
"ibss_ucode"
);
fw_name
=
IPW_FW_NAME
(
"ibss"
);
name
=
"ipw2200-ibss.fw"
;
break
;
#ifdef CONFIG_IPW2200_MONITOR
case
IW_MODE_MONITOR
:
ucode_name
=
IPW_FW_NAME
(
"sniffer_ucode"
);
fw_name
=
IPW_FW_NAME
(
"sniffer"
);
name
=
"ipw2200-sniffer.fw"
;
break
;
#endif
case
IW_MODE_INFRA
:
ucode_name
=
IPW_FW_NAME
(
"bss_ucode"
);
fw_name
=
IPW_FW_NAME
(
"bss"
);
name
=
"ipw2200-bss.fw"
;
break
;
default:
}
if
(
!
name
)
{
rc
=
-
EINVAL
;
goto
error
;
}
#ifdef CONFIG_PM
if
(
!
fw_loaded
)
{
#endif
rc
=
ipw_get_fw
(
priv
,
&
raw
,
name
);
if
(
rc
<
0
)
goto
error
;
#ifdef CONFIG_PM
}
#endif
fw
=
(
void
*
)
raw
->
data
;
boot_img
=
&
fw
->
data
[
0
];
ucode_img
=
&
fw
->
data
[
fw
->
boot_size
];
fw_img
=
&
fw
->
data
[
fw
->
boot_size
+
fw
->
ucode_size
];
if
(
rc
<
0
)
goto
error
;
...
...
@@ -3275,18 +3271,8 @@ static int ipw_load(struct ipw_priv *priv)
ipw_zero_memory
(
priv
,
IPW_NIC_SRAM_LOWER_BOUND
,
IPW_NIC_SRAM_UPPER_BOUND
-
IPW_NIC_SRAM_LOWER_BOUND
);
#ifdef CONFIG_PM
if
(
!
fw_loaded
)
{
#endif
rc
=
ipw_get_fw
(
priv
,
&
bootfw
,
IPW_FW_NAME
(
"boot"
));
if
(
rc
<
0
)
goto
error
;
#ifdef CONFIG_PM
}
#endif
/* DMA the initial boot firmware into the device */
rc
=
ipw_load_firmware
(
priv
,
bootfw
->
data
+
sizeof
(
struct
fw_header
),
bootfw
->
size
-
sizeof
(
struct
fw_header
));
rc
=
ipw_load_firmware
(
priv
,
boot_img
,
fw
->
boot_size
);
if
(
rc
<
0
)
{
IPW_ERROR
(
"Unable to load boot firmware: %d
\n
"
,
rc
);
goto
error
;
...
...
@@ -3307,19 +3293,8 @@ static int ipw_load(struct ipw_priv *priv)
/* ack fw init done interrupt */
ipw_write32
(
priv
,
IPW_INTA_RW
,
IPW_INTA_BIT_FW_INITIALIZATION_DONE
);
#ifdef CONFIG_PM
if
(
!
fw_loaded
)
{
#endif
rc
=
ipw_get_fw
(
priv
,
&
ucode
,
ucode_name
);
if
(
rc
<
0
)
goto
error
;
#ifdef CONFIG_PM
}
#endif
/* DMA the ucode into the device */
rc
=
ipw_load_ucode
(
priv
,
ucode
->
data
+
sizeof
(
struct
fw_header
),
ucode
->
size
-
sizeof
(
struct
fw_header
));
rc
=
ipw_load_ucode
(
priv
,
ucode_img
,
fw
->
ucode_size
);
if
(
rc
<
0
)
{
IPW_ERROR
(
"Unable to load ucode: %d
\n
"
,
rc
);
goto
error
;
...
...
@@ -3328,20 +3303,8 @@ static int ipw_load(struct ipw_priv *priv)
/* stop nic */
ipw_stop_nic
(
priv
);
#ifdef CONFIG_PM
if
(
!
fw_loaded
)
{
#endif
rc
=
ipw_get_fw
(
priv
,
&
firmware
,
fw_name
);
if
(
rc
<
0
)
goto
error
;
#ifdef CONFIG_PM
}
#endif
/* DMA bss firmware into the device */
rc
=
ipw_load_firmware
(
priv
,
firmware
->
data
+
sizeof
(
struct
fw_header
),
firmware
->
size
-
sizeof
(
struct
fw_header
));
rc
=
ipw_load_firmware
(
priv
,
fw_img
,
fw
->
fw_size
);
if
(
rc
<
0
)
{
IPW_ERROR
(
"Unable to load firmware: %d
\n
"
,
rc
);
goto
error
;
...
...
@@ -3406,9 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
ipw_write32
(
priv
,
IPW_INTA_RW
,
IPW_INTA_MASK_ALL
);
#ifndef CONFIG_PM
release_firmware
(
bootfw
);
release_firmware
(
ucode
);
release_firmware
(
firmware
);
release_firmware
(
raw
);
#endif
return
0
;
...
...
@@ -3418,15 +3379,11 @@ static int ipw_load(struct ipw_priv *priv)
priv
->
rxq
=
NULL
;
}
ipw_tx_queue_free
(
priv
);
if
(
bootfw
)
release_firmware
(
bootfw
);
if
(
ucode
)
release_firmware
(
ucode
);
if
(
firmware
)
release_firmware
(
firmware
);
if
(
raw
)
release_firmware
(
raw
);
#ifdef CONFIG_PM
fw_loaded
=
0
;
bootfw
=
ucode
=
firmware
=
NULL
;
raw
=
NULL
;
#endif
return
rc
;
...
...
@@ -4547,10 +4504,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
if
(
notif
->
size
==
sizeof
(
*
x
))
{
IPW_DEBUG
(
IPW_DL_NOTIF
|
IPW_DL_STATE
,
"link deterioration: '%s' "
MAC_FMT
"
\n
"
,
escape_essid
(
priv
->
essid
,
priv
->
essid_len
),
MAC_ARG
(
priv
->
bssid
));
"link deterioration: type %d, cnt %d
\n
"
,
x
->
silence_notification_type
,
x
->
silence_count
);
memcpy
(
&
priv
->
last_link_deterioration
,
x
,
sizeof
(
*
x
));
}
else
{
...
...
@@ -5533,15 +5489,6 @@ static int ipw_best_network(struct ipw_priv *priv,
return
0
;
}
if
(
priv
->
ieee
->
wpa_enabled
&&
network
->
wpa_ie_len
==
0
&&
network
->
rsn_ie_len
==
0
)
{
IPW_DEBUG_ASSOC
(
"Network '%s ("
MAC_FMT
")' excluded "
"because of WPA capability mismatch.
\n
"
,
escape_essid
(
network
->
ssid
,
network
->
ssid_len
),
MAC_ARG
(
network
->
bssid
));
return
0
;
}
if
((
priv
->
config
&
CFG_STATIC_BSSID
)
&&
memcmp
(
network
->
bssid
,
priv
->
bssid
,
ETH_ALEN
))
{
IPW_DEBUG_ASSOC
(
"Network '%s ("
MAC_FMT
")' excluded "
...
...
@@ -5562,7 +5509,7 @@ static int ipw_best_network(struct ipw_priv *priv,
}
/* Filter out invalid channel in current GEO */
if
(
!
i
pw
_is_valid_channel
(
priv
->
ieee
,
network
->
channel
))
{
if
(
!
i
eee80211
_is_valid_channel
(
priv
->
ieee
,
network
->
channel
))
{
IPW_DEBUG_ASSOC
(
"Network '%s ("
MAC_FMT
")' excluded "
"because of invalid channel in current GEO
\n
"
,
escape_essid
(
network
->
ssid
,
network
->
ssid_len
),
...
...
@@ -5607,7 +5554,7 @@ static int ipw_best_network(struct ipw_priv *priv,
static
void
ipw_adhoc_create
(
struct
ipw_priv
*
priv
,
struct
ieee80211_network
*
network
)
{
const
struct
ieee80211_geo
*
geo
=
i
pw
_get_geo
(
priv
->
ieee
);
const
struct
ieee80211_geo
*
geo
=
i
eee80211
_get_geo
(
priv
->
ieee
);
int
i
;
/*
...
...
@@ -5622,10 +5569,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
* FW fatal error.
*
*/
switch
(
i
pw
_is_valid_channel
(
priv
->
ieee
,
priv
->
channel
))
{
switch
(
i
eee80211
_is_valid_channel
(
priv
->
ieee
,
priv
->
channel
))
{
case
IEEE80211_52GHZ_BAND
:
network
->
mode
=
IEEE_A
;
i
=
i
pw
_channel_to_index
(
priv
->
ieee
,
priv
->
channel
);
i
=
i
eee80211
_channel_to_index
(
priv
->
ieee
,
priv
->
channel
);
if
(
i
==
-
1
)
BUG
();
if
(
geo
->
a
[
i
].
flags
&
IEEE80211_CH_PASSIVE_ONLY
)
{
...
...
@@ -5639,7 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
network
->
mode
=
IEEE_G
;
else
network
->
mode
=
IEEE_B
;
i
=
i
pw
_channel_to_index
(
priv
->
ieee
,
priv
->
channel
);
i
=
i
eee80211
_channel_to_index
(
priv
->
ieee
,
priv
->
channel
);
if
(
i
==
-
1
)
BUG
();
if
(
geo
->
bg
[
i
].
flags
&
IEEE80211_CH_PASSIVE_ONLY
)
{
...
...
@@ -5963,7 +5910,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
const
struct
ieee80211_geo
*
geo
;
int
i
;
geo
=
i
pw
_get_geo
(
priv
->
ieee
);
geo
=
i
eee80211
_get_geo
(
priv
->
ieee
);
if
(
priv
->
ieee
->
freq_band
&
IEEE80211_52GHZ_BAND
)
{
int
start
=
channel_index
;
...
...
@@ -6023,7 +5970,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
channel_index
++
;
scan
->
channels_list
[
channel_index
]
=
channel
;
index
=
i
pw
_channel_to_index
(
priv
->
ieee
,
channel
);
i
eee80211
_channel_to_index
(
priv
->
ieee
,
channel
);
ipw_set_scan_type
(
scan
,
channel_index
,
geo
->
bg
[
index
].
flags
&
...
...
@@ -6105,7 +6052,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
u8
channel
;
u8
band
=
0
;
switch
(
i
pw
_is_valid_channel
(
priv
->
ieee
,
priv
->
channel
))
{
switch
(
i
eee80211
_is_valid_channel
(
priv
->
ieee
,
priv
->
channel
))
{
case
IEEE80211_52GHZ_BAND
:
band
=
(
u8
)
(
IPW_A_MODE
<<
6
)
|
1
;
channel
=
priv
->
channel
;
...
...
@@ -6568,7 +6515,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
* get the modulation type of the current network or
* the card current mode
*/
u8
ipw_qos_current_mode
(
struct
ipw_priv
*
priv
)
static
u8
ipw_qos_current_mode
(
struct
ipw_priv
*
priv
)
{
u8
mode
=
0
;
...
...
@@ -7815,12 +7762,10 @@ static void ipw_rx(struct ipw_priv *priv)
while
(
i
!=
r
)
{
rxb
=
priv
->
rxq
->
queue
[
i
];
#ifdef CONFIG_IPW2200_DEBUG
if
(
unlikely
(
rxb
==
NULL
))
{
printk
(
KERN_CRIT
"Queue not allocated!
\n
"
);
break
;
}
#endif
priv
->
rxq
->
queue
[
i
]
=
NULL
;
pci_dma_sync_single_for_cpu
(
priv
->
pci_dev
,
rxb
->
dma_addr
,
...
...
@@ -7839,7 +7784,8 @@ static void ipw_rx(struct ipw_priv *priv)
le16_to_cpu
(
pkt
->
u
.
frame
.
rssi_dbm
)
-
IPW_RSSI_TO_DBM
,
.
signal
=
le16_to_cpu
(
pkt
->
u
.
frame
.
signal
),
le16_to_cpu
(
pkt
->
u
.
frame
.
rssi_dbm
)
-
IPW_RSSI_TO_DBM
+
0x100
,
.
noise
=
le16_to_cpu
(
pkt
->
u
.
frame
.
noise
),
.
rate
=
pkt
->
u
.
frame
.
rate
,
...
...
@@ -7903,7 +7849,8 @@ static void ipw_rx(struct ipw_priv *priv)
le16_to_cpu
(
pkt
->
u
.
frame
.
length
));
if
(
le16_to_cpu
(
pkt
->
u
.
frame
.
length
)
<
frame_hdr_len
(
header
))
{
ieee80211_get_hdrlen
(
le16_to_cpu
(
header
->
frame_ctl
)))
{
IPW_DEBUG_DROP
(
"Received packet is too small. "
"Dropping.
\n
"
);
...
...
@@ -7993,7 +7940,14 @@ static void ipw_rx(struct ipw_priv *priv)
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
static
int
ipw_sw_reset
(
struct
ipw_priv
*
priv
,
int
init
)
/**
* ipw_sw_reset
* @option: options to control different reset behaviour
* 0 = reset everything except the 'disable' module_param
* 1 = reset everything and print out driver info (for probe only)
* 2 = reset everything
*/
static
int
ipw_sw_reset
(
struct
ipw_priv
*
priv
,
int
option
)
{
int
band
,
modulation
;
int
old_mode
=
priv
->
ieee
->
iw_mode
;
...
...
@@ -8020,7 +7974,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
priv
->
essid_len
=
0
;
memset
(
priv
->
essid
,
0
,
IW_ESSID_MAX_SIZE
);
if
(
disable
)
{
if
(
disable
&&
option
)
{
priv
->
status
|=
STATUS_RF_KILL_SW
;
IPW_DEBUG_INFO
(
"Radio disabled.
\n
"
);
}
...
...
@@ -8072,7 +8026,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
if
((
priv
->
pci_dev
->
device
==
0x4223
)
||
(
priv
->
pci_dev
->
device
==
0x4224
))
{
if
(
init
)
if
(
option
==
1
)
printk
(
KERN_INFO
DRV_NAME
": Detected Intel PRO/Wireless 2915ABG Network "
"Connection
\n
"
);
...
...
@@ -8083,7 +8037,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
priv
->
adapter
=
IPW_2915ABG
;
priv
->
ieee
->
mode
=
IEEE_A
|
IEEE_G
|
IEEE_B
;
}
else
{
if
(
init
)
if
(
option
==
1
)
printk
(
KERN_INFO
DRV_NAME
": Detected Intel PRO/Wireless 2200BG Network "
"Connection
\n
"
);
...
...
@@ -8200,7 +8154,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
ipw_priv
*
priv
=
ieee80211_priv
(
dev
);
const
struct
ieee80211_geo
*
geo
=
i
pw
_get_geo
(
priv
->
ieee
);
const
struct
ieee80211_geo
*
geo
=
i
eee80211
_get_geo
(
priv
->
ieee
);
struct
iw_freq
*
fwrq
=
&
wrqu
->
freq
;
int
ret
=
0
,
i
;
u8
channel
,
flags
;
...
...
@@ -8215,17 +8169,17 @@ static int ipw_wx_set_freq(struct net_device *dev,
}
/* if setting by freq convert to channel */
if
(
fwrq
->
e
==
1
)
{
channel
=
i
pw
_freq_to_channel
(
priv
->
ieee
,
fwrq
->
m
);
channel
=
i
eee80211
_freq_to_channel
(
priv
->
ieee
,
fwrq
->
m
);
if
(
channel
==
0
)
return
-
EINVAL
;
}
else
channel
=
fwrq
->
m
;
if
(
!
(
band
=
i
pw
_is_valid_channel
(
priv
->
ieee
,
channel
)))
if
(
!
(
band
=
i
eee80211
_is_valid_channel
(
priv
->
ieee
,
channel
)))
return
-
EINVAL
;
if
(
priv
->
ieee
->
iw_mode
==
IW_MODE_ADHOC
)
{
i
=
i
pw
_channel_to_index
(
priv
->
ieee
,
channel
);
i
=
i
eee80211
_channel_to_index
(
priv
->
ieee
,
channel
);
if
(
i
==
-
1
)
return
-
EINVAL
;
...
...
@@ -8353,7 +8307,7 @@ static int ipw_wx_get_range(struct net_device *dev,
{
struct
ipw_priv
*
priv
=
ieee80211_priv
(
dev
);
struct
iw_range
*
range
=
(
struct
iw_range
*
)
extra
;
const
struct
ieee80211_geo
*
geo
=
i
pw
_get_geo
(
priv
->
ieee
);
const
struct
ieee80211_geo
*
geo
=
i
eee80211
_get_geo
(
priv
->
ieee
);
int
i
=
0
,
j
;
wrqu
->
data
.
length
=
sizeof
(
*
range
);
...
...
@@ -8365,7 +8319,7 @@ static int ipw_wx_get_range(struct net_device *dev,
range
->
max_qual
.
qual
=
100
;
/* TODO: Find real max RSSI and stick here */
range
->
max_qual
.
level
=
0
;
range
->
max_qual
.
noise
=
priv
->
ieee
->
worst_rssi
+
0x10
0
;
range
->
max_qual
.
noise
=
0
;
range
->
max_qual
.
updated
=
7
;
/* Updated all three */
range
->
avg_qual
.
qual
=
70
;
...
...
@@ -8395,20 +8349,28 @@ static int ipw_wx_get_range(struct net_device *dev,
i
=
0
;
if
(
priv
->
ieee
->
mode
&
(
IEEE_B
|
IEEE_G
))
{
for
(
j
=
0
;
j
<
geo
->
bg_channels
&&
i
<
IW_MAX_FREQUENCIES
;
i
++
,
j
++
)
{
for
(
j
=
0
;
j
<
geo
->
bg_channels
&&
i
<
IW_MAX_FREQUENCIES
;
j
++
)
{
if
((
priv
->
ieee
->
iw_mode
==
IW_MODE_ADHOC
)
&&
(
geo
->
bg
[
j
].
flags
&
IEEE80211_CH_PASSIVE_ONLY
))
continue
;
range
->
freq
[
i
].
i
=
geo
->
bg
[
j
].
channel
;
range
->
freq
[
i
].
m
=
geo
->
bg
[
j
].
freq
*
100000
;
range
->
freq
[
i
].
e
=
1
;
i
++
;
}
}
if
(
priv
->
ieee
->
mode
&
IEEE_A
)
{
for
(
j
=
0
;
j
<
geo
->
a_channels
&&
i
<
IW_MAX_FREQUENCIES
;
i
++
,
j
++
)
{
for
(
j
=
0
;
j
<
geo
->
a_channels
&&
i
<
IW_MAX_FREQUENCIES
;
j
++
)
{
if
((
priv
->
ieee
->
iw_mode
==
IW_MODE_ADHOC
)
&&
(
geo
->
a
[
j
].
flags
&
IEEE80211_CH_PASSIVE_ONLY
))
continue
;
range
->
freq
[
i
].
i
=
geo
->
a
[
j
].
channel
;
range
->
freq
[
i
].
m
=
geo
->
a
[
j
].
freq
*
100000
;
range
->
freq
[
i
].
e
=
1
;
i
++
;
}
}
...
...
@@ -8609,6 +8571,52 @@ static int ipw_wx_get_nick(struct net_device *dev,
return
0
;
}
static
int
ipw_wx_set_sens
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
ipw_priv
*
priv
=
ieee80211_priv
(
dev
);
int
err
=
0
;
IPW_DEBUG_WX
(
"Setting roaming threshold to %d
\n
"
,
wrqu
->
sens
.
value
);
IPW_DEBUG_WX
(
"Setting disassociate threshold to %d
\n
"
,
3
*
wrqu
->
sens
.
value
);
mutex_lock
(
&
priv
->
mutex
);
if
(
wrqu
->
sens
.
fixed
==
0
)
{
priv
->
roaming_threshold
=
IPW_MB_ROAMING_THRESHOLD_DEFAULT
;
priv
->
disassociate_threshold
=
IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT
;
goto
out
;
}
if
((
wrqu
->
sens
.
value
>
IPW_MB_ROAMING_THRESHOLD_MAX
)
||
(
wrqu
->
sens
.
value
<
IPW_MB_ROAMING_THRESHOLD_MIN
))
{
err
=
-
EINVAL
;
goto
out
;
}
priv
->
roaming_threshold
=
wrqu
->
sens
.
value
;
priv
->
disassociate_threshold
=
3
*
wrqu
->
sens
.
value
;
out:
mutex_unlock
(
&
priv
->
mutex
);
return
err
;
}
static
int
ipw_wx_get_sens
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
ipw_priv
*
priv
=
ieee80211_priv
(
dev
);
mutex_lock
(
&
priv
->
mutex
);
wrqu
->
sens
.
fixed
=
1
;
wrqu
->
sens
.
value
=
priv
->
roaming_threshold
;
mutex_unlock
(
&
priv
->
mutex
);
IPW_DEBUG_WX
(
"GET roaming threshold -> %s %d
\n
"
,
wrqu
->
power
.
disabled
?
"OFF"
:
"ON"
,
wrqu
->
power
.
value
);
return
0
;
}
static
int
ipw_wx_set_rate
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
...
...
@@ -9395,7 +9403,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
mutex_lock
(
&
priv
->
mutex
);
ret
=
ipw_sw_reset
(
priv
,
0
);
ret
=
ipw_sw_reset
(
priv
,
2
);
if
(
!
ret
)
{
free_firmware
();
ipw_adapter_restart
(
priv
);
...
...
@@ -9430,6 +9438,8 @@ static iw_handler ipw_wx_handlers[] = {
IW_IOCTL
(
SIOCGIWFREQ
)
=
ipw_wx_get_freq
,
IW_IOCTL
(
SIOCSIWMODE
)
=
ipw_wx_set_mode
,
IW_IOCTL
(
SIOCGIWMODE
)
=
ipw_wx_get_mode
,
IW_IOCTL
(
SIOCSIWSENS
)
=
ipw_wx_set_sens
,
IW_IOCTL
(
SIOCGIWSENS
)
=
ipw_wx_get_sens
,
IW_IOCTL
(
SIOCGIWRANGE
)
=
ipw_wx_get_range
,
IW_IOCTL
(
SIOCSIWAP
)
=
ipw_wx_set_wap
,
IW_IOCTL
(
SIOCGIWAP
)
=
ipw_wx_get_wap
,
...
...
@@ -9575,7 +9585,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
wstats
->
qual
.
level
=
average_value
(
&
priv
->
average_rssi
);
wstats
->
qual
.
noise
=
average_value
(
&
priv
->
average_noise
);
wstats
->
qual
.
updated
=
IW_QUAL_QUAL_UPDATED
|
IW_QUAL_LEVEL_UPDATED
|
IW_QUAL_NOISE_UPDATED
;
IW_QUAL_NOISE_UPDATED
|
IW_QUAL_DBM
;
wstats
->
miss
.
beacon
=
average_value
(
&
priv
->
average_missed_beacons
);
wstats
->
discard
.
retries
=
priv
->
last_tx_failures
;
...
...
@@ -9601,12 +9611,13 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
sys_config
->
disable_unicast_decryption
=
1
;
sys_config
->
exclude_multicast_unencrypted
=
0
;
sys_config
->
disable_multicast_decryption
=
1
;
sys_config
->
antenna_diversity
=
CFG_SYS_ANTENNA_
BOTH
;
sys_config
->
antenna_diversity
=
CFG_SYS_ANTENNA_
SLOW_DIV
;
sys_config
->
pass_crc_to_host
=
0
;
/* TODO: See if 1 gives us FCS */
sys_config
->
dot11g_auto_detection
=
0
;
sys_config
->
enable_cts_to_self
=
0
;
sys_config
->
bt_coexist_collision_thr
=
0
;
sys_config
->
pass_noise_stats_to_host
=
1
;
//1 -- fix for 256
sys_config
->
silence_threshold
=
0x1e
;
}
static
int
ipw_net_open
(
struct
net_device
*
dev
)
...
...
@@ -9654,11 +9665,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
u16
remaining_bytes
;
int
fc
;
/* If there isn't room in the queue, we return busy and let the
* network stack requeue the packet for us */
if
(
ipw_queue_space
(
q
)
<
q
->
high_mark
)
return
NETDEV_TX_BUSY
;
switch
(
priv
->
ieee
->
iw_mode
)
{
case
IW_MODE_ADHOC
:
hdr_len
=
IEEE80211_3ADDR_LEN
;
...
...
@@ -9824,6 +9830,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
q
->
first_empty
=
ipw_queue_inc_wrap
(
q
->
first_empty
,
q
->
n_bd
);
ipw_write32
(
priv
,
q
->
reg_w
,
q
->
first_empty
);
if
(
ipw_queue_space
(
q
)
<
q
->
high_mark
)
netif_stop_queue
(
priv
->
net_dev
);
return
NETDEV_TX_OK
;
drop:
...
...
@@ -9963,9 +9972,8 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
return
-
EINVAL
;
mutex_lock
(
&
p
->
mutex
);
memcpy
(
&
p
->
eeprom
[
eeprom
->
offset
],
bytes
,
eeprom
->
len
);
for
(
i
=
IPW_EEPROM_DATA
;
i
<
IPW_EEPROM_DATA
+
IPW_EEPROM_IMAGE_SIZE
;
i
++
)
ipw_write8
(
p
,
i
,
p
->
eeprom
[
i
]);
for
(
i
=
0
;
i
<
IPW_EEPROM_IMAGE_SIZE
;
i
++
)
ipw_write8
(
p
,
i
+
IPW_EEPROM_DATA
,
p
->
eeprom
[
i
]);
mutex_unlock
(
&
p
->
mutex
);
return
0
;
}
...
...
@@ -10370,6 +10378,9 @@ static int ipw_config(struct ipw_priv *priv)
* not intended for resale of the above mentioned Intel adapters has
* not been tested.
*
* Remember to update the table in README.ipw2200 when changing this
* table.
*
*/
static
const
struct
ieee80211_geo
ipw_geos
[]
=
{
{
/* Restricted */
...
...
@@ -10617,96 +10628,6 @@ static const struct ieee80211_geo ipw_geos[] = {
}
};
/* GEO code borrowed from ieee80211_geo.c */
static
int
ipw_is_valid_channel
(
struct
ieee80211_device
*
ieee
,
u8
channel
)
{
int
i
;
/* Driver needs to initialize the geography map before using
* these helper functions */
BUG_ON
(
ieee
->
geo
.
bg_channels
==
0
&&
ieee
->
geo
.
a_channels
==
0
);
if
(
ieee
->
freq_band
&
IEEE80211_24GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
bg_channels
;
i
++
)
/* NOTE: If G mode is currently supported but
* this is a B only channel, we don't see it
* as valid. */
if
((
ieee
->
geo
.
bg
[
i
].
channel
==
channel
)
&&
(
!
(
ieee
->
mode
&
IEEE_G
)
||
!
(
ieee
->
geo
.
bg
[
i
].
flags
&
IEEE80211_CH_B_ONLY
)))
return
IEEE80211_24GHZ_BAND
;
if
(
ieee
->
freq_band
&
IEEE80211_52GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
a_channels
;
i
++
)
if
(
ieee
->
geo
.
a
[
i
].
channel
==
channel
)
return
IEEE80211_52GHZ_BAND
;
return
0
;
}
static
int
ipw_channel_to_index
(
struct
ieee80211_device
*
ieee
,
u8
channel
)
{
int
i
;
/* Driver needs to initialize the geography map before using
* these helper functions */
BUG_ON
(
ieee
->
geo
.
bg_channels
==
0
&&
ieee
->
geo
.
a_channels
==
0
);
if
(
ieee
->
freq_band
&
IEEE80211_24GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
bg_channels
;
i
++
)
if
(
ieee
->
geo
.
bg
[
i
].
channel
==
channel
)
return
i
;
if
(
ieee
->
freq_band
&
IEEE80211_52GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
a_channels
;
i
++
)
if
(
ieee
->
geo
.
a
[
i
].
channel
==
channel
)
return
i
;
return
-
1
;
}
static
u8
ipw_freq_to_channel
(
struct
ieee80211_device
*
ieee
,
u32
freq
)
{
int
i
;
/* Driver needs to initialize the geography map before using
* these helper functions */
BUG_ON
(
ieee
->
geo
.
bg_channels
==
0
&&
ieee
->
geo
.
a_channels
==
0
);
freq
/=
100000
;
if
(
ieee
->
freq_band
&
IEEE80211_24GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
bg_channels
;
i
++
)
if
(
ieee
->
geo
.
bg
[
i
].
freq
==
freq
)
return
ieee
->
geo
.
bg
[
i
].
channel
;
if
(
ieee
->
freq_band
&
IEEE80211_52GHZ_BAND
)
for
(
i
=
0
;
i
<
ieee
->
geo
.
a_channels
;
i
++
)
if
(
ieee
->
geo
.
a
[
i
].
freq
==
freq
)
return
ieee
->
geo
.
a
[
i
].
channel
;
return
0
;
}
static
int
ipw_set_geo
(
struct
ieee80211_device
*
ieee
,
const
struct
ieee80211_geo
*
geo
)
{
memcpy
(
ieee
->
geo
.
name
,
geo
->
name
,
3
);
ieee
->
geo
.
name
[
3
]
=
'\0'
;
ieee
->
geo
.
bg_channels
=
geo
->
bg_channels
;
ieee
->
geo
.
a_channels
=
geo
->
a_channels
;
memcpy
(
ieee
->
geo
.
bg
,
geo
->
bg
,
geo
->
bg_channels
*
sizeof
(
struct
ieee80211_channel
));
memcpy
(
ieee
->
geo
.
a
,
geo
->
a
,
ieee
->
geo
.
a_channels
*
sizeof
(
struct
ieee80211_channel
));
return
0
;
}
static
const
struct
ieee80211_geo
*
ipw_get_geo
(
struct
ieee80211_device
*
ieee
)
{
return
&
ieee
->
geo
;
}
#define MAX_HW_RESTARTS 5
static
int
ipw_up
(
struct
ipw_priv
*
priv
)
{
...
...
@@ -10753,14 +10674,11 @@ static int ipw_up(struct ipw_priv *priv)
priv
->
eeprom
[
EEPROM_COUNTRY_CODE
+
2
]);
j
=
0
;
}
if
(
i
pw
_set_geo
(
priv
->
ieee
,
&
ipw_geos
[
j
]))
{
if
(
i
eee80211
_set_geo
(
priv
->
ieee
,
&
ipw_geos
[
j
]))
{
IPW_WARNING
(
"Could not set geography."
);
return
0
;
}
IPW_DEBUG_INFO
(
"Geography %03d [%s] detected.
\n
"
,
j
,
priv
->
ieee
->
geo
.
name
);
if
(
priv
->
status
&
STATUS_RF_KILL_SW
)
{
IPW_WARNING
(
"Radio disabled by module parameter.
\n
"
);
return
0
;
...
...
@@ -11081,6 +10999,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
IPW_ERROR
(
"failed to register network device
\n
"
);
goto
out_remove_sysfs
;
}
printk
(
KERN_INFO
DRV_NAME
": Detected geography %s (%d 802.11bg "
"channels, %d 802.11a channels)
\n
"
,
priv
->
ieee
->
geo
.
name
,
priv
->
ieee
->
geo
.
bg_channels
,
priv
->
ieee
->
geo
.
a_channels
);
return
0
;
out_remove_sysfs:
...
...
@@ -11271,8 +11195,10 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
module_param
(
led
,
int
,
0444
);
MODULE_PARM_DESC
(
led
,
"enable led control on some systems (default 0 off)
\n
"
);
#ifdef CONFIG_IPW2200_DEBUG
module_param
(
debug
,
int
,
0444
);
MODULE_PARM_DESC
(
debug
,
"debug output mask"
);
#endif
module_param
(
channel
,
int
,
0444
);
MODULE_PARM_DESC
(
channel
,
"channel to limit associate to (default 0 [ANY])"
);
...
...
drivers/net/wireless/ipw2200.h
View file @
2e9ff56e
/******************************************************************************
Copyright(c) 2003 - 200
5
Intel Corporation. All rights reserved.
Copyright(c) 2003 - 200
6
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
...
...
@@ -246,8 +246,10 @@ enum connection_manager_assoc_states {
#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
#define IPW_MB_
DISASSOCIATE_THRESHOLD_DEFAULT 24
#define IPW_MB_
ROAMING_THRESHOLD_MIN 1
#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
#define IPW_MB_ROAMING_THRESHOLD_MAX 30
#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 3*IPW_MB_ROAMING_THRESHOLD_DEFAULT
#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300
#define MACADRR_BYTE_LEN 6
...
...
@@ -618,13 +620,16 @@ struct notif_tgi_tx_key {
u8
reserved
;
}
__attribute__
((
packed
));
#define SILENCE_OVER_THRESH (1)
#define SILENCE_UNDER_THRESH (2)
struct
notif_link_deterioration
{
struct
ipw_cmd_stats
stats
;
u8
rate
;
u8
modulation
;
struct
rate_histogram
histogram
;
u8
reserved1
;
u16
reserved2
;
u8
silence_notification_type
;
/* SILENCE_OVER/UNDER_THRESH */
u16
silence_count
;
}
__attribute__
((
packed
));
struct
notif_association
{
...
...
@@ -782,7 +787,7 @@ struct ipw_sys_config {
u8
enable_cts_to_self
;
u8
enable_multicast_filtering
;
u8
bt_coexist_collision_thr
;
u8
reserved2
;
u8
silence_threshold
;
u8
accept_all_mgmt_bcpr
;
u8
accept_all_mgtm_frames
;
u8
pass_noise_stats_to_host
;
...
...
@@ -1892,6 +1897,7 @@ struct ipw_cmd_log {
#define CFG_SYS_ANTENNA_BOTH 0x00
/* NIC selects best antenna */
#define CFG_SYS_ANTENNA_A 0x01
/* force antenna A */
#define CFG_SYS_ANTENNA_B 0x03
/* force antenna B */
#define CFG_SYS_ANTENNA_SLOW_DIV 0x02
/* consider background noise */
/*
* The definitions below were lifted off the ipw2100 driver, which only
...
...
@@ -1907,27 +1913,4 @@ struct ipw_cmd_log {
#define IPW_MAX_CONFIG_RETRIES 10
static
inline
u32
frame_hdr_len
(
struct
ieee80211_hdr_4addr
*
hdr
)
{
u32
retval
;
u16
fc
;
retval
=
sizeof
(
struct
ieee80211_hdr_3addr
);
fc
=
le16_to_cpu
(
hdr
->
frame_ctl
);
/*
* Function ToDS FromDS
* IBSS 0 0
* To AP 1 0
* From AP 0 1
* WDS (bridge) 1 1
*
* Only WDS frames use Address4 among them. --YZ
*/
if
(
!
(
fc
&
IEEE80211_FCTL_TODS
)
||
!
(
fc
&
IEEE80211_FCTL_FROMDS
))
retval
-=
ETH_ALEN
;
return
retval
;
}
#endif
/* __ipw2200_h__ */
net/ieee80211/ieee80211_rx.c
View file @
2e9ff56e
...
...
@@ -1345,7 +1345,19 @@ static void update_network(struct ieee80211_network *dst,
ieee80211_network_reset
(
dst
);
dst
->
ibss_dfs
=
src
->
ibss_dfs
;
memcpy
(
&
dst
->
stats
,
&
src
->
stats
,
sizeof
(
struct
ieee80211_rx_stats
));
/* We only update the statistics if they were created by receiving
* the network information on the actual channel the network is on.
*
* This keeps beacons received on neighbor channels from bringing
* down the signal level of an AP. */
if
(
dst
->
channel
==
src
->
stats
.
received_channel
)
memcpy
(
&
dst
->
stats
,
&
src
->
stats
,
sizeof
(
struct
ieee80211_rx_stats
));
else
IEEE80211_DEBUG_SCAN
(
"Network "
MAC_FMT
" info received "
"off channel (%d vs. %d)
\n
"
,
MAC_ARG
(
src
->
bssid
),
dst
->
channel
,
src
->
stats
.
received_channel
);
dst
->
capability
=
src
->
capability
;
memcpy
(
dst
->
rates
,
src
->
rates
,
src
->
rates_len
);
dst
->
rates_len
=
src
->
rates_len
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment