Commit 3c34a5d8 authored by Dan Williams's avatar Dan Williams Committed by John W. Linville

atmel: return ENOENT on request_firmware failure

Return errors from request_firmware() (like other drivers that do
firmware load on device open) and make up plausible codes for other
error conditions. Gives userspace tools like NetworkManager a clue that
firmware may be missing when the result of setting IFF_UP is ENOENT.
Signed-off-by: default avatarDan Williams <dcbw@redhat.com>

v2: fix reversed check of atmel_wakeup_firmware() in probe_atmel_card()
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c2d42545
...@@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(atmel_open); ...@@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(atmel_open);
int atmel_open(struct net_device *dev) int atmel_open(struct net_device *dev)
{ {
struct atmel_private *priv = netdev_priv(dev); struct atmel_private *priv = netdev_priv(dev);
int i, channel; int i, channel, err;
/* any scheduled timer is no longer needed and might screw things up.. */ /* any scheduled timer is no longer needed and might screw things up.. */
del_timer_sync(&priv->management_timer); del_timer_sync(&priv->management_timer);
...@@ -1328,8 +1328,9 @@ int atmel_open(struct net_device *dev) ...@@ -1328,8 +1328,9 @@ int atmel_open(struct net_device *dev)
priv->site_survey_state = SITE_SURVEY_IDLE; priv->site_survey_state = SITE_SURVEY_IDLE;
priv->station_is_associated = 0; priv->station_is_associated = 0;
if (!reset_atmel_card(dev)) err = reset_atmel_card(dev);
return -EAGAIN; if (err)
return err;
if (priv->config_reg_domain) { if (priv->config_reg_domain) {
priv->reg_domain = priv->config_reg_domain; priv->reg_domain = priv->config_reg_domain;
...@@ -3580,12 +3581,12 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) ...@@ -3580,12 +3581,12 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
if (i == 0) { if (i == 0) {
printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
return 0; return -EIO;
} }
if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
return 0; return -ENODEV;
} }
/* now check for completion of MAC initialization through /* now check for completion of MAC initialization through
...@@ -3609,19 +3610,19 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) ...@@ -3609,19 +3610,19 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
if (i == 0) { if (i == 0) {
printk(KERN_ALERT "%s: MAC failed to initialise.\n", printk(KERN_ALERT "%s: MAC failed to initialise.\n",
priv->dev->name); priv->dev->name);
return 0; return -EIO;
} }
/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
if ((mr3 & MAC_INIT_COMPLETE) && if ((mr3 & MAC_INIT_COMPLETE) &&
!(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
return 0; return -EIO;
} }
if ((mr1 & MAC_INIT_COMPLETE) && if ((mr1 & MAC_INIT_COMPLETE) &&
!(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
return 0; return -EIO;
} }
atmel_copy_to_host(priv->dev, (unsigned char *)iface, atmel_copy_to_host(priv->dev, (unsigned char *)iface,
...@@ -3642,7 +3643,7 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) ...@@ -3642,7 +3643,7 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
iface->func_ctrl = le16_to_cpu(iface->func_ctrl); iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
iface->mac_status = le16_to_cpu(iface->mac_status); iface->mac_status = le16_to_cpu(iface->mac_status);
return 1; return 0;
} }
/* determine type of memory and MAC address */ /* determine type of memory and MAC address */
...@@ -3693,7 +3694,7 @@ static int probe_atmel_card(struct net_device *dev) ...@@ -3693,7 +3694,7 @@ static int probe_atmel_card(struct net_device *dev)
/* Standard firmware in flash, boot it up and ask /* Standard firmware in flash, boot it up and ask
for the Mac Address */ for the Mac Address */
priv->card_type = CARD_TYPE_SPI_FLASH; priv->card_type = CARD_TYPE_SPI_FLASH;
if (atmel_wakeup_firmware(priv)) { if (atmel_wakeup_firmware(priv) == 0) {
atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
/* got address, now squash it again until the network /* got address, now squash it again until the network
...@@ -3835,6 +3836,7 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3835,6 +3836,7 @@ static int reset_atmel_card(struct net_device *dev)
struct atmel_private *priv = netdev_priv(dev); struct atmel_private *priv = netdev_priv(dev);
u8 configuration; u8 configuration;
int old_state = priv->station_state; int old_state = priv->station_state;
int err = 0;
/* data to add to the firmware names, in priority order /* data to add to the firmware names, in priority order
this implemenents firmware versioning */ this implemenents firmware versioning */
...@@ -3868,11 +3870,12 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3868,11 +3870,12 @@ static int reset_atmel_card(struct net_device *dev)
dev->name); dev->name);
strcpy(priv->firmware_id, "atmel_at76c502.bin"); strcpy(priv->firmware_id, "atmel_at76c502.bin");
} }
if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) { err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
if (err != 0) {
printk(KERN_ALERT printk(KERN_ALERT
"%s: firmware %s is missing, cannot continue.\n", "%s: firmware %s is missing, cannot continue.\n",
dev->name, priv->firmware_id); dev->name, priv->firmware_id);
return 0; return err;
} }
} else { } else {
int fw_index = 0; int fw_index = 0;
...@@ -3901,7 +3904,7 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3901,7 +3904,7 @@ static int reset_atmel_card(struct net_device *dev)
"%s: firmware %s is missing, cannot start.\n", "%s: firmware %s is missing, cannot start.\n",
dev->name, priv->firmware_id); dev->name, priv->firmware_id);
priv->firmware_id[0] = '\0'; priv->firmware_id[0] = '\0';
return 0; return -ENOENT;
} }
} }
...@@ -3926,8 +3929,9 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3926,8 +3929,9 @@ static int reset_atmel_card(struct net_device *dev)
release_firmware(fw_entry); release_firmware(fw_entry);
} }
if (!atmel_wakeup_firmware(priv)) err = atmel_wakeup_firmware(priv);
return 0; if (err != 0)
return err;
/* Check the version and set the correct flag for wpa stuff, /* Check the version and set the correct flag for wpa stuff,
old and new firmware is incompatible. old and new firmware is incompatible.
...@@ -3968,10 +3972,9 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3968,10 +3972,9 @@ static int reset_atmel_card(struct net_device *dev)
if (!priv->radio_on_broken) { if (!priv->radio_on_broken) {
if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
CMD_STATUS_REJECTED_RADIO_OFF) { CMD_STATUS_REJECTED_RADIO_OFF) {
printk(KERN_INFO printk(KERN_INFO "%s: cannot turn the radio on.\n",
"%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
dev->name); dev->name);
return 0; return -EIO;
} }
} }
...@@ -4006,7 +4009,7 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -4006,7 +4009,7 @@ static int reset_atmel_card(struct net_device *dev)
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
} }
return 1; return 0;
} }
static void atmel_send_command(struct atmel_private *priv, int command, static void atmel_send_command(struct atmel_private *priv, int command,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment