Luca Coelho <luca@xxxxxxxxx> writes: > From: Emmanuel Grumbach <emmanuel.grumbach@xxxxxxxxx> > > The shared area is a DMA memory allocated in the host and > mapped so that the host and the CSME firmware can > exchange data. It is mapped through a dedicated PCI device > that is driven by the mei bus driver. > > The bus driver is in charge of allocating and mapping this > memory. It also needs to configure the CSME firmware with > a specific set of commands, so that the CSME firmware will > know that this memory is meant to be used by its internal > WLAN module. > > For this, the CSME firmware first needs to completely > initialize its WLAN module and only then get the mapping > request. > > The problem is that the mei bus enumeration completes > before the WLAN is completely ready. This means that > the WLAN module's initialization is racing with iwlmei's > allocation and mapping flow. > > Testing showed a problem in resume flows where iwlmei > was too fast and the DMA mapping failed. > > Add a retry mechanism to make sure that we will succeed > to map the memory. > > Fixes: 2da4366f9e2c ("iwlwifi: mei: add the driver to allow cooperation with CSME") > Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@xxxxxxxxx> > Fixes: bcbddc4f9d02 ("iwlwifi: mei: wait before mapping the shared area") I'll move the latter Fixes before s-o-b tag. > - /* > - * The CSME firmware needs to boot the internal WLAN client. Wait here > - * so that the DMA map request will succeed. > - */ > - msleep(20); > + do { > + ret = iwl_mei_alloc_shared_mem(cldev); > + if (!ret) > + break; > + /* > + * The CSME firmware needs to boot the internal WLAN client. > + * This can take time in certain configurations (usually > + * upon resume and when the whole CSME firmware is shut down > + * during suspend). > + * > + * Wait a bit before retrying and hope we'll succeed next time. > + */ > > - ret = iwl_mei_alloc_shared_mem(cldev); > - if (ret) > + dev_dbg(&cldev->dev, > + "Couldn't allocate the shared memory: %d, attempt %d / %d\n", > + ret, alloc_retry, ALLOC_SHARED_MEM_RETRY_MAX_NUM); > + msleep(100); > + alloc_retry--; > + } while (alloc_retry); Nitpicking, but this could have been: while (alloc_retry--); But no need to resend because of this. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches