*     increment traffic load value for tid and also remove
  *     any old values if passed the certain time period
  */
-static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid)
+static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
+                            struct ieee80211_hdr *hdr)
 {
        u32 curr_time = jiffies_to_msecs(jiffies);
        u32 time_diff;
        s32 index;
        struct iwl4965_traffic_load *tl = NULL;
+       u16 fc = le16_to_cpu(hdr->frame_control);
+       u8 tid;
 
-       if (tid >= TID_MAX_LOAD_COUNT)
+       if (ieee80211_is_qos_data(fc)) {
+               u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
+               tid = qc[0] & 0xf;
+       } else
                return;
 
        tl = &lq_data->load[tid];
        u16 high_low;
 #ifdef CONFIG_IWL4965_HT
        u8 tid = MAX_TID_COUNT;
-       __le16 *qc;
 #endif
 
        IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
        lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
 #ifdef CONFIG_IWL4965_HT
-       qc = ieee80211_get_qos_ctrl(hdr);
-       if (qc) {
-               tid = (u8)(le16_to_cpu(*qc) & 0xf);
-               rs_tl_add_packet(lq_sta, tid);
-       }
+       rs_tl_add_packet(lq_sta, hdr);
 #endif
        /*
         * Select rate-scale / modulation-mode table to work with in
 
 extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
                                        struct ieee80211_hdr *hdr,
                                        const u8 *dest, int left);
-extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
 extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
 int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
 
 
               ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP);
 }
 
+static inline int ieee80211_is_qos_data(u16 fc)
+{
+       return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+              ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
+}
+/**
+ * ieee80211_get_qos_ctrl - get pointer to the QoS control field
+ *
+ * This function returns the pointer to 802.11 header QoS field (2 bytes)
+ * This function doesn't check whether hdr is a QoS hdr, use with care
+ * @hdr: struct ieee80211_hdr *hdr
+ * @hdr_len: header length
+ */
+
+static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len)
+{
+       return  ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
+}
+
 static inline int iwl_check_bits(unsigned long field, unsigned long mask)
 {
        return ((field & mask) == mask) ? 1 : 0;
 
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
-static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
-{
-       u16 fc = le16_to_cpu(hdr->frame_control);
-       int hdr_len = ieee80211_get_hdrlen(fc);
-
-       if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
-               return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
-       return NULL;
-}
-
 static const struct ieee80211_supported_band *iwl3945_get_band(
                struct iwl3945_priv *priv, enum ieee80211_band band)
 {
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
 {
-       __le16 *qc;
        u16 fc = le16_to_cpu(hdr->frame_control);
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
 
        if (ieee80211_get_morefrag(hdr))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
 
-       qc = ieee80211_get_qos_ctrl(hdr);
-       if (qc) {
-               cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf);
+       if (ieee80211_is_qos_data(fc)) {
+               u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
+               cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
-       } else
+       } else {
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+       }
 
        if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
        struct iwl3945_cmd *out_cmd = NULL;
-       u16 len, idx, len_org;
-       u8 id, hdr_len, unicast;
+       u16 len, idx, len_org, hdr_len;
+       u8 id;
+       u8 unicast;
        u8 sta_id;
+       u8 tid = 0;
        u16 seq_number = 0;
        u16 fc;
-       __le16 *qc;
        u8 wait_write_ptr = 0;
+       u8 *qc = NULL;
        unsigned long flags;
        int rc;
 
 
        IWL_DEBUG_RATE("station Id %d\n", sta_id);
 
-       qc = ieee80211_get_qos_ctrl(hdr);
-       if (qc) {
-               u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
+       if (ieee80211_is_qos_data(fc)) {
+               qc = ieee80211_get_qos_ctrl(hdr, hdr_len);
+               tid = qc[0] & 0xf;
                seq_number = priv->stations[sta_id].tid[tid].seq_number &
                                IEEE80211_SCTL_SEQ;
                hdr->seq_ctrl = cpu_to_le16(seq_number) |
        if (!ieee80211_get_morefrag(hdr)) {
                txq->need_update = 1;
                if (qc) {
-                       u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
                        priv->stations[sta_id].tid[tid].seq_number = seq_number;
                }
        } else {
 
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
-__le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
-{
-       u16 fc = le16_to_cpu(hdr->frame_control);
-       int hdr_len = ieee80211_get_hdrlen(fc);
-
-       if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
-               return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
-       return NULL;
-}
-
 static const struct ieee80211_supported_band *iwl_get_hw_mode(
                struct iwl_priv *priv, enum ieee80211_band band)
 {
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
 {
-       __le16 *qc;
        u16 fc = le16_to_cpu(hdr->frame_control);
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
 
        if (ieee80211_get_morefrag(hdr))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
 
-       qc = ieee80211_get_qos_ctrl(hdr);
-       if (qc) {
-               cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf);
+       if (ieee80211_is_qos_data(fc)) {
+               u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
+               cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
-       } else
+       } else {
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+       }
 
        if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
        dma_addr_t scratch_phys;
        struct iwl_cmd *out_cmd = NULL;
        u16 len, idx, len_org;
-       u8 id, hdr_len, unicast;
+       u8 hdr_len;
+       u8 id;
+       u8 unicast;
        u8 sta_id;
+       u8 tid = 0;
+       u8 wait_write_ptr = 0;
        u16 seq_number = 0;
        u16 fc;
-       __le16 *qc;
-       u8 wait_write_ptr = 0;
+       u8 *qc = NULL;
        unsigned long flags;
        int rc;
 
 
        IWL_DEBUG_TX("station Id %d\n", sta_id);
 
-       qc = ieee80211_get_qos_ctrl(hdr);
-       if (qc) {
-               u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
+       if (ieee80211_is_qos_data(fc)) {
+               qc = ieee80211_get_qos_ctrl(hdr, hdr_len);
+               tid = qc[0] & 0xf;
                seq_number = priv->stations[sta_id].tid[tid].seq_number &
                                IEEE80211_SCTL_SEQ;
                hdr->seq_ctrl = cpu_to_le16(seq_number) |
 
        if (!ieee80211_get_morefrag(hdr)) {
                txq->need_update = 1;
-               if (qc) {
-                       u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
+               if (qc)
                        priv->stations[sta_id].tid[tid].seq_number = seq_number;
-               }
        } else {
                wait_write_ptr = 1;
                txq->need_update = 0;
        u32  status = le32_to_cpu(tx_resp->status);
 #ifdef CONFIG_IWL4965_HT
        int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
+       u16 fc;
        struct ieee80211_hdr *hdr;
-       __le16 *qc;
+       u8 *qc = NULL;
 #endif
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
 
 #ifdef CONFIG_IWL4965_HT
        hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index);
-       qc = ieee80211_get_qos_ctrl(hdr);
-
-       if (qc)
-               tid = le16_to_cpu(*qc) & 0xf;
+       fc = le16_to_cpu(hdr->frame_control);
+       if (ieee80211_is_qos_data(fc)) {
+               qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
+               tid = qc[0] & 0xf;
+       }
 
        sta_id = iwl4965_get_ra_sta_id(priv, hdr);
        if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {