vsprintf: move local vars to block local vars and remove unneeded ones
[safe/jmp/linux-2.6] / net / mac80211 / mesh_plink.c
index cb14253..0f7c6e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 open80211s Ltd.
+ * Copyright (c) 2008, 2009 open80211s Ltd.
  * Author:     Luis Carlos Cobo <luisca@cozybit.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,9 +18,8 @@
 #define mpl_dbg(fmt, args...)  do { (void)(0); } while (0)
 #endif
 
-#define PLINK_GET_FRAME_SUBTYPE(p) (p)
-#define PLINK_GET_LLID(p) (p + 1)
-#define PLINK_GET_PLID(p) (p + 3)
+#define PLINK_GET_LLID(p) (p + 4)
+#define PLINK_GET_PLID(p) (p + 6)
 
 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
                                jiffies + HZ * t / 1000))
@@ -65,6 +64,7 @@ void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
 {
        atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
        mesh_accept_plinks_update(sdata);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
 }
 
 static inline
@@ -72,12 +72,13 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
 {
        atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
        mesh_accept_plinks_update(sdata);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
 }
 
 /**
  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
  *
- * @sta: mes peer link to restart
+ * @sta: mesh peer link to restart
  *
  * Locking: this function must be called holding sta->lock
  */
@@ -152,6 +153,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
        struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
        struct ieee80211_mgmt *mgmt;
        bool include_plid = false;
+       static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
        u8 *pos;
        int ie_len;
 
@@ -169,7 +171,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
        memcpy(mgmt->da, da, ETH_ALEN);
        memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
        /* BSSID is left zeroed, wildcard value */
-       mgmt->u.action.category = PLINK_CATEGORY;
+       mgmt->u.action.category = MESH_PLINK_CATEGORY;
        mgmt->u.action.u.plink_action.action_code = action;
 
        if (action == PLINK_CLOSE)
@@ -179,7 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                if (action == PLINK_CONFIRM) {
                        pos = skb_put(skb, 4);
                        /* two-byte status code followed by two-byte AID */
-                       memset(pos, 0, 4);
+                       memset(pos, 0, 2);
+                       memcpy(pos + 2, &plid, 2);
                }
                mesh_mgmt_ies_add(skb, sdata);
        }
@@ -187,18 +190,18 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
        /* Add Peer Link Management element */
        switch (action) {
        case PLINK_OPEN:
-               ie_len = 3;
+               ie_len = 6;
                break;
        case PLINK_CONFIRM:
-               ie_len = 5;
+               ie_len = 8;
                include_plid = true;
                break;
        case PLINK_CLOSE:
        default:
                if (!plid)
-                       ie_len = 5;
+                       ie_len = 8;
                else {
-                       ie_len = 7;
+                       ie_len = 10;
                        include_plid = true;
                }
                break;
@@ -207,7 +210,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
        pos = skb_put(skb, 2 + ie_len);
        *pos++ = WLAN_EID_PEER_LINK;
        *pos++ = ie_len;
-       *pos++ = action;
+       memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto));
+       pos += 4;
        memcpy(pos, &llid, 2);
        if (include_plid) {
                pos += 2;
@@ -218,7 +222,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                memcpy(pos, &reason, 2);
        }
 
-       ieee80211_tx_skb(sdata, skb, 1);
+       ieee80211_tx_skb(sdata, skb);
        return 0;
 }
 
@@ -395,6 +399,17 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        u8 ie_len;
        u8 *baseaddr;
        __le16 plid, llid, reason;
+#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
+       static const char *mplstates[] = {
+               [PLINK_LISTEN] = "LISTEN",
+               [PLINK_OPN_SNT] = "OPN-SNT",
+               [PLINK_OPN_RCVD] = "OPN-RCVD",
+               [PLINK_CNF_RCVD] = "CNF_RCVD",
+               [PLINK_ESTAB] = "ESTAB",
+               [PLINK_HOLDING] = "HOLDING",
+               [PLINK_BLOCKED] = "BLOCKED"
+       };
+#endif
 
        /* need action_code, aux */
        if (len < IEEE80211_MIN_ACTION_SIZE + 3)
@@ -409,7 +424,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
        if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
                baseaddr += 4;
-               baselen -= 4;
+               baselen += 4;
        }
        ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
        if (!elems.peer_link) {
@@ -417,12 +432,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                return;
        }
 
-       ftype = *((u8 *)PLINK_GET_FRAME_SUBTYPE(elems.peer_link));
+       ftype = mgmt->u.action.u.plink_action.action_code;
        ie_len = elems.peer_link_len;
-       if ((ftype == PLINK_OPEN && ie_len != 3) ||
-           (ftype == PLINK_CONFIRM && ie_len != 5) ||
-           (ftype == PLINK_CLOSE && ie_len != 5 && ie_len != 7)) {
-               mpl_dbg("Mesh plink: incorrect plink ie length\n");
+       if ((ftype == PLINK_OPEN && ie_len != 6) ||
+           (ftype == PLINK_CONFIRM && ie_len != 8) ||
+           (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) {
+               mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
+                   ftype, ie_len);
                return;
        }
 
@@ -434,7 +450,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
         * from the point of view of this host.
         */
        memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
-       if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7))
+       if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10))
                memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
 
        rcu_read_lock();
@@ -532,8 +548,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                }
        }
 
-       mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %d %d %d %d\n",
-               mgmt->sa, sta->plink_state,
+       mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
+               mgmt->sa, mplstates[sta->plink_state],
                le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
                event);
        reason = 0;