libertas: Prepare stuff for if_spi.c pm support

To support suspend/resume in if_spi we need two things:
- re-setup fw in lbs_resume(), because if_spi powercycles card;
- don't touch hwaddr on second lbs_update_hw_spec() call for same
  reason;

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Vasily Khoruzhick 2011-01-21 22:44:49 +02:00 committed by John W. Linville
parent 16f775befc
commit 75abde4d19
3 changed files with 49 additions and 40 deletions

View File

@ -145,9 +145,13 @@ int lbs_update_hw_spec(struct lbs_private *priv)
if (priv->current_addr[0] == 0xff)
memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
if (priv->mesh_dev)
memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
if (!priv->copied_hwaddr) {
memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
if (priv->mesh_dev)
memcpy(priv->mesh_dev->dev_addr,
priv->current_addr, ETH_ALEN);
priv->copied_hwaddr = 1;
}
out:
lbs_deb_leave(LBS_DEB_CMD);

View File

@ -90,6 +90,7 @@ struct lbs_private {
void *card;
u8 fw_ready;
u8 surpriseremoved;
u8 setup_fw_on_resume;
int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
void (*reset_card) (struct lbs_private *priv);
int (*enter_deep_sleep) (struct lbs_private *priv);
@ -101,6 +102,7 @@ struct lbs_private {
u32 fwcapinfo;
u16 regioncode;
u8 current_addr[ETH_ALEN];
u8 copied_hwaddr;
/* Command download */
u8 dnld_sent;

View File

@ -539,6 +539,43 @@ static int lbs_thread(void *data)
return 0;
}
/**
* @brief This function gets the HW spec from the firmware and sets
* some basic parameters.
*
* @param priv A pointer to struct lbs_private structure
* @return 0 or -1
*/
static int lbs_setup_firmware(struct lbs_private *priv)
{
int ret = -1;
s16 curlevel = 0, minlevel = 0, maxlevel = 0;
lbs_deb_enter(LBS_DEB_FW);
/* Read MAC address from firmware */
memset(priv->current_addr, 0xff, ETH_ALEN);
ret = lbs_update_hw_spec(priv);
if (ret)
goto done;
/* Read power levels if available */
ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
if (ret == 0) {
priv->txpower_cur = curlevel;
priv->txpower_min = minlevel;
priv->txpower_max = maxlevel;
}
/* Send cmd to FW to enable 11D function */
ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
lbs_set_mac_control(priv);
done:
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
int lbs_suspend(struct lbs_private *priv)
{
int ret;
@ -584,48 +621,14 @@ int lbs_resume(struct lbs_private *priv)
lbs_pr_err("deep sleep activation failed: %d\n", ret);
}
if (priv->setup_fw_on_resume)
ret = lbs_setup_firmware(priv);
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
EXPORT_SYMBOL_GPL(lbs_resume);
/**
* @brief This function gets the HW spec from the firmware and sets
* some basic parameters.
*
* @param priv A pointer to struct lbs_private structure
* @return 0 or -1
*/
static int lbs_setup_firmware(struct lbs_private *priv)
{
int ret = -1;
s16 curlevel = 0, minlevel = 0, maxlevel = 0;
lbs_deb_enter(LBS_DEB_FW);
/* Read MAC address from firmware */
memset(priv->current_addr, 0xff, ETH_ALEN);
ret = lbs_update_hw_spec(priv);
if (ret)
goto done;
/* Read power levels if available */
ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
if (ret == 0) {
priv->txpower_cur = curlevel;
priv->txpower_min = minlevel;
priv->txpower_max = maxlevel;
}
/* Send cmd to FW to enable 11D function */
ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
lbs_set_mac_control(priv);
done:
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
/**
* This function handles the timeout of command sending.
* It will re-send the same command again.