/* Default mapping in classifier to work with default * queue setup.
*/ constint ieee802_1d_to_ac[8] = {
IEEE80211_AC_BE,
IEEE80211_AC_BK,
IEEE80211_AC_BK,
IEEE80211_AC_BE,
IEEE80211_AC_VI,
IEEE80211_AC_VI,
IEEE80211_AC_VO,
IEEE80211_AC_VO
};
staticint wme_downgrade_ac(struct sk_buff *skb)
{ switch (skb->priority) { case 6: case 7:
skb->priority = 5; /* VO -> VI */ return 0; case 4: case 5:
skb->priority = 3; /* VI -> BE */ return 0; case 0: case 3:
skb->priority = 2; /* BE -> BK */ return 0; default: return -1;
}
}
/** * ieee80211_fix_reserved_tid - return the TID to use if this one is reserved * @tid: the assumed-reserved TID * * Returns: the alternative TID to use, or 0 on error
*/ staticinline u8 ieee80211_fix_reserved_tid(u8 tid)
{ switch (tid) { case 0: return 3; case 1: return 2; case 2: return 1; case 3: return 0; case 4: return 5; case 5: return 4; case 6: return 7; case 7: return 6;
}
/* in case we are a client verify acm is not set for this ac */ while (sdata->wmm_acm & BIT(skb->priority)) { int ac = ieee802_1d_to_ac[skb->priority];
if (ifmgd->tx_tspec[ac].admitted_time &&
skb->priority == ifmgd->tx_tspec[ac].up) return ac;
if (wme_downgrade_ac(skb)) { /* * This should not really happen. The AP has marked all * lower ACs to require admission control which is not * a reasonable configuration. Allow the frame to be * transmitted using AC_BK as a workaround.
*/ break;
}
}
/* Check to see if this is a reserved TID */ if (sta && sta->reserved_tid == skb->priority)
skb->priority = ieee80211_fix_reserved_tid(skb->priority);
/* look up which queue to use for frames with this 1d tag */ return ieee802_1d_to_ac[skb->priority];
}
/* Indicate which queue to use for this fully formed 802.11 frame */
u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_hdr *hdr)
{ struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 *p;
/* Ensure hash is set prior to potential SW encryption */
skb_get_hash(skb);
if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) ||
local->hw.queues < IEEE80211_NUM_ACS) return 0;
if (!ieee80211_is_data(hdr->frame_control)) {
skb->priority = 7; return ieee802_1d_to_ac[skb->priority];
} if (!ieee80211_is_data_qos(hdr->frame_control)) {
skb->priority = 0; return ieee802_1d_to_ac[skb->priority];
}
p = ieee80211_get_qos_ctl(hdr);
skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
/* use the data classifier to determine what 802.1d tag the
* data frame has */
qos_map = rcu_dereference(sdata->qos_map);
skb->priority = cfg80211_classify8021d(skb, qos_map ?
&qos_map->qos_map : NULL);
/** * ieee80211_set_qos_hdr - Fill in the QoS header if there is one. * * @sdata: local subif * @skb: packet to be updated
*/ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
{ struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
u8 flags;
u8 *p;
if (!ieee80211_is_data_qos(hdr->frame_control)) return;
p = ieee80211_get_qos_ctl(hdr);
/* don't overwrite the QoS field of injected frames */ if (info->flags & IEEE80211_TX_CTL_INJECTED) { /* do take into account Ack policy of injected frames */ if (*p & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
info->flags |= IEEE80211_TX_CTL_NO_ACK; return;
}
/* set up the first byte */
/* * preserve everything but the TID and ACK policy * (which we both write here)
*/
flags = *p & ~(IEEE80211_QOS_CTL_TID_MASK |
IEEE80211_QOS_CTL_ACK_POLICY_MASK);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.