From patchwork Sat Dec 6 13:02:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 5449201 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 99EA3BEEA8 for ; Sat, 6 Dec 2014 13:02:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C605D20158 for ; Sat, 6 Dec 2014 13:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D3A5B20155 for ; Sat, 6 Dec 2014 13:02:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752623AbaLFNC0 (ORCPT ); Sat, 6 Dec 2014 08:02:26 -0500 Received: from mail-wi0-f182.google.com ([209.85.212.182]:53256 "EHLO mail-wi0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752613AbaLFNCY (ORCPT ); Sat, 6 Dec 2014 08:02:24 -0500 Received: by mail-wi0-f182.google.com with SMTP id h11so1041592wiw.15 for ; Sat, 06 Dec 2014 05:02:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:user-agent:cc:references:in-reply-to :mime-version:content-type:content-transfer-encoding:message-id; bh=P2k5BLJRcBcq3nnTSqzmIWf+gTNVjeQ16aTjWkLW+YI=; b=e+RLvW7307OH2HWBwkevG4/P/eFb0HR/A7CfBpEAOEwb6kaXM9WFtYqcDuGychYPMb VpQfLJmz5629dXDIpf4rXc1elvUJs0FGK80W5iDGMNnI8z4HIUI9cZknSHpYMA0e0J59 JTfo4F+81K8Vfkf+svAJ2ahQ1vUHa33yC5mjtx2N06LuchKOxvsLn5CeLGlYDHw54ogI wXe9rVlfgK6mW22bPhgop/eneoAVwK2jFzwlOkDs5vPH4mIQgH2a0K4JLusoo/R4WCKi 8TcM75rVo7uUcuxphjMw+zA78ew8vbH7kBpaAe9M/8ABE3hUsDqITtmc5XT0Bj/ZyJH6 7NIA== X-Received: by 10.194.109.6 with SMTP id ho6mr31941708wjb.93.1417870943245; Sat, 06 Dec 2014 05:02:23 -0800 (PST) Received: from pali-latitude.localnet ([2001:718:1e03:a01::1ca]) by mx.google.com with ESMTPSA id gs9sm48637561wjc.47.2014.12.06.05.02.22 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 06 Dec 2014 05:02:22 -0800 (PST) From: Pali =?utf-8?q?Roh=C3=A1r?= To: Pavel Machek , "Greg Kroah-Hartman" , Ming Lei Subject: Re: wl1251: NVS firmware data Date: Sat, 6 Dec 2014 14:02:21 +0100 User-Agent: KMail/1.13.7 (Linux/3.18.0-031800rc5-generic; KDE/4.14.1; x86_64; ; ) Cc: "John W. Linville" , Grazvydas Ignotas , "linux-wireless@vger.kernel.org" , Network Development , Linux Kernel Mailing List , Ivaylo Dimitrov , Aaro Koskinen , Kalle Valo , Sebastian Reichel , David Gnedt References: <201411271506.20457@pali> <20141127155840.GC24149@kroah.com> <20141206124954.GB17289@amd> In-Reply-To: <20141206124954.GB17289@amd> MIME-Version: 1.0 Message-Id: <201412061402.21514@pali> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, T_TVD_MIME_EPI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Saturday 06 December 2014 13:49:54 Pavel Machek wrote: > On Thu 2014-11-27 07:58:40, Greg Kroah-Hartman wrote: > > On Thu, Nov 27, 2014 at 04:22:58PM +0100, Pali Rohár wrote: > > > On Thursday 27 November 2014 16:16:55 Greg Kroah-Hartman wrote: > > > > On Thu, Nov 27, 2014 at 03:43:23PM +0100, Pali Rohár wrote: > > > > > On Thursday 27 November 2014 15:21:44 Ming Lei wrote: > > > > > > On Thu, Nov 27, 2014 at 10:06 PM, Pali Rohár > > > > > > > > > > wrote: > > > > > > > Hello, > > > > > > > > > > > > > > wifi driver wl1251 needs NVS calibration data for > > > > > > > working. These data are loaded by driver via > > > > > > > request_firmware from userspace file: > > > > > > > ti-connectivity/wl1251-nvs.bin. In linux-fimrware > > > > > > > git tree there is generic wl1251-nvs.bin file > > > > > > > which is used by default. > > > > > > > > > > > > > > Driver wl1251 is used on Nokia N900 cellphone for > > > > > > > its wifi chip. This cellphone has one special MTD > > > > > > > partition (called CAL) where are stored some > > > > > > > configuration data in special binary (key-value) > > > > > > > format. And there is also stored correct > > > > > > > calibration data for specific device (each device > > > > > > > has different data). It is preferred to use those > > > > > > > data instead generic one (provided by > > > > > > > linux-firmware git tree). > > > > > > > > > > > > > > Now my question is: How to correctly load > > > > > > > calibration data from special Nokia N900 CAL > > > > > > > partition into wl1251 kernel driver? > > > > > > > > > > > > It is better to let user space script handle the > > > > > > request. > > > > > > > > > > Yes, this makes sense. Implementing CAL parser in > > > > > kernel wl1251 driver would be hard... > > > > > > > > > > > > By default kernel reads > > > > > > > ti-connectivity/wl1251-nvs.bin file from VFS if > > > > > > > exists without any userspace support. If it fails > > > > > > > then it fallback to loading via udev. > > > > > > > > > > > > You can remove or rename this file so that loading > > > > > > from user space can be triggered. > > > > > > > > > > It is no so easy... In case when CAL does not contains > > > > > NVS data then we want to use this generic NVS file. > > > > > And telling everybody to rename this is file is not > > > > > good solution... > > > > > > > > But that's up to your system configuration, not the > > > > kernel. Make a userspace package for the firmware that > > > > creates it in the format you need it to be in, for the > > > > hardware you have, and then there would not be any need > > > > for a kernel change, right? > > > > > > > > greg k-h > > > > > > Not so simple as you think. Some parts of NVS data are > > > configured based on location and cellular station. Data > > > are not static. > > > > Then you need a dynamic program that you control, in > > userspace, to dump the needed data into the kernel. Don't > > try to do it with "static" firmware files. Use the binary > > sysfs file interface for this if you want. > > Actually, this seems to be similar situation to fpga > programming. > > There, it is static firmware for 90% users, but some special > use cases want it more dynamic. > Pavel Greg, Ming, what do you think about this approach? diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3d785eb..810c4b9 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -111,6 +111,11 @@ static inline long firmware_loading_timeout(void) #define FW_OPT_FALLBACK 0 #endif #define FW_OPT_NO_WARN (1U << 3) +#ifdef CONFIG_FW_LOADER_USER_HELPER +#define FW_OPT_PREFER_USER (1U << 4) +#else +#define FW_OPT_PREFER_USER 0 +#endif struct firmware_cache { /* firmware_buf instance will be added into the below list */ @@ -1131,7 +1136,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name, } } - ret = fw_get_filesystem_firmware(device, fw->priv); + if (opt_flags & FW_OPT_PREFER_USER) { + ret = fw_load_from_user_helper(fw, name, device, opt_flags, timeout); + if (ret) { + dev_warn(device, + "User helper firmware load for %s failed with error %d\n", + name, ret); + dev_warn(device, "Falling back to direct firmware load\n"); + } + } else { + ret = -EINVAL; + } + + if (ret) + ret = fw_get_filesystem_firmware(device, fw->priv); if (ret) { if (!(opt_flags & FW_OPT_NO_WARN)) dev_warn(device, @@ -1218,6 +1236,28 @@ int request_firmware_direct(const struct firmware **firmware_p, EXPORT_SYMBOL_GPL(request_firmware_direct); /** + * request_firmware_prefer_user: - prefer usermode helper for loading firmware + * @firmware_p: pointer to firmware image + * @name: name of firmware file + * @device: device for which firmware is being loaded + * + * This function works pretty much like request_firmware(), but it prefer + * usermode helper. If usermode helper fails then it fallback to direct access. + * Usefull for dynamic or model specific firmware data. + **/ +int request_firmware_prefer_user(const struct firmware **firmware_p, + const char *name, struct device *device) +{ + int ret; + __module_get(THIS_MODULE); + ret = _request_firmware(firmware_p, name, device, + FW_OPT_UEVENT | FW_OPT_PREFER_USER); + module_put(THIS_MODULE); + return ret; +} +EXPORT_SYMBOL_GPL(request_firmware_prefer_user); + +/** * release_firmware: - release the resource associated with a firmware image * @fw: firmware resource to release **/ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 5c41c5e..d35c511 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -47,6 +47,8 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context)); int request_firmware_direct(const struct firmware **fw, const char *name, struct device *device); +int request_firmware_prefer_user(const struct firmware **fw, const char *name, + struct device *device); void release_firmware(const struct firmware *fw); #else