b43: Allow running without PCM firmware
authorMichael Buesch <mb@bu3sch.de>
Sat, 17 May 2008 21:43:57 +0000 (23:43 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 22 May 2008 01:48:16 +0000 (21:48 -0400)
This patch adds code to allow running the device without PCM firmware loaded.
Without PCM firmware we don't have hardware accelerated crypto on
devices with a core rev <= 10.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/main.c

index 00468594b456c9f021b797aa0895e2628230cc83..f588dfa9c1d47c0805a1c8cfb47d37459ff0d794 100644 (file)
@@ -774,6 +774,10 @@ struct b43_firmware {
 
        /* Set to true, if we are using an opensource firmware. */
        bool opensource;
+       /* Set to true, if the core needs a PCM firmware, but
+        * we failed to load one. This is always false for
+        * core rev > 10, as these don't need PCM firmware. */
+       bool pcm_request_failed;
 };
 
 /* Device (802.11 core) initialization status. */
index 656a1f04ad6e273223c6dac20af2a86e63702ea5..6011747bb3b9fd5a85806efff9473beb8b47ee11 100644 (file)
@@ -1908,7 +1908,8 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
 
 static int do_request_fw(struct b43_wldev *dev,
                         const char *name,
-                        struct b43_firmware_file *fw)
+                        struct b43_firmware_file *fw,
+                        bool silent)
 {
        char path[sizeof(modparam_fwpostfix) + 32];
        const struct firmware *blob;
@@ -1932,9 +1933,15 @@ static int do_request_fw(struct b43_wldev *dev,
                 "b43%s/%s.fw",
                 modparam_fwpostfix, name);
        err = request_firmware(&blob, path, dev->dev->dev);
-       if (err) {
-               b43err(dev->wl, "Firmware file \"%s\" not found "
-                      "or load failed.\n", path);
+       if (err == -ENOENT) {
+               if (!silent) {
+                       b43err(dev->wl, "Firmware file \"%s\" not found\n",
+                              path);
+               }
+               return err;
+       } else if (err) {
+               b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
+                      path, err);
                return err;
        }
        if (blob->size < sizeof(struct b43_fw_header))
@@ -1985,7 +1992,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
                filename = "ucode13";
        else
                goto err_no_ucode;
-       err = do_request_fw(dev, filename, &fw->ucode);
+       err = do_request_fw(dev, filename, &fw->ucode, 0);
        if (err)
                goto err_load;
 
@@ -1996,8 +2003,13 @@ static int b43_request_firmware(struct b43_wldev *dev)
                filename = NULL;
        else
                goto err_no_pcm;
-       err = do_request_fw(dev, filename, &fw->pcm);
-       if (err)
+       fw->pcm_request_failed = 0;
+       err = do_request_fw(dev, filename, &fw->pcm, 1);
+       if (err == -ENOENT) {
+               /* We did not find a PCM file? Not fatal, but
+                * core rev <= 10 must do without hwcrypto then. */
+               fw->pcm_request_failed = 1;
+       } else if (err)
                goto err_load;
 
        /* Get initvals */
@@ -2028,7 +2040,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
        default:
                goto err_no_initvals;
        }
-       err = do_request_fw(dev, filename, &fw->initvals);
+       err = do_request_fw(dev, filename, &fw->initvals, 0);
        if (err)
                goto err_load;
 
@@ -2062,7 +2074,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
        default:
                goto err_no_initvals;
        }
-       err = do_request_fw(dev, filename, &fw->initvals_band);
+       err = do_request_fw(dev, filename, &fw->initvals_band, 0);
        if (err)
                goto err_load;
 
@@ -2186,14 +2198,20 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        if (dev->fw.opensource) {
                /* Patchlevel info is encoded in the "time" field. */
                dev->fw.patch = fwtime;
-               b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n",
-                       dev->fw.rev, dev->fw.patch);
+               b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n",
+                       dev->fw.rev, dev->fw.patch,
+                       dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : "");
        } else {
                b43info(dev->wl, "Loading firmware version %u.%u "
                        "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
                        fwrev, fwpatch,
                        (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
                        (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
+               if (dev->fw.pcm_request_failed) {
+                       b43warn(dev->wl, "No \"pcm5.fw\" firmware file found. "
+                               "Hardware accelerated cryptography is disabled.\n");
+                       b43_print_fw_helptext(dev->wl, 0);
+               }
        }
 
        if (b43_is_old_txhdr_format(dev)) {
@@ -3358,6 +3376,13 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
                goto out_unlock;
 
+       if (dev->fw.pcm_request_failed) {
+               /* We don't have firmware for the crypto engine.
+                * Must use software-crypto. */
+               err = -EOPNOTSUPP;
+               goto out_unlock;
+       }
+
        err = -EINVAL;
        switch (key->alg) {
        case ALG_WEP: