|
@@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static int tg3_request_firmware(struct tg3 *tp)
|
|
|
+{
|
|
|
+ const __be32 *fw_data;
|
|
|
+
|
|
|
+ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
|
|
|
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
|
|
|
+ tp->dev->name, tp->fw_needed);
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+
|
|
|
+ fw_data = (void *)tp->fw->data;
|
|
|
+
|
|
|
+ /* Firmware blob starts with version numbers, followed by
|
|
|
+ * start address and _full_ length including BSS sections
|
|
|
+ * (which must be longer than the actual data, of course
|
|
|
+ */
|
|
|
+
|
|
|
+ tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
|
|
|
+ if (tp->fw_len < (tp->fw->size - 12)) {
|
|
|
+ printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
|
|
|
+ tp->dev->name, tp->fw_len, tp->fw_needed);
|
|
|
+ release_firmware(tp->fw);
|
|
|
+ tp->fw = NULL;
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* We no longer need firmware; we have it. */
|
|
|
+ tp->fw_needed = NULL;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int tg3_open(struct net_device *dev)
|
|
|
{
|
|
|
struct tg3 *tp = netdev_priv(dev);
|
|
|
int err;
|
|
|
|
|
|
+ if (tp->fw_needed) {
|
|
|
+ err = tg3_request_firmware(tp);
|
|
|
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+ } else if (err) {
|
|
|
+ printk(KERN_WARNING "%s: TSO capability disabled.\n",
|
|
|
+ tp->dev->name);
|
|
|
+ tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
|
|
|
+ } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
|
|
|
+ printk(KERN_NOTICE "%s: TSO capability restored.\n",
|
|
|
+ tp->dev->name);
|
|
|
+ tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
netif_carrier_off(tp->dev);
|
|
|
|
|
|
err = tg3_set_power_state(tp, PCI_D0);
|
|
@@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|
|
struct net_device *dev;
|
|
|
struct tg3 *tp;
|
|
|
int err, pm_cap;
|
|
|
- const char *fw_name = NULL;
|
|
|
char str[40];
|
|
|
u64 dma_mask, persist_dma_mask;
|
|
|
|
|
@@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|
|
tg3_init_bufmgr_config(tp);
|
|
|
|
|
|
if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
|
|
|
- fw_name = FIRMWARE_TG3;
|
|
|
+ tp->fw_needed = FIRMWARE_TG3;
|
|
|
|
|
|
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
|
|
|
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
|
|
@@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|
|
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
|
|
|
} else {
|
|
|
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
|
|
|
- }
|
|
|
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
|
|
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
|
|
|
- fw_name = FIRMWARE_TG3TSO5;
|
|
|
+ tp->fw_needed = FIRMWARE_TG3TSO5;
|
|
|
else
|
|
|
- fw_name = FIRMWARE_TG3TSO;
|
|
|
- }
|
|
|
-
|
|
|
- if (fw_name) {
|
|
|
- const __be32 *fw_data;
|
|
|
-
|
|
|
- err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev);
|
|
|
- if (err) {
|
|
|
- printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n",
|
|
|
- fw_name);
|
|
|
- goto err_out_iounmap;
|
|
|
- }
|
|
|
-
|
|
|
- fw_data = (void *)tp->fw->data;
|
|
|
-
|
|
|
- /* Firmware blob starts with version numbers, followed by
|
|
|
- start address and _full_ length including BSS sections
|
|
|
- (which must be longer than the actual data, of course */
|
|
|
-
|
|
|
- tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
|
|
|
- if (tp->fw_len < (tp->fw->size - 12)) {
|
|
|
- printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n",
|
|
|
- tp->fw_len, fw_name);
|
|
|
- err = -EINVAL;
|
|
|
- goto err_out_fw;
|
|
|
- }
|
|
|
+ tp->fw_needed = FIRMWARE_TG3TSO;
|
|
|
}
|
|
|
|
|
|
/* TSO is on by default on chips that support hardware TSO.
|