Changes to the ieee80211 layer: - fixes a serious alignment problem of the driver's private data - makes the drivers use the ieee80211_device instead of the net_device where appropriate (will ease further development of ieee80211 as a self-contained layer) Signed-off-by: Jiri Benc Signed-off-by: Jirka Bohac Index: netdev/include/net/ieee80211.h =================================================================== --- netdev.orig/include/net/ieee80211.h 2005-09-17 14:42:32.000000000 +0200 +++ netdev/include/net/ieee80211.h 2005-09-17 14:47:03.000000000 +0200 @@ -727,15 +727,13 @@ struct ieee80211_device { int worst_rssi; /* Callback functions */ - void (*set_security) (struct net_device * dev, - struct ieee80211_security * sec); - int (*hard_start_xmit) (struct ieee80211_txb * txb, - struct net_device * dev); - int (*reset_port) (struct net_device * dev); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 */ - u8 priv[0]; + void (*set_security)(struct ieee80211_device *dev, + struct ieee80211_security *sec); + int (*hard_start_xmit)(struct ieee80211_txb *txb, + struct ieee80211_device *dev); + int (*reset_port)(struct ieee80211_device *dev); + + void *priv; }; #define IEEE_A (1<<0) @@ -743,9 +741,32 @@ struct ieee80211_device { #define IEEE_G (1<<2) #define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) -extern inline void *ieee80211_priv(struct net_device *dev) +static inline void *ieee80211_priv(struct ieee80211_device *ieee) +{ + return (char *)ieee + + ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); +} + +static inline void *ieee80211_dev_to_priv(struct net_device *dev) +{ + return (char *)dev + + ((sizeof(struct net_device) + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST) + + ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); +} + +static inline struct net_device *ieee80211_dev(struct ieee80211_device *ieee) +{ + return (struct net_device *)((char *)ieee - + ((sizeof(struct net_device) + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST)); +} + +static inline struct ieee80211_device *ieee80211_dev_to_ieee(struct net_device *dev) { - return ((struct ieee80211_device *)netdev_priv(dev))->priv; + return (struct ieee80211_device *)netdev_priv(dev); } extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) @@ -817,8 +838,8 @@ extern inline int ieee80211_get_hdrlen(u } /* ieee80211.c */ -extern void free_ieee80211(struct net_device *dev); -extern struct net_device *alloc_ieee80211(int sizeof_priv); +extern void free_ieee80211(struct ieee80211_device *ieee); +extern struct ieee80211_device *alloc_ieee80211(int sizeof_priv); extern int ieee80211_set_encryption(struct ieee80211_device *ieee); Index: netdev/net/ieee80211/ieee80211_module.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_module.c 2005-09-16 13:28:25.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_module.c 2005-09-17 14:44:44.000000000 +0200 @@ -70,7 +70,7 @@ static inline int ieee80211_networks_all GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); + ieee80211_dev(ieee)->name); return -ENOMEM; } @@ -99,23 +99,28 @@ static inline void ieee80211_networks_in &ieee->network_free_list); } -struct net_device *alloc_ieee80211(int sizeof_priv) +struct ieee80211_device *alloc_ieee80211(int sizeof_priv) { struct ieee80211_device *ieee; struct net_device *dev; + int alloc_size; int err; IEEE80211_DEBUG_INFO("Initializing...\n"); - dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); + alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST) + + sizeof_priv; + dev = alloc_etherdev(alloc_size); if (!dev) { IEEE80211_ERROR("Unable to network device.\n"); goto failed; } ieee = netdev_priv(dev); - dev->hard_start_xmit = ieee80211_xmit; - ieee->dev = dev; + ieee->priv = ieee80211_priv(ieee); + + dev->hard_start_xmit = ieee80211_xmit; err = ieee80211_networks_allocate(ieee); if (err) { @@ -147,7 +152,7 @@ struct net_device *alloc_ieee80211(int s ieee->privacy_invoked = 0; ieee->ieee802_1x = 1; - return dev; + return ieee; failed: if (dev) @@ -155,10 +160,8 @@ struct net_device *alloc_ieee80211(int s return NULL; } -void free_ieee80211(struct net_device *dev) +void free_ieee80211(struct ieee80211_device *ieee) { - struct ieee80211_device *ieee = netdev_priv(dev); - int i; del_timer_sync(&ieee->crypt_deinit_timer); @@ -177,7 +180,7 @@ void free_ieee80211(struct net_device *d } ieee80211_networks_free(ieee); - free_netdev(dev); + free_netdev(ieee80211_dev(ieee)); } #ifdef CONFIG_IEEE80211_DEBUG Index: netdev/net/ieee80211/ieee80211_rx.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_rx.c 2005-09-17 14:38:42.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_rx.c 2005-09-17 14:50:39.000000000 +0200 @@ -43,7 +43,7 @@ static inline void ieee80211_monitor_rx( struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; u16 fc = le16_to_cpu(hdr->frame_ctl); - skb->dev = ieee->dev; + skb->dev = ieee80211_dev(ieee); skb->mac.raw = skb->data; skb_pull(skb, ieee80211_get_hdrlen(fc)); skb->pkt_type = PACKET_OTHERHOST; @@ -100,7 +100,7 @@ static struct sk_buff *ieee80211_frag_ca if (frag == 0) { /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(ieee->dev->mtu + + skb = dev_alloc_skb(ieee80211_dev(ieee)->mtu + sizeof(struct ieee80211_hdr) + 8 /* LLC */ + 2 /* alignment */ + @@ -173,7 +173,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211 { if (ieee->iw_mode == IW_MODE_MASTER) { printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", - ieee->dev->name); + ieee80211_dev(ieee)->name); return 0; /* hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *) @@ -230,7 +230,7 @@ static unsigned char bridge_tunnel_heade static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, struct sk_buff *skb) { - struct net_device *dev = ieee->dev; + struct net_device *dev = ieee80211_dev(ieee); u16 fc, ethertype; struct ieee80211_hdr *hdr; u8 *pos; @@ -285,7 +285,7 @@ ieee80211_rx_frame_decrypt(struct ieee80 if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " "received packet from " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(hdr->addr2)); + ieee80211_dev(ieee)->name, MAC_ARG(hdr->addr2)); } return -1; } @@ -329,7 +329,7 @@ ieee80211_rx_frame_decrypt_msdu(struct i if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + ieee80211_dev(ieee)->name, MAC_ARG(hdr->addr2), keyidx); return -1; } @@ -342,7 +342,7 @@ ieee80211_rx_frame_decrypt_msdu(struct i int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats) { - struct net_device *dev = ieee->dev; + struct net_device *dev = ieee80211_dev(ieee); struct ieee80211_hdr *hdr; size_t hdrlen; u16 fc, type, stype, sc; @@ -405,7 +405,7 @@ int ieee80211_rx(struct ieee80211_device wstats.updated |= IW_QUAL_QUAL_INVALID; /* Update spy records */ - wireless_spy_update(ieee->dev, hdr->addr2, &wstats); + wireless_spy_update(ieee80211_dev(ieee), hdr->addr2, &wstats); } #endif /* IW_WIRELESS_SPY */ @@ -1202,7 +1202,7 @@ void ieee80211_rx_mgt(struct ieee80211_d WLAN_FC_GET_STYPE(le16_to_cpu (header->frame_ctl))); IEEE80211_WARNING("%s: Unknown management packet: %d\n", - ieee->dev->name, + ieee80211_dev(ieee)->name, WLAN_FC_GET_STYPE(le16_to_cpu (header->frame_ctl))); break; Index: netdev/net/ieee80211/ieee80211_tx.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_tx.c 2005-09-16 13:28:25.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_tx.c 2005-09-17 14:44:44.000000000 +0200 @@ -166,7 +166,7 @@ static inline int ieee80211_encrypt_frag if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " "TX packet to " MAC_FMT "\n", - ieee->dev->name, MAC_ARG(header->addr1)); + ieee80211_dev(ieee)->name, MAC_ARG(header->addr1)); } return -1; } @@ -187,7 +187,7 @@ static inline int ieee80211_encrypt_frag atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_INFO "%s: Encryption failed: len=%d.\n", - ieee->dev->name, frag->len); + ieee80211_dev(ieee)->name, frag->len); ieee->ieee_stats.tx_discards++; return -1; } @@ -261,13 +261,13 @@ int ieee80211_xmit(struct sk_buff *skb, /* If there is no driver handler to take the TXB, dont' bother * creating it... */ if (!ieee->hard_start_xmit) { - printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name); + printk(KERN_WARNING "%s: No xmit handler.\n", dev->name); goto success; } if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { printk(KERN_WARNING "%s: skb too small (%d).\n", - ieee->dev->name, skb->len); + dev->name, skb->len); goto success; } @@ -353,7 +353,7 @@ int ieee80211_xmit(struct sk_buff *skb, txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC); if (unlikely(!txb)) { printk(KERN_WARNING "%s: Could not allocate TXB\n", - ieee->dev->name); + dev->name); goto failed; } txb->encrypted = encrypt; @@ -407,7 +407,7 @@ int ieee80211_xmit(struct sk_buff *skb, dev_kfree_skb_any(skb); if (txb) { - if ((*ieee->hard_start_xmit) (txb, dev) == 0) { + if (ieee->hard_start_xmit(txb, ieee) == 0) { stats->tx_packets++; stats->tx_bytes += txb->payload_size; return 0; Index: netdev/net/ieee80211/ieee80211_wx.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_wx.c 2005-09-16 13:28:25.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_wx.c 2005-09-17 14:44:44.000000000 +0200 @@ -272,7 +272,7 @@ int ieee80211_wx_set_encode(struct ieee8 union iwreq_data *wrqu, char *keybuf) { struct iw_point *erq = &(wrqu->encoding); - struct net_device *dev = ieee->dev; + struct net_device *dev = ieee80211_dev(ieee); struct ieee80211_security sec = { .flags = 0 }; @@ -419,7 +419,7 @@ int ieee80211_wx_set_encode(struct ieee8 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ if (ieee->set_security) - ieee->set_security(dev, &sec); + ieee->set_security(ieee, &sec); /* Do not reset port if card is in Managed mode since resetting will * generate new IEEE 802.11 authentication which may end up in looping @@ -428,7 +428,7 @@ int ieee80211_wx_set_encode(struct ieee8 * the callbacks structures used to initialize the 802.11 stack. */ if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { + ieee->reset_port && ieee->reset_port(ieee)) { printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); return -EINVAL; }