diff mbox series

[1/8] brcmfmac: reset two D11 cores if chip has two D11 cores

Message ID 20191209223822.27236-1-smoch@web.de (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series [1/8] brcmfmac: reset two D11 cores if chip has two D11 cores | expand

Commit Message

Soeren Moch Dec. 9, 2019, 10:38 p.m. UTC
From: Wright Feng <wright.feng@cypress.com>

There are two D11 cores in RSDB chips like 4359. We have to reset two
D11 cores simutaneously before firmware download, or the firmware may
not be initialized correctly and cause "fw initialized failed" error.

Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: Arend van Spriel <arend.vanspriel@broadcom.com>
Cc: Franky Lin <franky.lin@broadcom.com>
Cc: Hante Meuleman <hante.meuleman@broadcom.com>
Cc: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Cc: Wright Feng <wright.feng@cypress.com>
Cc: linux-wireless@vger.kernel.org
Cc: brcm80211-dev-list.pdl@broadcom.com
Cc: brcm80211-dev-list@cypress.com
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 .../broadcom/brcm80211/brcmfmac/chip.c        | 50 +++++++++++++++++++
 .../broadcom/brcm80211/brcmfmac/chip.h        |  1 +
 .../broadcom/brcm80211/brcmfmac/pcie.c        |  2 +-
 3 files changed, 52 insertions(+), 1 deletion(-)

--
2.17.1

Comments

Chi-Hsien Lin Dec. 10, 2019, 3:36 a.m. UTC | #1
On 12/10/2019 6:38, Soeren Moch wrote:
> From: Wright Feng <wright.feng@cypress.com>
> 
> There are two D11 cores in RSDB chips like 4359. We have to reset two
> D11 cores simutaneously before firmware download, or the firmware may
> not be initialized correctly and cause "fw initialized failed" error.
> 
> Signed-off-by: Wright Feng <wright.feng@cypress.com>
Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>

> ---
> Cc: Kalle Valo <kvalo@codeaurora.org>
> Cc: Arend van Spriel <arend.vanspriel@broadcom.com>
> Cc: Franky Lin <franky.lin@broadcom.com>
> Cc: Hante Meuleman <hante.meuleman@broadcom.com>
> Cc: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
> Cc: Wright Feng <wright.feng@cypress.com>
> Cc: linux-wireless@vger.kernel.org
> Cc: brcm80211-dev-list.pdl@broadcom.com
> Cc: brcm80211-dev-list@cypress.com
> Cc: netdev@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
>   .../broadcom/brcm80211/brcmfmac/chip.c        | 50 +++++++++++++++++++
>   .../broadcom/brcm80211/brcmfmac/chip.h        |  1 +
>   .../broadcom/brcm80211/brcmfmac/pcie.c        |  2 +-
>   3 files changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
> index a795d781b4c5..0b5fbe5d8270 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
> @@ -433,11 +433,25 @@ static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
>   {
>   	struct brcmf_chip_priv *ci;
>   	int count;
> +	struct brcmf_core *d11core2 = NULL;
> +	struct brcmf_core_priv *d11priv2 = NULL;
> 
>   	ci = core->chip;
> 
> +	/* special handle two D11 cores reset */
> +	if (core->pub.id == BCMA_CORE_80211) {
> +		d11core2 = brcmf_chip_get_d11core(&ci->pub, 1);
> +		if (d11core2) {
> +			brcmf_dbg(INFO, "found two d11 cores, reset both\n");
> +			d11priv2 = container_of(d11core2,
> +						struct brcmf_core_priv, pub);
> +		}
> +	}
> +
>   	/* must disable first to work for arbitrary current core state */
>   	brcmf_chip_ai_coredisable(core, prereset, reset);
> +	if (d11priv2)
> +		brcmf_chip_ai_coredisable(d11priv2, prereset, reset);
> 
>   	count = 0;
>   	while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
> @@ -449,9 +463,30 @@ static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
>   		usleep_range(40, 60);
>   	}
> 
> +	if (d11priv2) {
> +		count = 0;
> +		while (ci->ops->read32(ci->ctx,
> +				       d11priv2->wrapbase + BCMA_RESET_CTL) &
> +				       BCMA_RESET_CTL_RESET) {
> +			ci->ops->write32(ci->ctx,
> +					 d11priv2->wrapbase + BCMA_RESET_CTL,
> +					 0);
> +			count++;
> +			if (count > 50)
> +				break;
> +			usleep_range(40, 60);
> +		}
> +	}
> +
>   	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
>   			 postreset | BCMA_IOCTL_CLK);
>   	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
> +
> +	if (d11priv2) {
> +		ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL,
> +				 postreset | BCMA_IOCTL_CLK);
> +		ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL);
> +	}
>   }
> 
>   char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len)
> @@ -1109,6 +1144,21 @@ void brcmf_chip_detach(struct brcmf_chip *pub)
>   	kfree(chip);
>   }
> 
> +struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)
> +{
> +	struct brcmf_chip_priv *chip;
> +	struct brcmf_core_priv *core;
> +
> +	chip = container_of(pub, struct brcmf_chip_priv, pub);
> +	list_for_each_entry(core, &chip->cores, list) {
> +		if (core->pub.id == BCMA_CORE_80211) {
> +			if (unit-- == 0)
> +				return &core->pub;
> +		}
> +	}
> +	return NULL;
> +}
> +
>   struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
>   {
>   	struct brcmf_chip_priv *chip;
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
> index 7b00f6a59e89..8fa38658e727 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
> @@ -74,6 +74,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx,
>   				     const struct brcmf_buscore_ops *ops);
>   void brcmf_chip_detach(struct brcmf_chip *chip);
>   struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
> +struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
>   struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
>   struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
>   bool brcmf_chip_iscoreup(struct brcmf_core *core);
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> index f64ce5074a55..7ac72804e285 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> @@ -78,7 +78,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
>   	BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
>   };
> 
> -#define BRCMF_PCIE_FW_UP_TIMEOUT		2000 /* msec */
> +#define BRCMF_PCIE_FW_UP_TIMEOUT		5000 /* msec */
> 
>   #define BRCMF_PCIE_REG_MAP_SIZE			(32 * 1024)
> 
> --
> 2.17.1
> 
> .
>
Kalle Valo Dec. 10, 2019, 9:08 a.m. UTC | #2
Soeren Moch <smoch@web.de> writes:

