diff options
Diffstat (limited to 'drivers/net/tg3.c')
| -rw-r--r-- | drivers/net/tg3.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5e2dbaee125b..8b3f84685387 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp) | |||
| 7535 | return err; | 7535 | return err; |
| 7536 | } | 7536 | } |
| 7537 | 7537 | ||
| 7538 | static int tg3_request_firmware(struct tg3 *tp) | ||
| 7539 | { | ||
| 7540 | const __be32 *fw_data; | ||
| 7541 | |||
| 7542 | if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { | ||
| 7543 | printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", | ||
| 7544 | tp->dev->name, tp->fw_needed); | ||
| 7545 | return -ENOENT; | ||
| 7546 | } | ||
| 7547 | |||
| 7548 | fw_data = (void *)tp->fw->data; | ||
| 7549 | |||
| 7550 | /* Firmware blob starts with version numbers, followed by | ||
| 7551 | * start address and _full_ length including BSS sections | ||
| 7552 | * (which must be longer than the actual data, of course | ||
| 7553 | */ | ||
| 7554 | |||
| 7555 | tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ | ||
| 7556 | if (tp->fw_len < (tp->fw->size - 12)) { | ||
| 7557 | printk(KERN_ERR "%s: bogus length %d in \"%s\"\n", | ||
| 7558 | tp->dev->name, tp->fw_len, tp->fw_needed); | ||
| 7559 | release_firmware(tp->fw); | ||
| 7560 | tp->fw = NULL; | ||
| 7561 | return -EINVAL; | ||
| 7562 | } | ||
| 7563 | |||
| 7564 | /* We no longer need firmware; we have it. */ | ||
| 7565 | tp->fw_needed = NULL; | ||
| 7566 | return 0; | ||
| 7567 | } | ||
| 7568 | |||
| 7538 | static int tg3_open(struct net_device *dev) | 7569 | static int tg3_open(struct net_device *dev) |
| 7539 | { | 7570 | { |
| 7540 | struct tg3 *tp = netdev_priv(dev); | 7571 | struct tg3 *tp = netdev_priv(dev); |
| 7541 | int err; | 7572 | int err; |
| 7542 | 7573 | ||
| 7574 | if (tp->fw_needed) { | ||
| 7575 | err = tg3_request_firmware(tp); | ||
| 7576 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) { | ||
| 7577 | if (err) | ||
| 7578 | return err; | ||
| 7579 | } else if (err) { | ||
| 7580 | printk(KERN_WARNING "%s: TSO capability disabled.\n", | ||
| 7581 | tp->dev->name); | ||
| 7582 | tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; | ||
| 7583 | } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { | ||
| 7584 | printk(KERN_NOTICE "%s: TSO capability restored.\n", | ||
| 7585 | tp->dev->name); | ||
| 7586 | tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; | ||
| 7587 | } | ||
| 7588 | } | ||
| 7589 | |||
| 7543 | netif_carrier_off(tp->dev); | 7590 | netif_carrier_off(tp->dev); |
| 7544 | 7591 | ||
| 7545 | err = tg3_set_power_state(tp, PCI_D0); | 7592 | err = tg3_set_power_state(tp, PCI_D0); |
| @@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 12934 | struct net_device *dev; | 12981 | struct net_device *dev; |
| 12935 | struct tg3 *tp; | 12982 | struct tg3 *tp; |
| 12936 | int err, pm_cap; | 12983 | int err, pm_cap; |
| 12937 | const char *fw_name = NULL; | ||
| 12938 | char str[40]; | 12984 | char str[40]; |
| 12939 | u64 dma_mask, persist_dma_mask; | 12985 | u64 dma_mask, persist_dma_mask; |
| 12940 | 12986 | ||
| @@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 13091 | tg3_init_bufmgr_config(tp); | 13137 | tg3_init_bufmgr_config(tp); |
| 13092 | 13138 | ||
| 13093 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) | 13139 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) |
| 13094 | fw_name = FIRMWARE_TG3; | 13140 | tp->fw_needed = FIRMWARE_TG3; |
| 13095 | 13141 | ||
| 13096 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { | 13142 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { |
| 13097 | tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; | 13143 | tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; |
| @@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 13104 | tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; | 13150 | tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; |
| 13105 | } else { | 13151 | } else { |
| 13106 | tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; | 13152 | tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; |
| 13107 | } | ||
| 13108 | if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { | ||
| 13109 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) | 13153 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) |
| 13110 | fw_name = FIRMWARE_TG3TSO5; | 13154 | tp->fw_needed = FIRMWARE_TG3TSO5; |
| 13111 | else | 13155 | else |
| 13112 | fw_name = FIRMWARE_TG3TSO; | 13156 | tp->fw_needed = FIRMWARE_TG3TSO; |
| 13113 | } | ||
| 13114 | |||
| 13115 | if (fw_name) { | ||
| 13116 | const __be32 *fw_data; | ||
| 13117 | |||
| 13118 | err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev); | ||
| 13119 | if (err) { | ||
| 13120 | printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n", | ||
| 13121 | fw_name); | ||
| 13122 | goto err_out_iounmap; | ||
| 13123 | } | ||
| 13124 | |||
| 13125 | fw_data = (void *)tp->fw->data; | ||
| 13126 | |||
| 13127 | /* Firmware blob starts with version numbers, followed by | ||
| 13128 | start address and _full_ length including BSS sections | ||
| 13129 | (which must be longer than the actual data, of course */ | ||
| 13130 | |||
| 13131 | tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ | ||
| 13132 | if (tp->fw_len < (tp->fw->size - 12)) { | ||
| 13133 | printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n", | ||
| 13134 | tp->fw_len, fw_name); | ||
| 13135 | err = -EINVAL; | ||
| 13136 | goto err_out_fw; | ||
| 13137 | } | ||
| 13138 | } | 13157 | } |
| 13139 | 13158 | ||
| 13140 | /* TSO is on by default on chips that support hardware TSO. | 13159 | /* TSO is on by default on chips that support hardware TSO. |
