wlp: start/stop radio on network interface up/down
Signed-off-by: David Vrabel <david.vrabel@csr.com>
This commit is contained in:
Родитель
6fae35f9ce
Коммит
e8e1594c81
|
@ -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 *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче