iwlwifi: allow dynamic configuration of internal memory
authorEran Harary <eran.harary@intel.com>
Sun, 11 May 2014 05:11:34 +0000 (08:11 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 14 May 2014 08:35:49 +0000 (11:35 +0300)
New transport need to configure internal memory based on
the data in the (enlarged) alive notification from the
firmware. Add a transport API for this.

Signed-off-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mvm.h

index 6fea27c..d5ed150 100644 (file)
@@ -196,6 +196,11 @@ struct fw_img {
        bool is_dual_cpus;
 };
 
+struct iwl_sf_region {
+       u32 addr;
+       u32 size;
+};
+
 /* uCode version contains 4 values: Major/Minor/API/Serial */
 #define IWL_UCODE_MAJOR(ver)   (((ver) & 0xFF000000) >> 24)
 #define IWL_UCODE_MINOR(ver)   (((ver) & 0x00FF0000) >> 16)
index c57d366..34d49e1 100644 (file)
@@ -473,6 +473,8 @@ struct iwl_trans_ops {
        void (*op_mode_leave)(struct iwl_trans *iwl_trans);
        int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
                        bool run_in_rfkill);
+       int (*update_sf)(struct iwl_trans *trans,
+                        struct iwl_sf_region *st_fwrd_space);
        void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
        void (*stop_device)(struct iwl_trans *trans);
 
@@ -636,6 +638,17 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
        return trans->ops->start_fw(trans, fw, run_in_rfkill);
 }
 
+static inline int iwl_trans_update_sf(struct iwl_trans *trans,
+                                     struct iwl_sf_region *st_fwrd_space)
+{
+       might_sleep();
+
+       if (trans->ops->update_sf)
+               return trans->ops->update_sf(trans, st_fwrd_space);
+
+       return 0;
+}
+
 static inline void iwl_trans_stop_device(struct iwl_trans *trans)
 {
        might_sleep();
index 2cb7265..883e702 100644 (file)
@@ -137,6 +137,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
                alive_data->scd_base_addr = le32_to_cpu(palive2->scd_base_ptr);
                mvm->umac_error_event_table =
                        le32_to_cpu(palive2->error_info_addr);
+               mvm->sf_space.addr = le32_to_cpu(palive2->st_fwrd_addr);
+               mvm->sf_space.size = le32_to_cpu(palive2->st_fwrd_size);
 
                alive_data->valid = le16_to_cpu(palive2->status) ==
                                    IWL_ALIVE_STATUS_OK;
@@ -180,6 +182,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
        int ret, i;
        enum iwl_ucode_type old_type = mvm->cur_ucode;
        static const u8 alive_cmd[] = { MVM_ALIVE };
+       struct iwl_sf_region st_fwrd_space;
 
        fw = iwl_get_ucode_image(mvm, ucode_type);
        if (WARN_ON(!fw))
@@ -215,6 +218,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
                return -EIO;
        }
 
+       /*
+        * update the sdio allocation according to the pointer we get in the
+        * alive notification.
+        */
+       st_fwrd_space.addr = mvm->sf_space.addr;
+       st_fwrd_space.size = mvm->sf_space.size;
+       ret = iwl_trans_update_sf(mvm->trans, &st_fwrd_space);
+
        iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr);
 
        /*
index a7d27fb..5d2effb 100644 (file)
@@ -490,6 +490,7 @@ struct iwl_mvm {
        u32 log_event_table;
        u32 umac_error_event_table;
        bool support_umac_log;
+       struct iwl_sf_region sf_space;
 
        u32 ampdu_ref;