Netdev List
 help / color / mirror / Atom feed
* [PATCH 01/18] ipw2200: Exponential averaging for signal and noise Level
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

This patch replaces sliding averaging by exponential averaging for
reporting the wireless statistics for signal and noise level for ipw2200.
See details from: http://www.ces.clemson.edu/linux/ipw2200_averages.shtml

Signed-off-by: Bill Moss <bmoss@clemson.edu>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |   34 ++++++++++++++++++++--------------
 drivers/net/wireless/ipw2200.h |    6 ++----
 2 files changed, 22 insertions(+), 18 deletions(-)

1864e427f7b49b5dc9e419f2c6b02ea8b682ead7
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 9dce522..77caeac 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -3771,6 +3771,13 @@ static void inline average_init(struct a
 	memset(avg, 0, sizeof(*avg));
 }
 
+#define DEPTH_RSSI 8
+#define DEPTH_NOISE 16
+static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)
+{
+	return ((depth-1)*prev_avg +  val)/depth;
+}
+
 static void average_add(struct average *avg, s16 val)
 {
 	avg->sum -= avg->entries[avg->pos];
@@ -3800,8 +3807,8 @@ static void ipw_reset_stats(struct ipw_p
 	priv->quality = 0;
 
 	average_init(&priv->average_missed_beacons);
-	average_init(&priv->average_rssi);
-	average_init(&priv->average_noise);
+	priv->exp_avg_rssi = -60;
+	priv->exp_avg_noise = -85 + 0x100;
 
 	priv->last_rate = 0;
 	priv->last_missed_beacons = 0;
@@ -4008,7 +4015,7 @@ static void ipw_gather_stats(struct ipw_
 	IPW_DEBUG_STATS("Tx quality   : %3d%% (%u errors, %u packets)\n",
 			tx_quality, tx_failures_delta, tx_packets_delta);
 
-	rssi = average_value(&priv->average_rssi);
+	rssi = priv->exp_avg_rssi;
 	signal_quality =
 	    (100 *
 	     (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
@@ -4023,7 +4030,7 @@ static void ipw_gather_stats(struct ipw_
 	else if (signal_quality < 1)
 		signal_quality = 0;
 
-	IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
+	IPW_ERROR("Signal level : %3d%% (%d dBm)\n",
 			signal_quality, rssi);
 
 	quality = min(beacon_quality,
@@ -4577,11 +4584,10 @@ static void ipw_rx_notification(struct i
 
 	case HOST_NOTIFICATION_NOISE_STATS:{
 			if (notif->size == sizeof(u32)) {
-				priv->last_noise =
-				    (u8) (le32_to_cpu(notif->u.noise.value) &
-					  0xff);
-				average_add(&priv->average_noise,
-					    priv->last_noise);
+				priv->exp_avg_noise =
+				    exponential_average(priv->exp_avg_noise,
+				    (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),
+				    DEPTH_NOISE);
 				break;
 			}
 
@@ -7840,9 +7846,9 @@ static void ipw_rx(struct ipw_priv *priv
 				if (network_packet && priv->assoc_network) {
 					priv->assoc_network->stats.rssi =
 					    stats.rssi;
-					average_add(&priv->average_rssi,
-						    stats.rssi);
-					priv->last_rx_rssi = stats.rssi;
+					priv->exp_avg_rssi =
+					    exponential_average(priv->exp_avg_rssi,
+					    stats.rssi, DEPTH_RSSI);
 				}
 
 				IPW_DEBUG_RX("Frame: len=%u\n",
@@ -9582,8 +9588,8 @@ static struct iw_statistics *ipw_get_wir
 	}
 
 	wstats->qual.qual = priv->quality;
-	wstats->qual.level = average_value(&priv->average_rssi);
-	wstats->qual.noise = average_value(&priv->average_noise);
+	wstats->qual.level = priv->exp_avg_rssi;
+	wstats->qual.noise = priv->exp_avg_noise;
 	wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
 	    IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
 
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 4b98049..1f2cab3 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1153,11 +1153,9 @@ struct ipw_priv {
 	u32 config;
 	u32 capability;
 
-	u8 last_rx_rssi;
-	u8 last_noise;
 	struct average average_missed_beacons;
-	struct average average_rssi;
-	struct average average_noise;
+	s16 exp_avg_rssi;
+	s16 exp_avg_noise;
 	u32 port_type;
 	int rx_bufs_min;	  /**< minimum number of bufs in Rx queue */
 	int rx_pend_max;	  /**< maximum pending buffers for one IRQ */
-- 
1.2.6


^ permalink raw reply related

* [PATCH 00/18] ipw2200 driver updates
From: Zhu Yi @ 2006-04-13  9:18 UTC (permalink / raw)
  To: netdev, John W. Linville

Hi,

The following patches are ipw2200 driver recently update. Please apply.


[PATCH 01/18] ipw2200: Exponential averaging for signal and noise Level
[PATCH 02/18] ipw2200: Fix TX QoS enabled frames problem
[PATCH 03/18] ipw2200: generates a scan event after a scan has completed
[PATCH 04/18] ipw2200: add module_param support for antenna selection
[PATCH 05/18] ipw2200: fix compile warning when !CONFIG_IPW2200_DEBUG
[PATCH 06/18] ipw2200: Do not continue loading the firmware if kmalloc fails
[PATCH 07/18] ipw2200: turn off signal debug log
[PATCH 08/18] ipw2200: Set the 'fixed' flags in wext get_rate
[PATCH 09/18] ipw2200: Fix endian issues with v3.0 fw image format
[PATCH 10/18] README.ipw2200: rename CONFIG_IPW_DEBUG to CONFIG_IPW2200_DEBUG
[PATCH 11/18] ipw2200: Enable rtap interface for RF promiscuous mode while associated
[PATCH 12/18] ipw2200: version string rework
[PATCH 13/18] ipw2200: update version stamp to 1.1.2
[PATCH 14/18] ipw2200: rename CONFIG_IPW_QOS to CONFIG_IPW2200_QOS
[PATCH 15/18] wireless Kconfig add IPW2200_RADIOTAP
[PATCH 16/18] ipw2200: rename CONFIG_IEEE80211_RADIOTAP to CONFIG_IPW2200_RADIOTAP
[PATCH 17/18] ipw2200: remove priv->last_noise reference
[PATCH 18/18] ipw2200: Fix wpa_supplicant association problem


Thanks,
-yi

^ permalink raw reply

* [PATCH 6/6] ieee80211: update version stamp to 1.1.13
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 include/net/ieee80211.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

ad81572a2505f80d22a1ceae5c055966e92df09f
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index bc6bdd6..4087dfc 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -29,7 +29,7 @@
 #include <linux/kernel.h>	/* ARRAY_SIZE */
 #include <linux/wireless.h>
 
-#define IEEE80211_VERSION "git-1.1.7"
+#define IEEE80211_VERSION "git-1.1.13"
 
 #define IEEE80211_DATA_LEN		2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
-- 
1.2.6


^ permalink raw reply related

* [PATCH 5/6] ieee80211: replace debug IEEE80211_WARNING with each own debug macro
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 net/ieee80211/ieee80211_rx.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

7a5148115c33ea94ff352a305ad2b2646a573219
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 0d18742..2bf567f 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -1690,8 +1690,8 @@ void ieee80211_rx_mgt(struct ieee80211_d
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
-		IEEE80211_WARNING("%s: IEEE80211_REASSOC_REQ received\n",
-				  ieee->dev->name);
+		IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",
+				     ieee->dev->name);
 		if (ieee->handle_reassoc_request != NULL)
 			ieee->handle_reassoc_request(ieee->dev,
 						    (struct ieee80211_reassoc_request *)
@@ -1703,8 +1703,8 @@ void ieee80211_rx_mgt(struct ieee80211_d
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
-		IEEE80211_WARNING("%s: IEEE80211_ASSOC_REQ received\n",
-				  ieee->dev->name);
+		IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",
+				     ieee->dev->name);
 		if (ieee->handle_assoc_request != NULL)
 			ieee->handle_assoc_request(ieee->dev);
 		break;
@@ -1720,10 +1720,10 @@ void ieee80211_rx_mgt(struct ieee80211_d
 		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
-		IEEE80211_WARNING("%s: Unknown management packet: %d\n",
-				  ieee->dev->name,
-				  WLAN_FC_GET_STYPE(le16_to_cpu
-						    (header->frame_ctl)));
+		IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",
+				     ieee->dev->name,
+				     WLAN_FC_GET_STYPE(le16_to_cpu
+						       (header->frame_ctl)));
 		break;
 	}
 }
-- 
1.2.6


^ permalink raw reply related

* [PATCH 4/6] ieee80211: remove unnecessary CONFIG_WIRELESS_EXT checking
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 net/ieee80211/ieee80211_rx.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

06f3e8b703c93ff8dbadf005878850fcd3393e5f
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 604b7b0..0d18742 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -369,7 +369,6 @@ int ieee80211_rx(struct ieee80211_device
 
 	/* Put this code here so that we avoid duplicating it in all
 	 * Rx paths. - Jean II */
-#ifdef CONFIG_WIRELESS_EXT
 #ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
 	/* If spy monitoring on */
 	if (ieee->spy_data.spy_number > 0) {
@@ -398,7 +397,6 @@ int ieee80211_rx(struct ieee80211_device
 		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
 	}
 #endif				/* IW_WIRELESS_SPY */
-#endif				/* CONFIG_WIRELESS_EXT */
 
 #ifdef NOT_YET
 	hostap_update_rx_stats(local->ap, hdr, rx_stats);
-- 
1.2.6


^ permalink raw reply related

* [PATCH 3/6] ieee80211: export list of bit rates with standard WEXT procddures
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

The patch replace the way to export the list of bit rates in scan results
from IWEVCUSTOM to SIOCGIWRATE. It also removes the max_rate item exported
with SIOCGIWRATE since this should be done by userspace.

Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 net/ieee80211/ieee80211_wx.c |   44 ++++++++++++++++++++----------------------
 1 files changed, 21 insertions(+), 23 deletions(-)

d0da9825b30b4db3df3bbe2718e220f4119e0b64
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index b885fd1..0ea55cb 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -50,7 +50,8 @@ static char *ieee80211_translate_scan(st
 	char *p;
 	struct iw_event iwe;
 	int i, j;
-	u8 max_rate, rate;
+	char *current_val;	/* For rates */
+	u8 rate;
 
 	/* First entry *MUST* be the AP MAC address */
 	iwe.cmd = SIOCGIWAP;
@@ -107,9 +108,13 @@ static char *ieee80211_translate_scan(st
 	start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
 
 	/* Add basic and extended rates */
-	max_rate = 0;
-	p = custom;
-	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
+	/* Rate : stuffing multiple values in a single event require a bit
+	 * more of magic - Jean II */
+	current_val = start + IW_EV_LCP_LEN;
+	iwe.cmd = SIOCGIWRATE;
+	/* Those two flags are ignored... */
+	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
 	for (i = 0, j = 0; i < network->rates_len;) {
 		if (j < network->rates_ex_len &&
 		    ((network->rates_ex[j] & 0x7F) <
@@ -117,28 +122,21 @@ static char *ieee80211_translate_scan(st
 			rate = network->rates_ex[j++] & 0x7F;
 		else
 			rate = network->rates[i++] & 0x7F;
-		if (rate > max_rate)
-			max_rate = rate;
-		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
+		/* Bit rate given in 500 kb/s units (+ 0x80) */
+		iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
+		/* Add new value to event */
+		current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
 	}
 	for (; j < network->rates_ex_len; j++) {
 		rate = network->rates_ex[j] & 0x7F;
-		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
-		if (rate > max_rate)
-			max_rate = rate;
-	}
-
-	iwe.cmd = SIOCGIWRATE;
-	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-	iwe.u.bitrate.value = max_rate * 500000;
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
-
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = p - custom;
-	if (iwe.u.data.length)
-		start = iwe_stream_add_point(start, stop, &iwe, custom);
+		/* Bit rate given in 500 kb/s units (+ 0x80) */
+		iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
+		/* Add new value to event */
+		current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+	}
+	/* Check if we added any rate */
+	if((current_val - start) > IW_EV_LCP_LEN)
+		start = current_val;
 
 	/* Add quality statistics */
 	iwe.cmd = IWEVQUAL;
-- 
1.2.6


^ permalink raw reply related

* [PATCH 2/6] ieee80211: Fix TX code doesn't enable QoS when using WPA + QoS
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

Fix ieee80211 TX code when using WPA+QOS. TKIP/CCMP will use
the TID field of qos_ctl in 802.11 frame header to do encryption. We
cannot ignore this field when doing host encryption and add the qos_ctl
field later.

Signed-off-by: Hong Liu <hong.liu@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 include/net/ieee80211.h      |    1 +
 net/ieee80211/ieee80211_tx.c |   63 ++++++++++++++++++++++++++++++++++--------
 2 files changed, 52 insertions(+), 12 deletions(-)

809115bccebe1ccae12c66466dad2c3d6874ac8b
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 66dc136..bc6bdd6 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -1076,6 +1076,7 @@ struct ieee80211_device {
 
 	int (*handle_management) (struct net_device * dev,
 				  struct ieee80211_network * network, u16 type);
+	int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
 
 	/* Typical STA methods */
 	int (*handle_auth) (struct net_device * dev,
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 8b4332f..233d527 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -220,13 +220,43 @@ static struct ieee80211_txb *ieee80211_a
 	return txb;
 }
 
+static int ieee80211_classify(struct sk_buff *skb)
+{
+	struct ethhdr *eth;
+	struct iphdr *ip;
+
+	eth = (struct ethhdr *)skb->data;
+	if (eth->h_proto != __constant_htons(ETH_P_IP))
+		return 0;
+
+	ip = skb->nh.iph;
+	switch (ip->tos & 0xfc) {
+	case 0x20:
+		return 2;
+	case 0x40:
+		return 1;
+	case 0x60:
+		return 3;
+	case 0x80:
+		return 4;
+	case 0xa0:
+		return 5;
+	case 0xc0:
+		return 6;
+	case 0xe0:
+		return 7;
+	default:
+		return 0;
+	}
+}
+
 /* Incoming skb is converted to a txb which consists of
  * a block of 802.11 fragment packets (stored as skbs) */
 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ieee80211_device *ieee = netdev_priv(dev);
 	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addr *frag_hdr;
+	struct ieee80211_hdr_3addrqos *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
 	    rts_required;
 	unsigned long flags;
@@ -234,9 +264,10 @@ int ieee80211_xmit(struct sk_buff *skb, 
 	int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
 	int bytes, fc, hdr_len;
 	struct sk_buff *skb_frag;
-	struct ieee80211_hdr_3addr header = {	/* Ensure zero initialized */
+	struct ieee80211_hdr_3addrqos header = {/* Ensure zero initialized */
 		.duration_id = 0,
-		.seq_ctl = 0
+		.seq_ctl = 0,
+		.qos_ctl = 0
 	};
 	u8 dest[ETH_ALEN], src[ETH_ALEN];
 	struct ieee80211_crypt_data *crypt;
@@ -282,12 +313,6 @@ int ieee80211_xmit(struct sk_buff *skb, 
 	memcpy(dest, skb->data, ETH_ALEN);
 	memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
 
-	/* Advance the SKB to the start of the payload */
-	skb_pull(skb, sizeof(struct ethhdr));
-
-	/* Determine total amount of storage required for TXB packets */
-	bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
 	if (host_encrypt || host_build_iv)
 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
 		    IEEE80211_FCTL_PROTECTED;
@@ -306,9 +331,23 @@ int ieee80211_xmit(struct sk_buff *skb, 
 		memcpy(header.addr2, src, ETH_ALEN);
 		memcpy(header.addr3, ieee->bssid, ETH_ALEN);
 	}
-	header.frame_ctl = cpu_to_le16(fc);
 	hdr_len = IEEE80211_3ADDR_LEN;
 
+	if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
+		fc |= IEEE80211_STYPE_QOS_DATA;
+		hdr_len += 2;
+
+		skb->priority = ieee80211_classify(skb);
+		header.qos_ctl |= skb->priority & IEEE80211_QCTL_TID;
+	}
+	header.frame_ctl = cpu_to_le16(fc);
+
+	/* Advance the SKB to the start of the payload */
+	skb_pull(skb, sizeof(struct ethhdr));
+
+	/* Determine total amount of storage required for TXB packets */
+	bytes = skb->len + SNAP_SIZE + sizeof(u16);
+
 	/* Encrypt msdu first on the whole data packet. */
 	if ((host_encrypt || host_encrypt_msdu) &&
 	    crypt && crypt->ops && crypt->ops->encrypt_msdu) {
@@ -402,7 +441,7 @@ int ieee80211_xmit(struct sk_buff *skb, 
 	if (rts_required) {
 		skb_frag = txb->fragments[0];
 		frag_hdr =
-		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+		    (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 
 		/*
 		 * Set header frame_ctl to the RTS.
@@ -433,7 +472,7 @@ int ieee80211_xmit(struct sk_buff *skb, 
 				    crypt->ops->extra_mpdu_prefix_len);
 
 		frag_hdr =
-		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+		    (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 		memcpy(frag_hdr, &header, hdr_len);
 
 		/* If this is not the last fragment, then add the MOREFRAGS
-- 
1.2.6


^ permalink raw reply related

* [PATCH 1/6] ieee80211: Fix TKIP MIC calculation for QoS frames
From: Zhu Yi @ 2006-04-13  9:17 UTC (permalink / raw)
  To: netdev, John W. Linville

Fix TKIP MIC verification failure when receiving QoS frames from AP.

Signed-off-by: Hong Liu <hong.liu@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 include/net/ieee80211.h              |    3 +++
 net/ieee80211/ieee80211_crypt_tkip.c |   11 ++++++++++-
 2 files changed, 13 insertions(+), 1 deletions(-)

2a0ee963da3c8a125e2af4dec07aca8bf4357d03
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 4725ff8..66dc136 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -104,6 +104,9 @@
 #define IEEE80211_SCTL_FRAG		0x000F
 #define IEEE80211_SCTL_SEQ		0xFFF0
 
+/* QOS control */
+#define IEEE80211_QCTL_TID		0x000F
+
 /* debug macros */
 
 #ifdef CONFIG_IEEE80211_DEBUG
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 93def94..3fa5df2 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -501,8 +501,11 @@ static int michael_mic(struct ieee80211_
 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
 {
 	struct ieee80211_hdr_4addr *hdr11;
+	u16 stype;
 
 	hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
+	stype  = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl));
+
 	switch (le16_to_cpu(hdr11->frame_ctl) &
 		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_TODS:
@@ -523,7 +526,13 @@ static void michael_mic_hdr(struct sk_bu
 		break;
 	}
 
-	hdr[12] = 0;		/* priority */
+	if (stype & IEEE80211_STYPE_QOS_DATA) {
+		const struct ieee80211_hdr_3addrqos *qoshdr =
+			(struct ieee80211_hdr_3addrqos *)skb->data;
+		hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
+	} else
+		hdr[12] = 0;		/* priority */
+
 	hdr[13] = hdr[14] = hdr[15] = 0;	/* reserved */
 }
 
-- 
1.2.6


^ permalink raw reply related

* [PATCH 0/6] ieee80211 updates
From: Zhu Yi @ 2006-04-13  9:16 UTC (permalink / raw)
  To: netdev, John W. Linville

Hi,

Here are some patches for ieee80211, please apply.


[PATCH 1/6] ieee80211: Fix TKIP MIC calculation for QoS frames
[PATCH 2/6] ieee80211: Fix TX code doesn't enable QoS when using WPA + QoS
[PATCH 3/6] ieee80211: export list of bit rates with standard WEXT procdures
[PATCH 4/6] ieee80211: remove unnecessary CONFIG_WIRELESS_EXT checking
[PATCH 5/6] ieee80211: replace debug IEEE80211_WARNING with each own debug macro
[PATCH 6/6] ieee80211: update version stamp to 1.1.13

Thanks,
-yi

^ permalink raw reply

* [PATCH] ipw2100: wraps the debug module param within #ifdefs
From: Zhu Yi @ 2006-04-13  9:14 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Henrik Brix Andersen <brix@gentoo.org>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2100.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

e78cfdab91a809722be99c06574d2e0a60467644
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 72335c8..2cd32a4 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -184,7 +184,9 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_IPW2100_DEBUG
 static int debug = 0;
+#endif
 static int mode = 0;
 static int channel = 0;
 static int associate = 1;
@@ -194,13 +196,17 @@ static struct ipw2100_fw ipw2100_firmwar
 #endif
 
 #include <linux/moduleparam.h>
+#ifdef CONFIG_IPW2100_DEBUG
 module_param(debug, int, 0444);
+#endif
 module_param(mode, int, 0444);
 module_param(channel, int, 0444);
 module_param(associate, int, 0444);
 module_param(disable, int, 0444);
 
+#ifdef CONFIG_IPW2100_DEBUG
 MODULE_PARM_DESC(debug, "debug level");
+#endif
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
 MODULE_PARM_DESC(channel, "channel");
 MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
-- 
1.2.6


^ permalink raw reply related

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Johannes Berg @ 2006-04-13  9:06 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: netdev, linville, softmac-dev, Jean Tourrilhes
In-Reply-To: <20060413020010.2ab16d7b.zaitcev@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 765 bytes --]

On Thu, 2006-04-13 at 02:00 -0700, Pete Zaitcev wrote:

> This sounds completely wrong. Do you guys remember the Subject: string
> of this discussion by any chance?

Discussed offline at the wireless summit, sorry.

> It's very likely that tools do indeed loop when they see EAGAIN, but
> this is a workaround, not the main mode of operation. It seems obvious
> to me that the get method should wait until the scan results are
> available. Perhaps the discussion had a specific scenario where
> EAGAIN would make sense, but I cannot imagine what it might be.

Right, they do loop, but they don't have a method to indicate
completion. Thus we'd have to actually wait for the completion in the
kernel. Jean, what is the intended use here?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Pete Zaitcev @ 2006-04-13  9:00 UTC (permalink / raw)
  To: johannes; +Cc: netdev, linville
In-Reply-To: <20060411085841.252064000@sipsolutions.net>

On Tue, 11 Apr 2006 10:58:06 +0200, johannes@sipsolutions.net wrote:

> Below patch was developed after discussion with Daniel Drake who
> mentioned to me that wireless tools expect an EAGAIN return from getscan
> so that they can wait for the scan to finish before printing out the
> results.

This sounds completely wrong. Do you guys remember the Subject: string
of this discussion by any chance?

It's very likely that tools do indeed loop when they see EAGAIN, but
this is a workaround, not the main mode of operation. It seems obvious
to me that the get method should wait until the scan results are
available. Perhaps the discussion had a specific scenario where
EAGAIN would make sense, but I cannot imagine what it might be.

-- Pete

^ permalink raw reply

* Re: [RFD][PATCH] typhoon and core sample for folding away VLAN stuff
From: Denis Vlasenko @ 2006-04-13  8:38 UTC (permalink / raw)
  To: Dave Dillow
  Cc: Ingo Oeser, Ingo Oeser, netdev, David S. Miller, linux-kernel,
	jgarzik
In-Reply-To: <443DA830.8030209@thedillows.org>

On Thursday 13 April 2006 04:24, Dave Dillow wrote:
> Regardless, I remain opposed to this particular instance of bloat 
> busting. While both patches have improved in style, they remove a useful 
> feature and make the code less clean, for no net gain.

What happened to non-modular build? "no net gain" is not true.
 
> > This kind of changes are important, because bloat creeps in byte by byte
> > of unused features. So I really appreciate your work here Denis.
> 
> On SMP FC4, typhoon.ko has a text size of 68330, so you need to cut 2794 
> bytes to see an actual difference in memory usage for a module. Non-SMP 
> it is 67741, so there you only need to cut 2205 bytes to get a win.

This is silly. Should I go this route and try a dozen of different gcc
versions and "-O2 versus -Os" things to demonstrate that sometimes
it will matter?
--
vda

^ permalink raw reply

* Re: [PATCH] deinline a few large functions in vlan code v2
From: Denis Vlasenko @ 2006-04-13  6:04 UTC (permalink / raw)
  To: Dave Dillow; +Cc: netdev, David S. Miller, linux-kernel, jgarzik
In-Reply-To: <1144862325.18319.32.camel@dillow.idleaire.com>

On Wednesday 12 April 2006 20:18, Dave Dillow wrote:
> > > or loaded. And even if it saves 200 bytes in one 
> > > module, unless that module text was already less than 200 bytes into a
> > > page, you've saved no memory -- a 4300 byte module takes 2 pages on x86,
> > > as does a 4100 byte module.
> > 
> > Sometimes, those 200 bytes can bring module size just under 4096.
> > Thus on the average, on many modules you get the same size savings
> > as on built-in code. (Not that we have THAT many network modules...)
> 
> You're making a bogus leap from "sometimes" to "average".

It's not bogus. See below.

> Assuming an even distribution of lengths mod 4096, less than 5% of the
> time will 200 bytes save any memory on a module.

Ok, imagine perfect module size distribution, and suppose we shave 204
bytes off each module. 5% of the modules will have their size reduced
so that they occupy one 4k page less.

Those 5% of modules will have their RAM footprint reduced not
by just 204 bytes, but by 4096 bytes.

Total RAM footprint of all modules, in kb (N=number of modules):
before: sum_of_orig_module_size
after, modular: sum_of_orig_module_size - 0.05*N * 4096
after, builtin: sum_of_orig_module_size - N * 204

0.05*4096 = 204.53

> I don't like "VLAN_ENABLED" as a global define -- it looks too much like
> something local. The CONFIG_VLAN... defines were more descriptive.

That will require Kconfig changes. Maybe you would like "VLAN_ENABLED_KERNER"
name? It doesn't sound local...

> I didn't think about this before, but I'm pretty sure you're taking away
> functionality. When I wrote the typhoon driver, ISTR that I looked
> through the vlan implantation, and determined that all the #ifdefs on
> CONFIG_VLAN_8021Q were not really needed, since all the hooks were
> there. You could just load the 8021q module (even perhaps building it at
> a later date), and it would work if you had filled in the hooks in
> struct net_device. So I didn't #ifdef out code in my driver to let the
> user have the option.

IOW: currently most of VLAN code is already in kernel.
Then why do we have VLAN as a config option? Let's make it unconditional
(will add only 10k to core kernel)?

# size net/8021q/8021q.o
   text    data     bss     dec     hex filename
   9379     484     136    9999    270f net/8021q/8021q.o

> You're taking that away in the name of a total of 5K, which most users
> won't actually get back?

It started as a kernel-wide audit for huge inlines, I was not aiming
at VLAN particularly. But yes, when I saw other (not related to inlines)
opportunities to make code smaller, I decided to do it.

You know, people say that even Linux is getting fat these days.
--
vda

^ permalink raw reply

* help needed in n/w
From: varun @ 2006-04-13  3:19 UTC (permalink / raw)
  To: netdev

Hi all,

            Iam new to netfilters and iam trying to play around to 
understand a few things. By default when no policies are specified then 
it allows all traffic to go out and in to the n/w. I want to change this 
to default as deny.
            That is when there is no policy all should be default deny.

          So in order to achieve that i tried to change the  code a little.
           In the file iptable_filter.c there is a variable called 
static int forward = NF_ACCEPT
            I changed this to NF_DROP and when i compiled and used it 
sure i was not able to send any or recv any packets
            but even after i give a policy like iptables -t filter -A 
INPUT -j ACCEPT
            Nothing changes. So achieve what i want what should i do? 
And where do i change?

            Another thing is that in normally when i put a policy like 
iptables -t filter -A OUTPUT -j REJECT
             Even my own self IP doesnt ping? Why should this happen?
              Isint it ok to ping local ip and loopback ip?
               If i want such implementation where i should be able to 
ping to self and local but not any other ip?
               Is it possible?
               I dont want to add policies rather is it possible just by 
changing the iptables kernel code?

               Please help me on this?

Varun

^ permalink raw reply

* Re: [RFD][PATCH] typhoon and core sample for folding away VLAN stuff
From: Dave Dillow @ 2006-04-13  1:24 UTC (permalink / raw)
  To: Ingo Oeser
  Cc: Ingo Oeser, Denis Vlasenko, netdev, David S. Miller, linux-kernel,
	jgarzik
In-Reply-To: <200604122132.46113.ioe-lkml@rameria.de>

Ingo Oeser wrote:
> Dave Dillow: Is this style clean enough to have it in your driver?

Though I'm not real fond of Denis's last patch, I think I prefer it's 
style to this, solely because it removes more code when VLANs are 
disabled -- you've left the spin_locks in, and have more #ifdefs.

Regardless, I remain opposed to this particular instance of bloat 
busting. While both patches have improved in style, they remove a useful 
feature and make the code less clean, for no net gain.

> This kind of changes are important, because bloat creeps in byte by byte
> of unused features. So I really appreciate your work here Denis.

On SMP FC4, typhoon.ko has a text size of 68330, so you need to cut 2794 
bytes to see an actual difference in memory usage for a module. Non-SMP 
it is 67741, so there you only need to cut 2205 bytes to get a win.

Every byte counts, except when it doesn't.


^ permalink raw reply

* [patch 4] softmac: fix event sending
From: Johannes Berg @ 2006-04-13  0:42 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville
In-Reply-To: <20060411085805.949313000@sipsolutions.net>

Softmac is sending custom events to userspace already, but it
should _really_ be sending the right WEXT events instead. This
patch fixes that.

Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

Index: wireless-2.6/include/net/ieee80211softmac.h
===================================================================
--- wireless-2.6.orig/include/net/ieee80211softmac.h	2006-04-13 02:35:54.686229309 +0200
+++ wireless-2.6/include/net/ieee80211softmac.h	2006-04-13 02:37:17.676229309 +0200
@@ -267,8 +267,9 @@
 #define IEEE80211SOFTMAC_EVENT_AUTH_FAILED		5
 #define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT		6
 #define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND	7
+#define IEEE80211SOFTMAC_EVENT_DISASSOCIATED		8
 /* keep this updated! */
-#define IEEE80211SOFTMAC_EVENT_LAST			7
+#define IEEE80211SOFTMAC_EVENT_LAST			8
 /*
  * If you want to be notified of certain events, you can call
  * ieee80211softmac_notify[_atomic] with
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c	2006-04-13 02:35:54.686229309 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c	2006-04-13 02:37:17.686229309 +0200
@@ -101,6 +101,7 @@
 	/* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
 	mac->associated = 0;
 	mac->associnfo.associating = 0;
+	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
 	spin_unlock_irqrestore(&mac->lock, flags);
 }
 
@@ -373,6 +374,7 @@
 	spin_lock_irqsave(&mac->lock, flags);
 	mac->associnfo.bssvalid = 0;
 	mac->associated = 0;
+	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
 	schedule_work(&mac->associnfo.work);
 	spin_unlock_irqrestore(&mac->lock, flags);
 	
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 02:35:54.686229309 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 02:38:51.036229309 +0200
@@ -67,6 +67,7 @@
 	"authenticating failed",
 	"authenticating timed out",
 	"associating failed because no suitable network was found",
+	"disassociated",
 };
 
 
@@ -128,13 +129,36 @@
 ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx)
 {
 	struct ieee80211softmac_event *eventptr, *tmp;
-	union iwreq_data wrqu;
-	char *msg;
+	struct ieee80211softmac_network *network;
 	
 	if (event >= 0) {
-		msg = event_descriptions[event];
-		wrqu.data.length = strlen(msg);
-		wireless_send_event(mac->dev, IWEVCUSTOM, &wrqu, msg);
+		union iwreq_data wrqu;
+		int we_event;
+		char *msg = NULL;
+
+		switch(event) {
+		case IEEE80211SOFTMAC_EVENT_ASSOCIATED:
+			network = (struct ieee80211softmac_network *)event_ctx;
+			wrqu.data.length = 0;
+			wrqu.data.flags = 0;
+			memcpy(wrqu.ap_addr.sa_data, &network->bssid[0], ETH_ALEN);
+			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+			we_event = SIOCGIWAP;
+			break;
+		case IEEE80211SOFTMAC_EVENT_DISASSOCIATED:
+			wrqu.data.length = 0;
+			wrqu.data.flags = 0;
+			memset(&wrqu, '\0', sizeof (union iwreq_data));
+			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+			we_event = SIOCGIWAP;
+			break;
+		default:
+			msg = event_descriptions[event];
+			wrqu.data.length = strlen(msg);
+			we_event = IWEVCUSTOM;
+			break;
+		}
+		wireless_send_event(mac->dev, we_event, &wrqu, msg);
 	}
 
 	if (!list_empty(&mac->events))



^ permalink raw reply

* [PATCH] bcm43xx: sysfs code cleanup
From: Michael Buesch @ 2006-04-13  0:32 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ, Andrew Morton
  Cc: bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w, netdev-u79uwXL29TY76Z2rM5mHXA,
	Bunk, Adrian

This should also go in before 2.6.17

---

This cleans up the bcm43xx sysfs code and makes it compliant
with the unwritten sysfs rules (at least I hope so).

Signed-off-by: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>

Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx.h	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx.h	2006-04-12 02:57:04.000000000 +0200
@@ -15,7 +15,6 @@
 
 #include "bcm43xx_debugfs.h"
 #include "bcm43xx_leds.h"
-#include "bcm43xx_sysfs.h"
 
 
 #define PFX				KBUILD_MODNAME ": "
@@ -638,8 +637,6 @@
 };
 
 struct bcm43xx_private {
-	struct bcm43xx_sysfs sysfs;
-
 	struct ieee80211_device *ieee;
 	struct ieee80211softmac_device *softmac;
 
@@ -772,6 +769,20 @@
 	return ieee80211softmac_priv(dev);
 }
 
+struct device;
+
+static inline
+struct bcm43xx_private * dev_to_bcm(struct device *dev)
+{
+	struct net_device *net_dev;
+	struct bcm43xx_private *bcm;
+
+	net_dev = dev_get_drvdata(dev);
+	bcm = bcm43xx_priv(net_dev);
+
+	return bcm;
+}
+
 
 /* Helper function, which returns a boolean.
  * TRUE, if PIO is used; FALSE, if DMA is used.
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_main.c	2006-04-12 02:12:39.000000000 +0200
@@ -52,6 +52,7 @@
 #include "bcm43xx_wx.h"
 #include "bcm43xx_ethtool.h"
 #include "bcm43xx_xmit.h"
+#include "bcm43xx_sysfs.h"
 
 
 MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c	2006-04-12 03:21:55.000000000 +0200
@@ -71,14 +71,46 @@
 	return -EINVAL;
 }
 
+static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
+{
+	int i, pos = 0;
+
+	for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
+		pos += snprintf(buf + pos, buf_len - pos - 1,
+				"%04X", swab16(sprom[i]) & 0xFFFF);
+	}
+	pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
+
+	return pos + 1;
+}
+
+static int hex2sprom(u16 *sprom, const char *dump, size_t len)
+{
+	char tmp[5] = { 0 };
+	int cnt = 0;
+	unsigned long parsed;
+
+	if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
+		return -EINVAL;
+
+	while (cnt < BCM43xx_SPROM_SIZE) {
+		memcpy(tmp, dump, 4);
+		dump += 4;
+		parsed = simple_strtoul(tmp, NULL, 16);
+		sprom[cnt++] = swab16((u16)parsed);
+	}
+
+	return 0;
+}
+
 static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
 				       struct device_attribute *attr,
 				       char *buf)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	u16 *sprom;
 	unsigned long flags;
-	int i, err;
+	int err;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -91,55 +123,53 @@
 	bcm43xx_lock_mmio(bcm, flags);
 	assert(bcm->initialized);
 	err = bcm43xx_sprom_read(bcm, sprom);
-	if (!err) {
-		for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
-			buf[i * 2] = sprom[i] & 0x00FF;
-			buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8;
-		}
-	}
+	if (!err)
+		err = sprom2hex(sprom, buf, PAGE_SIZE);
 	bcm43xx_unlock_mmio(bcm, flags);
 	kfree(sprom);
 
-	return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16);
+	return err;
 }
 
 static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	u16 *sprom;
 	unsigned long flags;
-	int i, err;
+	int err;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
-	if (count != BCM43xx_SPROM_SIZE * sizeof(u16))
-		return -EINVAL;
 	sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
 			GFP_KERNEL);
 	if (!sprom)
 		return -ENOMEM;
-	for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
-		sprom[i] = buf[i * 2] & 0xFF;
-		sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8;
-	}
+	err = hex2sprom(sprom, buf, count);
+	if (err)
+		goto out_kfree;
 	bcm43xx_lock_mmio(bcm, flags);
 	assert(bcm->initialized);
 	err = bcm43xx_sprom_write(bcm, sprom);
 	bcm43xx_unlock_mmio(bcm, flags);
+out_kfree:
 	kfree(sprom);
 
 	return err ? err : count;
 
 }
 
+static DEVICE_ATTR(sprom, 0600,
+		   bcm43xx_attr_sprom_show,
+		   bcm43xx_attr_sprom_store);
+
 static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
 					    struct device_attribute *attr,
 					    char *buf)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	unsigned long flags;
 	int err;
 	ssize_t count = 0;
@@ -175,7 +205,7 @@
 					     struct device_attribute *attr,
 					     const char *buf, size_t count)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	unsigned long flags;
 	int err;
 	int mode;
@@ -215,11 +245,15 @@
 	return err ? err : count;
 }
 
+static DEVICE_ATTR(interference, 0644,
+		   bcm43xx_attr_interfmode_show,
+		   bcm43xx_attr_interfmode_store);
+
 static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
 					  struct device_attribute *attr,
 					  char *buf)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	unsigned long flags;
 	int err;
 	ssize_t count;
@@ -245,7 +279,7 @@
 					   struct device_attribute *attr,
 					   const char *buf, size_t count)
 {
-	struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+	struct bcm43xx_private *bcm = dev_to_bcm(dev);
 	unsigned long flags;
 	int err;
 	int value;
@@ -267,56 +301,41 @@
 	return err ? err : count;
 }
 
+static DEVICE_ATTR(shortpreamble, 0644,
+		   bcm43xx_attr_preamble_show,
+		   bcm43xx_attr_preamble_store);
+
 int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
 {
 	struct device *dev = &bcm->pci_dev->dev;
-	struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
 	int err;
 
 	assert(bcm->initialized);
 
-	sysfs->attr_sprom.attr.name = "sprom";
-	sysfs->attr_sprom.attr.owner = THIS_MODULE;
-	sysfs->attr_sprom.attr.mode = 0600;
-	sysfs->attr_sprom.show = bcm43xx_attr_sprom_show;
-	sysfs->attr_sprom.store = bcm43xx_attr_sprom_store;
-	err = device_create_file(dev, &sysfs->attr_sprom);
+	err = device_create_file(dev, &dev_attr_sprom);
 	if (err)
 		goto out;
-
-	sysfs->attr_interfmode.attr.name = "interference";
-	sysfs->attr_interfmode.attr.owner = THIS_MODULE;
-	sysfs->attr_interfmode.attr.mode = 0600;
-	sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show;
-	sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store;
-	err = device_create_file(dev, &sysfs->attr_interfmode);
+	err = device_create_file(dev, &dev_attr_interference);
 	if (err)
 		goto err_remove_sprom;
-
-	sysfs->attr_preamble.attr.name = "shortpreamble";
-	sysfs->attr_preamble.attr.owner = THIS_MODULE;
-	sysfs->attr_preamble.attr.mode = 0600;
-	sysfs->attr_preamble.show = bcm43xx_attr_preamble_show;
-	sysfs->attr_preamble.store = bcm43xx_attr_preamble_store;
-	err = device_create_file(dev, &sysfs->attr_preamble);
+	err = device_create_file(dev, &dev_attr_shortpreamble);
 	if (err)
 		goto err_remove_interfmode;
 
 out:
 	return err;
 err_remove_interfmode:
-	device_remove_file(dev, &sysfs->attr_interfmode);
+	device_remove_file(dev, &dev_attr_interference);
 err_remove_sprom:
-	device_remove_file(dev, &sysfs->attr_sprom);
+	device_remove_file(dev, &dev_attr_sprom);
 	goto out;
 }
 
 void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
 {
 	struct device *dev = &bcm->pci_dev->dev;
-	struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
 
-	device_remove_file(dev, &sysfs->attr_preamble);
-	device_remove_file(dev, &sysfs->attr_interfmode);
-	device_remove_file(dev, &sysfs->attr_sprom);
+	device_remove_file(dev, &dev_attr_shortpreamble);
+	device_remove_file(dev, &dev_attr_interference);
+	device_remove_file(dev, &dev_attr_sprom);
 }
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h	2006-04-12 02:12:39.000000000 +0200
@@ -1,22 +1,6 @@
 #ifndef BCM43xx_SYSFS_H_
 #define BCM43xx_SYSFS_H_
 
-#include <linux/device.h>
-
-
-struct bcm43xx_sysfs {
-	struct device_attribute attr_sprom;
-	struct device_attribute attr_interfmode;
-	struct device_attribute attr_preamble;
-};
-
-#define devattr_to_bcm(attr, attr_name)	({				\
-	struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p;		\
-	__s = container_of((attr), struct bcm43xx_sysfs, attr_name);	\
-	__p = container_of(__s, struct bcm43xx_private, sysfs);		\
-	__p;								\
-					})
-
 struct bcm43xx_private;
 
 int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);

-- 
Greetings Michael.

^ permalink raw reply

* [PATCH] bcm43xx: fix pctl slowclock limit calculation
From: Michael Buesch @ 2006-04-13  0:30 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ, Andrew Morton
  Cc: bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w, netdev-u79uwXL29TY76Z2rM5mHXA,
	Bunk, Adrian

This fixes coverity bug:
http://marc.theaimsgroup.com/?l=linux-netdev&m=114417628413880&w=2

Signed-off-by: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>

Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_power.c	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.c	2006-04-13 02:10:17.000000000 +0200
@@ -35,77 +35,101 @@
 #include "bcm43xx_main.h"
 
 
+/* Get the Slow Clock Source */
+static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
+{
+	u32 tmp;
+	int err;
+
+	assert(bcm->current_core == &bcm->core_chipcommon);
+	if (bcm->current_core->rev < 6) {
+		if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
+		    bcm->bustype == BCM43xx_BUSTYPE_SB)
+			return BCM43xx_PCTL_CLKSRC_XTALOS;
+		if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
+			err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
+			assert(!err);
+			if (tmp & 0x10)
+				return BCM43xx_PCTL_CLKSRC_PCI;
+			return BCM43xx_PCTL_CLKSRC_XTALOS;
+		}
+	}
+	if (bcm->current_core->rev < 10) {
+		tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
+		tmp &= 0x7;
+		if (tmp == 0)
+			return BCM43xx_PCTL_CLKSRC_LOPWROS;
+		if (tmp == 1)
+			return BCM43xx_PCTL_CLKSRC_XTALOS;
+		if (tmp == 2)
+			return BCM43xx_PCTL_CLKSRC_PCI;
+	}
+
+	return BCM43xx_PCTL_CLKSRC_XTALOS;
+}
+
 /* Get max/min slowclock frequency
  * as described in http://bcm-specs.sipsolutions.net/PowerControl
  */
 static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
 				       int get_max)
 {
-	int limit = 0;
+	int limit;
+	int clocksrc;
 	int divisor;
-	int selection;
-	int err;
 	u32 tmp;
-	struct bcm43xx_coreinfo *old_core;
 
-	if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
-		goto out;
-	old_core = bcm->current_core;
-	err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
-	if (err)
-		goto out;
+	assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
+	assert(bcm->current_core == &bcm->core_chipcommon);
 
+	clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
 	if (bcm->current_core->rev < 6) {
-		if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) ||
-			(bcm->bustype == BCM43xx_BUSTYPE_SB)) {
-			selection = 1;
+		switch (clocksrc) {
+		case BCM43xx_PCTL_CLKSRC_PCI:
+			divisor = 64;
+			break;
+		case BCM43xx_PCTL_CLKSRC_XTALOS:
 			divisor = 32;
-		} else {
-			err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
-			if (err) {
-				printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n");
-				goto out_switchback;
-			}
-			if (tmp & 0x10) {
-				/* PCI */
-				selection = 2;
-				divisor = 64;
-			} else {
-				/* XTAL */
-				selection = 1;
-				divisor = 32;
-			}
+			break;
+		default:
+			assert(0);
+			divisor = 1;
 		}
 	} else if (bcm->current_core->rev < 10) {
-		selection = (tmp & 0x07);
-		if (selection) {
+		switch (clocksrc) {
+		case BCM43xx_PCTL_CLKSRC_LOPWROS:
+			divisor = 1;
+			break;
+		case BCM43xx_PCTL_CLKSRC_XTALOS:
+		case BCM43xx_PCTL_CLKSRC_PCI:
 			tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
-			divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
-		} else
+			divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+			divisor *= 4;
+			break;
+		default:
+			assert(0);
 			divisor = 1;
+		}
 	} else {
 		tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
-		divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
-		selection = 1;
+		divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+		divisor *= 4;
 	}
-	
-	switch (selection) {
-	case 0:
-		/* LPO */
+
+	switch (clocksrc) {
+	case BCM43xx_PCTL_CLKSRC_LOPWROS:
 		if (get_max)
 			limit = 43000;
 		else
 			limit = 25000;
 		break;
-	case 1:
-		/* XTAL */
+	case BCM43xx_PCTL_CLKSRC_XTALOS:
 		if (get_max)
 			limit = 20200000;
 		else
 			limit = 19800000;
 		break;
-	case 2:
-		/* PCI */
+	case BCM43xx_PCTL_CLKSRC_PCI:
 		if (get_max)
 			limit = 34000000;
 		else
@@ -113,17 +137,14 @@
 		break;
 	default:
 		assert(0);
+		limit = 0;
 	}
 	limit /= divisor;
 
-out_switchback:
-	err = bcm43xx_switch_core(bcm, old_core);
-	assert(err == 0);
-
-out:
 	return limit;
 }
 
+
 /* init power control
  * as described in http://bcm-specs.sipsolutions.net/PowerControl
  */
Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_power.h	2006-04-11 06:00:00.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_power.h	2006-04-13 01:28:05.000000000 +0200
@@ -33,6 +33,15 @@
 
 #include <linux/types.h>
 
+/* Clock sources */
+enum {
+	/* PCI clock */
+	BCM43xx_PCTL_CLKSRC_PCI,
+	/* Crystal slow clock oscillator */
+	BCM43xx_PCTL_CLKSRC_XTALOS,
+	/* Low power oscillator */
+	BCM43xx_PCTL_CLKSRC_LOPWROS,
+};
 
 struct bcm43xx_private;
 

-- 
Greetings Michael.

^ permalink raw reply

* [PATCH] bcm43xx: fix dyn tssi2dbm memleak
From: Michael Buesch @ 2006-04-13  0:27 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ, Andrew Morton
  Cc: bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w, netdev-u79uwXL29TY76Z2rM5mHXA,
	Bunk, Adrian

This patch fixes a memory leak spotted by the Coverity checker.

Signed-off-by: Adrian Bunk <bunk-HeJ8Db2Gnd6zQB+pC5nmwQ@public.gmane.org>
Signed-off-by: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>

Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_phy.c	2006-04-13 02:21:39.000000000 +0200
+++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_phy.c	2006-04-13 02:23:31.000000000 +0200
@@ -2151,6 +2151,7 @@
 				phy->tssi2dbm = NULL;
 				printk(KERN_ERR PFX "Could not generate "
 						    "tssi2dBm table\n");
+				kfree(dyn_tssi2dbm);
 				return -ENODEV;
 			}
 		phy->tssi2dbm = dyn_tssi2dbm;

-- 
Greetings Michael.

^ permalink raw reply

* Re: [RFC PATCH] softmac: (v2) send WEXT assoc/disassoc events to userspace
From: Johannes Berg @ 2006-04-12 23:56 UTC (permalink / raw)
  To: Dan Williams
  Cc: Larry Finger, netdev, softmac-dev, David Woodhouse, bcm43xx-dev
In-Reply-To: <1141936896.28038.6.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 498 bytes --]

On Thu, 2006-03-09 at 15:41 -0500, Dan Williams wrote:

> Can you grab a debug log from wpa_supplicant?  Run wpa_supplicant with
> the args "-ddd", and _don't_ run it as a daemon.  Mail the output to me
> if you don't want it to go to everyone on the cc list (might include
> SSIDs and such).  That should allow us to figure out exactly where
> wpa_supplicant and/or the driver are having issues.

Did this ever happen? I'm currently trying to collect all the pending
patches

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: Window shrinking (was Linux v2.6.16-rc6)
From: Andy Furniss @ 2006-04-12 23:34 UTC (permalink / raw)
  To: Roberto Nibali
  Cc: Mark Butler, David S. Miller, michal.k.k.piotrowski, netdev
In-Reply-To: <443D7015.7080707@drugphish.ch>

Roberto Nibali wrote:

> 
> I had the distinct pleasure of partly get involved with debugging 
> network stalls related to Linux clients (2.6.x kernel) and a Packeteer.

Dare I suggest that it could be something as trivial as it looks like 
window scaling defaults to off on SunOS 2.5.1 and it's on on Linux - 
maybe packeteer can't handle it properly. Would be an easy test to turn 
it off on the Suse boxes.

Andy.

^ permalink raw reply

* [PATCH] Fix locking in gianfar
From: Andy Fleming @ 2006-04-07  1:36 UTC (permalink / raw)
  To: Netdev

This patch fixes several bugs in the gianfar driver, including a  
major one
where spinlocks were horribly broken:

* Split gianfar locks into two types: TX and RX
* Made it so gfar_start() now clears RHALT
* Fixed a bug where calling gfar_start_xmit() with interrupts off would
corrupt the interrupt state
* Fixed a bug where a frame could potentially arrive, and never be  
handled
(if no more frames arrived
* Fixed a bug where the rx_work_limit would never be observed by the rx
completion code
* Fixed a bug where the interrupt handlers were not actually  
protected by
their spinlocks

Signed-off-by: Andy Fleming <afleming@freescale.com>

---

  drivers/net/gianfar.c         |   56 ++++++++++++++++ 
+-----------------
  drivers/net/gianfar.h         |   67 +++++++++++++++++++++++++++ 
+-------------
  drivers/net/gianfar_ethtool.c |   20 +++++++++---
  drivers/net/gianfar_sysfs.c   |   24 +++++++--------
  4 files changed, 100 insertions(+), 67 deletions(-)

5b638b01fefa46929a284b48e51ae36ad0c63009
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 771e25d..218d317 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -210,7 +210,8 @@ static int gfar_probe(struct platform_de
  		goto regs_fail;
  	}

-	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->txlock);
+	spin_lock_init(&priv->rxlock);

  	platform_set_drvdata(pdev, dev);

@@ -515,11 +516,13 @@ void stop_gfar(struct net_device *dev)
  	phy_stop(priv->phydev);

  	/* Lock it down */
-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);
+	spin_lock(&priv->rxlock);

  	gfar_halt(dev);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock(&priv->rxlock);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	/* Free the IRQs */
  	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
@@ -605,14 +608,15 @@ void gfar_start(struct net_device *dev)
  	tempval |= DMACTRL_INIT_SETTINGS;
  	gfar_write(&priv->regs->dmactrl, tempval);

-	/* Clear THLT, so that the DMA starts polling now */
-	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT);
-
  	/* Make sure we aren't stopped */
  	tempval = gfar_read(&priv->regs->dmactrl);
  	tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
  	gfar_write(&priv->regs->dmactrl, tempval);

+	/* Clear THLT/RHLT, so that the DMA starts polling now */
+	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT);
+	gfar_write(&regs->rstat, RSTAT_CLEAR_RHALT);
+
  	/* Unmask the interrupts we look for */
  	gfar_write(&regs->imask, IMASK_DEFAULT);
  }
@@ -928,12 +932,13 @@ static int gfar_start_xmit(struct sk_buf
  	struct txfcb *fcb = NULL;
  	struct txbd8 *txbdp;
  	u16 status;
+	unsigned long flags;

  	/* Update transmit stats */
  	priv->stats.tx_bytes += skb->len;

  	/* Lock priv now */
-	spin_lock_irq(&priv->lock);
+	spin_lock_irqsave(&priv->txlock, flags);

  	/* Point at the first free tx descriptor */
  	txbdp = priv->cur_tx;
@@ -1004,7 +1009,7 @@ static int gfar_start_xmit(struct sk_buf
  	gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT);

  	/* Unlock priv */
-	spin_unlock_irq(&priv->lock);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	return 0;
  }
@@ -1049,7 +1054,7 @@ static void gfar_vlan_rx_register(struct
  	unsigned long flags;
  	u32 tempval;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->rxlock, flags);

  	priv->vlgrp = grp;

@@ -1076,7 +1081,7 @@ static void gfar_vlan_rx_register(struct
  		gfar_write(&priv->regs->rctrl, tempval);
  	}

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->rxlock, flags);
  }


@@ -1085,12 +1090,12 @@ static void gfar_vlan_rx_kill_vid(struct
  	struct gfar_private *priv = netdev_priv(dev);
  	unsigned long flags;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->rxlock, flags);

  	if (priv->vlgrp)
  		priv->vlgrp->vlan_devices[vid] = NULL;

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->rxlock, flags);
  }


@@ -1179,7 +1184,7 @@ static irqreturn_t gfar_transmit(int irq
  	gfar_write(&priv->regs->ievent, IEVENT_TX_MASK);

  	/* Lock priv */
-	spin_lock(&priv->lock);
+	spin_lock(&priv->txlock);
  	bdp = priv->dirty_tx;
  	while ((bdp->status & TXBD_READY) == 0) {
  		/* If dirty_tx and cur_tx are the same, then either the */
@@ -1224,7 +1229,7 @@ static irqreturn_t gfar_transmit(int irq
  	else
  		gfar_write(&priv->regs->txic, 0);

-	spin_unlock(&priv->lock);
+	spin_unlock(&priv->txlock);

  	return IRQ_HANDLED;
  }
@@ -1305,9 +1310,10 @@ irqreturn_t gfar_receive(int irq, void *
  {
  	struct net_device *dev = (struct net_device *) dev_id;
  	struct gfar_private *priv = netdev_priv(dev);
-
  #ifdef CONFIG_GFAR_NAPI
  	u32 tempval;
+#else
+	unsigned long flags;
  #endif

  	/* Clear IEVENT, so rx interrupt isn't called again
@@ -1330,7 +1336,7 @@ irqreturn_t gfar_receive(int irq, void *
  	}
  #else

-	spin_lock(&priv->lock);
+	spin_lock_irqsave(&priv->rxlock, flags);
  	gfar_clean_rx_ring(dev, priv->rx_ring_size);

  	/* If we are coalescing interrupts, update the timer */
@@ -1341,7 +1347,7 @@ irqreturn_t gfar_receive(int irq, void *
  	else
  		gfar_write(&priv->regs->rxic, 0);

-	spin_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->rxlock, flags);
  #endif

  	return IRQ_HANDLED;
@@ -1490,13 +1496,6 @@ int gfar_clean_rx_ring(struct net_device
  	/* Update the current rxbd pointer to be the next one */
  	priv->cur_rx = bdp;

-	/* If no packets have arrived since the
-	 * last one we processed, clear the IEVENT RX and
-	 * BSY bits so that another interrupt won't be
-	 * generated when we set IMASK */
-	if (bdp->status & RXBD_EMPTY)
-		gfar_write(&priv->regs->ievent, IEVENT_RX_MASK);
-
  	return howmany;
  }

@@ -1516,7 +1515,7 @@ static int gfar_poll(struct net_device *
  	rx_work_limit -= howmany;
  	*budget -= howmany;

-	if (rx_work_limit >= 0) {
+	if (rx_work_limit > 0) {
  		netif_rx_complete(dev);

  		/* Clear the halt bit in RSTAT */
@@ -1533,7 +1532,8 @@ static int gfar_poll(struct net_device *
  			gfar_write(&priv->regs->rxic, 0);
  	}

-	return (rx_work_limit < 0) ? 1 : 0;
+	/* Return 1 if there's more work to do */
+	return (rx_work_limit > 0) ? 0 : 1;
  }
  #endif

@@ -1629,7 +1629,7 @@ static void adjust_link(struct net_devic
  	struct phy_device *phydev = priv->phydev;
  	int new_state = 0;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);
  	if (phydev->link) {
  		u32 tempval = gfar_read(&regs->maccfg2);
  		u32 ecntrl = gfar_read(&regs->ecntrl);
@@ -1694,7 +1694,7 @@ static void adjust_link(struct net_devic
  	if (new_state && netif_msg_link(priv))
  		phy_print_status(phydev);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->txlock, flags);
  }

  /* Update the hash table based on the current list of multicast
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index d37d540..127c98c 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -656,43 +656,62 @@ struct gfar {
   * the buffer descriptor determines the actual condition.
   */
  struct gfar_private {
-	/* pointers to arrays of skbuffs for tx and rx */
+	/* Fields controlled by TX lock */
+	spinlock_t txlock;
+
+	/* Pointer to the array of skbuffs */
  	struct sk_buff ** tx_skbuff;
-	struct sk_buff ** rx_skbuff;

-	/* indices pointing to the next free sbk in skb arrays */
+	/* next free skb in the array */
  	u16 skb_curtx;
-	u16 skb_currx;

-	/* index of the first skb which hasn't been transmitted
-	 * yet. */
+	/* First skb in line to be transmitted */
  	u16 skb_dirtytx;

  	/* Configuration info for the coalescing features */
  	unsigned char txcoalescing;
  	unsigned short txcount;
  	unsigned short txtime;
+
+	/* Buffer descriptor pointers */
+	struct txbd8 *tx_bd_base;	/* First tx buffer descriptor */
+	struct txbd8 *cur_tx;	        /* Next free ring entry */
+	struct txbd8 *dirty_tx;		/* First buffer in line
+					   to be transmitted */
+	unsigned int tx_ring_size;
+
+	/* RX Locked fields */
+	spinlock_t rxlock;
+
+	/* skb array and index */
+	struct sk_buff ** rx_skbuff;
+	u16 skb_currx;
+
+	/* RX Coalescing values */
  	unsigned char rxcoalescing;
  	unsigned short rxcount;
  	unsigned short rxtime;

-	/* GFAR addresses */
-	struct rxbd8 *rx_bd_base;	/* Base addresses of Rx and Tx Buffers */
-	struct txbd8 *tx_bd_base;
+	struct rxbd8 *rx_bd_base;	/* First Rx buffers */
  	struct rxbd8 *cur_rx;           /* Next free rx ring entry */
-	struct txbd8 *cur_tx;	        /* Next free ring entry */
-	struct txbd8 *dirty_tx;		/* The Ring entry to be freed. */
-	struct gfar __iomem *regs;	/* Pointer to the GFAR memory mapped  
Registers */
-	u32 __iomem *hash_regs[16];
-	int hash_width;
-	struct net_device_stats stats; /* linux network statistics */
-	struct gfar_extra_stats extra_stats;
-	spinlock_t lock;
+
+	/* RX parameters */
+	unsigned int rx_ring_size;
  	unsigned int rx_buffer_size;
  	unsigned int rx_stash_size;
  	unsigned int rx_stash_index;
-	unsigned int tx_ring_size;
-	unsigned int rx_ring_size;
+
+	struct vlan_group *vlgrp;
+
+	/* Unprotected fields */
+	/* Pointer to the GFAR memory mapped Registers */
+	struct gfar __iomem *regs;
+
+	/* Hash registers and their width */
+	u32 __iomem *hash_regs[16];
+	int hash_width;
+
+	/* global parameters */
  	unsigned int fifo_threshold;
  	unsigned int fifo_starve;
  	unsigned int fifo_starve_off;
@@ -702,13 +721,15 @@ struct gfar_private {
  		extended_hash:1,
  		bd_stash_en:1;
  	unsigned short padding;
-	struct vlan_group *vlgrp;
-	/* Info structure initialized by board setup code */
+
  	unsigned int interruptTransmit;
  	unsigned int interruptReceive;
  	unsigned int interruptError;
+
+	/* info structure initialized by platform code */
  	struct gianfar_platform_data *einfo;

+	/* PHY stuff */
  	struct phy_device *phydev;
  	struct mii_bus *mii_bus;
  	int oldspeed;
@@ -716,6 +737,10 @@ struct gfar_private {
  	int oldlink;

  	uint32_t msg_enable;
+
+	/* Network Statistics */
+	struct net_device_stats stats;
+	struct gfar_extra_stats extra_stats;
  };

  static inline u32 gfar_read(volatile unsigned __iomem *addr)
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/ 
gianfar_ethtool.c
index 5de7b2e..d69698c 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -455,10 +455,14 @@ static int gfar_sringparam(struct net_de

  		/* Halt TX and RX, and process the frames which
  		 * have already been received */
-		spin_lock_irqsave(&priv->lock, flags);
+		spin_lock_irqsave(&priv->txlock, flags);
+		spin_lock(&priv->rxlock);
+
  		gfar_halt(dev);
  		gfar_clean_rx_ring(dev, priv->rx_ring_size);
-		spin_unlock_irqrestore(&priv->lock, flags);
+
+		spin_unlock(&priv->rxlock);
+		spin_unlock_irqrestore(&priv->txlock, flags);

  		/* Now we take down the rings to rebuild them */
  		stop_gfar(dev);
@@ -488,10 +492,14 @@ static int gfar_set_rx_csum(struct net_d

  		/* Halt TX and RX, and process the frames which
  		 * have already been received */
-		spin_lock_irqsave(&priv->lock, flags);
+		spin_lock_irqsave(&priv->txlock, flags);
+		spin_lock(&priv->rxlock);
+
  		gfar_halt(dev);
  		gfar_clean_rx_ring(dev, priv->rx_ring_size);
-		spin_unlock_irqrestore(&priv->lock, flags);
+
+		spin_unlock(&priv->rxlock);
+		spin_unlock_irqrestore(&priv->txlock, flags);

  		/* Now we take down the rings to rebuild them */
  		stop_gfar(dev);
@@ -523,7 +531,7 @@ static int gfar_set_tx_csum(struct net_d
  	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
  		return -EOPNOTSUPP;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);
  	gfar_halt(dev);

  	if (data)
@@ -532,7 +540,7 @@ static int gfar_set_tx_csum(struct net_d
  		dev->features &= ~NETIF_F_IP_CSUM;

  	gfar_start(dev);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	return 0;
  }
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 51ef181..a6d5c43 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -82,7 +82,7 @@ static ssize_t gfar_set_bd_stash(struct
  	else
  		return count;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->rxlock, flags);

  	/* Set the new stashing value */
  	priv->bd_stash_en = new_setting;
@@ -96,7 +96,7 @@ static ssize_t gfar_set_bd_stash(struct

  	gfar_write(&priv->regs->attr, temp);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->rxlock, flags);

  	return count;
  }
@@ -118,7 +118,7 @@ static ssize_t gfar_set_rx_stash_size(st
  	u32 temp;
  	unsigned long flags;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->rxlock, flags);
  	if (length > priv->rx_buffer_size)
  		return count;

@@ -142,7 +142,7 @@ static ssize_t gfar_set_rx_stash_size(st

  	gfar_write(&priv->regs->attr, temp);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->rxlock, flags);

  	return count;
  }
@@ -166,7 +166,7 @@ static ssize_t gfar_set_rx_stash_index(s
  	u32 temp;
  	unsigned long flags;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->rxlock, flags);
  	if (index > priv->rx_stash_size)
  		return count;

@@ -180,7 +180,7 @@ static ssize_t gfar_set_rx_stash_index(s
  	temp |= ATTRELI_EI(index);
  	gfar_write(&priv->regs->attreli, flags);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->rxlock, flags);

  	return count;
  }
@@ -205,7 +205,7 @@ static ssize_t gfar_set_fifo_threshold(s
  	if (length > GFAR_MAX_FIFO_THRESHOLD)
  		return count;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);

  	priv->fifo_threshold = length;

@@ -214,7 +214,7 @@ static ssize_t gfar_set_fifo_threshold(s
  	temp |= length;
  	gfar_write(&priv->regs->fifo_tx_thr, temp);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	return count;
  }
@@ -240,7 +240,7 @@ static ssize_t gfar_set_fifo_starve(stru
  	if (num > GFAR_MAX_FIFO_STARVE)
  		return count;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);

  	priv->fifo_starve = num;

@@ -249,7 +249,7 @@ static ssize_t gfar_set_fifo_starve(stru
  	temp |= num;
  	gfar_write(&priv->regs->fifo_tx_starve, temp);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	return count;
  }
@@ -274,7 +274,7 @@ static ssize_t gfar_set_fifo_starve_off(
  	if (num > GFAR_MAX_FIFO_STARVE_OFF)
  		return count;

-	spin_lock_irqsave(&priv->lock, flags);
+	spin_lock_irqsave(&priv->txlock, flags);

  	priv->fifo_starve_off = num;

@@ -283,7 +283,7 @@ static ssize_t gfar_set_fifo_starve_off(
  	temp |= num;
  	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);

-	spin_unlock_irqrestore(&priv->lock, flags);
+	spin_unlock_irqrestore(&priv->txlock, flags);

  	return count;
  }
-- 
1.2.4

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [git patches] net driver fixes
From: Jeff Garzik @ 2006-04-12 23:04 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Andrew Morton, Linus Torvalds, netdev, linux-kernel
In-Reply-To: <1BF241D7-89AE-4519-A56F-9241CE5D57CF@kernel.crashing.org>

Kumar Gala wrote:
> 
> On Apr 12, 2006, at 5:45 PM, Jeff Garzik wrote:
> 
>> Kumar Gala wrote:
>>> Jeff,
>>> Noticed Andy's gianfar fixes aren't in here.  I'd be good to see if 
>>> we can get them in for 2.6.17
>>
>> Never saw them...
> 
> Odd, posted to netdev, Andy may not have copied you on them.
> 
> http://marc.theaimsgroup.com/?l=linux-netdev&m=114437381506340&w=2

That's fine, but I don't have it.  Please resend, git-applymbox doesn't 
work on URLs.

	Jeff




^ permalink raw reply

* Re: [git patches] net driver fixes
From: Kumar Gala @ 2006-04-12 22:47 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Andrew Morton, Linus Torvalds, netdev, linux-kernel
In-Reply-To: <443D8310.5020304@garzik.org>


On Apr 12, 2006, at 5:45 PM, Jeff Garzik wrote:

> Kumar Gala wrote:
>> Jeff,
>> Noticed Andy's gianfar fixes aren't in here.  I'd be good to see  
>> if we can get them in for 2.6.17
>
> Never saw them...

Odd, posted to netdev, Andy may not have copied you on them.

http://marc.theaimsgroup.com/?l=linux-netdev&m=114437381506340&w=2

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox