Skip to content

Commit

Permalink
mac80211: add set/cancel_priority implementation
Browse files Browse the repository at this point in the history
TODO: documentation, locking?, cleanup (the __ieee80211_*_priority
functions are for internal mac80211 use, maybe we can remove
them)

Signed-off-by: Eliad Peller <eliad@wizery.com>
  • Loading branch information
elp committed Apr 22, 2012
1 parent cf74026 commit 8e83959
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/net/mac80211.h
Expand Up @@ -2347,6 +2347,10 @@ struct ieee80211_ops {
enum nl80211_channel_type channel_type,
int duration);
int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
int (*set_priority)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*cancel_priority)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
void (*get_ringparam)(struct ieee80211_hw *hw,
u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
Expand Down
48 changes: 48 additions & 0 deletions net/mac80211/cfg.c
Expand Up @@ -2702,6 +2702,52 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
return 0;
}

int __ieee80211_set_priority(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
int ret;

if (local->prio_sdata) {
if (local->prio_sdata == sdata)
return 0;
else
return -EBUSY;
}

ret = drv_set_priority(local, sdata);
if (!ret)
local->prio_sdata = sdata;

return ret;
}
int __ieee80211_cancel_priority(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
int ret;

if (!local->prio_sdata || local->prio_sdata != sdata)
return 0;

ret = drv_cancel_priority(local, sdata);
if (!ret)
local->prio_sdata = NULL;

return ret;
}

static int ieee80211_set_priority(struct wiphy *wiphy,
struct net_device *dev)
{
return __ieee80211_set_priority(IEEE80211_DEV_TO_SUB_IF(dev));
}

static int ieee80211_cancel_priority(struct wiphy *wiphy,
struct net_device *dev)
{
return __ieee80211_cancel_priority(IEEE80211_DEV_TO_SUB_IF(dev));
}


static struct ieee80211_channel *
ieee80211_wiphy_get_channel(struct wiphy *wiphy)
{
Expand Down Expand Up @@ -2772,6 +2818,8 @@ struct cfg80211_ops mac80211_config_ops = {
.set_bitrate_mask = ieee80211_set_bitrate_mask,
.remain_on_channel = ieee80211_remain_on_channel,
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
.set_priority = ieee80211_set_priority,
.cancel_priority = ieee80211_cancel_priority,
.mgmt_tx = ieee80211_mgmt_tx,
.mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
Expand Down
32 changes: 32 additions & 0 deletions net/mac80211/driver-ops.h
Expand Up @@ -700,6 +700,38 @@ static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
return ret;
}

static inline int drv_set_priority(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
{
int ret = -EOPNOTSUPP;

might_sleep();
check_sdata_in_driver(sdata);

trace_drv_set_priority(local, sdata);
if (local->ops->set_priority)
ret = local->ops->set_priority(&local->hw, &sdata->vif);
trace_drv_return_int(local, ret);

return ret;
}

static inline int drv_cancel_priority(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
{
int ret = -EOPNOTSUPP;

might_sleep();
check_sdata_in_driver(sdata);

trace_drv_cancel_priority(local, sdata);
if (local->ops->cancel_priority)
ret = local->ops->cancel_priority(&local->hw, &sdata->vif);
trace_drv_return_int(local, ret);

return ret;
}

static inline int drv_set_ringparam(struct ieee80211_local *local,
u32 tx, u32 rx)
{
Expand Down
12 changes: 12 additions & 0 deletions net/mac80211/driver-trace.h
Expand Up @@ -981,6 +981,18 @@ DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel,
TP_ARGS(local)
);

DEFINE_EVENT(local_sdata_evt, drv_set_priority,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata),
TP_ARGS(local, sdata)
);

DEFINE_EVENT(local_sdata_evt, drv_cancel_priority,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata),
TP_ARGS(local, sdata)
);

TRACE_EVENT(drv_offchannel_tx,
TP_PROTO(struct ieee80211_local *local, struct sk_buff *skb,
struct ieee80211_channel *chan,
Expand Down
5 changes: 5 additions & 0 deletions net/mac80211/ieee80211_i.h
Expand Up @@ -390,6 +390,7 @@ struct ieee80211_mgd_auth_data {

u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
bool priority;
bool done;

size_t ie_len;
Expand Down Expand Up @@ -1096,6 +1097,8 @@ struct ieee80211_local {
u32 hw_roc_cookie;
bool hw_roc_for_tx;

struct ieee80211_sub_if_data *prio_sdata;

struct idr ack_status_frames;
spinlock_t ack_status_lock;

Expand Down Expand Up @@ -1513,6 +1516,8 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
int ieee80211_wk_cancel_remain_on_channel(
struct ieee80211_sub_if_data *sdata, u64 cookie);

int __ieee80211_cancel_priority(struct ieee80211_sub_if_data *sdata);

/* channel management */
enum ieee80211_chan_mode {
CHAN_MODE_UNDEFINED,
Expand Down
3 changes: 3 additions & 0 deletions net/mac80211/iface.c
Expand Up @@ -521,6 +521,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if (local->scan_sdata == sdata)
ieee80211_scan_cancel(local);

if (local->prio_sdata == sdata)
__ieee80211_cancel_priority(sdata);

/*
* Stop TX on this interface first.
*/
Expand Down

0 comments on commit 8e83959

Please sign in to comment.