LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath10k - bmi.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 15 278 5.4 %
Date: 2022-03-28 15:32:58 Functions: 1 14 7.1 %
Branches: 4 122 3.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: ISC
       2                 :            : /*
       3                 :            :  * Copyright (c) 2005-2011 Atheros Communications Inc.
       4                 :            :  * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "bmi.h"
       8                 :            : #include "hif.h"
       9                 :            : #include "debug.h"
      10                 :            : #include "htc.h"
      11                 :            : #include "hw.h"
      12                 :            : 
      13                 :          0 : void ath10k_bmi_start(struct ath10k *ar)
      14                 :            : {
      15                 :          0 :         int ret;
      16                 :            : 
      17         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n");
      18                 :            : 
      19                 :          0 :         ar->bmi.done_sent = false;
      20                 :            : 
      21                 :            :         /* Enable hardware clock to speed up firmware download */
      22         [ #  # ]:          0 :         if (ar->hw_params.hw_ops->enable_pll_clk) {
      23                 :          0 :                 ret = ar->hw_params.hw_ops->enable_pll_clk(ar);
      24         [ #  # ]:          0 :                 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi enable pll ret %d\n", ret);
      25                 :            :         }
      26                 :          0 : }
      27                 :            : 
      28                 :          0 : int ath10k_bmi_done(struct ath10k *ar)
      29                 :            : {
      30                 :          0 :         struct bmi_cmd cmd;
      31                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done);
      32                 :          0 :         int ret;
      33                 :            : 
      34         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi done\n");
      35                 :            : 
      36         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
      37         [ #  # ]:          0 :                 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi skipped\n");
      38                 :          0 :                 return 0;
      39                 :            :         }
      40                 :            : 
      41                 :          0 :         ar->bmi.done_sent = true;
      42                 :          0 :         cmd.id = __cpu_to_le32(BMI_DONE);
      43                 :            : 
      44                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
      45         [ #  # ]:          0 :         if (ret) {
      46                 :          0 :                 ath10k_warn(ar, "unable to write to the device: %d\n", ret);
      47                 :          0 :                 return ret;
      48                 :            :         }
      49                 :            : 
      50                 :            :         return 0;
      51                 :            : }
      52                 :            : 
      53                 :          7 : int ath10k_bmi_get_target_info(struct ath10k *ar,
      54                 :            :                                struct bmi_target_info *target_info)
      55                 :            : {
      56                 :          7 :         struct bmi_cmd cmd;
      57                 :          7 :         union bmi_resp resp;
      58                 :          7 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.get_target_info);
      59                 :          7 :         u32 resplen = sizeof(resp.get_target_info);
      60                 :          7 :         int ret;
      61                 :            : 
      62         [ +  - ]:          7 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info\n");
      63                 :            : 
      64         [ -  + ]:          7 :         if (ar->bmi.done_sent) {
      65                 :          0 :                 ath10k_warn(ar, "BMI Get Target Info Command disallowed\n");
      66                 :          0 :                 return -EBUSY;
      67                 :            :         }
      68                 :            : 
      69                 :          7 :         cmd.id = __cpu_to_le32(BMI_GET_TARGET_INFO);
      70                 :            : 
      71                 :          7 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
      72         [ -  + ]:          7 :         if (ret) {
      73                 :          0 :                 ath10k_warn(ar, "unable to get target info from device\n");
      74                 :          0 :                 return ret;
      75                 :            :         }
      76                 :            : 
      77         [ -  + ]:          7 :         if (resplen < sizeof(resp.get_target_info)) {
      78                 :          0 :                 ath10k_warn(ar, "invalid get_target_info response length (%d)\n",
      79                 :            :                             resplen);
      80                 :          0 :                 return -EIO;
      81                 :            :         }
      82                 :            : 
      83                 :          7 :         target_info->version = __le32_to_cpu(resp.get_target_info.version);
      84                 :          7 :         target_info->type    = __le32_to_cpu(resp.get_target_info.type);
      85                 :            : 
      86                 :          7 :         return 0;
      87                 :            : }
      88                 :            : 
      89                 :            : #define TARGET_VERSION_SENTINAL 0xffffffffu
      90                 :            : 
      91                 :          0 : int ath10k_bmi_get_target_info_sdio(struct ath10k *ar,
      92                 :            :                                     struct bmi_target_info *target_info)
      93                 :            : {
      94                 :          0 :         struct bmi_cmd cmd;
      95                 :          0 :         union bmi_resp resp;
      96                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.get_target_info);
      97                 :          0 :         u32 resplen, ver_len;
      98                 :          0 :         __le32 tmp;
      99                 :          0 :         int ret;
     100                 :            : 
     101         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info SDIO\n");
     102                 :            : 
     103         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     104                 :          0 :                 ath10k_warn(ar, "BMI Get Target Info Command disallowed\n");
     105                 :          0 :                 return -EBUSY;
     106                 :            :         }
     107                 :            : 
     108                 :          0 :         cmd.id = __cpu_to_le32(BMI_GET_TARGET_INFO);
     109                 :            : 
     110                 :            :         /* Step 1: Read 4 bytes of the target info and check if it is
     111                 :            :          * the special sentinal version word or the first word in the
     112                 :            :          * version response.
     113                 :            :          */
     114                 :          0 :         resplen = sizeof(u32);
     115                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &tmp, &resplen);
     116         [ #  # ]:          0 :         if (ret) {
     117                 :          0 :                 ath10k_warn(ar, "unable to read from device\n");
     118                 :          0 :                 return ret;
     119                 :            :         }
     120                 :            : 
     121                 :            :         /* Some SDIO boards have a special sentinal byte before the real
     122                 :            :          * version response.
     123                 :            :          */
     124         [ #  # ]:          0 :         if (__le32_to_cpu(tmp) == TARGET_VERSION_SENTINAL) {
     125                 :            :                 /* Step 1b: Read the version length */
     126                 :          0 :                 resplen = sizeof(u32);
     127                 :          0 :                 ret = ath10k_hif_exchange_bmi_msg(ar, NULL, 0, &tmp,
     128                 :            :                                                   &resplen);
     129         [ #  # ]:          0 :                 if (ret) {
     130                 :          0 :                         ath10k_warn(ar, "unable to read from device\n");
     131                 :          0 :                         return ret;
     132                 :            :                 }
     133                 :            :         }
     134                 :            : 
     135                 :          0 :         ver_len = __le32_to_cpu(tmp);
     136                 :            : 
     137                 :            :         /* Step 2: Check the target info length */
     138         [ #  # ]:          0 :         if (ver_len != sizeof(resp.get_target_info)) {
     139                 :          0 :                 ath10k_warn(ar, "Unexpected target info len: %u. Expected: %zu\n",
     140                 :            :                             ver_len, sizeof(resp.get_target_info));
     141                 :          0 :                 return -EINVAL;
     142                 :            :         }
     143                 :            : 
     144                 :            :         /* Step 3: Read the rest of the version response */
     145                 :          0 :         resplen = sizeof(resp.get_target_info) - sizeof(u32);
     146                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, NULL, 0,
     147                 :            :                                           &resp.get_target_info.version,
     148                 :            :                                           &resplen);
     149         [ #  # ]:          0 :         if (ret) {
     150                 :          0 :                 ath10k_warn(ar, "unable to read from device\n");
     151                 :          0 :                 return ret;
     152                 :            :         }
     153                 :            : 
     154                 :          0 :         target_info->version = __le32_to_cpu(resp.get_target_info.version);
     155                 :          0 :         target_info->type    = __le32_to_cpu(resp.get_target_info.type);
     156                 :            : 
     157                 :          0 :         return 0;
     158                 :            : }
     159                 :            : 
     160                 :          0 : int ath10k_bmi_read_memory(struct ath10k *ar,
     161                 :            :                            u32 address, void *buffer, u32 length)
     162                 :            : {
     163                 :          0 :         struct bmi_cmd cmd;
     164                 :          0 :         union bmi_resp resp;
     165                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_mem);
     166                 :          0 :         u32 rxlen;
     167                 :          0 :         int ret;
     168                 :            : 
     169         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n",
     170                 :            :                    address, length);
     171                 :            : 
     172         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     173                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     174                 :          0 :                 return -EBUSY;
     175                 :            :         }
     176                 :            : 
     177         [ #  # ]:          0 :         while (length) {
     178                 :          0 :                 rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE);
     179                 :            : 
     180                 :          0 :                 cmd.id            = __cpu_to_le32(BMI_READ_MEMORY);
     181                 :          0 :                 cmd.read_mem.addr = __cpu_to_le32(address);
     182                 :          0 :                 cmd.read_mem.len  = __cpu_to_le32(rxlen);
     183                 :            : 
     184                 :          0 :                 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen,
     185                 :            :                                                   &resp, &rxlen);
     186         [ #  # ]:          0 :                 if (ret) {
     187                 :          0 :                         ath10k_warn(ar, "unable to read from the device (%d)\n",
     188                 :            :                                     ret);
     189                 :          0 :                         return ret;
     190                 :            :                 }
     191                 :            : 
     192                 :          0 :                 memcpy(buffer, resp.read_mem.payload, rxlen);
     193                 :          0 :                 address += rxlen;
     194                 :          0 :                 buffer  += rxlen;
     195                 :          0 :                 length  -= rxlen;
     196                 :            :         }
     197                 :            : 
     198                 :            :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :          0 : int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val)
     202                 :            : {
     203                 :          0 :         struct bmi_cmd cmd;
     204                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.write_soc_reg);
     205                 :          0 :         int ret;
     206                 :            : 
     207         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI,
     208                 :            :                    "bmi write soc register 0x%08x val 0x%08x\n",
     209                 :            :                    address, reg_val);
     210                 :            : 
     211         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     212                 :          0 :                 ath10k_warn(ar, "bmi write soc register command in progress\n");
     213                 :          0 :                 return -EBUSY;
     214                 :            :         }
     215                 :            : 
     216                 :          0 :         cmd.id = __cpu_to_le32(BMI_WRITE_SOC_REGISTER);
     217                 :          0 :         cmd.write_soc_reg.addr = __cpu_to_le32(address);
     218                 :          0 :         cmd.write_soc_reg.value = __cpu_to_le32(reg_val);
     219                 :            : 
     220                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
     221         [ #  # ]:          0 :         if (ret) {
     222                 :          0 :                 ath10k_warn(ar, "Unable to write soc register to device: %d\n",
     223                 :            :                             ret);
     224                 :          0 :                 return ret;
     225                 :            :         }
     226                 :            : 
     227                 :            :         return 0;
     228                 :            : }
     229                 :            : 
     230                 :          0 : int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val)
     231                 :            : {
     232                 :          0 :         struct bmi_cmd cmd;
     233                 :          0 :         union bmi_resp resp;
     234                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_soc_reg);
     235                 :          0 :         u32 resplen = sizeof(resp.read_soc_reg);
     236                 :          0 :         int ret;
     237                 :            : 
     238         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register 0x%08x\n",
     239                 :            :                    address);
     240                 :            : 
     241         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     242                 :          0 :                 ath10k_warn(ar, "bmi read soc register command in progress\n");
     243                 :          0 :                 return -EBUSY;
     244                 :            :         }
     245                 :            : 
     246                 :          0 :         cmd.id = __cpu_to_le32(BMI_READ_SOC_REGISTER);
     247                 :          0 :         cmd.read_soc_reg.addr = __cpu_to_le32(address);
     248                 :            : 
     249                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
     250         [ #  # ]:          0 :         if (ret) {
     251                 :          0 :                 ath10k_warn(ar, "Unable to read soc register from device: %d\n",
     252                 :            :                             ret);
     253                 :          0 :                 return ret;
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         *reg_val = __le32_to_cpu(resp.read_soc_reg.value);
     257                 :            : 
     258         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register value 0x%08x\n",
     259                 :            :                    *reg_val);
     260                 :            : 
     261                 :            :         return 0;
     262                 :            : }
     263                 :            : 
     264                 :          0 : int ath10k_bmi_write_memory(struct ath10k *ar,
     265                 :            :                             u32 address, const void *buffer, u32 length)
     266                 :            : {
     267                 :          0 :         struct bmi_cmd cmd;
     268                 :          0 :         u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.write_mem);
     269                 :          0 :         u32 txlen;
     270                 :          0 :         int ret;
     271                 :            : 
     272         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n",
     273                 :            :                    address, length);
     274                 :            : 
     275         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     276                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     277                 :          0 :                 return -EBUSY;
     278                 :            :         }
     279                 :            : 
     280         [ #  # ]:          0 :         while (length) {
     281                 :          0 :                 txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen);
     282                 :            : 
     283                 :            :                 /* copy before roundup to avoid reading beyond buffer*/
     284                 :          0 :                 memcpy(cmd.write_mem.payload, buffer, txlen);
     285                 :          0 :                 txlen = roundup(txlen, 4);
     286                 :            : 
     287                 :          0 :                 cmd.id             = __cpu_to_le32(BMI_WRITE_MEMORY);
     288                 :          0 :                 cmd.write_mem.addr = __cpu_to_le32(address);
     289                 :          0 :                 cmd.write_mem.len  = __cpu_to_le32(txlen);
     290                 :            : 
     291                 :          0 :                 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
     292                 :            :                                                   NULL, NULL);
     293         [ #  # ]:          0 :                 if (ret) {
     294                 :          0 :                         ath10k_warn(ar, "unable to write to the device (%d)\n",
     295                 :            :                                     ret);
     296                 :          0 :                         return ret;
     297                 :            :                 }
     298                 :            : 
     299                 :            :                 /* fixup roundup() so `length` zeroes out for last chunk */
     300                 :          0 :                 txlen = min(txlen, length);
     301                 :            : 
     302                 :          0 :                 address += txlen;
     303                 :          0 :                 buffer  += txlen;
     304                 :          0 :                 length  -= txlen;
     305                 :            :         }
     306                 :            : 
     307                 :            :         return 0;
     308                 :            : }
     309                 :            : 
     310                 :          0 : int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
     311                 :            : {
     312                 :          0 :         struct bmi_cmd cmd;
     313                 :          0 :         union bmi_resp resp;
     314                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.execute);
     315                 :          0 :         u32 resplen = sizeof(resp.execute);
     316                 :          0 :         int ret;
     317                 :            : 
     318         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
     319                 :            :                    address, param);
     320                 :            : 
     321         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     322                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     323                 :          0 :                 return -EBUSY;
     324                 :            :         }
     325                 :            : 
     326                 :          0 :         cmd.id            = __cpu_to_le32(BMI_EXECUTE);
     327                 :          0 :         cmd.execute.addr  = __cpu_to_le32(address);
     328                 :          0 :         cmd.execute.param = __cpu_to_le32(param);
     329                 :            : 
     330                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
     331         [ #  # ]:          0 :         if (ret) {
     332                 :          0 :                 ath10k_warn(ar, "unable to read from the device\n");
     333                 :          0 :                 return ret;
     334                 :            :         }
     335                 :            : 
     336         [ #  # ]:          0 :         if (resplen < sizeof(resp.execute)) {
     337                 :          0 :                 ath10k_warn(ar, "invalid execute response length (%d)\n",
     338                 :            :                             resplen);
     339                 :          0 :                 return -EIO;
     340                 :            :         }
     341                 :            : 
     342                 :          0 :         *result = __le32_to_cpu(resp.execute.result);
     343                 :            : 
     344         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result);
     345                 :            : 
     346                 :            :         return 0;
     347                 :            : }
     348                 :            : 
     349                 :          0 : static int ath10k_bmi_lz_data_large(struct ath10k *ar, const void *buffer, u32 length)
     350                 :            : {
     351                 :          0 :         struct bmi_cmd *cmd;
     352                 :          0 :         u32 hdrlen = sizeof(cmd->id) + sizeof(cmd->lz_data);
     353                 :          0 :         u32 txlen;
     354                 :          0 :         int ret;
     355                 :          0 :         size_t buf_len;
     356                 :            : 
     357         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "large bmi lz data buffer 0x%pK length %d\n",
     358                 :            :                    buffer, length);
     359                 :            : 
     360         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     361                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     362                 :          0 :                 return -EBUSY;
     363                 :            :         }
     364                 :            : 
     365                 :          0 :         buf_len = sizeof(*cmd) + BMI_MAX_LARGE_DATA_SIZE - BMI_MAX_DATA_SIZE;
     366                 :          0 :         cmd = kzalloc(buf_len, GFP_KERNEL);
     367         [ #  # ]:          0 :         if (!cmd)
     368                 :            :                 return -ENOMEM;
     369                 :            : 
     370         [ #  # ]:          0 :         while (length) {
     371                 :          0 :                 txlen = min(length, BMI_MAX_LARGE_DATA_SIZE - hdrlen);
     372                 :            : 
     373         [ #  # ]:          0 :                 WARN_ON_ONCE(txlen & 3);
     374                 :            : 
     375                 :          0 :                 cmd->id          = __cpu_to_le32(BMI_LZ_DATA);
     376                 :          0 :                 cmd->lz_data.len = __cpu_to_le32(txlen);
     377                 :          0 :                 memcpy(cmd->lz_data.payload, buffer, txlen);
     378                 :            : 
     379                 :          0 :                 ret = ath10k_hif_exchange_bmi_msg(ar, cmd, hdrlen + txlen,
     380                 :            :                                                   NULL, NULL);
     381         [ #  # ]:          0 :                 if (ret) {
     382                 :          0 :                         ath10k_warn(ar, "unable to write to the device\n");
     383                 :          0 :                         return ret;
     384                 :            :                 }
     385                 :            : 
     386                 :          0 :                 buffer += txlen;
     387                 :          0 :                 length -= txlen;
     388                 :            :         }
     389                 :            : 
     390                 :          0 :         kfree(cmd);
     391                 :            : 
     392                 :          0 :         return 0;
     393                 :            : }
     394                 :            : 
     395                 :          0 : int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
     396                 :            : {
     397                 :          0 :         struct bmi_cmd cmd;
     398                 :          0 :         u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.lz_data);
     399                 :          0 :         u32 txlen;
     400                 :          0 :         int ret;
     401                 :            : 
     402         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%pK length %d\n",
     403                 :            :                    buffer, length);
     404                 :            : 
     405         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     406                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     407                 :          0 :                 return -EBUSY;
     408                 :            :         }
     409                 :            : 
     410         [ #  # ]:          0 :         while (length) {
     411                 :          0 :                 txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen);
     412                 :            : 
     413         [ #  # ]:          0 :                 WARN_ON_ONCE(txlen & 3);
     414                 :            : 
     415                 :          0 :                 cmd.id          = __cpu_to_le32(BMI_LZ_DATA);
     416                 :          0 :                 cmd.lz_data.len = __cpu_to_le32(txlen);
     417                 :          0 :                 memcpy(cmd.lz_data.payload, buffer, txlen);
     418                 :            : 
     419                 :          0 :                 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
     420                 :            :                                                   NULL, NULL);
     421         [ #  # ]:          0 :                 if (ret) {
     422                 :          0 :                         ath10k_warn(ar, "unable to write to the device\n");
     423                 :          0 :                         return ret;
     424                 :            :                 }
     425                 :            : 
     426                 :          0 :                 buffer += txlen;
     427                 :          0 :                 length -= txlen;
     428                 :            :         }
     429                 :            : 
     430                 :            :         return 0;
     431                 :            : }
     432                 :            : 
     433                 :          0 : int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
     434                 :            : {
     435                 :          0 :         struct bmi_cmd cmd;
     436                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start);
     437                 :          0 :         int ret;
     438                 :            : 
     439         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n",
     440                 :            :                    address);
     441                 :            : 
     442         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     443                 :          0 :                 ath10k_warn(ar, "command disallowed\n");
     444                 :          0 :                 return -EBUSY;
     445                 :            :         }
     446                 :            : 
     447                 :          0 :         cmd.id            = __cpu_to_le32(BMI_LZ_STREAM_START);
     448                 :          0 :         cmd.lz_start.addr = __cpu_to_le32(address);
     449                 :            : 
     450                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
     451         [ #  # ]:          0 :         if (ret) {
     452                 :          0 :                 printk(KERN_INFO "unable to Start LZ Stream to the device\n");
     453                 :          0 :                 return ret;
     454                 :            :         }
     455                 :            : 
     456                 :            :         return 0;
     457                 :            : }
     458                 :            : 
     459                 :          0 : int ath10k_bmi_fast_download(struct ath10k *ar,
     460                 :            :                              u32 address, const void *buffer, u32 length)
     461                 :            : {
     462                 :          0 :         u8 trailer[4] = {};
     463                 :          0 :         u32 head_len = rounddown(length, 4);
     464                 :          0 :         u32 trailer_len = length - head_len;
     465                 :          0 :         int ret;
     466                 :          0 :     printk(KERN_INFO
     467                 :            :                    "bmi fast download address 0x%x buffer 0x%pK length %d\n",
     468                 :            :                    address, buffer, length);
     469                 :            : 
     470         [ #  # ]:          0 :         ath10k_dbg(ar, ATH10K_DBG_BMI,
     471                 :            :                    "bmi fast download address 0x%x buffer 0x%pK length %d\n",
     472                 :            :                    address, buffer, length);
     473                 :            : 
     474                 :          0 :         ret = ath10k_bmi_lz_stream_start(ar, address);
     475         [ #  # ]:          0 :         if (ret)
     476                 :            :                 return ret;
     477                 :          0 :     printk(KERN_INFO "lz_stream_start\n");
     478                 :            : 
     479                 :            :         /* copy the last word into a zero padded buffer */
     480         [ #  # ]:          0 :         if (trailer_len > 0)
     481                 :          0 :                 memcpy(trailer, buffer + head_len, trailer_len);
     482                 :            : 
     483         [ #  # ]:          0 :         if (ar->hw_params.bmi_large_size_download)
     484                 :          0 :                 ret = ath10k_bmi_lz_data_large(ar, buffer, head_len);
     485                 :            :         else
     486                 :          0 :                 ret = ath10k_bmi_lz_data(ar, buffer, head_len);
     487                 :            : 
     488         [ #  # ]:          0 :         if (ret)
     489                 :            :                 return ret;
     490                 :          0 :     printk(KERN_INFO "lz_data buf\n");
     491                 :            : 
     492         [ #  # ]:          0 :         if (trailer_len > 0)
     493                 :          0 :                 ret = ath10k_bmi_lz_data(ar, trailer, 4);
     494                 :            : 
     495         [ #  # ]:          0 :         if (ret != 0)
     496                 :            :                 return ret;
     497                 :          0 :     printk(KERN_INFO "lz_data trail\n");
     498                 :            : 
     499                 :            :         /*
     500                 :            :          * Close compressed stream and open a new (fake) one.
     501                 :            :          * This serves mainly to flush Target caches.
     502                 :            :          */
     503                 :          0 :         ret = ath10k_bmi_lz_stream_start(ar, 0x00);
     504                 :            : 
     505                 :          0 :         return ret;
     506                 :            : }
     507                 :            : 
     508                 :          0 : int ath10k_bmi_set_start(struct ath10k *ar, u32 address)
     509                 :            : {
     510                 :          0 :         struct bmi_cmd cmd;
     511                 :          0 :         u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.set_app_start);
     512                 :          0 :         int ret;
     513                 :            : 
     514         [ #  # ]:          0 :         if (ar->bmi.done_sent) {
     515                 :          0 :                 ath10k_warn(ar, "bmi set start command disallowed\n");
     516                 :          0 :                 return -EBUSY;
     517                 :            :         }
     518                 :            : 
     519                 :          0 :         cmd.id = __cpu_to_le32(BMI_SET_APP_START);
     520                 :          0 :         cmd.set_app_start.addr = __cpu_to_le32(address);
     521                 :            : 
     522                 :          0 :         ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
     523         [ #  # ]:          0 :         if (ret) {
     524                 :          0 :                 ath10k_warn(ar, "unable to set start to the device:%d\n", ret);
     525                 :          0 :                 return ret;
     526                 :            :         }
     527                 :            : 
     528                 :            :         return 0;
     529                 :            : }

Generated by: LCOV version 1.14