LCOV - code coverage report
Current view: top level - drivers/bcma - sprom.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 237 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 7 0.0 %
Branches: 0 56 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Broadcom specific AMBA
       3                 :            :  * SPROM reading
       4                 :            :  *
       5                 :            :  * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
       6                 :            :  *
       7                 :            :  * Licensed under the GNU/GPL. See COPYING for details.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include "bcma_private.h"
      11                 :            : 
      12                 :            : #include <linux/bcma/bcma.h>
      13                 :            : #include <linux/bcma/bcma_regs.h>
      14                 :            : #include <linux/pci.h>
      15                 :            : #include <linux/io.h>
      16                 :            : #include <linux/dma-mapping.h>
      17                 :            : #include <linux/slab.h>
      18                 :            : 
      19                 :            : static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
      20                 :            : 
      21                 :            : /**
      22                 :            :  * bcma_arch_register_fallback_sprom - Registers a method providing a
      23                 :            :  * fallback SPROM if no SPROM is found.
      24                 :            :  *
      25                 :            :  * @sprom_callback: The callback function.
      26                 :            :  *
      27                 :            :  * With this function the architecture implementation may register a
      28                 :            :  * callback handler which fills the SPROM data structure. The fallback is
      29                 :            :  * used for PCI based BCMA devices, where no valid SPROM can be found
      30                 :            :  * in the shadow registers and to provide the SPROM for SoCs where BCMA is
      31                 :            :  * to controll the system bus.
      32                 :            :  *
      33                 :            :  * This function is useful for weird architectures that have a half-assed
      34                 :            :  * BCMA device hardwired to their PCI bus.
      35                 :            :  *
      36                 :            :  * This function is available for architecture code, only. So it is not
      37                 :            :  * exported.
      38                 :            :  */
      39                 :          0 : int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
      40                 :            :                                      struct ssb_sprom *out))
      41                 :            : {
      42         [ #  # ]:          0 :         if (get_fallback_sprom)
      43                 :            :                 return -EEXIST;
      44                 :          0 :         get_fallback_sprom = sprom_callback;
      45                 :            : 
      46                 :          0 :         return 0;
      47                 :            : }
      48                 :            : 
      49                 :          0 : static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
      50                 :            :                                          struct ssb_sprom *out)
      51                 :            : {
      52                 :          0 :         int err;
      53                 :            : 
      54         [ #  # ]:          0 :         if (!get_fallback_sprom) {
      55                 :          0 :                 err = -ENOENT;
      56                 :          0 :                 goto fail;
      57                 :            :         }
      58                 :            : 
      59                 :          0 :         err = get_fallback_sprom(bus, out);
      60         [ #  # ]:          0 :         if (err)
      61                 :          0 :                 goto fail;
      62                 :            : 
      63                 :            :         bcma_debug(bus, "Using SPROM revision %d provided by platform.\n",
      64                 :            :                    bus->sprom.revision);
      65                 :            :         return 0;
      66                 :          0 : fail:
      67                 :          0 :         bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err);
      68                 :          0 :         return err;
      69                 :            : }
      70                 :            : 
      71                 :            : /**************************************************
      72                 :            :  * R/W ops.
      73                 :            :  **************************************************/
      74                 :            : 
      75                 :            : static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
      76                 :            :                             size_t words)
      77                 :            : {
      78                 :            :         int i;
      79         [ #  # ]:          0 :         for (i = 0; i < words; i++)
      80                 :          0 :                 sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
      81                 :            : }
      82                 :            : 
      83                 :            : /**************************************************
      84                 :            :  * Validation.
      85                 :            :  **************************************************/
      86                 :            : 
      87                 :          0 : static inline u8 bcma_crc8(u8 crc, u8 data)
      88                 :            : {
      89                 :            :         /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
      90                 :          0 :         static const u8 t[] = {
      91                 :            :                 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
      92                 :            :                 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
      93                 :            :                 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
      94                 :            :                 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
      95                 :            :                 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
      96                 :            :                 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
      97                 :            :                 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
      98                 :            :                 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
      99                 :            :                 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
     100                 :            :                 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
     101                 :            :                 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
     102                 :            :                 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
     103                 :            :                 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
     104                 :            :                 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
     105                 :            :                 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
     106                 :            :                 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
     107                 :            :                 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
     108                 :            :                 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
     109                 :            :                 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
     110                 :            :                 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
     111                 :            :                 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
     112                 :            :                 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
     113                 :            :                 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
     114                 :            :                 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
     115                 :            :                 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
     116                 :            :                 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
     117                 :            :                 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
     118                 :            :                 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
     119                 :            :                 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
     120                 :            :                 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
     121                 :            :                 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
     122                 :            :                 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
     123                 :            :         };
     124                 :          0 :         return t[crc ^ data];
     125                 :            : }
     126                 :            : 
     127                 :          0 : static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
     128                 :            : {
     129                 :          0 :         int word;
     130                 :          0 :         u8 crc = 0xFF;
     131                 :            : 
     132         [ #  # ]:          0 :         for (word = 0; word < words - 1; word++) {
     133                 :          0 :                 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
     134                 :          0 :                 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
     135                 :            :         }
     136                 :          0 :         crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
     137                 :          0 :         crc ^= 0xFF;
     138                 :            : 
     139                 :          0 :         return crc;
     140                 :            : }
     141                 :            : 
     142                 :            : static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
     143                 :            : {
     144                 :            :         u8 crc;
     145                 :            :         u8 expected_crc;
     146                 :            :         u16 tmp;
     147                 :            : 
     148                 :            :         crc = bcma_sprom_crc(sprom, words);
     149                 :            :         tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
     150                 :            :         expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
     151                 :            :         if (crc != expected_crc)
     152                 :            :                 return -EPROTO;
     153                 :            : 
     154                 :            :         return 0;
     155                 :            : }
     156                 :            : 
     157                 :            : static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
     158                 :            :                             size_t words)
     159                 :            : {
     160                 :            :         u16 revision;
     161                 :            :         int err;
     162                 :            : 
     163                 :            :         err = bcma_sprom_check_crc(sprom, words);
     164                 :            :         if (err)
     165                 :            :                 return err;
     166                 :            : 
     167                 :            :         revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
     168                 :            :         if (revision != 8 && revision != 9 && revision != 10) {
     169                 :            :                 pr_err("Unsupported SPROM revision: %d\n", revision);
     170                 :            :                 return -ENOENT;
     171                 :            :         }
     172                 :            : 
     173                 :            :         bus->sprom.revision = revision;
     174                 :            :         bcma_debug(bus, "Found SPROM revision %d\n", revision);
     175                 :            : 
     176                 :            :         return 0;
     177                 :            : }
     178                 :            : 
     179                 :            : /**************************************************
     180                 :            :  * SPROM extraction.
     181                 :            :  **************************************************/
     182                 :            : 
     183                 :            : #define SPOFF(offset)   ((offset) / sizeof(u16))
     184                 :            : 
     185                 :            : #define SPEX(_field, _offset, _mask, _shift)    \
     186                 :            :         bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
     187                 :            : 
     188                 :            : #define SPEX32(_field, _offset, _mask, _shift)  \
     189                 :            :         bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
     190                 :            :                                 sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
     191                 :            : 
     192                 :            : #define SPEX_ARRAY8(_field, _offset, _mask, _shift)     \
     193                 :            :         do {    \
     194                 :            :                 SPEX(_field[0], _offset +  0, _mask, _shift);   \
     195                 :            :                 SPEX(_field[1], _offset +  2, _mask, _shift);   \
     196                 :            :                 SPEX(_field[2], _offset +  4, _mask, _shift);   \
     197                 :            :                 SPEX(_field[3], _offset +  6, _mask, _shift);   \
     198                 :            :                 SPEX(_field[4], _offset +  8, _mask, _shift);   \
     199                 :            :                 SPEX(_field[5], _offset + 10, _mask, _shift);   \
     200                 :            :                 SPEX(_field[6], _offset + 12, _mask, _shift);   \
     201                 :            :                 SPEX(_field[7], _offset + 14, _mask, _shift);   \
     202                 :            :         } while (0)
     203                 :            : 
     204                 :          0 : static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
     205                 :            : {
     206                 :          0 :         u16 v;
     207                 :          0 :         u8 gain;
     208                 :            : 
     209                 :          0 :         v = in[SPOFF(offset)];
     210                 :          0 :         gain = (v & mask) >> shift;
     211                 :          0 :         if (gain == 0xFF) {
     212                 :            :                 gain = 8; /* If unset use 2dBm */
     213                 :            :         } else {
     214                 :            :                 /* Q5.2 Fractional part is stored in 0xC0 */
     215                 :          0 :                 gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
     216                 :            :         }
     217                 :            : 
     218                 :          0 :         return (s8)gain;
     219                 :            : }
     220                 :            : 
     221                 :          0 : static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
     222                 :            : {
     223                 :          0 :         u16 v, o;
     224                 :          0 :         int i;
     225                 :          0 :         static const u16 pwr_info_offset[] = {
     226                 :            :                 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
     227                 :            :                 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
     228                 :            :         };
     229                 :          0 :         BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
     230                 :            :                         ARRAY_SIZE(bus->sprom.core_pwr_info));
     231                 :            : 
     232         [ #  # ]:          0 :         for (i = 0; i < 3; i++) {
     233                 :          0 :                 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
     234                 :          0 :                 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
     235                 :            :         }
     236                 :            : 
     237                 :          0 :         SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
     238                 :          0 :         SPEX(board_type, SSB_SPROM1_SPID, ~0, 0);
     239                 :            : 
     240                 :          0 :         SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
     241                 :            :              SSB_SPROM4_TXPID2G0_SHIFT);
     242                 :          0 :         SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
     243                 :            :              SSB_SPROM4_TXPID2G1_SHIFT);
     244                 :          0 :         SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
     245                 :            :              SSB_SPROM4_TXPID2G2_SHIFT);
     246                 :          0 :         SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
     247                 :            :              SSB_SPROM4_TXPID2G3_SHIFT);
     248                 :            : 
     249                 :          0 :         SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
     250                 :            :              SSB_SPROM4_TXPID5GL0_SHIFT);
     251                 :          0 :         SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
     252                 :            :              SSB_SPROM4_TXPID5GL1_SHIFT);
     253                 :          0 :         SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
     254                 :            :              SSB_SPROM4_TXPID5GL2_SHIFT);
     255                 :          0 :         SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
     256                 :            :              SSB_SPROM4_TXPID5GL3_SHIFT);
     257                 :            : 
     258                 :          0 :         SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
     259                 :            :              SSB_SPROM4_TXPID5G0_SHIFT);
     260                 :          0 :         SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
     261                 :            :              SSB_SPROM4_TXPID5G1_SHIFT);
     262                 :          0 :         SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
     263                 :            :              SSB_SPROM4_TXPID5G2_SHIFT);
     264                 :          0 :         SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
     265                 :            :              SSB_SPROM4_TXPID5G3_SHIFT);
     266                 :            : 
     267                 :          0 :         SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
     268                 :            :              SSB_SPROM4_TXPID5GH0_SHIFT);
     269                 :          0 :         SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
     270                 :            :              SSB_SPROM4_TXPID5GH1_SHIFT);
     271                 :          0 :         SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
     272                 :            :              SSB_SPROM4_TXPID5GH2_SHIFT);
     273                 :          0 :         SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
     274                 :            :              SSB_SPROM4_TXPID5GH3_SHIFT);
     275                 :            : 
     276                 :          0 :         SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
     277                 :          0 :         SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
     278                 :          0 :         SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
     279                 :          0 :         SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
     280                 :            : 
     281                 :          0 :         SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
     282                 :          0 :         SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
     283                 :            : 
     284                 :            :         /* Extract cores power info info */
     285         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
     286                 :          0 :                 o = pwr_info_offset[i];
     287                 :          0 :                 SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
     288                 :            :                         SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
     289                 :          0 :                 SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
     290                 :            :                         SSB_SPROM8_2G_MAXP, 0);
     291                 :            : 
     292                 :          0 :                 SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
     293                 :          0 :                 SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
     294                 :          0 :                 SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
     295                 :            : 
     296                 :          0 :                 SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
     297                 :            :                         SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
     298                 :          0 :                 SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
     299                 :            :                         SSB_SPROM8_5G_MAXP, 0);
     300                 :          0 :                 SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
     301                 :            :                         SSB_SPROM8_5GH_MAXP, 0);
     302                 :          0 :                 SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
     303                 :            :                         SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
     304                 :            : 
     305                 :          0 :                 SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
     306                 :          0 :                 SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
     307                 :          0 :                 SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
     308                 :          0 :                 SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
     309                 :          0 :                 SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
     310                 :          0 :                 SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
     311                 :          0 :                 SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
     312                 :          0 :                 SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
     313                 :          0 :                 SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
     314                 :            :         }
     315                 :            : 
     316                 :          0 :         SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
     317                 :            :              SSB_SROM8_FEM_TSSIPOS_SHIFT);
     318                 :          0 :         SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
     319                 :            :              SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
     320                 :          0 :         SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
     321                 :            :              SSB_SROM8_FEM_PDET_RANGE_SHIFT);
     322                 :          0 :         SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
     323                 :            :              SSB_SROM8_FEM_TR_ISO_SHIFT);
     324                 :          0 :         SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
     325                 :            :              SSB_SROM8_FEM_ANTSWLUT_SHIFT);
     326                 :            : 
     327                 :          0 :         SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
     328                 :            :              SSB_SROM8_FEM_TSSIPOS_SHIFT);
     329                 :          0 :         SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
     330                 :            :              SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
     331                 :          0 :         SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
     332                 :            :              SSB_SROM8_FEM_PDET_RANGE_SHIFT);
     333                 :          0 :         SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
     334                 :            :              SSB_SROM8_FEM_TR_ISO_SHIFT);
     335                 :          0 :         SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
     336                 :            :              SSB_SROM8_FEM_ANTSWLUT_SHIFT);
     337                 :            : 
     338                 :          0 :         SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
     339                 :            :              SSB_SPROM8_ANTAVAIL_A_SHIFT);
     340                 :          0 :         SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
     341                 :            :              SSB_SPROM8_ANTAVAIL_BG_SHIFT);
     342                 :          0 :         SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
     343                 :          0 :         SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
     344                 :            :              SSB_SPROM8_ITSSI_BG_SHIFT);
     345                 :          0 :         SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
     346                 :          0 :         SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
     347                 :            :              SSB_SPROM8_ITSSI_A_SHIFT);
     348                 :          0 :         SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
     349                 :          0 :         SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
     350                 :            :              SSB_SPROM8_MAXP_AL_SHIFT);
     351                 :          0 :         SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
     352                 :          0 :         SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
     353                 :            :              SSB_SPROM8_GPIOA_P1_SHIFT);
     354                 :          0 :         SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
     355                 :          0 :         SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
     356                 :            :              SSB_SPROM8_GPIOB_P3_SHIFT);
     357                 :          0 :         SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
     358                 :          0 :         SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
     359                 :            :              SSB_SPROM8_TRI5G_SHIFT);
     360                 :          0 :         SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
     361                 :          0 :         SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
     362                 :            :              SSB_SPROM8_TRI5GH_SHIFT);
     363                 :          0 :         SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
     364                 :            :              SSB_SPROM8_RXPO2G_SHIFT);
     365                 :          0 :         SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
     366                 :            :              SSB_SPROM8_RXPO5G_SHIFT);
     367                 :          0 :         SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
     368                 :          0 :         SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
     369                 :            :              SSB_SPROM8_RSSISMC2G_SHIFT);
     370                 :          0 :         SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
     371                 :            :              SSB_SPROM8_RSSISAV2G_SHIFT);
     372                 :          0 :         SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
     373                 :            :              SSB_SPROM8_BXA2G_SHIFT);
     374                 :          0 :         SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
     375                 :          0 :         SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
     376                 :            :              SSB_SPROM8_RSSISMC5G_SHIFT);
     377                 :          0 :         SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
     378                 :            :              SSB_SPROM8_RSSISAV5G_SHIFT);
     379                 :          0 :         SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
     380                 :            :              SSB_SPROM8_BXA5G_SHIFT);
     381                 :            : 
     382                 :          0 :         SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
     383                 :          0 :         SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
     384                 :          0 :         SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
     385                 :          0 :         SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
     386                 :          0 :         SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
     387                 :          0 :         SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
     388                 :          0 :         SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
     389                 :          0 :         SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
     390                 :          0 :         SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
     391                 :          0 :         SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
     392                 :          0 :         SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
     393                 :          0 :         SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
     394                 :          0 :         SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
     395                 :          0 :         SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
     396                 :          0 :         SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
     397                 :          0 :         SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
     398                 :          0 :         SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
     399                 :            : 
     400                 :            :         /* Extract the antenna gain values. */
     401         [ #  # ]:          0 :         bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
     402                 :            :                                                            SSB_SPROM8_AGAIN01,
     403                 :            :                                                            SSB_SPROM8_AGAIN0,
     404                 :            :                                                            SSB_SPROM8_AGAIN0_SHIFT);
     405         [ #  # ]:          0 :         bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
     406                 :            :                                                            SSB_SPROM8_AGAIN01,
     407                 :            :                                                            SSB_SPROM8_AGAIN1,
     408                 :            :                                                            SSB_SPROM8_AGAIN1_SHIFT);
     409         [ #  # ]:          0 :         bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
     410                 :            :                                                            SSB_SPROM8_AGAIN23,
     411                 :            :                                                            SSB_SPROM8_AGAIN2,
     412                 :            :                                                            SSB_SPROM8_AGAIN2_SHIFT);
     413         [ #  # ]:          0 :         bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
     414                 :            :                                                            SSB_SPROM8_AGAIN23,
     415                 :            :                                                            SSB_SPROM8_AGAIN3,
     416                 :            :                                                            SSB_SPROM8_AGAIN3_SHIFT);
     417                 :            : 
     418                 :          0 :         SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
     419                 :            :              SSB_SPROM8_LEDDC_ON_SHIFT);
     420                 :          0 :         SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
     421                 :            :              SSB_SPROM8_LEDDC_OFF_SHIFT);
     422                 :            : 
     423                 :          0 :         SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
     424                 :            :              SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
     425                 :          0 :         SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
     426                 :            :              SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
     427                 :          0 :         SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
     428                 :            :              SSB_SPROM8_TXRXC_SWITCH_SHIFT);
     429                 :            : 
     430                 :          0 :         SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
     431                 :            : 
     432                 :          0 :         SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
     433                 :          0 :         SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
     434                 :          0 :         SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
     435                 :          0 :         SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
     436                 :            : 
     437                 :          0 :         SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
     438                 :            :              SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
     439                 :          0 :         SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
     440                 :            :              SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
     441                 :          0 :         SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
     442                 :            :              SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
     443                 :            :              SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
     444                 :          0 :         SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
     445                 :            :              SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
     446                 :          0 :         SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
     447                 :            :              SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
     448                 :            :              SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
     449                 :          0 :         SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
     450                 :            :              SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
     451                 :            :              SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
     452                 :          0 :         SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
     453                 :            :              SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
     454                 :            :              SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
     455                 :          0 :         SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
     456                 :            :              SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
     457                 :            : 
     458                 :          0 :         SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
     459                 :          0 :         SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
     460                 :          0 :         SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
     461                 :          0 :         SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
     462                 :            : 
     463                 :          0 :         SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
     464                 :            :              SSB_SPROM8_THERMAL_TRESH_SHIFT);
     465                 :          0 :         SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
     466                 :            :              SSB_SPROM8_THERMAL_OFFSET_SHIFT);
     467                 :          0 :         SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
     468                 :            :              SSB_SPROM8_TEMPDELTA_PHYCAL,
     469                 :            :              SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
     470                 :          0 :         SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
     471                 :            :              SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
     472                 :          0 :         SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
     473                 :            :              SSB_SPROM8_TEMPDELTA_HYSTERESIS,
     474                 :            :              SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
     475                 :          0 : }
     476                 :            : 
     477                 :            : /*
     478                 :            :  * Indicates the presence of external SPROM.
     479                 :            :  */
     480                 :          0 : static bool bcma_sprom_ext_available(struct bcma_bus *bus)
     481                 :            : {
     482                 :          0 :         u32 chip_status;
     483                 :          0 :         u32 srom_control;
     484                 :          0 :         u32 present_mask;
     485                 :            : 
     486         [ #  # ]:          0 :         if (bus->drv_cc.core->id.rev >= 31) {
     487         [ #  # ]:          0 :                 if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
     488                 :            :                         return false;
     489                 :            : 
     490                 :          0 :                 srom_control = bcma_read32(bus->drv_cc.core,
     491                 :            :                                            BCMA_CC_SROM_CONTROL);
     492                 :          0 :                 return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
     493                 :            :         }
     494                 :            : 
     495                 :            :         /* older chipcommon revisions use chip status register */
     496                 :          0 :         chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
     497      [ #  #  # ]:          0 :         switch (bus->chipinfo.id) {
     498                 :            :         case BCMA_CHIP_ID_BCM4313:
     499                 :            :                 present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
     500                 :            :                 break;
     501                 :            : 
     502                 :          0 :         case BCMA_CHIP_ID_BCM4331:
     503                 :          0 :                 present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
     504                 :          0 :                 break;
     505                 :            : 
     506                 :            :         default:
     507                 :            :                 return true;
     508                 :            :         }
     509                 :            : 
     510                 :          0 :         return chip_status & present_mask;
     511                 :            : }
     512                 :            : 
     513                 :            : /*
     514                 :            :  * Indicates that on-chip OTP memory is present and enabled.
     515                 :            :  */
     516                 :          0 : static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
     517                 :            : {
     518                 :          0 :         u32 chip_status;
     519                 :          0 :         u32 otpsize = 0;
     520                 :          0 :         bool present;
     521                 :            : 
     522                 :          0 :         chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
     523   [ #  #  #  #  :          0 :         switch (bus->chipinfo.id) {
                      # ]
     524                 :          0 :         case BCMA_CHIP_ID_BCM4313:
     525                 :          0 :                 present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
     526                 :          0 :                 break;
     527                 :            : 
     528                 :          0 :         case BCMA_CHIP_ID_BCM4331:
     529                 :          0 :                 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
     530                 :          0 :                 break;
     531                 :            :         case BCMA_CHIP_ID_BCM43142:
     532                 :            :         case BCMA_CHIP_ID_BCM43224:
     533                 :            :         case BCMA_CHIP_ID_BCM43225:
     534                 :            :                 /* for these chips OTP is always available */
     535                 :            :                 present = true;
     536                 :            :                 break;
     537                 :          0 :         case BCMA_CHIP_ID_BCM43131:
     538                 :            :         case BCMA_CHIP_ID_BCM43217:
     539                 :            :         case BCMA_CHIP_ID_BCM43227:
     540                 :            :         case BCMA_CHIP_ID_BCM43228:
     541                 :            :         case BCMA_CHIP_ID_BCM43428:
     542                 :          0 :                 present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT;
     543                 :          0 :                 break;
     544                 :            :         default:
     545                 :            :                 present = false;
     546                 :            :                 break;
     547                 :            :         }
     548                 :            : 
     549         [ #  # ]:          0 :         if (present) {
     550                 :          0 :                 otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
     551                 :          0 :                 otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         return otpsize != 0;
     555                 :            : }
     556                 :            : 
     557                 :            : /*
     558                 :            :  * Verify OTP is filled and determine the byte
     559                 :            :  * offset where SPROM data is located.
     560                 :            :  *
     561                 :            :  * On error, returns 0; byte offset otherwise.
     562                 :            :  */
     563                 :            : static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
     564                 :            : {
     565                 :            :         struct bcma_device *cc = bus->drv_cc.core;
     566                 :            :         u32 offset;
     567                 :            : 
     568                 :            :         /* verify OTP status */
     569                 :            :         if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
     570                 :            :                 return 0;
     571                 :            : 
     572                 :            :         /* obtain bit offset from otplayout register */
     573                 :            :         offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
     574                 :            :         return BCMA_CC_SPROM + (offset >> 3);
     575                 :            : }
     576                 :            : 
     577                 :          0 : int bcma_sprom_get(struct bcma_bus *bus)
     578                 :            : {
     579                 :          0 :         u16 offset = BCMA_CC_SPROM;
     580                 :          0 :         u16 *sprom;
     581                 :          0 :         static const size_t sprom_sizes[] = {
     582                 :            :                 SSB_SPROMSIZE_WORDS_R4,
     583                 :            :                 SSB_SPROMSIZE_WORDS_R10,
     584                 :            :                 SSB_SPROMSIZE_WORDS_R11,
     585                 :            :         };
     586                 :          0 :         int i, err = 0;
     587                 :            : 
     588         [ #  # ]:          0 :         if (!bus->drv_cc.core)
     589                 :            :                 return -EOPNOTSUPP;
     590                 :            : 
     591         [ #  # ]:          0 :         if (!bcma_sprom_ext_available(bus)) {
     592                 :          0 :                 bool sprom_onchip;
     593                 :            : 
     594                 :            :                 /*
     595                 :            :                  * External SPROM takes precedence so check
     596                 :            :                  * on-chip OTP only when no external SPROM
     597                 :            :                  * is present.
     598                 :            :                  */
     599                 :          0 :                 sprom_onchip = bcma_sprom_onchip_available(bus);
     600         [ #  # ]:          0 :                 if (sprom_onchip) {
     601                 :            :                         /* determine offset */
     602                 :          0 :                         offset = bcma_sprom_onchip_offset(bus);
     603                 :            :                 }
     604         [ #  # ]:          0 :                 if (!offset || !sprom_onchip) {
     605                 :            :                         /*
     606                 :            :                          * Maybe there is no SPROM on the device?
     607                 :            :                          * Now we ask the arch code if there is some sprom
     608                 :            :                          * available for this device in some other storage.
     609                 :            :                          */
     610                 :          0 :                         err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
     611                 :          0 :                         return err;
     612                 :            :                 }
     613                 :            :         }
     614                 :            : 
     615         [ #  # ]:          0 :         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
     616                 :            :             bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
     617                 :          0 :                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
     618                 :            : 
     619                 :            :         bcma_debug(bus, "SPROM offset 0x%x\n", offset);
     620         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
     621                 :          0 :                 size_t words = sprom_sizes[i];
     622                 :            : 
     623                 :          0 :                 sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
     624         [ #  # ]:          0 :                 if (!sprom)
     625                 :            :                         return -ENOMEM;
     626                 :            : 
     627                 :            :                 bcma_sprom_read(bus, offset, sprom, words);
     628                 :          0 :                 err = bcma_sprom_valid(bus, sprom, words);
     629         [ #  # ]:          0 :                 if (!err)
     630                 :            :                         break;
     631                 :            : 
     632                 :          0 :                 kfree(sprom);
     633                 :            :         }
     634                 :            : 
     635         [ #  # ]:          0 :         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
     636                 :            :             bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
     637                 :          0 :                 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
     638                 :            : 
     639         [ #  # ]:          0 :         if (err) {
     640                 :          0 :                 bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
     641                 :          0 :                 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
     642                 :            :         } else {
     643                 :          0 :                 bcma_sprom_extract_r8(bus, sprom);
     644                 :          0 :                 kfree(sprom);
     645                 :            :         }
     646                 :            : 
     647                 :            :         return err;
     648                 :            : }

Generated by: LCOV version 1.14