Mesh forwarding is always on. Therefore, disabling radio when interface in not up will disable mesh forwarding as well. Have you thought of this? Thanks -Ashish
> -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dan > Williams > Sent: Wednesday, November 21, 2007 9:48 AM > To: [EMAIL PROTECTED] > Cc: Brajesh Dave; Andres Salomon > Subject: [RFC PATCH] libertas: turn radio off when down > > Backport of a patch to olpc-2.6 I'm going to post to linux-wireless. > When both interfaces are down (~IFF_UP), turn off the radio to save > power. When either interface is opened (via iwconfig up or otherwise) > turn the radio back on unless the radio was explicitly disabled by the > user via 'iwconfig txpower off' which also is the previous behavior > without this patch. > > This should allow NetworkManager to be told to go to sleep, at which > point it will mark all devices down, and with this patch should turn off > the radio and save power. > > It also cleans up some of the mess that was *_open, the intent for which > (unless I'm reading that code wrong) was just to check whether the > interface was up or not, since that's what open/close do. > > Comments? > > Signed-off-by: Dan Williams <[EMAIL PROTECTED]> > > diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c > index caf0b1c..5a15b56 100644 > --- a/drivers/net/wireless/libertas/cmd.c > +++ b/drivers/net/wireless/libertas/cmd.c > @@ -479,6 +479,8 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, > return 0; > } > > +#define TURN_ON_RF 0x01 > + > static int wlan_cmd_802_11_radio_control(wlan_private * priv, > struct cmd_ds_command *cmd, > int cmd_action) > @@ -510,7 +512,7 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv, > break; > } > > - if (adapter->radioon) > + if (adapter->radio_on) > pradiocontrol->control |= cpu_to_le16(TURN_ON_RF); > else > pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF); > @@ -1112,7 +1114,7 @@ int libertas_set_radio_control(wlan_private * priv) > CMD_OPTION_WAITFORRSP, 0, NULL); > > lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", > - priv->adapter->radioon, priv->adapter->preamble); > + priv->adapter->radio_on, priv->adapter->preamble); > > lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); > return ret; > diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c > index d391391..433d481 100644 > --- a/drivers/net/wireless/libertas/cmdresp.c > +++ b/drivers/net/wireless/libertas/cmdresp.c > @@ -991,7 +991,7 @@ int libertas_process_event(wlan_private * priv) > } > lbs_pr_info("EVENT: MESH_AUTO_STARTED\n"); > adapter->mesh_connect_status = LIBERTAS_CONNECTED; > - if (priv->mesh_open == 1) { > + if (priv->mesh_dev->flags & IFF_UP) { > netif_wake_queue(priv->mesh_dev); > netif_carrier_on(priv->mesh_dev); > } > diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h > index 404ca50..62c3e75 100644 > --- a/drivers/net/wireless/libertas/dev.h > +++ b/drivers/net/wireless/libertas/dev.h > @@ -100,9 +100,6 @@ struct wlan_mesh_stats { > > /** Private structure for the MV device */ > struct _wlan_private { > - int open; > - int mesh_open; > - int infra_open; > int mesh_autostart_enabled; > __le16 boot2_version; > > @@ -339,7 +336,8 @@ struct _wlan_adapter { > u16 nextSNRNF; > u16 numSNRNF; > > - u8 radioon; > + u8 user_radio_on; > + u8 radio_on; > u32 preamble; > > /** data rate stuff */ > diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h > index 00d5675..eb516be 100644 > --- a/drivers/net/wireless/libertas/host.h > +++ b/drivers/net/wireless/libertas/host.h > @@ -183,10 +183,6 @@ > #define CMD_TYPE_SHORT_PREAMBLE 0x0002 > #define CMD_TYPE_LONG_PREAMBLE 0x0003 > > -#define TURN_ON_RF 0x01 > -#define RADIO_ON 0x01 > -#define RADIO_OFF 0x00 > - > #define SET_AUTO_PREAMBLE 0x05 > #define SET_SHORT_PREAMBLE 0x03 > #define SET_LONG_PREAMBLE 0x01 > diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c > index 2b104d2..f07d5b4 100644 > --- a/drivers/net/wireless/libertas/main.c > +++ b/drivers/net/wireless/libertas/main.c > @@ -11,7 +11,9 @@ > #include <linux/netdevice.h> > #include <linux/if_arp.h> > #include <linux/kthread.h> > +#if CONFIG_OLPC > #include <asm/olpc.h> > +#endif > > #include <net/iw_handler.h> > #include <net/ieee80211.h> > @@ -406,8 +408,6 @@ static int libertas_dev_open(struct net_device *dev) > > lbs_deb_enter(LBS_DEB_NET); > > - priv->open = 1; > - > if (adapter->connect_status == LIBERTAS_CONNECTED) { > netif_carrier_on(priv->dev); > } > @@ -433,20 +433,33 @@ static int libertas_dev_open(struct net_device *dev) > */ > static int libertas_mesh_open(struct net_device *dev) > { > - wlan_private *priv = (wlan_private *) dev->priv ; > + wlan_private *priv = (wlan_private *) dev->priv; > + int ret = -1; > + > + lbs_deb_enter(LBS_DEB_NET); > > if (pre_open_check(dev) == -1) > - return -1; > - priv->mesh_open = 1 ; > + goto out; > + > + /* Turn the radio on unless it was turned off by the user */ > + if (priv->adapter->user_radio_on) > + libertas_set_radio_on (priv, 1); > + > netif_wake_queue(priv->mesh_dev); > > - priv->adapter->mesh_connect_status = LIBERTAS_CONNECTED; > + priv->adapter->mesh_connect_status = LIBERTAS_CONNECTED; > > netif_carrier_on(priv->mesh_dev); > netif_wake_queue(priv->mesh_dev); > - if (priv->infra_open == 0) > - return libertas_dev_open(priv->dev) ; > - return 0; > + > + if (!(priv->dev->flags & IFF_UP)) > + ret = libertas_dev_open(priv->dev); > + else > + ret = 0; > + > +out: > + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); > + return ret; > } > > /** > @@ -457,15 +470,28 @@ static int libertas_mesh_open(struct net_device *dev) > */ > static int libertas_open(struct net_device *dev) > { > - wlan_private *priv = (wlan_private *) dev->priv ; > + wlan_private *priv = (wlan_private *) dev->priv; > + int ret = -1; > + > + lbs_deb_enter(LBS_DEB_NET); > + > + if (pre_open_check(dev) == -1) > + goto out; > + > + /* Turn the radio on unless it was turned off by the user */ > + if (priv->adapter->user_radio_on) > + libertas_set_radio_on (priv, 1); > > - if(pre_open_check(dev) == -1) > - return -1; > - priv->infra_open = 1 ; > netif_wake_queue(priv->dev); > - if (priv->open == 0) > - return libertas_dev_open(priv->dev) ; > - return 0; > + > + if (!(priv->mesh_dev->flags & IFF_UP)) > + ret = libertas_dev_open(priv->dev); > + else > + ret = 0; > + > +out: > + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); > + return ret; > } > > static int libertas_dev_close(struct net_device *dev) > @@ -475,7 +501,6 @@ static int libertas_dev_close(struct net_device *dev) > lbs_deb_enter(LBS_DEB_NET); > > netif_carrier_off(priv->dev); > - priv->open = 0; > > lbs_deb_leave(LBS_DEB_NET); > return 0; > @@ -491,12 +516,15 @@ static int libertas_mesh_close(struct net_device *dev) > { > wlan_private *priv = (wlan_private *) (dev->priv); > > - priv->mesh_open = 0; > netif_stop_queue(priv->mesh_dev); > - if (priv->infra_open == 0) > + if (!(priv->dev->flags & IFF_UP)) { > + /* Turn the radio off if neither interface is up */ > + libertas_set_radio_on (priv, 0); > + > return libertas_dev_close(dev); > - else > - return 0; > + } > + > + return 0; > } > > /** > @@ -510,11 +538,14 @@ static int libertas_close(struct net_device *dev) > wlan_private *priv = (wlan_private *) dev->priv; > > netif_stop_queue(dev); > - priv->infra_open = 0; > - if (priv->mesh_open == 0) > + if (!(priv->mesh_dev->flags & IFF_UP)) { > + /* Turn the radio off if neither interface is up */ > + libertas_set_radio_on (priv, 0); > + > return libertas_dev_close(dev); > - else > - return 0; > + } > + > + return 0; > } > > > @@ -1148,7 +1179,8 @@ static void wlan_init_adapter(wlan_private * priv) > adapter->currentpacketfilter = > CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; > > - adapter->radioon = RADIO_ON; > + adapter->radio_on = 1; > + adapter->user_radio_on = adapter->radio_on; > > adapter->auto_rate = 1; > adapter->cur_rate = 0; > @@ -1234,8 +1266,6 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) > > priv->dev = dev; > priv->card = card; > - priv->mesh_open = 0; > - priv->infra_open = 0; > > SET_MODULE_OWNER(dev); > > diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c > index 11f9389..61b31fa 100644 > --- a/drivers/net/wireless/libertas/wext.c > +++ b/drivers/net/wireless/libertas/wext.c > @@ -111,16 +111,18 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * > adapter, > * @option Radio Option > * @return 0 --success, otherwise fail > */ > -static int wlan_radio_ioctl(wlan_private * priv, u8 option) > +int libertas_set_radio_on(wlan_private * priv, u8 on) > { > int ret = 0; > wlan_adapter *adapter = priv->adapter; > > + on = on ? 0x01 : 0x00; > + > lbs_deb_enter(LBS_DEB_WEXT); > > - if (adapter->radioon != option) { > - lbs_deb_wext("switching radio %s\n", option ? "on" : "off"); > - adapter->radioon = option; > + if (adapter->radio_on != on) { > + lbs_deb_wext("turning radio %s\n", on ? "on" : "off"); > + adapter->radio_on = on; > > ret = libertas_prepare_and_send_command(priv, > CMD_802_11_RADIO_CONTROL, > @@ -451,7 +453,7 @@ static int wlan_get_txpow(struct net_device *dev, > lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel); > vwrq->value = adapter->txpowerlevel; > vwrq->fixed = 1; > - if (adapter->radioon) { > + if (adapter->radio_on) { > vwrq->disabled = 0; > vwrq->flags = IW_TXPOW_DBM; > } else { > @@ -1885,19 +1887,20 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info > *info, > int ret = 0; > wlan_private *priv = dev->priv; > wlan_adapter *adapter = priv->adapter; > - > u16 dbm; > > lbs_deb_enter(LBS_DEB_WEXT); > > if (vwrq->disabled) { > - wlan_radio_ioctl(priv, RADIO_OFF); > + adapter->user_radio_on = 0; > + libertas_set_radio_on(priv, 0); > return 0; > } > > adapter->preamble = CMD_TYPE_AUTO_PREAMBLE; > + adapter->user_radio_on = 1; > > - wlan_radio_ioctl(priv, RADIO_ON); > + libertas_set_radio_on(priv, 1); > > /* Userspace check in iwrange if it should use dBm or mW, > * therefore this should never happen... Jean II */ > diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h > index e93853b..d01c54a 100644 > --- a/drivers/net/wireless/libertas/wext.h > +++ b/drivers/net/wireless/libertas/wext.h > @@ -67,5 +67,6 @@ struct wlan_ioctl_regrdwr { > extern struct iw_handler_def libertas_handler_def; > extern struct iw_handler_def mesh_handler_def; > int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); > +int libertas_set_radio_on(wlan_private * priv, u8 on); > > #endif /* _WLAN_WEXT_H_ */ > > _______________________________________________ > Devel mailing list > Devel@lists.laptop.org > http://lists.laptop.org/listinfo/devel _______________________________________________ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel