[2/5] ieee80211: ieee80211_device alignment fix and cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <[email protected]>
Signed-off-by: Jirka Bohac <[email protected]>

--- linux-2.6.12-rc2-mm3.01/include/net/ieee80211.h	2005-05-18 10:49:01.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/include/net/ieee80211.h	2005-05-18 12:02:03.000000000 +0200
@@ -704,15 +704,13 @@
 	int abg_ture;   /* ABG flag              */
 
 	/* Callback functions */
-	void (*set_security)(struct net_device *dev,
+	void (*set_security)(struct ieee80211_device *ieee,
 			     struct ieee80211_security *sec);
 	int (*hard_start_xmit)(struct ieee80211_txb *txb,
-			       struct net_device *dev);
-	int (*reset_port)(struct net_device *dev);
+			       struct ieee80211_device *ieee);
+	int (*reset_port)(struct ieee80211_device *ieee);
 
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
+	void *priv;
 };
 
 #define IEEE_A            (1<<0)
@@ -720,9 +718,18 @@
 #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 ((struct ieee80211_device *)netdev_priv(dev))->priv;
+	 return (char *)ieee + 
+	 	((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));
 }
 
 extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
@@ -795,8 +802,8 @@
 
 
 /* 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);
 
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_module.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_module.c	2005-05-18 12:04:30.000000000 +0200
@@ -70,7 +70,7 @@
 		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 @@
 }
 
 
-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) {
@@ -148,7 +153,7 @@
  	ieee->privacy_invoked = 0;
  	ieee->ieee802_1x = 1;
 
-	return dev;
+	return ieee;
 
  failed:
 	if (dev)
@@ -157,10 +162,8 @@
 }
 
 
-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);
@@ -179,7 +182,7 @@
 	}
 
 	ieee80211_networks_free(ieee);
-	free_netdev(dev);
+	free_netdev(ieee80211_dev(ieee));
 }
 
 #ifdef CONFIG_IEEE80211_DEBUG
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_rx.c	2005-05-18 10:49:01.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_rx.c	2005-05-18 12:24:18.000000000 +0200
@@ -100,7 +100,7 @@
 
 	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 */ +
@@ -176,7 +176,7 @@
 {
 	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 *)
@@ -234,7 +234,7 @@
 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;
@@ -290,7 +290,7 @@
 		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(dev)->name, MAC_ARG(hdr->addr2));
 		}
 		return -1;
 	}
@@ -335,7 +335,7 @@
 	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;
 	}
 
@@ -349,7 +349,7 @@
 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;
@@ -1195,7 +1195,7 @@
 		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
 				     WLAN_FC_GET_STYPE(header->frame_ctl));
 		IEEE80211_WARNING("%s: Unknown management packet: %d\n",
-				  ieee->dev->name,
+				  ieee80211_dev(ieee)->name,
 				  WLAN_FC_GET_STYPE(header->frame_ctl));
 		break;
 	}
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_tx.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_tx.c	2005-05-18 12:20:07.000000000 +0200
@@ -172,7 +172,7 @@
 		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;
 	}
@@ -193,7 +193,7 @@
 	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;
 	}
@@ -270,13 +270,13 @@
 	 * creating it... */
 	if (!ieee->hard_start_xmit) {
 		printk(KERN_WARNING "%s: No xmit handler.\n",
-		       ieee->dev->name);
+		       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;
 	}
 
@@ -372,7 +372,7 @@
 	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;
@@ -427,7 +427,7 @@
 	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;
--- linux-2.6.12-rc2-mm3.01/net/ieee80211/ieee80211_wx.c	2005-04-19 17:04:43.000000000 +0200
+++ linux-2.6.12-rc2-mm3.02.0/net/ieee80211/ieee80211_wx.c	2005-05-18 12:27:28.000000000 +0200
@@ -252,7 +252,7 @@
 			    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
 	};
@@ -402,7 +402,7 @@
 	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
@@ -411,7 +411,7 @@
 	 * 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;
 	}


--
Jiri Benc
SUSE Labs
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux