All of lore.kernel.org
 help / color / mirror / Atom feed
From: ludovic.desroches@atmel.com (Ludovic Desroches)
To: linux-arm-kernel@lists.infradead.org
Subject: AT91 SDIO WiFi no working
Date: Tue, 19 Jul 2011 16:30:48 +0200	[thread overview]
Message-ID: <4E259518.3020902@atmel.com> (raw)
In-Reply-To: <4E1DE39F.3030104@nlink.com.br>

Hello all.

On 7/13/2011 8:27 PM, Paulo Fragoso wrote:
> Hi,
>
> We are trying to run SDIO WiFI with a board based on AT91sam9 and our 
> configuration and firmware files are apparently ok but now we have got 
> this erro:
>
> root at buildroot:~# modprobe libertas
> root at buildroot:~# modprobe libertas_sdio.ko 
> helper_name=/lib/firmware/sd8686_v8_
> helper.bin fw_name=/lib/firmware/sd8686_v8.bin
> libertas_sdio: Libertas SDIO driver
> libertas_sdio: Copyright Pierre Ossman
> libertas: can't load helper firmware
> libertas: failed to load helper firmware
> libertas_sdio: probe of mmc0:0001:1 failed with error -2
>
> udev is running too, what might be happening?
>
> Thanks,
> Paulo.
>
I am also facing some problems using the libertas driver. I am not sure 
that it's the same problem as Paulo because I don't know which kernel 
version he is using. It's probably not the best place to talk about this 
because I don't think the problem is coming from at91 mmc driver, that's 
why I also send this message  to libertas-dev.

I have made my tests with 3.0-rc7 version this what I have (I have added 
some traces) :

    root at at91sam9g20ek:~# insmod libertas.ko libertas_debug=0x5063a7
    [   52.220000] libertas enter: lbs_init_module()
    [   52.220000] libertas leave: lbs_init_module()
    root at at91sam9g20ek:~#
    root at at91sam9g20ek:~#
    root at at91sam9g20ek:~#
    root at at91sam9g20ek:~# insmod libertas_sdio.ko
    helper_name="helper_sd.bin" fw_nam
    e="sd8686.bin"
    [   55.450000] libertas enter: if_sdio_init_module()
    [   55.450000] libertas_sdio: Libertas SDIO driver
    [   55.460000] libertas_sdio: Copyright Pierre Ossman
    [   55.460000] libertas leave: if_sdio_init_module(), ret 0
    root at at91sam9g20ek:~# [   58.020000] mmc1: new SDIO card at address 0001
    [   58.030000] libertas enter: if_sdio_probe()
    [   58.030000] libertas sdio: class = 0x7, vendor = 0x2DF, device =
    0x9103, model = 0xB, ioport = 0x10000
    [   58.040000] libertas enter: if_sdio_prog_firmware()
    [   58.060000] libertas sdio: firmware status = 0x0
    [   58.060000] libertas sdio: scratch ret = 0
    [   58.060000] libertas_sdio mmc1:0001:1: load user helper firmware:
    helper_sd.bin
    [   58.110000] libertas_sdio mmc1:0001:1: helperfw size: 2516
    [   58.120000] libertas_sdio mmc1:0001:1: load user main firmware:
    sd8686.bin
    [   58.170000] libertas_sdio mmc1:0001:1: mainfw size: 2516
    [   58.170000] libertas enter: if_sdio_prog_helper()
    [   58.380000] libertas sdio: waiting for helper to boot...
    [   58.380000] libertas leave: if_sdio_prog_helper(), ret 0
    [   58.390000] libertas sdio: Helper firmware loaded
    [   58.390000] libertas enter: if_sdio_prog_real()
    [   58.400000] libertas sdio: firmware size: 2516
    [   58.400000] libertas sdio: firmware wants 16 bytes
    [   58.410000] libertas sdio: sending 16 bytes (32 bytes) chunk
    [   58.420000] libertas sdio: firmware wants 17 bytes
    [   58.420000] libertas sdio: firmware helper signalled error
    [   58.430000] libertas_sdio: failed to load firmware
    [   58.430000] libertas leave: if_sdio_prog_real(), ret -5
    [   58.440000] libertas leave: if_sdio_prog_firmware(), ret -5
    [   58.450000] libertas leave: if_sdio_probe(), ret -5
    [   58.450000] libertas_sdio: probe of mmc1:0001:1 failed with error -5


