#include "uwb-internal.h"
static int uwb_radio_select_channel(struct uwb_rc *rc)
{
/*
* Default to channel 9 (BG1, TFC1) unless the user has
* selected a specific channel or there are no active PALs.
*/
if (rc->active_pals == 0)
return -1;
if (rc->beaconing_forced)
return rc->beaconing_forced;
return 9;
}
/*
* Notify all active PALs that the channel has changed.
*/
static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel)
{
struct uwb_pal *pal;
list_for_each_entry(pal, &rc->pals, node) {
if (pal->channel && channel != pal->channel) {
pal->channel = channel;
if (pal->channel_changed)
pal->channel_changed(pal, pal->channel);
}
}
}
/*
* Change to a new channel and notify any active PALs of the new
* channel.
*
* When stopping the radio, PALs need to be notified first so they can
* terminate any active reservations.
*/
static int uwb_radio_change_channel(struct uwb_rc *rc, int channel)
{
int ret = 0;
struct device *dev = &rc->uwb_dev.dev;
dev_dbg(dev, "%s: channel = %d, rc->beaconing = %d\n", __func__,
channel, rc->beaconing);
if (channel == -1)
uwb_radio_channel_changed(rc, channel);
if (channel != rc->beaconing) {
if (rc->beaconing != -1 && channel != -1) {
/*
* FIXME: should signal the channel change
* with a Channel Change IE.
*/
ret = uwb_radio_change_channel(rc, -1);
if (ret < 0)
return ret;
}
ret = uwb_rc_beacon(rc, channel, 0);
}
if (channel != -1)
uwb_radio_channel_changed(rc, rc->beaconing);
return ret;
}
/**
* uwb_radio_start - request that the radio be started
* @pal: the PAL making the request.
*
* If the radio is not already active, a suitable channel is selected
* and beacons are started.
*/
int uwb_radio_start(struct uwb_pal *pal)
{
struct uwb_rc *rc = pal->rc;
int ret = 0;
mutex_lock(&rc->uwb_dev.mutex);
if (!pal->channel) {
pal->channel = -1;
rc->active_pals++;
ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
}
mutex_unlock(&rc->uwb_dev.mutex);
return ret;
}
EXPORT_SYMBOL_GPL(uwb_radio_start);
/**
* uwb_radio_stop - request that the radio be stopped.
* @pal: the PAL making the request.
*
* Stops the radio if no other PAL is making use of it.
*/
void uwb_radio_stop(struct uwb_pal *pal)
{
struct uwb_rc *rc = pal->rc;
mutex_lock(&rc->uwb_dev.mutex);
if (pal->channel) {
rc->active_pals--;
uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
pal->channel = 0;
}
mutex_unlock(&rc->uwb_dev.mutex);
}
EXPORT_SYMBOL_GPL(uwb_radio_stop);
/*
* uwb_radio_force_channel - force a specific channel to be used
* @rc: the radio controller.
* @channel: the channel to use; -1 to force the radio to stop; 0 to
* use the default channel selection algorithm.
*/
int uwb_radio_force_channel(struct uwb_rc *rc, int channel)
{
int ret = 0;
mutex_lock(&rc->uwb_dev.mutex);
rc->beaconing_forced = channel;
ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
mutex_unlock(&rc->uwb_dev.mutex);
return ret;
}
/*
* uwb_radio_setup - setup the radio manager
* @rc: the radio controller.
*
* The radio controller is reset to ensure it's in a known state
* before it's used.
*/
int uwb_radio_setup(struct uwb_rc *rc)
{
return uwb_rc_reset(rc);
}
/*
* uwb_radio_reset_state - reset any radio manager state
* @rc: the radio controller.
*
* All internal radio manager state is reset to values corresponding
* to a reset radio controller.
*/
void uwb_radio_reset_state(struct uwb_rc *rc)
{
struct uwb_pal *pal;
mutex_lock(&rc->uwb_dev.mutex);
list_for_each_entry(pal, &rc->pals, node) {
if (pal->channel) {
pal->channel = -1;
if (pal->channel_changed)
pal->channel_changed(pal, -1);
}
}
rc->beaconing = -1;
rc->scanning = -1;
mutex_unlock(&rc->uwb_dev.mutex);
}
/*
* uwb_radio_shutdown - shutdown the radio manager
* @rc: the radio controller.
*
* The radio controller is reset.
*/
void uwb_radio_shutdown(struct uwb_rc *rc)
{
uwb_radio_reset_state(rc);
uwb_rc_reset(rc);
}
29 10:56:56 -0800
commit | 2c5d9555d6d937966d79d4c6529a5f7b9206e405 (patch) |
tree | 4f3d220ea3aeaadcae0796c5456e0ef9a908071d /net/tipc/server.c |
parent | 53cd1ad1a68fd10f677445e04ed63aa9ce39b36b (diff) |
---|
parent | 2ad5d52d42810bed95100a3d912679d8864421ec (diff) |
Merge branch 'parisc-4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull two parisc fixes from Helge Deller:
"One fix to avoid usage of BITS_PER_LONG in user-space exported swab.h
header which breaks compiling qemu, and one trivial fix for printk
continuation in the parisc parport driver"
* 'parisc-4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Don't use BITS_PER_LONG in userspace-exported swab.h header
parisc, parport_gsc: Fixes for printk continuation lines