> From: Wright Feng <wright.feng@cypress.com>
>
> There are two D11 cores in RSDB chips like 4359. We have to reset two
> D11 cores simutaneously before firmware download, or the firmware may
> not be initialized correctly and cause "fw initialized failed" error.
>
> Signed-off-by: Wright Feng <wright.feng@cypress.com>

Soeren's s-o-b missing at least in patches 1, 6 and 7. Please read:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing
Soeren Moch Dec. 10, 2019, 10:14 a.m. UTC | #3
On 10.12.19 10:08, Kalle Valo wrote:
> Soeren Moch <smoch@web.de> writes:
>
>> From: Wright Feng <wright.feng@cypress.com>
>>
>> There are two D11 cores in RSDB chips like 4359. We have to reset two
>> D11 cores simutaneously before firmware download, or the firmware may
>> not be initialized correctly and cause "fw initialized failed" error.
>>
>> Signed-off-by: Wright Feng <wright.feng@cypress.com>
> Soeren's s-o-b missing at least in patches 1, 6 and 7. Please read:
>
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing
>
OK, also for unmodified patches another s-o-b is required. I will add
them when sending a v2 of this series.

Thanks,
Soeren
Kalle Valo Dec. 10, 2019, 10:20 a.m. UTC | #4
Soeren Moch <smoch@web.de> writes:

