ieee80211_local has a separate class_device. That means it has reference
counting independent of master net_device and can be freed at a different
time, therefore these two structures cannot be allocated together.
Solve this by adding ieee80211_ptr pointer to net_device structure (similar
to other pointers already presented there) and using it as a pointer to
independently allocated ieee80211_local.
This also allows is_ieee80211_device function to be nice finally.
Signed-off-by: Jiri Benc [EMAIL PROTECTED]
---
include/linux/netdevice.h|1
net/d80211/ieee80211.c | 100 +-
net/d80211/ieee80211_dev.c | 17 +++
net/d80211/ieee80211_i.h |9 +++-
net/d80211/ieee80211_iface.c | 20
net/d80211/ieee80211_ioctl.c | 92 +++
net/d80211/ieee80211_proc.c |6 +--
net/d80211/ieee80211_scan.c | 10 ++--
net/d80211/ieee80211_sta.c | 58
net/d80211/ieee80211_sysfs.c | 26 ---
net/d80211/rate_control.c|4 +-
net/d80211/rate_control.h|4 +-
net/d80211/wme.c | 26 +--
13 files changed, 206 insertions(+), 167 deletions(-)
3085d33e38881f0987329c4258514f60ffe824af
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f4169bb..037e63a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -371,6 +371,7 @@ #define NETIF_F_UFO 8192
void*ip6_ptr; /* IPv6 specific data */
void*ec_ptr;/* Econet specific data */
void*ax25_ptr; /* AX.25 specific data */
+ void*ieee80211_ptr; /* IEEE 802.11 specific data */
/*
* Cache line mostly used on receive path (including eth_type_trans())
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 9724a49..4fc2e7d 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -110,7 +110,7 @@ static int rate_list_match(int *rate_lis
void ieee80211_prepare_rates(struct net_device *dev)
{
- struct ieee80211_local *local = dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
int i;
for (i = 0; i local-num_curr_rates; i++) {
@@ -1059,7 +1059,7 @@ __ieee80211_tx_prepare(struct ieee80211_
struct net_device *dev,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb-data;
int hdrlen;
@@ -1095,12 +1095,9 @@ __ieee80211_tx_prepare(struct ieee80211_
}
-/* FIXME: This is not nice but currently there doesn't exist more elegant way
*/
static int inline is_ieee80211_device(struct net_device *dev)
{
- return (dev-wireless_handlers ==
- (struct iw_handler_def *) ieee80211_iw_handler_def) ||
- (dev-hard_start_xmit == ieee80211_mgmt_start_xmit);
+ return (dev-ieee80211_ptr != NULL);
}
/* Device in tx-dev has a reference added; use dev_put(tx-dev) when
@@ -1131,7 +1128,7 @@ static void inline ieee80211_tx_prepare(
static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_tx_control *control, int mgmt)
{
- struct ieee80211_local *local = dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
struct sta_info *sta;
ieee80211_tx_handler *handler;
struct ieee80211_txrx_data tx;
@@ -1307,7 +1304,7 @@ #endif
static int ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
-struct ieee80211_local *local = (struct ieee80211_local *) dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
struct ieee80211_tx_packet_data *pkt_data;
struct ieee80211_sub_if_data *sdata;
int ret = 1, head_need;
@@ -1613,7 +1610,7 @@ static void ieee80211_beacon_add_tim(str
struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
struct sk_buff *skb;
struct net_device *bdev;
struct ieee80211_sub_if_data *sdata = NULL;
@@ -1690,7 +1687,7 @@ struct sk_buff *
ieee80211_get_buffered_bc(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev-priv;
+ struct ieee80211_local *local = dev-ieee80211_ptr;
struct sk_buff *skb;
struct sta_info *sta;
ieee80211_tx_handler *handler;
@@ -1754,7 +1751,7 @@ ieee80211_get_buffered_bc(struct net_dev
int ieee80211_if_config(struct net_device *dev)
{