diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2016-01-26 17:57:01 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2016-02-06 13:52:47 +0200 |
commit | a4f4abd037c1f8c6a834c95a46a2514d4b350888 (patch) | |
tree | 5bcac67d6a817dde42078eeea516dde69ff94524 | |
parent | 515b399c9a204da70d54916d23c1748ff7083fb8 (diff) | |
download | lwn-a4f4abd037c1f8c6a834c95a46a2514d4b350888.tar.gz lwn-a4f4abd037c1f8c6a834c95a46a2514d4b350888.zip |
brcmfmac: analyze descriptors of current component only
So far we were looking for address descriptors without a check for
crossing current component border. In case of dealing with unsupported
descriptor or descriptor missing at all the code would incorrectly get
data from another component.
Consider this binary-described component from BCM4366 EROM:
4bf83b01 TAG==CI CID==0x83b
20080201 TAG==CI PORTS==0+1 WRAPPERS==0+1
18400035 TAG==ADDR SZ_SZD TYPE_SLAVE
00050000
18107085 TAG==ADDR SZ_4K TYPE_SWRAP
Driver was assigning invalid base address to this core:
brcmfmac: [6 ] core 0x83b:32 base 0x18109000 wrap 0x18107000
which came from totally different component defined in EROM:
43b36701 TAG==CI CID==0x367
00000201 TAG==CI PORTS==0+1 WRAPPERS==0+0
18109005 TAG==ADDR SZ_4K TYPE_SLAVE
This change will also allow us to support components without wrapper
address in the future.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c index 82e4382eb177..e434e2a52098 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c @@ -803,7 +803,14 @@ static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr, *eromaddr -= 4; return -EFAULT; } - } while (desc != DMP_DESC_ADDRESS); + } while (desc != DMP_DESC_ADDRESS && + desc != DMP_DESC_COMPONENT); + + /* stop if we crossed current component border */ + if (desc == DMP_DESC_COMPONENT) { + *eromaddr -= 4; + return 0; + } /* skip upper 32-bit address descriptor */ if (val & DMP_DESC_ADDRSIZE_GT32) |