Message ID | 20240821184356.163816-1-marex@denx.de |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/2] dt-bindings: wireless: wilc1000: Document WILC3000 compatible string | expand |
Context | Check | Description |
---|---|---|
robh/checkpatch | success | |
robh/patch-applied | success | |
robh/dtbs-check | warning | build log |
robh/dt-meta-schema | success |
On Wed, Aug 21, 2024 at 08:42:32PM +0200, Marek Vasut wrote: > Document compatible string for the WILC3000 chip. The chip is similar > to WILC1000, except that the register layout is slightly different and > it does not support WPA3/SAE. > > Signed-off-by: Marek Vasut <marex@denx.de> > --- > Cc: "David S. Miller" <davem@davemloft.net> > Cc: Adham Abozaeid <adham.abozaeid@microchip.com> > Cc: Ajay Singh <ajay.kathat@microchip.com> > Cc: Alexis Lothoré <alexis.lothore@bootlin.com> > Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev> > Cc: Conor Dooley <conor+dt@kernel.org> > Cc: Eric Dumazet <edumazet@google.com> > Cc: Jakub Kicinski <kuba@kernel.org> > Cc: Kalle Valo <kvalo@kernel.org> > Cc: Krzysztof Kozlowski <krzk+dt@kernel.org> > Cc: Marek Vasut <marex@denx.de> > Cc: Paolo Abeni <pabeni@redhat.com> > Cc: Rob Herring <robh@kernel.org> > Cc: devicetree@vger.kernel.org > Cc: linux-wireless@vger.kernel.org > Cc: netdev@vger.kernel.org > --- > .../devicetree/bindings/net/wireless/microchip,wilc1000.yaml | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml > index 2460ccc082371..1bf3496c21e64 100644 > --- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml > +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml > @@ -16,7 +16,9 @@ description: > > properties: > compatible: > - const: microchip,wilc1000 > + enum: > + - microchip,wilc1000 > + - microchip,wilc3000 Your driver change suggests device type is fully auto-detectable, thus they are compatible. Best regards, Krzysztof
On Wed, Aug 21, 2024 at 08:42:33PM +0200, Marek Vasut wrote: > From: Ajay Singh <ajay.kathat@microchip.com> > > Add support for the WILC3000 chip. The chip is similar to WILC1000, > except that the register layout is slightly different and it does > not support WPA3/SAE. > > Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> > Signed-off-by: Marek Vasut <marex@denx.de> ... > diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c > index 41122199d51eb..7b99fcc450fd3 100644 > --- a/drivers/net/wireless/microchip/wilc1000/sdio.c > +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c > @@ -764,9 +764,13 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume) > * make sure can read back chip id correctly > **/ > if (!resume) { > - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); > - if (ret) { > - dev_err(&func->dev, "Fail cmd read chip id...\n"); > + chipid = wilc_get_chipid(wilc, true); > + if (is_wilc3000(chipid)) { > + wilc->chip = WILC_3000; > + } else if (is_wilc1000(chipid)) { > + wilc->chip = WILC_1000; > + } else { > + dev_err(&func->dev, "Unsupported chipid: %x\n", chipid); > return ret; Hi Marek and Ajay, It seems that with this change ret will be 0 here. Perhaps an negative error code should be returned instead? Flagged by Smatch. > } > dev_err(&func->dev, "chipid (%08x)\n", chipid); ...
Hello Marek, I was coincidentally working on adding wilc3000 support upstream too. My work is also based on downstream tree, so my comments will likely reflect the reworks I was doing or intended to do. For the record, I have some wilc1000 and wilc3000 modules, in both sdio and spi setups. On 8/21/24 20:42, Marek Vasut wrote: > From: Ajay Singh <ajay.kathat@microchip.com> [...] > if (!resume) { > - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); > - if (ret) { > - dev_err(&func->dev, "Fail cmd read chip id...\n"); > + chipid = wilc_get_chipid(wilc, true); > + if (is_wilc3000(chipid)) { > + wilc->chip = WILC_3000; > + } else if (is_wilc1000(chipid)) { > + wilc->chip = WILC_1000; > + } else { > + dev_err(&func->dev, "Unsupported chipid: %x\n", chipid); > return ret; > } I wonder if this additional enum (enum wilc_chip_type) is really useful. We already store the raw chipid, which just needs to be masked to know about the device type. We should likely store one or the other but not both, otherwise we may just risk to create desync without really saving useful info. Also, this change makes wilc1000-sdio failing to build as module (missing symbol export on wilc_get_chipid) [...] > - /* select VMM table 0 */ > - if (val & SEL_VMM_TBL0) > - reg |= BIT(5); > - /* select VMM table 1 */ > - if (val & SEL_VMM_TBL1) > - reg |= BIT(6); > - /* enable VMM */ > - if (val & EN_VMM) > - reg |= BIT(7); > + if (wilc->chip == WILC_1000) { wilc1000 should likely remain the default/fallback ? [...] > @@ -1232,10 +1234,7 @@ static int wilc_validate_chipid(struct wilc *wilc) > dev_err(&spi->dev, "Fail cmd read chip id...\n"); > return ret; > } > - if (!is_wilc1000(chipid)) { > - dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid); > - return -ENODEV; > - } > + Instead of dropping any filtering (and then making the function name become irrelevant), why not ensuring that it is at least either a wilc1000 or a wilc3000 ? > return 0; > } > > diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c > index 533939e71534a..a7cc8c0ea5de4 100644 > --- a/drivers/net/wireless/microchip/wilc1000/wlan.c > +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c > @@ -555,7 +555,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) > return rqe; > } [...] > +static int chip_allow_sleep_wilc3000(struct wilc *wilc) > +{ > + u32 reg = 0; > + int ret; > + const struct wilc_hif_func *hif_func = wilc->hif_func; > + > + if (wilc->io_type == WILC_HIF_SDIO) { > + ret = hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®); > + if (ret) > + return ret; > + ret = hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, > + reg & ~WILC_SDIO_WAKEUP_BIT); > + if (ret) > + return ret; > + } else { > + ret = hif_func->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®); > + if (ret) > + return ret; > + ret = hif_func->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG, > + reg & ~WILC_SPI_WAKEUP_BIT); > + if (ret) > + return ret; > } > + return 0; > +} > + > +void chip_allow_sleep(struct wilc *wilc) > +{ > + if (wilc->chip == WILC_1000) > + chip_allow_sleep_wilc1000(wilc); > + else > + chip_allow_sleep_wilc3000(wilc); > } > EXPORT_SYMBOL_GPL(chip_allow_sleep); > > -void chip_wakeup(struct wilc *wilc) > +static void chip_wakeup_wilc1000(struct wilc *wilc) > { > u32 ret = 0; > u32 clk_status_val = 0, trials = 0; > @@ -627,15 +662,15 @@ void chip_wakeup(struct wilc *wilc) > if (wilc->io_type == WILC_HIF_SDIO) { > wakeup_reg = WILC_SDIO_WAKEUP_REG; > wakeup_bit = WILC_SDIO_WAKEUP_BIT; > - clk_status_reg = WILC_SDIO_CLK_STATUS_REG; > - clk_status_bit = WILC_SDIO_CLK_STATUS_BIT; > + clk_status_reg = WILC1000_SDIO_CLK_STATUS_REG; > + clk_status_bit = WILC1000_SDIO_CLK_STATUS_BIT; > from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG; > from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT; > } else { > wakeup_reg = WILC_SPI_WAKEUP_REG; > wakeup_bit = WILC_SPI_WAKEUP_BIT; > - clk_status_reg = WILC_SPI_CLK_STATUS_REG; > - clk_status_bit = WILC_SPI_CLK_STATUS_BIT; > + clk_status_reg = WILC1000_SPI_CLK_STATUS_REG; > + clk_status_bit = WILC1000_SPI_CLK_STATUS_BIT; > from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG; > from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT; > } > @@ -674,12 +709,80 @@ void chip_wakeup(struct wilc *wilc) > if (wilc->io_type == WILC_HIF_SPI) > wilc->hif_func->hif_reset(wilc); > } > + > +static void chip_wakeup_wilc3000(struct wilc *wilc) > +{ > + u32 wakeup_reg_val, clk_status_reg_val, trials = 0; > + u32 wakeup_reg, wakeup_bit; > + u32 clk_status_reg, clk_status_bit; > + int wake_seq_trials = 5; > + const struct wilc_hif_func *hif_func = wilc->hif_func; > + > + if (wilc->io_type == WILC_HIF_SDIO) { > + wakeup_reg = WILC_SDIO_WAKEUP_REG; > + wakeup_bit = WILC_SDIO_WAKEUP_BIT; > + clk_status_reg = WILC3000_SDIO_CLK_STATUS_REG; > + clk_status_bit = WILC3000_SDIO_CLK_STATUS_BIT; > + } else { > + wakeup_reg = WILC_SPI_WAKEUP_REG; > + wakeup_bit = WILC_SPI_WAKEUP_BIT; > + clk_status_reg = WILC3000_SPI_CLK_STATUS_REG; > + clk_status_bit = WILC3000_SPI_CLK_STATUS_BIT; > + } > + > + hif_func->hif_read_reg(wilc, wakeup_reg, &wakeup_reg_val); > + do { > + hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val | > + wakeup_bit); > + /* Check the clock status */ > + hif_func->hif_read_reg(wilc, clk_status_reg, > + &clk_status_reg_val); > + > + /* In case of clocks off, wait 1ms, and check it again. > + * if still off, wait for another 1ms, for a total wait of 3ms. > + * If still off, redo the wake up sequence > + */ > + while ((clk_status_reg_val & clk_status_bit) == 0 && > + (++trials % 4) != 0) { > + /* Wait for the chip to stabilize*/ > + usleep_range(1000, 1100); > + > + /* Make sure chip is awake. This is an extra step that > + * can be removed later to avoid the bus access > + * overhead > + */ > + hif_func->hif_read_reg(wilc, clk_status_reg, > + &clk_status_reg_val); > + } > + /* in case of failure, Reset the wakeup bit to introduce a new > + * edge on the next loop > + */ > + if ((clk_status_reg_val & clk_status_bit) == 0) { > + hif_func->hif_write_reg(wilc, wakeup_reg, > + wakeup_reg_val & (~wakeup_bit)); > + /* added wait before wakeup sequence retry */ > + usleep_range(200, 300); > + } > + } while ((clk_status_reg_val & clk_status_bit) == 0 && wake_seq_trials-- > 0); > + if (!wake_seq_trials) > + dev_err(wilc->dev, "clocks still OFF. Wake up failed\n"); > +} > + > +void chip_wakeup(struct wilc *wilc) > +{ > + if (wilc->chip == WILC_1000) > + chip_wakeup_wilc1000(wilc); > + else > + chip_wakeup_wilc3000(wilc); > +} > EXPORT_SYMBOL_GPL(chip_wakeup); This new support makes a few places in wlan.c, netdev.c and in bus files (sdio.c, spi.c) install (sometimes big) branches on the device type (chip init, sleep, wakeup, read interrupt, clear interrupt, txq handling, etc), because the registers are different, the masks are different, the number of involved registers may not be the same, wilc3000 may need more operations to perform the same thing... I feel like it will make it harder in the long run to maintain the driver, especially if some new variants are added later. Those branches tend to show that some operations in those files are too specific to the targeted device. I was examining the possibility to start creating device-type specific files (wilc1000.c, wilc3000.c) and move those operations as "device-specific" ops. Then wlan/netdev would call those chip-specific ops, which in turn may call the hif_func ops. It may need some rework in the bus files to fit this new hierarchy, but it may allow to keep netdev and wlan unaware of the device type, and since wilc3000 has bluetooth, it may also make it easier to introduce the corresponding support later. What do you think about it ? Ajay, any opinion on this ? Thanks, Alexis
On 8/22/24 10:07 AM, Krzysztof Kozlowski wrote: Hi, >> diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >> index 2460ccc082371..1bf3496c21e64 100644 >> --- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >> +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >> @@ -16,7 +16,9 @@ description: >> >> properties: >> compatible: >> - const: microchip,wilc1000 >> + enum: >> + - microchip,wilc1000 >> + - microchip,wilc3000 > > Your driver change suggests device type is fully auto-detectable It seems that way, yes. >, thus > they are compatible. I _think_ the hardware is internally somewhat different, the WILC1000 is WiFi-only device and the WILC3000 has some extra Bluetooth part (which is currently not supported). Maybe a fallback compatible string would be better here ?
On 8/22/24 12:26 PM, Simon Horman wrote: > On Wed, Aug 21, 2024 at 08:42:33PM +0200, Marek Vasut wrote: >> From: Ajay Singh <ajay.kathat@microchip.com> >> >> Add support for the WILC3000 chip. The chip is similar to WILC1000, >> except that the register layout is slightly different and it does >> not support WPA3/SAE. >> >> Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> >> Signed-off-by: Marek Vasut <marex@denx.de> > > ... > >> diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c >> index 41122199d51eb..7b99fcc450fd3 100644 >> --- a/drivers/net/wireless/microchip/wilc1000/sdio.c >> +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c >> @@ -764,9 +764,13 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume) >> * make sure can read back chip id correctly >> **/ >> if (!resume) { >> - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); >> - if (ret) { >> - dev_err(&func->dev, "Fail cmd read chip id...\n"); >> + chipid = wilc_get_chipid(wilc, true); >> + if (is_wilc3000(chipid)) { >> + wilc->chip = WILC_3000; >> + } else if (is_wilc1000(chipid)) { >> + wilc->chip = WILC_1000; >> + } else { >> + dev_err(&func->dev, "Unsupported chipid: %x\n", chipid); >> return ret; > > Hi Marek and Ajay, > > It seems that with this change ret will be 0 here. > Perhaps an negative error code should be returned instead? Fixed by returning -EINVAL , thanks .
On 8/22/24 2:10 PM, Alexis Lothoré wrote: > Hello Marek, Hi, > I was coincidentally working on adding wilc3000 support upstream too. I hope you weren't too far along with that and I didn't waste too much of your time/effort here. > My work is > also based on downstream tree, so my comments will likely reflect the reworks I > was doing or intended to do. > For the record, I have some wilc1000 and wilc3000 modules, in both sdio and spi > setups. Nice, I only have this WILC3000 SDIO device . > On 8/21/24 20:42, Marek Vasut wrote: >> From: Ajay Singh <ajay.kathat@microchip.com> > > [...] > >> if (!resume) { >> - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); >> - if (ret) { >> - dev_err(&func->dev, "Fail cmd read chip id...\n"); >> + chipid = wilc_get_chipid(wilc, true); >> + if (is_wilc3000(chipid)) { >> + wilc->chip = WILC_3000; >> + } else if (is_wilc1000(chipid)) { >> + wilc->chip = WILC_1000; >> + } else { >> + dev_err(&func->dev, "Unsupported chipid: %x\n", chipid); >> return ret; >> } > > I wonder if this additional enum (enum wilc_chip_type) is really useful. We > already store the raw chipid, which just needs to be masked to know about the > device type. We should likely store one or the other but not both, otherwise we > may just risk to create desync without really saving useful info. > > Also, this change makes wilc1000-sdio failing to build as module (missing symbol > export on wilc_get_chipid) I think I have a separate patch for this, one which folds wilc_get_chipid() entirely into wlan.c , and then follow up which uses is_wilc1000() / is_wilc3000() all over the place to discern the two MACs based on cached chip ID . That should work, I'll test it and submit it later today I hope. > [...] > >> - /* select VMM table 0 */ >> - if (val & SEL_VMM_TBL0) >> - reg |= BIT(5); >> - /* select VMM table 1 */ >> - if (val & SEL_VMM_TBL1) >> - reg |= BIT(6); >> - /* enable VMM */ >> - if (val & EN_VMM) >> - reg |= BIT(7); >> + if (wilc->chip == WILC_1000) { > > wilc1000 should likely remain the default/fallback ? I am now validating whether the hardware is either wilc1000 or wilc3000 up front based on the chip ID early in init, so no other option can occur here, so there is no need for fallback, it is either wilc1000 or wilc3000 now (*). I think keeping them ordered alphanumerically is the nicer option. > [...] > >> @@ -1232,10 +1234,7 @@ static int wilc_validate_chipid(struct wilc *wilc) >> dev_err(&spi->dev, "Fail cmd read chip id...\n"); >> return ret; >> } >> - if (!is_wilc1000(chipid)) { >> - dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid); >> - return -ENODEV; >> - } >> + > > Instead of dropping any filtering (and then making the function name become > irrelevant), why not ensuring that it is at least either a wilc1000 or a wilc3000 ? Right, done. [...] >> +void chip_wakeup(struct wilc *wilc) >> +{ >> + if (wilc->chip == WILC_1000) >> + chip_wakeup_wilc1000(wilc); >> + else >> + chip_wakeup_wilc3000(wilc); >> +} >> EXPORT_SYMBOL_GPL(chip_wakeup); > > This new support makes a few places in wlan.c, netdev.c and in bus files > (sdio.c, spi.c) install (sometimes big) branches on the device type (chip init, > sleep, wakeup, read interrupt, clear interrupt, txq handling, etc), because the > registers are different, the masks are different, the number of involved > registers may not be the same, wilc3000 may need more operations to perform the > same thing... I feel like it will make it harder in the long run to maintain the > driver, especially if some new variants are added later. I agree the code is ugly. Looking at the roadmap, it seems the next thing is WILCS02 which has its own driver, and for the WILC1000/3000 inherited from atmel this seems to be the end of the road. > Those branches tend to > show that some operations in those files are too specific to the targeted > device. I was examining the possibility to start creating device-type specific > files (wilc1000.c, wilc3000.c) and move those operations as "device-specific" > ops. Then wlan/netdev would call those chip-specific ops, which in turn may call > the hif_func ops. It may need some rework in the bus files to fit this new > hierarchy, but it may allow to keep netdev and wlan unaware of the device type, > and since wilc3000 has bluetooth, it may also make it easier to introduce the > corresponding support later. What do you think about it ? Ajay, any opinion on > this ? I did something like that for KSZ8851, that had bus-specific ops. I vaguely recall there was feedback that the function pointer indirection had non-trivial overhead due to spectre mitigations, and in case of the handle_txq() here, the chip specific ops would be called in a while() {} loop. I can imagine some of the long functions like wilc_sdio_clear_int_ext or the handle_txq could be split up a bit, but likely only by factoring out some of the code into static functions. But looking at this closer, both pieces which are wilc1000/3000 specific in those functions manipulate with variables which would have to be passed in into that factored out code as function arguments, so I am not sure if this would improve readability by much either. [...]
On 23/08/2024 03:38, Marek Vasut wrote: > On 8/22/24 10:07 AM, Krzysztof Kozlowski wrote: > > Hi, > >>> diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >>> index 2460ccc082371..1bf3496c21e64 100644 >>> --- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >>> +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml >>> @@ -16,7 +16,9 @@ description: >>> >>> properties: >>> compatible: >>> - const: microchip,wilc1000 >>> + enum: >>> + - microchip,wilc1000 >>> + - microchip,wilc3000 >> >> Your driver change suggests device type is fully auto-detectable > > It seems that way, yes. > >> , thus >> they are compatible. > > I _think_ the hardware is internally somewhat different, the WILC1000 is > WiFi-only device and the WILC3000 has some extra Bluetooth part (which > is currently not supported). > > Maybe a fallback compatible string would be better here ? Yes, that's what I meant by compatibility. 3000 followed by 1000. Best regards, Krzysztof
On 8/22/24 19:46, Marek Vasut wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you know the > content is safe > > On 8/22/24 2:10 PM, Alexis Lothoré wrote: >> Hello Marek, > > Hi, > >> I was coincidentally working on adding wilc3000 support upstream too. > > I hope you weren't too far along with that and I didn't waste too much > of your time/effort here. > >> My work is >> also based on downstream tree, so my comments will likely reflect the reworks I >> was doing or intended to do. >> For the record, I have some wilc1000 and wilc3000 modules, in both sdio and >> spi >> setups. > > Nice, I only have this WILC3000 SDIO device . > >> On 8/21/24 20:42, Marek Vasut wrote: >>> From: Ajay Singh <ajay.kathat@microchip.com> >> >> [...] >> >>> if (!resume) { >>> - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); >>> - if (ret) { >>> - dev_err(&func->dev, "Fail cmd read chip id...\n"); >>> + chipid = wilc_get_chipid(wilc, true); >>> + if (is_wilc3000(chipid)) { >>> + wilc->chip = WILC_3000; >>> + } else if (is_wilc1000(chipid)) { >>> + wilc->chip = WILC_1000; >>> + } else { >>> + dev_err(&func->dev, "Unsupported chipid: %x\n", chipid); >>> return ret; >>> } >> >> I wonder if this additional enum (enum wilc_chip_type) is really useful. We >> already store the raw chipid, which just needs to be masked to know about the >> device type. We should likely store one or the other but not both, otherwise we >> may just risk to create desync without really saving useful info. >> >> Also, this change makes wilc1000-sdio failing to build as module (missing >> symbol >> export on wilc_get_chipid) > > I think I have a separate patch for this, one which folds > wilc_get_chipid() entirely into wlan.c , and then follow up which uses > is_wilc1000() / is_wilc3000() all over the place to discern the two MACs > based on cached chip ID . That should work, I'll test it and submit it > later today I hope. > >> [...] >> >>> - /* select VMM table 0 */ >>> - if (val & SEL_VMM_TBL0) >>> - reg |= BIT(5); >>> - /* select VMM table 1 */ >>> - if (val & SEL_VMM_TBL1) >>> - reg |= BIT(6); >>> - /* enable VMM */ >>> - if (val & EN_VMM) >>> - reg |= BIT(7); >>> + if (wilc->chip == WILC_1000) { >> >> wilc1000 should likely remain the default/fallback ? > > I am now validating whether the hardware is either wilc1000 or wilc3000 > up front based on the chip ID early in init, so no other option can > occur here, so there is no need for fallback, it is either wilc1000 or > wilc3000 now (*). I think keeping them ordered alphanumerically is the > nicer option. > >> [...] >> >>> @@ -1232,10 +1234,7 @@ static int wilc_validate_chipid(struct wilc *wilc) >>> dev_err(&spi->dev, "Fail cmd read chip id...\n"); >>> return ret; >>> } >>> - if (!is_wilc1000(chipid)) { >>> - dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid); >>> - return -ENODEV; >>> - } >>> + >> >> Instead of dropping any filtering (and then making the function name become >> irrelevant), why not ensuring that it is at least either a wilc1000 or a >> wilc3000 ? > > Right, done. > > [...] > >>> +void chip_wakeup(struct wilc *wilc) >>> +{ >>> + if (wilc->chip == WILC_1000) >>> + chip_wakeup_wilc1000(wilc); >>> + else >>> + chip_wakeup_wilc3000(wilc); >>> +} >>> EXPORT_SYMBOL_GPL(chip_wakeup); >> >> This new support makes a few places in wlan.c, netdev.c and in bus files >> (sdio.c, spi.c) install (sometimes big) branches on the device type (chip init, >> sleep, wakeup, read interrupt, clear interrupt, txq handling, etc), because the >> registers are different, the masks are different, the number of involved >> registers may not be the same, wilc3000 may need more operations to perform the >> same thing... I feel like it will make it harder in the long run to maintain >> the >> driver, especially if some new variants are added later. > > I agree the code is ugly. Looking at the roadmap, it seems the next > thing is WILCS02 which has its own driver, and for the WILC1000/3000 > inherited from atmel this seems to be the end of the road yes, WILCS02 is the next-generation product of WILC family. It supports both SDIO and SPI(mmc-over-spi) and the driver is same as WILC1000/3000. The same sdio driver will be used for mmc-over-spi interface. Similar to wilc3000, the wilcs02 have different register sets and minor difference in firmware start and txq_handling flow. The single driver will support all WILC variants. > >> Those branches tend to >> show that some operations in those files are too specific to the targeted >> device. I was examining the possibility to start creating device-type specific >> files (wilc1000.c, wilc3000.c) and move those operations as "device-specific" >> ops. Then wlan/netdev would call those chip-specific ops, which in turn may >> call >> the hif_func ops. It may need some rework in the bus files to fit this new >> hierarchy, but it may allow to keep netdev and wlan unaware of the device type, >> and since wilc3000 has bluetooth, it may also make it easier to introduce the >> corresponding support later. What do you think about it ? Ajay, any opinion on >> this ? > > I did something like that for KSZ8851, that had bus-specific ops. I > vaguely recall there was feedback that the function pointer indirection > had non-trivial overhead due to spectre mitigations, and in case of the > handle_txq() here, the chip specific ops would be called in a while() {} > loop. > > I can imagine some of the long functions like wilc_sdio_clear_int_ext or > the handle_txq could be split up a bit, but likely only by factoring out > some of the code into static functions. But looking at this closer, both > pieces which are wilc1000/3000 specific in those functions manipulate > with variables which would have to be passed in into that factored out > code as function arguments, so I am not sure if this would improve > readability by much either. > I also think adding wilc1000/wilc3000 specific may not improve much but some of the large functions can be refactored if it improves the readability. For most part, wilc1000 and wilc3000 has similar code but it mainly differs in txq_handle handling, which may not be improved even after separating the code to wilc1000 and wilc3000 specific files.
diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml index 2460ccc082371..1bf3496c21e64 100644 --- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml @@ -16,7 +16,9 @@ description: properties: compatible: - const: microchip,wilc1000 + enum: + - microchip,wilc1000 + - microchip,wilc3000 reg: true
Document compatible string for the WILC3000 chip. The chip is similar to WILC1000, except that the register layout is slightly different and it does not support WPA3/SAE. Signed-off-by: Marek Vasut <marex@denx.de> --- Cc: "David S. Miller" <davem@davemloft.net> Cc: Adham Abozaeid <adham.abozaeid@microchip.com> Cc: Ajay Singh <ajay.kathat@microchip.com> Cc: Alexis Lothoré <alexis.lothore@bootlin.com> Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev> Cc: Conor Dooley <conor+dt@kernel.org> Cc: Eric Dumazet <edumazet@google.com> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Kalle Valo <kvalo@kernel.org> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org> Cc: Marek Vasut <marex@denx.de> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Rob Herring <robh@kernel.org> Cc: devicetree@vger.kernel.org Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org --- .../devicetree/bindings/net/wireless/microchip,wilc1000.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)