root/drivers/net/wireless/st/cw1200/fwio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cw1200_get_hw_type
  2. cw1200_load_firmware_cw1200
  3. config_reg_read
  4. config_reg_write
  5. cw1200_load_firmware

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
   4  *
   5  * Copyright (c) 2010, ST-Ericsson
   6  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
   7  *
   8  * Based on:
   9  * ST-Ericsson UMAC CW1200 driver which is
  10  * Copyright (c) 2010, ST-Ericsson
  11  * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
  12  */
  13 
  14 #include <linux/vmalloc.h>
  15 #include <linux/sched.h>
  16 #include <linux/firmware.h>
  17 
  18 #include "cw1200.h"
  19 #include "fwio.h"
  20 #include "hwio.h"
  21 #include "hwbus.h"
  22 #include "bh.h"
  23 
  24 static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
  25 {
  26         int hw_type = -1;
  27         u32 silicon_type = (config_reg_val >> 24) & 0x7;
  28         u32 silicon_vers = (config_reg_val >> 31) & 0x1;
  29 
  30         switch (silicon_type) {
  31         case 0x00:
  32                 *major_revision = 1;
  33                 hw_type = HIF_9000_SILICON_VERSATILE;
  34                 break;
  35         case 0x01:
  36         case 0x02: /* CW1x00 */
  37         case 0x04: /* CW1x60 */
  38                 *major_revision = silicon_type;
  39                 if (silicon_vers)
  40                         hw_type = HIF_8601_VERSATILE;
  41                 else
  42                         hw_type = HIF_8601_SILICON;
  43                 break;
  44         default:
  45                 break;
  46         }
  47 
  48         return hw_type;
  49 }
  50 
  51 static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
  52 {
  53         int ret, block, num_blocks;
  54         unsigned i;
  55         u32 val32;
  56         u32 put = 0, get = 0;
  57         u8 *buf = NULL;
  58         const char *fw_path;
  59         const struct firmware *firmware = NULL;
  60 
  61         /* Macroses are local. */
  62 #define APB_WRITE(reg, val) \
  63         do { \
  64                 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
  65                 if (ret < 0) \
  66                         goto exit; \
  67         } while (0)
  68 #define APB_WRITE2(reg, val) \
  69         do { \
  70                 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
  71                 if (ret < 0) \
  72                         goto free_buffer; \
  73         } while (0)
  74 #define APB_READ(reg, val) \
  75         do { \
  76                 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
  77                 if (ret < 0) \
  78                         goto free_buffer; \
  79         } while (0)
  80 #define REG_WRITE(reg, val) \
  81         do { \
  82                 ret = cw1200_reg_write_32(priv, (reg), (val)); \
  83                 if (ret < 0) \
  84                         goto exit; \
  85         } while (0)
  86 #define REG_READ(reg, val) \
  87         do { \
  88                 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
  89                 if (ret < 0) \
  90                         goto exit; \
  91         } while (0)
  92 
  93         switch (priv->hw_revision) {
  94         case CW1200_HW_REV_CUT10:
  95                 fw_path = FIRMWARE_CUT10;
  96                 if (!priv->sdd_path)
  97                         priv->sdd_path = SDD_FILE_10;
  98                 break;
  99         case CW1200_HW_REV_CUT11:
 100                 fw_path = FIRMWARE_CUT11;
 101                 if (!priv->sdd_path)
 102                         priv->sdd_path = SDD_FILE_11;
 103                 break;
 104         case CW1200_HW_REV_CUT20:
 105                 fw_path = FIRMWARE_CUT20;
 106                 if (!priv->sdd_path)
 107                         priv->sdd_path = SDD_FILE_20;
 108                 break;
 109         case CW1200_HW_REV_CUT22:
 110                 fw_path = FIRMWARE_CUT22;
 111                 if (!priv->sdd_path)
 112                         priv->sdd_path = SDD_FILE_22;
 113                 break;
 114         case CW1X60_HW_REV:
 115                 fw_path = FIRMWARE_CW1X60;
 116                 if (!priv->sdd_path)
 117                         priv->sdd_path = SDD_FILE_CW1X60;
 118                 break;
 119         default:
 120                 pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
 121                 return -EINVAL;
 122         }
 123 
 124         /* Initialize common registers */
 125         APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
 126         APB_WRITE(DOWNLOAD_PUT_REG, 0);
 127         APB_WRITE(DOWNLOAD_GET_REG, 0);
 128         APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
 129         APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
 130 
 131         /* Write the NOP Instruction */
 132         REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
 133         REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
 134 
 135         /* Release CPU from RESET */
 136         REG_READ(ST90TDS_CONFIG_REG_ID, val32);
 137         val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
 138         REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
 139 
 140         /* Enable Clock */
 141         val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
 142         REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
 143 
 144         /* Load a firmware file */
 145         ret = request_firmware(&firmware, fw_path, priv->pdev);
 146         if (ret) {
 147                 pr_err("Can't load firmware file %s.\n", fw_path);
 148                 goto exit;
 149         }
 150 
 151         buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
 152         if (!buf) {
 153                 pr_err("Can't allocate firmware load buffer.\n");
 154                 ret = -ENOMEM;
 155                 goto firmware_release;
 156         }
 157 
 158         /* Check if the bootloader is ready */
 159         for (i = 0; i < 100; i += 1 + i / 2) {
 160                 APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
 161                 if (val32 == DOWNLOAD_I_AM_HERE)
 162                         break;
 163                 mdelay(i);
 164         } /* End of for loop */
 165 
 166         if (val32 != DOWNLOAD_I_AM_HERE) {
 167                 pr_err("Bootloader is not ready.\n");
 168                 ret = -ETIMEDOUT;
 169                 goto free_buffer;
 170         }
 171 
 172         /* Calculcate number of download blocks */
 173         num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
 174 
 175         /* Updating the length in Download Ctrl Area */
 176         val32 = firmware->size; /* Explicit cast from size_t to u32 */
 177         APB_WRITE2(DOWNLOAD_IMAGE_SIZE_REG, val32);
 178 
 179         /* Firmware downloading loop */
 180         for (block = 0; block < num_blocks; block++) {
 181                 size_t tx_size;
 182                 size_t block_size;
 183 
 184                 /* check the download status */
 185                 APB_READ(DOWNLOAD_STATUS_REG, val32);
 186                 if (val32 != DOWNLOAD_PENDING) {
 187                         pr_err("Bootloader reported error %d.\n", val32);
 188                         ret = -EIO;
 189                         goto free_buffer;
 190                 }
 191 
 192                 /* loop until put - get <= 24K */
 193                 for (i = 0; i < 100; i++) {
 194                         APB_READ(DOWNLOAD_GET_REG, get);
 195                         if ((put - get) <=
 196                             (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
 197                                 break;
 198                         mdelay(i);
 199                 }
 200 
 201                 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
 202                         pr_err("Timeout waiting for FIFO.\n");
 203                         ret = -ETIMEDOUT;
 204                         goto free_buffer;
 205                 }
 206 
 207                 /* calculate the block size */
 208                 tx_size = block_size = min_t(size_t, firmware->size - put,
 209                                         DOWNLOAD_BLOCK_SIZE);
 210 
 211                 memcpy(buf, &firmware->data[put], block_size);
 212                 if (block_size < DOWNLOAD_BLOCK_SIZE) {
 213                         memset(&buf[block_size], 0,
 214                                DOWNLOAD_BLOCK_SIZE - block_size);
 215                         tx_size = DOWNLOAD_BLOCK_SIZE;
 216                 }
 217 
 218                 /* send the block to sram */
 219                 ret = cw1200_apb_write(priv,
 220                         CW1200_APB(DOWNLOAD_FIFO_OFFSET +
 221                                    (put & (DOWNLOAD_FIFO_SIZE - 1))),
 222                         buf, tx_size);
 223                 if (ret < 0) {
 224                         pr_err("Can't write firmware block @ %d!\n",
 225                                put & (DOWNLOAD_FIFO_SIZE - 1));
 226                         goto free_buffer;
 227                 }
 228 
 229                 /* update the put register */
 230                 put += block_size;
 231                 APB_WRITE2(DOWNLOAD_PUT_REG, put);
 232         } /* End of firmware download loop */
 233 
 234         /* Wait for the download completion */
 235         for (i = 0; i < 300; i += 1 + i / 2) {
 236                 APB_READ(DOWNLOAD_STATUS_REG, val32);
 237                 if (val32 != DOWNLOAD_PENDING)
 238                         break;
 239                 mdelay(i);
 240         }
 241         if (val32 != DOWNLOAD_SUCCESS) {
 242                 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
 243                 ret = -ETIMEDOUT;
 244                 goto free_buffer;
 245         } else {
 246                 pr_info("Firmware download completed.\n");
 247                 ret = 0;
 248         }
 249 
 250 free_buffer:
 251         kfree(buf);
 252 firmware_release:
 253         release_firmware(firmware);
 254 exit:
 255         return ret;
 256 
 257 #undef APB_WRITE
 258 #undef APB_WRITE2
 259 #undef APB_READ
 260 #undef REG_WRITE
 261 #undef REG_READ
 262 }
 263 
 264 
 265 static int config_reg_read(struct cw1200_common *priv, u32 *val)
 266 {
 267         switch (priv->hw_type) {
 268         case HIF_9000_SILICON_VERSATILE: {
 269                 u16 val16;
 270                 int ret = cw1200_reg_read_16(priv,
 271                                              ST90TDS_CONFIG_REG_ID,
 272                                              &val16);
 273                 if (ret < 0)
 274                         return ret;
 275                 *val = val16;
 276                 return 0;
 277         }
 278         case HIF_8601_VERSATILE:
 279         case HIF_8601_SILICON:
 280         default:
 281                 cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
 282                 break;
 283         }
 284         return 0;
 285 }
 286 
 287 static int config_reg_write(struct cw1200_common *priv, u32 val)
 288 {
 289         switch (priv->hw_type) {
 290         case HIF_9000_SILICON_VERSATILE:
 291                 return cw1200_reg_write_16(priv,
 292                                            ST90TDS_CONFIG_REG_ID,
 293                                            (u16)val);
 294         case HIF_8601_VERSATILE:
 295         case HIF_8601_SILICON:
 296         default:
 297                 return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
 298         }
 299         return 0;
 300 }
 301 
 302 int cw1200_load_firmware(struct cw1200_common *priv)
 303 {
 304         int ret;
 305         int i;
 306         u32 val32;
 307         u16 val16;
 308         int major_revision = -1;
 309 
 310         /* Read CONFIG Register */
 311         ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
 312         if (ret < 0) {
 313                 pr_err("Can't read config register.\n");
 314                 goto out;
 315         }
 316 
 317         if (val32 == 0 || val32 == 0xffffffff) {
 318                 pr_err("Bad config register value (0x%08x)\n", val32);
 319                 ret = -EIO;
 320                 goto out;
 321         }
 322 
 323         ret = cw1200_get_hw_type(val32, &major_revision);
 324         if (ret < 0) {
 325                 pr_err("Can't deduce hardware type.\n");
 326                 goto out;
 327         }
 328         priv->hw_type = ret;
 329 
 330         /* Set DPLL Reg value, and read back to confirm writes work */
 331         ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
 332                                   cw1200_dpll_from_clk(priv->hw_refclk));
 333         if (ret < 0) {
 334                 pr_err("Can't write DPLL register.\n");
 335                 goto out;
 336         }
 337 
 338         msleep(20);
 339 
 340         ret = cw1200_reg_read_32(priv,
 341                 ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
 342         if (ret < 0) {
 343                 pr_err("Can't read DPLL register.\n");
 344                 goto out;
 345         }
 346 
 347         if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
 348                 pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
 349                        cw1200_dpll_from_clk(priv->hw_refclk), val32);
 350                 ret = -EIO;
 351                 goto out;
 352         }
 353 
 354         /* Set wakeup bit in device */
 355         ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
 356         if (ret < 0) {
 357                 pr_err("set_wakeup: can't read control register.\n");
 358                 goto out;
 359         }
 360 
 361         ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
 362                 val16 | ST90TDS_CONT_WUP_BIT);
 363         if (ret < 0) {
 364                 pr_err("set_wakeup: can't write control register.\n");
 365                 goto out;
 366         }
 367 
 368         /* Wait for wakeup */
 369         for (i = 0; i < 300; i += (1 + i / 2)) {
 370                 ret = cw1200_reg_read_16(priv,
 371                         ST90TDS_CONTROL_REG_ID, &val16);
 372                 if (ret < 0) {
 373                         pr_err("wait_for_wakeup: can't read control register.\n");
 374                         goto out;
 375                 }
 376 
 377                 if (val16 & ST90TDS_CONT_RDY_BIT)
 378                         break;
 379 
 380                 msleep(i);
 381         }
 382 
 383         if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
 384                 pr_err("wait_for_wakeup: device is not responding.\n");
 385                 ret = -ETIMEDOUT;
 386                 goto out;
 387         }
 388 
 389         switch (major_revision) {
 390         case 1:
 391                 /* CW1200 Hardware detection logic : Check for CUT1.1 */
 392                 ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
 393                 if (ret) {
 394                         pr_err("HW detection: can't read CUT ID.\n");
 395                         goto out;
 396                 }
 397 
 398                 switch (val32) {
 399                 case CW1200_CUT_11_ID_STR:
 400                         pr_info("CW1x00 Cut 1.1 silicon detected.\n");
 401                         priv->hw_revision = CW1200_HW_REV_CUT11;
 402                         break;
 403                 default:
 404                         pr_info("CW1x00 Cut 1.0 silicon detected.\n");
 405                         priv->hw_revision = CW1200_HW_REV_CUT10;
 406                         break;
 407                 }
 408 
 409                 /* According to ST-E, CUT<2.0 has busted BA TID0-3.
 410                    Just disable it entirely...
 411                 */
 412                 priv->ba_rx_tid_mask = 0;
 413                 priv->ba_tx_tid_mask = 0;
 414                 break;
 415         case 2: {
 416                 u32 ar1, ar2, ar3;
 417                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
 418                 if (ret) {
 419                         pr_err("(1) HW detection: can't read CUT ID\n");
 420                         goto out;
 421                 }
 422                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
 423                 if (ret) {
 424                         pr_err("(2) HW detection: can't read CUT ID.\n");
 425                         goto out;
 426                 }
 427 
 428                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
 429                 if (ret) {
 430                         pr_err("(3) HW detection: can't read CUT ID.\n");
 431                         goto out;
 432                 }
 433 
 434                 if (ar1 == CW1200_CUT_22_ID_STR1 &&
 435                     ar2 == CW1200_CUT_22_ID_STR2 &&
 436                     ar3 == CW1200_CUT_22_ID_STR3) {
 437                         pr_info("CW1x00 Cut 2.2 silicon detected.\n");
 438                         priv->hw_revision = CW1200_HW_REV_CUT22;
 439                 } else {
 440                         pr_info("CW1x00 Cut 2.0 silicon detected.\n");
 441                         priv->hw_revision = CW1200_HW_REV_CUT20;
 442                 }
 443                 break;
 444         }
 445         case 4:
 446                 pr_info("CW1x60 silicon detected.\n");
 447                 priv->hw_revision = CW1X60_HW_REV;
 448                 break;
 449         default:
 450                 pr_err("Unsupported silicon major revision %d.\n",
 451                        major_revision);
 452                 ret = -ENOTSUPP;
 453                 goto out;
 454         }
 455 
 456         /* Checking for access mode */
 457         ret = config_reg_read(priv, &val32);
 458         if (ret < 0) {
 459                 pr_err("Can't read config register.\n");
 460                 goto out;
 461         }
 462 
 463         if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
 464                 pr_err("Device is already in QUEUE mode!\n");
 465                 ret = -EINVAL;
 466                 goto out;
 467         }
 468 
 469         switch (priv->hw_type)  {
 470         case HIF_8601_SILICON:
 471                 if (priv->hw_revision == CW1X60_HW_REV) {
 472                         pr_err("Can't handle CW1160/1260 firmware load yet.\n");
 473                         ret = -ENOTSUPP;
 474                         goto out;
 475                 }
 476                 ret = cw1200_load_firmware_cw1200(priv);
 477                 break;
 478         default:
 479                 pr_err("Can't perform firmware load for hw type %d.\n",
 480                        priv->hw_type);
 481                 ret = -ENOTSUPP;
 482                 goto out;
 483         }
 484         if (ret < 0) {
 485                 pr_err("Firmware load error.\n");
 486                 goto out;
 487         }
 488 
 489         /* Enable interrupt signalling */
 490         priv->hwbus_ops->lock(priv->hwbus_priv);
 491         ret = __cw1200_irq_enable(priv, 1);
 492         priv->hwbus_ops->unlock(priv->hwbus_priv);
 493         if (ret < 0)
 494                 goto unsubscribe;
 495 
 496         /* Configure device for MESSSAGE MODE */
 497         ret = config_reg_read(priv, &val32);
 498         if (ret < 0) {
 499                 pr_err("Can't read config register.\n");
 500                 goto unsubscribe;
 501         }
 502         ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
 503         if (ret < 0) {
 504                 pr_err("Can't write config register.\n");
 505                 goto unsubscribe;
 506         }
 507 
 508         /* Unless we read the CONFIG Register we are
 509          * not able to get an interrupt
 510          */
 511         mdelay(10);
 512         config_reg_read(priv, &val32);
 513 
 514 out:
 515         return ret;
 516 
 517 unsubscribe:
 518         /* Disable interrupt signalling */
 519         priv->hwbus_ops->lock(priv->hwbus_priv);
 520         ret = __cw1200_irq_enable(priv, 0);
 521         priv->hwbus_ops->unlock(priv->hwbus_priv);
 522         return ret;
 523 }

/* [<][>][^][v][top][bottom][index][help] */