diff mbox

[RFC] cfg80211: send country ie processing on the reg_work struct

Message ID 1248744593-6597-1-git-send-email-lrodriguez@atheros.com (mailing list archive)
State RFC, archived
Headers show

Commit Message

Luis Rodriguez July 28, 2009, 1:29 a.m. UTC
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---

Did this in a flash, so just want to see if this is you like this
approach. Of course a lot of cleaning can be done here but ignore that
for now (like the fact that beacon hint doesn't really process IEs,
and the functions names used here).

This just compiles for me, never tested it.

 net/wireless/reg.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 93 insertions(+), 8 deletions(-)

Comments

Johannes Berg July 28, 2009, 7:37 a.m. UTC | #1
On Mon, 2009-07-27 at 18:29 -0700, Luis R. Rodriguez wrote:
> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> ---
> 
> Did this in a flash, so just want to see if this is you like this
> approach. Of course a lot of cleaning can be done here but ignore that
> for now (like the fact that beacon hint doesn't really process IEs,
> and the functions names used here).
> 
> This just compiles for me, never tested it.

Looks ok, but I don't see why you need this type enum?

> + * enum beacon_hint_type - type of regulatory beacon hint

I mean -- if the beacon was received we could just process it as before,
and if it also has a country IE we can just process that additionally?
Why bother doing both separately?

Also, I would have allocated the struct and the space for the IE
together, but that really doesn't matter :)

johannes
Luis Rodriguez July 28, 2009, 3:21 p.m. UTC | #2
On Tue, Jul 28, 2009 at 12:37 AM, Johannes
Berg<johannes@sipsolutions.net> wrote:
> On Mon, 2009-07-27 at 18:29 -0700, Luis R. Rodriguez wrote:
>> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
>> ---
>>
>> Did this in a flash, so just want to see if this is you like this
>> approach. Of course a lot of cleaning can be done here but ignore that
>> for now (like the fact that beacon hint doesn't really process IEs,
>> and the functions names used here).
>>
>> This just compiles for me, never tested it.
>
> Looks ok, but I don't see why you need this type enum?

To make it clear what type of beacon hint this is. I could have just
used an element in the struct reg_beacon but thought this would make
it more clear to the reader.

>> + * enum beacon_hint_type - type of regulatory beacon hint
>
> I mean -- if the beacon was received we could just process it as before,
> and if it also has a country IE we can just process that additionally?
> Why bother doing both separately?

I agree with you but this is different than addressing just the
lockdep warning and I wasn't really planning on doing that right now,
but it seems the work required may not be that much, I'll see if I can
just do it...

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

Patch

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index fb40428..3005ddf 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -73,9 +73,35 @@  static spinlock_t reg_pending_beacons_lock;
 /* Used to keep track of processed beacon hints */
 static LIST_HEAD(reg_beacon_list);
 
+/**
+ * enum beacon_hint_type - type of regulatory beacon hint
+ *
+ * Beacons contain useful information for regulatory purposes.
+ * Regular beacons are useful as they indicate to world
+ * roaming stations that an AP is nearby. With careful precautions
+ * taken one can use this to assess whether or not one can lift
+ * passive scan flags and no-ibss flags on a channel.
+ * Beacons also contain certain information elements, the country
+ * IE is very specific to regulatory and contains channels specific
+ * information an AP is indicating should be respected.
+ *
+ * @REG_BEACON: indicates a beacon has been received on a
+ *	specified channel. This is useful for world roaming.
+ * @REG_BEACON_COUNTRY_IE: indicates a beacon has been received
+ *	with a country IE attached.
+ */
+enum beacon_hint_type {
+	REG_BEACON,
+	REG_BEACON_COUNTRY_IE,
+};
+
 struct reg_beacon {
+	enum beacon_hint_type type;
+	struct wiphy *wiphy;
 	struct list_head list;
 	struct ieee80211_channel chan;
+	u8 *ie;
+	u8 ie_len;
 };
 
 /* We keep a static world regulatory domain in case of the absence of CRDA */
@@ -1607,10 +1633,35 @@  static void reg_process_pending_hints(void)
 	spin_unlock(&reg_requests_lock);
 }
 
-/* Processes beacon hints -- this has nothing to do with country IEs */
-static void reg_process_pending_beacon_hints(void)
+static void processs_reg_beacon(struct reg_beacon *reg_beacon)
 {
 	struct cfg80211_registered_device *rdev;
+
+	/* Applies the beacon hint to current wiphys */
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+		wiphy_update_new_beacon(&rdev->wiphy, reg_beacon);
+
+	/* Remembers the beacon hint for new wiphys or reg changes */
+	list_add_tail(&reg_beacon->list, &reg_beacon_list);
+}
+
+
+static void regulatory_hint_11d_work(struct wiphy *wiphy,
+				     u8 *country_ie,
+				     u8 country_ie_len);
+
+static void process_reg_beacon_country_ie(struct reg_beacon *reg_beacon)
+{
+	regulatory_hint_11d_work(reg_beacon->wiphy,
+				 reg_beacon->ie,
+				 reg_beacon->ie_len);
+	kfree(reg_beacon->ie);
+	kfree(reg_beacon);
+}
+
+/* Processes beacon hints */
+static void reg_process_pending_beacon_hints(void)
+{
 	struct reg_beacon *pending_beacon, *tmp;
 
 	mutex_lock(&cfg80211_mutex);
@@ -1628,12 +1679,14 @@  static void reg_process_pending_beacon_hints(void)
 
 		list_del_init(&pending_beacon->list);
 
-		/* Applies the beacon hint to current wiphys */
-		list_for_each_entry(rdev, &cfg80211_rdev_list, list)
-			wiphy_update_new_beacon(&rdev->wiphy, pending_beacon);
-
-		/* Remembers the beacon hint for new wiphys or reg changes */
-		list_add_tail(&pending_beacon->list, &reg_beacon_list);
+		switch (pending_beacon->type) {
+		case REG_BEACON:
+			processs_reg_beacon(pending_beacon);
+			break;
+		case REG_BEACON_COUNTRY_IE:
+			process_reg_beacon_country_ie(pending_beacon);
+			break;
+		}
 	}
 
 	spin_unlock_bh(&reg_pending_beacons_lock);
@@ -1766,6 +1819,37 @@  void regulatory_hint_11d(struct wiphy *wiphy,
 			u8 *country_ie,
 			u8 country_ie_len)
 {
+	struct reg_beacon *reg_beacon;
+
+	reg_beacon = kzalloc(sizeof(struct reg_beacon), GFP_KERNEL);
+	if (!reg_beacon)
+		return;
+
+	reg_beacon->ie = kzalloc(country_ie_len, GFP_KERNEL);
+	if (!reg_beacon->ie) {
+		kfree(reg_beacon);
+		return;
+	}
+
+	reg_beacon->wiphy = wiphy;
+	reg_beacon->ie_len = country_ie_len;
+	reg_beacon->type = REG_BEACON_COUNTRY_IE;
+
+	memcpy(&reg_beacon->ie, country_ie, reg_beacon->ie_len);
+
+	spin_lock_bh(&reg_pending_beacons_lock);
+	list_add_tail(&reg_beacon->list, &reg_pending_beacons);
+	spin_unlock_bh(&reg_pending_beacons_lock);
+
+	schedule_work(&reg_work);
+
+	return;
+}
+
+static void regulatory_hint_11d_work(struct wiphy *wiphy,
+				     u8 *country_ie,
+				     u8 country_ie_len)
+{
 	struct ieee80211_regdomain *rd = NULL;
 	char alpha2[2];
 	u32 checksum = 0;
@@ -1933,6 +2017,7 @@  int regulatory_hint_found_beacon(struct wiphy *wiphy,
 	memcpy(&reg_beacon->chan, beacon_chan,
 		sizeof(struct ieee80211_channel));
 
+	reg_beacon->type = REG_BEACON;
 
 	/*
 	 * Since we can be called from BH or and non-BH context