Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202739
b: refs/heads/master
c: 66fceb6
h: refs/heads/master
i:
  202737: a4bcd63
  202735: 83c83b5
v: v3
  • Loading branch information
Amitkumar Karwar authored and John W. Linville committed Jun 2, 2010
1 parent 90a8398 commit 1bf6017
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a7da74fc88bff6f82f8255f2def49907f82f4c61
refs/heads/master: 66fceb69b72ff7e9cd8da2ca70033982d5376e0e
37 changes: 32 additions & 5 deletions trunk/drivers/net/wireless/libertas/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ static u8 is_command_allowed_in_ps(u16 cmd)
switch (cmd) {
case CMD_802_11_RSSI:
return 1;
case CMD_802_11_HOST_SLEEP_CFG:
return 1;
default:
break;
}
Expand Down Expand Up @@ -185,6 +187,23 @@ int lbs_update_hw_spec(struct lbs_private *priv)
return ret;
}

static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
struct cmd_header *resp)
{
lbs_deb_enter(LBS_DEB_CMD);
if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
priv->is_host_sleep_configured = 0;
if (priv->psstate == PS_STATE_FULL_POWER) {
priv->is_host_sleep_activated = 0;
wake_up_interruptible(&priv->host_sleep_q);
}
} else {
priv->is_host_sleep_configured = 1;
}
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}

int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
struct wol_config *p_wol_config)
{
Expand All @@ -202,12 +221,11 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
else
cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;

ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
le16_to_cpu(cmd_config.hdr.size),
lbs_ret_host_sleep_cfg, 0);
if (!ret) {
if (criteria) {
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
priv->wol_criteria = criteria;
} else
if (p_wol_config)
memcpy((uint8_t *) p_wol_config,
(uint8_t *)&cmd_config.wol_conf,
sizeof(struct wol_config));
Expand Down Expand Up @@ -712,6 +730,10 @@ static void lbs_queue_cmd(struct lbs_private *priv,
}
}

if (le16_to_cpu(cmdnode->cmdbuf->command) ==
CMD_802_11_WAKEUP_CONFIRM)
addtail = 0;

spin_lock_irqsave(&priv->driver_lock, flags);

if (addtail)
Expand Down Expand Up @@ -1353,6 +1375,11 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
/* We don't get a response on the sleep-confirmation */
priv->dnld_sent = DNLD_RES_RECEIVED;

if (priv->is_host_sleep_configured) {
priv->is_host_sleep_activated = 1;
wake_up_interruptible(&priv->host_sleep_q);
}

/* If nothing to do, go back to sleep (?) */
if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
priv->psstate = PS_STATE_SLEEP;
Expand Down
30 changes: 6 additions & 24 deletions trunk/drivers/net/wireless/libertas/cmdresp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "dev.h"
#include "assoc.h"
#include "wext.h"
#include "cmd.h"

/**
* @brief This function handles disconnect event. it
Expand Down Expand Up @@ -341,32 +342,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
return ret;
}

static int lbs_send_confirmwake(struct lbs_private *priv)
{
struct cmd_header cmd;
int ret = 0;

lbs_deb_enter(LBS_DEB_HOST);

cmd.command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
cmd.size = cpu_to_le16(sizeof(cmd));
cmd.seqnum = cpu_to_le16(++priv->seqnum);
cmd.result = 0;

lbs_deb_hex(LBS_DEB_HOST, "wake confirm", (u8 *) &cmd,
sizeof(cmd));

ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &cmd, sizeof(cmd));
if (ret)
lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");

lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
return ret;
}

int lbs_process_event(struct lbs_private *priv, u32 event)
{
int ret = 0;
struct cmd_header cmd;

lbs_deb_enter(LBS_DEB_CMD);

Expand Down Expand Up @@ -410,7 +389,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
if (priv->reset_deep_sleep_wakeup)
priv->reset_deep_sleep_wakeup(priv);
priv->is_deep_sleep = 0;
lbs_send_confirmwake(priv);
lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
sizeof(cmd));
priv->is_host_sleep_activated = 0;
wake_up_interruptible(&priv->host_sleep_q);
break;

case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/libertas/decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ int lbs_set_mac_address(struct net_device *dev, void *addr);
void lbs_set_multicast_list(struct net_device *dev);

int lbs_suspend(struct lbs_private *priv);
void lbs_resume(struct lbs_private *priv);
int lbs_resume(struct lbs_private *priv);

void lbs_queue_event(struct lbs_private *priv, u32 event);
void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/libertas/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,19 @@ struct lbs_private {

/* Deep sleep */
int is_deep_sleep;
int deep_sleep_required;
int is_auto_deep_sleep_enabled;
int wakeup_dev_required;
int is_activity_detected;
int auto_deep_sleep_timeout; /* in ms */
wait_queue_head_t ds_awake_q;
struct timer_list auto_deepsleep_timer;

