From owner-svn-src-projects@FreeBSD.ORG Thu Apr 30 13:44:59 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CCB331065670; Thu, 30 Apr 2009 13:44:59 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BAC488FC08; Thu, 30 Apr 2009 13:44:59 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n3UDixkd013801; Thu, 30 Apr 2009 13:44:59 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3UDixdY013795; Thu, 30 Apr 2009 13:44:59 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <200904301344.n3UDixdY013795@svn.freebsd.org> From: Rui Paulo Date: Thu, 30 Apr 2009 13:44:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191689 - projects/mesh11s/sys/net80211 X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2009 13:45:00 -0000 Author: rpaulo Date: Thu Apr 30 13:44:59 2009 New Revision: 191689 URL: http://svn.freebsd.org/changeset/base/191689 Log: Move ieee80211_recv_action() to ieee80211_input.c and ieee80211_send_action() to ieee80211_output.c because they are used both by 11s and 11n. Sponsored by: The FreeBSD Foundation Modified: projects/mesh11s/sys/net80211/ieee80211_ht.c projects/mesh11s/sys/net80211/ieee80211_ht.h projects/mesh11s/sys/net80211/ieee80211_input.c projects/mesh11s/sys/net80211/ieee80211_input.h projects/mesh11s/sys/net80211/ieee80211_output.c projects/mesh11s/sys/net80211/ieee80211_proto.h Modified: projects/mesh11s/sys/net80211/ieee80211_ht.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_ht.c Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_ht.c Thu Apr 30 13:44:59 2009 (r191689) @@ -1732,84 +1732,6 @@ ieee80211_aggr_recv_action(struct ieee80 } /* - * Process a received 802.11n action frame. - * Aggregation-related frames are assumed to be handled - * already; we handle any other frames we can, otherwise - * complain about being unsupported (with debugging). - */ -void -ieee80211_recv_action(struct ieee80211_node *ni, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_action *ia; - int chw; - - ia = (const struct ieee80211_action *) frm; - switch (ia->ia_category) { - case IEEE80211_ACTION_CAT_BA: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: BA action %d not implemented", __func__, - ia->ia_action); - vap->iv_stats.is_rx_mgtdiscard++; - break; - case IEEE80211_ACTION_CAT_HT: - switch (ia->ia_action) { - case IEEE80211_ACTION_HT_TXCHWIDTH: - chw = frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040 ? 40 : 20; - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT txchwidth, width %d%s", - __func__, chw, ni->ni_chw != chw ? "*" : ""); - if (chw != ni->ni_chw) { - ni->ni_chw = chw; - /* XXX notify on change */ - } - break; - case IEEE80211_ACTION_HT_MIMOPWRSAVE: { - const struct ieee80211_action_ht_mimopowersave *mps = - (const struct ieee80211_action_ht_mimopowersave *) ia; - /* XXX check iv_htcaps */ - if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) - ni->ni_flags |= IEEE80211_NODE_MIMO_PS; - else - ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; - if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) - ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; - else - ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; - /* XXX notify on change */ - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT MIMO PS (%s%s)", __func__, - (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? - "on" : "off", - (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? - "+rts" : "" - ); - break; - } - default: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT action %d not implemented", __func__, - ia->ia_action); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - break; - default: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: category %d not implemented", __func__, - ia->ia_category); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } -} - -/* * Transmit processing. */ @@ -2102,199 +2024,6 @@ bad: } /* - * Send an action management frame. The arguments are stuff - * into a frame without inspection; the caller is assumed to - * prepare them carefully (e.g. based on the aggregation state). - */ -int -ieee80211_send_action(struct ieee80211_node *ni, - int category, int action, uint16_t args[4]) -{ -#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_bpf_params params; - struct mbuf *m; - uint8_t *frm; - uint16_t baparamset; - int ret, addsize; - - KASSERT(ni != NULL, ("null node")); - - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - addsize = 0; - switch (category) { - case IEEE80211_ACTION_CAT_BA: - case IEEE80211_ACTION_CAT_HT: - addsize += sizeof(struct ieee80211_action_ba_addbaresponse); - break; - case IEEE80211_ACTION_CAT_MESHPEERING: - addsize += sizeof(uint16_t); /* capabilities */ - addsize += 2 + vap->iv_meshidlen; /* Mesh ID */ - addsize += sizeof(struct ieee80211_meshconf_ie); - /* On Open frames, the peer link ID is not sent */ - if (action == IEEE80211_ACTION_MESHPEERING_OPEN) - addsize += sizeof(struct ieee80211_meshpeer_ie) - 2; - else - addsize += sizeof(struct ieee80211_meshpeer_ie); - break; - } - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - /* XXX may action payload */ - + addsize - - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - *frm++ = category; - *frm++ = action; - switch (category) { - case IEEE80211_ACTION_CAT_BA: - switch (action) { - case IEEE80211_ACTION_BA_ADDBA_REQUEST: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send ADDBA request: dialogtoken %d " - "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x", - args[0], args[1], MS(args[1], IEEE80211_BAPS_TID), - args[2], args[3]); - - *frm++ = args[0]; /* dialog token */ - ADDSHORT(frm, args[1]); /* baparamset */ - ADDSHORT(frm, args[2]); /* batimeout */ - ADDSHORT(frm, args[3]); /* baseqctl */ - break; - case IEEE80211_ACTION_BA_ADDBA_RESPONSE: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send ADDBA response: dialogtoken %d status %d " - "baparamset 0x%x (tid %d) batimeout %d", - args[0], args[1], args[2], - MS(args[2], IEEE80211_BAPS_TID), args[3]); - - *frm++ = args[0]; /* dialog token */ - ADDSHORT(frm, args[1]); /* statuscode */ - ADDSHORT(frm, args[2]); /* baparamset */ - ADDSHORT(frm, args[3]); /* batimeout */ - break; - case IEEE80211_ACTION_BA_DELBA: - /* XXX */ - baparamset = SM(args[0], IEEE80211_DELBAPS_TID) - | args[1] - ; - ADDSHORT(frm, baparamset); - ADDSHORT(frm, args[2]); /* reason code */ - - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send DELBA action: tid %d, initiator %d reason %d", - args[0], args[1], args[2]); - break; - default: - goto badaction; - } - break; - case IEEE80211_ACTION_CAT_HT: - switch (action) { - case IEEE80211_ACTION_HT_TXCHWIDTH: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "send HT txchwidth: width %d", - IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20 - ); - *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? - IEEE80211_A_HT_TXCHWIDTH_2040 : - IEEE80211_A_HT_TXCHWIDTH_20; - break; - default: - goto badaction; - } - break; - case IEEE80211_ACTION_CAT_MESHPEERING: - - switch (action) { - case IEEE80211_ACTION_MESHPEERING_OPEN: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER OPEN action: lid %x", args[0]); - *frm++ = 0; /* capabilites */ - *frm++ = 0; - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshconf(frm, vap); - *frm++ = IEEE80211_ELEMID_MESHPEER; - *frm++ = 3; /* len */ - *frm++ = IEEE80211_MESH_PEER_LINK_OPEN; /* subtype */ - ADDSHORT(frm, args[0]); /* local ID */ - break; - case IEEE80211_ACTION_MESHPEERING_CONFIRM: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER CONFIRM action: lid %x, pid %x", - args[0], args[1]); - *frm++ = 0; /* capabilites */ - *frm++ = 0; - *frm++ = 0; /* status code */ - *frm++ = 0; - *frm++ = 0; /* AID */ - *frm++ = 0; - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshconf(frm, vap); - *frm++ = IEEE80211_ELEMID_MESHPEER; - *frm++ = 5; /* len */ - *frm++ = IEEE80211_MESH_PEER_LINK_CONFIRM; /* subtype */ - ADDSHORT(frm, args[0]); - ADDSHORT(frm, args[1]); - break; - } - break; - default: - badaction: - IEEE80211_NOTE(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: unsupported category %d action %d", __func__, - category, action); - senderr(EINVAL, is_tx_unknownmgt); - /* NOTREACHED */ - } - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - - memset(¶ms, 0, sizeof(params)); - params.ibp_pri = WME_AC_VO; - params.ibp_rate0 = ni->ni_txparms->mgmtrate; - /* NB: we know all frames are unicast */ - params.ibp_try0 = ni->ni_txparms->maxretry; - params.ibp_power = ni->ni_txpower; - return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION, - ¶ms); -bad: - ieee80211_free_node(ni); - if (m != NULL) - m_freem(m); - return ret; -#undef ADDSHORT -#undef senderr -} - -/* * Construct the MCS bit mask for inclusion * in an HT information element. */ Modified: projects/mesh11s/sys/net80211/ieee80211_ht.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_ht.h Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_ht.h Thu Apr 30 13:44:59 2009 (r191689) @@ -186,16 +186,12 @@ void ieee80211_parse_htinfo(struct ieee8 void ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *, const uint8_t *); void ieee80211_ht_updatehtcap(struct ieee80211_node *, const uint8_t *); -void ieee80211_recv_action(struct ieee80211_node *, - const uint8_t *, const uint8_t *); int ieee80211_ampdu_request(struct ieee80211_node *, struct ieee80211_tx_ampdu *); void ieee80211_ampdu_stop(struct ieee80211_node *, struct ieee80211_tx_ampdu *, int); int ieee80211_send_bar(struct ieee80211_node *, struct ieee80211_tx_ampdu *, ieee80211_seq); -int ieee80211_send_action(struct ieee80211_node *, - int, int, uint16_t [4]); uint8_t *ieee80211_add_htcap(uint8_t *, struct ieee80211_node *); uint8_t *ieee80211_add_htcap_vendor(uint8_t *, struct ieee80211_node *); uint8_t *ieee80211_add_htinfo(uint8_t *, struct ieee80211_node *); Modified: projects/mesh11s/sys/net80211/ieee80211_input.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_input.c Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_input.c Thu Apr 30 13:44:59 2009 (r191689) @@ -739,6 +739,85 @@ ieee80211_parse_action(struct ieee80211_ return 0; } +/* + * Process a received 802.11 action frame. + * Aggregation-related frames are assumed to be handled + * already; we handle any other frames we can, otherwise + * complain about being unsupported (with debugging). + */ +void +ieee80211_recv_action(struct ieee80211_node *ni, + const uint8_t *frm, const uint8_t *efrm) +{ + struct ieee80211vap *vap = ni->ni_vap; + const struct ieee80211_action *ia; + int chw; + + ia = (const struct ieee80211_action *) frm; + switch (ia->ia_category) { + case IEEE80211_ACTION_CAT_BA: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: BA action %d not implemented", __func__, + ia->ia_action); + vap->iv_stats.is_rx_mgtdiscard++; + break; + case IEEE80211_ACTION_CAT_HT: + switch (ia->ia_action) { + case IEEE80211_ACTION_HT_TXCHWIDTH: + chw = frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040 ? 40 : 20; + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: HT txchwidth, width %d%s", + __func__, chw, ni->ni_chw != chw ? "*" : ""); + if (chw != ni->ni_chw) { + ni->ni_chw = chw; + /* XXX notify on change */ + } + break; + case IEEE80211_ACTION_HT_MIMOPWRSAVE: { + const struct ieee80211_action_ht_mimopowersave *mps = + (const struct ieee80211_action_ht_mimopowersave *) ia; + /* XXX check iv_htcaps */ + if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) + ni->ni_flags |= IEEE80211_NODE_MIMO_PS; + else + ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; + if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) + ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; + else + ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; + /* XXX notify on change */ + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: HT MIMO PS (%s%s)", __func__, + (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? + "on" : "off", + (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? + "+rts" : "" + ); + break; + } + default: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: HT action %d not implemented", __func__, + ia->ia_action); + vap->iv_stats.is_rx_mgtdiscard++; + break; + } + break; + default: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: category %d not implemented", __func__, + ia->ia_category); + vap->iv_stats.is_rx_mgtdiscard++; + break; + } +} + + #ifdef IEEE80211_DEBUG /* * Debugging support. Modified: projects/mesh11s/sys/net80211/ieee80211_input.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_input.h Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_input.h Thu Apr 30 13:44:59 2009 (r191689) @@ -156,4 +156,6 @@ int ieee80211_alloc_challenge(struct iee int ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *, struct ieee80211_scanparams *); int ieee80211_parse_action(struct ieee80211_node *, struct mbuf *); +void ieee80211_recv_action(struct ieee80211_node *, const uint8_t *, + const uint8_t *); #endif /* _NET80211_IEEE80211_INPUT_H_ */ Modified: projects/mesh11s/sys/net80211/ieee80211_output.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_output.c Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_output.c Thu Apr 30 13:44:59 2009 (r191689) @@ -527,6 +527,204 @@ ieee80211_send_setup( } /* + * Send an action management frame. The arguments are stuff + * into a frame without inspection; the caller is assumed to + * prepare them carefully (e.g. based on the aggregation state). + */ +int +ieee80211_send_action(struct ieee80211_node *ni, + int category, int action, uint16_t args[4]) +{ +#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) +#define ADDSHORT(frm, v) do { \ + frm[0] = (v) & 0xff; \ + frm[1] = (v) >> 8; \ + frm += 2; \ +} while (0) +#define MS(_v, _f) (((_v) & _f) >> _f##_S) +#define SM(_v, _f) (((_v) << _f##_S) & _f) + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_bpf_params params; + struct mbuf *m; + uint8_t *frm; + uint16_t baparamset; + int ret, addsize; + + KASSERT(ni != NULL, ("null node")); + + /* + * Hold a reference on the node so it doesn't go away until after + * the xmit is complete all the way in the driver. On error we + * will remove our reference. + */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, + "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", + __func__, __LINE__, + ni, ether_sprintf(ni->ni_macaddr), + ieee80211_node_refcnt(ni)+1); + ieee80211_ref_node(ni); + + addsize = 0; + switch (category) { + case IEEE80211_ACTION_CAT_BA: + case IEEE80211_ACTION_CAT_HT: + addsize += sizeof(struct ieee80211_action_ba_addbaresponse); + break; + case IEEE80211_ACTION_CAT_MESHPEERING: + addsize += sizeof(uint16_t); /* capabilities */ + addsize += 2 + vap->iv_meshidlen; /* Mesh ID */ + addsize += sizeof(struct ieee80211_meshconf_ie); + /* On Open frames, the peer link ID is not sent */ + if (action == IEEE80211_ACTION_MESHPEERING_OPEN) + addsize += sizeof(struct ieee80211_meshpeer_ie) - 2; + else + addsize += sizeof(struct ieee80211_meshpeer_ie); + break; + } + m = ieee80211_getmgtframe(&frm, + ic->ic_headroom + sizeof(struct ieee80211_frame), + sizeof(uint16_t) /* action+category */ + /* XXX may action payload */ + + addsize + + ); + if (m == NULL) + senderr(ENOMEM, is_tx_nobuf); + + *frm++ = category; + *frm++ = action; + switch (category) { + case IEEE80211_ACTION_CAT_BA: + switch (action) { + case IEEE80211_ACTION_BA_ADDBA_REQUEST: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "send ADDBA request: dialogtoken %d " + "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x", + args[0], args[1], MS(args[1], IEEE80211_BAPS_TID), + args[2], args[3]); + + *frm++ = args[0]; /* dialog token */ + ADDSHORT(frm, args[1]); /* baparamset */ + ADDSHORT(frm, args[2]); /* batimeout */ + ADDSHORT(frm, args[3]); /* baseqctl */ + break; + case IEEE80211_ACTION_BA_ADDBA_RESPONSE: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "send ADDBA response: dialogtoken %d status %d " + "baparamset 0x%x (tid %d) batimeout %d", + args[0], args[1], args[2], + MS(args[2], IEEE80211_BAPS_TID), args[3]); + + *frm++ = args[0]; /* dialog token */ + ADDSHORT(frm, args[1]); /* statuscode */ + ADDSHORT(frm, args[2]); /* baparamset */ + ADDSHORT(frm, args[3]); /* batimeout */ + break; + case IEEE80211_ACTION_BA_DELBA: + /* XXX */ + baparamset = SM(args[0], IEEE80211_DELBAPS_TID) + | args[1] + ; + ADDSHORT(frm, baparamset); + ADDSHORT(frm, args[2]); /* reason code */ + + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "send DELBA action: tid %d, initiator %d reason %d", + args[0], args[1], args[2]); + break; + default: + goto badaction; + } + break; + case IEEE80211_ACTION_CAT_HT: + switch (action) { + case IEEE80211_ACTION_HT_TXCHWIDTH: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, + ni, "send HT txchwidth: width %d", + IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20 + ); + *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? + IEEE80211_A_HT_TXCHWIDTH_2040 : + IEEE80211_A_HT_TXCHWIDTH_20; + break; + default: + goto badaction; + } + break; + case IEEE80211_ACTION_CAT_MESHPEERING: + + switch (action) { + case IEEE80211_ACTION_MESHPEERING_OPEN: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, + "send PEER OPEN action: lid %x", args[0]); + *frm++ = 0; /* capabilites */ + *frm++ = 0; + frm = ieee80211_add_meshid(frm, vap); + frm = ieee80211_add_meshconf(frm, vap); + *frm++ = IEEE80211_ELEMID_MESHPEER; + *frm++ = 3; /* len */ + *frm++ = IEEE80211_MESH_PEER_LINK_OPEN; /* subtype */ + ADDSHORT(frm, args[0]); /* local ID */ + break; + case IEEE80211_ACTION_MESHPEERING_CONFIRM: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, + "send PEER CONFIRM action: lid %x, pid %x", + args[0], args[1]); + *frm++ = 0; /* capabilites */ + *frm++ = 0; + *frm++ = 0; /* status code */ + *frm++ = 0; + *frm++ = 0; /* AID */ + *frm++ = 0; + frm = ieee80211_add_meshid(frm, vap); + frm = ieee80211_add_meshconf(frm, vap); + *frm++ = IEEE80211_ELEMID_MESHPEER; + *frm++ = 5; /* len */ + *frm++ = IEEE80211_MESH_PEER_LINK_CONFIRM; /* subtype */ + ADDSHORT(frm, args[0]); + ADDSHORT(frm, args[1]); + break; + } + break; + default: + badaction: + IEEE80211_NOTE(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, + "%s: unsupported category %d action %d", __func__, + category, action); + senderr(EINVAL, is_tx_unknownmgt); + /* NOTREACHED */ + } + m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); + + memset(¶ms, 0, sizeof(params)); + params.ibp_pri = WME_AC_VO; + params.ibp_rate0 = ni->ni_txparms->mgmtrate; + /* NB: we know all frames are unicast */ + params.ibp_try0 = ni->ni_txparms->maxretry; + params.ibp_power = ni->ni_txpower; + return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION, + ¶ms); +bad: + ieee80211_free_node(ni); + if (m != NULL) + m_freem(m); + return ret; +#undef ADDSHORT +#undef senderr +#undef MS +#undef SM +} + + +/* * Send a management frame to the specified node. The node pointer * must have a reference as the pointer will be passed to the driver * and potentially held for a long time. If the frame is successfully Modified: projects/mesh11s/sys/net80211/ieee80211_proto.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_proto.h Thu Apr 30 13:36:26 2009 (r191688) +++ projects/mesh11s/sys/net80211/ieee80211_proto.h Thu Apr 30 13:44:59 2009 (r191689) @@ -65,6 +65,7 @@ void ieee80211_syncflag_ext(struct ieee8 int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int, uint32_t); struct ieee80211_bpf_params; +int ieee80211_send_action(struct ieee80211_node *, int, int, uint16_t [4]); int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int, struct ieee80211_bpf_params *); int ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,