All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit e8e1594c authored by David Vrabel's avatar David Vrabel

wlp: start/stop radio on network interface up/down

Signed-off-by: default avatarDavid Vrabel <david.vrabel@csr.com>
parent 6fae35f9
......@@ -206,7 +206,7 @@ int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
wlp->fill_device_info = i1480u_fill_device_info;
wlp->stop_queue = i1480u_stop_queue;
wlp->start_queue = i1480u_start_queue;
result = wlp_setup(wlp, rc);
result = wlp_setup(wlp, rc, net_dev);
if (result < 0) {
dev_err(&iface->dev, "Cannot setup WLP\n");
goto error_wlp_setup;
......
......@@ -207,6 +207,11 @@ int i1480u_open(struct net_device *net_dev)
result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */
if (result < 0)
goto error_rx_setup;
result = uwb_radio_start(&wlp->pal);
if (result < 0)
goto error_radio_start;
netif_wake_queue(net_dev);
#ifdef i1480u_FLOW_CONTROL
result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);;
......@@ -215,25 +220,20 @@ int i1480u_open(struct net_device *net_dev)
goto error_notif_urb_submit;
}
#endif
i1480u->uwb_notifs_handler.cb = i1480u_uwb_notifs_cb;
i1480u->uwb_notifs_handler.data = i1480u;
if (uwb_bg_joined(rc))
netif_carrier_on(net_dev);
else
netif_carrier_off(net_dev);
uwb_notifs_register(rc, &i1480u->uwb_notifs_handler);
/* Interface is up with an address, now we can create WSS */
result = wlp_wss_setup(net_dev, &wlp->wss);
if (result < 0) {
dev_err(dev, "Can't create WSS: %d. \n", result);
goto error_notif_deregister;
goto error_wss_setup;
}
return 0;
error_notif_deregister:
uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
error_wss_setup:
#ifdef i1480u_FLOW_CONTROL
usb_kill_urb(i1480u->notif_urb);
error_notif_urb_submit:
#endif
uwb_radio_stop(&wlp->pal);
error_radio_start:
netif_stop_queue(net_dev);
i1480u_rx_release(i1480u);
error_rx_setup:
......@@ -248,16 +248,15 @@ int i1480u_stop(struct net_device *net_dev)
{
struct i1480u *i1480u = netdev_priv(net_dev);
struct wlp *wlp = &i1480u->wlp;
struct uwb_rc *rc = wlp->rc;
BUG_ON(wlp->rc == NULL);
wlp_wss_remove(&wlp->wss);
uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
netif_carrier_off(net_dev);
#ifdef i1480u_FLOW_CONTROL
usb_kill_urb(i1480u->notif_urb);
#endif
netif_stop_queue(net_dev);
uwb_radio_stop(&wlp->pal);
i1480u_rx_release(i1480u);
i1480u_tx_release(i1480u);
return 0;
......@@ -303,34 +302,6 @@ int i1480u_change_mtu(struct net_device *net_dev, int mtu)
return 0;
}
/**
* Callback function to handle events from UWB
* When we see other devices we know the carrier is ok,
* if we are the only device in the beacon group we set the carrier
* state to off.
* */
void i1480u_uwb_notifs_cb(void *data, struct uwb_dev *uwb_dev,
enum uwb_notifs event)
{
struct i1480u *i1480u = data;
struct net_device *net_dev = i1480u->net_dev;
struct device *dev = &i1480u->usb_iface->dev;
switch (event) {
case UWB_NOTIF_BG_JOIN:
netif_carrier_on(net_dev);
dev_info(dev, "Link is up\n");
break;
case UWB_NOTIF_BG_LEAVE:
netif_carrier_off(net_dev);
dev_info(dev, "Link is down\n");
break;
default:
dev_err(dev, "don't know how to handle event %d from uwb\n",
event);
}
}
/**
* Stop the network queue
*
......
......@@ -33,8 +33,6 @@
#include <linux/seq_file.h>
#include <linux/uwb/debug-cmd.h>
#define D_LOCAL 0
#include <linux/uwb/debug.h>
#include "uwb-internal.h"
......@@ -314,7 +312,6 @@ static struct file_operations drp_avail_fops = {
static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel)
{
struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal);
struct device *dev = &pal->rc->uwb_dev.dev;
if (channel > 0)
......
......@@ -526,7 +526,17 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
}
}
int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
static void wlp_channel_changed(struct uwb_pal *pal, int channel)
{
struct wlp *wlp = container_of(pal, struct wlp, pal);
if (channel < 0)
netif_carrier_off(wlp->ndev);
else
netif_carrier_on(wlp->ndev);
}
int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
{
struct device *dev = &rc->uwb_dev.dev;
int result;
......@@ -537,6 +547,7 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
BUG_ON(wlp->stop_queue == NULL);
BUG_ON(wlp->start_queue == NULL);
wlp->rc = rc;
wlp->ndev = ndev;
wlp_eda_init(&wlp->eda);/* Set up address cache */
wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
wlp->uwb_notifs_handler.data = wlp;
......@@ -544,6 +555,7 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
uwb_pal_init(&wlp->pal);
wlp->pal.rc = rc;
wlp->pal.channel_changed = wlp_channel_changed;
result = uwb_pal_register(&wlp->pal);
if (result < 0)
uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
......
......@@ -646,6 +646,7 @@ struct wlp_wss {
struct wlp {
struct mutex mutex;
struct uwb_rc *rc; /* UWB radio controller */
struct net_device *ndev;
struct uwb_pal pal;
struct wlp_eda eda;
struct wlp_uuid uuid;
......@@ -675,7 +676,7 @@ struct wlp_wss_attribute {
static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \
_show, _store)
extern int wlp_setup(struct wlp *, struct uwb_rc *);
extern int wlp_setup(struct wlp *, struct uwb_rc *, struct net_device *ndev);
extern void wlp_remove(struct wlp *);
extern ssize_t wlp_neighborhood_show(struct wlp *, char *);
extern int wlp_wss_setup(struct net_device *, struct wlp_wss *);
......
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