Merge remote-tracking branch 'lsk/v3.10/topic/gator' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlegacy / 4965-mac.c
index 9a95045c97b6b4fe6041f457a1999ecfb7926d12..d2586f09f45cce833f102b1dcabf256582164799 100644 (file)
@@ -574,9 +574,11 @@ il4965_translate_rx_status(struct il_priv *il, u32 decrypt_in)
        return decrypt_out;
 }
 
+#define SMALL_PACKET_SIZE 256
+
 static void
 il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
-                              u16 len, u32 ampdu_status, struct il_rx_buf *rxb,
+                              u32 len, u32 ampdu_status, struct il_rx_buf *rxb,
                               struct ieee80211_rx_status *stats)
 {
        struct sk_buff *skb;
@@ -593,21 +595,25 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
            il_set_decrypted_flag(il, hdr, ampdu_status, stats))
                return;
 
-       skb = dev_alloc_skb(128);
+       skb = dev_alloc_skb(SMALL_PACKET_SIZE);
        if (!skb) {
                IL_ERR("dev_alloc_skb failed\n");
                return;
        }
 
-       skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len,
-                       len);
+       if (len <= SMALL_PACKET_SIZE) {
+               memcpy(skb_put(skb, len), hdr, len);
+       } else {
+               skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb),
+                               len, PAGE_SIZE << il->hw_params.rx_page_order);
+               il->alloc_rxb_page--;
+               rxb->page = NULL;
+       }
 
        il_update_stats(il, false, fc, len);
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
        ieee80211_rx(il->hw, skb);
-       il->alloc_rxb_page--;
-       rxb->page = NULL;
 }
 
 /* Called for N_RX (legacy ABG frames), or
@@ -4442,13 +4448,13 @@ il4965_irq_tasklet(struct il_priv *il)
                 * is killed. Hence update the killswitch state here. The
                 * rfkill handler will care about restarting if needed.
                 */
-               if (!test_bit(S_ALIVE, &il->status)) {
-                       if (hw_rf_kill)
-                               set_bit(S_RFKILL, &il->status);
-                       else
-                               clear_bit(S_RFKILL, &il->status);
-                       wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
+               if (hw_rf_kill) {
+                       set_bit(S_RFKILL, &il->status);
+               } else {
+                       clear_bit(S_RFKILL, &il->status);
+                       il_force_reset(il, true);
                }
+               wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
 
                handled |= CSR_INT_BIT_RF_KILL;
        }
@@ -5316,6 +5322,9 @@ il4965_alive_start(struct il_priv *il)
 
        il->active_rate = RATES_MASK;
 
+       il_power_update_mode(il, true);
+       D_INFO("Updated power mode\n");
+
        if (il_is_associated(il)) {
                struct il_rxon_cmd *active_rxon =
                    (struct il_rxon_cmd *)&il->active;
@@ -5346,9 +5355,6 @@ il4965_alive_start(struct il_priv *il)
        D_INFO("ALIVE processing complete.\n");
        wake_up(&il->wait_command_queue);
 
-       il_power_update_mode(il, true);
-       D_INFO("Updated power mode\n");
-
        return;
 
 restart: