| 3124 | } |
| 3125 | |
| 3126 | static int |
| 3127 | ht_send_action_ht_txchwidth(struct ieee80211_node *ni, |
| 3128 | int category, int action, void *arg0) |
| 3129 | { |
| 3130 | struct ieee80211vap *vap = ni->ni_vap; |
| 3131 | struct ieee80211com *ic = ni->ni_ic; |
| 3132 | struct mbuf *m; |
| 3133 | uint8_t *frm; |
| 3134 | |
| 3135 | IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, |
| 3136 | "send HT txchwidth: width %d", |
| 3137 | IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20); |
| 3138 | |
| 3139 | IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, |
| 3140 | "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, |
| 3141 | ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); |
| 3142 | ieee80211_ref_node(ni); |
| 3143 | |
| 3144 | m = ieee80211_getmgtframe(&frm, |
| 3145 | ic->ic_headroom + sizeof(struct ieee80211_frame), |
| 3146 | sizeof(uint16_t) /* action+category */ |
| 3147 | /* XXX may action payload */ |
| 3148 | + sizeof(struct ieee80211_action_ba_addbaresponse) |
| 3149 | ); |
| 3150 | if (m != NULL) { |
| 3151 | *frm++ = category; |
| 3152 | *frm++ = action; |
| 3153 | *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? |
| 3154 | IEEE80211_A_HT_TXCHWIDTH_2040 : |
| 3155 | IEEE80211_A_HT_TXCHWIDTH_20; |
| 3156 | m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); |
| 3157 | return ht_action_output(ni, m); |
| 3158 | } else { |
| 3159 | vap->iv_stats.is_tx_nobuf++; |
| 3160 | ieee80211_free_node(ni); |
| 3161 | return ENOMEM; |
| 3162 | } |
| 3163 | } |
| 3164 | #undef ADDSHORT |
| 3165 | |
| 3166 | /* |
nothing calls this directly
no test coverage detected