The first problem is the main firmware size which is the size of the 
helper firmware.

Now the second problem:

    [1140] msg_queue_insert: seq 540 queued, 'add' 'firmware'
    [1170] run_program: 'firmware.sh'
    [1140] udev_event_run: seq 540 forked, pid [1170], 'add' 'firmware',
    0 seconds old
    [1170] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    helper_sd.bin'
    [1170] run_program: '/lib/udev/firmware.sh' returned with status 0
    [1170] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1170] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1170] run_program: '/lib/udev/firmware.sh'
    [1170] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    helper_sd.bin'
    [1170] run_program: '/lib/udev/firmware.sh' returned with status 0
    [1170] udev_event_run: seq 540 finished with 0
    [1140] msg_queue_insert: seq 541 queued, 'remove' 'firmware'
    [1175] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1175] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1175] udev_event_run: seq 541 finished with 0
    [1140] udev_event_run: seq 541 forked, pid [1175], 'remove'
    'firmware', 0 seconds old
    [1140] msg_queue_insert: seq 542 queued, 'add' 'firmware'
    [1140] udev_event_run: seq 542 forked, pid [1176], 'add' 'firmware',
    0 seconds old
    [1176] run_program: 'firmware.sh'
    [1176] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    sd8686.bin'
    [1176] run_program: '/lib/udev/firmware.sh' (stderr) 'udev firmware
    loader misses sysfs directory'
    [1176] run_program: '/lib/udev/firmware.sh' returned with status 1
    [1176] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1176] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1176] run_program: '/lib/udev/firmware.sh'
    [1176] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    sd8686.bin'
    [1176] run_program: '/lib/udev/firmware.sh' (stderr) 'udev firmware
    loader misses sysfs directory'
    [1176] run_program: '/lib/udev/firmware.sh' returned with status 1
    [1176] udev_event_run: seq 542 finished with -1


I don't understand why I have two to firmware.sh for helper_sd.bin and 
also for sd8686.bin. The second part I don't understand is why the sysfs 
entries for the firmware have been removed between the two uevent.


The function dealing with firmwares is lbs_get_firmware where we have 
two successive request_firmware calls. I am confused about the behavior 
but I had the feeling that the two successive request_firmware calls was 
the problem because the main firmware size is those of the helper 
firmware. That's why I did this:

    commit 53ad5481c1d659da920e950f47ae25cbfc288239
    Author: Ludovic Desroches <ludovic.desroches@atmel.com>
    Date:   Tue Jul 19 15:52:26 2011 +0200

         libertas: separate helper and main firmware request

         Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>

    diff --git a/drivers/net/wireless/libertas/if_sdio.c
    b/drivers/net/wireless/libertas/if_sdio.c
    index 224e985..01e530c 100644
    --- a/drivers/net/wireless/libertas/if_sdio.c
    +++ b/drivers/net/wireless/libertas/if_sdio.c
    @@ -723,7 +723,7 @@ static int if_sdio_prog_firmware(struct
    if_sdio_card *card)
          }

          ret = lbs_get_firmware(&card->func->dev, lbs_helper_name,
    lbs_fw_name,
    -                card->model, &fw_table[0], &helper, &mainfw);
    +                card->model, &fw_table[0], &helper, NULL);
          if (ret) {
              pr_err("failed to find firmware (%d)\n", ret);
              goto out;
    @@ -735,6 +735,10 @@ static int if_sdio_prog_firmware(struct
    if_sdio_card *card)

          lbs_deb_sdio("Helper firmware loaded\n");

    +    ret = lbs_get_firmware(&card->func->dev, lbs_helper_name,
    lbs_fw_name,
    +                card->model, &fw_table[0], NULL, &mainfw);
    +
    +
          ret = if_sdio_prog_real(card, mainfw);
          if (ret)
              goto out;
    diff --git a/drivers/net/wireless/libertas/main.c
    b/drivers/net/wireless/libertas/main.c
    index 8c40949..b35ca07 100644
    --- a/drivers/net/wireless/libertas/main.c
    +++ b/drivers/net/wireless/libertas/main.c
    @@ -1075,11 +1075,9 @@ int lbs_get_firmware(struct device *dev,
    const char *user_helper,
          const struct lbs_fw_table *iter;
          int ret;

    -    BUG_ON(helper == NULL);
    -    BUG_ON(mainfw == NULL);
    -
          /* Try user-specified firmware first */
    -    if (user_helper) {
    +    if (user_helper && helper) {
    +        dev_info(dev, "load user helper firmware: %s\n", user_helper);
              ret = request_firmware(helper, user_helper, dev);
              if (ret) {
                  dev_err(dev, "couldn't find helper firmware %s\n",
    @@ -1087,7 +1085,8 @@ int lbs_get_firmware(struct device *dev, const
    char *user_helper,
                  goto fail;
              }
          }
    -    if (user_mainfw) {
    +    if (user_mainfw && mainfw) {
    +        dev_info(dev, "load user main firmware: %s\n", user_mainfw);
              ret = request_firmware(mainfw, user_mainfw, dev);
              if (ret) {
                  dev_err(dev, "couldn't find main firmware %s\n",
    @@ -1096,8 +1095,7 @@ int lbs_get_firmware(struct device *dev, const
    char *user_helper,
              }
          }

    -    if (*helper && *mainfw)
    -        return 0;
    +    return 0;

          /* Otherwise search for firmware to use.  If neither the helper or
           * the main firmware were specified by the user, then we need to



Everything is ok with my patch but I would like to understand what 
happens, why I need this patch and if it is correct or just a lucky 
horrible hack ! Here the udev logs seems more logical even if I still 
have two requests for each firmware. The first call is ok but the second 
fails because of missing sysfs entries.

    [1113] msg_queue_insert: seq 524 queued, 'add' 'firmware'
    [1113] udev_event_run: seq 524 forked, pid [1125], 'add' 'firmware',
    0 seconds old
    [1125] run_program: 'firmware.sh'
    [1125] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    helper_sd.bin'
    [1125] run_program: '/lib/udev/firmware.sh' returned with status 0
    [1125] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1125] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1125] run_program: '/lib/udev/firmware.sh'
    [1125] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    helper_sd.bin'
    [1125] run_program: '/lib/udev/firmware.sh' (stderr) 'udev firmware
    loader misses sysfs directory'
    [1125] run_program: '/lib/udev/firmware.sh' returned with status 1
    [1125] udev_event_run: seq 524 finished with -1
    [1113] msg_queue_insert: seq 525 queued, 'remove' 'firmware'
    [1113] udev_event_run: seq 525 forked, pid [1130], 'remove'
    'firmware', 0 seconds old
    [1130] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1130] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1130] udev_event_run: seq 525 finished with 0
    [   95.140000] libertas_sdio mmc1:0001:1: load user main firmware:
    sd8686.bin
    [1113] msg_queue_insert: seq 526 queued, 'add' 'firmware'
    [1113] udev_event_run: seq 526 forked, pid [1131], 'add' 'firmware',
    0 seconds old
    [1131] run_program: 'firmware.sh'
    [1131] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    sd8686.bin'
    [1131] run_program: '/lib/udev/firmware.sh' returned with status 0
    [1131] pass_env_to_socket: passed -1 bytes to socket
    '@/org/kernel/udev/monitor',
    [1131] pass_env_to_socket: passed -1 bytes to socket
    '/org/kernel/udev/monitor',
    [1131] run_program: '/lib/udev/firmware.sh'
    [1131] run_program: '/lib/udev/firmware.sh' (stdout) 'firmware:
    sd8686.bin'
    [1131] run_program: '/lib/udev/firmware.sh' (stderr) 'udev firmware
    loader misses sysfs directory'
    [1131] run_program: '/lib/udev/firmware.sh' returned with status 1
    [1131] udev_event_run: seq 526 finished with -1


Thanks for you help.

Regards,

Ludovic

      reply	other threads:[~2011-07-19 14:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-13 18:27 AT91 SDIO WiFi no working Paulo Fragoso
2011-07-19 14:30 ` Ludovic Desroches [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E259518.3020902@atmel.com \
    --to=ludovic.desroches@atmel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.