linux/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
<<
>>
Prefs
   1/*****************************************************************************
   2
   3            (c) Cambridge Silicon Radio Limited 2012
   4            All rights reserved and confidential information of CSR
   5
   6            Refer to LICENSE.txt included with this source for details
   7            on the license terms.
   8
   9*****************************************************************************/
  10
  11/*
  12 * ---------------------------------------------------------------------------
  13 * FILE: csr_wifi_hip_card_sdio_mem.c
  14 *
  15 * PURPOSE: Implementation of the Card API for SDIO.
  16 *
  17 * ---------------------------------------------------------------------------
  18 */
  19#include "csr_wifi_hip_unifi.h"
  20#include "csr_wifi_hip_card.h"
  21
  22#define SDIO_RETRIES    3
  23#define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16
  24
  25
  26#define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT))
  27
  28
  29/*
  30 * ---------------------------------------------------------------------------
  31 *  retrying_read8
  32 *  retrying_write8
  33 *
  34 *      These functions provide the first level of retry for SDIO operations.
  35 *      If an SDIO command fails for reason of a response timeout or CRC
  36 *      error, it is retried immediately. If three attempts fail we report a
  37 *      failure.
  38 *      If the command failed for any other reason, the failure is reported
  39 *      immediately.
  40 *
  41 *  Arguments:
  42 *      card            Pointer to card structure.
  43 *      funcnum         The SDIO function to access.
  44 *                      Function 0 is the Card Configuration Register space,
  45 *                      function 1/2 is the UniFi register space.
  46 *      addr            Address to access
  47 *      pdata           Pointer in which to return the value read.
  48 *      data            Value to write.
  49 *
  50 *  Returns:
  51 *      CSR_RESULT_SUCCESS  on success, non-zero error code on error:
  52 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
  53 *      CSR_RESULT_FAILURE     an SDIO error occurred
  54 * ---------------------------------------------------------------------------
  55 */
  56static CsrResult retrying_read8(card_t *card, s16 funcnum, u32 addr, u8 *pdata)
  57{
  58    CsrSdioFunction *sdio = card->sdio_if;
  59    CsrResult r = CSR_RESULT_SUCCESS;
  60    s16 retries;
  61    CsrResult csrResult = CSR_RESULT_SUCCESS;
  62
  63    retries = 0;
  64    while (retries++ < SDIO_RETRIES)
  65    {
  66        if (funcnum == 0)
  67        {
  68#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
  69            unifi_debug_log_to_buf("r0@%02X", addr);
  70#endif
  71            csrResult = CsrSdioF0Read8(sdio, addr, pdata);
  72        }
  73        else
  74        {
  75#ifdef CSR_WIFI_TRANSPORT_CSPI
  76            unifi_error(card->ospriv,
  77                        "retrying_read_f0_8: F1 8-bit reads are not allowed.\n");
  78            return CSR_RESULT_FAILURE;
  79#else
  80#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
  81            unifi_debug_log_to_buf("r@%02X", addr);
  82#endif
  83            csrResult = CsrSdioRead8(sdio, addr, pdata);
  84#endif
  85        }
  86#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
  87        if (csrResult != CSR_RESULT_SUCCESS)
  88        {
  89            unifi_debug_log_to_buf("error=%X\n", csrResult);
  90        }
  91        else
  92        {
  93            unifi_debug_log_to_buf("=%X\n", *pdata);
  94        }
  95#endif
  96        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
  97        {
  98            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
  99        }
 100        /*
 101         * Try again for retryable (CRC or TIMEOUT) errors,
 102         * break on success or fatal error
 103         */
 104        if (!retryable_sdio_error(csrResult))
 105        {
 106#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
 107            card->cmd_prof.cmd52_count++;
 108#endif
 109            break;
 110        }
 111        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
 112    }
 113
 114    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
 115    {
 116        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
 117    }
 118
 119    if (csrResult != CSR_RESULT_SUCCESS)
 120    {
 121        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
 122                    addr, retries - 1);
 123        /* Report any SDIO error as a general i/o error */
 124        r = CSR_RESULT_FAILURE;
 125    }
 126
 127    return r;
 128} /* retrying_read8() */
 129
 130
 131static CsrResult retrying_write8(card_t *card, s16 funcnum, u32 addr, u8 data)
 132{
 133    CsrSdioFunction *sdio = card->sdio_if;
 134    CsrResult r = CSR_RESULT_SUCCESS;
 135    s16 retries;
 136    CsrResult csrResult = CSR_RESULT_SUCCESS;
 137
 138    retries = 0;
 139    while (retries++ < SDIO_RETRIES)
 140    {
 141        if (funcnum == 0)
 142        {
 143#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 144            unifi_debug_log_to_buf("w0@%02X=%X", addr, data);
 145#endif
 146            csrResult = CsrSdioF0Write8(sdio, addr, data);
 147        }
 148        else
 149        {
 150#ifdef CSR_WIFI_TRANSPORT_CSPI
 151            unifi_error(card->ospriv,
 152                        "retrying_write_f0_8: F1 8-bit writes are not allowed.\n");
 153            return CSR_RESULT_FAILURE;
 154#else
 155#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 156            unifi_debug_log_to_buf("w@%02X=%X", addr, data);
 157#endif
 158            csrResult = CsrSdioWrite8(sdio, addr, data);
 159#endif
 160        }
 161#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 162        if (csrResult != CSR_RESULT_SUCCESS)
 163        {
 164            unifi_debug_log_to_buf(",error=%X", csrResult);
 165        }
 166        unifi_debug_string_to_buf("\n");
 167#endif
 168        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
 169        {
 170            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
 171        }
 172        /*
 173         * Try again for retryable (CRC or TIMEOUT) errors,
 174         * break on success or fatal error
 175         */
 176        if (!retryable_sdio_error(csrResult))
 177        {
 178#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
 179            card->cmd_prof.cmd52_count++;
 180#endif
 181            break;
 182        }
 183        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
 184                    data, funcnum, addr);
 185    }
 186
 187    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
 188    {
 189        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
 190    }
 191
 192    if (csrResult != CSR_RESULT_SUCCESS)
 193    {
 194        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
 195                    addr, retries - 1);
 196        /* Report any SDIO error as a general i/o error */
 197        r = CSR_RESULT_FAILURE;
 198    }
 199
 200    return r;
 201} /* retrying_write8() */
 202
 203
 204static CsrResult retrying_read16(card_t *card, s16 funcnum,
 205                                 u32 addr, u16 *pdata)
 206{
 207    CsrSdioFunction *sdio = card->sdio_if;
 208    CsrResult r = CSR_RESULT_SUCCESS;
 209    s16 retries;
 210    CsrResult csrResult = CSR_RESULT_SUCCESS;
 211
 212    retries = 0;
 213    while (retries++ < SDIO_RETRIES)
 214    {
 215#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 216        unifi_debug_log_to_buf("r@%02X", addr);
 217#endif
 218        csrResult = CsrSdioRead16(sdio, addr, pdata);
 219#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 220        if (csrResult != CSR_RESULT_SUCCESS)
 221        {
 222            unifi_debug_log_to_buf("error=%X\n", csrResult);
 223        }
 224        else
 225        {
 226            unifi_debug_log_to_buf("=%X\n", *pdata);
 227        }
 228#endif
 229        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
 230        {
 231            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
 232        }
 233
 234        /*
 235         * Try again for retryable (CRC or TIMEOUT) errors,
 236         * break on success or fatal error
 237         */
 238        if (!retryable_sdio_error(csrResult))
 239        {
 240#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
 241            card->cmd_prof.cmd52_count++;
 242#endif
 243            break;
 244        }
 245        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
 246    }
 247
 248    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
 249    {
 250        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
 251    }
 252
 253    if (csrResult != CSR_RESULT_SUCCESS)
 254    {
 255        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
 256                    addr, retries - 1);
 257        /* Report any SDIO error as a general i/o error */
 258        r = CSR_RESULT_FAILURE;
 259    }
 260
 261    return r;
 262} /* retrying_read16() */
 263
 264
 265static CsrResult retrying_write16(card_t *card, s16 funcnum,
 266                                  u32 addr, u16 data)
 267{
 268    CsrSdioFunction *sdio = card->sdio_if;
 269    CsrResult r = CSR_RESULT_SUCCESS;
 270    s16 retries;
 271    CsrResult csrResult = CSR_RESULT_SUCCESS;
 272
 273    retries = 0;
 274    while (retries++ < SDIO_RETRIES)
 275    {
 276#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 277        unifi_debug_log_to_buf("w@%02X=%X", addr, data);
 278#endif
 279        csrResult = CsrSdioWrite16(sdio, addr, data);
 280#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
 281        if (csrResult != CSR_RESULT_SUCCESS)
 282        {
 283            unifi_debug_log_to_buf(",error=%X", csrResult);
 284        }
 285        unifi_debug_string_to_buf("\n");
 286#endif
 287        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
 288        {
 289            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
 290        }
 291
 292        /*
 293         * Try again for retryable (CRC or TIMEOUT) errors,
 294         * break on success or fatal error
 295         */
 296        if (!retryable_sdio_error(csrResult))
 297        {
 298#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
 299            card->cmd_prof.cmd52_count++;
 300#endif
 301            break;
 302        }
 303        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
 304                    data, funcnum, addr);
 305    }
 306
 307    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
 308    {
 309        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
 310    }
 311
 312    if (csrResult != CSR_RESULT_SUCCESS)
 313    {
 314        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
 315                    addr, retries - 1);
 316        /* Report any SDIO error as a general i/o error */
 317        r = CSR_RESULT_FAILURE;
 318    }
 319
 320    return r;
 321} /* retrying_write16() */
 322
 323
 324/*
 325 * ---------------------------------------------------------------------------
 326 *  sdio_read_f0
 327 *
 328 *      Reads a byte value from the CCCR (func 0) area of UniFi.
 329 *
 330 *  Arguments:
 331 *      card    Pointer to card structure.
 332 *      addr    Address to read from
 333 *      pdata   Pointer in which to store the read value.
 334 *
 335 *  Returns:
 336 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 337 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 338 *      CSR_RESULT_FAILURE     an SDIO error occurred
 339 * ---------------------------------------------------------------------------
 340 */
 341CsrResult sdio_read_f0(card_t *card, u32 addr, u8 *pdata)
 342{
 343#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
 344    card->cmd_prof.cmd52_f0_r_count++;
 345#endif
 346    return retrying_read8(card, 0, addr, pdata);
 347} /* sdio_read_f0() */
 348
 349
 350/*
 351 * ---------------------------------------------------------------------------
 352 *  sdio_write_f0
 353 *
 354 *      Writes a byte value to the CCCR (func 0) area of UniFi.
 355 *
 356 *  Arguments:
 357 *      card    Pointer to card structure.
 358 *      addr    Address to read from
 359 *      data    Data value to write.
 360 *
 361 *  Returns:
 362 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 363 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 364 *      CSR_RESULT_FAILURE     an SDIO error occurred
 365 * ---------------------------------------------------------------------------
 366 */
 367CsrResult sdio_write_f0(card_t *card, u32 addr, u8 data)
 368{
 369#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
 370    card->cmd_prof.cmd52_f0_w_count++;
 371#endif
 372    return retrying_write8(card, 0, addr, data);
 373} /* sdio_write_f0() */
 374
 375
 376/*
 377 * ---------------------------------------------------------------------------
 378 * unifi_read_direct_8_or_16
 379 *
 380 *      Read a 8-bit value from the UniFi SDIO interface.
 381 *
 382 *  Arguments:
 383 *      card    Pointer to card structure.
 384 *      addr    Address to read from
 385 *      pdata   Pointer in which to return data.
 386 *
 387 *  Returns:
 388 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 389 * ---------------------------------------------------------------------------
 390 */
 391CsrResult unifi_read_direct_8_or_16(card_t *card, u32 addr, u8 *pdata)
 392{
 393#ifdef CSR_WIFI_TRANSPORT_CSPI
 394    u16 w;
 395    CsrResult r;
 396
 397    r = retrying_read16(card, card->function, addr, &w);
 398    *pdata = (u8)(w & 0xFF);
 399    return r;
 400#else
 401    return retrying_read8(card, card->function, addr, pdata);
 402#endif
 403} /* unifi_read_direct_8_or_16() */
 404
 405
 406/*
 407 * ---------------------------------------------------------------------------
 408 *  unifi_write_direct_8_or_16
 409 *
 410 *      Write a byte value to the UniFi SDIO interface.
 411 *
 412 *  Arguments:
 413 *      card    Pointer to card structure.
 414 *      addr    Address to write to
 415 *      data    Value to write.
 416 *
 417 *  Returns:
 418 *      CSR_RESULT_SUCCESS on success, non-zero error code on error
 419 *
 420 *  Notes:
 421 *      If 8-bit write is used, the even address *must* be written second.
 422 *      This is because writes to odd bytes are cached and not committed
 423 *      to memory until the preceding even address is written.
 424 * ---------------------------------------------------------------------------
 425 */
 426CsrResult unifi_write_direct_8_or_16(card_t *card, u32 addr, u8 data)
 427{
 428    if (addr & 1)
 429    {
 430        unifi_warning(card->ospriv,
 431                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
 432                      addr);
 433    }
 434
 435#ifdef CSR_WIFI_TRANSPORT_CSPI
 436    return retrying_write16(card, card->function, addr, (u16)data);
 437#else
 438    return retrying_write8(card, card->function, addr, data);
 439#endif
 440} /* unifi_write_direct_8_or_16() */
 441
 442
 443/*
 444 * ---------------------------------------------------------------------------
 445 *  unifi_read_direct16
 446 *
 447 *      Read a 16-bit value from the UniFi SDIO interface.
 448 *
 449 *  Arguments:
 450 *      card    Pointer to card structure.
 451 *      addr    Address to read from
 452 *      pdata   Pointer in which to return data.
 453 *
 454 *  Returns:
 455 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 456 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 457 *      CSR_RESULT_FAILURE     an SDIO error occurred
 458 *
 459 *  Notes:
 460 *      The even address *must* be read first. This is because reads from
 461 *      odd bytes are cached and read from memory when the preceding
 462 *      even address is read.
 463 * ---------------------------------------------------------------------------
 464 */
 465CsrResult unifi_read_direct16(card_t *card, u32 addr, u16 *pdata)
 466{
 467    return retrying_read16(card, card->function, addr, pdata);
 468} /* unifi_read_direct16() */
 469
 470
 471/*
 472 * ---------------------------------------------------------------------------
 473 *  unifi_write_direct16
 474 *
 475 *      Write a 16-bit value to the UniFi SDIO interface.
 476 *
 477 *  Arguments:
 478 *      card    Pointer to card structure.
 479 *      addr    Address to write to
 480 *      data    Value to write.
 481 *
 482 *  Returns:
 483 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 484 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 485 *      CSR_RESULT_FAILURE     an SDIO error occurred
 486 *
 487 *  Notes:
 488 *      The even address *must* be written second. This is because writes to
 489 *      odd bytes are cached and not committed to memory until the preceding
 490 *      even address is written.
 491 * ---------------------------------------------------------------------------
 492 */
 493CsrResult unifi_write_direct16(card_t *card, u32 addr, u16 data)
 494{
 495    return retrying_write16(card, card->function, addr, data);
 496} /* unifi_write_direct16() */
 497
 498
 499/*
 500 * ---------------------------------------------------------------------------
 501 *  unifi_read_direct32
 502 *
 503 *      Read a 32-bit value from the UniFi SDIO interface.
 504 *
 505 *  Arguments:
 506 *      card    Pointer to card structure.
 507 *      addr    Address to read from
 508 *      pdata   Pointer in which to return data.
 509 *
 510 *  Returns:
 511 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 512 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 513 *      CSR_RESULT_FAILURE     an SDIO error occurred
 514 * ---------------------------------------------------------------------------
 515 */
 516CsrResult unifi_read_direct32(card_t *card, u32 addr, u32 *pdata)
 517{
 518    CsrResult r;
 519    u16 w0, w1;
 520
 521    r = retrying_read16(card, card->function, addr, &w0);
 522    if (r != CSR_RESULT_SUCCESS)
 523    {
 524        return r;
 525    }
 526
 527    r = retrying_read16(card, card->function, addr + 2, &w1);
 528    if (r != CSR_RESULT_SUCCESS)
 529    {
 530        return r;
 531    }
 532
 533    *pdata = ((u32)w1 << 16) | (u32)w0;
 534
 535    return CSR_RESULT_SUCCESS;
 536} /* unifi_read_direct32() */
 537
 538
 539/*
 540 * ---------------------------------------------------------------------------
 541 *  unifi_read_directn_match
 542 *
 543 *      Read multiple 8-bit values from the UniFi SDIO interface,
 544 *      stopping when either we have read 'len' bytes or we have read
 545 *      a octet equal to 'match'.  If 'match' is not a valid octet
 546 *      then this function is the same as 'unifi_read_directn'.
 547 *
 548 *  Arguments:
 549 *      card            Pointer to card structure.
 550 *      addr            Start address to read from.
 551 *      pdata           Pointer to which to write data.
 552 *      len             Maximum umber of bytes to read
 553 *      match           The value to stop reading at.
 554 *      num             Pointer to buffer to write number of bytes read
 555 *
 556 *  Returns:
 557 *      number of octets read on success, negative error code on error:
 558 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 559 *      CSR_RESULT_FAILURE     an SDIO error occurred
 560 *
 561 *  Notes:
 562 *      The even address *must* be read first. This is because reads from
 563 *      odd bytes are cached and read from memory when the preceding
 564 *      even address is read.
 565 * ---------------------------------------------------------------------------
 566 */
 567static CsrResult unifi_read_directn_match(card_t *card, u32 addr, void *pdata, u16 len, s8 m, u32 *num)
 568{
 569    CsrResult r;
 570    u32 i;
 571    u8 *cptr;
 572    u16 w;
 573
 574    *num = 0;
 575
 576    cptr = (u8 *)pdata;
 577    for (i = 0; i < len; i += 2)
 578    {
 579        r = retrying_read16(card, card->function, addr, &w);
 580        if (r != CSR_RESULT_SUCCESS)
 581        {
 582            return r;
 583        }
 584
 585        *cptr++ = ((u8)w & 0xFF);
 586        if ((m >= 0) && (((s8)w & 0xFF) == m))
 587        {
 588            break;
 589        }
 590
 591        if (i + 1 == len)
 592        {
 593            /* The len is odd. Ignore the last high byte */
 594            break;
 595        }
 596
 597        *cptr++ = ((u8)(w >> 8) & 0xFF);
 598        if ((m >= 0) && (((s8)(w >> 8) & 0xFF) == m))
 599        {
 600            break;
 601        }
 602
 603        addr += 2;
 604    }
 605
 606    *num = (s32)(cptr - (u8 *)pdata);
 607    return CSR_RESULT_SUCCESS;
 608}
 609
 610
 611/*
 612 * ---------------------------------------------------------------------------
 613 *  unifi_read_directn
 614 *
 615 *      Read multiple 8-bit values from the UniFi SDIO interface.
 616 *
 617 *  Arguments:
 618 *      card            Pointer to card structure.
 619 *      addr            Start address to read from.
 620 *      pdata           Pointer to which to write data.
 621 *      len             Number of bytes to read
 622 *
 623 *  Returns:
 624 *      0 on success, non-zero error code on error:
 625 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 626 *      CSR_RESULT_FAILURE     an SDIO error occurred
 627 *
 628 *  Notes:
 629 *      The even address *must* be read first. This is because reads from
 630 *      odd bytes are cached and read from memory when the preceding
 631 *      even address is read.
 632 * ---------------------------------------------------------------------------
 633 */
 634CsrResult unifi_read_directn(card_t *card, u32 addr, void *pdata, u16 len)
 635{
 636    u32 num;
 637
 638    return unifi_read_directn_match(card, addr, pdata, len, -1, &num);
 639} /* unifi_read_directn() */
 640
 641
 642/*
 643 * ---------------------------------------------------------------------------
 644 *  unifi_write_directn
 645 *
 646 *      Write multiple 8-bit values to the UniFi SDIO interface.
 647 *
 648 *  Arguments:
 649 *      card            Pointer to card structure.
 650 *      addr            Start address to write to.
 651 *      pdata           Source data pointer.
 652 *      len             Number of bytes to write, must be even.
 653 *
 654 *  Returns:
 655 *      0 on success, non-zero error code on error:
 656 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 657 *      CSR_RESULT_FAILURE     an SDIO error occurred
 658 *
 659 *  Notes:
 660 *      The UniFi has a peculiar 16-bit bus architecture. Writes are only
 661 *      committed to memory when an even address is accessed. Writes to
 662 *      odd addresses are cached and only committed if the next write is
 663 *      to the preceding address.
 664 *      This means we must write data as pairs of bytes in reverse order.
 665 * ---------------------------------------------------------------------------
 666 */
 667CsrResult unifi_write_directn(card_t *card, u32 addr, void *pdata, u16 len)
 668{
 669    CsrResult r;
 670    u8 *cptr;
 671    s16 signed_len;
 672
 673    cptr = (u8 *)pdata;
 674    signed_len = (s16)len;
 675    while (signed_len > 0)
 676    {
 677        /* This is UniFi-1 specific code. CSPI not supported so 8-bit write allowed */
 678        r = retrying_write16(card, card->function, addr, *cptr);
 679        if (r != CSR_RESULT_SUCCESS)
 680        {
 681            return r;
 682        }
 683
 684        cptr += 2;
 685        addr += 2;
 686        signed_len -= 2;
 687    }
 688
 689    return CSR_RESULT_SUCCESS;
 690} /* unifi_write_directn() */
 691
 692
 693/*
 694 * ---------------------------------------------------------------------------
 695 *  set_dmem_page
 696 *  set_pmem_page
 697 *
 698 *      Set up the page register for the shared data memory window or program
 699 *      memory window.
 700 *
 701 *  Arguments:
 702 *      card            Pointer to card structure.
 703 *      dmem_addr       UniFi shared-data-memory address to access.
 704 *      pmem_addr       UniFi program memory address to access. This includes
 705 *                        External FLASH memory at    0x000000
 706 *                        Processor program memory at 0x200000
 707 *                        External SRAM at memory     0x400000
 708 *      paddr           Location to write an SDIO address (24-bit) for
 709 *                       use in a unifi_read_direct or unifi_write_direct call.
 710 *
 711 *  Returns:
 712 *      CSR_RESULT_SUCCESS on success
 713 *      CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
 714 *      CSR_RESULT_FAILURE an SDIO error occurred
 715 * ---------------------------------------------------------------------------
 716 */
 717static CsrResult set_dmem_page(card_t *card, u32 dmem_addr, u32 *paddr)
 718{
 719    u16 page, addr;
 720    u32 len;
 721    CsrResult r;
 722
 723    *paddr = 0;
 724
 725    if (!ChipHelper_DecodeWindow(card->helper,
 726                                 CHIP_HELPER_WINDOW_3,
 727                                 CHIP_HELPER_WT_SHARED,
 728                                 dmem_addr / 2,
 729                                 &page, &addr, &len))
 730    {
 731        unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr);
 732        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 733    }
 734
 735    if (page != card->dmem_page)
 736    {
 737        unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr);
 738
 739        /* change page register */
 740        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page);
 741        if (r != CSR_RESULT_SUCCESS)
 742        {
 743            unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
 744            return r;
 745        }
 746
 747        card->dmem_page = page;
 748    }
 749
 750    *paddr = ((s32)addr * 2) + (dmem_addr & 1);
 751
 752    return CSR_RESULT_SUCCESS;
 753} /* set_dmem_page() */
 754
 755
 756static CsrResult set_pmem_page(card_t *card, u32 pmem_addr,
 757                               enum chip_helper_window_type mem_type, u32 *paddr)
 758{
 759    u16 page, addr;
 760    u32 len;
 761    CsrResult r;
 762
 763    *paddr = 0;
 764
 765    if (!ChipHelper_DecodeWindow(card->helper,
 766                                 CHIP_HELPER_WINDOW_2,
 767                                 mem_type,
 768                                 pmem_addr / 2,
 769                                 &page, &addr, &len))
 770    {
 771        unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type);
 772        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 773    }
 774
 775    if (page != card->pmem_page)
 776    {
 777        unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr);
 778
 779        /* change page register */
 780        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page);
 781        if (r != CSR_RESULT_SUCCESS)
 782        {
 783            unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n");
 784            return r;
 785        }
 786
 787        card->pmem_page = page;
 788    }
 789
 790    *paddr = ((s32)addr * 2) + (pmem_addr & 1);
 791
 792    return CSR_RESULT_SUCCESS;
 793} /* set_pmem_page() */
 794
 795
 796/*
 797 * ---------------------------------------------------------------------------
 798 *  set_page
 799 *
 800 *      Sets up the appropriate page register to access the given address.
 801 *      Returns the sdio address at which the unifi address can be accessed.
 802 *
 803 *  Arguments:
 804 *      card            Pointer to card structure.
 805 *      generic_addr    UniFi internal address to access, in Generic Pointer
 806 *                      format, i.e. top byte is space indicator.
 807 *      paddr           Location to write page address
 808 *                          SDIO address (24-bit) for use in a unifi_read_direct or
 809 *                          unifi_write_direct call
 810 *
 811 *  Returns:
 812 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 813 *      CSR_RESULT_FAILURE     an SDIO error occurred
 814 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  the address is invalid
 815 * ---------------------------------------------------------------------------
 816 */
 817static CsrResult set_page(card_t *card, u32 generic_addr, u32 *paddr)
 818{
 819    s32 space;
 820    u32 addr;
 821    CsrResult r = CSR_RESULT_SUCCESS;
 822
 823    if (!paddr)
 824    {
 825        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 826    }
 827    *paddr = 0;
 828    space = UNIFI_GP_SPACE(generic_addr);
 829    addr = UNIFI_GP_OFFSET(generic_addr);
 830    switch (space)
 831    {
 832        case UNIFI_SH_DMEM:
 833            /* Shared Data Memory is accessed via the Shared Data Memory window */
 834            r = set_dmem_page(card, addr, paddr);
 835            if (r != CSR_RESULT_SUCCESS)
 836            {
 837                return r;
 838            }
 839            break;
 840
 841        case UNIFI_EXT_FLASH:
 842            if (!ChipHelper_HasFlash(card->helper))
 843            {
 844                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 845                            generic_addr, card->helper);
 846                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 847            }
 848            /* External FLASH is accessed via the Program Memory window */
 849            r = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH, paddr);
 850            break;
 851
 852        case UNIFI_EXT_SRAM:
 853            if (!ChipHelper_HasExtSram(card->helper))
 854            {
 855                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n",
 856                            generic_addr, card->helper);
 857                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 858            }
 859            /* External SRAM is accessed via the Program Memory window */
 860            r = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM, paddr);
 861            break;
 862
 863        case UNIFI_REGISTERS:
 864            /* Registers are accessed directly */
 865            *paddr = addr;
 866            break;
 867
 868        case UNIFI_PHY_DMEM:
 869            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
 870            if (r != CSR_RESULT_SUCCESS)
 871            {
 872                return r;
 873            }
 874            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
 875            break;
 876
 877        case UNIFI_MAC_DMEM:
 878            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
 879            if (r != CSR_RESULT_SUCCESS)
 880            {
 881                return r;
 882            }
 883            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
 884            break;
 885
 886        case UNIFI_BT_DMEM:
 887            if (!ChipHelper_HasBt(card->helper))
 888            {
 889                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 890                            generic_addr, card->helper);
 891                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 892            }
 893            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
 894            if (r != CSR_RESULT_SUCCESS)
 895            {
 896                return r;
 897            }
 898            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
 899            break;
 900
 901        case UNIFI_PHY_PMEM:
 902            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
 903            if (r != CSR_RESULT_SUCCESS)
 904            {
 905                return r;
 906            }
 907            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
 908            break;
 909
 910        case UNIFI_MAC_PMEM:
 911            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
 912            if (r != CSR_RESULT_SUCCESS)
 913            {
 914                return r;
 915            }
 916            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
 917            break;
 918
 919        case UNIFI_BT_PMEM:
 920            if (!ChipHelper_HasBt(card->helper))
 921            {
 922                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 923                            generic_addr, card->helper);
 924                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 925            }
 926            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
 927            if (r != CSR_RESULT_SUCCESS)
 928            {
 929                return r;
 930            }
 931            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
 932            break;
 933
 934        case UNIFI_PHY_ROM:
 935            if (!ChipHelper_HasRom(card->helper))
 936            {
 937                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 938                            generic_addr, card->helper);
 939                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 940            }
 941            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
 942            if (r != CSR_RESULT_SUCCESS)
 943            {
 944                return r;
 945            }
 946            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
 947            break;
 948
 949        case UNIFI_MAC_ROM:
 950            if (!ChipHelper_HasRom(card->helper))
 951            {
 952                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 953                            generic_addr, card->helper);
 954                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 955            }
 956            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
 957            if (r != CSR_RESULT_SUCCESS)
 958            {
 959                return r;
 960            }
 961            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
 962            break;
 963
 964        case UNIFI_BT_ROM:
 965            if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper))
 966            {
 967                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
 968                            generic_addr, card->helper);
 969                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 970            }
 971            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
 972            if (r != CSR_RESULT_SUCCESS)
 973            {
 974                return r;
 975            }
 976            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
 977            break;
 978
 979        default:
 980            unifi_error(card->ospriv, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n",
 981                        space, generic_addr, card->helper);
 982            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 983    }
 984
 985    return r;
 986} /* set_page() */
 987
 988
 989/*
 990 * ---------------------------------------------------------------------------
 991 *  unifi_set_proc_select
 992 *
 993 *
 994 *  Arguments:
 995 *      card            Pointer to card structure.
 996 *      select          Which XAP core to select
 997 *
 998 *  Returns:
 999 *      0 on success, non-zero error code on error:
1000 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1001 *      CSR_RESULT_FAILURE     an SDIO error occurred
1002 * ---------------------------------------------------------------------------
1003 */
1004CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select)
1005{
1006    CsrResult r;
1007
1008    /* Verify the the select value is allowed. */
1009    switch (select)
1010    {
1011        case UNIFI_PROC_MAC:
1012        case UNIFI_PROC_PHY:
1013        case UNIFI_PROC_BOTH:
1014            break;
1015
1016
1017        default:
1018            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1019    }
1020
1021    if (card->proc_select != (u32)select)
1022    {
1023        r = unifi_write_direct16(card,
1024                                 ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2,
1025                                 (u8)select);
1026        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1027        {
1028            return r;
1029        }
1030        if (r != CSR_RESULT_SUCCESS)
1031        {
1032            unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
1033            return r;
1034        }
1035
1036        card->proc_select = (u32)select;
1037    }
1038
1039    return CSR_RESULT_SUCCESS;
1040}
1041
1042
1043/*
1044 * ---------------------------------------------------------------------------
1045 * unifi_read_8_or_16
1046 *
1047 * Performs a byte read of the given address in shared data memory.
1048 * Set up the shared data memory page register as required.
1049 *
1050 * Arguments:
1051 * card Pointer to card structure.
1052 * unifi_addr UniFi shared-data-memory address to access.
1053 * pdata Pointer to a byte variable for the value read.
1054 *
1055 * Returns:
1056 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1057 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1058 * CSR_RESULT_FAILURE an SDIO error occurred
1059 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1060 * ---------------------------------------------------------------------------
1061 */
1062CsrResult unifi_read_8_or_16(card_t *card, u32 unifi_addr, u8 *pdata)
1063{
1064    u32 sdio_addr;
1065    CsrResult r;
1066#ifdef CSR_WIFI_TRANSPORT_CSPI
1067    u16 w;
1068#endif
1069
1070    r = set_page(card, unifi_addr, &sdio_addr);
1071    if (r != CSR_RESULT_SUCCESS)
1072    {
1073        return r;
1074    }
1075
1076#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1077    card->cmd_prof.cmd52_r8or16_count++;
1078#endif
1079#ifdef CSR_WIFI_TRANSPORT_CSPI
1080    r = retrying_read16(card, card->function, sdio_addr, &w);
1081    *pdata = (u8)(w & 0xFF);
1082    return r;
1083#else
1084    return retrying_read8(card, card->function, sdio_addr, pdata);
1085#endif
1086} /* unifi_read_8_or_16() */
1087
1088
1089/*
1090 * ---------------------------------------------------------------------------
1091 * unifi_write_8_or_16
1092 *
1093 * Performs a byte write of the given address in shared data memory.
1094 * Set up the shared data memory page register as required.
1095 *
1096 * Arguments:
1097 * card Pointer to card context struct.
1098 * unifi_addr UniFi shared-data-memory address to access.
1099 * data Value to write.
1100 *
1101 * Returns:
1102 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1103 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1104 * CSR_RESULT_FAILURE an SDIO error occurred
1105 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1106 *
1107 * Notes:
1108 * Beware using unifi_write8() because byte writes are not safe on UniFi.
1109 * Writes to odd bytes are cached, writes to even bytes perform a 16-bit
1110 * write with the previously cached odd byte.
1111 * ---------------------------------------------------------------------------
1112 */
1113CsrResult unifi_write_8_or_16(card_t *card, u32 unifi_addr, u8 data)
1114{
1115    u32 sdio_addr;
1116    CsrResult r;
1117#ifdef CSR_WIFI_TRANSPORT_CSPI
1118    u16 w;
1119#endif
1120
1121    r = set_page(card, unifi_addr, &sdio_addr);
1122    if (r != CSR_RESULT_SUCCESS)
1123    {
1124        return r;
1125    }
1126
1127    if (sdio_addr & 1)
1128    {
1129        unifi_warning(card->ospriv,
1130                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
1131                      sdio_addr);
1132    }
1133
1134#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1135    card->cmd_prof.cmd52_w8or16_count++;
1136#endif
1137#ifdef CSR_WIFI_TRANSPORT_CSPI
1138    w = data;
1139    return retrying_write16(card, card->function, sdio_addr, w);
1140#else
1141    return retrying_write8(card, card->function, sdio_addr, data);
1142#endif
1143} /* unifi_write_8_or_16() */
1144
1145
1146/*
1147 * ---------------------------------------------------------------------------
1148 *  unifi_card_read16
1149 *
1150 *      Performs a 16-bit read of the given address in shared data memory.
1151 *      Set up the shared data memory page register as required.
1152 *
1153 *  Arguments:
1154 *      card            Pointer to card structure.
1155 *      unifi_addr      UniFi shared-data-memory address to access.
1156 *      pdata           Pointer to a 16-bit int variable for the value read.
1157 *
1158 *  Returns:
1159 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
1160 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1161 *      CSR_RESULT_FAILURE     an SDIO error occurred
1162 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
1163 * ---------------------------------------------------------------------------
1164 */
1165CsrResult unifi_card_read16(card_t *card, u32 unifi_addr, u16 *pdata)
1166{
1167    u32 sdio_addr;
1168    CsrResult r;
1169
1170    r = set_page(card, unifi_addr, &sdio_addr);
1171    if (r != CSR_RESULT_SUCCESS)
1172    {
1173        return r;
1174    }
1175
1176#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1177    card->cmd_prof.cmd52_r16_count++;
1178#endif
1179    return unifi_read_direct16(card, sdio_addr, pdata);
1180} /* unifi_card_read16() */
1181
1182
1183/*
1184 * ---------------------------------------------------------------------------
1185 *  unifi_card_write16
1186 *
1187 *      Performs a 16-bit write of the given address in shared data memory.
1188 *      Set up the shared data memory page register as required.
1189 *
1190 *  Arguments:
1191 *      card            Pointer to card structure.
1192 *      unifi_addr      UniFi shared-data-memory address to access.
1193 *      pdata           Pointer to a byte variable for the value write.
1194 *
1195 *  Returns:
1196 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
1197 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1198 *      CSR_RESULT_FAILURE     an SDIO error occurred
1199 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
1200 * ---------------------------------------------------------------------------
1201 */
1202CsrResult unifi_card_write16(card_t *card, u32 unifi_addr, u16 data)
1203{
1204    u32 sdio_addr;
1205    CsrResult r;
1206
1207    r = set_page(card, unifi_addr, &sdio_addr);
1208    if (r != CSR_RESULT_SUCCESS)
1209    {
1210        return r;
1211    }
1212
1213#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1214    card->cmd_prof.cmd52_w16_count++;
1215#endif
1216    return unifi_write_direct16(card, sdio_addr, data);
1217} /* unifi_card_write16() */
1218
1219
1220/*
1221 * ---------------------------------------------------------------------------
1222 *  unifi_read32
1223 *
1224 *      Performs a 32-bit read of the given address in shared data memory.
1225 *      Set up the shared data memory page register as required.
1226 *
1227 *  Arguments:
1228 *      card            Pointer to card structure.
1229 *      unifi_addr      UniFi shared-data-memory address to access.
1230 *      pdata           Pointer to a int variable for the value read.
1231 *
1232 *  Returns:
1233 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
1234 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1235 *      CSR_RESULT_FAILURE     an SDIO error occurred
1236 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
1237 * ---------------------------------------------------------------------------
1238 */
1239CsrResult unifi_read32(card_t *card, u32 unifi_addr, u32 *pdata)
1240{
1241    u32 sdio_addr;
1242    CsrResult r;
1243
1244    r = set_page(card, unifi_addr, &sdio_addr);
1245    if (r != CSR_RESULT_SUCCESS)
1246    {
1247        return r;
1248    }
1249
1250#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1251    card->cmd_prof.cmd52_r32_count++;
1252#endif
1253    return unifi_read_direct32(card, sdio_addr, pdata);
1254} /* unifi_read32() */
1255
1256
1257/*
1258 * ---------------------------------------------------------------------------
1259 *  unifi_card_readn
1260 *  unifi_readnz
1261 *
1262 *      Read multiple 8-bit values from the UniFi SDIO interface.
1263 *      This function interprets the address as a GenericPointer as
1264 *      defined in the UniFi Host Interface Protocol Specification.
1265 *      The readnz version of this function will stop when it reads a
1266 *      zero octet.
1267 *
1268 *  Arguments:
1269 *      card            Pointer to card structure.
1270 *      unifi_addr      UniFi shared-data-memory address to access.
1271 *      pdata           Pointer to which to write data.
1272 *      len             Number of bytes to read
1273 *
1274 *  Returns:
1275 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
1276 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1277 *      CSR_RESULT_FAILURE     an SDIO error occurred
1278 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
1279 * ---------------------------------------------------------------------------
1280 */
1281CsrResult unifi_readn_match(card_t *card, u32 unifi_addr, void *pdata, u16 len, s8 match)
1282{
1283    u32 sdio_addr;
1284    CsrResult r;
1285    u32 num;
1286
1287    r = set_page(card, unifi_addr, &sdio_addr);
1288    if (r != CSR_RESULT_SUCCESS)
1289    {
1290        return r;
1291    }
1292
1293    r = unifi_read_directn_match(card, sdio_addr, pdata, len, match, &num);
1294    return r;
1295} /* unifi_readn_match() */
1296
1297
1298CsrResult unifi_card_readn(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1299{
1300    return unifi_readn_match(card, unifi_addr, pdata, len, -1);
1301} /* unifi_card_readn() */
1302
1303
1304CsrResult unifi_readnz(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1305{
1306    return unifi_readn_match(card, unifi_addr, pdata, len, 0);
1307} /* unifi_readnz() */
1308
1309
1310/*
1311 * ---------------------------------------------------------------------------
1312 *  unifi_read_shared_count
1313 *
1314 *      Read signal count locations, checking for an SDIO error.  The
1315 *      signal count locations only contain a valid number if the
1316 *      highest bit isn't set.
1317 *
1318 *  Arguments:
1319 *      card            Pointer to card context structure.
1320 *      addr            Shared-memory address to read.
1321 *
1322 *  Returns:
1323 *      Value read from memory (0-127) or -1 on error
1324 * ---------------------------------------------------------------------------
1325 */
1326s32 unifi_read_shared_count(card_t *card, u32 addr)
1327{
1328    u8 b;
1329    /* I've increased this count, because I have seen cases where
1330     * there were three reads in a row with the top bit set.  I'm not
1331     * sure why this might have happened, but I can't see a problem
1332     * with increasing this limit.  It's better to take a while to
1333     * recover than to fail. */
1334#define SHARED_READ_RETRY_LIMIT 10
1335    s32 i;
1336
1337    /*
1338     * Get the to-host-signals-written count.
1339     * The top-bit will be set if the firmware was in the process of
1340     * changing the value, in which case we read again.
1341     */
1342    /* Limit the number of repeats so we don't freeze */
1343    for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
1344    {
1345        CsrResult r;
1346        r = unifi_read_8_or_16(card, addr, &b);
1347        if (r != CSR_RESULT_SUCCESS)
1348        {
1349            return -1;
1350        }
1351        if (!(b & 0x80))
1352        {
1353            /* There is a chance that the MSB may have contained invalid data
1354             * (overflow) at the time it was read. Therefore mask off the MSB.
1355             * This avoids a race between driver read and firmware write of the
1356             * word, the value we need is in the lower 8 bits anway.
1357             */
1358            return (s32)(b & 0xff);
1359        }
1360    }
1361
1362    return -1;                  /* this function has changed in WMM mods */
1363} /* unifi_read_shared_count() */
1364
1365
1366/*
1367 * ---------------------------------------------------------------------------
1368 *  unifi_writen
1369 *
1370 *      Write multiple 8-bit values to the UniFi SDIO interface using CMD52
1371 *      This function interprets the address as a GenericPointer as
1372 *      defined in the UniFi Host Interface Protocol Specification.
1373 *
1374 *  Arguments:
1375 *      card            Pointer to card structure.
1376 *      unifi_addr      UniFi shared-data-memory address to access.
1377 *      pdata           Pointer to which to write data.
1378 *      len             Number of bytes to write
1379 *
1380 *  Returns:
1381 *      0 on success, non-zero error code on error:
1382 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1383 *      CSR_RESULT_FAILURE     an SDIO error occurred
1384 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE    an odd length or length too big.
1385 * ---------------------------------------------------------------------------
1386 */
1387CsrResult unifi_writen(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1388{
1389    u32 sdio_addr;
1390    CsrResult r;
1391
1392    r = set_page(card, unifi_addr, &sdio_addr);
1393    if (r != CSR_RESULT_SUCCESS)
1394    {
1395        return r;
1396    }
1397
1398    return unifi_write_directn(card, sdio_addr, pdata, len);
1399} /* unifi_writen() */
1400
1401
1402static CsrResult csr_sdio_block_rw(card_t *card, s16 funcnum,
1403                                   u32 addr, u8 *pdata,
1404                                   u16 count, s16 dir_is_write)
1405{
1406    CsrResult csrResult;
1407
1408    if (dir_is_write == UNIFI_SDIO_READ)
1409    {
1410#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1411        unifi_debug_log_to_buf("r@%02X#%X=", addr, count);
1412#endif
1413#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1414        unifi_debug_log_to_buf("R");
1415#endif
1416        csrResult = CsrSdioRead(card->sdio_if, addr, pdata, count);
1417#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1418        unifi_debug_log_to_buf("<");
1419#endif
1420    }
1421    else
1422    {
1423#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1424        unifi_debug_log_to_buf("w@%02X#%X=", addr, count);
1425        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
1426#endif
1427#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1428        unifi_debug_log_to_buf("W");
1429#endif
1430        csrResult = CsrSdioWrite(card->sdio_if, addr, pdata, count);
1431#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1432        unifi_debug_log_to_buf(">");
1433#endif
1434    }
1435#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
1436    card->cmd_prof.cmd53_count++;
1437#endif
1438#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1439    if (csrResult != CSR_RESULT_SUCCESS)
1440    {
1441        unifi_debug_log_to_buf("error=%X", csrResult);
1442    }
1443    else if (dir_is_write == UNIFI_SDIO_READ)
1444    {
1445        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
1446    }
1447    unifi_debug_string_to_buf("\n");
1448#endif
1449    return csrResult;  /* CSR SDIO (not HIP) error code */
1450}
1451
1452
1453/*
1454 * ---------------------------------------------------------------------------
1455 *  unifi_bulk_rw
1456 *
1457 *      Transfer bulk data to or from the UniFi SDIO interface.
1458 *      This function is used to read or write signals and bulk data.
1459 *
1460 *  Arguments:
1461 *      card            Pointer to card structure.
1462 *      handle          Value to put in the Register Address field of the CMD53 req.
1463 *      data            Pointer to data to write.
1464 *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
1465 *
1466 *  Returns:
1467 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
1468 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1469 *      CSR_RESULT_FAILURE     an SDIO error occurred
1470 *
1471 *  Notes:
1472 *      This function uses SDIO CMD53, which is the block transfer mode.
1473 * ---------------------------------------------------------------------------
1474 */
1475CsrResult unifi_bulk_rw(card_t *card, u32 handle, void *pdata,
1476                        u32 len, s16 direction)
1477{
1478#define CMD53_RETRIES 3
1479    /*
1480     * Ideally instead of sleeping, we want to busy wait.
1481     * Currently there is no framework API to do this. When it becomes available,
1482     * we can use it to busy wait using usecs
1483     */
1484#define REWIND_RETRIES          15    /* when REWIND_DELAY==1msec, or 250 when REWIND_DELAY==50usecs */
1485#define REWIND_POLLING_RETRIES  5
1486#define REWIND_DELAY            1     /* msec or 50usecs */
1487    CsrResult csrResult;              /* SDIO error code */
1488    CsrResult r = CSR_RESULT_SUCCESS; /* HIP error code */
1489    s16 retries = CMD53_RETRIES;
1490    s16 stat_retries;
1491    u8 stat;
1492    s16 dump_read;
1493#ifdef UNIFI_DEBUG
1494    u8 *pdata_lsb = ((u8 *)&pdata) + card->lsb;
1495#endif
1496#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1497    static s16 fake_error;
1498#endif
1499
1500    dump_read = 0;
1501#ifdef UNIFI_DEBUG
1502    if (*pdata_lsb & 1)
1503    {
1504        unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
1505                     pdata, (direction == UNIFI_SDIO_READ)?"To" : "From");
1506        if (direction == UNIFI_SDIO_WRITE)
1507        {
1508            dump(pdata, (u16)len);
1509        }
1510        else
1511        {
1512            dump_read = 1;
1513        }
1514    }
1515#endif
1516
1517    /* Defensive checks */
1518    if (!pdata)
1519    {
1520        unifi_error(card->ospriv, "Null pdata for unifi_bulk_rw() len: %d\n", len);
1521        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1522    }
1523    if ((len & 1) || (len > 0xffff))
1524    {
1525        unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len);
1526        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1527    }
1528
1529    while (1)
1530    {
1531        csrResult = csr_sdio_block_rw(card, card->function, handle,
1532                                      (u8 *)pdata, (u16)len,
1533                                      direction);
1534        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
1535        {
1536            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
1537        }
1538#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1539        if (++fake_error > 100)
1540        {
1541            fake_error = 90;
1542            unifi_warning(card->ospriv, "Faking a CMD53 error,\n");
1543            if (csrResult == CSR_RESULT_SUCCESS)
1544            {
1545                csrResult = CSR_RESULT_FAILURE;
1546            }
1547        }
1548#endif
1549        if (csrResult == CSR_RESULT_SUCCESS)
1550        {
1551            if (dump_read)
1552            {
1553                dump(pdata, (u16)len);
1554            }
1555            break;
1556        }
1557
1558        /*
1559         * At this point the SDIO driver should have written the I/O Abort
1560         * register to notify UniFi that the command has failed.
1561         * UniFi-1 and UniFi-2 (not UF6xxx) use the same register to store the
1562         * Deep Sleep State. This means we have to restore the Deep Sleep
1563         * State (AWAKE in any case since we can not perform a CD53 in any other
1564         * state) by rewriting the I/O Abort register to its previous value.
1565         */
1566        if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
1567        {
1568            (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
1569        }
1570
1571        /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
1572         * then stop retrying
1573         */
1574        if (!retryable_sdio_error(csrResult))
1575        {
1576            unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n");
1577            break;
1578        }
1579
1580        /*
1581         * These happen from time to time, try again
1582         */
1583        if (--retries == 0)
1584        {
1585            break;
1586        }
1587
1588        unifi_trace(card->ospriv, UDBG4,
1589                    "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
1590                    (s16)handle & 0xff, len);
1591
1592        /* The transfer failed, rewind and try again */
1593        r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 8,
1594                                (u8)(handle & 0xff));
1595        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1596        {
1597            return r;
1598        }
1599        if (r != CSR_RESULT_SUCCESS)
1600        {
1601            /*
1602             * If we can't even do CMD52 (register read/write) then
1603             * stop here.
1604             */
1605            unifi_error(card->ospriv, "Failed to write REWIND cmd\n");
1606            return r;
1607        }
1608
1609        /* Signal the UniFi to look for the rewind request. */
1610        r = CardGenInt(card);
1611        if (r != CSR_RESULT_SUCCESS)
1612        {
1613            return r;
1614        }
1615
1616        /* Wait for UniFi to acknowledge the rewind */
1617        stat_retries = REWIND_RETRIES;
1618        while (1)
1619        {
1620            r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 8, &stat);
1621            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1622            {
1623                return r;
1624            }
1625            if (r != CSR_RESULT_SUCCESS)
1626            {
1627                unifi_error(card->ospriv, "Failed to read REWIND status\n");
1628                return CSR_RESULT_FAILURE;
1629            }
1630
1631            if (stat == 0)
1632            {
1633                break;
1634            }
1635            if (--stat_retries == 0)
1636            {
1637                unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n");
1638                return CSR_RESULT_FAILURE;
1639            }
1640
1641            /* Poll for the ack a few times */
1642            if (stat_retries < REWIND_RETRIES - REWIND_POLLING_RETRIES)
1643            {
1644                CsrThreadSleep(REWIND_DELAY);
1645            }
1646        }
1647    }
1648
1649    /* The call to csr_sdio_block_rw() still failed after retrying */
1650    if (csrResult != CSR_RESULT_SUCCESS)
1651    {
1652        unifi_error(card->ospriv, "Block %s failed after %d retries\n",
1653                    (direction == UNIFI_SDIO_READ)?"read" : "write",
1654                    CMD53_RETRIES - retries);
1655        /* Report any SDIO error as a general i/o error */
1656        return CSR_RESULT_FAILURE;
1657    }
1658
1659    /* Collect some stats */
1660    if (direction == UNIFI_SDIO_READ)
1661    {
1662        card->sdio_bytes_read += len;
1663    }
1664    else
1665    {
1666        card->sdio_bytes_written += len;
1667    }
1668
1669    return CSR_RESULT_SUCCESS;
1670} /* unifi_bulk_rw() */
1671
1672
1673/*
1674 * ---------------------------------------------------------------------------
1675 *  unifi_bulk_rw_noretry
1676 *
1677 *      Transfer bulk data to or from the UniFi SDIO interface.
1678 *      This function is used to read or write signals and bulk data.
1679 *
1680 *  Arguments:
1681 *      card            Pointer to card structure.
1682 *      handle          Value to put in the Register Address field of
1683 *                      the CMD53 req.
1684 *      data            Pointer to data to write.
1685 *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
1686 *
1687 *  Returns:
1688 *      0 on success, non-zero error code on error:
1689 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
1690 *      CSR_RESULT_FAILURE     an SDIO error occurred
1691 *
1692 *  Notes:
1693 *      This function uses SDIO CMD53, which is the block transfer mode.
1694 * ---------------------------------------------------------------------------
1695 */
1696CsrResult unifi_bulk_rw_noretry(card_t *card, u32 handle, void *pdata,
1697                                u32 len, s16 direction)
1698{
1699    CsrResult csrResult;
1700
1701    csrResult = csr_sdio_block_rw(card, card->function, handle,
1702                                  (u8 *)pdata, (u16)len, direction);
1703    if (csrResult != CSR_RESULT_SUCCESS)
1704    {
1705        unifi_error(card->ospriv, "Block %s failed\n",
1706                    (direction == UNIFI_SDIO_READ)?"read" : "write");
1707        return csrResult;
1708    }
1709
1710    return CSR_RESULT_SUCCESS;
1711} /* unifi_bulk_rw_noretry() */
1712
1713
1714