> On 10.12.19 10:08, Kalle Valo wrote:
>> Soeren Moch <smoch@web.de> writes:
>>
>>> From: Wright Feng <wright.feng@cypress.com>
>>>
>>> There are two D11 cores in RSDB chips like 4359. We have to reset two
>>> D11 cores simutaneously before firmware download, or the firmware may
>>> not be initialized correctly and cause "fw initialized failed" error.
>>>
>>> Signed-off-by: Wright Feng <wright.feng@cypress.com>
>> Soeren's s-o-b missing at least in patches 1, 6 and 7. Please read:
>>
>> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing
>>
>
> OK, also for unmodified patches another s-o-b is required.

Yes, every patch you submit needs to have your s-o-b to mark that you
agree with Developer's Certificate of Origin.

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin
diff mbox series

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index a795d781b4c5..0b5fbe5d8270 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -433,11 +433,25 @@  static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
 {
 	struct brcmf_chip_priv *ci;
 	int count;
+	struct brcmf_core *d11core2 = NULL;
+	struct brcmf_core_priv *d11priv2 = NULL;

 	ci = core->chip;

+	/* special handle two D11 cores reset */
+	if (core->pub.id == BCMA_CORE_80211) {
+		d11core2 = brcmf_chip_get_d11core(&ci->pub, 1);
+		if (d11core2) {
+			brcmf_dbg(INFO, "found two d11 cores, reset both\n");
+			d11priv2 = container_of(d11core2,
+						struct brcmf_core_priv, pub);
+		}
+	}
+
 	/* must disable first to work for arbitrary current core state */
 	brcmf_chip_ai_coredisable(core, prereset, reset);
+	if (d11priv2)
+		brcmf_chip_ai_coredisable(d11priv2, prereset, reset);

 	count = 0;
 	while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
@@ -449,9 +463,30 @@  static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
 		usleep_range(40, 60);
 	}

+	if (d11priv2) {
+		count = 0;
+		while (ci->ops->read32(ci->ctx,
+				       d11priv2->wrapbase + BCMA_RESET_CTL) &
+				       BCMA_RESET_CTL_RESET) {
+			ci->ops->write32(ci->ctx,
+					 d11priv2->wrapbase + BCMA_RESET_CTL,
+					 0);
+			count++;
+			if (count > 50)
+				break;
+			usleep_range(40, 60);
+		}
+	}
+
 	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
 			 postreset | BCMA_IOCTL_CLK);
 	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
+
+	if (d11priv2) {
+		ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL,
+				 postreset | BCMA_IOCTL_CLK);
+		ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL);
+	}
 }

 char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len)
@@ -1109,6 +1144,21 @@  void brcmf_chip_detach(struct brcmf_chip *pub)
 	kfree(chip);
 }

+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)
+{
+	struct brcmf_chip_priv *chip;
+	struct brcmf_core_priv *core;
+
+	chip = container_of(pub, struct brcmf_chip_priv, pub);
+	list_for_each_entry(core, &chip->cores, list) {
+		if (core->pub.id == BCMA_CORE_80211) {
+			if (unit-- == 0)
+				return &core->pub;
+		}
+	}
+	return NULL;
+}
+
 struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
 {
 	struct brcmf_chip_priv *chip;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
index 7b00f6a59e89..8fa38658e727 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
@@ -74,6 +74,7 @@  struct brcmf_chip *brcmf_chip_attach(void *ctx,
 				     const struct brcmf_buscore_ops *ops);
 void brcmf_chip_detach(struct brcmf_chip *chip);
 struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
 struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
 struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
 bool brcmf_chip_iscoreup(struct brcmf_core *core);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index f64ce5074a55..7ac72804e285 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -78,7 +78,7 @@  static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
 	BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
 };

-#define BRCMF_PCIE_FW_UP_TIMEOUT		2000 /* msec */
+#define BRCMF_PCIE_FW_UP_TIMEOUT		5000 /* msec */

 #define BRCMF_PCIE_REG_MAP_SIZE			(32 * 1024)