/* Host sleep*/
int is_host_sleep_configured;
int is_host_sleep_activated;
wait_queue_head_t host_sleep_q;

/* Hardware access */
void *card;
u8 fw_ready;
Expand Down
15 changes: 7 additions & 8 deletions trunk/drivers/net/wireless/libertas/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,22 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0;

if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
return -EOPNOTSUPP;

priv->wol_criteria = 0;
if (wol->wolopts & WAKE_UCAST)
criteria |= EHS_WAKE_ON_UNICAST_DATA;
priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA;
if (wol->wolopts & WAKE_MCAST)
criteria |= EHS_WAKE_ON_MULTICAST_DATA;
priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA;
if (wol->wolopts & WAKE_BCAST)
criteria |= EHS_WAKE_ON_BROADCAST_DATA;
priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA;
if (wol->wolopts & WAKE_PHY)
criteria |= EHS_WAKE_ON_MAC_EVENT;
priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT;
if (wol->wolopts == 0)
criteria |= EHS_REMOVE_WAKEUP;

return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
priv->wol_criteria |= EHS_REMOVE_WAKEUP;
return 0;
}

const struct ethtool_ops lbs_ethtool_ops = {
Expand Down
58 changes: 58 additions & 0 deletions trunk/drivers/net/wireless/libertas/if_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,11 +1182,69 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_deb_leave(LBS_DEB_SDIO);
}

static int if_sdio_suspend(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
int ret;
struct if_sdio_card *card = sdio_get_drvdata(func);

mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);

lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
sdio_func_id(func), flags);

/* If we aren't being asked to wake on anything, we should bail out
* and let the SD stack power down the card.
*/
if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
lbs_pr_info("Suspend without wake params -- "
"powering down card.");
return -ENOSYS;
}

if (!(flags & MMC_PM_KEEP_POWER)) {
lbs_pr_err("%s: cannot remain alive while host is suspended\n",
sdio_func_id(func));
return -ENOSYS;
}

ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
if (ret)
return ret;

ret = lbs_suspend(card->priv);
if (ret)
return ret;

return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
}

static int if_sdio_resume(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
struct if_sdio_card *card = sdio_get_drvdata(func);
int ret;

lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));

ret = lbs_resume(card->priv);

return ret;
}

static const struct dev_pm_ops if_sdio_pm_ops = {
.suspend = if_sdio_suspend,
.resume = if_sdio_resume,
};

static struct sdio_driver if_sdio_driver = {
.name = "libertas_sdio",
.id_table = if_sdio_ids,
.probe = if_sdio_probe,
.remove = if_sdio_remove,
.drv = {
.pm = &if_sdio_pm_ops,
},
};

/*******************************************************************/
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/libertas/if_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,12 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (priv->psstate != PS_STATE_FULL_POWER)
return -1;

if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
lbs_pr_info("Suspend attempt without "
"configuring wake params!\n");
return -ENOSYS;
}

ret = lbs_suspend(priv);
if (ret)
goto out;
Expand Down
Loading

0 comments on commit 1bf6017

Please sign in to comment.