aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-11-17 11:16:51 -0500
committerDavid Vrabel <david.vrabel@csr.com>2008-11-19 09:47:04 -0500
commite8e1594c8126b1b773988fa2e3bfec76cff88336 (patch)
treeafa666ce45d8652880855b04a26755e4e5182e01
parent6fae35f9cea92793a98b2d9ab21235e5ae035581 (diff)
wlp: start/stop radio on network interface up/down
Signed-off-by: David Vrabel <david.vrabel@csr.com>
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/lc.c2
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/netdev.c51
-rw-r--r--drivers/uwb/uwb-debug.c3
-rw-r--r--drivers/uwb/wlp/wlp-lc.c14
-rw-r--r--include/linux/wlp.h3
5 files changed, 27 insertions, 46 deletions
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
index 384306c11bbe..488b2e30a0a8 100644
--- a/drivers/uwb/i1480/i1480u-wlp/lc.c
+++ b/drivers/uwb/i1480/i1480u-wlp/lc.c
@@ -206,7 +206,7 @@ int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
206 wlp->fill_device_info = i1480u_fill_device_info; 206 wlp->fill_device_info = i1480u_fill_device_info;
207 wlp->stop_queue = i1480u_stop_queue; 207 wlp->stop_queue = i1480u_stop_queue;
208 wlp->start_queue = i1480u_start_queue; 208 wlp->start_queue = i1480u_start_queue;
209 result = wlp_setup(wlp, rc); 209 result = wlp_setup(wlp, rc, net_dev);
210 if (result < 0) { 210 if (result < 0) {
211 dev_err(&iface->dev, "Cannot setup WLP\n"); 211 dev_err(&iface->dev, "Cannot setup WLP\n");
212 goto error_wlp_setup; 212 goto error_wlp_setup;
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c
index 8802ac43d872..2eafb973cd05 100644
--- a/drivers/uwb/i1480/i1480u-wlp/netdev.c
+++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c
@@ -207,6 +207,11 @@ int i1480u_open(struct net_device *net_dev)
207 result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */ 207 result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */
208 if (result < 0) 208 if (result < 0)
209 goto error_rx_setup; 209 goto error_rx_setup;
210
211 result = uwb_radio_start(&wlp->pal);
212 if (result < 0)
213 goto error_radio_start;
214
210 netif_wake_queue(net_dev); 215 netif_wake_queue(net_dev);
211#ifdef i1480u_FLOW_CONTROL 216#ifdef i1480u_FLOW_CONTROL
212 result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);; 217 result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);;
@@ -215,25 +220,20 @@ int i1480u_open(struct net_device *net_dev)
215 goto error_notif_urb_submit; 220 goto error_notif_urb_submit;
216 } 221 }
217#endif 222#endif
218 i1480u->uwb_notifs_handler.cb = i1480u_uwb_notifs_cb;
219 i1480u->uwb_notifs_handler.data = i1480u;
220 if (uwb_bg_joined(rc))
221 netif_carrier_on(net_dev);
222 else
223 netif_carrier_off(net_dev);
224 uwb_notifs_register(rc, &i1480u->uwb_notifs_handler);
225 /* Interface is up with an address, now we can create WSS */ 223 /* Interface is up with an address, now we can create WSS */
226 result = wlp_wss_setup(net_dev, &wlp->wss); 224 result = wlp_wss_setup(net_dev, &wlp->wss);
227 if (result < 0) { 225 if (result < 0) {
228 dev_err(dev, "Can't create WSS: %d. \n", result); 226 dev_err(dev, "Can't create WSS: %d. \n", result);
229 goto error_notif_deregister; 227 goto error_wss_setup;
230 } 228 }
231 return 0; 229 return 0;
232error_notif_deregister: 230error_wss_setup:
233 uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
234#ifdef i1480u_FLOW_CONTROL 231#ifdef i1480u_FLOW_CONTROL
232 usb_kill_urb(i1480u->notif_urb);
235error_notif_urb_submit: 233error_notif_urb_submit:
236#endif 234#endif
235 uwb_radio_stop(&wlp->pal);
236error_radio_start:
237 netif_stop_queue(net_dev); 237 netif_stop_queue(net_dev);
238 i1480u_rx_release(i1480u); 238 i1480u_rx_release(i1480u);
239error_rx_setup: 239error_rx_setup:
@@ -248,16 +248,15 @@ int i1480u_stop(struct net_device *net_dev)
248{ 248{
249 struct i1480u *i1480u = netdev_priv(net_dev); 249 struct i1480u *i1480u = netdev_priv(net_dev);
250 struct wlp *wlp = &i1480u->wlp; 250 struct wlp *wlp = &i1480u->wlp;
251 struct uwb_rc *rc = wlp->rc;
252 251
253 BUG_ON(wlp->rc == NULL); 252 BUG_ON(wlp->rc == NULL);
254 wlp_wss_remove(&wlp->wss); 253 wlp_wss_remove(&wlp->wss);
255 uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
256 netif_carrier_off(net_dev); 254 netif_carrier_off(net_dev);
257#ifdef i1480u_FLOW_CONTROL 255#ifdef i1480u_FLOW_CONTROL
258 usb_kill_urb(i1480u->notif_urb); 256 usb_kill_urb(i1480u->notif_urb);
259#endif 257#endif
260 netif_stop_queue(net_dev); 258 netif_stop_queue(net_dev);
259 uwb_radio_stop(&wlp->pal);
261 i1480u_rx_release(i1480u); 260 i1480u_rx_release(i1480u);
262 i1480u_tx_release(i1480u); 261 i1480u_tx_release(i1480u);
263 return 0; 262 return 0;
@@ -303,34 +302,6 @@ int i1480u_change_mtu(struct net_device *net_dev, int mtu)
303 return 0; 302 return 0;
304} 303}
305 304
306
307/**
308 * Callback function to handle events from UWB
309 * When we see other devices we know the carrier is ok,
310 * if we are the only device in the beacon group we set the carrier
311 * state to off.
312 * */
313void i1480u_uwb_notifs_cb(void *data, struct uwb_dev *uwb_dev,
314 enum uwb_notifs event)
315{
316 struct i1480u *i1480u = data;
317 struct net_device *net_dev = i1480u->net_dev;
318 struct device *dev = &i1480u->usb_iface->dev;
319 switch (event) {
320 case UWB_NOTIF_BG_JOIN:
321 netif_carrier_on(net_dev);
322 dev_info(dev, "Link is up\n");
323 break;
324 case UWB_NOTIF_BG_LEAVE:
325 netif_carrier_off(net_dev);
326 dev_info(dev, "Link is down\n");
327 break;
328 default:
329 dev_err(dev, "don't know how to handle event %d from uwb\n",
330 event);
331 }
332}
333
334/** 305/**
335 * Stop the network queue 306 * Stop the network queue
336 * 307 *
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 0e58071a232d..e02fb83469d5 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -33,8 +33,6 @@
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/uwb/debug-cmd.h> 35#include <linux/uwb/debug-cmd.h>
36#define D_LOCAL 0
37#include <linux/uwb/debug.h>
38 36
39#include "uwb-internal.h" 37#include "uwb-internal.h"
40 38
@@ -314,7 +312,6 @@ static struct file_operations drp_avail_fops = {
314 312
315static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel) 313static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel)
316{ 314{
317 struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal);
318 struct device *dev = &pal->rc->uwb_dev.dev; 315 struct device *dev = &pal->rc->uwb_dev.dev;
319 316
320 if (channel > 0) 317 if (channel > 0)
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
index 7e5eb49b03b8..e531093c4162 100644
--- a/drivers/uwb/wlp/wlp-lc.c
+++ b/drivers/uwb/wlp/wlp-lc.c
@@ -526,7 +526,17 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
526 } 526 }
527} 527}
528 528
529int wlp_setup(struct wlp *wlp, struct uwb_rc *rc) 529static void wlp_channel_changed(struct uwb_pal *pal, int channel)
530{
531 struct wlp *wlp = container_of(pal, struct wlp, pal);
532
533 if (channel < 0)
534 netif_carrier_off(wlp->ndev);
535 else
536 netif_carrier_on(wlp->ndev);
537}
538
539int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
530{ 540{
531 struct device *dev = &rc->uwb_dev.dev; 541 struct device *dev = &rc->uwb_dev.dev;
532 int result; 542 int result;
@@ -537,6 +547,7 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
537 BUG_ON(wlp->stop_queue == NULL); 547 BUG_ON(wlp->stop_queue == NULL);
538 BUG_ON(wlp->start_queue == NULL); 548 BUG_ON(wlp->start_queue == NULL);
539 wlp->rc = rc; 549 wlp->rc = rc;
550 wlp->ndev = ndev;
540 wlp_eda_init(&wlp->eda);/* Set up address cache */ 551 wlp_eda_init(&wlp->eda);/* Set up address cache */
541 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; 552 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
542 wlp->uwb_notifs_handler.data = wlp; 553 wlp->uwb_notifs_handler.data = wlp;
@@ -544,6 +555,7 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
544 555
545 uwb_pal_init(&wlp->pal); 556 uwb_pal_init(&wlp->pal);
546 wlp->pal.rc = rc; 557 wlp->pal.rc = rc;
558 wlp->pal.channel_changed = wlp_channel_changed;
547 result = uwb_pal_register(&wlp->pal); 559 result = uwb_pal_register(&wlp->pal);
548 if (result < 0) 560 if (result < 0)
549 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 561 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
diff --git a/include/linux/wlp.h b/include/linux/wlp.h
index 033545e145c7..ac95ce6606ac 100644
--- a/include/linux/wlp.h
+++ b/include/linux/wlp.h
@@ -646,6 +646,7 @@ struct wlp_wss {
646struct wlp { 646struct wlp {
647 struct mutex mutex; 647 struct mutex mutex;
648 struct uwb_rc *rc; /* UWB radio controller */ 648 struct uwb_rc *rc; /* UWB radio controller */
649 struct net_device *ndev;
649 struct uwb_pal pal; 650 struct uwb_pal pal;
650 struct wlp_eda eda; 651 struct wlp_eda eda;
651 struct wlp_uuid uuid; 652 struct wlp_uuid uuid;
@@ -675,7 +676,7 @@ struct wlp_wss_attribute {
675static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \ 676static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \
676 _show, _store) 677 _show, _store)
677 678
678extern int wlp_setup(struct wlp *, struct uwb_rc *); 679extern int wlp_setup(struct wlp *, struct uwb_rc *, struct net_device *ndev);
679extern void wlp_remove(struct wlp *); 680extern void wlp_remove(struct wlp *);
680extern ssize_t wlp_neighborhood_show(struct wlp *, char *); 681extern ssize_t wlp_neighborhood_show(struct wlp *, char *);
681extern int wlp_wss_setup(struct net_device *, struct wlp_wss *); 682extern int wlp_wss_setup(struct net_device *, struct wlp_wss *);