spidernet: load firmware when open
authorKou Ishizaki <kou.ishizaki@toshiba.co.jp>
Tue, 20 Feb 2007 22:34:50 +0000 (16:34 -0600)
committerJeff Garzik <jeff@garzik.org>
Tue, 27 Feb 2007 09:16:03 +0000 (04:16 -0500)
This patch moves calling init_firmware() from spider_net_probe() to
spider_net_open() so as to use the driver by built-in.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/spider_net.c

index 8aa3ebe..fef4556 100644 (file)
@@ -1704,6 +1704,124 @@ spider_net_enable_card(struct spider_net_card *card)
                             SPIDER_NET_GDTBSTA);
 }
 
+/**
+ * spider_net_download_firmware - loads firmware into the adapter
+ * @card: card structure
+ * @firmware_ptr: pointer to firmware data
+ *
+ * spider_net_download_firmware loads the firmware data into the
+ * adapter. It assumes the length etc. to be allright.
+ */
+static int
+spider_net_download_firmware(struct spider_net_card *card,
+                            const void *firmware_ptr)
+{
+       int sequencer, i;
+       const u32 *fw_ptr = firmware_ptr;
+
+       /* stop sequencers */
+       spider_net_write_reg(card, SPIDER_NET_GSINIT,
+                            SPIDER_NET_STOP_SEQ_VALUE);
+
+       for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
+            sequencer++) {
+               spider_net_write_reg(card,
+                                    SPIDER_NET_GSnPRGADR + sequencer * 8, 0);
+               for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
+                       spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
+                                            sequencer * 8, *fw_ptr);
+                       fw_ptr++;
+               }
+       }
+
+       if (spider_net_read_reg(card, SPIDER_NET_GSINIT))
+               return -EIO;
+
+       spider_net_write_reg(card, SPIDER_NET_GSINIT,
+                            SPIDER_NET_RUN_SEQ_VALUE);
+
+       return 0;
+}
+
+/**
+ * spider_net_init_firmware - reads in firmware parts
+ * @card: card structure
+ *
+ * Returns 0 on success, <0 on failure
+ *
+ * spider_net_init_firmware opens the sequencer firmware and does some basic
+ * checks. This function opens and releases the firmware structure. A call
+ * to download the firmware is performed before the release.
+ *
+ * Firmware format
+ * ===============
+ * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being
+ * the program for each sequencer. Use the command
+ *    tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt              \
+ *         Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt   \
+ *         Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin
+ *
+ * to generate spider_fw.bin, if you have sequencer programs with something
+ * like the following contents for each sequencer:
+ *    <ONE LINE COMMENT>
+ *    <FIRST 4-BYTES-WORD FOR SEQUENCER>
+ *    <SECOND 4-BYTES-WORD FOR SEQUENCER>
+ *     ...
+ *    <1024th 4-BYTES-WORD FOR SEQUENCER>
+ */
+static int
+spider_net_init_firmware(struct spider_net_card *card)
+{
+       struct firmware *firmware = NULL;
+       struct device_node *dn;
+       const u8 *fw_prop = NULL;
+       int err = -ENOENT;
+       int fw_size;
+
+       if (request_firmware((const struct firmware **)&firmware,
+                            SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
+               if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
+                    netif_msg_probe(card) ) {
+                       pr_err("Incorrect size of spidernet firmware in " \
+                              "filesystem. Looking in host firmware...\n");
+                       goto try_host_fw;
+               }
+               err = spider_net_download_firmware(card, firmware->data);
+
+               release_firmware(firmware);
+               if (err)
+                       goto try_host_fw;
+
+               goto done;
+       }
+
+try_host_fw:
+       dn = pci_device_to_OF_node(card->pdev);
+       if (!dn)
+               goto out_err;
+
+       fw_prop = get_property(dn, "firmware", &fw_size);
+       if (!fw_prop)
+               goto out_err;
+
+       if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
+            netif_msg_probe(card) ) {
+               pr_err("Incorrect size of spidernet firmware in " \
+                      "host firmware\n");
+               goto done;
+       }
+
+       err = spider_net_download_firmware(card, fw_prop);
+
+done:
+       return err;
+out_err:
+       if (netif_msg_probe(card))
+               pr_err("Couldn't find spidernet firmware in filesystem " \
+                      "or host firmware\n");
+       return err;
+}
+
 /**
  * spider_net_open - called upon ifonfig up
  * @netdev: interface device structure
@@ -1719,6 +1837,10 @@ spider_net_open(struct net_device *netdev)
        struct spider_net_card *card = netdev_priv(netdev);
        int result;
 
+       result = spider_net_init_firmware(card);
+       if (result)
+               goto init_firmware_failed;
+
        /* start probing with copper */
        spider_net_setup_aneg(card);
        if (card->phy.def->phy_id)
@@ -1762,6 +1884,7 @@ alloc_rx_failed:
        spider_net_free_chain(card, &card->tx_chain);
 alloc_tx_failed:
        del_timer_sync(&card->aneg_timer);
+init_firmware_failed:
        return result;
 }
 
@@ -1872,124 +1995,6 @@ spider_net_setup_phy(struct spider_net_card *card)
        return 0;
 }
 
-/**
- * spider_net_download_firmware - loads firmware into the adapter
- * @card: card structure
- * @firmware_ptr: pointer to firmware data
- *
- * spider_net_download_firmware loads the firmware data into the
- * adapter. It assumes the length etc. to be allright.
- */
-static int
-spider_net_download_firmware(struct spider_net_card *card,
-                            const void *firmware_ptr)
-{
-       int sequencer, i;
-       const u32 *fw_ptr = firmware_ptr;
-
-       /* stop sequencers */
-       spider_net_write_reg(card, SPIDER_NET_GSINIT,
-                            SPIDER_NET_STOP_SEQ_VALUE);
-
-       for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
-            sequencer++) {
-               spider_net_write_reg(card,
-                                    SPIDER_NET_GSnPRGADR + sequencer * 8, 0);
-               for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
-                       spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
-                                            sequencer * 8, *fw_ptr);
-                       fw_ptr++;
-               }
-       }
-
-       if (spider_net_read_reg(card, SPIDER_NET_GSINIT))
-               return -EIO;
-
-       spider_net_write_reg(card, SPIDER_NET_GSINIT,
-                            SPIDER_NET_RUN_SEQ_VALUE);
-
-       return 0;
-}
-
-/**
- * spider_net_init_firmware - reads in firmware parts
- * @card: card structure
- *
- * Returns 0 on success, <0 on failure
- *
- * spider_net_init_firmware opens the sequencer firmware and does some basic
- * checks. This function opens and releases the firmware structure. A call
- * to download the firmware is performed before the release.
- *
- * Firmware format
- * ===============
- * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being
- * the program for each sequencer. Use the command
- *    tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt              \
- *         Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt   \
- *         Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin
- *
- * to generate spider_fw.bin, if you have sequencer programs with something
- * like the following contents for each sequencer:
- *    <ONE LINE COMMENT>
- *    <FIRST 4-BYTES-WORD FOR SEQUENCER>
- *    <SECOND 4-BYTES-WORD FOR SEQUENCER>
- *     ...
- *    <1024th 4-BYTES-WORD FOR SEQUENCER>
- */
-static int
-spider_net_init_firmware(struct spider_net_card *card)
-{
-       struct firmware *firmware = NULL;
-       struct device_node *dn;
-       const u8 *fw_prop = NULL;
-       int err = -ENOENT;
-       int fw_size;
-
-       if (request_firmware((const struct firmware **)&firmware,
-                            SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
-               if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
-                    netif_msg_probe(card) ) {
-                       pr_err("Incorrect size of spidernet firmware in " \
-                              "filesystem. Looking in host firmware...\n");
-                       goto try_host_fw;
-               }
-               err = spider_net_download_firmware(card, firmware->data);
-
-               release_firmware(firmware);
-               if (err)
-                       goto try_host_fw;
-
-               goto done;
-       }
-
-try_host_fw:
-       dn = pci_device_to_OF_node(card->pdev);
-       if (!dn)
-               goto out_err;
-
-       fw_prop = get_property(dn, "firmware", &fw_size);
-       if (!fw_prop)
-               goto out_err;
-
-       if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
-            netif_msg_probe(card) ) {
-               pr_err("Incorrect size of spidernet firmware in " \
-                      "host firmware\n");
-               goto done;
-       }
-
-       err = spider_net_download_firmware(card, fw_prop);
-
-done:
-       return err;
-out_err:
-       if (netif_msg_probe(card))
-               pr_err("Couldn't find spidernet firmware in filesystem " \
-                      "or host firmware\n");
-       return err;
-}
-
 /**
  * spider_net_workaround_rxramfull - work around firmware bug
  * @card: card structure
@@ -2090,8 +2095,6 @@ spider_net_tx_timeout_task(struct work_struct *work)
 
        if (spider_net_setup_phy(card))
                goto out;
-       if (spider_net_init_firmware(card))
-               goto out;
 
        spider_net_open(netdev);
        spider_net_kick_tx_dma(card);
@@ -2363,10 +2366,6 @@ spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto out_undo_pci;
 
-       err = spider_net_init_firmware(card);
-       if (err)
-               goto out_undo_pci;
-
        err = spider_net_setup_netdev(card);
        if (err)
                goto out_undo_pci;