From cc61d8df0a0157fabae2a3422f0b7f9f18f81c82 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 29 Sep 2014 02:36:30 +0200 Subject: mac80211: minstrel_ht: fix MCS_GROUP_RATES usage Commit 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability") replaced the constant 8 with MCS_GROUP_RATES when getting the number of streams of an HT MCS. See commit 7a5e3fa2c81c ("mac80211: minstrel_ht: replace some occurences of MCS_GROUP_RATES"). Fixes: 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability") Signed-off-by: Karl Beldan Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index df90ce2db00c..17ef54a7a492 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -135,7 +135,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); static int minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) { - return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, + return GROUP_IDX((rate->idx / 8) + 1, !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); } -- cgit v1.2.3 From 66be7d2bcd826344894be09dc385f9f805136b84 Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Fri, 12 Sep 2014 08:58:49 +0200 Subject: cfg80211: add ops to query mesh proxy path table Add two new cfg80211 operations for querying a table with proxied mesh paths. Signed-off-by: Henning Rogge Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 7 ++++ include/uapi/linux/nl80211.h | 6 +++ net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 27 +++++++++++- net/wireless/trace.h | 45 ++++++++++++++++++++ 5 files changed, 183 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a2ddcf2398fd..3f3aaa06adb5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2146,6 +2146,8 @@ struct cfg80211_qos_map { * @change_mpath: change a given mesh path * @get_mpath: get a mesh path for the given parameters * @dump_mpath: dump mesh path callback -- resume dump at index @idx + * @get_mpp: get a mesh proxy path for the given parameters + * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx * @join_mesh: join the mesh network with the specified parameters * (invoked with the wireless_dev mutex held) * @leave_mesh: leave the current mesh network @@ -2396,6 +2398,11 @@ struct cfg80211_ops { int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo); + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, + u8 *dst, u8 *mpp, struct mpath_info *pinfo); + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *dst, u8 *mpp, + struct mpath_info *pinfo); int (*get_mesh_config)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 4b28dc07bcb1..846071b0cde9 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -738,6 +738,10 @@ * before removing a station entry entirely, or before disassociating * or similar, cleanup will happen in the driver/device in this case. * + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -912,6 +916,8 @@ enum nl80211_commands { NL80211_CMD_ADD_TX_TS, NL80211_CMD_DEL_TX_TS, + NL80211_CMD_GET_MPP, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cb9f5a44ffad..d527aa0706c1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4624,6 +4624,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) return rdev_del_mpath(rdev, dev, dst); } +static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + int err; + struct net_device *dev = info->user_ptr[1]; + struct mpath_info pinfo; + struct sk_buff *msg; + u8 *dst = NULL; + u8 mpp[ETH_ALEN]; + + memset(&pinfo, 0, sizeof(pinfo)); + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + dst = nla_data(info->attrs[NL80211_ATTR_MAC]); + + if (!rdev->ops->get_mpp) + return -EOPNOTSUPP; + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + + err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); + if (err) + return err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, + dev, dst, mpp, &pinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } + + return genlmsg_reply(msg, info); +} + +static int nl80211_dump_mpp(struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct mpath_info pinfo; + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; + u8 dst[ETH_ALEN]; + u8 mpp[ETH_ALEN]; + int path_idx = cb->args[2]; + int err; + + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (err) + return err; + + if (!rdev->ops->dump_mpp) { + err = -EOPNOTSUPP; + goto out_err; + } + + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { + err = -EOPNOTSUPP; + goto out_err; + } + + while (1) { + err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, + mpp, &pinfo); + if (err == -ENOENT) + break; + if (err) + goto out_err; + + if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + wdev->netdev, dst, mpp, + &pinfo) < 0) + goto out; + + path_idx++; + } + + out: + cb->args[2] = path_idx; + err = skb->len; + out_err: + nl80211_finish_wdev_dump(rdev); + return err; +} + static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -9773,6 +9863,15 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_GET_MPP, + .doit = nl80211_get_mpp, + .dumpit = nl80211_dump_mpp, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, { .cmd = NL80211_CMD_SET_MPATH, .doit = nl80211_set_mpath, diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index f6d457d6a558..c09e697bcb15 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, } +static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, + struct net_device *dev, u8 *dst, u8 *mpp, + struct mpath_info *pinfo) +{ + int ret; + + trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); + ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); + return ret; +} + static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo) @@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, int ret; trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, - pinfo); + pinfo); + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); + return ret; +} + +static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, + struct net_device *dev, int idx, u8 *dst, + u8 *mpp, struct mpath_info *pinfo) + +{ + int ret; + + trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); + ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 625a6e6d1168..8e4f8f04332d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath, MAC_PR_ARG(next_hop)) ); +TRACE_EVENT(rdev_get_mpp, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + u8 *dst, u8 *mpp), + TP_ARGS(wiphy, netdev, dst, mpp), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(dst) + MAC_ENTRY(mpp) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(dst, dst); + MAC_ASSIGN(mpp, mpp); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT + ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, + MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) +); + +TRACE_EVENT(rdev_dump_mpp, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, + u8 *dst, u8 *mpp), + TP_ARGS(wiphy, netdev, idx, mpp, dst), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(dst) + MAC_ENTRY(mpp) + __field(int, idx) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(dst, dst); + MAC_ASSIGN(mpp, mpp); + __entry->idx = idx; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " + MAC_PR_FMT ", mpp: " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), + MAC_PR_ARG(mpp)) +); + TRACE_EVENT(rdev_return_int_mpath_info, TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), TP_ARGS(wiphy, ret, pinfo), -- cgit v1.2.3 From a2db2ed3fb7d35ff2405d08fc012a5db8ddb36e0 Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Fri, 12 Sep 2014 08:58:50 +0200 Subject: mac80211: implement cfg80211_ops to query mesh proxy path table Implement get_mpp and dump_mpp cfg80211_ops to export the content of the 802.11s mesh proxy path table to userspace. Signed-off-by: Henning Rogge Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/mesh.h | 3 +++ net/mac80211/mesh_pathtbl.c | 31 ++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) (limited to 'net') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fb6a1502b6df..3a04f2edd3c3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1516,6 +1516,57 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, return 0; } +static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, + struct mpath_info *pinfo) +{ + memset(pinfo, 0, sizeof(*pinfo)); + memcpy(mpp, mpath->mpp, ETH_ALEN); + + pinfo->generation = mpp_paths_generation; +} + +static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, + u8 *dst, u8 *mpp, struct mpath_info *pinfo) + +{ + struct ieee80211_sub_if_data *sdata; + struct mesh_path *mpath; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + rcu_read_lock(); + mpath = mpp_path_lookup(sdata, dst); + if (!mpath) { + rcu_read_unlock(); + return -ENOENT; + } + memcpy(dst, mpath->dst, ETH_ALEN); + mpp_set_pinfo(mpath, mpp, pinfo); + rcu_read_unlock(); + return 0; +} + +static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *dst, u8 *mpp, + struct mpath_info *pinfo) +{ + struct ieee80211_sub_if_data *sdata; + struct mesh_path *mpath; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + rcu_read_lock(); + mpath = mpp_path_lookup_by_idx(sdata, idx); + if (!mpath) { + rcu_read_unlock(); + return -ENOENT; + } + memcpy(dst, mpath->dst, ETH_ALEN); + mpp_set_pinfo(mpath, mpp, pinfo); + rcu_read_unlock(); + return 0; +} + static int ieee80211_get_mesh_config(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf) @@ -3547,6 +3598,8 @@ const struct cfg80211_ops mac80211_config_ops = { .change_mpath = ieee80211_change_mpath, .get_mpath = ieee80211_get_mpath, .dump_mpath = ieee80211_dump_mpath, + .get_mpp = ieee80211_get_mpp, + .dump_mpp = ieee80211_dump_mpp, .update_mesh_config = ieee80211_update_mesh_config, .get_mesh_config = ieee80211_get_mesh_config, .join_mesh = ieee80211_join_mesh, diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index f39a19f9090f..50c8473cf9dc 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -270,6 +270,8 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst, const u8 *mpp); struct mesh_path * mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); +struct mesh_path * +mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); void mesh_path_expire(struct ieee80211_sub_if_data *sdata); void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, @@ -317,6 +319,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); extern int mesh_paths_generation; +extern int mpp_paths_generation; #ifdef CONFIG_MAC80211_MESH static inline diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index a6699dceae7c..b890e225a8f1 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -44,6 +44,7 @@ static struct mesh_table __rcu *mesh_paths; static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ int mesh_paths_generation; +int mpp_paths_generation; /* This lock will have the grow table function as writer and add / delete nodes * as readers. RCU provides sufficient protection only when reading the table @@ -409,6 +410,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) return NULL; } +/** + * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index + * @idx: index + * @sdata: local subif, or NULL for all entries + * + * Returns: pointer to the proxy path structure, or NULL if not found. + * + * Locking: must be called within a read rcu section. + */ +struct mesh_path * +mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) +{ + struct mesh_table *tbl = rcu_dereference(mpp_paths); + struct mpath_node *node; + int i; + int j = 0; + + for_each_mesh_entry(tbl, node, i) { + if (sdata && node->mpath->sdata != sdata) + continue; + if (j++ == idx) + return node->mpath; + } + + return NULL; +} + /** * mesh_path_add_gate - add the given mpath to a mesh gate to our path table * @mpath: gate path to add to table @@ -691,6 +719,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); + + mpp_paths_generation++; + if (grow) { set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); ieee80211_queue_work(&local->hw, &sdata->work); -- cgit v1.2.3 From 2ba45384e5426b9a4aeb77656dce0bf3250ce54e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:35 +0300 Subject: mac80211: add device_timestamp to the ieee80211_channel_switch struct Some devices may need the device timestamp in order to synchronize the channel switch. To pass this value back to the driver, add it to the channel switch structure and copy the device_timestamp value received in the rx info structure into it. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +++ net/mac80211/mlme.c | 15 ++++++++++----- net/mac80211/trace.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0ad1f47d2dc7..ec0a5b07055b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1117,6 +1117,8 @@ struct ieee80211_conf { * Function (TSF) timer when the frame containing the channel switch * announcement was received. This is simply the rx.mactime parameter * the driver passed into mac80211. + * @device_timestamp: arbitrary timestamp for the device, this is the + * rx.device_timestamp parameter the driver passed to mac80211. * @block_tx: Indicates whether transmission must be blocked before the * scheduled channel switch, as indicated by the AP. * @chandef: the new channel to switch to @@ -1124,6 +1126,7 @@ struct ieee80211_conf { */ struct ieee80211_channel_switch { u64 timestamp; + u32 device_timestamp; bool block_tx; struct cfg80211_chan_def chandef; u8 count; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2de88704278b..f2e048fa250c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1046,7 +1046,8 @@ static void ieee80211_chswitch_timer(unsigned long data) static void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, - u64 timestamp, struct ieee802_11_elems *elems, + u64 timestamp, u32 device_timestamp, + struct ieee802_11_elems *elems, bool beacon) { struct ieee80211_local *local = sdata->local; @@ -1154,6 +1155,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, /* use driver's channel switch callback */ struct ieee80211_channel_switch ch_switch = { .timestamp = timestamp, + .device_timestamp = device_timestamp, .block_tx = csa_ie.mode, .chandef = csa_ie.chandef, .count = csa_ie.count, @@ -3203,6 +3205,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + rx_status->device_timestamp, &elems, true); if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && @@ -3334,8 +3337,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, break; ieee80211_sta_process_chanswitch(sdata, - rx_status->mactime, - &elems, false); + rx_status->mactime, + rx_status->device_timestamp, + &elems, false); } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ies_len = skb->len - offsetof(struct ieee80211_mgmt, @@ -3356,8 +3360,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, &mgmt->u.action.u.ext_chan_switch.data; ieee80211_sta_process_chanswitch(sdata, - rx_status->mactime, - &elems, false); + rx_status->mactime, + rx_status->device_timestamp, + &elems, false); } break; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 38fae7ebe984..853c440218d4 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -995,6 +995,7 @@ TRACE_EVENT(drv_channel_switch, LOCAL_ENTRY CHANDEF_ENTRY __field(u64, timestamp) + __field(u32, device_timestamp) __field(bool, block_tx) __field(u8, count) ), @@ -1003,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch, LOCAL_ASSIGN; CHANDEF_ASSIGN(&ch_switch->chandef) __entry->timestamp = ch_switch->timestamp; + __entry->device_timestamp = ch_switch->device_timestamp; __entry->block_tx = ch_switch->block_tx; __entry->count = ch_switch->count; ), -- cgit v1.2.3 From e9a21949b79414dda42a017855b288901c07e613 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:36 +0300 Subject: mac80211: add extended channel switching capability if the driver supports CSA The Extended Channel Switching capability bit in the extended capabilities element must be set if the driver supports CSA on non-beaconing interfaces. Since this capability needs to be set during driver registration, the extended_capabiliities global variable needs to be moved to the local structure so that it can be modified. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 5 +++++ net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/main.c | 20 +++++++++++--------- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index b1be39c76931..5fab17b382b5 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1998,6 +1998,11 @@ enum ieee80211_tdls_actioncode { WLAN_TDLS_DISCOVERY_REQUEST = 10, }; +/* Extended Channel Switching capability to be set in the 1st byte of + * the @WLAN_EID_EXT_CAPABILITY information element + */ +#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) + /* Interworking capabilities are set in 7th bit of 4th byte of the * @WLAN_EID_EXT_CAPABILITY information element */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c2aaec4dfcf0..a9cc49128980 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1307,6 +1307,9 @@ struct ieee80211_local { /* virtual monitor interface */ struct ieee80211_sub_if_data __rcu *monitor_sdata; struct cfg80211_chan_def monitor_chandef; + + /* extended capabilities provided by mac80211 */ + u8 ext_capa[8]; }; static inline struct ieee80211_sub_if_data * diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0de7c93bf62b..107d1c884de3 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -478,11 +478,6 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { }, }; -static const u8 extended_capabilities[] = { - 0, 0, 0, 0, 0, 0, 0, - WLAN_EXT_CAPA8_OPMODE_NOTIF, -}; - struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -539,10 +534,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, WIPHY_FLAG_REPORTS_OBSS | WIPHY_FLAG_OFFCHAN_TX; - wiphy->extended_capabilities = extended_capabilities; - wiphy->extended_capabilities_mask = extended_capabilities; - wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities); - if (ops->remain_on_channel) wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; @@ -591,6 +582,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; + local->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF; + + wiphy->extended_capabilities = local->ext_capa; + wiphy->extended_capabilities_mask = local->ext_capa; + wiphy->extended_capabilities_len = + ARRAY_SIZE(local->ext_capa); + INIT_LIST_HEAD(&local->interfaces); __hw_addr_init(&local->mc_list); @@ -958,6 +956,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + /* mac80211 supports eCSA, if the driver supports STA CSA at all */ + if (local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA) + local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; + local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; result = wiphy_register(local->hw.wiphy); -- cgit v1.2.3 From 6d027bcc8a4e2518ae825b0ff3dd069ab1abfe96 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:37 +0300 Subject: mac80211: add pre_channel_switch driver operation Some drivers may need to prepare for a channel switch also when it is initiated from the remote side (eg. station, P2P client). To make this possible, add a generic callback that can be called for all interface types. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 7 +++++++ net/mac80211/cfg.c | 11 +++++++++++ net/mac80211/driver-ops.h | 18 ++++++++++++++++++ net/mac80211/mlme.c | 25 +++++++++++++++++-------- net/mac80211/trace.h | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ec0a5b07055b..19e4159ce3a3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2832,6 +2832,10 @@ enum ieee80211_roc_type { * transmitted and then call ieee80211_csa_finish(). * If the CSA count starts as zero or 1, this function will not be called, * since there won't be any time to beacon before the switch anyway. + * @pre_channel_switch: This is an optional callback that is called + * before a channel switch procedure is started (ie. when a STA + * gets a CSA or an userspace initiated channel-switch), allowing + * the driver to prepare for the channel switch. * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A @@ -3038,6 +3042,9 @@ struct ieee80211_ops { void (*channel_switch_beacon)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef); + int (*pre_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel_switch *ch_switch); int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3a04f2edd3c3..647a2f6eb7dc 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3104,6 +3104,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; + struct ieee80211_channel_switch ch_switch; struct ieee80211_chanctx_conf *conf; struct ieee80211_chanctx *chanctx; int err, changed = 0; @@ -3139,6 +3140,10 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } + err = drv_pre_channel_switch(sdata, &ch_switch); + if (err) + goto out; + err = ieee80211_vif_reserve_chanctx(sdata, ¶ms->chandef, chanctx->mode, params->radar_required); @@ -3152,6 +3157,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } + ch_switch.timestamp = 0; + ch_switch.device_timestamp = 0; + ch_switch.block_tx = params->block_tx; + ch_switch.chandef = params->chandef; + ch_switch.count = params->count; + err = ieee80211_set_csa_beacon(sdata, params, &changed); if (err) { ieee80211_vif_unreserve_chanctx(sdata); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 196d48c68134..5522672129ce 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1196,6 +1196,24 @@ drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, } } +static inline int +drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch) +{ + struct ieee80211_local *local = sdata->local; + int ret = 0; + + if (!check_sdata_in_driver(sdata)) + return -EIO; + + trace_drv_pre_channel_switch(local, sdata, ch_switch); + if (local->ops->pre_channel_switch) + ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, + ch_switch); + trace_drv_return_int(local, ret); + return ret; +} + static inline int drv_join_ibss(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f2e048fa250c..d23d6d97e453 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1057,6 +1057,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx *chanctx; enum ieee80211_band current_band; struct ieee80211_csa_ie csa_ie; + struct ieee80211_channel_switch ch_switch; int res; sdata_assert_lock(sdata); @@ -1128,6 +1129,22 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, } } + ch_switch.timestamp = timestamp; + ch_switch.device_timestamp = device_timestamp; + ch_switch.block_tx = csa_ie.mode; + ch_switch.chandef = csa_ie.chandef; + ch_switch.count = csa_ie.count; + + if (drv_pre_channel_switch(sdata, &ch_switch)) { + sdata_info(sdata, + "preparing for channel switch failed, disconnecting\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + return; + } + res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, chanctx->mode, false); if (res) { @@ -1153,14 +1170,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (local->ops->channel_switch) { /* use driver's channel switch callback */ - struct ieee80211_channel_switch ch_switch = { - .timestamp = timestamp, - .device_timestamp = device_timestamp, - .block_tx = csa_ie.mode, - .chandef = csa_ie.chandef, - .count = csa_ie.count, - }; - drv_channel_switch(local, &ch_switch); return; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 853c440218d4..30476d2c7302 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2108,6 +2108,39 @@ TRACE_EVENT(drv_channel_switch_beacon, ) ); +TRACE_EVENT(drv_pre_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch), + + TP_ARGS(local, sdata, ch_switch), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + CHANDEF_ENTRY + __field(u64, timestamp) + __field(bool, block_tx) + __field(u8, count) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + CHANDEF_ASSIGN(&ch_switch->chandef) + __entry->timestamp = ch_switch->timestamp; + __entry->block_tx = ch_switch->block_tx; + __entry->count = ch_switch->count; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " prepare channel switch to " + CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu", + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count, + __entry->block_tx, __entry->timestamp + ) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- cgit v1.2.3 From f1d65583bc5bd43ace8abb9d4f4d9e8da407f708 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:38 +0300 Subject: mac80211: add post_channel_switch driver operation As a counterpart to the pre_channel_switch operation, add a post_channel_switch operation. This allows the drivers to go back to a normal configuration after the channel switch is completed. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 7 ++++++- net/mac80211/driver-ops.h | 16 ++++++++++++++++ net/mac80211/mlme.c | 9 +++++++++ net/mac80211/trace.h | 6 ++++++ 5 files changed, 43 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 19e4159ce3a3..7861ed875c4d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2836,6 +2836,9 @@ enum ieee80211_roc_type { * before a channel switch procedure is started (ie. when a STA * gets a CSA or an userspace initiated channel-switch), allowing * the driver to prepare for the channel switch. + * @post_channel_switch: This is an optional callback that is called + * after a channel switch procedure is completed, allowing the + * driver to go back to a normal configuration. * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A @@ -3046,6 +3049,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch); + int (*post_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); u32 (*get_expected_throughput)(struct ieee80211_sta *sta); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 647a2f6eb7dc..9d58b30b096a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2919,7 +2919,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) return err; ieee80211_bss_info_change_notify(sdata, changed); - cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, @@ -2927,6 +2926,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) sdata->csa_block_tx = false; } + err = drv_post_channel_switch(sdata); + if (err) + return err; + + cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); + return 0; } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5522672129ce..0a6090644769 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1214,6 +1214,22 @@ drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, return ret; } +static inline int +drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + int ret = 0; + + if (!check_sdata_in_driver(sdata)) + return -EIO; + + trace_drv_post_channel_switch(local, sdata); + if (local->ops->post_channel_switch) + ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); + trace_drv_return_int(local, ret); + return ret; +} + static inline int drv_join_ibss(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d23d6d97e453..cb1a8c3bc73f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1010,6 +1010,15 @@ static void ieee80211_chswitch_work(struct work_struct *work) sdata->csa_block_tx = false; } + ret = drv_post_channel_switch(sdata); + if (ret) { + sdata_info(sdata, + "driver post channel switch failed, disconnecting\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + goto out; + } + ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 30476d2c7302..ca0e12dd23c0 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2141,6 +2141,12 @@ TRACE_EVENT(drv_pre_channel_switch, ) ); +DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata), + TP_ARGS(local, sdata) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- cgit v1.2.3 From 0c21e6320f6ea7c4bd2fc0a8c1d8577b372f92d2 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:39 +0300 Subject: mac80211: wait for the first beacon on the new channel after CSA Instead of immediately reopening the queues (in case of block_tx), calling the post_channel_switch operation and sending the notification, wait for the first beacon on the new channel. This makes sure that we don't lose packets if the AP/GO is not on the new channel yet. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 2 ++ net/mac80211/mlme.c | 45 ++++++++++++++++++++++++++++++++------------- 3 files changed, 36 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a9cc49128980..78d6121eb372 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -434,6 +434,8 @@ struct ieee80211_if_managed { unsigned int flags; + bool csa_waiting_bcn; + bool beacon_crc_valid; u32 beacon_crc; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index af237223a8cd..e469b3390f2a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -842,6 +842,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, sdata_lock(sdata); mutex_lock(&local->mtx); sdata->vif.csa_active = false; + if (sdata->vif.type == NL80211_IFTYPE_STATION) + sdata->u.mgd.csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cb1a8c3bc73f..148253c1bd78 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1001,31 +1001,44 @@ static void ieee80211_chswitch_work(struct work_struct *work) /* XXX: shouldn't really modify cfg80211-owned data! */ ifmgd->associated->channel = sdata->csa_chandef.chan; - sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = true; + + ieee80211_sta_reset_beacon_monitor(sdata); + ieee80211_sta_reset_conn_monitor(sdata); + +out: + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + sdata_unlock(sdata); +} + +static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + int ret; + + sdata_assert_lock(sdata); + + WARN_ON(!sdata->vif.csa_active); - /* XXX: wait for a beacon first? */ if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); sdata->csa_block_tx = false; } + sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; + ret = drv_post_channel_switch(sdata); if (ret) { sdata_info(sdata, "driver post channel switch failed, disconnecting\n"); ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); - goto out; + return; } - - ieee80211_sta_reset_beacon_monitor(sdata); - ieee80211_sta_reset_conn_monitor(sdata); - -out: - mutex_unlock(&local->chanctx_mtx); - mutex_unlock(&local->mtx); - sdata_unlock(sdata); } void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) @@ -1943,6 +1956,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ieee80211_vif_release_channel(sdata); sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -2191,6 +2205,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) true, frame_buf); mutex_lock(&local->mtx); sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -3215,6 +3230,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } + if (ifmgd->csa_waiting_bcn) + ieee80211_chswitch_post_beacon(sdata); + if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) return; ifmgd->beacon_crc = ncrc; @@ -3687,11 +3705,12 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) struct ieee80211_sub_if_data *sdata = (struct ieee80211_sub_if_data *) data; struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; if (local->quiescing) return; - if (sdata->vif.csa_active) + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; sdata->u.mgd.connection_loss = false; @@ -3709,7 +3728,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) if (local->quiescing) return; - if (sdata->vif.csa_active) + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); -- cgit v1.2.3 From 0f791eb47f8222fd594e6f8a090632344ef23924 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:40 +0300 Subject: mac80211: allow channel switch with multiple channel contexts Channel switch with multiple channel contexts should now work fine. Remove check that disallows switches when multiple contexts are in use. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlegacy/4965-mac.c | 2 +- drivers/net/wireless/iwlegacy/4965.h | 5 +++-- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 1 + drivers/net/wireless/ti/wlcore/main.c | 23 ++++++++--------------- include/net/mac80211.h | 1 + net/mac80211/driver-ops.h | 7 ++++--- net/mac80211/mlme.c | 26 ++++++++++---------------- net/mac80211/trace.h | 9 ++++++--- 8 files changed, 34 insertions(+), 40 deletions(-) (limited to 'net') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 26fec54dcd03..2748fde4b90c 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6063,7 +6063,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } void -il4965_mac_channel_switch(struct ieee80211_hw *hw, +il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct il_priv *il = hw->priv; diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 337dfcf3bbde..3a57f71b8ed5 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -187,8 +187,9 @@ int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 buf_size); int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -void il4965_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch); +void +il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel_switch *ch_switch); void il4965_led_enable(struct il_priv *il); diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2364a3c09b9e..a967bf893a89 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -941,6 +941,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, } static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 575c8f6d4009..6ad3fcedab9b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5177,10 +5177,11 @@ out: } static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int ret; wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); @@ -5190,14 +5191,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); if (unlikely(wl->state == WLCORE_STATE_OFF)) { - wl12xx_for_each_wlvif_sta(wl, wlvif) { - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); - - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; - + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ieee80211_chswitch_done(vif, false); - } goto out; } else if (unlikely(wl->state != WLCORE_STATE_ON)) { goto out; @@ -5208,11 +5203,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, goto out; /* TODO: change mac80211 to pass vif as param */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - unsigned long delay_usec; - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { + unsigned long delay_usec; ret = wl->ops->channel_switch(wl, wlvif, ch_switch); if (ret) @@ -5222,10 +5215,10 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, /* indicate failure 5 seconds after channel switch time */ delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) * - ch_switch->count; + ch_switch->count; ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work, - usecs_to_jiffies(delay_usec) + - msecs_to_jiffies(5000)); + usecs_to_jiffies(delay_usec) + + msecs_to_jiffies(5000)); } out_sleep: diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7861ed875c4d..9bb2fc73aeaa 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2969,6 +2969,7 @@ struct ieee80211_ops { void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch); int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 0a6090644769..1bbb0790264f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -764,12 +764,13 @@ static inline void drv_flush(struct ieee80211_local *local, } static inline void drv_channel_switch(struct ieee80211_local *local, - struct ieee80211_channel_switch *ch_switch) + struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch) { might_sleep(); - trace_drv_channel_switch(local, ch_switch); - local->ops->channel_switch(&local->hw, ch_switch); + trace_drv_channel_switch(local, sdata, ch_switch); + local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); trace_drv_return_void(local); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 148253c1bd78..fb6561509caf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1134,21 +1134,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, chanctx = container_of(conf, struct ieee80211_chanctx, conf); - if (local->use_chanctx) { - u32 num_chanctx = 0; - list_for_each_entry(chanctx, &local->chanctx_list, list) - num_chanctx++; - - if (num_chanctx > 1 || - !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { - sdata_info(sdata, - "not handling chan-switch with channel contexts\n"); - ieee80211_queue_work(&local->hw, - &ifmgd->csa_connection_drop_work); - mutex_unlock(&local->chanctx_mtx); - mutex_unlock(&local->mtx); - return; - } + if (local->use_chanctx && + !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { + sdata_info(sdata, + "driver doesn't support chan-switch with channel contexts\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + return; } ch_switch.timestamp = timestamp; @@ -1192,7 +1186,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (local->ops->channel_switch) { /* use driver's channel switch callback */ - drv_channel_switch(local, &ch_switch); + drv_channel_switch(local, sdata, &ch_switch); return; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index ca0e12dd23c0..976606aebac9 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -987,12 +987,14 @@ TRACE_EVENT(drv_flush, TRACE_EVENT(drv_channel_switch, TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, struct ieee80211_channel_switch *ch_switch), - TP_ARGS(local, ch_switch), + TP_ARGS(local, sdata, ch_switch), TP_STRUCT__entry( LOCAL_ENTRY + VIF_ENTRY CHANDEF_ENTRY __field(u64, timestamp) __field(u32, device_timestamp) @@ -1002,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch, TP_fast_assign( LOCAL_ASSIGN; + VIF_ASSIGN; CHANDEF_ASSIGN(&ch_switch->chandef) __entry->timestamp = ch_switch->timestamp; __entry->device_timestamp = ch_switch->device_timestamp; @@ -1010,8 +1013,8 @@ TRACE_EVENT(drv_channel_switch, ), TP_printk( - LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", - LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count + LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d", + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count ) ); -- cgit v1.2.3 From 408b18abf677841f49d64ceb884e2b196ca1cf05 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 9 Oct 2014 20:36:22 +0200 Subject: mac80211: directly return ieee80211_vif_use_reserved_context() No need to store ieee80211_vif_use_reserved_context() result and test it before returning. Signed-off-by: Fabian Frederick Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'net') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9d58b30b096a..4bb2d34b2dd7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2901,11 +2901,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) if (sdata->reserved_ready) return 0; - err = ieee80211_vif_use_reserved_context(sdata); - if (err) - return err; - - return 0; + return ieee80211_vif_use_reserved_context(sdata); } if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, -- cgit v1.2.3 From 486cf4c08fe8b2b049bfccb76ce445ec1088fa25 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 10 Oct 2014 12:43:23 +0200 Subject: mac80211: enable DFS with channel contexts It is okay to enable DFS for channel contexts based drivers as long as no combination advertises radar detection and multi-channel operation at the same time. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/main.c | 5 +++-- net/mac80211/util.c | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 107d1c884de3..9e322dce64ec 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -785,13 +785,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) return -EINVAL; - /* DFS currently not supported with channel context drivers */ + /* DFS is not supported with multi-channel combinations yet */ for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { const struct ieee80211_iface_combination *comb; comb = &local->hw.wiphy->iface_combinations[i]; - if (comb->radar_detect_widths) + if (comb->radar_detect_widths && + comb->num_different_channels > 1) return -EINVAL; } } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3c61060a4d2b..c76c9d7294ae 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2526,11 +2526,23 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) struct ieee80211_local *local = container_of(work, struct ieee80211_local, radar_detected_work); struct cfg80211_chan_def chandef = local->hw.conf.chandef; + struct ieee80211_chanctx *ctx; + int num_chanctx = 0; + + mutex_lock(&local->chanctx_mtx); + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) + continue; + + num_chanctx++; + chandef = ctx->conf.def; + } + mutex_unlock(&local->chanctx_mtx); ieee80211_dfs_cac_cancel(local); - if (local->use_chanctx) - /* currently not handled */ + if (num_chanctx > 1) + /* XXX: multi-channel is not supported yet */ WARN_ON(1); else cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); -- cgit v1.2.3 From 2a84ee8625953fbce38b541aed77344044688a3e Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Tue, 7 Oct 2014 11:42:18 +0200 Subject: cfg80211: set the rates mask in connection probes over specified freq ATM, specifying the frequency when connecting sends a void 'supported rates' EID. Signed-off-by: Karl Beldan [fix memory leak in error path] Signed-off-by: Johannes Berg --- net/wireless/sme.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/wireless/sme.c b/net/wireless/sme.c index dc1668ff543b..0ab3711c79a0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -80,9 +80,18 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) if (!request) return -ENOMEM; - if (wdev->conn->params.channel) + if (wdev->conn->params.channel) { + enum ieee80211_band band = wdev->conn->params.channel->band; + struct ieee80211_supported_band *sband = + wdev->wiphy->bands[band]; + + if (!sband) { + kfree(request); + return -EINVAL; + } request->channels[0] = wdev->conn->params.channel; - else { + request->rates[band] = (1 << sband->n_bitrates) - 1; + } else { int i = 0, j; enum ieee80211_band band; struct ieee80211_supported_band *bands; -- cgit v1.2.3 From 89c771e5a62b856f4705f189892c489190edaec1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 10 Oct 2014 20:52:40 +0300 Subject: cfg80211: Convert del_station() callback to use a param struct This makes it easier to add new parameters for the del_station calls without having to modify all drivers that use this. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 4 ++-- drivers/net/wireless/ath/wil6210/cfg80211.c | 5 +++-- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 8 +++---- drivers/net/wireless/mwifiex/cfg80211.c | 9 ++++---- drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 4 +++- include/net/cfg80211.h | 15 +++++++++++-- net/mac80211/cfg.c | 6 +++--- net/wireless/nl80211.c | 8 ++++--- net/wireless/rdev-ops.h | 7 +++--- net/wireless/trace.h | 25 +++++++++++++++++++--- 10 files changed, 64 insertions(+), 27 deletions(-) (limited to 'net') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index ba60e37213eb..7a5337877a0c 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2976,11 +2976,11 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); - const u8 *addr = mac ? mac : bcast_addr; + const u8 *addr = params->mac ? params->mac : bcast_addr; return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index d9f4b30dd343..8fdfa3222a6e 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -792,12 +792,13 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, } static int wil_cfg80211_del_station(struct wiphy *wiphy, - struct net_device *dev, const u8 *mac) + struct net_device *dev, + struct station_del_parameters *params) { struct wil6210_priv *wil = wiphy_to_wil(wiphy); mutex_lock(&wil->mutex); - wil6210_disconnect(wil, mac); + wil6210_disconnect(wil, params->mac); mutex_unlock(&wil->mutex); return 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28fa25b509db..1a2e062d3bfd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3998,24 +3998,24 @@ brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, - const u8 *mac) + struct station_del_parameters *params) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_scb_val_le scbval; struct brcmf_if *ifp = netdev_priv(ndev); s32 err; - if (!mac) + if (!params->mac) return -EFAULT; - brcmf_dbg(TRACE, "Enter %pM\n", mac); + brcmf_dbg(TRACE, "Enter %pM\n", params->mac); if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; if (!check_vif_up(ifp->vif)) return -EIO; - memcpy(&scbval.ea, mac, ETH_ALEN); + memcpy(&scbval.ea, params->mac, ETH_ALEN); scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scbval)); diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 0dd672954ad1..71e29c7055de 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1239,7 +1239,7 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy, */ static int mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_sta_node *sta_node; @@ -1248,7 +1248,7 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, if (list_empty(&priv->sta_list) || !priv->bss_started) return 0; - if (!mac || is_broadcast_ether_addr(mac)) { + if (!params->mac || is_broadcast_ether_addr(params->mac)) { wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__); list_for_each_entry(sta_node, &priv->sta_list, list) { if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH, @@ -1258,9 +1258,10 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, mwifiex_uap_del_sta_data(priv, sta_node); } } else { - wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac); + wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, + params->mac); spin_lock_irqsave(&priv->sta_list_spinlock, flags); - sta_node = mwifiex_get_sta_entry(priv, mac); + sta_node = mwifiex_get_sta_entry(priv, params->mac); spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); if (sta_node) { if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH, diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index bd6953af0a03..3d26955da724 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -2856,8 +2856,10 @@ static int cfg80211_rtw_add_station(struct wiphy *wiphy, } static int cfg80211_rtw_del_station(struct wiphy *wiphy, - struct net_device *ndev, const u8 *mac) + struct net_device *ndev, + struct station_del_parameters *params) { + const u8 *mac = params->mac; int ret = 0; struct list_head *phead, *plist, *ptmp; u8 updated = 0; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3f3aaa06adb5..ebb69f671979 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -798,6 +798,17 @@ struct station_parameters { bool opmode_notif_used; }; +/** + * struct station_del_parameters - station deletion parameters + * + * Used to delete a station entry (or all stations). + * + * @mac: MAC address of the station to remove or NULL to remove all stations + */ +struct station_del_parameters { + const u8 *mac; +}; + /** * enum cfg80211_station_type - the type of station being modified * @CFG80211_STA_AP_CLIENT: client of an AP interface @@ -2132,7 +2143,7 @@ struct cfg80211_qos_map { * @stop_ap: Stop being an AP, including stopping beaconing. * * @add_station: Add a new station. - * @del_station: Remove a station; @mac may be NULL to remove all stations. + * @del_station: Remove a station * @change_station: Modify a given station. Note that flags changes are not much * validated in cfg80211, in particular the auth/assoc/authorized flags * might come to the driver in invalid combinations -- make sure to check @@ -2378,7 +2389,7 @@ struct cfg80211_ops { const u8 *mac, struct station_parameters *params); int (*del_station)(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac); + struct station_del_parameters *params); int (*change_station)(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4bb2d34b2dd7..a1498416ad55 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1225,14 +1225,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct ieee80211_sub_if_data *sdata; sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (mac) - return sta_info_destroy_addr_bss(sdata, mac); + if (params->mac) + return sta_info_destroy_addr_bss(sdata, params->mac); sta_info_flush(sdata); return 0; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d527aa0706c1..40cf7b937926 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4398,10 +4398,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; - u8 *mac_addr = NULL; + struct station_del_parameters params; + + memset(¶ms, 0, sizeof(params)); if (info->attrs[NL80211_ATTR_MAC]) - mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]); if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && @@ -4412,7 +4414,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_station) return -EOPNOTSUPP; - return rdev_del_station(rdev, dev, mac_addr); + return rdev_del_station(rdev, dev, ¶ms); } static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c09e697bcb15..71b1db3cc645 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -178,11 +178,12 @@ static inline int rdev_add_station(struct cfg80211_registered_device *rdev, } static inline int rdev_del_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac) + struct net_device *dev, + struct station_del_parameters *params) { int ret; - trace_rdev_del_station(&rdev->wiphy, dev, mac); - ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); + trace_rdev_del_station(&rdev->wiphy, dev, params); + ret = rdev->ops->del_station(&rdev->wiphy, dev, params); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 8e4f8f04332d..b1339400631d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -680,9 +680,28 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) ); -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) +DECLARE_EVENT_CLASS(station_del, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct station_del_parameters *params), + TP_ARGS(wiphy, netdev, params), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(sta_mac) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(sta_mac, params->mac); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) +); + +DEFINE_EVENT(station_del, rdev_del_station, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct station_del_parameters *params), + TP_ARGS(wiphy, netdev, params) ); DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, -- cgit v1.2.3 From 988568669d171774b96e59fe35ef575df7f8cffd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 20 Oct 2014 13:20:45 +0300 Subject: cfg80211: Specify frame and reason code for NL80211_CMD_DEL_STATION The optional NL80211_ATTR_MGMT_SUBTYPE and NL80211_ATTR_REASON_CODE attributes can now be included in NL80211_CMD_DEL_STATION to indicate to the driver which frame (Deauthentication/Disassociation) and reason code in that frame should be used to indicate removal to the specific station. This is used by drivers that implement AP SME and generate those frames internally. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 5 +++++ include/uapi/linux/nl80211.h | 6 +++++- net/wireless/nl80211.c | 21 +++++++++++++++++++++ net/wireless/trace.h | 10 ++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ebb69f671979..ed896c0b5b8b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -804,9 +804,14 @@ struct station_parameters { * Used to delete a station entry (or all stations). * * @mac: MAC address of the station to remove or NULL to remove all stations + * @subtype: Management frame subtype to use for indicating removal + * (10 = Disassociation, 12 = Deauthentication) + * @reason_code: Reason code for the Disassociation/Deauthentication frame */ struct station_del_parameters { const u8 *mac; + u8 subtype; + u16 reason_code; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 846071b0cde9..b553c48404d3 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -227,7 +227,11 @@ * the interface identified by %NL80211_ATTR_IFINDEX. * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC * or, if no MAC address given, all stations, on the interface identified - * by %NL80211_ATTR_IFINDEX. + * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and + * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type + * of disconnection indication should be sent to the station + * (Deauthentication or Disassociation frame and reason code for that + * frame). * * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to * destination %NL80211_ATTR_MAC on the interface identified by diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 40cf7b937926..0c0f2045e1f8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4414,6 +4414,27 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_station) return -EOPNOTSUPP; + if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) { + params.subtype = + nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]); + if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 && + params.subtype != IEEE80211_STYPE_DEAUTH >> 4) + return -EINVAL; + } else { + /* Default to Deauthentication frame */ + params.subtype = IEEE80211_STYPE_DEAUTH >> 4; + } + + if (info->attrs[NL80211_ATTR_REASON_CODE]) { + params.reason_code = + nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); + if (params.reason_code == 0) + return -EINVAL; /* 0 is reserved */ + } else { + /* Default to reason code 2 */ + params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID; + } + return rdev_del_station(rdev, dev, ¶ms); } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b1339400631d..cdb2c2ef1ae1 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -688,14 +688,20 @@ DECLARE_EVENT_CLASS(station_del, WIPHY_ENTRY NETDEV_ENTRY MAC_ENTRY(sta_mac) + __field(u8, subtype) + __field(u16, reason_code) ), TP_fast_assign( WIPHY_ASSIGN; NETDEV_ASSIGN; MAC_ASSIGN(sta_mac, params->mac); + __entry->subtype = params->subtype; + __entry->reason_code = params->reason_code; ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT + ", subtype: %u, reason_code: %u", + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), + __entry->subtype, __entry->reason_code) ); DEFINE_EVENT(station_del, rdev_del_station, -- cgit v1.2.3 From b08cc24e0a24f8d67ba7d66dab43c40ed25a3f5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Oct 2014 21:36:04 +0200 Subject: mac80211: fix change flags variable signedness This showed up as a sparse warning (with higher verbosity) and is certainly correct - the change flags should be unsigned. It's not that important since high flag numbers aren't used and bitwise operations would still work. Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a1498416ad55..acebf2c5bb0c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3108,7 +3108,8 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel_switch ch_switch; struct ieee80211_chanctx_conf *conf; struct ieee80211_chanctx *chanctx; - int err, changed = 0; + u32 changed = 0; + int err; sdata_assert_lock(sdata); lockdep_assert_held(&local->mtx); -- cgit v1.2.3 From d4d141cae804a430054f4138fa177229114f203a Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:45:59 +0200 Subject: mac80211: minstrel_ht: Increase the range of handled rate indexes Since 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability"), the rate indexes are manipulated via u8's and hence allow for a maximum of 256 mcs_group entries in minstrel_mcs_groups. ATM, minstrel_ht advertizes support up to 3HTSS@40MHz, consuming: 8(MCS_GROUP_RATES) * (3(SS)*2(GI)*2(BW)+1(CCK)), i.e. 104 entries. Support for 3VHTSS@80MHz will require: 10(MCS_GROUP_RATES) * (3(SS)*2(GI)*2(BW)+1(CCK)) + 10(MCS_GROUP_RATES) * (3(SS)*2(GI)*3(BW)), i.e. 130 + 180 entries. This change moves from u8s to u16s where necessary. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 16 ++++++++-------- net/mac80211/rc80211_minstrel_ht.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 17ef54a7a492..ccec718c29f9 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -240,8 +240,8 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) * MCS groups, CCK rates do not provide aggregation and are therefore at last. */ static void -minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, - u8 *tp_list) +minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index, + u16 *tp_list) { int cur_group, cur_idx, cur_thr, cur_prob; int tmp_group, tmp_idx, tmp_thr, tmp_prob; @@ -278,7 +278,7 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, * Find and set the topmost probability rate per sta and per group */ static void -minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) +minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index) { struct minstrel_mcs_group_data *mg; struct minstrel_rate_stats *mr; @@ -321,8 +321,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) */ static void minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, - u8 tmp_mcs_tp_rate[MAX_THR_RATES], - u8 tmp_cck_tp_rate[MAX_THR_RATES]) + u16 tmp_mcs_tp_rate[MAX_THR_RATES], + u16 tmp_cck_tp_rate[MAX_THR_RATES]) { unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; int i; @@ -386,8 +386,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) struct minstrel_mcs_group_data *mg; struct minstrel_rate_stats *mr; int group, i, j; - u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; - u8 tmp_cck_tp_rate[MAX_THR_RATES], index; + u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; if (mi->ampdu_packets > 0) { mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, @@ -517,7 +517,7 @@ minstrel_next_sample_idx(struct minstrel_ht_sta *mi) } static void -minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) +minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) { int group, orig_group; diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index 01570e0e014b..8b54e894b197 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -34,8 +34,8 @@ struct minstrel_mcs_group_data { u8 supported; /* sorted rate set within a MCS group*/ - u8 max_group_tp_rate[MAX_THR_RATES]; - u8 max_group_prob_rate; + u16 max_group_tp_rate[MAX_THR_RATES]; + u16 max_group_prob_rate; /* MCS rate statistics */ struct minstrel_rate_stats rates[MCS_GROUP_RATES]; @@ -52,8 +52,8 @@ struct minstrel_ht_sta { unsigned int avg_ampdu_len; /* overall sorted rate set */ - u8 max_tp_rate[MAX_THR_RATES]; - u8 max_prob_rate; + u16 max_tp_rate[MAX_THR_RATES]; + u16 max_prob_rate; /* time of last status update */ unsigned long stats_update; -- cgit v1.2.3 From 8a0ee4fe1951af252b1ac7b5c6af4083bafc4c7e Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:46:00 +0200 Subject: mac80211: minstrel_ht: macros adjustments for future VHT_GROUPs No functional change. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 51 +++++++++++++++--------------- net/mac80211/rc80211_minstrel_ht.h | 15 +++++++-- net/mac80211/rc80211_minstrel_ht_debugfs.c | 10 +++--- 3 files changed, 42 insertions(+), 34 deletions(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index ccec718c29f9..a48eb76440c6 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -34,12 +34,16 @@ /* Transmit duration for the raw data part of an average sized packet */ #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) +#define BW_20 0 +#define BW_40 1 + /* * Define group sort order: HT40 -> SGI -> #streams */ #define GROUP_IDX(_streams, _sgi, _ht40) \ + MINSTREL_HT_GROUP_0 + \ MINSTREL_MAX_STREAMS * 2 * _ht40 + \ - MINSTREL_MAX_STREAMS * _sgi + \ + MINSTREL_MAX_STREAMS * _sgi + \ _streams - 1 /* MCS rate information for an MCS group */ @@ -76,13 +80,13 @@ CCK_ACK_DURATION(55, _short), \ CCK_ACK_DURATION(110, _short) -#define CCK_GROUP \ - [MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS] = { \ - .streams = 0, \ - .duration = { \ - CCK_DURATION_LIST(false), \ - CCK_DURATION_LIST(true) \ - } \ +#define CCK_GROUP \ + [MINSTREL_CCK_GROUP] = { \ + .streams = 0, \ + .duration = { \ + CCK_DURATION_LIST(false), \ + CCK_DURATION_LIST(true) \ + } \ } /* @@ -91,38 +95,36 @@ * use. * * Sortorder has to be fixed for GROUP_IDX macro to be applicable: - * HT40 -> SGI -> #streams + * BW -> SGI -> #streams */ const struct mcs_group minstrel_mcs_groups[] = { - MCS_GROUP(1, 0, 0), - MCS_GROUP(2, 0, 0), + MCS_GROUP(1, 0, BW_20), + MCS_GROUP(2, 0, BW_20), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, 0), + MCS_GROUP(3, 0, BW_20), #endif - MCS_GROUP(1, 1, 0), - MCS_GROUP(2, 1, 0), + MCS_GROUP(1, 1, BW_20), + MCS_GROUP(2, 1, BW_20), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, 0), + MCS_GROUP(3, 1, BW_20), #endif - MCS_GROUP(1, 0, 1), - MCS_GROUP(2, 0, 1), + MCS_GROUP(1, 0, BW_40), + MCS_GROUP(2, 0, BW_40), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, 1), + MCS_GROUP(3, 0, BW_40), #endif - MCS_GROUP(1, 1, 1), - MCS_GROUP(2, 1, 1), + MCS_GROUP(1, 1, BW_40), + MCS_GROUP(2, 1, BW_40), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, 1), + MCS_GROUP(3, 1, BW_40), #endif - /* must be last */ CCK_GROUP }; -#define MINSTREL_CCK_GROUP (ARRAY_SIZE(minstrel_mcs_groups) - 1) static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; @@ -971,8 +973,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, if (!sta->ht_cap.ht_supported) goto use_legacy; - BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != - MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); msp->is_ht = true; memset(mi, 0, sizeof(*mi)); diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index 8b54e894b197..e747ac668afe 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -13,8 +13,17 @@ * The number of streams can be changed to 2 to reduce code * size and memory footprint. */ -#define MINSTREL_MAX_STREAMS 3 -#define MINSTREL_STREAM_GROUPS 4 +#define MINSTREL_MAX_STREAMS 3 +#define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ + +#define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_HT_STREAM_GROUPS) +#define MINSTREL_CCK_GROUPS_NB 1 +#define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ + MINSTREL_CCK_GROUPS_NB) + +#define MINSTREL_HT_GROUP_0 0 +#define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) #define MCS_GROUP_RATES 8 @@ -80,7 +89,7 @@ struct minstrel_ht_sta { u8 cck_supported_short; /* MCS rate group info and statistics */ - struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; + struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; }; struct minstrel_ht_sta_priv { diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index d537bec93754..d2f53b867660 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -18,7 +18,6 @@ static char * minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) { - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; const struct mcs_group *mg; unsigned int j, tp, prob, eprob; char htmode = '2'; @@ -41,7 +40,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (!(mi->groups[i].supported & BIT(j))) continue; - if (i == max_mcs) + if (i == MINSTREL_CCK_GROUP) p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); else p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); @@ -52,7 +51,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; - if (i == max_mcs) { + if (i == MINSTREL_CCK_GROUP) { int r = bitrates[j % 4]; p += sprintf(p, " %2u.%1uM", r / 10, r % 10); } else { @@ -85,7 +84,6 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_debugfs_info *ms; unsigned int i; - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; char *p; int ret; @@ -106,8 +104,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) "ret *ok(*cum) ok( cum)\n"); - p = minstrel_ht_stats_dump(mi, max_mcs, p); - for (i = 0; i < max_mcs; i++) + p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); + for (i = 0; i < MINSTREL_CCK_GROUP; i++) p = minstrel_ht_stats_dump(mi, i, p); p += sprintf(p, "\nTotal packet count:: ideal %d " -- cgit v1.2.3 From 3ec373c421b6efc41b84b20265b4381beb1d7908 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:46:01 +0200 Subject: mac80211: minstrel_ht: include type (cck/ht) in rates flag ATM, we grep cck rates idx with idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP. Matching neither-cck-non-ht rates could be done by replacing '==' with '>', however it would be less versatile or explicit. This will allow to match VHT rates with IEEE80211_TX_RC_VHT_MCS. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index a48eb76440c6..e760d3d71fe1 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -51,6 +51,7 @@ [GROUP_IDX(_streams, _sgi, _ht40)] = { \ .streams = _streams, \ .flags = \ + IEEE80211_TX_RC_MCS | \ (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ .duration = { \ @@ -83,6 +84,7 @@ #define CCK_GROUP \ [MINSTREL_CCK_GROUP] = { \ .streams = 0, \ + .flags = 0, \ .duration = { \ CCK_DURATION_LIST(false), \ CCK_DURATION_LIST(true) \ @@ -716,7 +718,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; struct minstrel_rate_stats *mr; u8 idx; - u16 flags; + u16 flags = group->flags; mr = minstrel_get_ratestats(mi, index); if (!mr->retry_updated) @@ -732,13 +734,10 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; } - if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { + if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; - flags = 0; - } else { + else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; - flags = IEEE80211_TX_RC_MCS | group->flags; - } if (offset > 0) { ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; @@ -918,13 +917,12 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); rate->idx = mp->cck_rates[idx]; - rate->flags = 0; - return; + } else { + rate->idx = sample_idx % MCS_GROUP_RATES + + (sample_group->streams - 1) * 8; } - rate->idx = sample_idx % MCS_GROUP_RATES + - (sample_group->streams - 1) * 8; - rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; + rate->flags = sample_group->flags; } static void @@ -1006,14 +1004,16 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, mi->tx_flags |= IEEE80211_TX_CTL_LDPC; for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + mi->groups[i].supported = 0; if (i == MINSTREL_CCK_GROUP) { minstrel_ht_update_cck(mp, mi, sband, sta); continue; } - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) continue; } else { @@ -1022,7 +1022,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, } } - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH && + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH && sta->bandwidth < IEEE80211_STA_RX_BW_40) continue; -- cgit v1.2.3 From 9208247d74bc52dcaf370ba3cee29b5e8775464b Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Tue, 21 Oct 2014 10:38:38 +0200 Subject: mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz When the new CONFIG_MAC80211_RC_MINSTREL_VHT is not set (default 'N'), there is no behavioral change including in sampling and MCS_GROUP_RATES remains 8. Otherwise MCS_GROUP_RATES is 10, and a module parameter *vht_only* (default 'true'), restricts the rates selection to VHT when VHT is supported. Regarding the debugfs stats buffer: It is explicitly increased from 8k to 32k to fit every rates incl. when both HT and VHT rates are enabled, as for the format, before: type rate tpt eprob *prob ret *ok(*cum) ok( cum) HT20/LGI ABCDP MCS0 0.0 0.0 0.0 1 0( 0) 0( 0) after: type rate tpt eprob *prob ret *ok(*cum) ok( cum) HT20/LGI ABCDP MCS0 0.0 0.0 0.0 1 0( 0) 0( 0) VHT40/LGI MCS5/2 0.0 0.0 0.0 0 0( 0) 0( 0) Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/Kconfig | 7 + net/mac80211/rc80211_minstrel_ht.c | 216 +++++++++++++++++++++++++++-- net/mac80211/rc80211_minstrel_ht.h | 17 ++- net/mac80211/rc80211_minstrel_ht_debugfs.c | 23 +-- 4 files changed, 241 insertions(+), 22 deletions(-) (limited to 'net') diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index aeb6a483b3bc..67cf8125d75d 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -33,6 +33,13 @@ config MAC80211_RC_MINSTREL_HT ---help--- This option enables the 'minstrel_ht' TX rate control algorithm +config MAC80211_RC_MINSTREL_VHT + bool "Minstrel 802.11ac support" if EXPERT + depends on MAC80211_RC_MINSTREL_HT + default n + ---help--- + This option enables VHT in the 'minstrel_ht' TX rate control algorithm + choice prompt "Default rate control algorithm" depends on MAC80211_HAS_RC diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index e760d3d71fe1..46666818719b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "rate.h" @@ -36,6 +37,7 @@ #define BW_20 0 #define BW_40 1 +#define BW_80 2 /* * Define group sort order: HT40 -> SGI -> #streams @@ -66,6 +68,47 @@ } \ } +#define VHT_GROUP_IDX(_streams, _sgi, _bw) \ + (MINSTREL_VHT_GROUP_0 + \ + MINSTREL_MAX_STREAMS * 2 * (_bw) + \ + MINSTREL_MAX_STREAMS * (_sgi) + \ + (_streams) - 1) + +#define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +#define VHT_GROUP(_streams, _sgi, _bw) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ + (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH : \ + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 117, 54, 26)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 234, 108, 52)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 351, 162, 78)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 468, 216, 104)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 702, 324, 156)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 936, 432, 208)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1053, 486, 234)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1170, 540, 260)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1404, 648, 312)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1560, 720, 346)) \ + } \ +} + #define CCK_DURATION(_bitrate, _short, _len) \ (1000 * (10 /* SIFS */ + \ (_short ? 72 + 24 : 144 + 48) + \ @@ -91,6 +134,13 @@ } \ } +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +static bool minstrel_vht_only = true; +module_param(minstrel_vht_only, bool, 0644); +MODULE_PARM_DESC(minstrel_vht_only, + "Use only VHT rates when VHT is supported by sta."); +#endif + /* * To enable sufficiently targeted rate sampling, MCS rates are divided into * groups, based on the number of streams and flags (HT40, SGI) that they @@ -124,15 +174,91 @@ const struct mcs_group minstrel_mcs_groups[] = { MCS_GROUP(3, 1, BW_40), #endif - CCK_GROUP -}; + CCK_GROUP, + +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_20), +#endif + + VHT_GROUP(1, 1, BW_20), + VHT_GROUP(2, 1, BW_20), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_20), +#endif + VHT_GROUP(1, 0, BW_40), + VHT_GROUP(2, 0, BW_40), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_40), +#endif + + VHT_GROUP(1, 1, BW_40), + VHT_GROUP(2, 1, BW_40), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_40), +#endif + + VHT_GROUP(1, 0, BW_80), + VHT_GROUP(2, 0, BW_80), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_80), +#endif + + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_80), +#endif +#endif +}; static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; static void minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); +/* + * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer) + * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1 + * + * Returns the valid mcs map for struct minstrel_mcs_group_data.supported + */ +static u16 +minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map) +{ + u16 mask = 0; + + if (bw == BW_20) { + if (nss != 3 && nss != 6) + mask = BIT(9); + } else if (bw == BW_80) { + if (nss == 3 || nss == 7) + mask = BIT(6); + else if (nss == 6) + mask = BIT(9); + } else { + WARN_ON(bw != BW_40); + } + + switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + mask |= 0x300; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + mask |= 0x200; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_9: + break; + default: + mask = 0x3ff; + } + + return 0x3ff & ~mask; +} + /* * Look up an MCS group index based on mac80211 rate information */ @@ -144,6 +270,15 @@ minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); } +static int +minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate) +{ + return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate), + !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), + !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + + 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)); +} + static struct minstrel_rate_stats * minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, struct ieee80211_tx_rate *rate) @@ -153,6 +288,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (rate->flags & IEEE80211_TX_RC_MCS) { group = minstrel_ht_get_group_idx(rate); idx = rate->idx % 8; + } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + group = minstrel_vht_get_group_idx(rate); + idx = ieee80211_rate_get_vht_mcs(rate); } else { group = MINSTREL_CCK_GROUP; @@ -489,7 +627,8 @@ minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rat if (!rate->count) return false; - if (rate->flags & IEEE80211_TX_RC_MCS) + if (rate->flags & IEEE80211_TX_RC_MCS || + rate->flags & IEEE80211_TX_RC_VHT_MCS) return true; return rate->idx == mp->cck_rates[0] || @@ -736,6 +875,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; + else if (flags & IEEE80211_TX_RC_VHT_MCS) + idx = ((group->streams - 1) << 4) | + ((index % MCS_GROUP_RATES) & 0xF); else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; @@ -917,6 +1059,9 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); rate->idx = mp->cck_rates[idx]; + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); } else { rate->idx = sample_idx % MCS_GROUP_RATES + (sample_group->streams - 1) * 8; @@ -962,6 +1107,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, struct minstrel_ht_sta *mi = &msp->ht; struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; u16 sta_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + int use_vht; int n_supported = 0; int ack_dur; int stbc; @@ -973,6 +1120,13 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + if (vht_cap->vht_supported) + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); + else +#endif + use_vht = 0; + msp->is_ht = true; memset(mi, 0, sizeof(*mi)); @@ -996,15 +1150,19 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, } mi->sample_tries = 4; - stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> - IEEE80211_HT_CAP_RX_STBC_SHIFT; - mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { + stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; + mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; - if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) - mi->tx_flags |= IEEE80211_TX_CTL_LDPC; + if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) + mi->tx_flags |= IEEE80211_TX_CTL_LDPC; + } for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; mi->groups[i].supported = 0; if (i == MINSTREL_CCK_GROUP) { @@ -1026,13 +1184,47 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, sta->bandwidth < IEEE80211_STA_RX_BW_40) continue; + nss = minstrel_mcs_groups[i].streams; + /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ - if (sta->smps_mode == IEEE80211_SMPS_STATIC && - minstrel_mcs_groups[i].streams > 1) + if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) + continue; + + /* HT rate */ + if (gflags & IEEE80211_TX_RC_MCS) { +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + if (minstrel_vht_only) + continue; +#endif + mi->groups[i].supported = mcs->rx_mask[nss - 1]; + if (mi->groups[i].supported) + n_supported++; + continue; + } + + /* VHT rate */ + if (!vht_cap->vht_supported || + WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) || + WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH)) continue; - mi->groups[i].supported = - mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; + if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) { + if (sta->bandwidth < IEEE80211_STA_RX_BW_80 || + ((gflags & IEEE80211_TX_RC_SHORT_GI) && + !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { + continue; + } + } + + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = BW_40; + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) + bw = BW_80; + else + bw = BW_20; + + mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss, + vht_cap->vht_mcs.tx_mcs_map); if (mi->groups[i].supported) n_supported++; diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index e747ac668afe..f2217d6aa0c2 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -15,17 +15,30 @@ */ #define MINSTREL_MAX_STREAMS 3 #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +#define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ +#else +#define MINSTREL_VHT_STREAM_GROUPS 0 +#endif #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ MINSTREL_HT_STREAM_GROUPS) +#define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_VHT_STREAM_GROUPS) #define MINSTREL_CCK_GROUPS_NB 1 #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ + MINSTREL_VHT_GROUPS_NB + \ MINSTREL_CCK_GROUPS_NB) #define MINSTREL_HT_GROUP_0 0 #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) +#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) -#define MCS_GROUP_RATES 8 +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +#define MCS_GROUP_RATES 10 +#else +#define MCS_GROUP_RATES 8 +#endif struct mcs_group { u32 flags; @@ -40,7 +53,7 @@ struct minstrel_mcs_group_data { u8 column; /* bitfield of supported MCS rates of this group */ - u8 supported; + u16 supported; /* sorted rate set within a MCS group*/ u16 max_group_tp_rate[MAX_THR_RATES]; diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index d2f53b867660..52bb6ef55b19 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -29,6 +29,8 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) mg = &minstrel_mcs_groups[i]; if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) htmode = '4'; + else if (mg->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + htmode = '8'; if (mg->flags & IEEE80211_TX_RC_SHORT_GI) gimode = 'S'; @@ -41,9 +43,11 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) continue; if (i == MINSTREL_CCK_GROUP) - p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); + p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); + else if (i >= MINSTREL_VHT_GROUP_0) + p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode); else - p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); + p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; @@ -53,9 +57,11 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (i == MINSTREL_CCK_GROUP) { int r = bitrates[j % 4]; - p += sprintf(p, " %2u.%1uM", r / 10, r % 10); + p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); + } else if (i >= MINSTREL_VHT_GROUP_0) { + p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); } else { - p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); + p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); } tp = mr->cur_tp / 10; @@ -94,19 +100,20 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) return ret; } - ms = kmalloc(8192, GFP_KERNEL); + ms = kmalloc(32768, GFP_KERNEL); if (!ms) return -ENOMEM; file->private_data = ms; p = ms->buf; - p += sprintf(p, "type rate tpt eprob *prob " + p += sprintf(p, " type rate tpt eprob *prob " "ret *ok(*cum) ok( cum)\n"); - p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); for (i = 0; i < MINSTREL_CCK_GROUP; i++) p = minstrel_ht_stats_dump(mi, i, p); + for (i++; i < ARRAY_SIZE(mi->groups); i++) + p = minstrel_ht_stats_dump(mi, i, p); p += sprintf(p, "\nTotal packet count:: ideal %d " "lookaround %d\n", @@ -117,7 +124,7 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); ms->len = p - ms->buf; - WARN_ON(ms->len + sizeof(*ms) > 8192); + WARN_ON(ms->len + sizeof(*ms) > 32768); return nonseekable_open(inode, file); } -- cgit v1.2.3 From 5c6761adc77c131ef1601016f9ebbad0a9ae6d1a Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 21 Oct 2014 18:20:12 +0200 Subject: mac80211: remove unnecessary null test before debugfs_remove() The debugfs_remove() function can safely take NULL parameters so the additionally null test isn't required, and there's no other reason to have it here, so remove it. Signed-off-by: Fabian Frederick [rewrite commit message, re-introduce blank line after assert] Signed-off-by: Johannes Berg --- net/mac80211/debugfs_key.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 1521cabad3d6..5523b94c7c90 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -300,10 +300,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&sdata->local->key_mtx); - if (sdata->debugfs.default_unicast_key) { - debugfs_remove(sdata->debugfs.default_unicast_key); - sdata->debugfs.default_unicast_key = NULL; - } + debugfs_remove(sdata->debugfs.default_unicast_key); + sdata->debugfs.default_unicast_key = NULL; if (sdata->default_unicast_key) { key = key_mtx_dereference(sdata->local, @@ -314,10 +312,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) sdata->vif.debugfs_dir, buf); } - if (sdata->debugfs.default_multicast_key) { - debugfs_remove(sdata->debugfs.default_multicast_key); - sdata->debugfs.default_multicast_key = NULL; - } + debugfs_remove(sdata->debugfs.default_multicast_key); + sdata->debugfs.default_multicast_key = NULL; if (sdata->default_multicast_key) { key = key_mtx_dereference(sdata->local, -- cgit v1.2.3 From 723e73acd16d2ea08cdbd8b449b7bc69389b94d4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Oct 2014 09:25:06 +0200 Subject: cfg80211: make WMM TSPEC support flag an nl80211 feature flag During the review of the corresponding wpa_supplicant patches we noticed that the only way for it to detect that this functionality is supported currently is to check for the command support. This can be misleading though, as the command was also designed to, in the future, support pure 802.11 TSPECs. Expose the WMM-TSPEC feature flag to nl80211 so later we can also expose an 802.11-TSPEC feature flag (if needed) to differentiate the two cases. Note: this change isn't needed in 3.18 as there's no driver there yet that supports the functionality at all. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 6 +----- include/uapi/linux/nl80211.h | 5 +++++ net/wireless/nl80211.c | 14 ++++++-------- 3 files changed, 12 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ed896c0b5b8b..77aa805d7e7c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2646,13 +2646,9 @@ struct cfg80211_ops { * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in * beaconing mode (AP, IBSS, Mesh, ...). - * @WIPHY_FLAG_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM - * TSPEC sessions (TID aka TSID 0-7) with the NL80211_CMD_ADD_TX_TS - * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it - * needs to be able to handle Block-Ack agreements and other things. */ enum wiphy_flags { - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION = BIT(0), + /* use hole at 0 */ /* use hole at 1 */ /* use hole at 2 */ WIPHY_FLAG_NETNS_OK = BIT(3), diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index b553c48404d3..be1d5def304d 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4052,6 +4052,10 @@ enum nl80211_ap_sme_features { * multiplexing powersave, ie. can turn off all but one chain * and then wake the rest up as required after, for example, * rts/cts handshake. + * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM + * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS + * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it + * needs to be able to handle Block-Ack agreements and other things. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4080,6 +4084,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, NL80211_FEATURE_STATIC_SMPS = 1 << 24, NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d05fe6d6481d..d98d4ea27819 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1514,8 +1514,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) CMD(channel_switch, CHANNEL_SWITCH); CMD(set_qos_map, SET_QOS_MAP); - if (rdev->wiphy.flags & - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) + if (rdev->wiphy.features & + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION) CMD(add_tx_ts, ADD_TX_TS); } /* add into the if now */ @@ -9557,7 +9557,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) u16 admitted_time = 0; int err; - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) + if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)) return -EOPNOTSUPP; if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || @@ -9573,12 +9573,10 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* WMM uses TIDs 0-7 even for TSPEC */ - if (tsid < IEEE80211_FIRST_TSPEC_TSID) { - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) - return -EINVAL; - } else { + if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { /* TODO: handle 802.11 TSPEC/admission control - * need more attributes for that (e.g. BA session requirement) + * need more attributes for that (e.g. BA session requirement); + * change the WMM adminssion test above to allow both then */ return -EINVAL; } -- cgit v1.2.3 From f409079bb678600be0201cd03afb4731f0480b4e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 8 Oct 2014 14:37:47 +0200 Subject: mac80211: sanity check CW_min/CW_max towards driver There's no reason to ever set invalid CW_min/CW_max to the drivers, we should catch it in higher layers. However, the consequences of setting it wrong can be quite severe, so double-check at a low level and error out for invalid data. Signed-off-by: Johannes Berg --- net/mac80211/driver-ops.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net') diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 1bbb0790264f..3df28e0fa045 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -631,6 +631,12 @@ static inline int drv_conf_tx(struct ieee80211_local *local, if (!check_sdata_in_driver(sdata)) return -EIO; + if (WARN_ONCE(params->cw_min == 0 || + params->cw_min > params->cw_max, + "%s: invalid CW_min/CW_max: %d/%d\n", + sdata->name, params->cw_min, params->cw_max)) + return -EINVAL; + trace_drv_conf_tx(local, sdata, ac, params); if (local->ops->conf_tx) ret = local->ops->conf_tx(&local->hw, &sdata->vif, -- cgit v1.2.3 From 02219b3abca59fca81711bfe7ee78df7abad97ce Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 7 Oct 2014 10:38:50 +0300 Subject: mac80211: add WMM admission control support Use the currently existing APIs between mac80211 and the low level driver to implement WMM admission control. The low level driver needs to report the media time used by each transmitted packet in ieee80211_tx_status. Based on that information, mac80211 will modify the QoS parameters of the admission controlled Access Category when the limit is reached. Once the original QoS parameters can be restored, mac80211 will do so. One issue with this approach is that management frames will also erroneously be downgraded, but the upside is that the implementation is simple. In the future, it can be extended to driver- or device-based implementations that are better. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +- net/mac80211/agg-tx.c | 5 -- net/mac80211/cfg.c | 73 +++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 38 +++++++++++- net/mac80211/mlme.c | 142 +++++++++++++++++++++++++++++++++++++++++++-- net/mac80211/status.c | 3 +- net/mac80211/wme.c | 29 ++++++--- net/mac80211/wme.h | 2 - 8 files changed, 272 insertions(+), 23 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9bb2fc73aeaa..9dc5e7606322 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -739,7 +739,8 @@ struct ieee80211_tx_info { u8 ampdu_ack_len; u8 ampdu_len; u8 antenna; - void *status_driver_data[21 / sizeof(void *)]; + u16 tx_time; + void *status_driver_data[19 / sizeof(void *)]; } status; struct { struct ieee80211_tx_rate driver_rates[ diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index d6986f3aa5c4..9242c60048cf 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -149,11 +149,6 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); } -static inline int ieee80211_ac_from_tid(int tid) -{ - return ieee802_1d_to_ac[tid & 7]; -} - /* * When multiple aggregation sessions on multiple stations * are being created/destroyed simultaneously, we need to diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 64deb9aa0f81..d6b01ad2f7d7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -20,6 +20,7 @@ #include "cfg.h" #include "rate.h" #include "mesh.h" +#include "wme.h" static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, const char *name, @@ -3585,6 +3586,76 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy, return ret; } +static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev, + u8 tsid, const u8 *peer, u8 up, + u16 admitted_time) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + int ac = ieee802_1d_to_ac[up]; + + if (sdata->vif.type != NL80211_IFTYPE_STATION) + return -EOPNOTSUPP; + + if (!(sdata->wmm_acm & BIT(up))) + return -EINVAL; + + if (ifmgd->tx_tspec[ac].admitted_time) + return -EBUSY; + + if (admitted_time) { + ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time; + ifmgd->tx_tspec[ac].tsid = tsid; + ifmgd->tx_tspec[ac].up = up; + } + + return 0; +} + +static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev, + u8 tsid, const u8 *peer) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_local *local = wiphy_priv(wiphy); + int ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + + /* skip unused entries */ + if (!tx_tspec->admitted_time) + continue; + + if (tx_tspec->tsid != tsid) + continue; + + /* due to this new packets will be reassigned to non-ACM ACs */ + tx_tspec->up = -1; + + /* Make sure that all packets have been sent to avoid to + * restore the QoS params on packets that are still on the + * queues. + */ + synchronize_net(); + ieee80211_flush_queues(local, sdata); + + /* restore the normal QoS parameters + * (unconditionally to avoid races) + */ + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; + tx_tspec->downgraded = false; + ieee80211_sta_handle_tspec_ac_params(sdata); + + /* finally clear all the data */ + memset(tx_tspec, 0, sizeof(*tx_tspec)); + + return 0; + } + + return -ENOENT; +} + const struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -3663,4 +3734,6 @@ const struct cfg80211_ops mac80211_config_ops = { .channel_switch = ieee80211_channel_switch, .set_qos_map = ieee80211_set_qos_map, .set_ap_chanwidth = ieee80211_set_ap_chanwidth, + .add_tx_ts = ieee80211_add_tx_ts, + .del_tx_ts = ieee80211_del_tx_ts, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 78d6121eb372..60063be057d0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -399,6 +399,24 @@ struct ieee80211_mgd_assoc_data { u8 ie[]; }; +struct ieee80211_sta_tx_tspec { + /* timestamp of the first packet in the time slice */ + unsigned long time_slice_start; + + u32 admitted_time; /* in usecs, unlike over the air */ + u8 tsid; + s8 up; /* signed to be able to invalidate with -1 during teardown */ + + /* consumed TX time in microseconds in the time slice */ + u32 consumed_tx_time; + enum { + TX_TSPEC_ACTION_NONE = 0, + TX_TSPEC_ACTION_DOWNGRADE, + TX_TSPEC_ACTION_STOP_DOWNGRADE, + } action; + bool downgraded; +}; + struct ieee80211_if_managed { struct timer_list timer; struct timer_list conn_mon_timer; @@ -509,6 +527,16 @@ struct ieee80211_if_managed { u8 tdls_peer[ETH_ALEN] __aligned(2); struct delayed_work tdls_peer_del_work; + + /* WMM-AC TSPEC support */ + struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; + /* Use a separate work struct so that we can do something here + * while the sdata->work is flushing the queues, for example. + * otherwise, in scenarios where we hardly get any traffic out + * on the BE queue, but there's a lot of VO traffic, we might + * get stuck in a downgraded situation and flush takes forever. + */ + struct delayed_work tx_tspec_wk; }; struct ieee80211_if_ibss { @@ -1459,6 +1487,7 @@ void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, __le16 fc, bool acked); void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); +void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); @@ -1763,6 +1792,13 @@ static inline bool ieee80211_rx_reorder_ready(struct sk_buff_head *frames) return true; } +extern const int ieee802_1d_to_ac[8]; + +static inline int ieee80211_ac_from_tid(int tid) +{ + return ieee802_1d_to_ac[tid & 7]; +} + void ieee80211_dynamic_ps_enable_work(struct work_struct *work); void ieee80211_dynamic_ps_disable_work(struct work_struct *work); void ieee80211_dynamic_ps_timer(unsigned long data); @@ -1772,7 +1808,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr); void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr, bool ack); + struct ieee80211_hdr *hdr, bool ack, u16 tx_time); void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, unsigned long queues, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fb6561509caf..4d9b4d165ce8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1606,6 +1606,95 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work) mutex_unlock(&sdata->local->mtx); } +static bool +__ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + bool ret; + int ac; + + if (local->hw.queues < IEEE80211_NUM_ACS) + return false; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + int non_acm_ac; + unsigned long now = jiffies; + + if (tx_tspec->action == TX_TSPEC_ACTION_NONE && + tx_tspec->admitted_time && + time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->consumed_tx_time = 0; + tx_tspec->time_slice_start = now; + + if (tx_tspec->downgraded) + tx_tspec->action = + TX_TSPEC_ACTION_STOP_DOWNGRADE; + } + + switch (tx_tspec->action) { + case TX_TSPEC_ACTION_STOP_DOWNGRADE: + /* take the original parameters */ + if (drv_conf_tx(local, sdata, ac, &sdata->tx_conf[ac])) + sdata_err(sdata, + "failed to set TX queue parameters for queue %d\n", + ac); + tx_tspec->action = TX_TSPEC_ACTION_NONE; + tx_tspec->downgraded = false; + ret = true; + break; + case TX_TSPEC_ACTION_DOWNGRADE: + if (time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->action = TX_TSPEC_ACTION_NONE; + ret = true; + break; + } + /* downgrade next lower non-ACM AC */ + for (non_acm_ac = ac + 1; + non_acm_ac < IEEE80211_NUM_ACS; + non_acm_ac++) + if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac))) + break; + /* The loop will result in using BK even if it requires + * admission control, such configuration makes no sense + * and we have to transmit somehow - the AC selection + * does the same thing. + */ + if (drv_conf_tx(local, sdata, ac, + &sdata->tx_conf[non_acm_ac])) + sdata_err(sdata, + "failed to set TX queue parameters for queue %d\n", + ac); + tx_tspec->action = TX_TSPEC_ACTION_NONE; + ret = true; + schedule_delayed_work(&ifmgd->tx_tspec_wk, + tx_tspec->time_slice_start + HZ - now + 1); + break; + case TX_TSPEC_ACTION_NONE: + /* nothing now */ + break; + } + } + + return ret; +} + +void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) +{ + if (__ieee80211_sta_handle_tspec_ac_params(sdata)) + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); +} + +static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work) +{ + struct ieee80211_sub_if_data *sdata; + + sdata = container_of(work, struct ieee80211_sub_if_data, + u.mgd.tx_tspec_wk.work); + ieee80211_sta_handle_tspec_ac_params(sdata); +} + /* MLME */ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, @@ -1690,12 +1779,14 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, params.uapsd = uapsd; mlme_dbg(sdata, - "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n", queue, aci, acm, params.aifs, params.cw_min, params.cw_max, - params.txop, params.uapsd); + params.txop, params.uapsd, + ifmgd->tx_tspec[queue].downgraded); sdata->tx_conf[queue] = params; - if (drv_conf_tx(local, sdata, queue, ¶ms)) + if (!ifmgd->tx_tspec[queue].downgraded && + drv_conf_tx(local, sdata, queue, ¶ms)) sdata_err(sdata, "failed to set TX queue parameters for queue %d\n", queue); @@ -1958,6 +2049,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, } mutex_unlock(&local->mtx); + /* existing TX TSPEC sessions no longer exist */ + memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec)); + cancel_delayed_work_sync(&ifmgd->tx_tspec_wk); + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; } @@ -2010,9 +2105,46 @@ out: mutex_unlock(&local->mtx); } +static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr, + u16 tx_time) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; + int ac = ieee80211_ac_from_tid(tid); + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + unsigned long now = jiffies; + + if (likely(!tx_tspec->admitted_time)) + return; + + if (time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->consumed_tx_time = 0; + tx_tspec->time_slice_start = now; + + if (tx_tspec->downgraded) { + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); + } + } + + if (tx_tspec->downgraded) + return; + + tx_tspec->consumed_tx_time += tx_time; + + if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) { + tx_tspec->downgraded = true; + tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE; + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); + } +} + void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr, bool ack) + struct ieee80211_hdr *hdr, bool ack, u16 tx_time) { + ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time); + if (!ieee80211_is_data(hdr->frame_control)) return; @@ -3834,6 +3966,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) (unsigned long) sdata); setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, (unsigned long) sdata); + INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk, + ieee80211_sta_handle_tspec_ac_params_wk); ifmgd->flags = 0; ifmgd->powersave = sdata->wdev.ps; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 89290e33dafe..9612d89fad56 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -704,7 +704,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) - ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); + ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, + acked, info->status.tx_time); if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { if (info->flags & IEEE80211_TX_STAT_ACK) { diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 3b873989992c..d3c5672d775f 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -54,10 +54,18 @@ static int wme_downgrade_ac(struct sk_buff *skb) } static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb) + struct sta_info *sta, struct sk_buff *skb) { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + /* in case we are a client verify acm is not set for this ac */ - while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { + while (sdata->wmm_acm & BIT(skb->priority)) { + int ac = ieee802_1d_to_ac[skb->priority]; + + if (ifmgd->tx_tspec[ac].admitted_time && + skb->priority == ifmgd->tx_tspec[ac].up) + return ac; + if (wme_downgrade_ac(skb)) { /* * This should not really happen. The AP has marked all @@ -96,7 +104,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, p = ieee80211_get_qos_ctl(hdr); skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; - return ieee80211_downgrade_queue(sdata, skb); + return ieee80211_downgrade_queue(sdata, NULL, skb); } /* Indicate which queue to use. */ @@ -108,6 +116,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, const u8 *ra = NULL; bool qos = false; struct mac80211_qos_map *qos_map; + u16 ret; if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { skb->priority = 0; /* required for correct WPA/11i MIC */ @@ -148,27 +157,29 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, if (sta) qos = sta->sta.wme; } - rcu_read_unlock(); if (!qos) { skb->priority = 0; /* required for correct WPA/11i MIC */ - return IEEE80211_AC_BE; + ret = IEEE80211_AC_BE; + goto out; } if (skb->protocol == sdata->control_port_protocol) { skb->priority = 7; - return ieee80211_downgrade_queue(sdata, skb); + goto downgrade; } /* use the data classifier to determine what 802.1d tag the * data frame has */ - rcu_read_lock(); qos_map = rcu_dereference(sdata->qos_map); skb->priority = cfg80211_classify8021d(skb, qos_map ? &qos_map->qos_map : NULL); - rcu_read_unlock(); - return ieee80211_downgrade_queue(sdata, skb); + downgrade: + ret = ieee80211_downgrade_queue(sdata, sta, skb); + out: + rcu_read_unlock(); + return ret; } /** diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index 7fea4bb8acbc..80151edc5195 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h @@ -13,8 +13,6 @@ #include #include "ieee80211_i.h" -extern const int ieee802_1d_to_ac[8]; - u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_hdr *hdr); -- cgit v1.2.3 From 4619194a49bfbbb03d20d4ca45c3eb1dc8297d9d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Oct 2014 13:43:29 +0200 Subject: mac80211: don't remove tainted keys after not programming When a key is tainted during resume, it is no longer programmed into the device; however, it's uploaded flag may (will) be set. Clear the flag when not programming it because it's tainted to avoid attempting to remove it again later. Signed-off-by: Johannes Berg --- net/mac80211/key.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 4712150dc210..434a91ad12c8 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -94,8 +94,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) might_sleep(); - if (key->flags & KEY_FLAG_TAINTED) + if (key->flags & KEY_FLAG_TAINTED) { + /* If we get here, it's during resume and the key is + * tainted so shouldn't be used/programmed any more. + * However, its flags may still indicate that it was + * programmed into the device (since we're in resume) + * so clear that flag now to avoid trying to remove + * it again later. + */ + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; return -EINVAL; + } if (!key->local->ops->set_key) goto out_unsupported; -- cgit v1.2.3 From 8ec7886b1cd59c6e76a6d8fa413f9d338cfedc96 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Wed, 22 Oct 2014 18:20:37 +0200 Subject: mac80211: minstrel_ht: use group flags instead of index to display rates When displaying a rate through debugfs minstrel_ht guesses its flags comparing group indexes. Since 3ec373c421b6 ("mac80211: minstrel_ht: include type (cck/ht) in rates flag"), the rate flags of interest are present in the mcs_group-s, so use it. While improving the code, this also fixes a smatch false positive "error: testing array offset 'i' after use" in minstrel_ht_stats_dump. This warning only triggers after 9208247d74bc ("mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz") with CONFIG_MAC80211_RC_MINSTREL_VHT unset because then MINSTREL_VHT_GROUP_0 is above MINSTREL_GROUPS_NB and smatch only barks when the "testing array offset" seems to prevent possible out of bonds accesses (which does not happen here since i < ARRAY_SIZE(mi->groups)). Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht_debugfs.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 52bb6ef55b19..20c676b8e5b6 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -22,16 +22,19 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) unsigned int j, tp, prob, eprob; char htmode = '2'; char gimode = 'L'; + u32 gflags; if (!mi->groups[i].supported) return p; mg = &minstrel_mcs_groups[i]; - if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + gflags = mg->flags; + + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) htmode = '4'; - else if (mg->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) htmode = '8'; - if (mg->flags & IEEE80211_TX_RC_SHORT_GI) + if (gflags & IEEE80211_TX_RC_SHORT_GI) gimode = 'S'; for (j = 0; j < MCS_GROUP_RATES; j++) { @@ -42,12 +45,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (!(mi->groups[i].supported & BIT(j))) continue; - if (i == MINSTREL_CCK_GROUP) - p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); - else if (i >= MINSTREL_VHT_GROUP_0) + if (gflags & IEEE80211_TX_RC_MCS) + p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); + else if (gflags & IEEE80211_TX_RC_VHT_MCS) p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode); else - p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); + p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; @@ -55,13 +58,14 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; - if (i == MINSTREL_CCK_GROUP) { - int r = bitrates[j % 4]; - p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); - } else if (i >= MINSTREL_VHT_GROUP_0) { + if (gflags & IEEE80211_TX_RC_MCS) { + p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); + } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); } else { - p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); + int r = bitrates[j % 4]; + + p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); } tp = mr->cur_tp / 10; -- cgit v1.2.3 From a7f3a768289858f03f5c1866639c8b476c1b8ebc Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Wed, 22 Oct 2014 15:22:49 +0300 Subject: mac80211: export IE splitting function Export ieee80211_ie_split function, so it can be reused by drivers which need to insert additional elements. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 28 ++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 2 -- net/mac80211/util.c | 26 +------------------------- 3 files changed, 29 insertions(+), 27 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9dc5e7606322..96d224357c8c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4906,4 +4906,32 @@ void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf); void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer, enum nl80211_tdls_operation oper, u16 reason_code, gfp_t gfp); + +/** + * ieee80211_ie_split - split an IE buffer according to ordering + * + * @ies: the IE buffer + * @ielen: the length of the IE buffer + * @ids: an array with element IDs that are allowed before + * the split + * @n_ids: the size of the element ID array + * @offset: offset where to start splitting in the buffer + * + * This function splits an IE buffer by updating the @offset + * variable to point to the location where the buffer should be + * split. + * + * It assumes that the given IE buffer is well-formed, this + * has to be guaranteed by the caller! + * + * It also assumes that the IEs in the buffer are ordered + * correctly, if not the result of using this function will not + * be ordered correctly either, i.e. it does no reordering. + * + * The function returns the offset where the next part of the + * buffer starts, which may be @ielen if the entire (remainder) + * of the buffer should be used. + */ +size_t ieee80211_ie_split(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, size_t offset); #endif /* MAC80211_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 60063be057d0..146a818e52b5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1874,8 +1874,6 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); -size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u16 cap); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c76c9d7294ae..9247a960ea59 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2052,31 +2052,6 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } -/** - * ieee80211_ie_split - split an IE buffer according to ordering - * - * @ies: the IE buffer - * @ielen: the length of the IE buffer - * @ids: an array with element IDs that are allowed before - * the split - * @n_ids: the size of the element ID array - * @offset: offset where to start splitting in the buffer - * - * This function splits an IE buffer by updating the @offset - * variable to point to the location where the buffer should be - * split. - * - * It assumes that the given IE buffer is well-formed, this - * has to be guaranteed by the caller! - * - * It also assumes that the IEs in the buffer are ordered - * correctly, if not the result of using this function will not - * be ordered correctly either, i.e. it does no reordering. - * - * The function returns the offset where the next part of the - * buffer starts, which may be @ielen if the entire (remainder) - * of the buffer should be used. - */ size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset) { @@ -2087,6 +2062,7 @@ size_t ieee80211_ie_split(const u8 *ies, size_t ielen, return pos; } +EXPORT_SYMBOL(ieee80211_ie_split); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) { -- cgit v1.2.3 From 452218d9fd22505ed790e95b460b0f40cebb95a0 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:33:45 +0300 Subject: mac80211: fix network header breakage during encryption When an IV is generated, only the MAC header is moved back. The network header location remains the same relative to the skb head, as the new IV is using headroom space that was reserved in advance. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/wep.c | 2 -- net/mac80211/wpa.c | 5 ----- 2 files changed, 7 deletions(-) (limited to 'net') diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9181fb6d6437..a4220e92f0cc 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -111,8 +111,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) return newhdr + hdrlen; - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_WEP_IV_LEN); ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); return newhdr + hdrlen; } diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 983527a4c1ab..12398fde02e8 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -209,8 +209,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_TKIP_IV_LEN); pos += hdrlen; /* the HW only needs room for the IV, but not the actual IV */ @@ -434,8 +432,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_CCMP_HDR_LEN); /* the HW only needs room for the IV, but not the actual IV */ if (info->control.hw_key && @@ -575,7 +571,6 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, pos = skb_push(skb, cs->hdr_len); memmove(pos, pos + cs->hdr_len, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len); return TX_CONTINUE; } -- cgit v1.2.3 From 8b94148cfec4c40f4c55308fdcd816bbfe2b4016 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:32:48 +0300 Subject: mac80211: expose TDLS-initiator value to low level driver Some drivers need to know which station is the TDLS link initiator. Expose this value via the mac80211 ieee80211_sta structure. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +++ net/mac80211/tdls.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 96d224357c8c..99dd3ce7484e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1427,6 +1427,8 @@ struct ieee80211_sta_rates { * @smps_mode: current SMPS mode (off, static or dynamic) * @rates: rate control selection table * @tdls: indicates whether the STA is a TDLS peer + * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only + * valid if the STA is a TDLS peer in the first place. */ struct ieee80211_sta { u32 supp_rates[IEEE80211_NUM_BANDS]; @@ -1442,6 +1444,7 @@ struct ieee80211_sta { enum ieee80211_smps_mode smps_mode; struct ieee80211_sta_rates __rcu *rates; bool tdls; + bool tdls_initiator; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 4ea25dec0698..b4f368e2cb3b 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -562,8 +562,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, /* infer the initiator if we can, to support old userspace */ switch (action_code) { case WLAN_TDLS_SETUP_REQUEST: - if (sta) + if (sta) { set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); + sta->sta.tdls_initiator = false; + } /* fall-through */ case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_DISCOVERY_REQUEST: @@ -575,8 +577,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, * Make the last packet sent take effect for the initiator * value. */ - if (sta) + if (sta) { clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); + sta->sta.tdls_initiator = true; + } /* fall-through */ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: initiator = false; -- cgit v1.2.3 From 2bad7748b332d7218377287248eb66c25de033b2 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:32:16 +0300 Subject: mac80211: add stations in order to the station list During reconfig the station list is traversed in order and station are added back to the driver. Make sure the stations are added to the driver in the same order they were added to mac80211. This has a real side effect - some drivers (iwlwifi) require TDLS stations to be added only after the AP station for the same network. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index de494df3bab8..2cd48cefcbdc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -501,7 +501,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) /* make the station visible */ sta_info_hash_add(local, sta); - list_add_rcu(&sta->list, &local->sta_list); + list_add_tail_rcu(&sta->list, &local->sta_list); /* notify driver */ err = sta_info_insert_drv_state(local, sdata, sta); -- cgit v1.2.3 From 0fc1e0495fd6e261e75acdbe66b53e769e5ffb81 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:30:59 +0300 Subject: mac80211: expose API allowing station iteration Allow drivers to iterate all stations currently uploaded to them. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 16 ++++++++++++++++ net/mac80211/util.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 99dd3ce7484e..2b7426a90ff0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4192,6 +4192,22 @@ void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw, struct ieee80211_vif *vif), void *data); +/** + * ieee80211_iterate_stations_atomic - iterate stations + * + * This function iterates over all stations associated with a given + * hardware that are currently uploaded to the driver and calls the callback + * function for them. + * This function requires the iterator callback function to be atomic, + * + * @hw: the hardware struct of which the interfaces should be iterated over + * @iterator: the iterator function to call, cannot sleep + * @data: first argument of the iterator function + */ +void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data); /** * ieee80211_queue_work - add work onto the mac80211 workqueue * diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9247a960ea59..666aa1306c45 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -693,6 +693,34 @@ void ieee80211_iterate_active_interfaces_rtnl( } EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); +static void __iterate_stations(struct ieee80211_local *local, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data) +{ + struct sta_info *sta; + + list_for_each_entry_rcu(sta, &local->sta_list, list) { + if (!sta->uploaded) + continue; + + iterator(data, &sta->sta); + } +} + +void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data) +{ + struct ieee80211_local *local = hw_to_local(hw); + + rcu_read_lock(); + __iterate_stations(local, iterator, data); + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); + struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); -- cgit v1.2.3 From ee4c148e8a6a749f821170976489a8ea1802fdbb Mon Sep 17 00:00:00 2001 From: Julien Catalano Date: Sun, 5 Oct 2014 20:23:11 +0200 Subject: trivial: net/mac802154: Fix Kconfig typo Signed-off-by: Julien Catalano Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig index 1818a99b3081..aa462b480a39 100644 --- a/net/mac802154/Kconfig +++ b/net/mac802154/Kconfig @@ -16,5 +16,5 @@ config MAC802154 been tested yet! If you plan to use HardMAC IEEE 802.15.4 devices, you can - say N here. Alternatievly you can say M to compile it as + say N here. Alternatively you can say M to compile it as module. -- cgit v1.2.3 From 39f6eb19cf85b08b8a926294750f5e79c50a6a7b Mon Sep 17 00:00:00 2001 From: Simon Vincent Date: Sun, 5 Oct 2014 20:23:12 +0200 Subject: ieee802154: 6lowpan: Drop PACKET_OTHERHOST skbs in 6lowpan There is no point processing pkts which are PACKET_OTHERHOST in 6lowpan as they are discarded as soon as they reach the ipv6 layer. Therefore we should drop them in the 6lowpan layer. Signed-off-by: Simon Vincent Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net') diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 44136297b673..56252ee157c9 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -515,6 +515,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, if (!netif_running(dev)) goto drop_skb; + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop_skb; + if (dev->type != ARPHRD_IEEE802154) goto drop_skb; -- cgit v1.2.3 From cd97a713acbc1b63feb67ba137c3b827fa4f2308 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:50 +0200 Subject: ieee802154: 6lowpan: fix byteorder for frag tag This patch fix byteorder issues with fragment tag of generation 802.15.4 6LoWPAN fragment header. net/ieee802154/6lowpan_rtnl.c:278:54: warning restricted __be16 degrades to integer net/ieee802154/6lowpan_rtnl.c:278:18: warning: incorrect type in assignment (different base types) net/ieee802154/6lowpan_rtnl.c:278:18: expected restricted __be16 [usertype] frag_tag net/ieee802154/6lowpan_rtnl.c:278:18: got unsigned short Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 56252ee157c9..2d547ea190e8 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -63,7 +63,7 @@ static LIST_HEAD(lowpan_devices); struct lowpan_dev_info { struct net_device *real_dev; /* real WPAN device ptr */ struct mutex dev_list_mtx; /* mutex for list ops */ - __be16 fragment_tag; + u16 fragment_tag; }; struct lowpan_dev_record { @@ -275,7 +275,8 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, dgram_size = lowpan_uncompress_size(skb, &dgram_offset) - skb->mac_len; - frag_tag = lowpan_dev_info(dev)->fragment_tag++; + frag_tag = htons(lowpan_dev_info(dev)->fragment_tag); + lowpan_dev_info(dev)->fragment_tag++; frag_hdr[0] = LOWPAN_DISPATCH_FRAG1 | ((dgram_size >> 8) & 0x07); frag_hdr[1] = dgram_size & 0xff; @@ -294,7 +295,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, frag_len + skb_network_header_len(skb)); if (rc) { pr_debug("%s unable to send FRAG1 packet (tag: %d)", - __func__, frag_tag); + __func__, ntohs(frag_tag)); goto err; } @@ -315,7 +316,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, frag_len); if (rc) { pr_debug("%s unable to send a FRAGN packet. (tag: %d, offset: %d)\n", - __func__, frag_tag, skb_offset); + __func__, ntohs(frag_tag), skb_offset); goto err; } } while (skb_unprocessed > frag_cap); -- cgit v1.2.3 From f870b8c6314c85712ff1e82765a902d895b73f21 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:51 +0200 Subject: ieee802154: reassembly: fix tag byteorder This patch fix byte order handling in reassembly code of 802.15.4 6LoWPAN fragmentation handling. net/ieee802154/reassembly.c:58:43: warning: restricted __be16 degrades to integer Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/ieee802154/reassembly.c | 8 +++++--- net/ieee802154/reassembly.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c index 7cfcd6885225..9d980ed3ffe2 100644 --- a/net/ieee802154/reassembly.c +++ b/net/ieee802154/reassembly.c @@ -33,7 +33,7 @@ static const char lowpan_frags_cache_name[] = "lowpan-frags"; struct lowpan_frag_info { - __be16 d_tag; + u16 d_tag; u16 d_size; u8 d_offset; }; @@ -48,7 +48,7 @@ static struct inet_frags lowpan_frags; static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev, struct net_device *dev); -static unsigned int lowpan_hash_frag(__be16 tag, u16 d_size, +static unsigned int lowpan_hash_frag(u16 tag, u16 d_size, const struct ieee802154_addr *saddr, const struct ieee802154_addr *daddr) { @@ -330,11 +330,13 @@ static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type, { bool fail; u8 pattern = 0, low = 0; + __be16 d_tag = 0; fail = lowpan_fetch_skb(skb, &pattern, 1); fail |= lowpan_fetch_skb(skb, &low, 1); frag_info->d_size = (pattern & 7) << 8 | low; - fail |= lowpan_fetch_skb(skb, &frag_info->d_tag, 2); + fail |= lowpan_fetch_skb(skb, &d_tag, 2); + frag_info->d_tag = ntohs(d_tag); if (frag_type == LOWPAN_DISPATCH_FRAGN) { fail |= lowpan_fetch_skb(skb, &frag_info->d_offset, 1); diff --git a/net/ieee802154/reassembly.h b/net/ieee802154/reassembly.h index 74e4a7c98191..836b16fa001f 100644 --- a/net/ieee802154/reassembly.h +++ b/net/ieee802154/reassembly.h @@ -4,7 +4,7 @@ #include struct lowpan_create_arg { - __be16 tag; + u16 tag; u16 d_size; const struct ieee802154_addr *src; const struct ieee802154_addr *dst; @@ -15,7 +15,7 @@ struct lowpan_create_arg { struct lowpan_frag_queue { struct inet_frag_queue q; - __be16 tag; + u16 tag; u16 d_size; struct ieee802154_addr saddr; struct ieee802154_addr daddr; -- cgit v1.2.3 From c0bffc7ddc1383d20efa5c1a36b81e2df48cf65c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:52 +0200 Subject: ieee802154: 6lowpan: fix sign of errno return val This patch fix ERR_PTR(-rc) to ERR_PTR(rc). The variable rc is already a negative errno value. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 2d547ea190e8..c7e07b8a8f9f 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -233,7 +233,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size, &master_hdr->source, size); if (rc < 0) { kfree_skb(frag); - return ERR_PTR(-rc); + return ERR_PTR(rc); } } else { frag = ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 48ec92fa4f16c0f71e95c31490c03b6c9e0e793b Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:10 +0000 Subject: Bluetooth: Refactor arguments of mgmt_device_connected The values of a lot of the mgmt_device_connected() parameters come straight from a hci_conn object. We can simplify the function by passing the full hci_conn pointer to it. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 5 ++--- net/bluetooth/hci_event.c | 14 ++++---------- net/bluetooth/l2cap_core.c | 4 +--- net/bluetooth/mgmt.c | 13 ++++++------- 4 files changed, 13 insertions(+), 23 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 37ff1aef0845..f1407fe0fc5b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1310,9 +1310,8 @@ int mgmt_update_adv_data(struct hci_dev *hdev); void mgmt_discoverable_timeout(struct hci_dev *hdev); void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent); -void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class); +void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, + u32 flags, u8 *name, u8 name_len); void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason, bool mgmt_connected); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8b0a2a6de419..6ee7de26cbb6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1577,8 +1577,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, struct inquiry_entry *e; if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, - name_len, conn->dev_class); + mgmt_device_connected(hdev, conn, 0, name, name_len); if (discov->state == DISCOVERY_STOPPED) return; @@ -2536,9 +2535,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + mgmt_device_connected(hdev, conn, 0, NULL, 0); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -3434,9 +3431,7 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + mgmt_device_connected(hdev, conn, 0, NULL, 0); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -4214,8 +4209,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) } if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, NULL); + mgmt_device_connected(hdev, conn, 0, NULL, 0); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b6f9777e057d..2ff5591bee97 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3873,9 +3873,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn, hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags) && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) - mgmt_device_connected(hdev, &hcon->dst, hcon->type, - hcon->dst_type, 0, NULL, 0, - hcon->dev_class); + mgmt_device_connected(hdev, hcon, 0, NULL, 0); hci_dev_unlock(hdev); l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index efb71b022ab6..fc275dca94f8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6171,16 +6171,15 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, return eir_len; } -void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class) +void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, + u32 flags, u8 *name, u8 name_len) { char buf[512]; struct mgmt_ev_device_connected *ev = (void *) buf; u16 eir_len = 0; - bacpy(&ev->addr.bdaddr, bdaddr); - ev->addr.type = link_to_bdaddr(link_type, addr_type); + bacpy(&ev->addr.bdaddr, &conn->dst); + ev->addr.type = link_to_bdaddr(conn->type, conn->dst_type); ev->flags = __cpu_to_le32(flags); @@ -6188,9 +6187,9 @@ void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, name_len); - if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) + if (conn->dev_class && memcmp(conn->dev_class, "\0\0\0", 3) != 0) eir_len = eir_append_data(ev->eir, eir_len, - EIR_CLASS_OF_DEV, dev_class, 3); + EIR_CLASS_OF_DEV, conn->dev_class, 3); ev->eir_len = cpu_to_le16(eir_len); -- cgit v1.2.3 From fd45ada9105635a69cbaa2d142d502d402eef6fe Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:11 +0000 Subject: Bluetooth: Include ADV_IND report in Device Connected event There are scenarios when autoconnecting to a device after the reception of an ADV_IND report (action 0x02), in which userland might want to examine the report's contents. For instance, the Service Data might have changed and it would be useful to know ahead of time before starting any GATT procedures. Also, the ADV_IND may contain Manufacturer Specific data which would be lost if not propagated to userland. In fact, this patch results from the need to rebond with a device lacking persistent storage which notifies about losing its LTK in ADV_IND reports. This patch appends the ADV_IND report which triggered the autoconnection to the EIR Data in the Device Connected event. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_event.c | 32 ++++++++++++++++++++++---------- net/bluetooth/mgmt.c | 24 ++++++++++++++++++------ 3 files changed, 42 insertions(+), 16 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index f1407fe0fc5b..07ddeed62419 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -398,6 +398,8 @@ struct hci_conn { __u16 le_conn_interval; __u16 le_conn_latency; __u16 le_supv_timeout; + __u8 le_adv_data[HCI_MAX_AD_LENGTH]; + __u8 le_adv_data_len; __s8 rssi; __s8 tx_power; __s8 max_tx_power; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6ee7de26cbb6..96291530606d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4263,25 +4263,26 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, } /* This function requires the caller holds hdev->lock */ -static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, - u8 addr_type, u8 adv_type) +static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, + bdaddr_t *addr, + u8 addr_type, u8 adv_type) { struct hci_conn *conn; struct hci_conn_params *params; /* If the event is not connectable don't proceed further */ if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) - return; + return NULL; /* Ignore if the device is blocked */ if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) - return; + return NULL; /* Most controller will fail if we try to create new connections * while we have an existing one in slave role. */ if (hdev->conn_hash.le_num_slave > 0) - return; + return NULL; /* If we're not connectable only connect devices that we have in * our pend_le_conns list. @@ -4289,7 +4290,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type); if (!params) - return; + return NULL; switch (params->auto_connect) { case HCI_AUTO_CONN_DIRECT: @@ -4298,7 +4299,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, * incoming connections from slave devices. */ if (adv_type != LE_ADV_DIRECT_IND) - return; + return NULL; break; case HCI_AUTO_CONN_ALWAYS: /* Devices advertising with ADV_IND or ADV_DIRECT_IND @@ -4309,7 +4310,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, */ break; default: - return; + return NULL; } conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, @@ -4322,7 +4323,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, * count consistent once the connection is established. */ params->conn = hci_conn_get(conn); - return; + return conn; } switch (PTR_ERR(conn)) { @@ -4335,7 +4336,10 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, break; default: BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); + return NULL; } + + return NULL; } static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, @@ -4343,6 +4347,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, { struct discovery_state *d = &hdev->discovery; struct smp_irk *irk; + struct hci_conn *conn; bool match; u32 flags; @@ -4354,7 +4359,14 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, } /* Check if we have been requested to connect to this device */ - check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); + conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); + if (conn && type == LE_ADV_IND) { + /* Store report for later inclusion by + * mgmt_device_connected + */ + memcpy(conn->le_adv_data, data, len); + conn->le_adv_data_len = len; + } /* Passive scanning shouldn't trigger any device found events, * except for devices marked as CONN_REPORT for which we do send diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index fc275dca94f8..10caab587cca 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6183,13 +6183,25 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, ev->flags = __cpu_to_le32(flags); - if (name_len > 0) - eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, - name, name_len); + /* We must ensure that the EIR Data fields are ordered and + * unique. Keep it simple for now and avoid the problem by not + * adding any BR/EDR data to the LE adv. + */ + if (conn->le_adv_data_len > 0) { + memcpy(&ev->eir[eir_len], + conn->le_adv_data, conn->le_adv_data_len); + eir_len = conn->le_adv_data_len; + } else { + if (name_len > 0) + eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, + name, name_len); - if (conn->dev_class && memcmp(conn->dev_class, "\0\0\0", 3) != 0) - eir_len = eir_append_data(ev->eir, eir_len, - EIR_CLASS_OF_DEV, conn->dev_class, 3); + if (conn->dev_class && + memcmp(conn->dev_class, "\0\0\0", 3) != 0) + eir_len = eir_append_data(ev->eir, eir_len, + EIR_CLASS_OF_DEV, + conn->dev_class, 3); + } ev->eir_len = cpu_to_le16(eir_len); -- cgit v1.2.3 From ddbea5cff7d5e2a9727f72c948e92b676a061fc5 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:12 +0000 Subject: Bluetooth: Remove redundant check on hci_conn's device class NULL-checking conn->dev_class is pointless since the variable is defined as an array, i.e. it will always be non-NULL. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- net/bluetooth/mgmt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 10caab587cca..3fd88b06ed5a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6196,8 +6196,7 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, name_len); - if (conn->dev_class && - memcmp(conn->dev_class, "\0\0\0", 3) != 0) + if (memcmp(conn->dev_class, "\0\0\0", 3) != 0) eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, conn->dev_class, 3); -- cgit v1.2.3 From 1ae2605e55c6ef640238fb2e03d044119acd9a37 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 13 Oct 2014 10:33:06 +0200 Subject: ieee802154: 6lowpan: improve packet registration This patch improves the packet registration handling. Instead of registration with module init we have a open count variable and registration the lowpan packet handler when it's needed. The open count variable should be protected by RTNL. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index c7e07b8a8f9f..da78fae5b301 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -58,6 +58,7 @@ #include "reassembly.h" static LIST_HEAD(lowpan_devices); +static int lowpan_open_count; /* private device info */ struct lowpan_dev_info { @@ -571,11 +572,17 @@ drop: return NET_RX_DROP; } +static struct packet_type lowpan_packet_type = { + .type = htons(ETH_P_IEEE802154), + .func = lowpan_rcv, +}; + static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct net_device *real_dev; struct lowpan_dev_record *entry; + int ret; pr_debug("adding new link\n"); @@ -610,9 +617,14 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, list_add_tail(&entry->list, &lowpan_devices); mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); - register_netdevice(dev); + ret = register_netdevice(dev); + if (ret >= 0) { + if (!lowpan_open_count) + dev_add_pack(&lowpan_packet_type); + lowpan_open_count++; + } - return 0; + return ret; } static void lowpan_dellink(struct net_device *dev, struct list_head *head) @@ -623,6 +635,10 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) ASSERT_RTNL(); + lowpan_open_count--; + if (!lowpan_open_count) + dev_remove_pack(&lowpan_packet_type); + mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { if (entry->ldev == dev) { @@ -685,11 +701,6 @@ static struct notifier_block lowpan_dev_notifier = { .notifier_call = lowpan_device_event, }; -static struct packet_type lowpan_packet_type = { - .type = htons(ETH_P_IEEE802154), - .func = lowpan_rcv, -}; - static int __init lowpan_init_module(void) { int err = 0; @@ -702,8 +713,6 @@ static int __init lowpan_init_module(void) if (err < 0) goto out_frag; - dev_add_pack(&lowpan_packet_type); - err = register_netdevice_notifier(&lowpan_dev_notifier); if (err < 0) goto out_pack; @@ -711,7 +720,6 @@ static int __init lowpan_init_module(void) return 0; out_pack: - dev_remove_pack(&lowpan_packet_type); lowpan_netlink_fini(); out_frag: lowpan_net_frag_exit(); @@ -723,8 +731,6 @@ static void __exit lowpan_cleanup_module(void) { lowpan_netlink_fini(); - dev_remove_pack(&lowpan_packet_type); - lowpan_net_frag_exit(); unregister_netdevice_notifier(&lowpan_dev_notifier); -- cgit v1.2.3 From c37a8106de1b8d286fe577599ccc9bbb0efdd7ad Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 13 Oct 2014 10:33:07 +0200 Subject: ieee802154: 6lowpan: add RTNL assertion This patch ensure that the rtnl lock is hold while newlink callback. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index da78fae5b301..0c1a49b51e57 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -584,6 +584,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct lowpan_dev_record *entry; int ret; + ASSERT_RTNL(); + pr_debug("adding new link\n"); if (!tb[IFLA_LINK]) -- cgit v1.2.3 From 89cbb0638e9b7ba6fab02558f47a29f144df1a19 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Sat, 11 Oct 2014 21:44:47 +0000 Subject: Bluetooth: Defer connection-parameter removal when unpairing Systematically removing the LE connection parameters and autoconnect action is inconvenient for rebonding without disconnecting from userland (i.e. unpairing followed by repairing without disconnecting). The parameters will be lost after unparing and userland needs to take care of book-keeping them and re-adding them. This patch allows userland to forget about parameter management when rebonding without disconnecting. It defers clearing the connection parameters when unparing without disconnecting, giving a chance of keeping the parameters if a repairing happens before the connection is closed. Signed-off-by: Alfonso Acosta Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 3 +++ net/bluetooth/mgmt.c | 51 ++++++++++++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 07ddeed62419..b8685a77a15e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -555,6 +555,7 @@ enum { HCI_CONN_STK_ENCRYPT, HCI_CONN_AUTH_INITIATOR, HCI_CONN_DROP, + HCI_CONN_PARAM_REMOVAL_PEND, }; static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b9517bd17190..11aac06d53ce 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -544,6 +544,9 @@ int hci_conn_del(struct hci_conn *conn) hci_conn_del_sysfs(conn); + if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags)) + hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type); + hci_dev_put(hdev); hci_conn_put(conn); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3fd88b06ed5a..9c4daf715cf8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2725,10 +2725,40 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, } if (cp->addr.type == BDADDR_BREDR) { + /* If disconnection is requested, then look up the + * connection. If the remote device is connected, it + * will be later used to terminate the link. + * + * Setting it to NULL explicitly will cause no + * termination of the link. + */ + if (cp->disconnect) + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, + &cp->addr.bdaddr); + else + conn = NULL; + err = hci_remove_link_key(hdev, &cp->addr.bdaddr); } else { u8 addr_type; + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, + &cp->addr.bdaddr); + if (conn) { + /* Defer clearing up the connection parameters + * until closing to give a chance of keeping + * them if a repairing happens. + */ + set_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); + + /* If disconnection is not requested, then + * clear the connection variable so that the + * link is not terminated. + */ + if (!cp->disconnect) + conn = NULL; + } + if (cp->addr.type == BDADDR_LE_PUBLIC) addr_type = ADDR_LE_DEV_PUBLIC; else @@ -2736,8 +2766,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type); - hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type); - err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type); } @@ -2747,17 +2775,9 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, goto unlock; } - if (cp->disconnect) { - if (cp->addr.type == BDADDR_BREDR) - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, - &cp->addr.bdaddr); - else - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, - &cp->addr.bdaddr); - } else { - conn = NULL; - } - + /* If the connection variable is set, then termination of the + * link is requested. + */ if (!conn) { err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, &rp, sizeof(rp)); @@ -3062,6 +3082,11 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) hci_conn_put(conn); mgmt_pending_remove(cmd); + + /* The device is paired so there is no need to remove + * its connection parameters anymore. + */ + clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); } void mgmt_smp_complete(struct hci_conn *conn, bool complete) -- cgit v1.2.3 From ec511545ef791577ed9dd055e3b2d6d926b85daf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 13 Oct 2014 11:43:53 +0200 Subject: Bluetooth: Fix RFCOMM NSC response rfcomm_send_nsc expects CR to be either 0 or 1 since it is later passed to __mcc_type macro and shitfed. Unfortunatelly CR extracted from received frame type was not sanitized and shifted value was passed resulting in bogus response. Note: shifted value was also passed to other functions but was used only in if satements so this bug appears only for NSC case. The CR bit in the value octet shall be set to the same value as the CR bit in the type field octet of the not supported command frame but the CR bit for NCS response should be set to 0 since it is always a response. This was affecting TC_RFC_BV_25_C PTS qualification test. Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/rfcomm/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index af73bc3acb40..d0bbc737f162 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -78,7 +78,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); #define __get_type(b) ((b & 0xef)) #define __test_ea(b) ((b & 0x01)) -#define __test_cr(b) ((b & 0x02)) +#define __test_cr(b) (!!(b & 0x02)) #define __test_pf(b) ((b & 0x10)) #define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) @@ -904,7 +904,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) hdr->len = __len8(sizeof(*mcc) + 1); mcc = (void *) ptr; ptr += sizeof(*mcc); - mcc->type = __mcc_type(cr, RFCOMM_NSC); + mcc->type = __mcc_type(0, RFCOMM_NSC); mcc->len = __len8(1); /* Type that we didn't like */ -- cgit v1.2.3 From 15346a9c2875cae8e84c13196a2fc7428d9358d4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 13 Oct 2014 11:43:54 +0200 Subject: Bluetooth: Improve RFCOMM __test_pf macro robustness Value returned by this macro might be used as bit value so it should return either 0 or 1 to avoid possible bugs (similar to NSC bug) when shifting it. Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/rfcomm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index d0bbc737f162..bce9c3d39324 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -79,7 +79,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); #define __test_ea(b) ((b & 0x01)) #define __test_cr(b) (!!(b & 0x02)) -#define __test_pf(b) ((b & 0x10)) +#define __test_pf(b) (!!(b & 0x10)) #define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) #define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) -- cgit v1.2.3 From 4456c50d23d44352f4174a9a0cb75313d3150907 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Thu, 16 Oct 2014 10:21:55 +0800 Subject: Bluetooth: 6lowpan: remove unnecessary codes in give_skb_to_upper netif_rx() only returns NET_RX_DROP and NET_RX_SUCCESS, not returns negative value Signed-off-by: Li RongQing Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index c2e0d14433df..9b5c89b18718 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -249,19 +249,12 @@ static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *skb_cp; - int ret; skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) return -ENOMEM; - ret = netif_rx(skb_cp); - if (ret < 0) { - BT_DBG("receive skb %d", ret); - return NET_RX_DROP; - } - - return ret; + return netif_rx(skb_cp); } static int process_data(struct sk_buff *skb, struct net_device *netdev, -- cgit v1.2.3 From 11e3ff7072789ad4585870cbdde1be10c45f1cc4 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Mon, 13 Oct 2014 11:00:56 +0100 Subject: 6lowpan: Use skb_cow in IPHC decompression. Currently there are potentially 2 skb_copy_expand calls in IPHC decompression. This patch replaces this with one call to skb_cow which will check to see if there is enough headroom first to ensure it's only done if necessary and will handle alignment issues for cache. As skb_cow uses pskb_expand_head we ensure the skb isn't shared from bluetooth and ieee802.15.4 code that use the IPHC decompression. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/6lowpan/iphc.c | 47 +++++++++++++++++++++-------------------------- net/bluetooth/6lowpan.c | 4 ++++ 2 files changed, 25 insertions(+), 26 deletions(-) (limited to 'net') diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 142eef55c9e2..747b3ccfc4f8 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -174,30 +174,22 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb, static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, struct net_device *dev, skb_delivery_cb deliver_skb) { - struct sk_buff *new; int stat; - new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), - GFP_ATOMIC); - kfree_skb(skb); - - if (!new) - return -ENOMEM; - - skb_push(new, sizeof(struct ipv6hdr)); - skb_reset_network_header(new); - skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr)); + skb_push(skb, sizeof(struct ipv6hdr)); + skb_reset_network_header(skb); + skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr)); - new->protocol = htons(ETH_P_IPV6); - new->pkt_type = PACKET_HOST; - new->dev = dev; + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + skb->dev = dev; raw_dump_table(__func__, "raw skb data dump before receiving", - new->data, new->len); + skb->data, skb->len); - stat = deliver_skb(new, dev); + stat = deliver_skb(skb, dev); - kfree_skb(new); + consume_skb(skb); return stat; } @@ -460,7 +452,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, /* UDP data uncompression */ if (iphc0 & LOWPAN_IPHC_NH_C) { struct udphdr uh; - struct sk_buff *new; + const int needed = sizeof(struct udphdr) + sizeof(hdr); if (uncompress_udp_header(skb, &uh)) goto drop; @@ -468,14 +460,11 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, /* replace the compressed UDP head by the uncompressed UDP * header */ - new = skb_copy_expand(skb, sizeof(struct udphdr), - skb_tailroom(skb), GFP_ATOMIC); - kfree_skb(skb); - - if (!new) - return -ENOMEM; - - skb = new; + err = skb_cow(skb, needed); + if (unlikely(err)) { + kfree_skb(skb); + return err; + } skb_push(skb, sizeof(struct udphdr)); skb_reset_transport_header(skb); @@ -485,6 +474,12 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, (u8 *)&uh, sizeof(uh)); hdr.nexthdr = UIP_PROTO_UDP; + } else { + err = skb_cow(skb, sizeof(hdr)); + if (unlikely(err)) { + kfree_skb(skb); + return err; + } } hdr.payload_len = htons(skb->len); diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 9b5c89b18718..6c5c2eff45bd 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -309,6 +309,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (dev->type != ARPHRD_6LOWPAN) goto drop; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto drop; + /* check that it's our buffer */ if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { /* Copy the packet so that the IPv6 header is -- cgit v1.2.3 From ee93053d569b8b56e09a278fc9c41b7adf070a96 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Mon, 13 Oct 2014 19:24:45 +0100 Subject: Bluetooth: Fix missing channel unlock in l2cap_le_credits In the error case where credits is greater than max_credits there is a missing l2cap_chan_unlock before returning. Signed-off-by: Martin Townsend Tested-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2ff5591bee97..d46c5127f6c3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5492,6 +5492,7 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn, if (credits > max_credits) { BT_ERR("LE credits overflow"); l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_chan_unlock(chan); /* Return 0 so that we don't trigger an unnecessary * command reject packet. -- cgit v1.2.3 From b3020f0a35fc431f7acf3fba9a5b7376d79932e5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:07 +0200 Subject: ieee802154: mac802154: remove FSF address This patch removes the FSF address in files which belongs to ieee802154 and mac802154. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 ---- drivers/net/ieee802154/fakelb.c | 4 ---- drivers/net/ieee802154/mrf24j40.c | 4 ---- include/linux/nl802154.h | 4 ---- include/net/af_ieee802154.h | 4 ---- include/net/ieee802154.h | 4 ---- include/net/ieee802154_netdev.h | 4 ---- include/net/mac802154.h | 3 --- include/net/nl802154.h | 4 ---- include/net/wpan-phy.h | 4 ---- net/ieee802154/af802154.h | 4 ---- net/ieee802154/af_ieee802154.c | 4 ---- net/ieee802154/dgram.c | 4 ---- net/ieee802154/ieee802154.h | 4 ---- net/ieee802154/netlink.c | 4 ---- net/ieee802154/nl-mac.c | 4 ---- net/ieee802154/nl-phy.c | 4 ---- net/ieee802154/nl_policy.c | 4 ---- net/ieee802154/raw.c | 4 ---- net/ieee802154/wpan-class.c | 4 ---- net/mac802154/ieee802154_dev.c | 4 ---- net/mac802154/mac802154.h | 4 ---- net/mac802154/mac_cmd.c | 4 ---- net/mac802154/mib.c | 4 ---- net/mac802154/monitor.c | 4 ---- net/mac802154/rx.c | 4 ---- net/mac802154/tx.c | 4 ---- net/mac802154/wpan.c | 4 ---- 28 files changed, 111 deletions(-) (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 6ebd665892d8..b8b1e40feeb8 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Alexander Smirnov diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 27d83207d24c..e4b1b1f66bd2 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index b1e73bc6e398..ba9a3960d26d 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -13,10 +13,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 20163b9a0eae..167342c2ce6b 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef NL802154_H diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h index 085940f7eeec..7d38e2ffd256 100644 --- a/include/net/af_ieee802154.h +++ b/include/net/af_ieee802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h index 0aa7122e8f15..4db4e320b2f5 100644 --- a/include/net/ieee802154.h +++ b/include/net/ieee802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 3b53c8e405e4..f87420689d70 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 2e67cdd19cdc..f95b98ec50a8 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef NET_MAC802154_H #define NET_MAC802154_H diff --git a/include/net/nl802154.h b/include/net/nl802154.h index b23548e04098..b5cdea29d9d9 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef IEEE802154_NL_H diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 10ab0fc6d4f7..65a05f19eb68 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov */ diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h index 8330a09bfc95..343b63e6f953 100644 --- a/net/ieee802154/af802154.h +++ b/net/ieee802154/af802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index 29e0de63001b..26da1e179737 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Maxim Gorbachyov diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index ef2ad8aaef13..71e99a0994e1 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h index 5d352f86979e..42ae63a345ab 100644 --- a/net/ieee802154/ieee802154.h +++ b/net/ieee802154/ieee802154.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef IEEE_802154_LOCAL_H #define IEEE_802154_LOCAL_H diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 9222966f5e6d..6c3c2595a201 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index c6bfe22bfa5e..78a1529e8bb2 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 972baf83411a..e943e20bcf09 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c index 3a703ab88348..35c432668454 100644 --- a/net/ieee802154/nl_policy.c +++ b/net/ieee802154/nl_policy.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 9d1f64806f02..3ffcf4a9de01 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 4955e0fe5883..9a2dfab5648d 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index b36b2b996578..6af6a2427aaf 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -14,10 +14,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 762a6f849c6b..e3503c1bc04e 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index bf809131eef7..85f70edbe8dd 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 868a040fd422..d7e5df872be7 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index a68230e2b25f..81249bb7c935 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index a14cf9ede171..e99d9394d13a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fdf4c0e67259..95ea412395c7 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 4ab86a57dca5..b11a98d824e0 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin -- cgit v1.2.3 From 139f14adab08223fda55759cb93b9b80ba4bfee7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:08 +0200 Subject: ieee802154: ieee802154_dev: fix align typo This patch fix a typo and fix align instead allign. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index 6af6a2427aaf..086d4a91ae45 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -263,7 +263,7 @@ ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) * +-----------------------+ * * Due to ieee802154 layer isn't aware of driver and MAC structures, - * so lets allign them here. + * so lets align them here. */ priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; -- cgit v1.2.3 From 57205c14ca9147c1907556f77998cf82624d9fd6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:09 +0200 Subject: mac802154: fix typo IEEE802515 to IEEE802154 This patch fixs a typo in address filter defines from IEEE802515 to IEEE802154. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 8 ++++---- drivers/net/ieee802154/cc2520.c | 8 ++++---- drivers/net/ieee802154/mrf24j40.c | 8 ++++---- include/net/mac802154.h | 8 ++++---- net/mac802154/mib.c | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b8b1e40feeb8..83a635f17367 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1097,7 +1097,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, { struct at86rf230_local *lp = dev->priv; - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); dev_vdbg(&lp->spi->dev, @@ -1106,7 +1106,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_SHORT_ADDR_1, addr >> 8); } - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 pan = le16_to_cpu(filt->pan_id); dev_vdbg(&lp->spi->dev, @@ -1115,7 +1115,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_PAN_ID_1, pan >> 8); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { u8 i, addr[8]; memcpy(addr, &filt->ieee_addr, 8); @@ -1125,7 +1125,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_IEEE_ADDR_0 + i, addr[i]); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&lp->spi->dev, "at86rf230_set_hw_addr_filt called for panc change\n"); if (filt->pan_coord) diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 8a5ac7ab2300..571f280204b6 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -593,7 +593,7 @@ cc2520_filter(struct ieee802154_dev *dev, { struct cc2520_private *priv = dev->priv; - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); dev_vdbg(&priv->spi->dev, @@ -602,7 +602,7 @@ cc2520_filter(struct ieee802154_dev *dev, sizeof(panid), (u8 *)&panid); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for IEEE addr\n"); cc2520_write_ram(priv, CC2520RAM_IEEEADDR, @@ -610,7 +610,7 @@ cc2520_filter(struct ieee802154_dev *dev, (u8 *)&filt->ieee_addr); } - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); dev_vdbg(&priv->spi->dev, @@ -619,7 +619,7 @@ cc2520_filter(struct ieee802154_dev *dev, sizeof(addr), (u8 *)&addr); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for panc change\n"); if (filt->pan_coord) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index ba9a3960d26d..0006b9ad5127 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -462,7 +462,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, dev_dbg(printdev(devrec), "filter\n"); - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { /* Short Addr */ u8 addrh, addrl; @@ -475,7 +475,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, "Set short addr to %04hx\n", filt->short_addr); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { /* Device Address */ u8 i, addr[8]; @@ -491,7 +491,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, #endif } - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { /* PAN ID */ u8 panidl, panidh; @@ -503,7 +503,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { /* Pan Coordinator */ u8 val; int ret; diff --git a/include/net/mac802154.h b/include/net/mac802154.h index f95b98ec50a8..70351de3a72c 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -32,13 +32,13 @@ */ /* indicates that the Short Address changed */ -#define IEEE802515_AFILT_SADDR_CHANGED 0x00000001 +#define IEEE802154_AFILT_SADDR_CHANGED 0x00000001 /* indicates that the IEEE Address changed */ -#define IEEE802515_AFILT_IEEEADDR_CHANGED 0x00000002 +#define IEEE802154_AFILT_IEEEADDR_CHANGED 0x00000002 /* indicates that the PAN ID changed */ -#define IEEE802515_AFILT_PANID_CHANGED 0x00000004 +#define IEEE802154_AFILT_PANID_CHANGED 0x00000004 /* indicates that PAN Coordinator status changed */ -#define IEEE802515_AFILT_PANC_CHANGED 0x00000008 +#define IEEE802154_AFILT_PANC_CHANGED 0x00000008 struct ieee802154_hw_addr_filt { __le16 pan_id; /* Each independent PAN selects a unique diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index d7e5df872be7..3ee604292238 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -89,7 +89,7 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) if ((priv->hw->ops->set_hw_addr_filt) && (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { priv->hw->hw.hw_filt.short_addr = priv->short_addr; - set_hw_addr_filt(dev, IEEE802515_AFILT_SADDR_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } @@ -117,7 +117,7 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev) if (mac->ops->set_hw_addr_filt && mac->hw.hw_filt.ieee_addr != priv->extended_addr) { mac->hw.hw_filt.ieee_addr = priv->extended_addr; - set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } @@ -148,7 +148,7 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) if ((priv->hw->ops->set_hw_addr_filt) && (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { priv->hw->hw.hw_filt.pan_id = priv->pan_id; - set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } -- cgit v1.2.3 From ed1da148178d90bc21d96f35cfa62f969362495f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:12 +0200 Subject: ieee802154: wpan-class: fix trailing semicolon This patch removes an unnecessary tailing semicolon after macro define. Otherwise we get a trailing semicolon while using this macro. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/wpan-class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 9a2dfab5648d..e4c6fb31a360 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -33,7 +33,7 @@ static ssize_t name ## _show(struct device *dev, \ mutex_unlock(&phy->pib_lock); \ return ret; \ } \ -static DEVICE_ATTR_RO(name); +static DEVICE_ATTR_RO(name) #define MASTER_SHOW(field, format_string) \ MASTER_SHOW_COMPLEX(field, format_string, phy->field) -- cgit v1.2.3 From 4f639edef73c15ddb1534e39f4bd6234ee04e4f8 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 25 Oct 2014 10:48:58 +0200 Subject: Bluetooth: fix shadow warning in hci_disconnect() use clkoff_cp for hci_cp_read_clock_offset instead of cp (already defined above). Suggested-by: Marcel Holtmann Signed-off-by: Fabian Frederick Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 11aac06d53ce..6a3225bf7bac 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -141,10 +141,11 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason) */ if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { struct hci_dev *hdev = conn->hdev; - struct hci_cp_read_clock_offset cp; + struct hci_cp_read_clock_offset clkoff_cp; - cp.handle = cpu_to_le16(conn->handle); - hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(cp), &cp); + clkoff_cp.handle = cpu_to_le16(conn->handle); + hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(clkoff_cp), + &clkoff_cp); } conn->state = BT_DISCONN; -- cgit v1.2.3 From e491eaf3c0b02b5325535a2de3e4fa15a3093190 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:37 +0200 Subject: Bluetooth: Pass only crypto context to SMP crypto functions In order to make unit testing possible we need to make the SMP crypto functions only take the crypto context instead of the full SMP context (the latter would require having hci_dev, hci_conn, l2cap_chan, l2cap_conn, etc around). The drawback is that we no-longer get the involved hdev in the debug logs, but this is really the only way to make simple unit tests for the code. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'net') diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index f09b6b65cf6b..fea3782989f4 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -191,16 +191,13 @@ int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa) return 0; } -static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], - u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra, - u8 res[16]) +static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16], + u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, + bdaddr_t *ra, u8 res[16]) { - struct hci_dev *hdev = smp->conn->hcon->hdev; u8 p1[16], p2[16]; int err; - BT_DBG("%s", hdev->name); - memset(p1, 0, 16); /* p1 = pres || preq || _rat || _iat */ @@ -218,7 +215,7 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); /* res = e(k, res) */ - err = smp_e(smp->tfm_aes, k, res); + err = smp_e(tfm_aes, k, res); if (err) { BT_ERR("Encrypt data error"); return err; @@ -228,26 +225,23 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); /* res = e(k, res) */ - err = smp_e(smp->tfm_aes, k, res); + err = smp_e(tfm_aes, k, res); if (err) BT_ERR("Encrypt data error"); return err; } -static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], - u8 _r[16]) +static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16], + u8 r2[16], u8 _r[16]) { - struct hci_dev *hdev = smp->conn->hcon->hdev; int err; - BT_DBG("%s", hdev->name); - /* Just least significant octets from r1 and r2 are considered */ memcpy(_r, r2, 8); memcpy(_r + 8, r1, 8); - err = smp_e(smp->tfm_aes, k, _r); + err = smp_e(tfm_aes, k, _r); if (err) BT_ERR("Encrypt data error"); @@ -547,7 +541,7 @@ static u8 smp_confirm(struct smp_chan *smp) BT_DBG("conn %p", conn); - ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp, + ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp, conn->hcon->init_addr_type, &conn->hcon->init_addr, conn->hcon->resp_addr_type, &conn->hcon->resp_addr, cp.confirm_val); @@ -578,7 +572,7 @@ static u8 smp_random(struct smp_chan *smp) BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); - ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp, + ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp, hcon->init_addr_type, &hcon->init_addr, hcon->resp_addr_type, &hcon->resp_addr, confirm); if (ret) @@ -594,7 +588,7 @@ static u8 smp_random(struct smp_chan *smp) __le64 rand = 0; __le16 ediv = 0; - smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk); + smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); @@ -613,7 +607,7 @@ static u8 smp_random(struct smp_chan *smp) smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), smp->prnd); - smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk); + smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); -- cgit v1.2.3 From 4cd3362da899a59955146851dd860198b0aaaa75 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:38 +0200 Subject: Bluetooth: Add skeleton for SMP self-tests This patch adds a basic skeleton for SMP self-tests. The tests are put behind a new configuration option since running them will slow down the boot process. For now there are no actual tests defined but those will come in a subsequent patch. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/Kconfig | 6 ++++++ net/bluetooth/smp.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'net') diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 600fb29288f4..2675b4106b00 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -45,6 +45,12 @@ config BT_6LOWPAN help IPv6 compression over Bluetooth Low Energy. +config BT_SELFTEST + bool "Run self-tests on boot" + depends on BT && DEBUG_KERNEL + help + Run self-tests during boot. Currently limited to SMP. + source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/bnep/Kconfig" diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fea3782989f4..9821dc938e2c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1743,3 +1743,36 @@ void smp_unregister(struct hci_dev *hdev) hdev->smp_data = NULL; l2cap_chan_put(chan); } + +#ifdef CONFIG_BT_SELFTEST + +static int __init run_selftests(struct crypto_blkcipher *tfm_aes) +{ + return 0; +} + +static int __init test_smp(void) +{ + struct crypto_blkcipher *tfm_aes; + int err; + + tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm_aes)) { + BT_ERR("Unable to create ECB crypto context"); + return PTR_ERR(tfm_aes); + } + + err = run_selftests(tfm_aes); + if (err < 0) + BT_ERR("Self tests failed"); + else + BT_INFO("Self-tests passed"); + + crypto_free_blkcipher(tfm_aes); + + return err; +} + +module_init(test_smp); + +#endif /* CONFIG_BT_SELFTEST */ -- cgit v1.2.3 From c6992e9ef2a17e9738b7bb8a03a7fe581a8f9977 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:39 +0200 Subject: Bluetooth: Add self-tests for SMP crypto functions This patch adds self-tests for the c1 and s1 crypto functions used for SMP pairing. The data used is the sample data from the core specification. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'net') diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 9821dc938e2c..983d1e0793f6 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1746,8 +1746,95 @@ void smp_unregister(struct hci_dev *hdev) #ifdef CONFIG_BT_SELFTEST +static int __init test_ah(struct crypto_blkcipher *tfm_aes) +{ + u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, + 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; + u8 r[3] = { 0x94, 0x81, 0x70 }; + u8 exp[3] = { 0xaa, 0xfb, 0x0d }; + u8 res[3]; + int err; + + err = smp_ah(tfm_aes, irk, r, res); + if (err) + return err; + + if (memcmp(res, exp, 3) != 0) + return -EINVAL; + + return 0; +} + +static int __init test_c1(struct crypto_blkcipher *tfm_aes) +{ + u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 r[16] = { 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, + 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; + u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; + u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; + u8 _iat = 0x01; + u8 _rat = 0x00; + bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; + bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; + u8 exp[16] = { 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, + 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; + u8 res[16]; + int err; + + err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); + if (err) + return err; + + if (memcmp(res, exp, 16) != 0) + return -EINVAL; + + return 0; +} + +static int __init test_s1(struct crypto_blkcipher *tfm_aes) +{ + u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 r1[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; + u8 r2[16] = { 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; + u8 exp[16] = { 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, + 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; + u8 res[16]; + int err; + + err = smp_s1(tfm_aes, k, r1, r2, res); + if (err) + return err; + + if (memcmp(res, exp, 16) != 0) + return -EINVAL; + + return 0; +} + static int __init run_selftests(struct crypto_blkcipher *tfm_aes) { + int err; + + err = test_ah(tfm_aes); + if (err) { + BT_ERR("smp_ah test failed"); + return err; + } + + err = test_c1(tfm_aes); + if (err) { + BT_ERR("smp_c1 test failed"); + return err; + } + + err = test_s1(tfm_aes); + if (err) { + BT_ERR("smp_s1 test failed"); + return err; + } + return 0; } -- cgit v1.2.3 From 62eb01f5c2d735e8aeab6bc95e5832cb59397527 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:40:59 +0200 Subject: mac802154: move ieee802154_dev.c to main.c The ieee802154_dev functionality contains various function for allocation and registration of an ieee802154_dev. This is equal to the net/mac80211/main.c file. This patch rename the ieee802154_dev.c to main.c to have the same behaviour. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/ieee802154_dev.c | 411 ----------------------------------------- net/mac802154/main.c | 411 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 412 insertions(+), 412 deletions(-) delete mode 100644 net/mac802154/ieee802154_dev.c create mode 100644 net/mac802154/main.c (limited to 'net') diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 9723d6f3f3e5..1ecbc47d4276 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o \ +mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ monitor.o wpan.o llsec.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c deleted file mode 100644 index 086d4a91ae45..000000000000 --- a/net/mac802154/ieee802154_dev.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) 2007-2012 Siemens AG - * - * Written by: - * Alexander Smirnov - * - * Based on the code from 'linux-zigbee.sourceforge.net' project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "mac802154.h" - -int mac802154_slave_open(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_sub_if_data *subif; - struct mac802154_priv *ipriv = priv->hw; - int res = 0; - - ASSERT_RTNL(); - - if (priv->type == IEEE802154_DEV_WPAN) { - mutex_lock(&priv->hw->slaves_mtx); - list_for_each_entry(subif, &priv->hw->slaves, list) { - if (subif != priv && subif->type == priv->type && - subif->running) { - mutex_unlock(&priv->hw->slaves_mtx); - return -EBUSY; - } - } - mutex_unlock(&priv->hw->slaves_mtx); - } - - mutex_lock(&priv->hw->slaves_mtx); - priv->running = true; - mutex_unlock(&priv->hw->slaves_mtx); - - if (ipriv->open_count++ == 0) { - res = ipriv->ops->start(&ipriv->hw); - WARN_ON(res); - if (res) - goto err; - } - - if (ipriv->ops->ieee_addr) { - __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); - - res = ipriv->ops->ieee_addr(&ipriv->hw, addr); - WARN_ON(res); - if (res) - goto err; - mac802154_dev_set_ieee_addr(dev); - } - - netif_start_queue(dev); - return 0; -err: - priv->hw->open_count--; - - return res; -} - -int mac802154_slave_close(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *ipriv = priv->hw; - - ASSERT_RTNL(); - - netif_stop_queue(dev); - - mutex_lock(&priv->hw->slaves_mtx); - priv->running = false; - mutex_unlock(&priv->hw->slaves_mtx); - - if (!--ipriv->open_count) - ipriv->ops->stop(&ipriv->hw); - - return 0; -} - -static int -mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - struct mac802154_priv *ipriv; - int err; - - ipriv = wpan_phy_priv(phy); - - priv = netdev_priv(dev); - priv->dev = dev; - priv->hw = ipriv; - - dev->needed_headroom = ipriv->hw.extra_tx_headroom; - - SET_NETDEV_DEV(dev, &ipriv->phy->dev); - - mutex_lock(&ipriv->slaves_mtx); - if (!ipriv->running) { - mutex_unlock(&ipriv->slaves_mtx); - return -ENODEV; - } - mutex_unlock(&ipriv->slaves_mtx); - - err = register_netdev(dev); - if (err < 0) - return err; - - rtnl_lock(); - mutex_lock(&ipriv->slaves_mtx); - list_add_tail_rcu(&priv->list, &ipriv->slaves); - mutex_unlock(&ipriv->slaves_mtx); - rtnl_unlock(); - - return 0; -} - -static void -mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) -{ - struct mac802154_sub_if_data *sdata; - - ASSERT_RTNL(); - - sdata = netdev_priv(dev); - - BUG_ON(sdata->hw->phy != phy); - - mutex_lock(&sdata->hw->slaves_mtx); - list_del_rcu(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); - - synchronize_rcu(); - unregister_netdevice(sdata->dev); -} - -static struct net_device * -mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) -{ - struct net_device *dev; - int err = -ENOMEM; - - switch (type) { - case IEEE802154_DEV_MONITOR: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), - name, NET_NAME_UNKNOWN, - mac802154_monitor_setup); - break; - case IEEE802154_DEV_WPAN: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), - name, NET_NAME_UNKNOWN, - mac802154_wpan_setup); - break; - default: - dev = NULL; - err = -EINVAL; - break; - } - if (!dev) - goto err; - - err = mac802154_netdev_register(phy, dev); - if (err) - goto err_free; - - dev_hold(dev); /* we return an incremented device refcount */ - return dev; - -err_free: - free_netdev(dev); -err: - return ERR_PTR(err); -} - -static int mac802154_set_txpower(struct wpan_phy *phy, int db) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_txpower(&priv->hw, db); -} - -static int mac802154_set_lbt(struct wpan_phy *phy, bool on) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_lbt(&priv->hw, on); -} - -static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_cca_mode(&priv->hw, mode); -} - -static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_cca_ed_level(&priv->hw, level); -} - -static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, - u8 max_be, u8 retries) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries); -} - -static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) -{ - struct mac802154_priv *priv = wpan_phy_priv(phy); - - return priv->ops->set_frame_retries(&priv->hw, retries); -} - -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) -{ - struct wpan_phy *phy; - struct mac802154_priv *priv; - size_t priv_size; - - if (!ops || !ops->xmit || !ops->ed || !ops->start || - !ops->stop || !ops->set_channel) { - pr_err("undefined IEEE802.15.4 device operations\n"); - return NULL; - } - - /* Ensure 32-byte alignment of our private data and hw private data. - * We use the wpan_phy priv data for both our mac802154_priv and for - * the driver's private data - * - * in memory it'll be like this: - * - * +-----------------------+ - * | struct wpan_phy | - * +-----------------------+ - * | struct mac802154_priv | - * +-----------------------+ - * | driver's private data | - * +-----------------------+ - * - * Due to ieee802154 layer isn't aware of driver and MAC structures, - * so lets align them here. - */ - - priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; - - phy = wpan_phy_alloc(priv_size); - if (!phy) { - pr_err("failure to allocate master IEEE802.15.4 device\n"); - return NULL; - } - - priv = wpan_phy_priv(phy); - priv->phy = phy; - priv->hw.phy = priv->phy; - priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); - priv->ops = ops; - - INIT_LIST_HEAD(&priv->slaves); - mutex_init(&priv->slaves_mtx); - - return &priv->hw; -} -EXPORT_SYMBOL(ieee802154_alloc_device); - -void ieee802154_free_device(struct ieee802154_dev *hw) -{ - struct mac802154_priv *priv = mac802154_to_priv(hw); - - BUG_ON(!list_empty(&priv->slaves)); - - mutex_destroy(&priv->slaves_mtx); - - wpan_phy_free(priv->phy); -} -EXPORT_SYMBOL(ieee802154_free_device); - -int ieee802154_register_device(struct ieee802154_dev *dev) -{ - struct mac802154_priv *priv = mac802154_to_priv(dev); - int rc = -ENOSYS; - - if (dev->flags & IEEE802154_HW_TXPOWER) { - if (!priv->ops->set_txpower) - goto out; - - priv->phy->set_txpower = mac802154_set_txpower; - } - - if (dev->flags & IEEE802154_HW_LBT) { - if (!priv->ops->set_lbt) - goto out; - - priv->phy->set_lbt = mac802154_set_lbt; - } - - if (dev->flags & IEEE802154_HW_CCA_MODE) { - if (!priv->ops->set_cca_mode) - goto out; - - priv->phy->set_cca_mode = mac802154_set_cca_mode; - } - - if (dev->flags & IEEE802154_HW_CCA_ED_LEVEL) { - if (!priv->ops->set_cca_ed_level) - goto out; - - priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; - } - - if (dev->flags & IEEE802154_HW_CSMA_PARAMS) { - if (!priv->ops->set_csma_params) - goto out; - - priv->phy->set_csma_params = mac802154_set_csma_params; - } - - if (dev->flags & IEEE802154_HW_FRAME_RETRIES) { - if (!priv->ops->set_frame_retries) - goto out; - - priv->phy->set_frame_retries = mac802154_set_frame_retries; - } - - priv->dev_workqueue = - create_singlethread_workqueue(wpan_phy_name(priv->phy)); - if (!priv->dev_workqueue) { - rc = -ENOMEM; - goto out; - } - - wpan_phy_set_dev(priv->phy, priv->hw.parent); - - priv->phy->add_iface = mac802154_add_iface; - priv->phy->del_iface = mac802154_del_iface; - - rc = wpan_phy_register(priv->phy); - if (rc < 0) - goto out_wq; - - rtnl_lock(); - - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_RUN; - mutex_unlock(&priv->slaves_mtx); - - rtnl_unlock(); - - return 0; - -out_wq: - destroy_workqueue(priv->dev_workqueue); -out: - return rc; -} -EXPORT_SYMBOL(ieee802154_register_device); - -void ieee802154_unregister_device(struct ieee802154_dev *dev) -{ - struct mac802154_priv *priv = mac802154_to_priv(dev); - struct mac802154_sub_if_data *sdata, *next; - - flush_workqueue(priv->dev_workqueue); - destroy_workqueue(priv->dev_workqueue); - - rtnl_lock(); - - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&priv->slaves_mtx); - - list_for_each_entry_safe(sdata, next, &priv->slaves, list) { - mutex_lock(&sdata->hw->slaves_mtx); - list_del(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); - - unregister_netdevice(sdata->dev); - } - - rtnl_unlock(); - - wpan_phy_unregister(priv->phy); -} -EXPORT_SYMBOL(ieee802154_unregister_device); - -MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); -MODULE_LICENSE("GPL v2"); diff --git a/net/mac802154/main.c b/net/mac802154/main.c new file mode 100644 index 000000000000..086d4a91ae45 --- /dev/null +++ b/net/mac802154/main.c @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2007-2012 Siemens AG + * + * Written by: + * Alexander Smirnov + * + * Based on the code from 'linux-zigbee.sourceforge.net' project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mac802154.h" + +int mac802154_slave_open(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct mac802154_sub_if_data *subif; + struct mac802154_priv *ipriv = priv->hw; + int res = 0; + + ASSERT_RTNL(); + + if (priv->type == IEEE802154_DEV_WPAN) { + mutex_lock(&priv->hw->slaves_mtx); + list_for_each_entry(subif, &priv->hw->slaves, list) { + if (subif != priv && subif->type == priv->type && + subif->running) { + mutex_unlock(&priv->hw->slaves_mtx); + return -EBUSY; + } + } + mutex_unlock(&priv->hw->slaves_mtx); + } + + mutex_lock(&priv->hw->slaves_mtx); + priv->running = true; + mutex_unlock(&priv->hw->slaves_mtx); + + if (ipriv->open_count++ == 0) { + res = ipriv->ops->start(&ipriv->hw); + WARN_ON(res); + if (res) + goto err; + } + + if (ipriv->ops->ieee_addr) { + __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); + + res = ipriv->ops->ieee_addr(&ipriv->hw, addr); + WARN_ON(res); + if (res) + goto err; + mac802154_dev_set_ieee_addr(dev); + } + + netif_start_queue(dev); + return 0; +err: + priv->hw->open_count--; + + return res; +} + +int mac802154_slave_close(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct mac802154_priv *ipriv = priv->hw; + + ASSERT_RTNL(); + + netif_stop_queue(dev); + + mutex_lock(&priv->hw->slaves_mtx); + priv->running = false; + mutex_unlock(&priv->hw->slaves_mtx); + + if (!--ipriv->open_count) + ipriv->ops->stop(&ipriv->hw); + + return 0; +} + +static int +mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + struct mac802154_priv *ipriv; + int err; + + ipriv = wpan_phy_priv(phy); + + priv = netdev_priv(dev); + priv->dev = dev; + priv->hw = ipriv; + + dev->needed_headroom = ipriv->hw.extra_tx_headroom; + + SET_NETDEV_DEV(dev, &ipriv->phy->dev); + + mutex_lock(&ipriv->slaves_mtx); + if (!ipriv->running) { + mutex_unlock(&ipriv->slaves_mtx); + return -ENODEV; + } + mutex_unlock(&ipriv->slaves_mtx); + + err = register_netdev(dev); + if (err < 0) + return err; + + rtnl_lock(); + mutex_lock(&ipriv->slaves_mtx); + list_add_tail_rcu(&priv->list, &ipriv->slaves); + mutex_unlock(&ipriv->slaves_mtx); + rtnl_unlock(); + + return 0; +} + +static void +mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) +{ + struct mac802154_sub_if_data *sdata; + + ASSERT_RTNL(); + + sdata = netdev_priv(dev); + + BUG_ON(sdata->hw->phy != phy); + + mutex_lock(&sdata->hw->slaves_mtx); + list_del_rcu(&sdata->list); + mutex_unlock(&sdata->hw->slaves_mtx); + + synchronize_rcu(); + unregister_netdevice(sdata->dev); +} + +static struct net_device * +mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) +{ + struct net_device *dev; + int err = -ENOMEM; + + switch (type) { + case IEEE802154_DEV_MONITOR: + dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + name, NET_NAME_UNKNOWN, + mac802154_monitor_setup); + break; + case IEEE802154_DEV_WPAN: + dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + name, NET_NAME_UNKNOWN, + mac802154_wpan_setup); + break; + default: + dev = NULL; + err = -EINVAL; + break; + } + if (!dev) + goto err; + + err = mac802154_netdev_register(phy, dev); + if (err) + goto err_free; + + dev_hold(dev); /* we return an incremented device refcount */ + return dev; + +err_free: + free_netdev(dev); +err: + return ERR_PTR(err); +} + +static int mac802154_set_txpower(struct wpan_phy *phy, int db) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_txpower(&priv->hw, db); +} + +static int mac802154_set_lbt(struct wpan_phy *phy, bool on) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_lbt(&priv->hw, on); +} + +static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_cca_mode(&priv->hw, mode); +} + +static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_cca_ed_level(&priv->hw, level); +} + +static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, + u8 max_be, u8 retries) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries); +} + +static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) +{ + struct mac802154_priv *priv = wpan_phy_priv(phy); + + return priv->ops->set_frame_retries(&priv->hw, retries); +} + +struct ieee802154_dev * +ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) +{ + struct wpan_phy *phy; + struct mac802154_priv *priv; + size_t priv_size; + + if (!ops || !ops->xmit || !ops->ed || !ops->start || + !ops->stop || !ops->set_channel) { + pr_err("undefined IEEE802.15.4 device operations\n"); + return NULL; + } + + /* Ensure 32-byte alignment of our private data and hw private data. + * We use the wpan_phy priv data for both our mac802154_priv and for + * the driver's private data + * + * in memory it'll be like this: + * + * +-----------------------+ + * | struct wpan_phy | + * +-----------------------+ + * | struct mac802154_priv | + * +-----------------------+ + * | driver's private data | + * +-----------------------+ + * + * Due to ieee802154 layer isn't aware of driver and MAC structures, + * so lets align them here. + */ + + priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; + + phy = wpan_phy_alloc(priv_size); + if (!phy) { + pr_err("failure to allocate master IEEE802.15.4 device\n"); + return NULL; + } + + priv = wpan_phy_priv(phy); + priv->phy = phy; + priv->hw.phy = priv->phy; + priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); + priv->ops = ops; + + INIT_LIST_HEAD(&priv->slaves); + mutex_init(&priv->slaves_mtx); + + return &priv->hw; +} +EXPORT_SYMBOL(ieee802154_alloc_device); + +void ieee802154_free_device(struct ieee802154_dev *hw) +{ + struct mac802154_priv *priv = mac802154_to_priv(hw); + + BUG_ON(!list_empty(&priv->slaves)); + + mutex_destroy(&priv->slaves_mtx); + + wpan_phy_free(priv->phy); +} +EXPORT_SYMBOL(ieee802154_free_device); + +int ieee802154_register_device(struct ieee802154_dev *dev) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + int rc = -ENOSYS; + + if (dev->flags & IEEE802154_HW_TXPOWER) { + if (!priv->ops->set_txpower) + goto out; + + priv->phy->set_txpower = mac802154_set_txpower; + } + + if (dev->flags & IEEE802154_HW_LBT) { + if (!priv->ops->set_lbt) + goto out; + + priv->phy->set_lbt = mac802154_set_lbt; + } + + if (dev->flags & IEEE802154_HW_CCA_MODE) { + if (!priv->ops->set_cca_mode) + goto out; + + priv->phy->set_cca_mode = mac802154_set_cca_mode; + } + + if (dev->flags & IEEE802154_HW_CCA_ED_LEVEL) { + if (!priv->ops->set_cca_ed_level) + goto out; + + priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; + } + + if (dev->flags & IEEE802154_HW_CSMA_PARAMS) { + if (!priv->ops->set_csma_params) + goto out; + + priv->phy->set_csma_params = mac802154_set_csma_params; + } + + if (dev->flags & IEEE802154_HW_FRAME_RETRIES) { + if (!priv->ops->set_frame_retries) + goto out; + + priv->phy->set_frame_retries = mac802154_set_frame_retries; + } + + priv->dev_workqueue = + create_singlethread_workqueue(wpan_phy_name(priv->phy)); + if (!priv->dev_workqueue) { + rc = -ENOMEM; + goto out; + } + + wpan_phy_set_dev(priv->phy, priv->hw.parent); + + priv->phy->add_iface = mac802154_add_iface; + priv->phy->del_iface = mac802154_del_iface; + + rc = wpan_phy_register(priv->phy); + if (rc < 0) + goto out_wq; + + rtnl_lock(); + + mutex_lock(&priv->slaves_mtx); + priv->running = MAC802154_DEVICE_RUN; + mutex_unlock(&priv->slaves_mtx); + + rtnl_unlock(); + + return 0; + +out_wq: + destroy_workqueue(priv->dev_workqueue); +out: + return rc; +} +EXPORT_SYMBOL(ieee802154_register_device); + +void ieee802154_unregister_device(struct ieee802154_dev *dev) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_sub_if_data *sdata, *next; + + flush_workqueue(priv->dev_workqueue); + destroy_workqueue(priv->dev_workqueue); + + rtnl_lock(); + + mutex_lock(&priv->slaves_mtx); + priv->running = MAC802154_DEVICE_STOPPED; + mutex_unlock(&priv->slaves_mtx); + + list_for_each_entry_safe(sdata, next, &priv->slaves, list) { + mutex_lock(&sdata->hw->slaves_mtx); + list_del(&sdata->list); + mutex_unlock(&sdata->hw->slaves_mtx); + + unregister_netdevice(sdata->dev); + } + + rtnl_unlock(); + + wpan_phy_unregister(priv->phy); +} +EXPORT_SYMBOL(ieee802154_unregister_device); + +MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 0f1556bc2b152fc5d2a6b929c579748ec90c55d0 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:00 +0200 Subject: mac802154: move mac802154.h to ieee802154_i.h This patch moves the mac802154.h internal header to ieee802154_i.h like the wireless stack ieee80211_i.h file. This avoids confusing with the not internal header include/net/mac802154.h header. Additional we get the same naming conversion like mac80211 for this file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 168 +++++++++++++++++++++++++++++++++++++++++++ net/mac802154/llsec.c | 2 +- net/mac802154/mac802154.h | 168 ------------------------------------------- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 2 +- net/mac802154/mib.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- net/mac802154/wpan.c | 2 +- 10 files changed, 176 insertions(+), 176 deletions(-) create mode 100644 net/mac802154/ieee802154_i.h delete mode 100644 net/mac802154/mac802154.h (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h new file mode 100644 index 000000000000..970b621fc50b --- /dev/null +++ b/net/mac802154/ieee802154_i.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Written by: + * Pavel Smolenskiy + * Maxim Gorbachyov + * Dmitry Eremin-Solenikov + * Alexander Smirnov + */ +#ifndef __IEEE802154_I_H +#define __IEEE802154_I_H + +#include +#include +#include + +#include "llsec.h" + +/* mac802154 device private data */ +struct mac802154_priv { + struct ieee802154_dev hw; + struct ieee802154_ops *ops; + + /* ieee802154 phy */ + struct wpan_phy *phy; + + int open_count; + + /* As in mac80211 slaves list is modified: + * 1) under the RTNL + * 2) protected by slaves_mtx; + * 3) in an RCU manner + * + * So atomic readers can use any of this protection methods. + */ + struct list_head slaves; + struct mutex slaves_mtx; + + /* This one is used for scanning and other jobs not to be interfered + * with serial driver. + */ + struct workqueue_struct *dev_workqueue; + + /* SoftMAC device is registered and running. One can add subinterfaces. + * This flag should be modified under slaves_mtx and RTNL, so you can + * read them using any of protection methods. + */ + bool running; +}; + +#define MAC802154_DEVICE_STOPPED 0x00 +#define MAC802154_DEVICE_RUN 0x01 + +/* Slave interface definition. + * + * Slaves represent typical network interfaces available from userspace. + * Each ieee802154 device/transceiver may have several slaves and able + * to be associated with several networks at the same time. + */ +struct mac802154_sub_if_data { + struct list_head list; /* the ieee802154_priv->slaves list */ + + struct mac802154_priv *hw; + struct net_device *dev; + + int type; + bool running; + + spinlock_t mib_lock; + + __le16 pan_id; + __le16 short_addr; + __le64 extended_addr; + + u8 chan; + u8 page; + + struct ieee802154_mac_params mac_params; + + /* MAC BSN field */ + u8 bsn; + /* MAC DSN field */ + u8 dsn; + + /* protects sec from concurrent access by netlink. access by + * encrypt/decrypt/header_create safe without additional protection. + */ + struct mutex sec_mtx; + + struct mac802154_llsec sec; +}; + +#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) + +#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ + +extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; +extern struct ieee802154_mlme_ops mac802154_mlme_wpan; + +int mac802154_slave_open(struct net_device *dev); +int mac802154_slave_close(struct net_device *dev); + +void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_monitor_setup(struct net_device *dev); + +void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_wpan_setup(struct net_device *dev); + +netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, + u8 page, u8 chan); + +/* MIB callbacks */ +void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); +__le16 mac802154_dev_get_short_addr(const struct net_device *dev); +void mac802154_dev_set_ieee_addr(struct net_device *dev); +__le16 mac802154_dev_get_pan_id(const struct net_device *dev); +void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); +void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); +u8 mac802154_dev_get_dsn(const struct net_device *dev); + +int mac802154_set_mac_params(struct net_device *dev, + const struct ieee802154_mac_params *params); +void mac802154_get_mac_params(struct net_device *dev, + struct ieee802154_mac_params *params); + +int mac802154_get_params(struct net_device *dev, + struct ieee802154_llsec_params *params); +int mac802154_set_params(struct net_device *dev, + const struct ieee802154_llsec_params *params, + int changed); + +int mac802154_add_key(struct net_device *dev, + const struct ieee802154_llsec_key_id *id, + const struct ieee802154_llsec_key *key); +int mac802154_del_key(struct net_device *dev, + const struct ieee802154_llsec_key_id *id); + +int mac802154_add_dev(struct net_device *dev, + const struct ieee802154_llsec_device *llsec_dev); +int mac802154_del_dev(struct net_device *dev, __le64 dev_addr); + +int mac802154_add_devkey(struct net_device *dev, + __le64 device_addr, + const struct ieee802154_llsec_device_key *key); +int mac802154_del_devkey(struct net_device *dev, + __le64 device_addr, + const struct ieee802154_llsec_device_key *key); + +int mac802154_add_seclevel(struct net_device *dev, + const struct ieee802154_llsec_seclevel *sl); +int mac802154_del_seclevel(struct net_device *dev, + const struct ieee802154_llsec_seclevel *sl); + +void mac802154_lock_table(struct net_device *dev); +void mac802154_get_table(struct net_device *dev, + struct ieee802154_llsec_table **t); +void mac802154_unlock_table(struct net_device *dev); + +#endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index 457058142098..26f876128ae0 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -20,7 +20,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" #include "llsec.h" static void llsec_key_put(struct mac802154_llsec_key *key); diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h deleted file mode 100644 index e3503c1bc04e..000000000000 --- a/net/mac802154/mac802154.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ -#ifndef MAC802154_H -#define MAC802154_H - -#include -#include -#include - -#include "llsec.h" - -/* mac802154 device private data */ -struct mac802154_priv { - struct ieee802154_dev hw; - struct ieee802154_ops *ops; - - /* ieee802154 phy */ - struct wpan_phy *phy; - - int open_count; - - /* As in mac80211 slaves list is modified: - * 1) under the RTNL - * 2) protected by slaves_mtx; - * 3) in an RCU manner - * - * So atomic readers can use any of this protection methods. - */ - struct list_head slaves; - struct mutex slaves_mtx; - - /* This one is used for scanning and other jobs not to be interfered - * with serial driver. - */ - struct workqueue_struct *dev_workqueue; - - /* SoftMAC device is registered and running. One can add subinterfaces. - * This flag should be modified under slaves_mtx and RTNL, so you can - * read them using any of protection methods. - */ - bool running; -}; - -#define MAC802154_DEVICE_STOPPED 0x00 -#define MAC802154_DEVICE_RUN 0x01 - -/* Slave interface definition. - * - * Slaves represent typical network interfaces available from userspace. - * Each ieee802154 device/transceiver may have several slaves and able - * to be associated with several networks at the same time. - */ -struct mac802154_sub_if_data { - struct list_head list; /* the ieee802154_priv->slaves list */ - - struct mac802154_priv *hw; - struct net_device *dev; - - int type; - bool running; - - spinlock_t mib_lock; - - __le16 pan_id; - __le16 short_addr; - __le64 extended_addr; - - u8 chan; - u8 page; - - struct ieee802154_mac_params mac_params; - - /* MAC BSN field */ - u8 bsn; - /* MAC DSN field */ - u8 dsn; - - /* protects sec from concurrent access by netlink. access by - * encrypt/decrypt/header_create safe without additional protection. - */ - struct mutex sec_mtx; - - struct mac802154_llsec sec; -}; - -#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) - -#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ - -extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; -extern struct ieee802154_mlme_ops mac802154_mlme_wpan; - -int mac802154_slave_open(struct net_device *dev); -int mac802154_slave_close(struct net_device *dev); - -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); -void mac802154_monitor_setup(struct net_device *dev); - -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb); -void mac802154_wpan_setup(struct net_device *dev); - -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, - u8 page, u8 chan); - -/* MIB callbacks */ -void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); -__le16 mac802154_dev_get_short_addr(const struct net_device *dev); -void mac802154_dev_set_ieee_addr(struct net_device *dev); -__le16 mac802154_dev_get_pan_id(const struct net_device *dev); -void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); -void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); -u8 mac802154_dev_get_dsn(const struct net_device *dev); - -int mac802154_set_mac_params(struct net_device *dev, - const struct ieee802154_mac_params *params); -void mac802154_get_mac_params(struct net_device *dev, - struct ieee802154_mac_params *params); - -int mac802154_get_params(struct net_device *dev, - struct ieee802154_llsec_params *params); -int mac802154_set_params(struct net_device *dev, - const struct ieee802154_llsec_params *params, - int changed); - -int mac802154_add_key(struct net_device *dev, - const struct ieee802154_llsec_key_id *id, - const struct ieee802154_llsec_key *key); -int mac802154_del_key(struct net_device *dev, - const struct ieee802154_llsec_key_id *id); - -int mac802154_add_dev(struct net_device *dev, - const struct ieee802154_llsec_device *llsec_dev); -int mac802154_del_dev(struct net_device *dev, __le64 dev_addr); - -int mac802154_add_devkey(struct net_device *dev, - __le64 device_addr, - const struct ieee802154_llsec_device_key *key); -int mac802154_del_devkey(struct net_device *dev, - __le64 device_addr, - const struct ieee802154_llsec_device_key *key); - -int mac802154_add_seclevel(struct net_device *dev, - const struct ieee802154_llsec_seclevel *sl); -int mac802154_del_seclevel(struct net_device *dev, - const struct ieee802154_llsec_seclevel *sl); - -void mac802154_lock_table(struct net_device *dev); -void mac802154_get_table(struct net_device *dev, - struct ieee802154_llsec_table **t); -void mac802154_unlock_table(struct net_device *dev); - -#endif /* MAC802154_H */ diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 85f70edbe8dd..7c4b05ba2fe1 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -27,7 +27,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static int mac802154_mlme_start_req(struct net_device *dev, struct ieee802154_addr *addr, diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 086d4a91ae45..d11e42ae10d6 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -27,7 +27,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" int mac802154_slave_open(struct net_device *dev) { diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 3ee604292238..91cd3b260243 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -23,7 +23,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" struct phy_chan_notify_work { struct work_struct work; diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 81249bb7c935..2647a9e002ea 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -28,7 +28,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index e99d9394d13a..bc6cffd51f94 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -26,7 +26,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" /* The IEEE 802.15.4 standard defines 4 MAC packet types: * - beacon frame diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 95ea412395c7..ef11cc6fa323 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -25,7 +25,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index b11a98d824e0..5adcbd87a4f5 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -29,7 +29,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static int mac802154_wpan_update_llsec(struct net_device *dev) { -- cgit v1.2.3 From 15859a5e141c4914c7c4d9dc9b2d54fa948fbd42 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:01 +0200 Subject: mac802154: move wpan.c to iface.c The wpan.c file contains the interface handling functions now. It's similar like the mac80211 iface.c file. This patch renames this file to iface.c to have similar naming convention in mac802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/iface.c | 595 +++++++++++++++++++++++++++++++++++++++++++++++++ net/mac802154/wpan.c | 595 ------------------------------------------------- 3 files changed, 596 insertions(+), 596 deletions(-) create mode 100644 net/mac802154/iface.c delete mode 100644 net/mac802154/wpan.c (limited to 'net') diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 1ecbc47d4276..203f42d511af 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o wpan.o llsec.o + monitor.o iface.o llsec.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c new file mode 100644 index 000000000000..5adcbd87a4f5 --- /dev/null +++ b/net/mac802154/iface.c @@ -0,0 +1,595 @@ +/* + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Written by: + * Dmitry Eremin-Solenikov + * Sergey Lapin + * Maxim Gorbachyov + * Alexander Smirnov + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ieee802154_i.h" + +static int mac802154_wpan_update_llsec(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); + int rc = 0; + + if (ops->llsec) { + struct ieee802154_llsec_params params; + int changed = 0; + + params.pan_id = priv->pan_id; + changed |= IEEE802154_LLSEC_PARAM_PAN_ID; + + params.hwaddr = priv->extended_addr; + changed |= IEEE802154_LLSEC_PARAM_HWADDR; + + rc = ops->llsec->set_params(dev, ¶ms, changed); + } + + return rc; +} + +static int +mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct sockaddr_ieee802154 *sa = + (struct sockaddr_ieee802154 *)&ifr->ifr_addr; + int err = -ENOIOCTLCMD; + + spin_lock_bh(&priv->mib_lock); + + switch (cmd) { + case SIOCGIFADDR: + { + u16 pan_id, short_addr; + + pan_id = le16_to_cpu(priv->pan_id); + short_addr = le16_to_cpu(priv->short_addr); + if (pan_id == IEEE802154_PANID_BROADCAST || + short_addr == IEEE802154_ADDR_BROADCAST) { + err = -EADDRNOTAVAIL; + break; + } + + sa->family = AF_IEEE802154; + sa->addr.addr_type = IEEE802154_ADDR_SHORT; + sa->addr.pan_id = pan_id; + sa->addr.short_addr = short_addr; + + err = 0; + break; + } + case SIOCSIFADDR: + dev_warn(&dev->dev, + "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n"); + if (sa->family != AF_IEEE802154 || + sa->addr.addr_type != IEEE802154_ADDR_SHORT || + sa->addr.pan_id == IEEE802154_PANID_BROADCAST || + sa->addr.short_addr == IEEE802154_ADDR_BROADCAST || + sa->addr.short_addr == IEEE802154_ADDR_UNDEF) { + err = -EINVAL; + break; + } + + priv->pan_id = cpu_to_le16(sa->addr.pan_id); + priv->short_addr = cpu_to_le16(sa->addr.short_addr); + + err = mac802154_wpan_update_llsec(dev); + break; + } + + spin_unlock_bh(&priv->mib_lock); + return err; +} + +static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + /* FIXME: validate addr */ + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + mac802154_dev_set_ieee_addr(dev); + return mac802154_wpan_update_llsec(dev); +} + +int mac802154_set_mac_params(struct net_device *dev, + const struct ieee802154_mac_params *params) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + mutex_lock(&priv->hw->slaves_mtx); + priv->mac_params = *params; + mutex_unlock(&priv->hw->slaves_mtx); + + return 0; +} + +void mac802154_get_mac_params(struct net_device *dev, + struct ieee802154_mac_params *params) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + mutex_lock(&priv->hw->slaves_mtx); + *params = priv->mac_params; + mutex_unlock(&priv->hw->slaves_mtx); +} + +static int mac802154_wpan_open(struct net_device *dev) +{ + int rc; + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct wpan_phy *phy = priv->hw->phy; + + rc = mac802154_slave_open(dev); + if (rc < 0) + return rc; + + mutex_lock(&phy->pib_lock); + + if (phy->set_txpower) { + rc = phy->set_txpower(phy, priv->mac_params.transmit_power); + if (rc < 0) + goto out; + } + + if (phy->set_lbt) { + rc = phy->set_lbt(phy, priv->mac_params.lbt); + if (rc < 0) + goto out; + } + + if (phy->set_cca_mode) { + rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode); + if (rc < 0) + goto out; + } + + if (phy->set_cca_ed_level) { + rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level); + if (rc < 0) + goto out; + } + + if (phy->set_csma_params) { + rc = phy->set_csma_params(phy, priv->mac_params.min_be, + priv->mac_params.max_be, + priv->mac_params.csma_retries); + if (rc < 0) + goto out; + } + + if (phy->set_frame_retries) { + rc = phy->set_frame_retries(phy, + priv->mac_params.frame_retries); + if (rc < 0) + goto out; + } + + mutex_unlock(&phy->pib_lock); + return 0; + +out: + mutex_unlock(&phy->pib_lock); + return rc; +} + +static int mac802154_set_header_security(struct mac802154_sub_if_data *priv, + struct ieee802154_hdr *hdr, + const struct ieee802154_mac_cb *cb) +{ + struct ieee802154_llsec_params params; + u8 level; + + mac802154_llsec_get_params(&priv->sec, ¶ms); + + if (!params.enabled && cb->secen_override && cb->secen) + return -EINVAL; + if (!params.enabled || + (cb->secen_override && !cb->secen) || + !params.out_level) + return 0; + if (cb->seclevel_override && !cb->seclevel) + return -EINVAL; + + level = cb->seclevel_override ? cb->seclevel : params.out_level; + + hdr->fc.security_enabled = 1; + hdr->sec.level = level; + hdr->sec.key_id_mode = params.out_key.mode; + if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX) + hdr->sec.short_src = params.out_key.short_source; + else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX) + hdr->sec.extended_src = params.out_key.extended_source; + hdr->sec.key_id = params.out_key.id; + + return 0; +} + +static int mac802154_header_create(struct sk_buff *skb, + struct net_device *dev, + unsigned short type, + const void *daddr, + const void *saddr, + unsigned len) +{ + struct ieee802154_hdr hdr; + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_mac_cb *cb = mac_cb(skb); + int hlen; + + if (!daddr) + return -EINVAL; + + memset(&hdr.fc, 0, sizeof(hdr.fc)); + hdr.fc.type = cb->type; + hdr.fc.security_enabled = cb->secen; + hdr.fc.ack_request = cb->ackreq; + hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); + + if (mac802154_set_header_security(priv, &hdr, cb) < 0) + return -EINVAL; + + if (!saddr) { + spin_lock_bh(&priv->mib_lock); + + if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || + priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || + priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { + hdr.source.mode = IEEE802154_ADDR_LONG; + hdr.source.extended_addr = priv->extended_addr; + } else { + hdr.source.mode = IEEE802154_ADDR_SHORT; + hdr.source.short_addr = priv->short_addr; + } + + hdr.source.pan_id = priv->pan_id; + + spin_unlock_bh(&priv->mib_lock); + } else { + hdr.source = *(const struct ieee802154_addr *)saddr; + } + + hdr.dest = *(const struct ieee802154_addr *)daddr; + + hlen = ieee802154_hdr_push(skb, &hdr); + if (hlen < 0) + return -EINVAL; + + skb_reset_mac_header(skb); + skb->mac_len = hlen; + + if (len > ieee802154_max_payload(&hdr)) + return -EMSGSIZE; + + return hlen; +} + +static int +mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{ + struct ieee802154_hdr hdr; + struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr; + + if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) { + pr_debug("malformed packet\n"); + return 0; + } + + *addr = hdr.source; + return sizeof(*addr); +} + +static netdev_tx_t +mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + u8 chan, page; + int rc; + + priv = netdev_priv(dev); + + spin_lock_bh(&priv->mib_lock); + chan = priv->chan; + page = priv->page; + spin_unlock_bh(&priv->mib_lock); + + if (chan == MAC802154_CHAN_NONE || + page >= WPAN_NUM_PAGES || + chan >= WPAN_NUM_CHANNELS) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + + rc = mac802154_llsec_encrypt(&priv->sec, skb); + if (rc) { + pr_warn("encryption failed: %i\n", rc); + kfree_skb(skb); + return NETDEV_TX_OK; + } + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(priv->hw, skb, page, chan); +} + +static struct header_ops mac802154_header_ops = { + .create = mac802154_header_create, + .parse = mac802154_header_parse, +}; + +static const struct net_device_ops mac802154_wpan_ops = { + .ndo_open = mac802154_wpan_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = mac802154_wpan_xmit, + .ndo_do_ioctl = mac802154_wpan_ioctl, + .ndo_set_mac_address = mac802154_wpan_mac_addr, +}; + +static void mac802154_wpan_free(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + mac802154_llsec_destroy(&priv->sec); + + free_netdev(dev); +} + +void mac802154_wpan_setup(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + + dev->addr_len = IEEE802154_ADDR_LEN; + memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); + + dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; + dev->header_ops = &mac802154_header_ops; + dev->needed_tailroom = 2 + 16; /* FCS + MIC */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 300; + dev->type = ARPHRD_IEEE802154; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = mac802154_wpan_free; + dev->netdev_ops = &mac802154_wpan_ops; + dev->ml_priv = &mac802154_mlme_wpan; + + priv = netdev_priv(dev); + priv->type = IEEE802154_DEV_WPAN; + + priv->chan = MAC802154_CHAN_NONE; + priv->page = 0; + + spin_lock_init(&priv->mib_lock); + mutex_init(&priv->sec_mtx); + + get_random_bytes(&priv->bsn, 1); + get_random_bytes(&priv->dsn, 1); + + /* defaults per 802.15.4-2011 */ + priv->mac_params.min_be = 3; + priv->mac_params.max_be = 5; + priv->mac_params.csma_retries = 4; + priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */ + + priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); + priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + + mac802154_llsec_init(&priv->sec); +} + +static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +{ + return netif_rx_ni(skb); +} + +static int +mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, + const struct ieee802154_hdr *hdr) +{ + __le16 span, sshort; + int rc; + + pr_debug("getting packet via slave interface %s\n", sdata->dev->name); + + spin_lock_bh(&sdata->mib_lock); + + span = sdata->pan_id; + sshort = sdata->short_addr; + + switch (mac_cb(skb)->dest.mode) { + case IEEE802154_ADDR_NONE: + if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) + /* FIXME: check if we are PAN coordinator */ + skb->pkt_type = PACKET_OTHERHOST; + else + /* ACK comes with both addresses empty */ + skb->pkt_type = PACKET_HOST; + break; + case IEEE802154_ADDR_LONG: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) + skb->pkt_type = PACKET_HOST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + case IEEE802154_ADDR_SHORT: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.short_addr == sshort) + skb->pkt_type = PACKET_HOST; + else if (mac_cb(skb)->dest.short_addr == + cpu_to_le16(IEEE802154_ADDR_BROADCAST)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + default: + spin_unlock_bh(&sdata->mib_lock); + pr_debug("invalid dest mode\n"); + kfree_skb(skb); + return NET_RX_DROP; + } + + spin_unlock_bh(&sdata->mib_lock); + + skb->dev = sdata->dev; + + rc = mac802154_llsec_decrypt(&sdata->sec, skb); + if (rc) { + pr_debug("decryption failed: %i\n", rc); + goto fail; + } + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + + switch (mac_cb(skb)->type) { + case IEEE802154_FC_TYPE_DATA: + return mac802154_process_data(sdata->dev, skb); + default: + pr_warn("ieee802154: bad frame received (type = %d)\n", + mac_cb(skb)->type); + goto fail; + } + +fail: + kfree_skb(skb); + return NET_RX_DROP; +} + +static void mac802154_print_addr(const char *name, + const struct ieee802154_addr *addr) +{ + if (addr->mode == IEEE802154_ADDR_NONE) + pr_debug("%s not present\n", name); + + pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); + if (addr->mode == IEEE802154_ADDR_SHORT) { + pr_debug("%s is short: %04x\n", name, + le16_to_cpu(addr->short_addr)); + } else { + u64 hw = swab64((__force u64) addr->extended_addr); + + pr_debug("%s is hardware: %8phC\n", name, &hw); + } +} + +static int mac802154_parse_frame_start(struct sk_buff *skb, + struct ieee802154_hdr *hdr) +{ + int hlen; + struct ieee802154_mac_cb *cb = mac_cb_init(skb); + + hlen = ieee802154_hdr_pull(skb, hdr); + if (hlen < 0) + return -EINVAL; + + skb->mac_len = hlen; + + pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), + hdr->seq); + + cb->type = hdr->fc.type; + cb->ackreq = hdr->fc.ack_request; + cb->secen = hdr->fc.security_enabled; + + mac802154_print_addr("destination", &hdr->dest); + mac802154_print_addr("source", &hdr->source); + + cb->source = hdr->source; + cb->dest = hdr->dest; + + if (hdr->fc.security_enabled) { + u64 key; + + pr_debug("seclevel %i\n", hdr->sec.level); + + switch (hdr->sec.key_id_mode) { + case IEEE802154_SCF_KEY_IMPLICIT: + pr_debug("implicit key\n"); + break; + + case IEEE802154_SCF_KEY_INDEX: + pr_debug("key %02x\n", hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_SHORT_INDEX: + pr_debug("key %04x:%04x %02x\n", + le32_to_cpu(hdr->sec.short_src) >> 16, + le32_to_cpu(hdr->sec.short_src) & 0xffff, + hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_HW_INDEX: + key = swab64((__force u64) hdr->sec.extended_src); + pr_debug("key source %8phC %02x\n", &key, + hdr->sec.key_id); + break; + } + } + + return 0; +} + +void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) +{ + int ret; + struct mac802154_sub_if_data *sdata; + struct ieee802154_hdr hdr; + + ret = mac802154_parse_frame_start(skb, &hdr); + if (ret) { + pr_debug("got invalid frame\n"); + kfree_skb(skb); + return; + } + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &priv->slaves, list) { + if (sdata->type != IEEE802154_DEV_WPAN || + !netif_running(sdata->dev)) + continue; + + mac802154_subif_frame(sdata, skb, &hdr); + skb = NULL; + break; + } + rcu_read_unlock(); + + if (skb) + kfree_skb(skb); +} diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c deleted file mode 100644 index 5adcbd87a4f5..000000000000 --- a/net/mac802154/wpan.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ieee802154_i.h" - -static int mac802154_wpan_update_llsec(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); - int rc = 0; - - if (ops->llsec) { - struct ieee802154_llsec_params params; - int changed = 0; - - params.pan_id = priv->pan_id; - changed |= IEEE802154_LLSEC_PARAM_PAN_ID; - - params.hwaddr = priv->extended_addr; - changed |= IEEE802154_LLSEC_PARAM_HWADDR; - - rc = ops->llsec->set_params(dev, ¶ms, changed); - } - - return rc; -} - -static int -mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct sockaddr_ieee802154 *sa = - (struct sockaddr_ieee802154 *)&ifr->ifr_addr; - int err = -ENOIOCTLCMD; - - spin_lock_bh(&priv->mib_lock); - - switch (cmd) { - case SIOCGIFADDR: - { - u16 pan_id, short_addr; - - pan_id = le16_to_cpu(priv->pan_id); - short_addr = le16_to_cpu(priv->short_addr); - if (pan_id == IEEE802154_PANID_BROADCAST || - short_addr == IEEE802154_ADDR_BROADCAST) { - err = -EADDRNOTAVAIL; - break; - } - - sa->family = AF_IEEE802154; - sa->addr.addr_type = IEEE802154_ADDR_SHORT; - sa->addr.pan_id = pan_id; - sa->addr.short_addr = short_addr; - - err = 0; - break; - } - case SIOCSIFADDR: - dev_warn(&dev->dev, - "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n"); - if (sa->family != AF_IEEE802154 || - sa->addr.addr_type != IEEE802154_ADDR_SHORT || - sa->addr.pan_id == IEEE802154_PANID_BROADCAST || - sa->addr.short_addr == IEEE802154_ADDR_BROADCAST || - sa->addr.short_addr == IEEE802154_ADDR_UNDEF) { - err = -EINVAL; - break; - } - - priv->pan_id = cpu_to_le16(sa->addr.pan_id); - priv->short_addr = cpu_to_le16(sa->addr.short_addr); - - err = mac802154_wpan_update_llsec(dev); - break; - } - - spin_unlock_bh(&priv->mib_lock); - return err; -} - -static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) -{ - struct sockaddr *addr = p; - - if (netif_running(dev)) - return -EBUSY; - - /* FIXME: validate addr */ - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - mac802154_dev_set_ieee_addr(dev); - return mac802154_wpan_update_llsec(dev); -} - -int mac802154_set_mac_params(struct net_device *dev, - const struct ieee802154_mac_params *params) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - - mutex_lock(&priv->hw->slaves_mtx); - priv->mac_params = *params; - mutex_unlock(&priv->hw->slaves_mtx); - - return 0; -} - -void mac802154_get_mac_params(struct net_device *dev, - struct ieee802154_mac_params *params) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - - mutex_lock(&priv->hw->slaves_mtx); - *params = priv->mac_params; - mutex_unlock(&priv->hw->slaves_mtx); -} - -static int mac802154_wpan_open(struct net_device *dev) -{ - int rc; - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct wpan_phy *phy = priv->hw->phy; - - rc = mac802154_slave_open(dev); - if (rc < 0) - return rc; - - mutex_lock(&phy->pib_lock); - - if (phy->set_txpower) { - rc = phy->set_txpower(phy, priv->mac_params.transmit_power); - if (rc < 0) - goto out; - } - - if (phy->set_lbt) { - rc = phy->set_lbt(phy, priv->mac_params.lbt); - if (rc < 0) - goto out; - } - - if (phy->set_cca_mode) { - rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode); - if (rc < 0) - goto out; - } - - if (phy->set_cca_ed_level) { - rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level); - if (rc < 0) - goto out; - } - - if (phy->set_csma_params) { - rc = phy->set_csma_params(phy, priv->mac_params.min_be, - priv->mac_params.max_be, - priv->mac_params.csma_retries); - if (rc < 0) - goto out; - } - - if (phy->set_frame_retries) { - rc = phy->set_frame_retries(phy, - priv->mac_params.frame_retries); - if (rc < 0) - goto out; - } - - mutex_unlock(&phy->pib_lock); - return 0; - -out: - mutex_unlock(&phy->pib_lock); - return rc; -} - -static int mac802154_set_header_security(struct mac802154_sub_if_data *priv, - struct ieee802154_hdr *hdr, - const struct ieee802154_mac_cb *cb) -{ - struct ieee802154_llsec_params params; - u8 level; - - mac802154_llsec_get_params(&priv->sec, ¶ms); - - if (!params.enabled && cb->secen_override && cb->secen) - return -EINVAL; - if (!params.enabled || - (cb->secen_override && !cb->secen) || - !params.out_level) - return 0; - if (cb->seclevel_override && !cb->seclevel) - return -EINVAL; - - level = cb->seclevel_override ? cb->seclevel : params.out_level; - - hdr->fc.security_enabled = 1; - hdr->sec.level = level; - hdr->sec.key_id_mode = params.out_key.mode; - if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX) - hdr->sec.short_src = params.out_key.short_source; - else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX) - hdr->sec.extended_src = params.out_key.extended_source; - hdr->sec.key_id = params.out_key.id; - - return 0; -} - -static int mac802154_header_create(struct sk_buff *skb, - struct net_device *dev, - unsigned short type, - const void *daddr, - const void *saddr, - unsigned len) -{ - struct ieee802154_hdr hdr; - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_mac_cb *cb = mac_cb(skb); - int hlen; - - if (!daddr) - return -EINVAL; - - memset(&hdr.fc, 0, sizeof(hdr.fc)); - hdr.fc.type = cb->type; - hdr.fc.security_enabled = cb->secen; - hdr.fc.ack_request = cb->ackreq; - hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); - - if (mac802154_set_header_security(priv, &hdr, cb) < 0) - return -EINVAL; - - if (!saddr) { - spin_lock_bh(&priv->mib_lock); - - if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || - priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || - priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { - hdr.source.mode = IEEE802154_ADDR_LONG; - hdr.source.extended_addr = priv->extended_addr; - } else { - hdr.source.mode = IEEE802154_ADDR_SHORT; - hdr.source.short_addr = priv->short_addr; - } - - hdr.source.pan_id = priv->pan_id; - - spin_unlock_bh(&priv->mib_lock); - } else { - hdr.source = *(const struct ieee802154_addr *)saddr; - } - - hdr.dest = *(const struct ieee802154_addr *)daddr; - - hlen = ieee802154_hdr_push(skb, &hdr); - if (hlen < 0) - return -EINVAL; - - skb_reset_mac_header(skb); - skb->mac_len = hlen; - - if (len > ieee802154_max_payload(&hdr)) - return -EMSGSIZE; - - return hlen; -} - -static int -mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) -{ - struct ieee802154_hdr hdr; - struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr; - - if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) { - pr_debug("malformed packet\n"); - return 0; - } - - *addr = hdr.source; - return sizeof(*addr); -} - -static netdev_tx_t -mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - u8 chan, page; - int rc; - - priv = netdev_priv(dev); - - spin_lock_bh(&priv->mib_lock); - chan = priv->chan; - page = priv->page; - spin_unlock_bh(&priv->mib_lock); - - if (chan == MAC802154_CHAN_NONE || - page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - - rc = mac802154_llsec_encrypt(&priv->sec, skb); - if (rc) { - pr_warn("encryption failed: %i\n", rc); - kfree_skb(skb); - return NETDEV_TX_OK; - } - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(priv->hw, skb, page, chan); -} - -static struct header_ops mac802154_header_ops = { - .create = mac802154_header_create, - .parse = mac802154_header_parse, -}; - -static const struct net_device_ops mac802154_wpan_ops = { - .ndo_open = mac802154_wpan_open, - .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_wpan_xmit, - .ndo_do_ioctl = mac802154_wpan_ioctl, - .ndo_set_mac_address = mac802154_wpan_mac_addr, -}; - -static void mac802154_wpan_free(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - - mac802154_llsec_destroy(&priv->sec); - - free_netdev(dev); -} - -void mac802154_wpan_setup(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - - dev->addr_len = IEEE802154_ADDR_LEN; - memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); - - dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; - dev->header_ops = &mac802154_header_ops; - dev->needed_tailroom = 2 + 16; /* FCS + MIC */ - dev->mtu = IEEE802154_MTU; - dev->tx_queue_len = 300; - dev->type = ARPHRD_IEEE802154; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; - - dev->destructor = mac802154_wpan_free; - dev->netdev_ops = &mac802154_wpan_ops; - dev->ml_priv = &mac802154_mlme_wpan; - - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_WPAN; - - priv->chan = MAC802154_CHAN_NONE; - priv->page = 0; - - spin_lock_init(&priv->mib_lock); - mutex_init(&priv->sec_mtx); - - get_random_bytes(&priv->bsn, 1); - get_random_bytes(&priv->dsn, 1); - - /* defaults per 802.15.4-2011 */ - priv->mac_params.min_be = 3; - priv->mac_params.max_be = 5; - priv->mac_params.csma_retries = 4; - priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */ - - priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); - priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); - - mac802154_llsec_init(&priv->sec); -} - -static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) -{ - return netif_rx_ni(skb); -} - -static int -mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, - const struct ieee802154_hdr *hdr) -{ - __le16 span, sshort; - int rc; - - pr_debug("getting packet via slave interface %s\n", sdata->dev->name); - - spin_lock_bh(&sdata->mib_lock); - - span = sdata->pan_id; - sshort = sdata->short_addr; - - switch (mac_cb(skb)->dest.mode) { - case IEEE802154_ADDR_NONE: - if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) - /* FIXME: check if we are PAN coordinator */ - skb->pkt_type = PACKET_OTHERHOST; - else - /* ACK comes with both addresses empty */ - skb->pkt_type = PACKET_HOST; - break; - case IEEE802154_ADDR_LONG: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) - skb->pkt_type = PACKET_HOST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - case IEEE802154_ADDR_SHORT: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.short_addr == sshort) - skb->pkt_type = PACKET_HOST; - else if (mac_cb(skb)->dest.short_addr == - cpu_to_le16(IEEE802154_ADDR_BROADCAST)) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - default: - spin_unlock_bh(&sdata->mib_lock); - pr_debug("invalid dest mode\n"); - kfree_skb(skb); - return NET_RX_DROP; - } - - spin_unlock_bh(&sdata->mib_lock); - - skb->dev = sdata->dev; - - rc = mac802154_llsec_decrypt(&sdata->sec, skb); - if (rc) { - pr_debug("decryption failed: %i\n", rc); - goto fail; - } - - sdata->dev->stats.rx_packets++; - sdata->dev->stats.rx_bytes += skb->len; - - switch (mac_cb(skb)->type) { - case IEEE802154_FC_TYPE_DATA: - return mac802154_process_data(sdata->dev, skb); - default: - pr_warn("ieee802154: bad frame received (type = %d)\n", - mac_cb(skb)->type); - goto fail; - } - -fail: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void mac802154_print_addr(const char *name, - const struct ieee802154_addr *addr) -{ - if (addr->mode == IEEE802154_ADDR_NONE) - pr_debug("%s not present\n", name); - - pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); - if (addr->mode == IEEE802154_ADDR_SHORT) { - pr_debug("%s is short: %04x\n", name, - le16_to_cpu(addr->short_addr)); - } else { - u64 hw = swab64((__force u64) addr->extended_addr); - - pr_debug("%s is hardware: %8phC\n", name, &hw); - } -} - -static int mac802154_parse_frame_start(struct sk_buff *skb, - struct ieee802154_hdr *hdr) -{ - int hlen; - struct ieee802154_mac_cb *cb = mac_cb_init(skb); - - hlen = ieee802154_hdr_pull(skb, hdr); - if (hlen < 0) - return -EINVAL; - - skb->mac_len = hlen; - - pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), - hdr->seq); - - cb->type = hdr->fc.type; - cb->ackreq = hdr->fc.ack_request; - cb->secen = hdr->fc.security_enabled; - - mac802154_print_addr("destination", &hdr->dest); - mac802154_print_addr("source", &hdr->source); - - cb->source = hdr->source; - cb->dest = hdr->dest; - - if (hdr->fc.security_enabled) { - u64 key; - - pr_debug("seclevel %i\n", hdr->sec.level); - - switch (hdr->sec.key_id_mode) { - case IEEE802154_SCF_KEY_IMPLICIT: - pr_debug("implicit key\n"); - break; - - case IEEE802154_SCF_KEY_INDEX: - pr_debug("key %02x\n", hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_SHORT_INDEX: - pr_debug("key %04x:%04x %02x\n", - le32_to_cpu(hdr->sec.short_src) >> 16, - le32_to_cpu(hdr->sec.short_src) & 0xffff, - hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_HW_INDEX: - key = swab64((__force u64) hdr->sec.extended_src); - pr_debug("key source %8phC %02x\n", &key, - hdr->sec.key_id); - break; - } - } - - return 0; -} - -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) -{ - int ret; - struct mac802154_sub_if_data *sdata; - struct ieee802154_hdr hdr; - - ret = mac802154_parse_frame_start(skb, &hdr); - if (ret) { - pr_debug("got invalid frame\n"); - kfree_skb(skb); - return; - } - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { - if (sdata->type != IEEE802154_DEV_WPAN || - !netif_running(sdata->dev)) - continue; - - mac802154_subif_frame(sdata, skb, &hdr); - skb = NULL; - break; - } - rcu_read_unlock(); - - if (skb) - kfree_skb(skb); -} -- cgit v1.2.3 From 5ad60d36993596f7b3b958500f9c66c5338cd855 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:02 +0200 Subject: ieee802154: move wpan-phy.h to cfg802154.h The wpan-phy header contains the wpan_phy struct information. Later this header will be have similar function like cfg80211 header. The cfg80211 header contains the wiphy struct which is identically the wpan_phy struct inside 802.15.4 subsystem. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakehard.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/cfg802154.h | 103 +++++++++++++++++++++++++++++++++++++ include/net/wpan-phy.h | 102 ------------------------------------ net/ieee802154/nl-mac.c | 2 +- net/ieee802154/nl-phy.c | 2 +- net/ieee802154/wpan-class.c | 2 +- net/mac802154/iface.c | 2 +- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 2 +- net/mac802154/mib.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 2 +- 16 files changed, 117 insertions(+), 116 deletions(-) create mode 100644 include/net/cfg802154.h delete mode 100644 include/net/wpan-phy.h (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 83a635f17367..795ac116602c 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -32,7 +32,7 @@ #include #include -#include +#include struct at86rf230_local; /* at86rf2xx chip depend data. diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 571f280204b6..f1770cf892ed 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #define SPI_COMMAND_BUFFER 3 diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 9ce854f43917..1460bf520498 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include struct fakehard_priv { struct wpan_phy *phy; diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index e4b1b1f66bd2..e6e2993b7ec6 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include static int numlbs = 1; diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 0006b9ad5127..bea7349db6ad 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h new file mode 100644 index 000000000000..5c674673ef20 --- /dev/null +++ b/include/net/cfg802154.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007, 2008, 2009 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Written by: + * Dmitry Eremin-Solenikov + */ + +#ifndef __NET_CFG802154_H +#define __NET_CFG802154_H + +#include +#include +#include + +/* According to the IEEE 802.15.4 stadard the upper most significant bits of + * the 32-bit channel bitmaps shall be used as an integer value to specify 32 + * possible channel pages. The lower 27 bits of the channel bit map shall be + * used as a bit mask to specify channel numbers within a channel page. + */ +#define WPAN_NUM_CHANNELS 27 +#define WPAN_NUM_PAGES 32 + +struct wpan_phy { + struct mutex pib_lock; + + /* + * This is a PIB according to 802.15.4-2011. + * We do not provide timing-related variables, as they + * aren't used outside of driver + */ + u8 current_channel; + u8 current_page; + u32 channels_supported[32]; + s8 transmit_power; + u8 cca_mode; + u8 min_be; + u8 max_be; + u8 csma_retries; + s8 frame_retries; + + bool lbt; + s32 cca_ed_level; + + struct device dev; + int idx; + + struct net_device *(*add_iface)(struct wpan_phy *phy, + const char *name, int type); + void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); + + int (*set_txpower)(struct wpan_phy *phy, int db); + int (*set_lbt)(struct wpan_phy *phy, bool on); + int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); + int (*set_cca_ed_level)(struct wpan_phy *phy, int level); + int (*set_csma_params)(struct wpan_phy *phy, u8 min_be, u8 max_be, + u8 retries); + int (*set_frame_retries)(struct wpan_phy *phy, s8 retries); + + char priv[0] __aligned(NETDEV_ALIGN); +}; + +#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) + +struct wpan_phy *wpan_phy_alloc(size_t priv_size); +static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) +{ + phy->dev.parent = dev; +} + +int wpan_phy_register(struct wpan_phy *phy); +void wpan_phy_unregister(struct wpan_phy *phy); +void wpan_phy_free(struct wpan_phy *phy); +/* Same semantics as for class_for_each_device */ +int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data); + +static inline void *wpan_phy_priv(struct wpan_phy *phy) +{ + BUG_ON(!phy); + return &phy->priv; +} + +struct wpan_phy *wpan_phy_find(const char *str); + +static inline void wpan_phy_put(struct wpan_phy *phy) +{ + put_device(&phy->dev); +} + +static inline const char *wpan_phy_name(struct wpan_phy *phy) +{ + return dev_name(&phy->dev); +} + +#endif /* __NET_CFG802154_H */ diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h deleted file mode 100644 index 1e9795f116ba..000000000000 --- a/include/net/wpan-phy.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Dmitry Eremin-Solenikov - */ - -#ifndef WPAN_PHY_H -#define WPAN_PHY_H - -#include -#include -#include - -/* According to the IEEE 802.15.4 stadard the upper most significant bits of - * the 32-bit channel bitmaps shall be used as an integer value to specify 32 - * possible channel pages. The lower 27 bits of the channel bit map shall be - * used as a bit mask to specify channel numbers within a channel page. - */ -#define WPAN_NUM_CHANNELS 27 -#define WPAN_NUM_PAGES 32 - -struct wpan_phy { - struct mutex pib_lock; - - /* - * This is a PIB according to 802.15.4-2011. - * We do not provide timing-related variables, as they - * aren't used outside of driver - */ - u8 current_channel; - u8 current_page; - u32 channels_supported[32]; - s8 transmit_power; - u8 cca_mode; - u8 min_be; - u8 max_be; - u8 csma_retries; - s8 frame_retries; - - bool lbt; - s32 cca_ed_level; - - struct device dev; - int idx; - - struct net_device *(*add_iface)(struct wpan_phy *phy, - const char *name, int type); - void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); - - int (*set_txpower)(struct wpan_phy *phy, int db); - int (*set_lbt)(struct wpan_phy *phy, bool on); - int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); - int (*set_cca_ed_level)(struct wpan_phy *phy, int level); - int (*set_csma_params)(struct wpan_phy *phy, u8 min_be, u8 max_be, - u8 retries); - int (*set_frame_retries)(struct wpan_phy *phy, s8 retries); - - char priv[0] __aligned(NETDEV_ALIGN); -}; - -#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) - -struct wpan_phy *wpan_phy_alloc(size_t priv_size); -static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) -{ - phy->dev.parent = dev; -} - -int wpan_phy_register(struct wpan_phy *phy); -void wpan_phy_unregister(struct wpan_phy *phy); -void wpan_phy_free(struct wpan_phy *phy); -/* Same semantics as for class_for_each_device */ -int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data); - -static inline void *wpan_phy_priv(struct wpan_phy *phy) -{ - BUG_ON(!phy); - return &phy->priv; -} - -struct wpan_phy *wpan_phy_find(const char *str); - -static inline void wpan_phy_put(struct wpan_phy *phy) -{ - put_device(&phy->dev); -} - -static inline const char *wpan_phy_name(struct wpan_phy *phy) -{ - return dev_name(&phy->dev); -} -#endif diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index 78a1529e8bb2..a9c8e3e98387 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "ieee802154.h" diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index e943e20bcf09..0afe760ff512 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include /* for rtnl_{un,}lock */ diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index e4c6fb31a360..760b7d752190 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include "ieee802154.h" diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 5adcbd87a4f5..5a604074555b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 7c4b05ba2fe1..f118ea06d344 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/net/mac802154/main.c b/net/mac802154/main.c index d11e42ae10d6..9798c741739c 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 91cd3b260243..7c9467216199 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 2647a9e002ea..ca1dedd9b229 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index ef11cc6fa323..8f537bf731ca 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include "ieee802154_i.h" -- cgit v1.2.3 From 86d52cd96414f05c4053fb264a85309772c6ae26 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:03 +0200 Subject: ieee802154: move wpan-class.c to core.c Like the wireless core.c file this file contains function for phy allocation and freeing. Move this file to core.c to get similar behaviour. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/Makefile | 2 +- net/ieee802154/core.c | 226 ++++++++++++++++++++++++++++++++++++++++++++ net/ieee802154/wpan-class.c | 226 -------------------------------------------- 3 files changed, 227 insertions(+), 227 deletions(-) create mode 100644 net/ieee802154/core.c delete mode 100644 net/ieee802154/wpan-class.c (limited to 'net') diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index 3914b1ed4274..e58c4cbb3639 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o -ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o \ +ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ header_ops.o af_802154-y := af_ieee802154.o raw.o dgram.o diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c new file mode 100644 index 000000000000..760b7d752190 --- /dev/null +++ b/net/ieee802154/core.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2007, 2008, 2009 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +#include + +#include "ieee802154.h" + +#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ +static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ + int ret; \ + \ + mutex_lock(&phy->pib_lock); \ + ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ + mutex_unlock(&phy->pib_lock); \ + return ret; \ +} \ +static DEVICE_ATTR_RO(name) + +#define MASTER_SHOW(field, format_string) \ + MASTER_SHOW_COMPLEX(field, format_string, phy->field) + +MASTER_SHOW(current_channel, "%d"); +MASTER_SHOW(current_page, "%d"); +MASTER_SHOW(transmit_power, "%d +- 1 dB"); +MASTER_SHOW(cca_mode, "%d"); + +static ssize_t channels_supported_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); + int ret; + int i, len = 0; + + mutex_lock(&phy->pib_lock); + for (i = 0; i < 32; i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, + "%#09x\n", phy->channels_supported[i]); + if (ret < 0) + break; + len += ret; + } + mutex_unlock(&phy->pib_lock); + return len; +} +static DEVICE_ATTR_RO(channels_supported); + +static struct attribute *pmib_attrs[] = { + &dev_attr_current_channel.attr, + &dev_attr_current_page.attr, + &dev_attr_channels_supported.attr, + &dev_attr_transmit_power.attr, + &dev_attr_cca_mode.attr, + NULL, +}; +ATTRIBUTE_GROUPS(pmib); + +static void wpan_phy_release(struct device *d) +{ + struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); + + kfree(phy); +} + +static struct class wpan_phy_class = { + .name = "ieee802154", + .dev_release = wpan_phy_release, + .dev_groups = pmib_groups, +}; + +static DEFINE_MUTEX(wpan_phy_mutex); +static int wpan_phy_idx; + +static int wpan_phy_match(struct device *dev, const void *data) +{ + return !strcmp(dev_name(dev), (const char *)data); +} + +struct wpan_phy *wpan_phy_find(const char *str) +{ + struct device *dev; + + if (WARN_ON(!str)) + return NULL; + + dev = class_find_device(&wpan_phy_class, NULL, str, wpan_phy_match); + if (!dev) + return NULL; + + return container_of(dev, struct wpan_phy, dev); +} +EXPORT_SYMBOL(wpan_phy_find); + +struct wpan_phy_iter_data { + int (*fn)(struct wpan_phy *phy, void *data); + void *data; +}; + +static int wpan_phy_iter(struct device *dev, void *_data) +{ + struct wpan_phy_iter_data *wpid = _data; + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); + + return wpid->fn(phy, wpid->data); +} + +int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), + void *data) +{ + struct wpan_phy_iter_data wpid = { + .fn = fn, + .data = data, + }; + + return class_for_each_device(&wpan_phy_class, NULL, + &wpid, wpan_phy_iter); +} +EXPORT_SYMBOL(wpan_phy_for_each); + +static int wpan_phy_idx_valid(int idx) +{ + return idx >= 0; +} + +struct wpan_phy *wpan_phy_alloc(size_t priv_size) +{ + struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size, + GFP_KERNEL); + + if (!phy) + goto out; + mutex_lock(&wpan_phy_mutex); + phy->idx = wpan_phy_idx++; + if (unlikely(!wpan_phy_idx_valid(phy->idx))) { + wpan_phy_idx--; + mutex_unlock(&wpan_phy_mutex); + kfree(phy); + goto out; + } + mutex_unlock(&wpan_phy_mutex); + + mutex_init(&phy->pib_lock); + + device_initialize(&phy->dev); + dev_set_name(&phy->dev, "wpan-phy%d", phy->idx); + + phy->dev.class = &wpan_phy_class; + + phy->current_channel = -1; /* not initialised */ + phy->current_page = 0; /* for compatibility */ + + return phy; + +out: + return NULL; +} +EXPORT_SYMBOL(wpan_phy_alloc); + +int wpan_phy_register(struct wpan_phy *phy) +{ + return device_add(&phy->dev); +} +EXPORT_SYMBOL(wpan_phy_register); + +void wpan_phy_unregister(struct wpan_phy *phy) +{ + device_del(&phy->dev); +} +EXPORT_SYMBOL(wpan_phy_unregister); + +void wpan_phy_free(struct wpan_phy *phy) +{ + put_device(&phy->dev); +} +EXPORT_SYMBOL(wpan_phy_free); + +static int __init wpan_phy_class_init(void) +{ + int rc; + + rc = class_register(&wpan_phy_class); + if (rc) + goto err; + + rc = ieee802154_nl_init(); + if (rc) + goto err_nl; + + return 0; +err_nl: + class_unregister(&wpan_phy_class); +err: + return rc; +} +subsys_initcall(wpan_phy_class_init); + +static void __exit wpan_phy_class_exit(void) +{ + ieee802154_nl_exit(); + class_unregister(&wpan_phy_class); +} +module_exit(wpan_phy_class_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface"); +MODULE_AUTHOR("Dmitry Eremin-Solenikov"); + diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c deleted file mode 100644 index 760b7d752190..000000000000 --- a/net/ieee802154/wpan-class.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -#include - -#include "ieee802154.h" - -#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ -static ssize_t name ## _show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ - int ret; \ - \ - mutex_lock(&phy->pib_lock); \ - ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ - mutex_unlock(&phy->pib_lock); \ - return ret; \ -} \ -static DEVICE_ATTR_RO(name) - -#define MASTER_SHOW(field, format_string) \ - MASTER_SHOW_COMPLEX(field, format_string, phy->field) - -MASTER_SHOW(current_channel, "%d"); -MASTER_SHOW(current_page, "%d"); -MASTER_SHOW(transmit_power, "%d +- 1 dB"); -MASTER_SHOW(cca_mode, "%d"); - -static ssize_t channels_supported_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); - int ret; - int i, len = 0; - - mutex_lock(&phy->pib_lock); - for (i = 0; i < 32; i++) { - ret = snprintf(buf + len, PAGE_SIZE - len, - "%#09x\n", phy->channels_supported[i]); - if (ret < 0) - break; - len += ret; - } - mutex_unlock(&phy->pib_lock); - return len; -} -static DEVICE_ATTR_RO(channels_supported); - -static struct attribute *pmib_attrs[] = { - &dev_attr_current_channel.attr, - &dev_attr_current_page.attr, - &dev_attr_channels_supported.attr, - &dev_attr_transmit_power.attr, - &dev_attr_cca_mode.attr, - NULL, -}; -ATTRIBUTE_GROUPS(pmib); - -static void wpan_phy_release(struct device *d) -{ - struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); - - kfree(phy); -} - -static struct class wpan_phy_class = { - .name = "ieee802154", - .dev_release = wpan_phy_release, - .dev_groups = pmib_groups, -}; - -static DEFINE_MUTEX(wpan_phy_mutex); -static int wpan_phy_idx; - -static int wpan_phy_match(struct device *dev, const void *data) -{ - return !strcmp(dev_name(dev), (const char *)data); -} - -struct wpan_phy *wpan_phy_find(const char *str) -{ - struct device *dev; - - if (WARN_ON(!str)) - return NULL; - - dev = class_find_device(&wpan_phy_class, NULL, str, wpan_phy_match); - if (!dev) - return NULL; - - return container_of(dev, struct wpan_phy, dev); -} -EXPORT_SYMBOL(wpan_phy_find); - -struct wpan_phy_iter_data { - int (*fn)(struct wpan_phy *phy, void *data); - void *data; -}; - -static int wpan_phy_iter(struct device *dev, void *_data) -{ - struct wpan_phy_iter_data *wpid = _data; - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); - - return wpid->fn(phy, wpid->data); -} - -int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), - void *data) -{ - struct wpan_phy_iter_data wpid = { - .fn = fn, - .data = data, - }; - - return class_for_each_device(&wpan_phy_class, NULL, - &wpid, wpan_phy_iter); -} -EXPORT_SYMBOL(wpan_phy_for_each); - -static int wpan_phy_idx_valid(int idx) -{ - return idx >= 0; -} - -struct wpan_phy *wpan_phy_alloc(size_t priv_size) -{ - struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size, - GFP_KERNEL); - - if (!phy) - goto out; - mutex_lock(&wpan_phy_mutex); - phy->idx = wpan_phy_idx++; - if (unlikely(!wpan_phy_idx_valid(phy->idx))) { - wpan_phy_idx--; - mutex_unlock(&wpan_phy_mutex); - kfree(phy); - goto out; - } - mutex_unlock(&wpan_phy_mutex); - - mutex_init(&phy->pib_lock); - - device_initialize(&phy->dev); - dev_set_name(&phy->dev, "wpan-phy%d", phy->idx); - - phy->dev.class = &wpan_phy_class; - - phy->current_channel = -1; /* not initialised */ - phy->current_page = 0; /* for compatibility */ - - return phy; - -out: - return NULL; -} -EXPORT_SYMBOL(wpan_phy_alloc); - -int wpan_phy_register(struct wpan_phy *phy) -{ - return device_add(&phy->dev); -} -EXPORT_SYMBOL(wpan_phy_register); - -void wpan_phy_unregister(struct wpan_phy *phy) -{ - device_del(&phy->dev); -} -EXPORT_SYMBOL(wpan_phy_unregister); - -void wpan_phy_free(struct wpan_phy *phy) -{ - put_device(&phy->dev); -} -EXPORT_SYMBOL(wpan_phy_free); - -static int __init wpan_phy_class_init(void) -{ - int rc; - - rc = class_register(&wpan_phy_class); - if (rc) - goto err; - - rc = ieee802154_nl_init(); - if (rc) - goto err_nl; - - return 0; -err_nl: - class_unregister(&wpan_phy_class); -err: - return rc; -} -subsys_initcall(wpan_phy_class_init); - -static void __exit wpan_phy_class_exit(void) -{ - ieee802154_nl_exit(); - class_unregister(&wpan_phy_class); -} -module_exit(wpan_phy_class_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface"); -MODULE_AUTHOR("Dmitry Eremin-Solenikov"); - -- cgit v1.2.3 From 4ca24aca55fe1e2a61f3ffaac9015d9c45204729 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:04 +0200 Subject: ieee802154: move ieee802154 header This patch moves the ieee802154 header into include/linux instead include/net. Similar like wireless which have the ieee80211 header inside of include/linux. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakehard.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/linux/ieee802154.h | 189 ++++++++++++++++++++++++++++++++++++ include/net/ieee802154.h | 191 ------------------------------------- include/net/ieee802154_netdev.h | 2 +- net/ieee802154/6lowpan_rtnl.c | 2 +- net/ieee802154/dgram.c | 2 +- net/ieee802154/header_ops.c | 3 +- net/ieee802154/nl-mac.c | 2 +- net/mac802154/iface.c | 2 +- net/mac802154/llsec.c | 2 +- net/mac802154/mac_cmd.c | 2 +- net/mac802154/monitor.c | 2 +- 15 files changed, 203 insertions(+), 204 deletions(-) create mode 100644 include/linux/ieee802154.h delete mode 100644 include/net/ieee802154.h (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 795ac116602c..a433d20587e1 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -29,8 +29,8 @@ #include #include #include +#include -#include #include #include diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index f1770cf892ed..32b3c8862b4f 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -21,10 +21,10 @@ #include #include #include +#include #include #include -#include #define SPI_COMMAND_BUFFER 3 #define HIGH 1 diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 1460bf520498..8be05ade0ceb 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -25,10 +25,10 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index bea7349db6ad..56a69599ac31 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include /* MRF24J40 Short Address Registers */ #define REG_RXMCR 0x00 /* Receive MAC control */ diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h new file mode 100644 index 000000000000..2dfab2db103a --- /dev/null +++ b/include/linux/ieee802154.h @@ -0,0 +1,189 @@ +/* + * IEEE802.15.4-2003 specification + * + * Copyright (C) 2007, 2008 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Written by: + * Pavel Smolenskiy + * Maxim Gorbachyov + * Maxim Osipov + * Dmitry Eremin-Solenikov + * Alexander Smirnov + */ + +#ifndef LINUX_IEEE802154_H +#define LINUX_IEEE802154_H + +#define IEEE802154_MTU 127 + +#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ +#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ +#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ +#define IEEE802154_FC_TYPE_MAC_CMD 0x3 /* Frame is MAC command */ + +#define IEEE802154_FC_TYPE_SHIFT 0 +#define IEEE802154_FC_TYPE_MASK ((1 << 3) - 1) +#define IEEE802154_FC_TYPE(x) ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT) +#define IEEE802154_FC_SET_TYPE(v, x) do { \ + v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \ + (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ + } while (0) + +#define IEEE802154_FC_SECEN_SHIFT 3 +#define IEEE802154_FC_SECEN (1 << IEEE802154_FC_SECEN_SHIFT) +#define IEEE802154_FC_FRPEND_SHIFT 4 +#define IEEE802154_FC_FRPEND (1 << IEEE802154_FC_FRPEND_SHIFT) +#define IEEE802154_FC_ACK_REQ_SHIFT 5 +#define IEEE802154_FC_ACK_REQ (1 << IEEE802154_FC_ACK_REQ_SHIFT) +#define IEEE802154_FC_INTRA_PAN_SHIFT 6 +#define IEEE802154_FC_INTRA_PAN (1 << IEEE802154_FC_INTRA_PAN_SHIFT) + +#define IEEE802154_FC_SAMODE_SHIFT 14 +#define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) +#define IEEE802154_FC_DAMODE_SHIFT 10 +#define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) + +#define IEEE802154_FC_VERSION_SHIFT 12 +#define IEEE802154_FC_VERSION_MASK (3 << IEEE802154_FC_VERSION_SHIFT) +#define IEEE802154_FC_VERSION(x) ((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT) + +#define IEEE802154_FC_SAMODE(x) \ + (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) + +#define IEEE802154_FC_DAMODE(x) \ + (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) + +#define IEEE802154_SCF_SECLEVEL_MASK 7 +#define IEEE802154_SCF_SECLEVEL_SHIFT 0 +#define IEEE802154_SCF_SECLEVEL(x) (x & IEEE802154_SCF_SECLEVEL_MASK) +#define IEEE802154_SCF_KEY_ID_MODE_SHIFT 3 +#define IEEE802154_SCF_KEY_ID_MODE_MASK (3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT) +#define IEEE802154_SCF_KEY_ID_MODE(x) \ + ((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT) + +#define IEEE802154_SCF_KEY_IMPLICIT 0 +#define IEEE802154_SCF_KEY_INDEX 1 +#define IEEE802154_SCF_KEY_SHORT_INDEX 2 +#define IEEE802154_SCF_KEY_HW_INDEX 3 + +#define IEEE802154_SCF_SECLEVEL_NONE 0 +#define IEEE802154_SCF_SECLEVEL_MIC32 1 +#define IEEE802154_SCF_SECLEVEL_MIC64 2 +#define IEEE802154_SCF_SECLEVEL_MIC128 3 +#define IEEE802154_SCF_SECLEVEL_ENC 4 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC32 5 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC64 6 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC128 7 + +/* MAC footer size */ +#define IEEE802154_MFR_SIZE 2 /* 2 octets */ + +/* MAC's Command Frames Identifiers */ +#define IEEE802154_CMD_ASSOCIATION_REQ 0x01 +#define IEEE802154_CMD_ASSOCIATION_RESP 0x02 +#define IEEE802154_CMD_DISASSOCIATION_NOTIFY 0x03 +#define IEEE802154_CMD_DATA_REQ 0x04 +#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY 0x05 +#define IEEE802154_CMD_ORPHAN_NOTIFY 0x06 +#define IEEE802154_CMD_BEACON_REQ 0x07 +#define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08 +#define IEEE802154_CMD_GTS_REQ 0x09 + +/* + * The return values of MAC operations + */ +enum { + /* + * The requested operation was completed successfully. + * For a transmission request, this value indicates + * a successful transmission. + */ + IEEE802154_SUCCESS = 0x0, + + /* The beacon was lost following a synchronization request. */ + IEEE802154_BEACON_LOSS = 0xe0, + /* + * A transmission could not take place due to activity on the + * channel, i.e., the CSMA-CA mechanism has failed. + */ + IEEE802154_CHNL_ACCESS_FAIL = 0xe1, + /* The GTS request has been denied by the PAN coordinator. */ + IEEE802154_DENINED = 0xe2, + /* The attempt to disable the transceiver has failed. */ + IEEE802154_DISABLE_TRX_FAIL = 0xe3, + /* + * The received frame induces a failed security check according to + * the security suite. + */ + IEEE802154_FAILED_SECURITY_CHECK = 0xe4, + /* + * The frame resulting from secure processing has a length that is + * greater than aMACMaxFrameSize. + */ + IEEE802154_FRAME_TOO_LONG = 0xe5, + /* + * The requested GTS transmission failed because the specified GTS + * either did not have a transmit GTS direction or was not defined. + */ + IEEE802154_INVALID_GTS = 0xe6, + /* + * A request to purge an MSDU from the transaction queue was made using + * an MSDU handle that was not found in the transaction table. + */ + IEEE802154_INVALID_HANDLE = 0xe7, + /* A parameter in the primitive is out of the valid range.*/ + IEEE802154_INVALID_PARAMETER = 0xe8, + /* No acknowledgment was received after aMaxFrameRetries. */ + IEEE802154_NO_ACK = 0xe9, + /* A scan operation failed to find any network beacons.*/ + IEEE802154_NO_BEACON = 0xea, + /* No response data were available following a request. */ + IEEE802154_NO_DATA = 0xeb, + /* The operation failed because a short address was not allocated. */ + IEEE802154_NO_SHORT_ADDRESS = 0xec, + /* + * A receiver enable request was unsuccessful because it could not be + * completed within the CAP. + */ + IEEE802154_OUT_OF_CAP = 0xed, + /* + * A PAN identifier conflict has been detected and communicated to the + * PAN coordinator. + */ + IEEE802154_PANID_CONFLICT = 0xee, + /* A coordinator realignment command has been received. */ + IEEE802154_REALIGMENT = 0xef, + /* The transaction has expired and its information discarded. */ + IEEE802154_TRANSACTION_EXPIRED = 0xf0, + /* There is no capacity to store the transaction. */ + IEEE802154_TRANSACTION_OVERFLOW = 0xf1, + /* + * The transceiver was in the transmitter enabled state when the + * receiver was requested to be enabled. + */ + IEEE802154_TX_ACTIVE = 0xf2, + /* The appropriate key is not available in the ACL. */ + IEEE802154_UNAVAILABLE_KEY = 0xf3, + /* + * A SET/GET request was issued with the identifier of a PIB attribute + * that is not supported. + */ + IEEE802154_UNSUPPORTED_ATTR = 0xf4, + /* + * A request to perform a scan operation failed because the MLME was + * in the process of performing a previously initiated scan operation. + */ + IEEE802154_SCAN_IN_PROGRESS = 0xfc, +}; + + +#endif /* LINUX_IEEE802154_H */ diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h deleted file mode 100644 index 4db4e320b2f5..000000000000 --- a/include/net/ieee802154.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * IEEE802.15.4-2003 specification - * - * Copyright (C) 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Maxim Osipov - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ - -#ifndef NET_IEEE802154_H -#define NET_IEEE802154_H - -#define IEEE802154_MTU 127 - -#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ -#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ -#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ -#define IEEE802154_FC_TYPE_MAC_CMD 0x3 /* Frame is MAC command */ - -#define IEEE802154_FC_TYPE_SHIFT 0 -#define IEEE802154_FC_TYPE_MASK ((1 << 3) - 1) -#define IEEE802154_FC_TYPE(x) ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT) -#define IEEE802154_FC_SET_TYPE(v, x) do { \ - v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \ - (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ - } while (0) - -#define IEEE802154_FC_SECEN_SHIFT 3 -#define IEEE802154_FC_SECEN (1 << IEEE802154_FC_SECEN_SHIFT) -#define IEEE802154_FC_FRPEND_SHIFT 4 -#define IEEE802154_FC_FRPEND (1 << IEEE802154_FC_FRPEND_SHIFT) -#define IEEE802154_FC_ACK_REQ_SHIFT 5 -#define IEEE802154_FC_ACK_REQ (1 << IEEE802154_FC_ACK_REQ_SHIFT) -#define IEEE802154_FC_INTRA_PAN_SHIFT 6 -#define IEEE802154_FC_INTRA_PAN (1 << IEEE802154_FC_INTRA_PAN_SHIFT) - -#define IEEE802154_FC_SAMODE_SHIFT 14 -#define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) -#define IEEE802154_FC_DAMODE_SHIFT 10 -#define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) - -#define IEEE802154_FC_VERSION_SHIFT 12 -#define IEEE802154_FC_VERSION_MASK (3 << IEEE802154_FC_VERSION_SHIFT) -#define IEEE802154_FC_VERSION(x) ((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT) - -#define IEEE802154_FC_SAMODE(x) \ - (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) - -#define IEEE802154_FC_DAMODE(x) \ - (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) - -#define IEEE802154_SCF_SECLEVEL_MASK 7 -#define IEEE802154_SCF_SECLEVEL_SHIFT 0 -#define IEEE802154_SCF_SECLEVEL(x) (x & IEEE802154_SCF_SECLEVEL_MASK) -#define IEEE802154_SCF_KEY_ID_MODE_SHIFT 3 -#define IEEE802154_SCF_KEY_ID_MODE_MASK (3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT) -#define IEEE802154_SCF_KEY_ID_MODE(x) \ - ((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT) - -#define IEEE802154_SCF_KEY_IMPLICIT 0 -#define IEEE802154_SCF_KEY_INDEX 1 -#define IEEE802154_SCF_KEY_SHORT_INDEX 2 -#define IEEE802154_SCF_KEY_HW_INDEX 3 - -#define IEEE802154_SCF_SECLEVEL_NONE 0 -#define IEEE802154_SCF_SECLEVEL_MIC32 1 -#define IEEE802154_SCF_SECLEVEL_MIC64 2 -#define IEEE802154_SCF_SECLEVEL_MIC128 3 -#define IEEE802154_SCF_SECLEVEL_ENC 4 -#define IEEE802154_SCF_SECLEVEL_ENC_MIC32 5 -#define IEEE802154_SCF_SECLEVEL_ENC_MIC64 6 -#define IEEE802154_SCF_SECLEVEL_ENC_MIC128 7 - -/* MAC footer size */ -#define IEEE802154_MFR_SIZE 2 /* 2 octets */ - -/* MAC's Command Frames Identifiers */ -#define IEEE802154_CMD_ASSOCIATION_REQ 0x01 -#define IEEE802154_CMD_ASSOCIATION_RESP 0x02 -#define IEEE802154_CMD_DISASSOCIATION_NOTIFY 0x03 -#define IEEE802154_CMD_DATA_REQ 0x04 -#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY 0x05 -#define IEEE802154_CMD_ORPHAN_NOTIFY 0x06 -#define IEEE802154_CMD_BEACON_REQ 0x07 -#define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08 -#define IEEE802154_CMD_GTS_REQ 0x09 - -/* - * The return values of MAC operations - */ -enum { - /* - * The requested operation was completed successfully. - * For a transmission request, this value indicates - * a successful transmission. - */ - IEEE802154_SUCCESS = 0x0, - - /* The beacon was lost following a synchronization request. */ - IEEE802154_BEACON_LOSS = 0xe0, - /* - * A transmission could not take place due to activity on the - * channel, i.e., the CSMA-CA mechanism has failed. - */ - IEEE802154_CHNL_ACCESS_FAIL = 0xe1, - /* The GTS request has been denied by the PAN coordinator. */ - IEEE802154_DENINED = 0xe2, - /* The attempt to disable the transceiver has failed. */ - IEEE802154_DISABLE_TRX_FAIL = 0xe3, - /* - * The received frame induces a failed security check according to - * the security suite. - */ - IEEE802154_FAILED_SECURITY_CHECK = 0xe4, - /* - * The frame resulting from secure processing has a length that is - * greater than aMACMaxFrameSize. - */ - IEEE802154_FRAME_TOO_LONG = 0xe5, - /* - * The requested GTS transmission failed because the specified GTS - * either did not have a transmit GTS direction or was not defined. - */ - IEEE802154_INVALID_GTS = 0xe6, - /* - * A request to purge an MSDU from the transaction queue was made using - * an MSDU handle that was not found in the transaction table. - */ - IEEE802154_INVALID_HANDLE = 0xe7, - /* A parameter in the primitive is out of the valid range.*/ - IEEE802154_INVALID_PARAMETER = 0xe8, - /* No acknowledgment was received after aMaxFrameRetries. */ - IEEE802154_NO_ACK = 0xe9, - /* A scan operation failed to find any network beacons.*/ - IEEE802154_NO_BEACON = 0xea, - /* No response data were available following a request. */ - IEEE802154_NO_DATA = 0xeb, - /* The operation failed because a short address was not allocated. */ - IEEE802154_NO_SHORT_ADDRESS = 0xec, - /* - * A receiver enable request was unsuccessful because it could not be - * completed within the CAP. - */ - IEEE802154_OUT_OF_CAP = 0xed, - /* - * A PAN identifier conflict has been detected and communicated to the - * PAN coordinator. - */ - IEEE802154_PANID_CONFLICT = 0xee, - /* A coordinator realignment command has been received. */ - IEEE802154_REALIGMENT = 0xef, - /* The transaction has expired and its information discarded. */ - IEEE802154_TRANSACTION_EXPIRED = 0xf0, - /* There is no capacity to store the transaction. */ - IEEE802154_TRANSACTION_OVERFLOW = 0xf1, - /* - * The transceiver was in the transmitter enabled state when the - * receiver was requested to be enabled. - */ - IEEE802154_TX_ACTIVE = 0xf2, - /* The appropriate key is not available in the ACL. */ - IEEE802154_UNAVAILABLE_KEY = 0xf3, - /* - * A SET/GET request was issued with the identifier of a PIB attribute - * that is not supported. - */ - IEEE802154_UNSUPPORTED_ATTR = 0xf4, - /* - * A request to perform a scan operation failed because the MLME was - * in the process of performing a previously initiated scan operation. - */ - IEEE802154_SCAN_IN_PROGRESS = 0xfc, -}; - - -#endif - - diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index f87420689d70..5e62d758eea5 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -23,10 +23,10 @@ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H -#include #include #include #include +#include struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 0c1a49b51e57..1779a08d110a 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -49,8 +49,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 71e99a0994e1..3d58befef467 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -23,9 +23,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index c09294e39ca6..a051b6993177 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -14,8 +14,9 @@ * Phoebe Buckheister */ +#include + #include -#include #include static int diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index a9c8e3e98387..fb6866d1dd39 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 5a604074555b..03eedc3b23ef 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -20,13 +20,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index 26f876128ae0..fa0d5237c2e0 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index f118ea06d344..ad09d54bc690 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -20,8 +20,8 @@ #include #include +#include -#include #include #include #include diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index ca1dedd9b229..ca82c72a635c 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -21,8 +21,8 @@ #include #include #include +#include -#include #include #include #include -- cgit v1.2.3 From 5a50439775853a8d565115edb63a5ab4bb780479 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:34 +0200 Subject: ieee802154: rename ieee802154_dev to ieee802154_hw The identical struct of the wireless stack implementation is named ieee80211_hw. This is useful to name the variable hw instead of get confusing with netdev dev variable. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 90 +++++++++++++++++++------------------- drivers/net/ieee802154/cc2520.c | 50 ++++++++++----------- drivers/net/ieee802154/fakelb.c | 78 ++++++++++++++++----------------- drivers/net/ieee802154/mrf24j40.c | 48 ++++++++++---------- include/net/mac802154.h | 44 +++++++++---------- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 34 +++++++------- net/mac802154/rx.c | 12 ++--- 8 files changed, 179 insertions(+), 179 deletions(-) (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index a433d20587e1..b0d68d7061c1 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -77,7 +77,7 @@ struct at86rf230_state_change { struct at86rf230_local { struct spi_device *spi; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct at86rf2xx_chip_data *data; struct regmap *regmap; @@ -808,7 +808,7 @@ at86rf230_rx(struct at86rf230_local *lp, /* We do not put CRC into the frame */ skb_trim(skb, len - 2); - ieee802154_rx_irqsafe(lp->dev, skb, lqi); + ieee802154_rx_irqsafe(lp->hw, skb, lqi); } static void @@ -969,9 +969,9 @@ at86rf230_xmit_tx_on(void *context) } static int -at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; struct at86rf230_state_change *ctx = &lp->tx; void (*tx_complete)(void *context) = at86rf230_write_frame; @@ -1012,7 +1012,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) } static int -at86rf230_ed(struct ieee802154_dev *dev, u8 *level) +at86rf230_ed(struct ieee802154_hw *hw, u8 *level) { might_sleep(); BUG_ON(!level); @@ -1021,15 +1021,15 @@ at86rf230_ed(struct ieee802154_dev *dev, u8 *level) } static int -at86rf230_start(struct ieee802154_dev *dev) +at86rf230_start(struct ieee802154_hw *hw) { - return at86rf230_sync_state_change(dev->priv, STATE_RX_AACK_ON); + return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); } static void -at86rf230_stop(struct ieee802154_dev *dev) +at86rf230_stop(struct ieee802154_hw *hw) { - at86rf230_sync_state_change(dev->priv, STATE_FORCE_TRX_OFF); + at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); } static int @@ -1064,15 +1064,15 @@ at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel) } static int -at86rf230_channel(struct ieee802154_dev *dev, int page, int channel) +at86rf230_channel(struct ieee802154_hw *hw, int page, int channel) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc; might_sleep(); if (page < 0 || page > 31 || - !(lp->dev->phy->channels_supported[page] & BIT(channel))) { + !(lp->hw->phy->channels_supported[page] & BIT(channel))) { WARN_ON(1); return -EINVAL; } @@ -1084,18 +1084,18 @@ at86rf230_channel(struct ieee802154_dev *dev, int page, int channel) /* Wait for PLL */ usleep_range(lp->data->t_channel_switch, lp->data->t_channel_switch + 10); - dev->phy->current_channel = channel; - dev->phy->current_page = page; + hw->phy->current_channel = channel; + hw->phy->current_page = page; return 0; } static int -at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, +at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); @@ -1138,9 +1138,9 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, } static int -at86rf230_set_txpower(struct ieee802154_dev *dev, int db) +at86rf230_set_txpower(struct ieee802154_hw *hw, int db) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; /* typical maximum output is 5dBm with RG_PHY_TX_PWR 0x60, lower five * bits decrease power in 1dB steps. 0x60 represents extra PA gain of @@ -1157,17 +1157,17 @@ at86rf230_set_txpower(struct ieee802154_dev *dev, int db) } static int -at86rf230_set_lbt(struct ieee802154_dev *dev, bool on) +at86rf230_set_lbt(struct ieee802154_hw *hw, bool on) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; return at86rf230_write_subreg(lp, SR_CSMA_LBT_MODE, on); } static int -at86rf230_set_cca_mode(struct ieee802154_dev *dev, u8 mode) +at86rf230_set_cca_mode(struct ieee802154_hw *hw, u8 mode) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; return at86rf230_write_subreg(lp, SR_CCA_MODE, mode); } @@ -1185,9 +1185,9 @@ at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level) } static int -at86rf230_set_cca_ed_level(struct ieee802154_dev *dev, s32 level) +at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 level) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; if (level < lp->data->rssi_base_val || level > 30) return -EINVAL; @@ -1197,10 +1197,10 @@ at86rf230_set_cca_ed_level(struct ieee802154_dev *dev, s32 level) } static int -at86rf230_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be, +at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc; if (min_be > max_be || max_be > 8 || retries > 5) @@ -1218,9 +1218,9 @@ at86rf230_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be, } static int -at86rf230_set_frame_retries(struct ieee802154_dev *dev, s8 retries) +at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc = 0; if (retries < -1 || retries > 15) @@ -1409,8 +1409,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) return -EINVAL; } - lp->dev->extra_tx_headroom = 0; - lp->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | + lp->hw->extra_tx_headroom = 0; + lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA; switch (part) { @@ -1421,15 +1421,15 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 3: chip = "at86rf231"; lp->data = &at86rf231_data; - lp->dev->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->channels_supported[0] = 0x7FFF800; break; case 7: chip = "at86rf212"; if (version == 1) { lp->data = &at86rf212_data; - lp->dev->flags |= IEEE802154_HW_LBT; - lp->dev->phy->channels_supported[0] = 0x00007FF; - lp->dev->phy->channels_supported[2] = 0x00007FF; + lp->hw->flags |= IEEE802154_HW_LBT; + lp->hw->phy->channels_supported[0] = 0x00007FF; + lp->hw->phy->channels_supported[2] = 0x00007FF; } else { rc = -ENOTSUPP; } @@ -1437,7 +1437,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 11: chip = "at86rf233"; lp->data = &at86rf233_data; - lp->dev->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->channels_supported[0] = 0x7FFF800; break; default: chip = "unkown"; @@ -1478,7 +1478,7 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) static int at86rf230_probe(struct spi_device *spi) { struct at86rf230_platform_data *pdata; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct at86rf230_local *lp; unsigned int status; int rc, irq_type; @@ -1517,14 +1517,14 @@ static int at86rf230_probe(struct spi_device *spi) usleep_range(120, 240); } - dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops); - if (!dev) + hw = ieee802154_alloc_hw(sizeof(*lp), &at86rf230_ops); + if (!hw) return -ENOMEM; - lp = dev->priv; - lp->dev = dev; + lp = hw->priv; + lp->hw = hw; lp->spi = spi; - dev->parent = &spi->dev; + hw->parent = &spi->dev; lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); if (IS_ERR(lp->regmap)) { @@ -1564,14 +1564,14 @@ static int at86rf230_probe(struct spi_device *spi) if (rc) goto free_dev; - rc = ieee802154_register_device(lp->dev); + rc = ieee802154_register_hw(lp->hw); if (rc) goto free_dev; return rc; free_dev: - ieee802154_free_device(lp->dev); + ieee802154_free_hw(lp->hw); return rc; } @@ -1582,8 +1582,8 @@ static int at86rf230_remove(struct spi_device *spi) /* mask all at86rf230 irq's */ at86rf230_write_subreg(lp, SR_IRQ_MASK, 0); - ieee802154_unregister_device(lp->dev); - ieee802154_free_device(lp->dev); + ieee802154_unregister_hw(lp->hw); + ieee802154_free_hw(lp->hw); dev_dbg(&spi->dev, "unregistered at86rf230\n"); return 0; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 32b3c8862b4f..b827e04d481b 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -193,7 +193,7 @@ /* Driver private information */ struct cc2520_private { struct spi_device *spi; /* SPI device structure */ - struct ieee802154_dev *dev; /* IEEE-802.15.4 device */ + struct ieee802154_hw *hw; /* IEEE-802.15.4 device */ u8 *buf; /* SPI TX/Rx data buffer */ struct mutex buffer_mutex; /* SPI buffer mutex */ bool is_tx; /* Flag for sync b/w Tx and Rx */ @@ -453,20 +453,20 @@ cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi) return status; } -static int cc2520_start(struct ieee802154_dev *dev) +static int cc2520_start(struct ieee802154_hw *hw) { - return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON); + return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON); } -static void cc2520_stop(struct ieee802154_dev *dev) +static void cc2520_stop(struct ieee802154_hw *hw) { - cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF); + cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF); } static int -cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb) +cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; unsigned long flags; int rc; u8 status = 0; @@ -536,7 +536,7 @@ static int cc2520_rx(struct cc2520_private *priv) skb_trim(skb, skb->len - 2); - ieee802154_rx_irqsafe(priv->dev, skb, lqi); + ieee802154_rx_irqsafe(priv->hw, skb, lqi); dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi); @@ -544,9 +544,9 @@ static int cc2520_rx(struct cc2520_private *priv) } static int -cc2520_ed(struct ieee802154_dev *dev, u8 *level) +cc2520_ed(struct ieee802154_hw *hw, u8 *level) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; u8 status = 0xff; u8 rssi; int ret; @@ -569,9 +569,9 @@ cc2520_ed(struct ieee802154_dev *dev, u8 *level) } static int -cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) +cc2520_set_channel(struct ieee802154_hw *hw, int page, int channel) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; int ret; might_sleep(); @@ -588,10 +588,10 @@ cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) } static int -cc2520_filter(struct ieee802154_dev *dev, +cc2520_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); @@ -645,27 +645,27 @@ static int cc2520_register(struct cc2520_private *priv) { int ret = -ENOMEM; - priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops); - if (!priv->dev) + priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops); + if (!priv->hw) goto err_ret; - priv->dev->priv = priv; - priv->dev->parent = &priv->spi->dev; - priv->dev->extra_tx_headroom = 0; + priv->hw->priv = priv; + priv->hw->parent = &priv->spi->dev; + priv->hw->extra_tx_headroom = 0; /* We do support only 2.4 Ghz */ - priv->dev->phy->channels_supported[0] = 0x7FFF800; - priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; + priv->hw->phy->channels_supported[0] = 0x7FFF800; + priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; dev_vdbg(&priv->spi->dev, "registered cc2520\n"); - ret = ieee802154_register_device(priv->dev); + ret = ieee802154_register_hw(priv->hw); if (ret) goto err_free_device; return 0; err_free_device: - ieee802154_free_device(priv->dev); + ieee802154_free_hw(priv->hw); err_ret: return ret; } @@ -1002,8 +1002,8 @@ static int cc2520_remove(struct spi_device *spi) mutex_destroy(&priv->buffer_mutex); flush_work(&priv->fifop_irqwork); - ieee802154_unregister_device(priv->dev); - ieee802154_free_device(priv->dev); + ieee802154_unregister_hw(priv->hw); + ieee802154_free_hw(priv->hw); return 0; } diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index e6e2993b7ec6..51e3c589d2e4 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -30,7 +30,7 @@ static int numlbs = 1; struct fakelb_dev_priv { - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct list_head list; struct fakelb_priv *fake; @@ -45,7 +45,7 @@ struct fakelb_priv { }; static int -fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) +fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level) { might_sleep(); BUG_ON(!level); @@ -55,13 +55,13 @@ fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) } static int -fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) +fakelb_hw_channel(struct ieee802154_hw *hw, int page, int channel) { pr_debug("set channel to %d\n", channel); might_sleep(); - dev->phy->current_page = page; - dev->phy->current_channel = channel; + hw->phy->current_page = page; + hw->phy->current_channel = channel; return 0; } @@ -74,15 +74,15 @@ fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) spin_lock(&priv->lock); if (priv->working) { newskb = pskb_copy(skb, GFP_ATOMIC); - ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); + ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc); } spin_unlock(&priv->lock); } static int -fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct fakelb_dev_priv *priv = dev->priv; + struct fakelb_dev_priv *priv = hw->priv; struct fakelb_priv *fake = priv->fake; might_sleep(); @@ -95,8 +95,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) struct fakelb_dev_priv *dp; list_for_each_entry(dp, &priv->fake->list, list) { if (dp != priv && - (dp->dev->phy->current_channel == - priv->dev->phy->current_channel)) + (dp->hw->phy->current_channel == + priv->hw->phy->current_channel)) fakelb_hw_deliver(dp, skb); } } @@ -106,8 +106,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) } static int -fakelb_hw_start(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; +fakelb_hw_start(struct ieee802154_hw *hw) { + struct fakelb_dev_priv *priv = hw->priv; int ret = 0; spin_lock(&priv->lock); @@ -121,8 +121,8 @@ fakelb_hw_start(struct ieee802154_dev *dev) { } static void -fakelb_hw_stop(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; +fakelb_hw_stop(struct ieee802154_hw *hw) { + struct fakelb_dev_priv *priv = hw->priv; spin_lock(&priv->lock); priv->working = 0; @@ -146,54 +146,54 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) { struct fakelb_dev_priv *priv; int err; - struct ieee802154_dev *ieee; + struct ieee802154_hw *hw; - ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); - if (!ieee) + hw = ieee802154_alloc_hw(sizeof(*priv), &fakelb_ops); + if (!hw) return -ENOMEM; - priv = ieee->priv; - priv->dev = ieee; + priv = hw->priv; + priv->hw = hw; /* 868 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 1; + hw->phy->channels_supported[0] |= 1; /* 915 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7fe; + hw->phy->channels_supported[0] |= 0x7fe; /* 2.4 GHz O-QPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7FFF800; + hw->phy->channels_supported[0] |= 0x7FFF800; /* 868 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 1; + hw->phy->channels_supported[1] |= 1; /* 915 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 0x7fe; + hw->phy->channels_supported[1] |= 0x7fe; /* 868 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 1; + hw->phy->channels_supported[2] |= 1; /* 915 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 0x7fe; + hw->phy->channels_supported[2] |= 0x7fe; /* 2.4 GHz CSS 802.15.4a-2007 */ - ieee->phy->channels_supported[3] |= 0x3fff; + hw->phy->channels_supported[3] |= 0x3fff; /* UWB Sub-gigahertz 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 1; + hw->phy->channels_supported[4] |= 1; /* UWB Low band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0x1e; + hw->phy->channels_supported[4] |= 0x1e; /* UWB High band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0xffe0; + hw->phy->channels_supported[4] |= 0xffe0; /* 750 MHz O-QPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf; + hw->phy->channels_supported[5] |= 0xf; /* 750 MHz MPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf0; + hw->phy->channels_supported[5] |= 0xf0; /* 950 MHz BPSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ff; + hw->phy->channels_supported[6] |= 0x3ff; /* 950 MHz GFSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ffc00; + hw->phy->channels_supported[6] |= 0x3ffc00; INIT_LIST_HEAD(&priv->list); priv->fake = fake; spin_lock_init(&priv->lock); - ieee->parent = dev; + hw->parent = dev; - err = ieee802154_register_device(ieee); + err = ieee802154_register_hw(hw); if (err) goto err_reg; @@ -204,7 +204,7 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) return 0; err_reg: - ieee802154_free_device(priv->dev); + ieee802154_free_hw(priv->hw); return err; } @@ -214,8 +214,8 @@ static void fakelb_del(struct fakelb_dev_priv *priv) list_del(&priv->list); write_unlock_bh(&priv->fake->lock); - ieee802154_unregister_device(priv->dev); - ieee802154_free_device(priv->dev); + ieee802154_unregister_hw(priv->hw); + ieee802154_free_hw(priv->hw); } static int fakelb_probe(struct platform_device *pdev) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 56a69599ac31..2e267c5c44da 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -79,7 +79,7 @@ enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC }; /* Device Private Data */ struct mrf24j40 { struct spi_device *spi; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct mutex buffer_mutex; /* only used to protect buf */ struct completion tx_complete; @@ -332,9 +332,9 @@ out: return ret; } -static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) +static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret = 0; @@ -383,7 +383,7 @@ err: return ret; } -static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) +static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level) { /* TODO: */ pr_warn("mrf24j40: ed not implemented\n"); @@ -391,9 +391,9 @@ static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) return 0; } -static int mrf24j40_start(struct ieee802154_dev *dev) +static int mrf24j40_start(struct ieee802154_hw *hw) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -408,9 +408,9 @@ static int mrf24j40_start(struct ieee802154_dev *dev) return 0; } -static void mrf24j40_stop(struct ieee802154_dev *dev) +static void mrf24j40_stop(struct ieee802154_hw *hw) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -423,10 +423,10 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) write_short_reg(devrec, REG_INTCON, val); } -static int mrf24j40_set_channel(struct ieee802154_dev *dev, +static int mrf24j40_set_channel(struct ieee802154_hw *hw, int page, int channel) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -454,11 +454,11 @@ static int mrf24j40_set_channel(struct ieee802154_dev *dev, return 0; } -static int mrf24j40_filter(struct ieee802154_dev *dev, +static int mrf24j40_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; dev_dbg(printdev(devrec), "filter\n"); @@ -564,7 +564,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040, * also from a workqueue). I think irqsafe is not necessary here. * Can someone confirm? */ - ieee802154_rx_irqsafe(devrec->dev, skb, lqi); + ieee802154_rx_irqsafe(devrec->hw, skb, lqi); dev_dbg(printdev(devrec), "RX Handled\n"); @@ -745,17 +745,17 @@ static int mrf24j40_probe(struct spi_device *spi) /* Register with the 802154 subsystem */ - devrec->dev = ieee802154_alloc_device(0, &mrf24j40_ops); - if (!devrec->dev) + devrec->hw = ieee802154_alloc_hw(0, &mrf24j40_ops); + if (!devrec->hw) goto err_ret; - devrec->dev->priv = devrec; - devrec->dev->parent = &devrec->spi->dev; - devrec->dev->phy->channels_supported[0] = CHANNEL_MASK; - devrec->dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; + devrec->hw->priv = devrec; + devrec->hw->parent = &devrec->spi->dev; + devrec->hw->phy->channels_supported[0] = CHANNEL_MASK; + devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; dev_dbg(printdev(devrec), "registered mrf24j40\n"); - ret = ieee802154_register_device(devrec->dev); + ret = ieee802154_register_hw(devrec->hw); if (ret) goto err_register_device; @@ -780,9 +780,9 @@ static int mrf24j40_probe(struct spi_device *spi) err_irq: err_hw_init: - ieee802154_unregister_device(devrec->dev); + ieee802154_unregister_hw(devrec->hw); err_register_device: - ieee802154_free_device(devrec->dev); + ieee802154_free_hw(devrec->hw); err_ret: return ret; } @@ -793,8 +793,8 @@ static int mrf24j40_remove(struct spi_device *spi) dev_dbg(printdev(devrec), "remove\n"); - ieee802154_unregister_device(devrec->dev); - ieee802154_free_device(devrec->dev); + ieee802154_unregister_hw(devrec->hw); + ieee802154_free_hw(devrec->hw); /* TODO: Will ieee802154_free_device() wait until ->xmit() is * complete? */ diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 70351de3a72c..eb0e1cb9ca98 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -52,7 +52,7 @@ struct ieee802154_hw_addr_filt { u8 pan_coord; }; -struct ieee802154_dev { +struct ieee802154_hw { /* filled by the driver */ int extra_tx_headroom; u32 flags; @@ -159,37 +159,37 @@ struct ieee802154_dev { */ struct ieee802154_ops { struct module *owner; - int (*start)(struct ieee802154_dev *dev); - void (*stop)(struct ieee802154_dev *dev); - int (*xmit)(struct ieee802154_dev *dev, + int (*start)(struct ieee802154_hw *hw); + void (*stop)(struct ieee802154_hw *hw); + int (*xmit)(struct ieee802154_hw *hw, struct sk_buff *skb); - int (*ed)(struct ieee802154_dev *dev, u8 *level); - int (*set_channel)(struct ieee802154_dev *dev, + int (*ed)(struct ieee802154_hw *hw, u8 *level); + int (*set_channel)(struct ieee802154_hw *hw, int page, int channel); - int (*set_hw_addr_filt)(struct ieee802154_dev *dev, - struct ieee802154_hw_addr_filt *filt, + int (*set_hw_addr_filt)(struct ieee802154_hw *hw, + struct ieee802154_hw_addr_filt *filt, unsigned long changed); - int (*ieee_addr)(struct ieee802154_dev *dev, __le64 addr); - int (*set_txpower)(struct ieee802154_dev *dev, int db); - int (*set_lbt)(struct ieee802154_dev *dev, bool on); - int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode); - int (*set_cca_ed_level)(struct ieee802154_dev *dev, + int (*ieee_addr)(struct ieee802154_hw *hw, __le64 addr); + int (*set_txpower)(struct ieee802154_hw *hw, int db); + int (*set_lbt)(struct ieee802154_hw *hw, bool on); + int (*set_cca_mode)(struct ieee802154_hw *hw, u8 mode); + int (*set_cca_ed_level)(struct ieee802154_hw *hw, s32 level); - int (*set_csma_params)(struct ieee802154_dev *dev, + int (*set_csma_params)(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries); - int (*set_frame_retries)(struct ieee802154_dev *dev, + int (*set_frame_retries)(struct ieee802154_hw *hw, s8 retries); }; -/* Basic interface to register ieee802154 device */ -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops); -void ieee802154_free_device(struct ieee802154_dev *dev); -int ieee802154_register_device(struct ieee802154_dev *dev); -void ieee802154_unregister_device(struct ieee802154_dev *dev); +/* Basic interface to register ieee802154 hwice */ +struct ieee802154_hw * +ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops); +void ieee802154_free_hw(struct ieee802154_hw *hw); +int ieee802154_register_hw(struct ieee802154_hw *hw); +void ieee802154_unregister_hw(struct ieee802154_hw *hw); -void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, +void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 970b621fc50b..0cb98e87645a 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -27,7 +27,7 @@ /* mac802154 device private data */ struct mac802154_priv { - struct ieee802154_dev hw; + struct ieee802154_hw hw; struct ieee802154_ops *ops; /* ieee802154 phy */ diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9798c741739c..b0bcc063e9af 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -235,8 +235,8 @@ static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) return priv->ops->set_frame_retries(&priv->hw, retries); } -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) +struct ieee802154_hw * +ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { struct wpan_phy *phy; struct mac802154_priv *priv; @@ -285,9 +285,9 @@ ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) return &priv->hw; } -EXPORT_SYMBOL(ieee802154_alloc_device); +EXPORT_SYMBOL(ieee802154_alloc_hw); -void ieee802154_free_device(struct ieee802154_dev *hw) +void ieee802154_free_hw(struct ieee802154_hw *hw) { struct mac802154_priv *priv = mac802154_to_priv(hw); @@ -297,49 +297,49 @@ void ieee802154_free_device(struct ieee802154_dev *hw) wpan_phy_free(priv->phy); } -EXPORT_SYMBOL(ieee802154_free_device); +EXPORT_SYMBOL(ieee802154_free_hw); -int ieee802154_register_device(struct ieee802154_dev *dev) +int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); int rc = -ENOSYS; - if (dev->flags & IEEE802154_HW_TXPOWER) { + if (hw->flags & IEEE802154_HW_TXPOWER) { if (!priv->ops->set_txpower) goto out; priv->phy->set_txpower = mac802154_set_txpower; } - if (dev->flags & IEEE802154_HW_LBT) { + if (hw->flags & IEEE802154_HW_LBT) { if (!priv->ops->set_lbt) goto out; priv->phy->set_lbt = mac802154_set_lbt; } - if (dev->flags & IEEE802154_HW_CCA_MODE) { + if (hw->flags & IEEE802154_HW_CCA_MODE) { if (!priv->ops->set_cca_mode) goto out; priv->phy->set_cca_mode = mac802154_set_cca_mode; } - if (dev->flags & IEEE802154_HW_CCA_ED_LEVEL) { + if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { if (!priv->ops->set_cca_ed_level) goto out; priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; } - if (dev->flags & IEEE802154_HW_CSMA_PARAMS) { + if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { if (!priv->ops->set_csma_params) goto out; priv->phy->set_csma_params = mac802154_set_csma_params; } - if (dev->flags & IEEE802154_HW_FRAME_RETRIES) { + if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { if (!priv->ops->set_frame_retries) goto out; @@ -377,11 +377,11 @@ out_wq: out: return rc; } -EXPORT_SYMBOL(ieee802154_register_device); +EXPORT_SYMBOL(ieee802154_register_hw); -void ieee802154_unregister_device(struct ieee802154_dev *dev) +void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); struct mac802154_sub_if_data *sdata, *next; flush_workqueue(priv->dev_workqueue); @@ -405,7 +405,7 @@ void ieee802154_unregister_device(struct ieee802154_dev *dev) wpan_phy_unregister(priv->phy); } -EXPORT_SYMBOL(ieee802154_unregister_device); +EXPORT_SYMBOL(ieee802154_unregister_hw); MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); MODULE_LICENSE("GPL v2"); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index bc6cffd51f94..62b5c7dfe7f3 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -42,12 +42,12 @@ struct rx_work { struct sk_buff *skb; struct work_struct work; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; u8 lqi; }; static void -mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) +mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { struct mac802154_priv *priv = mac802154_to_priv(hw); @@ -83,14 +83,14 @@ static void mac802154_rx_worker(struct work_struct *work) { struct rx_work *rw = container_of(work, struct rx_work, work); - mac802154_subif_rx(rw->dev, rw->skb, rw->lqi); + mac802154_subif_rx(rw->hw, rw->skb, rw->lqi); kfree(rw); } void -ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) +ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); struct rx_work *work; if (!skb) @@ -102,7 +102,7 @@ ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) INIT_WORK(&work->work, mac802154_rx_worker); work->skb = skb; - work->dev = dev; + work->hw = hw; work->lqi = lqi; queue_work(priv->dev_workqueue, &work->work); -- cgit v1.2.3 From a5e1ec538f54c4cb8ec9ce30867cfbab57225280 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:35 +0200 Subject: mac802154: rename mac802154_priv to ieee802154_local This patch rename the mac802154_priv to ieee802154_local. The mac802154_priv structure is like ieee80211_local and so we name it ieee802154_local. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 12 +-- net/mac802154/iface.c | 4 +- net/mac802154/main.c | 172 +++++++++++++++++++++---------------------- net/mac802154/mib.c | 21 +++--- net/mac802154/monitor.c | 4 +- net/mac802154/rx.c | 12 +-- net/mac802154/tx.c | 36 ++++----- 7 files changed, 130 insertions(+), 131 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 0cb98e87645a..eb55cd2d0b34 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -26,7 +26,7 @@ #include "llsec.h" /* mac802154 device private data */ -struct mac802154_priv { +struct ieee802154_local { struct ieee802154_hw hw; struct ieee802154_ops *ops; @@ -69,7 +69,7 @@ struct mac802154_priv { struct mac802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ - struct mac802154_priv *hw; + struct ieee802154_local *hw; struct net_device *dev; int type; @@ -99,7 +99,7 @@ struct mac802154_sub_if_data { struct mac802154_llsec sec; }; -#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) +#define mac802154_to_priv(_hw) container_of(_hw, struct ieee802154_local, hw) #define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ @@ -109,13 +109,13 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, +netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan); /* MIB callbacks */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 03eedc3b23ef..10f1ee27a616 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -565,7 +565,7 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, return 0; } -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) +void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) { int ret; struct mac802154_sub_if_data *sdata; @@ -579,7 +579,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) } rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { + list_for_each_entry_rcu(sdata, &local->slaves, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index b0bcc063e9af..387d4cf94853 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -33,7 +33,7 @@ int mac802154_slave_open(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); struct mac802154_sub_if_data *subif; - struct mac802154_priv *ipriv = priv->hw; + struct ieee802154_local *local = priv->hw; int res = 0; ASSERT_RTNL(); @@ -54,17 +54,17 @@ int mac802154_slave_open(struct net_device *dev) priv->running = true; mutex_unlock(&priv->hw->slaves_mtx); - if (ipriv->open_count++ == 0) { - res = ipriv->ops->start(&ipriv->hw); + if (local->open_count++ == 0) { + res = local->ops->start(&local->hw); WARN_ON(res); if (res) goto err; } - if (ipriv->ops->ieee_addr) { + if (local->ops->ieee_addr) { __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); - res = ipriv->ops->ieee_addr(&ipriv->hw, addr); + res = local->ops->ieee_addr(&local->hw, addr); WARN_ON(res); if (res) goto err; @@ -82,7 +82,7 @@ err: int mac802154_slave_close(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *ipriv = priv->hw; + struct ieee802154_local *local = priv->hw; ASSERT_RTNL(); @@ -92,8 +92,8 @@ int mac802154_slave_close(struct net_device *dev) priv->running = false; mutex_unlock(&priv->hw->slaves_mtx); - if (!--ipriv->open_count) - ipriv->ops->stop(&ipriv->hw); + if (!--local->open_count) + local->ops->stop(&local->hw); return 0; } @@ -102,34 +102,34 @@ static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { struct mac802154_sub_if_data *priv; - struct mac802154_priv *ipriv; + struct ieee802154_local *local; int err; - ipriv = wpan_phy_priv(phy); + local = wpan_phy_priv(phy); priv = netdev_priv(dev); priv->dev = dev; - priv->hw = ipriv; + priv->hw = local; - dev->needed_headroom = ipriv->hw.extra_tx_headroom; + dev->needed_headroom = local->hw.extra_tx_headroom; - SET_NETDEV_DEV(dev, &ipriv->phy->dev); + SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&ipriv->slaves_mtx); - if (!ipriv->running) { - mutex_unlock(&ipriv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + if (!local->running) { + mutex_unlock(&local->slaves_mtx); return -ENODEV; } - mutex_unlock(&ipriv->slaves_mtx); + mutex_unlock(&local->slaves_mtx); err = register_netdev(dev); if (err < 0) return err; rtnl_lock(); - mutex_lock(&ipriv->slaves_mtx); - list_add_tail_rcu(&priv->list, &ipriv->slaves); - mutex_unlock(&ipriv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + list_add_tail_rcu(&priv->list, &local->slaves); + mutex_unlock(&local->slaves_mtx); rtnl_unlock(); return 0; @@ -194,52 +194,52 @@ err: static int mac802154_set_txpower(struct wpan_phy *phy, int db) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_txpower(&priv->hw, db); + return local->ops->set_txpower(&local->hw, db); } static int mac802154_set_lbt(struct wpan_phy *phy, bool on) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_lbt(&priv->hw, on); + return local->ops->set_lbt(&local->hw, on); } static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_cca_mode(&priv->hw, mode); + return local->ops->set_cca_mode(&local->hw, mode); } static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_cca_ed_level(&priv->hw, level); + return local->ops->set_cca_ed_level(&local->hw, level); } static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, u8 max_be, u8 retries) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries); + return local->ops->set_csma_params(&local->hw, min_be, max_be, retries); } static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_frame_retries(&priv->hw, retries); + return local->ops->set_frame_retries(&local->hw, retries); } struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { struct wpan_phy *phy; - struct mac802154_priv *priv; + struct ieee802154_local *local; size_t priv_size; if (!ops || !ops->xmit || !ops->ed || !ops->start || @@ -249,24 +249,24 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) } /* Ensure 32-byte alignment of our private data and hw private data. - * We use the wpan_phy priv data for both our mac802154_priv and for + * We use the wpan_phy priv data for both our ieee802154_local and for * the driver's private data * * in memory it'll be like this: * - * +-----------------------+ - * | struct wpan_phy | - * +-----------------------+ - * | struct mac802154_priv | - * +-----------------------+ - * | driver's private data | - * +-----------------------+ + * +-------------------------+ + * | struct wpan_phy | + * +-------------------------+ + * | struct ieee802154_local | + * +-------------------------+ + * | driver's private data | + * +-------------------------+ * * Due to ieee802154 layer isn't aware of driver and MAC structures, * so lets align them here. */ - priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; + priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; phy = wpan_phy_alloc(priv_size); if (!phy) { @@ -274,106 +274,106 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) return NULL; } - priv = wpan_phy_priv(phy); - priv->phy = phy; - priv->hw.phy = priv->phy; - priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); - priv->ops = ops; + local = wpan_phy_priv(phy); + local->phy = phy; + local->hw.phy = local->phy; + local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); + local->ops = ops; - INIT_LIST_HEAD(&priv->slaves); - mutex_init(&priv->slaves_mtx); + INIT_LIST_HEAD(&local->slaves); + mutex_init(&local->slaves_mtx); - return &priv->hw; + return &local->hw; } EXPORT_SYMBOL(ieee802154_alloc_hw); void ieee802154_free_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); - BUG_ON(!list_empty(&priv->slaves)); + BUG_ON(!list_empty(&local->slaves)); - mutex_destroy(&priv->slaves_mtx); + mutex_destroy(&local->slaves_mtx); - wpan_phy_free(priv->phy); + wpan_phy_free(local->phy); } EXPORT_SYMBOL(ieee802154_free_hw); int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); int rc = -ENOSYS; if (hw->flags & IEEE802154_HW_TXPOWER) { - if (!priv->ops->set_txpower) + if (!local->ops->set_txpower) goto out; - priv->phy->set_txpower = mac802154_set_txpower; + local->phy->set_txpower = mac802154_set_txpower; } if (hw->flags & IEEE802154_HW_LBT) { - if (!priv->ops->set_lbt) + if (!local->ops->set_lbt) goto out; - priv->phy->set_lbt = mac802154_set_lbt; + local->phy->set_lbt = mac802154_set_lbt; } if (hw->flags & IEEE802154_HW_CCA_MODE) { - if (!priv->ops->set_cca_mode) + if (!local->ops->set_cca_mode) goto out; - priv->phy->set_cca_mode = mac802154_set_cca_mode; + local->phy->set_cca_mode = mac802154_set_cca_mode; } if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { - if (!priv->ops->set_cca_ed_level) + if (!local->ops->set_cca_ed_level) goto out; - priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; + local->phy->set_cca_ed_level = mac802154_set_cca_ed_level; } if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { - if (!priv->ops->set_csma_params) + if (!local->ops->set_csma_params) goto out; - priv->phy->set_csma_params = mac802154_set_csma_params; + local->phy->set_csma_params = mac802154_set_csma_params; } if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { - if (!priv->ops->set_frame_retries) + if (!local->ops->set_frame_retries) goto out; - priv->phy->set_frame_retries = mac802154_set_frame_retries; + local->phy->set_frame_retries = mac802154_set_frame_retries; } - priv->dev_workqueue = - create_singlethread_workqueue(wpan_phy_name(priv->phy)); - if (!priv->dev_workqueue) { + local->dev_workqueue = + create_singlethread_workqueue(wpan_phy_name(local->phy)); + if (!local->dev_workqueue) { rc = -ENOMEM; goto out; } - wpan_phy_set_dev(priv->phy, priv->hw.parent); + wpan_phy_set_dev(local->phy, local->hw.parent); - priv->phy->add_iface = mac802154_add_iface; - priv->phy->del_iface = mac802154_del_iface; + local->phy->add_iface = mac802154_add_iface; + local->phy->del_iface = mac802154_del_iface; - rc = wpan_phy_register(priv->phy); + rc = wpan_phy_register(local->phy); if (rc < 0) goto out_wq; rtnl_lock(); - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_RUN; - mutex_unlock(&priv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + local->running = MAC802154_DEVICE_RUN; + mutex_unlock(&local->slaves_mtx); rtnl_unlock(); return 0; out_wq: - destroy_workqueue(priv->dev_workqueue); + destroy_workqueue(local->dev_workqueue); out: return rc; } @@ -381,19 +381,19 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); struct mac802154_sub_if_data *sdata, *next; - flush_workqueue(priv->dev_workqueue); - destroy_workqueue(priv->dev_workqueue); + flush_workqueue(local->dev_workqueue); + destroy_workqueue(local->dev_workqueue); rtnl_lock(); - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&priv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + local->running = MAC802154_DEVICE_STOPPED; + mutex_unlock(&local->slaves_mtx); - list_for_each_entry_safe(sdata, next, &priv->slaves, list) { + list_for_each_entry_safe(sdata, next, &local->slaves, list) { mutex_lock(&sdata->hw->slaves_mtx); list_del(&sdata->list); mutex_unlock(&sdata->hw->slaves_mtx); @@ -403,7 +403,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_unlock(); - wpan_phy_unregister(priv->phy); + wpan_phy_unregister(local->phy); } EXPORT_SYMBOL(ieee802154_unregister_hw); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 7c9467216199..5d9592a128db 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -36,7 +36,7 @@ struct hw_addr_filt_notify_work { unsigned long changed; }; -static struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) +static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); @@ -49,12 +49,11 @@ static void hw_addr_notify(struct work_struct *work) { struct hw_addr_filt_notify_work *nw = container_of(work, struct hw_addr_filt_notify_work, work); - struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); int res; - res = hw->ops->set_hw_addr_filt(&hw->hw, - &hw->hw.hw_filt, - nw->changed); + res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt, + nw->changed); if (res) pr_debug("failed changed mask %lx\n", nw->changed); @@ -110,13 +109,13 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *mac = priv->hw; + struct ieee802154_local *local = priv->hw; priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); - if (mac->ops->set_hw_addr_filt && - mac->hw.hw_filt.ieee_addr != priv->extended_addr) { - mac->hw.hw_filt.ieee_addr = priv->extended_addr; + if (local->ops->set_hw_addr_filt && + local->hw.hw_filt.ieee_addr != priv->extended_addr) { + local->hw.hw_filt.ieee_addr = priv->extended_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } @@ -165,12 +164,12 @@ static void phy_chan_notify(struct work_struct *work) { struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); - struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); int res; mutex_lock(&priv->hw->phy->pib_lock); - res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan); + res = local->ops->set_channel(&local->hw, priv->page, priv->chan); if (res) { pr_debug("set_channel failed\n"); } else { diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index ca82c72a635c..a107fd2f2312 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -57,7 +57,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, } -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct mac802154_sub_if_data *sdata; @@ -65,7 +65,7 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) u8 *data; rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { + list_for_each_entry_rcu(sdata, &local->slaves, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 62b5c7dfe7f3..dc01817a92c5 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -49,13 +49,13 @@ struct rx_work { static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc; if (skb->len < 2) { @@ -70,8 +70,8 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) skb_trim(skb, skb->len - 2); /* CRC */ } - mac802154_monitors_rx(priv, skb); - mac802154_wpans_rx(priv, skb); + mac802154_monitors_rx(local, skb); + mac802154_wpans_rx(local, skb); return; @@ -90,7 +90,7 @@ static void mac802154_rx_worker(struct work_struct *work) void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); struct rx_work *work; if (!skb) @@ -105,6 +105,6 @@ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) work->hw = hw; work->lqi = lqi; - queue_work(priv->dev_workqueue, &work->work); + queue_work(local->dev_workqueue, &work->work); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8f537bf731ca..d4c92bd3ad32 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -33,7 +33,7 @@ struct xmit_work { struct sk_buff *skb; struct work_struct work; - struct mac802154_priv *priv; + struct ieee802154_local *local; u8 chan; u8 page; }; @@ -44,10 +44,10 @@ static void mac802154_xmit_worker(struct work_struct *work) struct mac802154_sub_if_data *sdata; int res; - mutex_lock(&xw->priv->phy->pib_lock); - if (xw->priv->phy->current_channel != xw->chan || - xw->priv->phy->current_page != xw->page) { - res = xw->priv->ops->set_channel(&xw->priv->hw, + mutex_lock(&xw->local->phy->pib_lock); + if (xw->local->phy->current_channel != xw->chan || + xw->local->phy->current_page != xw->page) { + res = xw->local->ops->set_channel(&xw->local->hw, xw->page, xw->chan); if (res) { @@ -55,20 +55,20 @@ static void mac802154_xmit_worker(struct work_struct *work) goto out; } - xw->priv->phy->current_channel = xw->chan; - xw->priv->phy->current_page = xw->page; + xw->local->phy->current_channel = xw->chan; + xw->local->phy->current_page = xw->page; } - res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); + res = xw->local->ops->xmit(&xw->local->hw, xw->skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&xw->priv->phy->pib_lock); + mutex_unlock(&xw->local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->priv->slaves, list) + list_for_each_entry_rcu(sdata, &xw->local->slaves, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); @@ -77,20 +77,20 @@ out: kfree(xw); } -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, +netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; struct mac802154_sub_if_data *sdata; - if (!(priv->phy->channels_supported[page] & (1 << chan))) { + if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); goto err_tx; } - mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); + mac802154_monitors_rx(mac802154_to_priv(&local->hw), skb); - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data = skb_put(skb, 2); @@ -98,7 +98,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, data[1] = crc >> 8; } - if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) + if (skb_cow_head(skb, local->hw.extra_tx_headroom)) goto err_tx; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -109,17 +109,17 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) + list_for_each_entry_rcu(sdata, &local->slaves, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); INIT_WORK(&work->work, mac802154_xmit_worker); work->skb = skb; - work->priv = priv; + work->local = local; work->page = page; work->chan = chan; - queue_work(priv->dev_workqueue, &work->work); + queue_work(local->dev_workqueue, &work->work); return NETDEV_TX_OK; -- cgit v1.2.3 From 036562f9c4d942f2fbc77ae3215309bde340546f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:36 +0200 Subject: mac802154: rename mac802154_sub_if_data Like wireless this structure should named ieee802154_sub_if_data and not mac802154_sub_if_data. This patch renames the struct and variables to sdata instead priv sometimes. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 137 +++++++++++++++--------------- net/mac802154/mac_cmd.c | 4 +- net/mac802154/main.c | 54 ++++++------ net/mac802154/mib.c | 192 +++++++++++++++++++++---------------------- net/mac802154/monitor.c | 22 ++--- net/mac802154/tx.c | 4 +- 7 files changed, 208 insertions(+), 207 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index eb55cd2d0b34..daaca371110f 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -66,7 +66,7 @@ struct ieee802154_local { * Each ieee802154 device/transceiver may have several slaves and able * to be associated with several networks at the same time. */ -struct mac802154_sub_if_data { +struct ieee802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ struct ieee802154_local *hw; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 10f1ee27a616..d3eb8a445a81 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -33,7 +33,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); int rc = 0; @@ -41,10 +41,10 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) struct ieee802154_llsec_params params; int changed = 0; - params.pan_id = priv->pan_id; + params.pan_id = sdata->pan_id; changed |= IEEE802154_LLSEC_PARAM_PAN_ID; - params.hwaddr = priv->extended_addr; + params.hwaddr = sdata->extended_addr; changed |= IEEE802154_LLSEC_PARAM_HWADDR; rc = ops->llsec->set_params(dev, ¶ms, changed); @@ -56,20 +56,20 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) static int mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct sockaddr_ieee802154 *sa = (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; - spin_lock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); switch (cmd) { case SIOCGIFADDR: { u16 pan_id, short_addr; - pan_id = le16_to_cpu(priv->pan_id); - short_addr = le16_to_cpu(priv->short_addr); + pan_id = le16_to_cpu(sdata->pan_id); + short_addr = le16_to_cpu(sdata->short_addr); if (pan_id == IEEE802154_PANID_BROADCAST || short_addr == IEEE802154_ADDR_BROADCAST) { err = -EADDRNOTAVAIL; @@ -96,14 +96,14 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; } - priv->pan_id = cpu_to_le16(sa->addr.pan_id); - priv->short_addr = cpu_to_le16(sa->addr.short_addr); + sdata->pan_id = cpu_to_le16(sa->addr.pan_id); + sdata->short_addr = cpu_to_le16(sa->addr.short_addr); err = mac802154_wpan_update_llsec(dev); break; } - spin_unlock_bh(&priv->mib_lock); + spin_unlock_bh(&sdata->mib_lock); return err; } @@ -123,11 +123,11 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) int mac802154_set_mac_params(struct net_device *dev, const struct ieee802154_mac_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&priv->hw->slaves_mtx); - priv->mac_params = *params; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->mac_params = *params; + mutex_unlock(&sdata->hw->slaves_mtx); return 0; } @@ -135,18 +135,18 @@ int mac802154_set_mac_params(struct net_device *dev, void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_mac_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&priv->hw->slaves_mtx); - *params = priv->mac_params; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + *params = sdata->mac_params; + mutex_unlock(&sdata->hw->slaves_mtx); } static int mac802154_wpan_open(struct net_device *dev) { int rc; - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct wpan_phy *phy = priv->hw->phy; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct wpan_phy *phy = sdata->hw->phy; rc = mac802154_slave_open(dev); if (rc < 0) @@ -155,40 +155,40 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); if (phy->set_txpower) { - rc = phy->set_txpower(phy, priv->mac_params.transmit_power); + rc = phy->set_txpower(phy, sdata->mac_params.transmit_power); if (rc < 0) goto out; } if (phy->set_lbt) { - rc = phy->set_lbt(phy, priv->mac_params.lbt); + rc = phy->set_lbt(phy, sdata->mac_params.lbt); if (rc < 0) goto out; } if (phy->set_cca_mode) { - rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode); + rc = phy->set_cca_mode(phy, sdata->mac_params.cca_mode); if (rc < 0) goto out; } if (phy->set_cca_ed_level) { - rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level); + rc = phy->set_cca_ed_level(phy, sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } if (phy->set_csma_params) { - rc = phy->set_csma_params(phy, priv->mac_params.min_be, - priv->mac_params.max_be, - priv->mac_params.csma_retries); + rc = phy->set_csma_params(phy, sdata->mac_params.min_be, + sdata->mac_params.max_be, + sdata->mac_params.csma_retries); if (rc < 0) goto out; } if (phy->set_frame_retries) { rc = phy->set_frame_retries(phy, - priv->mac_params.frame_retries); + sdata->mac_params.frame_retries); if (rc < 0) goto out; } @@ -201,14 +201,14 @@ out: return rc; } -static int mac802154_set_header_security(struct mac802154_sub_if_data *priv, +static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata, struct ieee802154_hdr *hdr, const struct ieee802154_mac_cb *cb) { struct ieee802154_llsec_params params; u8 level; - mac802154_llsec_get_params(&priv->sec, ¶ms); + mac802154_llsec_get_params(&sdata->sec, ¶ms); if (!params.enabled && cb->secen_override && cb->secen) return -EINVAL; @@ -241,7 +241,7 @@ static int mac802154_header_create(struct sk_buff *skb, unsigned len) { struct ieee802154_hdr hdr; - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; @@ -254,25 +254,25 @@ static int mac802154_header_create(struct sk_buff *skb, hdr.fc.ack_request = cb->ackreq; hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); - if (mac802154_set_header_security(priv, &hdr, cb) < 0) + if (mac802154_set_header_security(sdata, &hdr, cb) < 0) return -EINVAL; if (!saddr) { - spin_lock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); - if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || - priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || - priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { + if (sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || + sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || + sdata->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { hdr.source.mode = IEEE802154_ADDR_LONG; - hdr.source.extended_addr = priv->extended_addr; + hdr.source.extended_addr = sdata->extended_addr; } else { hdr.source.mode = IEEE802154_ADDR_SHORT; - hdr.source.short_addr = priv->short_addr; + hdr.source.short_addr = sdata->short_addr; } - hdr.source.pan_id = priv->pan_id; + hdr.source.pan_id = sdata->pan_id; - spin_unlock_bh(&priv->mib_lock); + spin_unlock_bh(&sdata->mib_lock); } else { hdr.source = *(const struct ieee802154_addr *)saddr; } @@ -310,16 +310,16 @@ mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) static netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; u8 chan, page; int rc; - priv = netdev_priv(dev); + sdata = netdev_priv(dev); - spin_lock_bh(&priv->mib_lock); - chan = priv->chan; - page = priv->page; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + chan = sdata->chan; + page = sdata->page; + spin_unlock_bh(&sdata->mib_lock); if (chan == MAC802154_CHAN_NONE || page >= WPAN_NUM_PAGES || @@ -328,7 +328,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - rc = mac802154_llsec_encrypt(&priv->sec, skb); + rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { pr_warn("encryption failed: %i\n", rc); kfree_skb(skb); @@ -339,7 +339,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(priv->hw, skb, page, chan); + return mac802154_tx(sdata->hw, skb, page, chan); } static struct header_ops mac802154_header_ops = { @@ -357,16 +357,16 @@ static const struct net_device_ops mac802154_wpan_ops = { static void mac802154_wpan_free(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mac802154_llsec_destroy(&priv->sec); + mac802154_llsec_destroy(&sdata->sec); free_netdev(dev); } void mac802154_wpan_setup(struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; dev->addr_len = IEEE802154_ADDR_LEN; memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); @@ -384,28 +384,29 @@ void mac802154_wpan_setup(struct net_device *dev) dev->netdev_ops = &mac802154_wpan_ops; dev->ml_priv = &mac802154_mlme_wpan; - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_WPAN; + sdata = netdev_priv(dev); + sdata->type = IEEE802154_DEV_WPAN; - priv->chan = MAC802154_CHAN_NONE; - priv->page = 0; + sdata->chan = MAC802154_CHAN_NONE; + sdata->page = 0; - spin_lock_init(&priv->mib_lock); - mutex_init(&priv->sec_mtx); + spin_lock_init(&sdata->mib_lock); + mutex_init(&sdata->sec_mtx); - get_random_bytes(&priv->bsn, 1); - get_random_bytes(&priv->dsn, 1); + get_random_bytes(&sdata->bsn, 1); + get_random_bytes(&sdata->dsn, 1); /* defaults per 802.15.4-2011 */ - priv->mac_params.min_be = 3; - priv->mac_params.max_be = 5; - priv->mac_params.csma_retries = 4; - priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */ + sdata->mac_params.min_be = 3; + sdata->mac_params.max_be = 5; + sdata->mac_params.csma_retries = 4; + /* for compatibility, actual default is 3 */ + sdata->mac_params.frame_retries = -1; - priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); - priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); + sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); - mac802154_llsec_init(&priv->sec); + mac802154_llsec_init(&sdata->sec); } static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) @@ -414,7 +415,7 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) } static int -mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, +mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, const struct ieee802154_hdr *hdr) { __le16 span, sshort; @@ -568,7 +569,7 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) { int ret; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; struct ieee802154_hdr hdr; ret = mac802154_parse_frame_start(skb, &hdr); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index ad09d54bc690..bccaefbe0ba2 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -75,11 +75,11 @@ static int mac802154_mlme_start_req(struct net_device *dev, static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return to_phy(get_device(&priv->hw->phy->dev)); + return to_phy(get_device(&sdata->hw->phy->dev)); } static struct ieee802154_llsec_ops mac802154_llsec_ops = { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 387d4cf94853..6f630d4990fa 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -31,28 +31,28 @@ int mac802154_slave_open(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_sub_if_data *subif; - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *subif; + struct ieee802154_local *local = sdata->hw; int res = 0; ASSERT_RTNL(); - if (priv->type == IEEE802154_DEV_WPAN) { - mutex_lock(&priv->hw->slaves_mtx); - list_for_each_entry(subif, &priv->hw->slaves, list) { - if (subif != priv && subif->type == priv->type && + if (sdata->type == IEEE802154_DEV_WPAN) { + mutex_lock(&sdata->hw->slaves_mtx); + list_for_each_entry(subif, &sdata->hw->slaves, list) { + if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&priv->hw->slaves_mtx); + mutex_unlock(&sdata->hw->slaves_mtx); return -EBUSY; } } - mutex_unlock(&priv->hw->slaves_mtx); + mutex_unlock(&sdata->hw->slaves_mtx); } - mutex_lock(&priv->hw->slaves_mtx); - priv->running = true; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->running = true; + mutex_unlock(&sdata->hw->slaves_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -74,23 +74,23 @@ int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: - priv->hw->open_count--; + sdata->hw->open_count--; return res; } int mac802154_slave_close(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_local *local = sdata->hw; ASSERT_RTNL(); netif_stop_queue(dev); - mutex_lock(&priv->hw->slaves_mtx); - priv->running = false; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->running = false; + mutex_unlock(&sdata->hw->slaves_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -101,15 +101,15 @@ int mac802154_slave_close(struct net_device *dev) static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; struct ieee802154_local *local; int err; local = wpan_phy_priv(phy); - priv = netdev_priv(dev); - priv->dev = dev; - priv->hw = local; + sdata = netdev_priv(dev); + sdata->dev = dev; + sdata->hw = local; dev->needed_headroom = local->hw.extra_tx_headroom; @@ -128,7 +128,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) rtnl_lock(); mutex_lock(&local->slaves_mtx); - list_add_tail_rcu(&priv->list, &local->slaves); + list_add_tail_rcu(&sdata->list, &local->slaves); mutex_unlock(&local->slaves_mtx); rtnl_unlock(); @@ -138,7 +138,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) static void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) { - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; ASSERT_RTNL(); @@ -162,12 +162,12 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) switch (type) { case IEEE802154_DEV_MONITOR: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), name, NET_NAME_UNKNOWN, mac802154_monitor_setup); break; case IEEE802154_DEV_WPAN: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), name, NET_NAME_UNKNOWN, mac802154_wpan_setup); break; @@ -382,7 +382,7 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = mac802154_to_priv(hw); - struct mac802154_sub_if_data *sdata, *next; + struct ieee802154_sub_if_data *sdata, *next; flush_workqueue(local->dev_workqueue); destroy_workqueue(local->dev_workqueue); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 5d9592a128db..ef05b3bd9a63 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -38,11 +38,11 @@ struct hw_addr_filt_notify_work { static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return priv->hw; + return sdata->hw; } static void hw_addr_notify(struct work_struct *work) @@ -62,7 +62,7 @@ static void hw_addr_notify(struct work_struct *work) static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct hw_addr_filt_notify_work *work; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -72,92 +72,92 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(priv->hw->dev_workqueue, &work->work); + queue_work(sdata->hw->dev_workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->short_addr = val; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->short_addr = val; + spin_unlock_bh(&sdata->mib_lock); - if ((priv->hw->ops->set_hw_addr_filt) && - (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { - priv->hw->hw.hw_filt.short_addr = priv->short_addr; + if ((sdata->hw->ops->set_hw_addr_filt) && + (sdata->hw->hw.hw_filt.short_addr != sdata->short_addr)) { + sdata->hw->hw.hw_filt.short_addr = sdata->short_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } __le16 mac802154_dev_get_short_addr(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - ret = priv->short_addr; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + ret = sdata->short_addr; + spin_unlock_bh(&sdata->mib_lock); return ret; } void mac802154_dev_set_ieee_addr(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_local *local = sdata->hw; - priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); + sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); if (local->ops->set_hw_addr_filt && - local->hw.hw_filt.ieee_addr != priv->extended_addr) { - local->hw.hw_filt.ieee_addr = priv->extended_addr; + local->hw.hw_filt.ieee_addr != sdata->extended_addr) { + local->hw.hw_filt.ieee_addr = sdata->extended_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } __le16 mac802154_dev_get_pan_id(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - ret = priv->pan_id; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + ret = sdata->pan_id; + spin_unlock_bh(&sdata->mib_lock); return ret; } void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->pan_id = val; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->pan_id = val; + spin_unlock_bh(&sdata->mib_lock); - if ((priv->hw->ops->set_hw_addr_filt) && - (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { - priv->hw->hw.hw_filt.pan_id = priv->pan_id; + if ((sdata->hw->ops->set_hw_addr_filt) && + (sdata->hw->hw.hw_filt.pan_id != sdata->pan_id)) { + sdata->hw->hw.hw_filt.pan_id = sdata->pan_id; set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } u8 mac802154_dev_get_dsn(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return priv->dsn++; + return sdata->dsn++; } static void phy_chan_notify(struct work_struct *work) @@ -165,38 +165,38 @@ static void phy_chan_notify(struct work_struct *work) struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); - struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); int res; - mutex_lock(&priv->hw->phy->pib_lock); - res = local->ops->set_channel(&local->hw, priv->page, priv->chan); + mutex_lock(&sdata->hw->phy->pib_lock); + res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { - priv->hw->phy->current_channel = priv->chan; - priv->hw->phy->current_page = priv->page; + sdata->hw->phy->current_channel = sdata->chan; + sdata->hw->phy->current_page = sdata->page; } - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_unlock(&sdata->hw->phy->pib_lock); kfree(nw); } void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct phy_chan_notify_work *work; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->page = page; - priv->chan = chan; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->page = page; + sdata->chan = chan; + spin_unlock_bh(&sdata->mib_lock); - mutex_lock(&priv->hw->phy->pib_lock); - if (priv->hw->phy->current_channel != priv->chan || - priv->hw->phy->current_page != priv->page) { - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_lock(&sdata->hw->phy->pib_lock); + if (sdata->hw->phy->current_channel != sdata->chan || + sdata->hw->phy->current_page != sdata->page) { + mutex_unlock(&sdata->hw->phy->pib_lock); work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) @@ -204,9 +204,9 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(priv->hw->dev_workqueue, &work->work); + queue_work(sdata->hw->dev_workqueue, &work->work); } else { - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_unlock(&sdata->hw->phy->pib_lock); } } @@ -214,14 +214,14 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_get_params(&priv->sec, params); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_get_params(&sdata->sec, params); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -230,14 +230,14 @@ int mac802154_set_params(struct net_device *dev, const struct ieee802154_llsec_params *params, int changed) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_set_params(&priv->sec, params, changed); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_set_params(&sdata->sec, params, changed); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -247,14 +247,14 @@ int mac802154_add_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id, const struct ieee802154_llsec_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_key_add(&priv->sec, id, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_key_add(&sdata->sec, id, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -262,14 +262,14 @@ int mac802154_add_key(struct net_device *dev, int mac802154_del_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_key_del(&priv->sec, id); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_key_del(&sdata->sec, id); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -278,28 +278,28 @@ int mac802154_del_key(struct net_device *dev, int mac802154_add_dev(struct net_device *dev, const struct ieee802154_llsec_device *llsec_dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_dev_add(&priv->sec, llsec_dev); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_dev_add(&sdata->sec, llsec_dev); + mutex_unlock(&sdata->sec_mtx); return res; } int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_dev_del(&priv->sec, dev_addr); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_dev_del(&sdata->sec, dev_addr); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -309,14 +309,14 @@ int mac802154_add_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_devkey_add(&priv->sec, device_addr, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_devkey_add(&sdata->sec, device_addr, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -325,14 +325,14 @@ int mac802154_del_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_devkey_del(&priv->sec, device_addr, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_devkey_del(&sdata->sec, device_addr, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -341,14 +341,14 @@ int mac802154_del_devkey(struct net_device *dev, int mac802154_add_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_seclevel_add(&priv->sec, sl); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_seclevel_add(&sdata->sec, sl); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -356,14 +356,14 @@ int mac802154_add_seclevel(struct net_device *dev, int mac802154_del_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_seclevel_del(&priv->sec, sl); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_seclevel_del(&sdata->sec, sl); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -371,28 +371,28 @@ int mac802154_del_seclevel(struct net_device *dev, void mac802154_lock_table(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); } void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - *t = &priv->sec.table; + *t = &sdata->sec.table; } void mac802154_unlock_table(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_unlock(&priv->sec_mtx); + mutex_unlock(&sdata->sec_mtx); } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index a107fd2f2312..bd63e120b914 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -33,14 +33,14 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; u8 chan, page; - priv = netdev_priv(dev); + sdata = netdev_priv(dev); /* FIXME: locking */ - chan = priv->hw->phy->current_channel; - page = priv->hw->phy->current_page; + chan = sdata->hw->phy->current_channel; + page = sdata->hw->phy->current_page; if (chan == MAC802154_CHAN_NONE) /* not initialized */ return NETDEV_TX_OK; @@ -53,14 +53,14 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(priv->hw, skb, page, chan); + return mac802154_tx(sdata->hw, skb, page, chan); } void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; @@ -90,7 +90,7 @@ static const struct net_device_ops mac802154_monitor_ops = { void mac802154_monitor_setup(struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; dev->addr_len = 0; dev->hard_header_len = 0; @@ -105,9 +105,9 @@ void mac802154_monitor_setup(struct net_device *dev) dev->netdev_ops = &mac802154_monitor_ops; dev->ml_priv = &mac802154_mlme_reduced; - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_MONITOR; + sdata = netdev_priv(dev); + sdata->type = IEEE802154_DEV_MONITOR; - priv->chan = MAC802154_CHAN_NONE; /* not initialized */ - priv->page = 0; + sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ + sdata->page = 0; } diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d4c92bd3ad32..d20dadd6f27c 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -41,7 +41,7 @@ struct xmit_work { static void mac802154_xmit_worker(struct work_struct *work) { struct xmit_work *xw = container_of(work, struct xmit_work, work); - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; int res; mutex_lock(&xw->local->phy->pib_lock); @@ -81,7 +81,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); -- cgit v1.2.3 From 04e850fe06312a9f570fcc7dbd0f141c012df404 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:37 +0200 Subject: mac802154: rename hw subif_data variable to local This patch renames the hw attribute in struct ieee802154_sub_if_data to local. This avoid confusing with the struct ieee802154_hw hw; inside of local struct. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 12 ++++++------ net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 34 +++++++++++++++++----------------- net/mac802154/mib.c | 38 +++++++++++++++++++------------------- net/mac802154/monitor.c | 6 +++--- 6 files changed, 47 insertions(+), 47 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index daaca371110f..c5b1ab743695 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -69,7 +69,7 @@ struct ieee802154_local { struct ieee802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ - struct ieee802154_local *hw; + struct ieee802154_local *local; struct net_device *dev; int type; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index d3eb8a445a81..6eace90da3ed 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -125,9 +125,9 @@ int mac802154_set_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->mac_params = *params; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); return 0; } @@ -137,16 +137,16 @@ void mac802154_get_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); *params = sdata->mac_params; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); } static int mac802154_wpan_open(struct net_device *dev) { int rc; struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct wpan_phy *phy = sdata->hw->phy; + struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); if (rc < 0) @@ -339,7 +339,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->hw, skb, page, chan); + return mac802154_tx(sdata->local, skb, page, chan); } static struct header_ops mac802154_header_ops = { diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index bccaefbe0ba2..5ee1088e47ab 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -79,7 +79,7 @@ static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); - return to_phy(get_device(&sdata->hw->phy->dev)); + return to_phy(get_device(&sdata->local->phy->dev)); } static struct ieee802154_llsec_ops mac802154_llsec_ops = { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 6f630d4990fa..9b2644ff6de5 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -33,26 +33,26 @@ int mac802154_slave_open(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_sub_if_data *subif; - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; int res = 0; ASSERT_RTNL(); if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->hw->slaves_mtx); - list_for_each_entry(subif, &sdata->hw->slaves, list) { + mutex_lock(&sdata->local->slaves_mtx); + list_for_each_entry(subif, &sdata->local->slaves, list) { if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); return -EBUSY; } } - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); } - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->running = true; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -74,7 +74,7 @@ int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: - sdata->hw->open_count--; + sdata->local->open_count--; return res; } @@ -82,15 +82,15 @@ err: int mac802154_slave_close(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; ASSERT_RTNL(); netif_stop_queue(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->running = false; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -109,7 +109,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) sdata = netdev_priv(dev); sdata->dev = dev; - sdata->hw = local; + sdata->local = local; dev->needed_headroom = local->hw.extra_tx_headroom; @@ -144,11 +144,11 @@ mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) sdata = netdev_priv(dev); - BUG_ON(sdata->hw->phy != phy); + BUG_ON(sdata->local->phy != phy); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); list_del_rcu(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); synchronize_rcu(); unregister_netdevice(sdata->dev); @@ -394,9 +394,9 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) mutex_unlock(&local->slaves_mtx); list_for_each_entry_safe(sdata, next, &local->slaves, list) { - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); list_del(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); unregister_netdevice(sdata->dev); } diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index ef05b3bd9a63..1ffca5c6b0b9 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -42,7 +42,7 @@ static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); - return sdata->hw; + return sdata->local; } static void hw_addr_notify(struct work_struct *work) @@ -72,7 +72,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(sdata->hw->dev_workqueue, &work->work); + queue_work(sdata->local->dev_workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) @@ -85,9 +85,9 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) sdata->short_addr = val; spin_unlock_bh(&sdata->mib_lock); - if ((sdata->hw->ops->set_hw_addr_filt) && - (sdata->hw->hw.hw_filt.short_addr != sdata->short_addr)) { - sdata->hw->hw.hw_filt.short_addr = sdata->short_addr; + if ((sdata->local->ops->set_hw_addr_filt) && + (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) { + sdata->local->hw.hw_filt.short_addr = sdata->short_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } @@ -109,7 +109,7 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); @@ -144,9 +144,9 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) sdata->pan_id = val; spin_unlock_bh(&sdata->mib_lock); - if ((sdata->hw->ops->set_hw_addr_filt) && - (sdata->hw->hw.hw_filt.pan_id != sdata->pan_id)) { - sdata->hw->hw.hw_filt.pan_id = sdata->pan_id; + if ((sdata->local->ops->set_hw_addr_filt) && + (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) { + sdata->local->hw.hw_filt.pan_id = sdata->pan_id; set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } @@ -168,15 +168,15 @@ static void phy_chan_notify(struct work_struct *work) struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); int res; - mutex_lock(&sdata->hw->phy->pib_lock); + mutex_lock(&sdata->local->phy->pib_lock); res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { - sdata->hw->phy->current_channel = sdata->chan; - sdata->hw->phy->current_page = sdata->page; + sdata->local->phy->current_channel = sdata->chan; + sdata->local->phy->current_page = sdata->page; } - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_unlock(&sdata->local->phy->pib_lock); kfree(nw); } @@ -193,10 +193,10 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) sdata->chan = chan; spin_unlock_bh(&sdata->mib_lock); - mutex_lock(&sdata->hw->phy->pib_lock); - if (sdata->hw->phy->current_channel != sdata->chan || - sdata->hw->phy->current_page != sdata->page) { - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_lock(&sdata->local->phy->pib_lock); + if (sdata->local->phy->current_channel != sdata->chan || + sdata->local->phy->current_page != sdata->page) { + mutex_unlock(&sdata->local->phy->pib_lock); work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) @@ -204,9 +204,9 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(sdata->hw->dev_workqueue, &work->work); + queue_work(sdata->local->dev_workqueue, &work->work); } else { - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_unlock(&sdata->local->phy->pib_lock); } } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index bd63e120b914..79bce5258b0c 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -39,8 +39,8 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, sdata = netdev_priv(dev); /* FIXME: locking */ - chan = sdata->hw->phy->current_channel; - page = sdata->hw->phy->current_page; + chan = sdata->local->phy->current_channel; + page = sdata->local->phy->current_page; if (chan == MAC802154_CHAN_NONE) /* not initialized */ return NETDEV_TX_OK; @@ -53,7 +53,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->hw, skb, page, chan); + return mac802154_tx(sdata->local, skb, page, chan); } -- cgit v1.2.3 From d98be45b3657fc233f5a098279a4e42ab6f0fa4f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:38 +0200 Subject: mac802154: rename sdata slaves and slaves_mtx This patch renamens the slaves attribute in sdata to interfaces and slaves_mtx to iflist_mtx. This is similar like the mac80211 stack naming convention. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 4 ++-- net/mac802154/iface.c | 10 ++++---- net/mac802154/main.c | 54 ++++++++++++++++++++++---------------------- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 4 ++-- 5 files changed, 37 insertions(+), 37 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index c5b1ab743695..b7cf41c989ec 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -42,8 +42,8 @@ struct ieee802154_local { * * So atomic readers can use any of this protection methods. */ - struct list_head slaves; - struct mutex slaves_mtx; + struct list_head interfaces; + struct mutex iflist_mtx; /* This one is used for scanning and other jobs not to be interfered * with serial driver. diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 6eace90da3ed..c0dbb402b99b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -125,9 +125,9 @@ int mac802154_set_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->mac_params = *params; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); return 0; } @@ -137,9 +137,9 @@ void mac802154_get_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); *params = sdata->mac_params; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); } static int mac802154_wpan_open(struct net_device *dev) @@ -580,7 +580,7 @@ void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) } rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) { + list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9b2644ff6de5..34e7e617611a 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -39,20 +39,20 @@ int mac802154_slave_open(struct net_device *dev) ASSERT_RTNL(); if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->local->slaves_mtx); - list_for_each_entry(subif, &sdata->local->slaves, list) { + mutex_lock(&sdata->local->iflist_mtx); + list_for_each_entry(subif, &sdata->local->interfaces, list) { if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); return -EBUSY; } } - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); } - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->running = true; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -88,9 +88,9 @@ int mac802154_slave_close(struct net_device *dev) netif_stop_queue(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->running = false; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -115,21 +115,21 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); if (!local->running) { - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); return -ENODEV; } - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); err = register_netdev(dev); if (err < 0) return err; rtnl_lock(); - mutex_lock(&local->slaves_mtx); - list_add_tail_rcu(&sdata->list, &local->slaves); - mutex_unlock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); + list_add_tail_rcu(&sdata->list, &local->interfaces); + mutex_unlock(&local->iflist_mtx); rtnl_unlock(); return 0; @@ -146,9 +146,9 @@ mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) BUG_ON(sdata->local->phy != phy); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); list_del_rcu(&sdata->list); - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); synchronize_rcu(); unregister_netdevice(sdata->dev); @@ -280,8 +280,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); local->ops = ops; - INIT_LIST_HEAD(&local->slaves); - mutex_init(&local->slaves_mtx); + INIT_LIST_HEAD(&local->interfaces); + mutex_init(&local->iflist_mtx); return &local->hw; } @@ -291,9 +291,9 @@ void ieee802154_free_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = mac802154_to_priv(hw); - BUG_ON(!list_empty(&local->slaves)); + BUG_ON(!list_empty(&local->interfaces)); - mutex_destroy(&local->slaves_mtx); + mutex_destroy(&local->iflist_mtx); wpan_phy_free(local->phy); } @@ -364,9 +364,9 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); local->running = MAC802154_DEVICE_RUN; - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); rtnl_unlock(); @@ -389,14 +389,14 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); local->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); - list_for_each_entry_safe(sdata, next, &local->slaves, list) { - mutex_lock(&sdata->local->slaves_mtx); + list_for_each_entry_safe(sdata, next, &local->interfaces, list) { + mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); unregister_netdevice(sdata->dev); } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 79bce5258b0c..9d2ac5ea6634 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -65,7 +65,7 @@ void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u8 *data; rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) { + list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d20dadd6f27c..b6039c75d175 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -68,7 +68,7 @@ out: /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->local->slaves, list) + list_for_each_entry_rcu(sdata, &xw->local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); @@ -109,7 +109,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) + list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); -- cgit v1.2.3 From 60741361c3ca229a1dbb18e05d11e97b7ea75d69 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:39 +0200 Subject: mac802154: introduce hw_to_local function This patch replace the mac802154_to_priv macro with a static inline function named hw_to_local. This brings a similar naming convention like mac80211 stack. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 8 ++++++-- net/mac802154/main.c | 6 +++--- net/mac802154/rx.c | 4 ++-- net/mac802154/tx.c | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index b7cf41c989ec..41e29b00e7a0 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -99,10 +99,14 @@ struct ieee802154_sub_if_data { struct mac802154_llsec sec; }; -#define mac802154_to_priv(_hw) container_of(_hw, struct ieee802154_local, hw) - #define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ +static inline struct ieee802154_local * +hw_to_local(struct ieee802154_hw *hw) +{ + return container_of(hw, struct ieee802154_local, hw); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 34e7e617611a..c7799faf508b 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(ieee802154_alloc_hw); void ieee802154_free_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); BUG_ON(!list_empty(&local->interfaces)); @@ -301,7 +301,7 @@ EXPORT_SYMBOL(ieee802154_free_hw); int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); int rc = -ENOSYS; if (hw->flags & IEEE802154_HW_TXPOWER) { @@ -381,7 +381,7 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; flush_workqueue(local->dev_workqueue); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index dc01817a92c5..1b5e8e332b9b 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -49,7 +49,7 @@ struct rx_work { static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); @@ -90,7 +90,7 @@ static void mac802154_rx_worker(struct work_struct *work) void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); struct rx_work *work; if (!skb) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index b6039c75d175..36844264b20b 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -88,7 +88,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, goto err_tx; } - mac802154_monitors_rx(mac802154_to_priv(&local->hw), skb); + mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); -- cgit v1.2.3 From 59d19cd70cd38afd2d9bf2e3b48c3a5bbb630b5a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:40 +0200 Subject: mac802154: introduce IEEE802154_DEV_TO_SUB_IF This function adds a wrapper to call netdev_priv to getting the sdata attribute. This is similar like the IEEE80211_DEV_TO_SUB_IF function inside wireless stack implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 6 ++++++ net/mac802154/iface.c | 18 ++++++++-------- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 11 ++++------ net/mac802154/mib.c | 49 ++++++++++++++++++++++---------------------- net/mac802154/monitor.c | 4 ++-- 6 files changed, 47 insertions(+), 43 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 41e29b00e7a0..61885aaea6b6 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -107,6 +107,12 @@ hw_to_local(struct ieee802154_hw *hw) return container_of(hw, struct ieee802154_local, hw); } +static inline struct ieee802154_sub_if_data * +IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) +{ + return netdev_priv(dev); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0dbb402b99b..cdd661f0ef3f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -33,7 +33,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); int rc = 0; @@ -56,7 +56,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) static int mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct sockaddr_ieee802154 *sa = (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; @@ -123,7 +123,7 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) int mac802154_set_mac_params(struct net_device *dev, const struct ieee802154_mac_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mutex_lock(&sdata->local->iflist_mtx); sdata->mac_params = *params; @@ -135,7 +135,7 @@ int mac802154_set_mac_params(struct net_device *dev, void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_mac_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mutex_lock(&sdata->local->iflist_mtx); *params = sdata->mac_params; @@ -145,7 +145,7 @@ void mac802154_get_mac_params(struct net_device *dev, static int mac802154_wpan_open(struct net_device *dev) { int rc; - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); @@ -241,7 +241,7 @@ static int mac802154_header_create(struct sk_buff *skb, unsigned len) { struct ieee802154_hdr hdr; - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; @@ -314,7 +314,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) u8 chan, page; int rc; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); spin_lock_bh(&sdata->mib_lock); chan = sdata->chan; @@ -357,7 +357,7 @@ static const struct net_device_ops mac802154_wpan_ops = { static void mac802154_wpan_free(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mac802154_llsec_destroy(&sdata->sec); @@ -384,7 +384,7 @@ void mac802154_wpan_setup(struct net_device *dev) dev->netdev_ops = &mac802154_wpan_ops; dev->ml_priv = &mac802154_mlme_wpan; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_WPAN; sdata->chan = MAC802154_CHAN_NONE; diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 5ee1088e47ab..ed767f590ef9 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -75,7 +75,7 @@ static int mac802154_mlme_start_req(struct net_device *dev, static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index c7799faf508b..a34006edcb8d 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -31,7 +31,7 @@ int mac802154_slave_open(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_sub_if_data *subif; struct ieee802154_local *local = sdata->local; int res = 0; @@ -81,7 +81,7 @@ err: int mac802154_slave_close(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; ASSERT_RTNL(); @@ -101,13 +101,12 @@ int mac802154_slave_close(struct net_device *dev) static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { - struct ieee802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local; int err; local = wpan_phy_priv(phy); - sdata = netdev_priv(dev); sdata->dev = dev; sdata->local = local; @@ -138,12 +137,10 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) static void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) { - struct ieee802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); ASSERT_RTNL(); - sdata = netdev_priv(dev); - BUG_ON(sdata->local->phy != phy); mutex_lock(&sdata->local->iflist_mtx); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 1ffca5c6b0b9..d7a25048a8af 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -38,7 +38,7 @@ struct hw_addr_filt_notify_work { static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -62,7 +62,7 @@ static void hw_addr_notify(struct work_struct *work) static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct hw_addr_filt_notify_work *work; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -77,7 +77,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -94,7 +94,7 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) __le16 mac802154_dev_get_short_addr(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -108,7 +108,7 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); @@ -122,7 +122,7 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev) __le16 mac802154_dev_get_pan_id(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -136,7 +136,7 @@ __le16 mac802154_dev_get_pan_id(const struct net_device *dev) void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -153,7 +153,7 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) u8 mac802154_dev_get_dsn(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -164,8 +164,9 @@ static void phy_chan_notify(struct work_struct *work) { struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); - struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); - struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); + struct net_device *dev = nw->dev; + struct ieee802154_local *local = mac802154_slave_get_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; mutex_lock(&sdata->local->phy->pib_lock); @@ -183,7 +184,7 @@ static void phy_chan_notify(struct work_struct *work) void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct phy_chan_notify_work *work; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -214,7 +215,7 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -230,7 +231,7 @@ int mac802154_set_params(struct net_device *dev, const struct ieee802154_llsec_params *params, int changed) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -247,7 +248,7 @@ int mac802154_add_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id, const struct ieee802154_llsec_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -262,7 +263,7 @@ int mac802154_add_key(struct net_device *dev, int mac802154_del_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -278,7 +279,7 @@ int mac802154_del_key(struct net_device *dev, int mac802154_add_dev(struct net_device *dev, const struct ieee802154_llsec_device *llsec_dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -292,7 +293,7 @@ int mac802154_add_dev(struct net_device *dev, int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -309,7 +310,7 @@ int mac802154_add_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -325,7 +326,7 @@ int mac802154_del_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -341,7 +342,7 @@ int mac802154_del_devkey(struct net_device *dev, int mac802154_add_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -356,7 +357,7 @@ int mac802154_add_seclevel(struct net_device *dev, int mac802154_del_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -371,7 +372,7 @@ int mac802154_del_seclevel(struct net_device *dev, void mac802154_lock_table(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -381,7 +382,7 @@ void mac802154_lock_table(struct net_device *dev) void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -390,7 +391,7 @@ void mac802154_get_table(struct net_device *dev, void mac802154_unlock_table(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 9d2ac5ea6634..f8ea6dc8dda5 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -36,7 +36,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct ieee802154_sub_if_data *sdata; u8 chan, page; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); /* FIXME: locking */ chan = sdata->local->phy->current_channel; @@ -105,7 +105,7 @@ void mac802154_monitor_setup(struct net_device *dev) dev->netdev_ops = &mac802154_monitor_ops; dev->ml_priv = &mac802154_mlme_reduced; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ -- cgit v1.2.3 From f773054254b6aa0196063658c7e247e7c6eacbeb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:41 +0200 Subject: mac802154: rename dev_workqueue to workqueue Small rename to use the name workqueue than dev_workqueue. To bring the same naming convention like wireless into 802.15.4. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 10 +++++----- net/mac802154/mib.c | 4 ++-- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 61885aaea6b6..7aae6920fa30 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -48,7 +48,7 @@ struct ieee802154_local { /* This one is used for scanning and other jobs not to be interfered * with serial driver. */ - struct workqueue_struct *dev_workqueue; + struct workqueue_struct *workqueue; /* SoftMAC device is registered and running. One can add subinterfaces. * This flag should be modified under slaves_mtx and RTNL, so you can diff --git a/net/mac802154/main.c b/net/mac802154/main.c index a34006edcb8d..5ce3184bc674 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -343,9 +343,9 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) local->phy->set_frame_retries = mac802154_set_frame_retries; } - local->dev_workqueue = + local->workqueue = create_singlethread_workqueue(wpan_phy_name(local->phy)); - if (!local->dev_workqueue) { + if (!local->workqueue) { rc = -ENOMEM; goto out; } @@ -370,7 +370,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) return 0; out_wq: - destroy_workqueue(local->dev_workqueue); + destroy_workqueue(local->workqueue); out: return rc; } @@ -381,8 +381,8 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; - flush_workqueue(local->dev_workqueue); - destroy_workqueue(local->dev_workqueue); + flush_workqueue(local->workqueue); + destroy_workqueue(local->workqueue); rtnl_lock(); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index d7a25048a8af..16baff1ea313 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -72,7 +72,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(sdata->local->dev_workqueue, &work->work); + queue_work(sdata->local->workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) @@ -205,7 +205,7 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(sdata->local->dev_workqueue, &work->work); + queue_work(sdata->local->workqueue, &work->work); } else { mutex_unlock(&sdata->local->phy->pib_lock); } diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 1b5e8e332b9b..53c9e0c10a87 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -105,6 +105,6 @@ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) work->hw = hw; work->lqi = lqi; - queue_work(local->dev_workqueue, &work->work); + queue_work(local->workqueue, &work->work); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 36844264b20b..2c40d9bb8387 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -119,7 +119,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, work->page = page; work->chan = chan; - queue_work(local->dev_workqueue, &work->work); + queue_work(local->workqueue, &work->work); return NETDEV_TX_OK; -- cgit v1.2.3 From c6f635faf3bca66cf73f6b3319a054959e367b19 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:42 +0200 Subject: mac802154: remove ieee802154_addr from driver_ops This driver_ops callback function is never used by any driver. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 1 - net/mac802154/main.c | 10 ---------- 2 files changed, 11 deletions(-) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index eb0e1cb9ca98..b07d431c0b19 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -170,7 +170,6 @@ struct ieee802154_ops { int (*set_hw_addr_filt)(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed); - int (*ieee_addr)(struct ieee802154_hw *hw, __le64 addr); int (*set_txpower)(struct ieee802154_hw *hw, int db); int (*set_lbt)(struct ieee802154_hw *hw, bool on); int (*set_cca_mode)(struct ieee802154_hw *hw, u8 mode); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 5ce3184bc674..0e9a6a203f7a 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -61,16 +61,6 @@ int mac802154_slave_open(struct net_device *dev) goto err; } - if (local->ops->ieee_addr) { - __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); - - res = local->ops->ieee_addr(&local->hw, addr); - WARN_ON(res); - if (res) - goto err; - mac802154_dev_set_ieee_addr(dev); - } - netif_start_queue(dev); return 0; err: -- cgit v1.2.3 From 50c6fb9965907732b4f5c45bd3bacf4b4f3463b9 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:01 +0100 Subject: mac802154: tx: move xmit callback to tx file This patch moves the netdev xmit callback functions into the tx.c file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 5 ++-- net/mac802154/iface.c | 35 -------------------------- net/mac802154/monitor.c | 27 -------------------- net/mac802154/tx.c | 59 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 67 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 7aae6920fa30..a9a9d8e15278 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -121,12 +121,11 @@ int mac802154_slave_close(struct net_device *dev); void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); +netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev); void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); - -netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, - u8 page, u8 chan); +netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev); /* MIB callbacks */ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index cdd661f0ef3f..f14e4365c4c7 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -307,41 +307,6 @@ mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) return sizeof(*addr); } -static netdev_tx_t -mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - u8 chan, page; - int rc; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - spin_lock_bh(&sdata->mib_lock); - chan = sdata->chan; - page = sdata->page; - spin_unlock_bh(&sdata->mib_lock); - - if (chan == MAC802154_CHAN_NONE || - page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - - rc = mac802154_llsec_encrypt(&sdata->sec, skb); - if (rc) { - pr_warn("encryption failed: %i\n", rc); - kfree_skb(skb); - return NETDEV_TX_OK; - } - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(sdata->local, skb, page, chan); -} - static struct header_ops mac802154_header_ops = { .create = mac802154_header_create, .parse = mac802154_header_parse, diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index f8ea6dc8dda5..cb9600bcca51 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -30,33 +30,6 @@ #include "ieee802154_i.h" -static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - u8 chan, page; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - /* FIXME: locking */ - chan = sdata->local->phy->current_channel; - page = sdata->local->phy->current_page; - - if (chan == MAC802154_CHAN_NONE) /* not initialized */ - return NETDEV_TX_OK; - - if (WARN_ON(page >= WPAN_NUM_PAGES) || - WARN_ON(chan >= WPAN_NUM_CHANNELS)) - return NETDEV_TX_OK; - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(sdata->local, skb, page, chan); -} - - void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 2c40d9bb8387..2eb06c2cf96d 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -77,8 +77,8 @@ out: kfree(xw); } -netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, - u8 page, u8 chan) +static netdev_tx_t mac802154_tx(struct ieee802154_local *local, + struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; struct ieee802154_sub_if_data *sdata; @@ -127,3 +127,58 @@ err_tx: kfree_skb(skb); return NETDEV_TX_OK; } + +netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + u8 chan, page; + + /* FIXME: locking */ + chan = sdata->local->phy->current_channel; + page = sdata->local->phy->current_page; + + if (chan == MAC802154_CHAN_NONE) /* not initialized */ + return NETDEV_TX_OK; + + if (WARN_ON(page >= WPAN_NUM_PAGES) || + WARN_ON(chan >= WPAN_NUM_CHANNELS)) + return NETDEV_TX_OK; + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(sdata->local, skb, page, chan); +} + +netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + u8 chan, page; + int rc; + + spin_lock_bh(&sdata->mib_lock); + chan = sdata->chan; + page = sdata->page; + spin_unlock_bh(&sdata->mib_lock); + + if (chan == MAC802154_CHAN_NONE || + page >= WPAN_NUM_PAGES || + chan >= WPAN_NUM_CHANNELS) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + + rc = mac802154_llsec_encrypt(&sdata->sec, skb); + if (rc) { + pr_warn("encryption failed: %i\n", rc); + kfree_skb(skb); + return NETDEV_TX_OK; + } + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(sdata->local, skb, page, chan); +} -- cgit v1.2.3 From fe24371d6645b766c59ec664c59d0a9c310ad455 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:02 +0100 Subject: mac802154: tx: remove kmalloc in xmit hotpath This patch removes the kmalloc allocation for workqueue data. This patch replaces the kmalloc and uses the control block of skb. The control block has enough space and isn't use by any other layer in this case. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 56 ++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 2eb06c2cf96d..513e760a8557 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -30,7 +30,7 @@ /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct xmit_work { +struct wpan_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; @@ -38,50 +38,54 @@ struct xmit_work { u8 page; }; +static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct wpan_xmit_cb)); + + return (struct wpan_xmit_cb *)skb->cb; +} + static void mac802154_xmit_worker(struct work_struct *work) { - struct xmit_work *xw = container_of(work, struct xmit_work, work); + struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_sub_if_data *sdata; int res; - mutex_lock(&xw->local->phy->pib_lock); - if (xw->local->phy->current_channel != xw->chan || - xw->local->phy->current_page != xw->page) { - res = xw->local->ops->set_channel(&xw->local->hw, - xw->page, - xw->chan); + mutex_lock(&cb->local->phy->pib_lock); + if (cb->local->phy->current_channel != cb->chan || + cb->local->phy->current_page != cb->page) { + res = cb->local->ops->set_channel(&cb->local->hw, cb->page, + cb->chan); if (res) { pr_debug("set_channel failed\n"); goto out; } - xw->local->phy->current_channel = xw->chan; - xw->local->phy->current_page = xw->page; + cb->local->phy->current_channel = cb->chan; + cb->local->phy->current_page = cb->page; } - res = xw->local->ops->xmit(&xw->local->hw, xw->skb); + res = cb->local->ops->xmit(&cb->local->hw, cb->skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&xw->local->phy->pib_lock); + mutex_unlock(&cb->local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->local->interfaces, list) + list_for_each_entry_rcu(sdata, &cb->local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); - dev_kfree_skb(xw->skb); - - kfree(xw); + dev_kfree_skb(cb->skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { - struct xmit_work *work; struct ieee802154_sub_if_data *sdata; + struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); @@ -101,25 +105,19 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, if (skb_cow_head(skb, local->hw.extra_tx_headroom)) goto err_tx; - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) { - kfree_skb(skb); - return NETDEV_TX_BUSY; - } - /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); - INIT_WORK(&work->work, mac802154_xmit_worker); - work->skb = skb; - work->local = local; - work->page = page; - work->chan = chan; + INIT_WORK(&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; + cb->page = page; + cb->chan = chan; - queue_work(local->workqueue, &work->work); + queue_work(local->workqueue, &cb->work); return NETDEV_TX_OK; -- cgit v1.2.3 From e89e45f22a382d14d5e2362cd4f4d12d77ee4935 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:03 +0100 Subject: mac802154: tx: squash multiple dereferencing This patch introduce some new stack variables to avoid multiple dereferencing inside the xmit worker function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 513e760a8557..d0ceb46134d9 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -48,37 +48,38 @@ static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) static void mac802154_xmit_worker(struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); + struct ieee802154_local *local = cb->local; struct ieee802154_sub_if_data *sdata; + struct sk_buff *skb = cb->skb; int res; - mutex_lock(&cb->local->phy->pib_lock); - if (cb->local->phy->current_channel != cb->chan || - cb->local->phy->current_page != cb->page) { - res = cb->local->ops->set_channel(&cb->local->hw, cb->page, - cb->chan); + mutex_lock(&local->phy->pib_lock); + if (local->phy->current_channel != cb->chan || + local->phy->current_page != cb->page) { + res = local->ops->set_channel(&local->hw, cb->page, cb->chan); if (res) { pr_debug("set_channel failed\n"); goto out; } - cb->local->phy->current_channel = cb->chan; - cb->local->phy->current_page = cb->page; + local->phy->current_channel = cb->chan; + local->phy->current_page = cb->page; } - res = cb->local->ops->xmit(&cb->local->hw, cb->skb); + res = local->ops->xmit(&local->hw, skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&cb->local->phy->pib_lock); + mutex_unlock(&local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &cb->local->interfaces, list) + list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); - dev_kfree_skb(cb->skb); + dev_kfree_skb(skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, -- cgit v1.2.3 From dc67c6b30f36d57b70b70547a30e7a8432540c6f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:04 +0100 Subject: mac802154: tx: remove xmit channel context switch This patch removes the channel hopping feature before xmit. There are several issues to provide a real channel hopping (timing requirements, etc...). We don't have any known kernelspace protocol which really use this feature. And I don't know an real user of this feature. We simply drop this feature now. This patch removes also the hold of pib lock which isn't needed by any real driver xmit callback implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 3 +-- net/mac802154/tx.c | 58 ++++--------------------------------------------- 2 files changed, 5 insertions(+), 56 deletions(-) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index b07d431c0b19..ba8ddff70bb6 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -113,8 +113,7 @@ struct ieee802154_hw { * skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration. - * This function should return zero or negative errno. Called with - * pib_lock held. + * This function should return zero or negative errno. * * ed: Handler that 802.15.4 module calls for Energy Detection. * This function should place the value for detected energy diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d0ceb46134d9..be8deae19386 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -34,8 +34,6 @@ struct wpan_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; - u8 chan; - u8 page; }; static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) @@ -53,26 +51,10 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; - mutex_lock(&local->phy->pib_lock); - if (local->phy->current_channel != cb->chan || - local->phy->current_page != cb->page) { - res = local->ops->set_channel(&local->hw, cb->page, cb->chan); - if (res) { - pr_debug("set_channel failed\n"); - goto out; - } - - local->phy->current_channel = cb->chan; - local->phy->current_page = cb->page; - } - res = local->ops->xmit(&local->hw, skb); if (res) pr_debug("transmission failed\n"); -out: - mutex_unlock(&local->phy->pib_lock); - /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) @@ -82,17 +64,12 @@ out: dev_kfree_skb(skb); } -static netdev_tx_t mac802154_tx(struct ieee802154_local *local, - struct sk_buff *skb, u8 page, u8 chan) +static netdev_tx_t +mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct ieee802154_sub_if_data *sdata; struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); - if (!(local->phy->channels_supported[page] & (1 << chan))) { - WARN_ON(1); - goto err_tx; - } - mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { @@ -115,8 +92,6 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; cb->local = local; - cb->page = page; - cb->chan = chan; queue_work(local->workqueue, &cb->work); @@ -130,44 +105,19 @@ err_tx: netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - u8 chan, page; - - /* FIXME: locking */ - chan = sdata->local->phy->current_channel; - page = sdata->local->phy->current_page; - - if (chan == MAC802154_CHAN_NONE) /* not initialized */ - return NETDEV_TX_OK; - - if (WARN_ON(page >= WPAN_NUM_PAGES) || - WARN_ON(chan >= WPAN_NUM_CHANNELS)) - return NETDEV_TX_OK; skb->skb_iif = dev->ifindex; dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->local, skb, page, chan); + return mac802154_tx(sdata->local, skb); } netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - u8 chan, page; int rc; - spin_lock_bh(&sdata->mib_lock); - chan = sdata->chan; - page = sdata->page; - spin_unlock_bh(&sdata->mib_lock); - - if (chan == MAC802154_CHAN_NONE || - page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { pr_warn("encryption failed: %i\n", rc); @@ -179,5 +129,5 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->local, skb, page, chan); + return mac802154_tx(sdata->local, skb); } -- cgit v1.2.3 From c20851035126cc1d97c337083f98b797eed155a3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:05 +0100 Subject: mac802154: add netdev qeue helpers This patch adds a new file net/mac802154/util.c which contains utility functions for drivers, etc. This file contains functions to start and stop queues for all virtual interfaces, this is useful for asynchronous handling by driver level. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 4 ++++ net/mac802154/Makefile | 2 +- net/mac802154/util.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 net/mac802154/util.c (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index ba8ddff70bb6..29af5c346ebf 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -190,4 +190,8 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); +void ieee802154_wake_queue(struct ieee802154_hw *hw); +void ieee802154_stop_queue(struct ieee802154_hw *hw); +void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb); + #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 203f42d511af..e68debaf2a59 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o iface.o llsec.o + monitor.o iface.o llsec.o util.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/util.c b/net/mac802154/util.c new file mode 100644 index 000000000000..117e4eff4ca8 --- /dev/null +++ b/net/mac802154/util.c @@ -0,0 +1,55 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/mac80211/util.c + */ + +#include "ieee802154_i.h" + +void ieee802154_wake_queue(struct ieee802154_hw *hw) +{ + struct ieee802154_local *local = hw_to_local(hw); + struct ieee802154_sub_if_data *sdata; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + netif_wake_queue(sdata->dev); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee802154_wake_queue); + +void ieee802154_stop_queue(struct ieee802154_hw *hw) +{ + struct ieee802154_local *local = hw_to_local(hw); + struct ieee802154_sub_if_data *sdata; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + netif_stop_queue(sdata->dev); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee802154_stop_queue); + +void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb) +{ + ieee802154_wake_queue(hw); + consume_skb(skb); +} +EXPORT_SYMBOL(ieee802154_xmit_complete); -- cgit v1.2.3 From 18d60a0d49ef3eb2d31f65cf5b652702d9c6e710 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:06 +0100 Subject: mac802154: tx: use queue helpers in xmit worker This patch uses the queue utility helpers inside the xmit worker of mac802154 subsystem. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index be8deae19386..8e2f429a4546 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -47,7 +47,6 @@ static void mac802154_xmit_worker(struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_local *local = cb->local; - struct ieee802154_sub_if_data *sdata; struct sk_buff *skb = cb->skb; int res; @@ -56,18 +55,12 @@ static void mac802154_xmit_worker(struct work_struct *work) pr_debug("transmission failed\n"); /* Restart the netif queue on each sub_if_data object. */ - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_wake_queue(sdata->dev); - rcu_read_unlock(); - - dev_kfree_skb(skb); + ieee802154_xmit_complete(&local->hw, skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct ieee802154_sub_if_data *sdata; struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); mac802154_monitors_rx(local, skb); @@ -84,10 +77,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) goto err_tx; /* Stop the netif queue on each sub_if_data object. */ - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_stop_queue(sdata->dev); - rcu_read_unlock(); + ieee802154_stop_queue(&local->hw); INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; -- cgit v1.2.3 From cdb66beaa0da7d326069b10bef090645d61d813f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:07 +0100 Subject: mac802154: tx: fix error handling while xmit In case of an error we should call kfree_skb instead of consume_skb which is called by ieee802154_xmit_complete function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8e2f429a4546..23139cae0764 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -51,11 +51,15 @@ static void mac802154_xmit_worker(struct work_struct *work) int res; res = local->ops->xmit(&local->hw, skb); - if (res) + if (res) { pr_debug("transmission failed\n"); - - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_xmit_complete(&local->hw, skb); + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_wake_queue(&local->hw); + kfree_skb(skb); + } else { + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_xmit_complete(&local->hw, skb); + } } static netdev_tx_t -- cgit v1.2.3 From ed0a5dce0c29f30ee53a87793206156cf38ae70d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:08 +0100 Subject: mac802154: tx: add support for xmit_async callback This patch renames the existsing xmit callback to xmit_sync and introduces an asynchronous xmit_async function. If ieee802154_ops doesn't provide the xmit_async callback, then we have a fallback to the xmit_sync callback. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 17 ++++++++++++++--- net/mac802154/main.c | 4 ++-- net/mac802154/tx.c | 20 +++++++++++++++----- 7 files changed, 35 insertions(+), 14 deletions(-) (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b0d68d7061c1..06a3e9013d60 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1237,7 +1237,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) static struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, - .xmit = at86rf230_xmit, + .xmit_sync = at86rf230_xmit, .ed = at86rf230_ed, .set_channel = at86rf230_channel, .start = at86rf230_start, diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index b827e04d481b..f6f07f4eb0ec 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -635,7 +635,7 @@ static struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, .stop = cc2520_stop, - .xmit = cc2520_tx, + .xmit_sync = cc2520_tx, .ed = cc2520_ed, .set_channel = cc2520_set_channel, .set_hw_addr_filt = cc2520_filter, diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 51e3c589d2e4..db0703f0fa41 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -131,7 +131,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) { static struct ieee802154_ops fakelb_ops = { .owner = THIS_MODULE, - .xmit = fakelb_hw_xmit, + .xmit_sync = fakelb_hw_xmit, .ed = fakelb_hw_ed, .set_channel = fakelb_hw_channel, .start = fakelb_hw_start, diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 2e267c5c44da..3d775afa217f 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -581,7 +581,7 @@ out: static struct ieee802154_ops mrf24j40_ops = { .owner = THIS_MODULE, - .xmit = mrf24j40_tx, + .xmit_sync = mrf24j40_tx, .ed = mrf24j40_ed, .start = mrf24j40_start, .stop = mrf24j40_stop, diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 29af5c346ebf..57b120281afc 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -109,7 +109,16 @@ struct ieee802154_hw { * stop: Handler that 802.15.4 module calls for device cleanup. * This function is called after the last interface is removed. * - * xmit: Handler that 802.15.4 module calls for each transmitted frame. + * xmit_sync: + * Handler that 802.15.4 module calls for each transmitted frame. + * skb cntains the buffer starting from the IEEE 802.15.4 header. + * The low-level driver should send the frame based on available + * configuration. This is called by a workqueue and useful for + * synchronous 802.15.4 drivers. + * This function should return zero or negative errno. + * + * xmit_async: + * Handler that 802.15.4 module calls for each transmitted frame. * skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration. @@ -160,8 +169,10 @@ struct ieee802154_ops { struct module *owner; int (*start)(struct ieee802154_hw *hw); void (*stop)(struct ieee802154_hw *hw); - int (*xmit)(struct ieee802154_hw *hw, - struct sk_buff *skb); + int (*xmit_sync)(struct ieee802154_hw *hw, + struct sk_buff *skb); + int (*xmit_async)(struct ieee802154_hw *hw, + struct sk_buff *skb); int (*ed)(struct ieee802154_hw *hw, u8 *level); int (*set_channel)(struct ieee802154_hw *hw, int page, diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 0e9a6a203f7a..3c0a824d24ac 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -229,8 +229,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) struct ieee802154_local *local; size_t priv_size; - if (!ops || !ops->xmit || !ops->ed || !ops->start || - !ops->stop || !ops->set_channel) { + if (!ops || !(ops->xmit_async || ops->xmit_sync) || !ops->ed || + !ops->start || !ops->stop || !ops->set_channel) { pr_err("undefined IEEE802.15.4 device operations\n"); return NULL; } diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 23139cae0764..1a4f6d91ab8c 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -50,7 +50,7 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; - res = local->ops->xmit(&local->hw, skb); + res = local->ops->xmit_sync(&local->hw, skb); if (res) { pr_debug("transmission failed\n"); /* Restart the netif queue on each sub_if_data object. */ @@ -66,6 +66,7 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + int ret; mac802154_monitors_rx(local, skb); @@ -83,11 +84,20 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) /* Stop the netif queue on each sub_if_data object. */ ieee802154_stop_queue(&local->hw); - INIT_WORK(&cb->work, mac802154_xmit_worker); - cb->skb = skb; - cb->local = local; + /* async is priority, otherwise sync is fallback */ + if (local->ops->xmit_async) { + ret = local->ops->xmit_async(&local->hw, skb); + if (ret) { + ieee802154_wake_queue(&local->hw); + goto err_tx; + } + } else { + INIT_WORK(&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; - queue_work(local->workqueue, &cb->work); + queue_work(local->workqueue, &cb->work); + } return NETDEV_TX_OK; -- cgit v1.2.3 From 6001d5223dd458e4f0063df2a24762eb2a619b17 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:09 +0100 Subject: mac802154: tx: don't allow if down while sync tx This patch holds rtnl lock while sync xmit inside of workqueue. Otherwise we could down the interface while worker xmit handling. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 1a4f6d91ab8c..44390419af86 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -50,16 +51,28 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; + rtnl_lock(); + + /* check if ifdown occurred while schedule */ + if (!netif_running(skb->dev)) + goto err_tx; + res = local->ops->xmit_sync(&local->hw, skb); - if (res) { - pr_debug("transmission failed\n"); - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_wake_queue(&local->hw); - kfree_skb(skb); - } else { - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_xmit_complete(&local->hw, skb); - } + if (res) + goto err_tx; + + ieee802154_xmit_complete(&local->hw, skb); + + rtnl_unlock(); + + return; + +err_tx: + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_wake_queue(&local->hw); + rtnl_unlock(); + kfree_skb(skb); + pr_debug("transmission failed\n"); } static netdev_tx_t -- cgit v1.2.3 From cfa626cb3725101fd1853c2cab857aabfd78274b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:10 +0100 Subject: mac802154: tx: use netdev print helpers This patch replace the pr_foo printout function to netdev_foo printout function. Inside the xmit handling, the interface is already known. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 44390419af86..d39c7d946bc3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -72,7 +72,7 @@ err_tx: ieee802154_wake_queue(&local->hw); rtnl_unlock(); kfree_skb(skb); - pr_debug("transmission failed\n"); + netdev_dbg(skb->dev, "transmission failed\n"); } static netdev_tx_t @@ -137,7 +137,7 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { - pr_warn("encryption failed: %i\n", rc); + netdev_warn(dev, "encryption failed: %i\n", rc); kfree_skb(skb); return NETDEV_TX_OK; } -- cgit v1.2.3 From b7eec52bcb7ab93a8cce0f718f42fa17d6d91745 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:11 +0100 Subject: mac802154: tx: cleanup crc calculation Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d39c7d946bc3..70fd22632cf6 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -84,11 +84,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data = skb_put(skb, 2); + __le16 crc = cpu_to_le16(crc_ccitt(0, skb->data, skb->len)); - data[0] = crc & 0xff; - data[1] = crc >> 8; + memcpy(skb_put(skb, 2), &crc, 2); } if (skb_cow_head(skb, local->hw.extra_tx_headroom)) -- cgit v1.2.3 From 409c3b0c5f030e36e9d6ca747dc3059eadde0cad Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:12 +0100 Subject: mac802154: tx: move stats tx increment This patch moves the stats increment of successful transmitted packets in the right place when the skb was really successful transmitted. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 70fd22632cf6..fe105d42ef83 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -49,12 +49,13 @@ static void mac802154_xmit_worker(struct work_struct *work) struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_local *local = cb->local; struct sk_buff *skb = cb->skb; + struct net_device *dev = skb->dev; int res; rtnl_lock(); /* check if ifdown occurred while schedule */ - if (!netif_running(skb->dev)) + if (!netif_running(dev)) goto err_tx; res = local->ops->xmit_sync(&local->hw, skb); @@ -63,6 +64,9 @@ static void mac802154_xmit_worker(struct work_struct *work) ieee802154_xmit_complete(&local->hw, skb); + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + rtnl_unlock(); return; @@ -72,13 +76,14 @@ err_tx: ieee802154_wake_queue(&local->hw); rtnl_unlock(); kfree_skb(skb); - netdev_dbg(skb->dev, "transmission failed\n"); + netdev_dbg(dev, "transmission failed\n"); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + struct net_device *dev = skb->dev; int ret; mac802154_monitors_rx(local, skb); @@ -102,6 +107,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) ieee802154_wake_queue(&local->hw); goto err_tx; } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; } else { INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; @@ -122,8 +130,6 @@ netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; return mac802154_tx(sdata->local, skb); } @@ -141,8 +147,6 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) } skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; return mac802154_tx(sdata->local, skb); } -- cgit v1.2.3 From e5e584fcc26b6b2225855b6fdba64d90dd8e2ea6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:13 +0100 Subject: mac802154: tx: change naming convention This patch changes the naming convention of the tx functions like mac80211. Just with an 802154 instead 80211 inside the name. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 6 ++++-- net/mac802154/iface.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 30 +++++++++++++++++------------- 4 files changed, 23 insertions(+), 17 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index a9a9d8e15278..ef29c10eeb66 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -121,11 +121,13 @@ int mac802154_slave_close(struct net_device *dev); void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); -netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev); +netdev_tx_t +ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); -netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev); +netdev_tx_t +ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); /* MIB callbacks */ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index f14e4365c4c7..be45dc9257b3 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -315,7 +315,7 @@ static struct header_ops mac802154_header_ops = { static const struct net_device_ops mac802154_wpan_ops = { .ndo_open = mac802154_wpan_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_wpan_xmit, + .ndo_start_xmit = ieee802154_subif_start_xmit, .ndo_do_ioctl = mac802154_wpan_ioctl, .ndo_set_mac_address = mac802154_wpan_mac_addr, }; diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index cb9600bcca51..575832231fd6 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -58,7 +58,7 @@ void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) static const struct net_device_ops mac802154_monitor_ops = { .ndo_open = mac802154_slave_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_monitor_xmit, + .ndo_start_xmit = ieee802154_monitor_start_xmit, }; void mac802154_monitor_setup(struct net_device *dev) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fe105d42ef83..74882c72b6c3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -31,22 +31,24 @@ /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct wpan_xmit_cb { +struct ieee802154_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; }; -static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) +static inline struct ieee802154_xmit_cb * +ieee802154_xmit_cb(const struct sk_buff *skb) { - BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct wpan_xmit_cb)); + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ieee802154_xmit_cb)); - return (struct wpan_xmit_cb *)skb->cb; + return (struct ieee802154_xmit_cb *)skb->cb; } -static void mac802154_xmit_worker(struct work_struct *work) +static void ieee802154_xmit_worker(struct work_struct *work) { - struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); + struct ieee802154_xmit_cb *cb = + container_of(work, struct ieee802154_xmit_cb, work); struct ieee802154_local *local = cb->local; struct sk_buff *skb = cb->skb; struct net_device *dev = skb->dev; @@ -80,9 +82,9 @@ err_tx: } static netdev_tx_t -mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) +ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + struct ieee802154_xmit_cb *cb = ieee802154_xmit_cb(skb); struct net_device *dev = skb->dev; int ret; @@ -111,7 +113,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; } else { - INIT_WORK(&cb->work, mac802154_xmit_worker); + INIT_WORK(&cb->work, ieee802154_xmit_worker); cb->skb = skb; cb->local = local; @@ -125,16 +127,18 @@ err_tx: return NETDEV_TX_OK; } -netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) +netdev_tx_t +ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); skb->skb_iif = dev->ifindex; - return mac802154_tx(sdata->local, skb); + return ieee802154_tx(sdata->local, skb); } -netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +netdev_tx_t +ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int rc; @@ -148,5 +152,5 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) skb->skb_iif = dev->ifindex; - return mac802154_tx(sdata->local, skb); + return ieee802154_tx(sdata->local, skb); } -- cgit v1.2.3 From f81f466ca588a5bd868008154050305481f241d4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 18:15:34 +0100 Subject: mac802154: tx: make worker information static This patch moves the worker information struct out of skb control block. Instead control block we declare it static inside of tx.c file. We can do that, because the worker can't be used twice at the same time. It's protected by stop and wake netdev queue. This patch fix an issue that the "struct ieee802154_xmit_cb" doesn't fit into the skb control block on some kernel configuartion reported by kbuild test robot. It was introduced by commit fe24371d6645b766c59ec664c59d0a9c310ad455 ("mac802154: tx: remove kmalloc in xmit hotpath"). Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 74882c72b6c3..fe2e17e6fee3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -37,13 +37,7 @@ struct ieee802154_xmit_cb { struct ieee802154_local *local; }; -static inline struct ieee802154_xmit_cb * -ieee802154_xmit_cb(const struct sk_buff *skb) -{ - BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ieee802154_xmit_cb)); - - return (struct ieee802154_xmit_cb *)skb->cb; -} +static struct ieee802154_xmit_cb ieee802154_xmit_cb; static void ieee802154_xmit_worker(struct work_struct *work) { @@ -84,7 +78,6 @@ err_tx: static netdev_tx_t ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct ieee802154_xmit_cb *cb = ieee802154_xmit_cb(skb); struct net_device *dev = skb->dev; int ret; @@ -113,11 +106,11 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; } else { - INIT_WORK(&cb->work, ieee802154_xmit_worker); - cb->skb = skb; - cb->local = local; + INIT_WORK(&ieee802154_xmit_cb.work, ieee802154_xmit_worker); + ieee802154_xmit_cb.skb = skb; + ieee802154_xmit_cb.local = local; - queue_work(local->workqueue, &cb->work); + queue_work(local->workqueue, &ieee802154_xmit_cb.work); } return NETDEV_TX_OK; -- cgit v1.2.3 From 1998d90ad424c1ff12ea24816ce158d5262e06a5 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:00 -0700 Subject: cfg80211: support creating wiphy with suggested name Kernel will attempt to use the name if it is supplied, but if name cannot be used for some reason, the default phyX name will be used instead. Signed-off-by: Ben Greear [while at it, use wiphy_name() instead of dev_name(), fix format string issue reported by Kees Cook] Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 23 ++++++++++++++++++- net/wireless/core.c | 60 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 77aa805d7e7c..39d7996b0609 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3184,6 +3184,23 @@ static inline const char *wiphy_name(const struct wiphy *wiphy) return dev_name(&wiphy->dev); } +/** + * wiphy_new_nm - create a new wiphy for use with cfg80211 + * + * @ops: The configuration operations for this device + * @sizeof_priv: The size of the private area to allocate + * @requested_name: Request a particular name. + * NULL is valid value, and means use the default phy%d naming. + * + * Create a new wiphy and associate the given operations with it. + * @sizeof_priv bytes are allocated for private use. + * + * Return: A pointer to the new wiphy. This pointer must be + * assigned to each netdev's ieee80211_ptr for proper operation. + */ +struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, + const char *requested_name); + /** * wiphy_new - create a new wiphy for use with cfg80211 * @@ -3196,7 +3213,11 @@ static inline const char *wiphy_name(const struct wiphy *wiphy) * Return: A pointer to the new wiphy. This pointer must be * assigned to each netdev's ieee80211_ptr for proper operation. */ -struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); +static inline struct wiphy *wiphy_new(const struct cfg80211_ops *ops, + int sizeof_priv) +{ + return wiphy_new_nm(ops, sizeof_priv, NULL); +} /** * wiphy_register - register a wiphy with cfg80211 diff --git a/net/wireless/core.c b/net/wireless/core.c index f52a4cd7017c..87bb502bc8de 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -86,11 +86,11 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) return &rdev->wiphy; } -int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, - char *newname) +static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, + const char *newname) { struct cfg80211_registered_device *rdev2; - int wiphy_idx, taken = -1, result, digits; + int wiphy_idx, taken = -1, digits; ASSERT_RTNL(); @@ -109,15 +109,28 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, return -EINVAL; } + /* Ensure another device does not already have this name. */ + list_for_each_entry(rdev2, &cfg80211_rdev_list, list) + if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0) + return -EINVAL; + + return 0; +} + +int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, + char *newname) +{ + int result; + + ASSERT_RTNL(); /* Ignore nop renames */ - if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) + if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0) return 0; - /* Ensure another device does not already have this name. */ - list_for_each_entry(rdev2, &cfg80211_rdev_list, list) - if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) - return -EINVAL; + result = cfg80211_dev_check_name(rdev, newname); + if (result < 0) + return result; result = device_rename(&rdev->wiphy.dev, newname); if (result) @@ -309,7 +322,8 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work) /* exported functions */ -struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) +struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, + const char *requested_name) { static atomic_t wiphy_counter = ATOMIC_INIT(0); @@ -346,7 +360,31 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) rdev->wiphy_idx--; /* give it a proper name */ - dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + if (requested_name && requested_name[0]) { + int rv; + + rtnl_lock(); + rv = cfg80211_dev_check_name(rdev, requested_name); + + if (rv < 0) { + rtnl_unlock(); + goto use_default_name; + } + + rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name); + rtnl_unlock(); + if (rv) + goto use_default_name; + } else { +use_default_name: + /* NOTE: This is *probably* safe w/out holding rtnl because of + * the restrictions on phy names. Probably this call could + * fail if some other part of the kernel (re)named a device + * phyX. But, might should add some locking and check return + * value, and use a different name if this one exists? + */ + dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + } INIT_LIST_HEAD(&rdev->wdev_list); INIT_LIST_HEAD(&rdev->beacon_registrations); @@ -406,7 +444,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) return &rdev->wiphy; } -EXPORT_SYMBOL(wiphy_new); +EXPORT_SYMBOL(wiphy_new_nm); static int wiphy_verify_combinations(struct wiphy *wiphy) { -- cgit v1.2.3 From ad28757eef268e609677d0e3d8c0bdadde52a711 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:01 -0700 Subject: mac80211: allow creating wiphy devices with suggested name Support creating wiphy devices with an optional name. This will be used by hwsim to have better automated control over virtual radio creation/deletion. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- include/net/mac80211.h | 28 ++++++++++++++++++++++++++-- net/mac80211/main.c | 9 +++++---- 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2b7426a90ff0..bb50e8beec0e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3063,7 +3063,7 @@ struct ieee80211_ops { }; /** - * ieee80211_alloc_hw - Allocate a new hardware device + * ieee80211_alloc_hw_nm - Allocate a new hardware device * * This must be called once for each hardware device. The returned pointer * must be used to refer to this device when calling other functions. @@ -3073,11 +3073,35 @@ struct ieee80211_ops { * * @priv_data_len: length of private data * @ops: callbacks for this device + * @requested_name: Requested name for this device. + * NULL is valid value, and means use the default naming (phy%d) * * Return: A pointer to the new hardware device, or %NULL on error. */ +struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + const struct ieee80211_ops *ops, + const char *requested_name); + +/** + * ieee80211_alloc_hw - Allocate a new hardware device + * + * This must be called once for each hardware device. The returned pointer + * must be used to refer to this device when calling other functions. + * mac80211 allocates a private data area for the driver pointed to by + * @priv in &struct ieee80211_hw, the size of this area is given as + * @priv_data_len. + * + * @priv_data_len: length of private data + * @ops: callbacks for this device + * + * Return: A pointer to the new hardware device, or %NULL on error. + */ +static inline struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - const struct ieee80211_ops *ops); + const struct ieee80211_ops *ops) +{ + return ieee80211_alloc_hw_nm(priv_data_len, ops, NULL); +} /** * ieee80211_register_hw - Register hardware device diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9e322dce64ec..b189122d4b20 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -478,8 +478,9 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { }, }; -struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - const struct ieee80211_ops *ops) +struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + const struct ieee80211_ops *ops, + const char *requested_name) { struct ieee80211_local *local; int priv_size, i; @@ -519,7 +520,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, */ priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; - wiphy = wiphy_new(&mac80211_config_ops, priv_size); + wiphy = wiphy_new_nm(&mac80211_config_ops, priv_size, requested_name); if (!wiphy) return NULL; @@ -649,7 +650,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, return &local->hw; } -EXPORT_SYMBOL(ieee80211_alloc_hw); +EXPORT_SYMBOL(ieee80211_alloc_hw_nm); static int ieee80211_init_cipher_suites(struct ieee80211_local *local) { -- cgit v1.2.3 From e27513fbd030d8558cfa9250bd62b2baf19dc114 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:03 -0700 Subject: mac80211: support creating wiphy w/out creating wlanX This will be helpful when using the mac80211_hwsim wiphys and automated testing. Let user create the vifs as needed, and named as expected. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- include/net/mac80211.h | 7 ++++++- net/mac80211/main.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index bb50e8beec0e..1614b2fc3bf6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1583,6 +1583,10 @@ struct ieee80211_tx_control { * a virtual monitor interface when monitor interfaces are the only * active interfaces. * + * @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to + * be created. It is expected user-space will create vifs as + * desired (and thus have them named as desired). + * * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface * queue mapping in order to use different queues (not just one per AC) * for different virtual interfaces. See the doc section on HW queue @@ -1629,7 +1633,8 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, IEEE80211_HW_MFP_CAPABLE = 1<<13, IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, - /* free slots */ + IEEE80211_HW_NO_AUTO_VIF = 1<<15, + /* free slot */ IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b189122d4b20..7d40e3f0a77b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1023,7 +1023,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } /* add one default STA interface if supported */ - if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && + !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) { result = ieee80211_if_add(local, "wlan%d", NULL, NL80211_IFTYPE_STATION, NULL); if (result) -- cgit v1.2.3 From e8f479b11268af3f206d1580f6b0d572d6ecb4f7 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:05 -0700 Subject: cfg80211: support configuring vif mac addr on create This is useful when creating virtual interfaces. Keeps udev from mucking with things it shouldn't, since the default MAC is never seen by udev when specified on the cmd-line during creation. Signed-off-by: Ben Greear [check for feature flag in nl80211 to force drivers to set it] Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 9 ++++++--- include/uapi/linux/nl80211.h | 4 ++++ net/wireless/nl80211.c | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 39d7996b0609..f67948e18600 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -319,9 +319,12 @@ struct ieee80211_supported_band { /** * struct vif_params - describes virtual interface parameters * @use_4addr: use 4-address frames - * @macaddr: address to use for this virtual interface. This will only - * be used for non-netdevice interfaces. If this parameter is set - * to zero address the driver may determine the address as needed. + * @macaddr: address to use for this virtual interface. + * If this parameter is set to zero address the driver may + * determine the address as needed. + * This feature is only fully supported by drivers that enable the + * %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating + ** only p2p devices with specified MAC. */ struct vif_params { int use_4addr; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index be1d5def304d..f7daae59248e 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4056,6 +4056,9 @@ enum nl80211_ap_sme_features { * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it * needs to be able to handle Block-Ack agreements and other things. + * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring + * the vif's MAC address upon creation. + * See 'macaddr' field in the vif_params (cfg80211.h). */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4085,6 +4088,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_STATIC_SMPS = 1 << 24, NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, + NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d98d4ea27819..12736a7cd506 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2605,7 +2605,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) !(rdev->wiphy.interface_modes & (1 << type))) return -EOPNOTSUPP; - if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) { + if ((type == NL80211_IFTYPE_P2P_DEVICE || + rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) && + info->attrs[NL80211_ATTR_MAC]) { nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], ETH_ALEN); if (!is_valid_ether_addr(params.macaddr)) -- cgit v1.2.3 From b5dfae020b3539feaa014d3b6152f48660c2d75b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:06 -0700 Subject: mac80211: support creating vifs with specified mac address This is useful when creating virtual interfaces. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 5 ++++- net/mac80211/main.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e469b3390f2a..1ffcc0701244 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1671,7 +1671,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, } ieee80211_assign_perm_addr(local, ndev->perm_addr, type); - memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); + if (params && is_valid_ether_addr(params->macaddr)) + memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN); + else + memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7d40e3f0a77b..282a4f36eb92 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -542,6 +542,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, NL80211_FEATURE_SAE | NL80211_FEATURE_HT_IBSS | NL80211_FEATURE_VIF_TXPOWER | + NL80211_FEATURE_MAC_ON_CREATE | NL80211_FEATURE_USERSPACE_MPM; if (!ops->hw_scan) -- cgit v1.2.3 From cfede0d80d785cc6d972cad2df2df0a502312d25 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 20 Oct 2014 15:57:18 +0300 Subject: mac80211: don't flush when probing the AP All the callers of ieee80211_mgd_probe_ap_send return right after they call the flush() callback. This means that calling flush() is uneeded since its meaning is to wait until the queues of the device are empty. Devices that know how to report status on Tx will do so using the regular path (ieee80211_tx_status) and this status will trigger the continuation of the flow of the probe (ieee80211_sta_tx_notify). Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'net') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d9b4d165ce8..c078cd344ca4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2207,8 +2207,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); run_again(sdata, ifmgd->probe_timeout); - if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) - ieee80211_flush_queues(sdata->local, sdata); } static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, -- cgit v1.2.3 From 9ffe904405580fa54f935e2a30fb7b2c9328f9ff Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Fri, 24 Oct 2014 14:34:49 +0200 Subject: mac80211: minstrel_ht: do not always skip ht rates vht_only is true When CONFIG_MAC80211_RC_MINSTREL_VHT is set, the module param minstrel_vht_only tells minstrel_ht whether to allow the mix of ht rates with vht rates. ATM, minstrel_ht skips ht rates when minstrel_vht_only is true, but it does that even if vht is not supported, which makes the sta rates fallback to legacy as no ht rate gets enabled. Fixes: 9208247d74bc ("mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz") Signed-off-by: Karl Beldan Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 46666818719b..c50fd94d2aef 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1193,7 +1193,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, /* HT rate */ if (gflags & IEEE80211_TX_RC_MCS) { #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT - if (minstrel_vht_only) + if (use_vht && minstrel_vht_only) continue; #endif mi->groups[i].supported = mcs->rx_mask[nss - 1]; -- cgit v1.2.3 From f8b361768ea2eaf9b21dfbe7388958ec31798c8b Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:53 +0100 Subject: 6lowpan: remove skb_deliver from IPHC Separating skb delivery from decompression ensures that we can support further decompression schemes and removes the mixed return value of error codes with NET_RX_FOO. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- include/net/6lowpan.h | 4 +--- net/6lowpan/iphc.c | 32 ++++++-------------------------- net/bluetooth/6lowpan.c | 14 ++++++++++++-- net/ieee802154/6lowpan_rtnl.c | 41 ++++++++++++++++++++++++++--------------- 4 files changed, 45 insertions(+), 46 deletions(-) (limited to 'net') diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index d184df1d0d41..abfa3593e911 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset) return skb->len + uncomp_header - ret; } -typedef int (*skb_delivery_cb)(struct sk_buff *skb, struct net_device *dev); - int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, const u8 *saddr, const u8 saddr_type, const u8 saddr_len, const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1, skb_delivery_cb skb_deliver); + u8 iphc0, u8 iphc1); int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len); diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 747b3ccfc4f8..45714fe885f0 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb, return 0; } -static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, - struct net_device *dev, skb_delivery_cb deliver_skb) -{ - int stat; - - skb_push(skb, sizeof(struct ipv6hdr)); - skb_reset_network_header(skb); - skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr)); - - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - skb->dev = dev; - - raw_dump_table(__func__, "raw skb data dump before receiving", - skb->data, skb->len); - - stat = deliver_skb(skb, dev); - - consume_skb(skb); - - return stat; -} - /* Uncompress function for multicast destination address, * when M bit is set. */ @@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, const u8 *saddr, const u8 saddr_type, const u8 saddr_len, const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb) + u8 iphc0, u8 iphc1) { struct ipv6hdr hdr = {}; u8 tmp, num_context = 0; @@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, hdr.hop_limit, &hdr.daddr); - raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); + skb_push(skb, sizeof(hdr)); + skb_reset_network_header(skb); + skb_copy_to_linear_data(skb, &hdr, sizeof(hdr)); - return skb_deliver(skb, &hdr, dev, deliver_skb); + raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); + return 0; drop: kfree_skb(skb); return -EINVAL; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 6c5c2eff45bd..45d9a9fef634 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -252,7 +252,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) - return -ENOMEM; + return NET_RX_DROP; return netif_rx(skb_cp); } @@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev, return lowpan_process_data(skb, netdev, saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - iphc0, iphc1, give_skb_to_upper); + iphc0, iphc1); drop: kfree_skb(skb); @@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (ret != NET_RX_SUCCESS) goto drop; + local_skb->protocol = htons(ETH_P_IPV6); + local_skb->pkt_type = PACKET_HOST; + local_skb->dev = dev; + + if (give_skb_to_upper(local_skb, dev) + != NET_RX_SUCCESS) { + kfree_skb(local_skb); + goto drop; + } + dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 1779a08d110a..15c7717c5e06 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -141,20 +141,28 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb, struct sk_buff *skb_cp; int stat = NET_RX_SUCCESS; + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + rcu_read_lock(); list_for_each_entry_rcu(entry, &lowpan_devices, list) if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) { - stat = -ENOMEM; - break; + kfree_skb(skb); + rcu_read_unlock(); + return NET_RX_DROP; } skb_cp->dev = entry->ldev; stat = netif_rx(skb_cp); + if (stat == NET_RX_DROP) + break; } rcu_read_unlock(); + consume_skb(skb); + return stat; } @@ -190,8 +198,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, IEEE802154_ADDR_LEN, dap, da.addr_type, - IEEE802154_ADDR_LEN, iphc0, iphc1, - lowpan_give_skb_to_devices); + IEEE802154_ADDR_LEN, iphc0, iphc1); drop: kfree_skb(skb); @@ -528,44 +535,48 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, /* check that it's our buffer */ if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - /* Pull off the 1-byte of 6lowpan header. */ skb_pull(skb, 1); - - ret = lowpan_give_skb_to_devices(skb, NULL); - if (ret == NET_RX_DROP) - goto drop; + return lowpan_give_skb_to_devices(skb, NULL); } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; - break; + + return lowpan_give_skb_to_devices(skb, NULL); case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; + + return lowpan_give_skb_to_devices(skb, NULL); + } else if (ret == -1) { + return NET_RX_DROP; + } else { + return NET_RX_SUCCESS; } - break; case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; + + return lowpan_give_skb_to_devices(skb, NULL); + } else if (ret == -1) { + return NET_RX_DROP; + } else { + return NET_RX_SUCCESS; } - break; default: break; } } - return NET_RX_SUCCESS; drop_skb: kfree_skb(skb); drop: -- cgit v1.2.3 From 04dfd7386ab7a0f016bbcf30b3a5051650242120 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:54 +0100 Subject: 6lowpan: fix process_data return values As process_data now returns just error codes fix up the calls to this function to only drop the skb if an error code is returned. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 2 +- net/ieee802154/6lowpan_rtnl.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 45d9a9fef634..94bbb6611bc5 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -347,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, goto drop; ret = process_data(local_skb, dev, chan); - if (ret != NET_RX_SUCCESS) + if (ret < 0) goto drop; local_skb->protocol = htons(ETH_P_IPV6); diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 15c7717c5e06..21742c827475 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -542,7 +542,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); @@ -550,7 +550,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); @@ -563,7 +563,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); -- cgit v1.2.3 From 3c400b843d4c07703b68e91854bc395c95e4c51a Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:55 +0100 Subject: bluetooth:6lowpan: use consume_skb when packet processed successfully Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 94bbb6611bc5..40e2cec7fcef 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -337,8 +337,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; - kfree_skb(local_skb); - kfree_skb(skb); + consume_skb(local_skb); + consume_skb(skb); } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ @@ -363,7 +363,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; - kfree_skb(skb); + consume_skb(local_skb); + consume_skb(skb); break; default: break; -- cgit v1.2.3 From 01141234f237957ec962dda2f1ca89d9ef180884 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:56 +0100 Subject: ieee802154: 6lowpan: rename process_data and lowpan_process_data As we have decouple decompression from data delivery we can now rename all occurences of process_data in receive path. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- include/net/6lowpan.h | 10 ++++++---- net/6lowpan/iphc.c | 12 +++++++----- net/bluetooth/6lowpan.c | 15 ++++++++------- net/ieee802154/6lowpan_rtnl.c | 15 ++++++++------- 4 files changed, 29 insertions(+), 23 deletions(-) (limited to 'net') diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index abfa3593e911..dc03d77ad23b 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -372,10 +372,12 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset) return skb->len + uncomp_header - ret; } -int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, - const u8 *saddr, const u8 saddr_type, const u8 saddr_len, - const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1); +int +lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, + const u8 *saddr, const u8 saddr_type, + const u8 saddr_len, const u8 *daddr, + const u8 daddr_type, const u8 daddr_len, + u8 iphc0, u8 iphc1); int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len); diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 45714fe885f0..73a7065f0c6b 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -301,10 +301,12 @@ err: /* TTL uncompression values */ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; -int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, - const u8 *saddr, const u8 saddr_type, const u8 saddr_len, - const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1) +int +lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, + const u8 *saddr, const u8 saddr_type, + const u8 saddr_len, const u8 *daddr, + const u8 daddr_type, const u8 daddr_len, + u8 iphc0, u8 iphc1) { struct ipv6hdr hdr = {}; u8 tmp, num_context = 0; @@ -480,7 +482,7 @@ drop: kfree_skb(skb); return -EINVAL; } -EXPORT_SYMBOL_GPL(lowpan_process_data); +EXPORT_SYMBOL_GPL(lowpan_header_decompress); static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift, const struct in6_addr *ipaddr, diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 40e2cec7fcef..aa6ebbfc5d31 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -257,8 +257,8 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) return netif_rx(skb_cp); } -static int process_data(struct sk_buff *skb, struct net_device *netdev, - struct l2cap_chan *chan) +static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, + struct l2cap_chan *chan) { const u8 *saddr, *daddr; u8 iphc0, iphc1; @@ -287,10 +287,11 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev, if (lowpan_fetch_skb_u8(skb, &iphc1)) goto drop; - return lowpan_process_data(skb, netdev, - saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - iphc0, iphc1); + return lowpan_header_decompress(skb, netdev, + saddr, IEEE802154_ADDR_LONG, + EUI64_ADDR_LEN, daddr, + IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, + iphc0, iphc1); drop: kfree_skb(skb); @@ -346,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (!local_skb) goto drop; - ret = process_data(local_skb, dev, chan); + ret = iphc_decompress(local_skb, dev, chan); if (ret < 0) goto drop; diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 21742c827475..519a65452d90 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -166,7 +166,8 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb, return stat; } -static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) +static int +iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) { u8 iphc0, iphc1; struct ieee802154_addr_sa sa, da; @@ -196,9 +197,9 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) else dap = &da.hwaddr; - return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, - IEEE802154_ADDR_LEN, dap, da.addr_type, - IEEE802154_ADDR_LEN, iphc0, iphc1); + return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, + IEEE802154_ADDR_LEN, dap, da.addr_type, + IEEE802154_ADDR_LEN, iphc0, iphc1); drop: kfree_skb(skb); @@ -541,7 +542,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; @@ -549,7 +550,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; @@ -562,7 +563,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; -- cgit v1.2.3 From 061ef8f915988839b12460c47ebfcf3700e124f0 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:28 +0100 Subject: mac802154: tx: use put_unaligned_le16 for copy crc This patch replaces the memcpy with a put_unaligned_le16. The placement of crc inside of PSDU can also be unaligned. With memcpy this can fail on some architectures. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fe2e17e6fee3..31e51e4635e4 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -84,9 +85,9 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - __le16 crc = cpu_to_le16(crc_ccitt(0, skb->data, skb->len)); + u16 crc = crc_ccitt(0, skb->data, skb->len); - memcpy(skb_put(skb, 2), &crc, 2); + put_unaligned_le16(crc, skb_put(skb, 2)); } if (skb_cow_head(skb, local->hw.extra_tx_headroom)) -- cgit v1.2.3 From c5c47e67bcd24638a059b1b5e9ec18c95f8634ca Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:30 +0100 Subject: mac802154: rx: use tasklet instead workqueue Tasklets have much less overhead than workqueues. This patch also removes the heap allocation for the worker on receiving path. Like mac80211 we should prefer use a tasklet here instead a workqueue to getting fast out of interrupt context when ieee802154_rx_irqsafe is called by driver. Like wireless inside the tasklet context we should call netif_receive_skb instead netif_rx_ni anymore. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 1 + net/mac802154/ieee802154_i.h | 7 +++++++ net/mac802154/iface.c | 2 +- net/mac802154/main.c | 30 +++++++++++++++++++++++++++ net/mac802154/rx.c | 48 ++++++++------------------------------------ 5 files changed, 47 insertions(+), 41 deletions(-) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 942dd53d4658..4c4642ef244f 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -202,6 +202,7 @@ void ieee802154_free_hw(struct ieee802154_hw *hw); int ieee802154_register_hw(struct ieee802154_hw *hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw); +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index ef29c10eeb66..603509a94a86 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -55,11 +55,18 @@ struct ieee802154_local { * read them using any of protection methods. */ bool running; + + struct tasklet_struct tasklet; + struct sk_buff_head skb_queue; }; #define MAC802154_DEVICE_STOPPED 0x00 #define MAC802154_DEVICE_RUN 0x01 +enum { + IEEE802154_RX_MSG = 1, +}; + /* Slave interface definition. * * Slaves represent typical network interfaces available from userspace. diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index be45dc9257b3..311f60c8629b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -376,7 +376,7 @@ void mac802154_wpan_setup(struct net_device *dev) static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { - return netif_rx_ni(skb); + return netif_receive_skb(skb); } static int diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 3c0a824d24ac..ff0de0f990cb 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -222,6 +222,29 @@ static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) return local->ops->set_frame_retries(&local->hw, retries); } +static void ieee802154_tasklet_handler(unsigned long data) +{ + struct ieee802154_local *local = (struct ieee802154_local *)data; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&local->skb_queue))) { + switch (skb->pkt_type) { + case IEEE802154_RX_MSG: + /* Clear skb->pkt_type in order to not confuse kernel + * netstack. + */ + skb->pkt_type = 0; + ieee802154_rx(&local->hw, skb); + break; + default: + WARN(1, "mac802154: Packet is of unknown type %d\n", + skb->pkt_type); + kfree_skb(skb); + break; + } + } +} + struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { @@ -270,6 +293,12 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) INIT_LIST_HEAD(&local->interfaces); mutex_init(&local->iflist_mtx); + tasklet_init(&local->tasklet, + ieee802154_tasklet_handler, + (unsigned long)local); + + skb_queue_head_init(&local->skb_queue); + return &local->hw; } EXPORT_SYMBOL(ieee802154_alloc_hw); @@ -371,6 +400,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; + tasklet_kill(&local->tasklet); flush_workqueue(local->workqueue); destroy_workqueue(local->workqueue); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 53c9e0c10a87..2851a3f7ac0b 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -28,30 +27,11 @@ #include "ieee802154_i.h" -/* The IEEE 802.15.4 standard defines 4 MAC packet types: - * - beacon frame - * - MAC command frame - * - acknowledgement frame - * - data frame - * - * and only the data frame should be pushed to the upper layers, other types - * are just internal MAC layer management information. So only data packets - * are going to be sent to the networking queue, all other will be processed - * right here by using the device workqueue. - */ -struct rx_work { - struct sk_buff *skb; - struct work_struct work; - struct ieee802154_hw *hw; - u8 lqi; -}; - static void -mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) +mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); - mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); @@ -79,32 +59,20 @@ fail: kfree_skb(skb); } -static void mac802154_rx_worker(struct work_struct *work) +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct rx_work *rw = container_of(work, struct rx_work, work); - - mac802154_subif_rx(rw->hw, rw->skb, rw->lqi); - kfree(rw); + mac802154_subif_rx(hw, skb); } +EXPORT_SYMBOL(ieee802154_rx); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { struct ieee802154_local *local = hw_to_local(hw); - struct rx_work *work; - if (!skb) - return; - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, mac802154_rx_worker); - work->skb = skb; - work->hw = hw; - work->lqi = lqi; - - queue_work(local->workqueue, &work->work); + mac_cb(skb)->lqi = lqi; + skb->pkt_type = IEEE802154_RX_MSG; + skb_queue_tail(&local->skb_queue, skb); + tasklet_schedule(&local->tasklet); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); -- cgit v1.2.3 From c730c90316aa5753c6b2d3d5af40085c220e3a91 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:31 +0100 Subject: mac802154: rx: document ieee802154_rx() context requirement This patch is similar like d20ef63d32461332958661df73e21c0ca42601b0 ("mac80211: document ieee80211_rx() context requirement"). The netif_receive_skb call requires with softirqs disabled. This patch adds a warning if softirqs are pending while calling ieee802154_rx. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 2851a3f7ac0b..c4df3210c5e6 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -61,6 +61,8 @@ fail: void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { + WARN_ON_ONCE(softirq_count() == 0); + mac802154_subif_rx(hw, skb); } EXPORT_SYMBOL(ieee802154_rx); -- cgit v1.2.3 From 2a9820c9e20a7889bf464e1edff5f75d685a8214 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:32 +0100 Subject: mac802154: rx: move receive handling into rx.c This patch removes all relevant receiving functions inclusive frame parsing into rx file. Like mac80211 we should implement the complete receive handling and parsing in this file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 - net/mac802154/iface.c | 186 ------------------------------------- net/mac802154/monitor.c | 27 ------ net/mac802154/rx.c | 214 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 214 insertions(+), 214 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 603509a94a86..be2f2f6774ae 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -131,7 +131,6 @@ void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); -void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 311f60c8629b..7e4bffcbcd4d 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -373,189 +373,3 @@ void mac802154_wpan_setup(struct net_device *dev) mac802154_llsec_init(&sdata->sec); } - -static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) -{ - return netif_receive_skb(skb); -} - -static int -mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, - const struct ieee802154_hdr *hdr) -{ - __le16 span, sshort; - int rc; - - pr_debug("getting packet via slave interface %s\n", sdata->dev->name); - - spin_lock_bh(&sdata->mib_lock); - - span = sdata->pan_id; - sshort = sdata->short_addr; - - switch (mac_cb(skb)->dest.mode) { - case IEEE802154_ADDR_NONE: - if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) - /* FIXME: check if we are PAN coordinator */ - skb->pkt_type = PACKET_OTHERHOST; - else - /* ACK comes with both addresses empty */ - skb->pkt_type = PACKET_HOST; - break; - case IEEE802154_ADDR_LONG: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) - skb->pkt_type = PACKET_HOST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - case IEEE802154_ADDR_SHORT: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.short_addr == sshort) - skb->pkt_type = PACKET_HOST; - else if (mac_cb(skb)->dest.short_addr == - cpu_to_le16(IEEE802154_ADDR_BROADCAST)) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - default: - spin_unlock_bh(&sdata->mib_lock); - pr_debug("invalid dest mode\n"); - kfree_skb(skb); - return NET_RX_DROP; - } - - spin_unlock_bh(&sdata->mib_lock); - - skb->dev = sdata->dev; - - rc = mac802154_llsec_decrypt(&sdata->sec, skb); - if (rc) { - pr_debug("decryption failed: %i\n", rc); - goto fail; - } - - sdata->dev->stats.rx_packets++; - sdata->dev->stats.rx_bytes += skb->len; - - switch (mac_cb(skb)->type) { - case IEEE802154_FC_TYPE_DATA: - return mac802154_process_data(sdata->dev, skb); - default: - pr_warn("ieee802154: bad frame received (type = %d)\n", - mac_cb(skb)->type); - goto fail; - } - -fail: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void mac802154_print_addr(const char *name, - const struct ieee802154_addr *addr) -{ - if (addr->mode == IEEE802154_ADDR_NONE) - pr_debug("%s not present\n", name); - - pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); - if (addr->mode == IEEE802154_ADDR_SHORT) { - pr_debug("%s is short: %04x\n", name, - le16_to_cpu(addr->short_addr)); - } else { - u64 hw = swab64((__force u64) addr->extended_addr); - - pr_debug("%s is hardware: %8phC\n", name, &hw); - } -} - -static int mac802154_parse_frame_start(struct sk_buff *skb, - struct ieee802154_hdr *hdr) -{ - int hlen; - struct ieee802154_mac_cb *cb = mac_cb_init(skb); - - hlen = ieee802154_hdr_pull(skb, hdr); - if (hlen < 0) - return -EINVAL; - - skb->mac_len = hlen; - - pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), - hdr->seq); - - cb->type = hdr->fc.type; - cb->ackreq = hdr->fc.ack_request; - cb->secen = hdr->fc.security_enabled; - - mac802154_print_addr("destination", &hdr->dest); - mac802154_print_addr("source", &hdr->source); - - cb->source = hdr->source; - cb->dest = hdr->dest; - - if (hdr->fc.security_enabled) { - u64 key; - - pr_debug("seclevel %i\n", hdr->sec.level); - - switch (hdr->sec.key_id_mode) { - case IEEE802154_SCF_KEY_IMPLICIT: - pr_debug("implicit key\n"); - break; - - case IEEE802154_SCF_KEY_INDEX: - pr_debug("key %02x\n", hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_SHORT_INDEX: - pr_debug("key %04x:%04x %02x\n", - le32_to_cpu(hdr->sec.short_src) >> 16, - le32_to_cpu(hdr->sec.short_src) & 0xffff, - hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_HW_INDEX: - key = swab64((__force u64) hdr->sec.extended_src); - pr_debug("key source %8phC %02x\n", &key, - hdr->sec.key_id); - break; - } - } - - return 0; -} - -void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) -{ - int ret; - struct ieee802154_sub_if_data *sdata; - struct ieee802154_hdr hdr; - - ret = mac802154_parse_frame_start(skb, &hdr); - if (ret) { - pr_debug("got invalid frame\n"); - kfree_skb(skb); - return; - } - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_WPAN || - !netif_running(sdata->dev)) - continue; - - mac802154_subif_frame(sdata, skb, &hdr); - skb = NULL; - break; - } - rcu_read_unlock(); - - if (skb) - kfree_skb(skb); -} diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 575832231fd6..dfdedc206c6a 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -18,9 +18,7 @@ */ #include -#include #include -#include #include #include @@ -30,31 +28,6 @@ #include "ieee802154_i.h" -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) -{ - struct sk_buff *skb2; - struct ieee802154_sub_if_data *sdata; - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data; - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_MONITOR || - !netif_running(sdata->dev)) - continue; - - skb2 = skb_clone(skb, GFP_ATOMIC); - skb2->dev = sdata->dev; - skb2->pkt_type = PACKET_HOST; - data = skb_put(skb2, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; - - netif_rx_ni(skb2); - } - rcu_read_unlock(); -} - static const struct net_device_ops mac802154_monitor_ops = { .ndo_open = mac802154_slave_open, .ndo_stop = mac802154_slave_close, diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c4df3210c5e6..d8498c5fc297 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -24,9 +24,223 @@ #include #include +#include +#include #include "ieee802154_i.h" +static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +{ + return netif_receive_skb(skb); +} + +static int +mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, + const struct ieee802154_hdr *hdr) +{ + __le16 span, sshort; + int rc; + + pr_debug("getting packet via slave interface %s\n", sdata->dev->name); + + spin_lock_bh(&sdata->mib_lock); + + span = sdata->pan_id; + sshort = sdata->short_addr; + + switch (mac_cb(skb)->dest.mode) { + case IEEE802154_ADDR_NONE: + if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) + /* FIXME: check if we are PAN coordinator */ + skb->pkt_type = PACKET_OTHERHOST; + else + /* ACK comes with both addresses empty */ + skb->pkt_type = PACKET_HOST; + break; + case IEEE802154_ADDR_LONG: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) + skb->pkt_type = PACKET_HOST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + case IEEE802154_ADDR_SHORT: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.short_addr == sshort) + skb->pkt_type = PACKET_HOST; + else if (mac_cb(skb)->dest.short_addr == + cpu_to_le16(IEEE802154_ADDR_BROADCAST)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + default: + spin_unlock_bh(&sdata->mib_lock); + pr_debug("invalid dest mode\n"); + kfree_skb(skb); + return NET_RX_DROP; + } + + spin_unlock_bh(&sdata->mib_lock); + + skb->dev = sdata->dev; + + rc = mac802154_llsec_decrypt(&sdata->sec, skb); + if (rc) { + pr_debug("decryption failed: %i\n", rc); + goto fail; + } + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + + switch (mac_cb(skb)->type) { + case IEEE802154_FC_TYPE_DATA: + return mac802154_process_data(sdata->dev, skb); + default: + pr_warn("ieee802154: bad frame received (type = %d)\n", + mac_cb(skb)->type); + goto fail; + } + +fail: + kfree_skb(skb); + return NET_RX_DROP; +} + +static void mac802154_print_addr(const char *name, + const struct ieee802154_addr *addr) +{ + if (addr->mode == IEEE802154_ADDR_NONE) + pr_debug("%s not present\n", name); + + pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); + if (addr->mode == IEEE802154_ADDR_SHORT) { + pr_debug("%s is short: %04x\n", name, + le16_to_cpu(addr->short_addr)); + } else { + u64 hw = swab64((__force u64)addr->extended_addr); + + pr_debug("%s is hardware: %8phC\n", name, &hw); + } +} + +static int mac802154_parse_frame_start(struct sk_buff *skb, + struct ieee802154_hdr *hdr) +{ + int hlen; + struct ieee802154_mac_cb *cb = mac_cb_init(skb); + + hlen = ieee802154_hdr_pull(skb, hdr); + if (hlen < 0) + return -EINVAL; + + skb->mac_len = hlen; + + pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), + hdr->seq); + + cb->type = hdr->fc.type; + cb->ackreq = hdr->fc.ack_request; + cb->secen = hdr->fc.security_enabled; + + mac802154_print_addr("destination", &hdr->dest); + mac802154_print_addr("source", &hdr->source); + + cb->source = hdr->source; + cb->dest = hdr->dest; + + if (hdr->fc.security_enabled) { + u64 key; + + pr_debug("seclevel %i\n", hdr->sec.level); + + switch (hdr->sec.key_id_mode) { + case IEEE802154_SCF_KEY_IMPLICIT: + pr_debug("implicit key\n"); + break; + + case IEEE802154_SCF_KEY_INDEX: + pr_debug("key %02x\n", hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_SHORT_INDEX: + pr_debug("key %04x:%04x %02x\n", + le32_to_cpu(hdr->sec.short_src) >> 16, + le32_to_cpu(hdr->sec.short_src) & 0xffff, + hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_HW_INDEX: + key = swab64((__force u64)hdr->sec.extended_src); + pr_debug("key source %8phC %02x\n", &key, + hdr->sec.key_id); + break; + } + } + + return 0; +} + +static void +mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) +{ + int ret; + struct ieee802154_sub_if_data *sdata; + struct ieee802154_hdr hdr; + + ret = mac802154_parse_frame_start(skb, &hdr); + if (ret) { + pr_debug("got invalid frame\n"); + kfree_skb(skb); + return; + } + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (sdata->type != IEEE802154_DEV_WPAN || + !netif_running(sdata->dev)) + continue; + + mac802154_subif_frame(sdata, skb, &hdr); + skb = NULL; + break; + } + rcu_read_unlock(); + + if (skb) + kfree_skb(skb); +} + +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +{ + struct sk_buff *skb2; + struct ieee802154_sub_if_data *sdata; + u16 crc = crc_ccitt(0, skb->data, skb->len); + u8 *data; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (sdata->type != IEEE802154_DEV_MONITOR || + !netif_running(sdata->dev)) + continue; + + skb2 = skb_clone(skb, GFP_ATOMIC); + skb2->dev = sdata->dev; + skb2->pkt_type = PACKET_HOST; + data = skb_put(skb2, 2); + data[0] = crc & 0xff; + data[1] = crc >> 8; + + netif_rx_ni(skb2); + } + rcu_read_unlock(); +} + static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { -- cgit v1.2.3 From 4ca18be54f507ddb2bedb44c2e3b988163684988 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:33 +0100 Subject: mac802154: tx: remove monitor receive while xmit This removes the call of monitor receive funktion when any interface type call xmit. There exist no such use case that a monitor interface should receive the actual sending frame. One use case could be that a wpan interface and monitor interface could be running at the same time on one phy. Then the monitor interface receives the wpan frames also. Furthermore we adding support for promiscous mode setting. With promiscous mode setting we can't run a wpan and monitor interface at the same time. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 - net/mac802154/rx.c | 3 ++- net/mac802154/tx.c | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index be2f2f6774ae..ac907d943bae 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -126,7 +126,6 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index d8498c5fc297..04f3d61719ec 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -216,7 +216,8 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) kfree_skb(skb); } -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +static void +mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 31e51e4635e4..e85767355c48 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -82,8 +82,6 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) struct net_device *dev = skb->dev; int ret; - mac802154_monitors_rx(local, skb); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); -- cgit v1.2.3 From 469100d6c2ff22cd1f50672ac6d09a1633334489 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:34 +0100 Subject: mac802154: rx: rename remove mac802154_subif_rx This patch removes the mac802154_subif_rx function and do the necessary calls inside of ieee802154_rx function. The ieee802154_rx is small enough to move the functionality inside this function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 04f3d61719ec..246a60e8f76a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -242,11 +242,12 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) rcu_read_unlock(); } -static void -mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); + WARN_ON_ONCE(softirq_count() == 0); + skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); @@ -273,13 +274,6 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) fail: kfree_skb(skb); } - -void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) -{ - WARN_ON_ONCE(softirq_count() == 0); - - mac802154_subif_rx(hw, skb); -} EXPORT_SYMBOL(ieee802154_rx); void -- cgit v1.2.3 From 702dcf994a0f0c467aae4b65885833a114126387 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:35 +0100 Subject: mac802154: rx: move skb->protocol setting This patch moves the skb->protocol setting to the position when it's needed. It's only needed when frame parsing was successful. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 246a60e8f76a..c4066b5006f1 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -31,6 +31,8 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { + skb->protocol = htons(ETH_P_IEEE802154); + return netif_receive_skb(skb); } @@ -224,6 +226,8 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb->protocol = htons(ETH_P_IEEE802154); + rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || @@ -248,7 +252,6 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { -- cgit v1.2.3 From 75a46f0ee774894152d505de594616f9c4dd7ef5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:36 +0100 Subject: mac802154: rx: add CHECKSUM_UNNECESSARY This patch adds CHECKSUM_UNNECESSARY to skb->ip_summed before delivery. There exist no transceiver with IP checksum functionality. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c4066b5006f1..14eecace1859 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -31,6 +31,7 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { + skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); return netif_receive_skb(skb); @@ -226,6 +227,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); rcu_read_lock(); -- cgit v1.2.3 From c9ca6401405ea0c197ab7c8bcab2b82b26678145 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:37 +0100 Subject: mac802154: rx: add monitor pkt_type information This patch adds a PACKET_OTHERHOST setting when a monitor interface receives a skb. All receiving skb's to the monitor interface should be PACKET_OTHERHOST. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 14eecace1859..f7f09b46faa4 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -228,6 +228,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u8 *data; skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); rcu_read_lock(); -- cgit v1.2.3 From 9cf215d0733256687796ef1161b7b358be1b0602 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:38 +0100 Subject: mac802154: rx: move skb_reset_mac_header This patch moves the skb_reset_mac_header call before frame parsing while wpan rx and before monitor deliver functionality. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index f7f09b46faa4..c2999804126a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -138,6 +138,8 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, int hlen; struct ieee802154_mac_cb *cb = mac_cb_init(skb); + skb_reset_mac_header(skb); + hlen = ieee802154_hdr_pull(skb, hdr); if (hlen < 0) return -EINVAL; @@ -227,6 +229,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); @@ -255,8 +258,6 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - skb_reset_mac_header(skb); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc; -- cgit v1.2.3 From e176b681b00d2b60e9231072d3ca841f9ddc74ea Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:39 +0100 Subject: mac802154: rx: move rcu locking Instead of twice lock and unlock mechanism this patch hold these locks only once at one position. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c2999804126a..689bb7ff5b2a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -205,7 +205,6 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) return; } - rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) @@ -215,7 +214,6 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) skb = NULL; break; } - rcu_read_unlock(); if (skb) kfree_skb(skb); @@ -234,7 +232,6 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); - rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) @@ -249,7 +246,6 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) netif_rx_ni(skb2); } - rcu_read_unlock(); } void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) @@ -273,9 +269,13 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) skb_trim(skb, skb->len - 2); /* CRC */ } + rcu_read_lock(); + mac802154_monitors_rx(local, skb); mac802154_wpans_rx(local, skb); + rcu_read_unlock(); + return; fail: -- cgit v1.2.3 From be9d215fa9d13ecfe013a1b0d0f92f6d84a52c5c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:43 +0100 Subject: mac802154: rx: change naming convention This patch changes the naming convention of mac802154 rx file. It should be more named like mac80211 stack. Furthermore we introduce a new frame parsing implementation which is much similar the mac80211 implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 689bb7ff5b2a..86394befbf88 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -29,7 +29,7 @@ #include "ieee802154_i.h" -static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +static int ieee802154_deliver_skb(struct net_device *dev, struct sk_buff *skb) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); @@ -38,8 +38,8 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) } static int -mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, - const struct ieee802154_hdr *hdr) +ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, + struct sk_buff *skb, const struct ieee802154_hdr *hdr) { __le16 span, sshort; int rc; @@ -103,7 +103,7 @@ mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, switch (mac_cb(skb)->type) { case IEEE802154_FC_TYPE_DATA: - return mac802154_process_data(sdata->dev, skb); + return ieee802154_deliver_skb(sdata->dev, skb); default: pr_warn("ieee802154: bad frame received (type = %d)\n", mac_cb(skb)->type); @@ -115,8 +115,8 @@ fail: return NET_RX_DROP; } -static void mac802154_print_addr(const char *name, - const struct ieee802154_addr *addr) +static void +ieee802154_print_addr(const char *name, const struct ieee802154_addr *addr) { if (addr->mode == IEEE802154_ADDR_NONE) pr_debug("%s not present\n", name); @@ -132,8 +132,8 @@ static void mac802154_print_addr(const char *name, } } -static int mac802154_parse_frame_start(struct sk_buff *skb, - struct ieee802154_hdr *hdr) +static int +ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr) { int hlen; struct ieee802154_mac_cb *cb = mac_cb_init(skb); @@ -153,8 +153,8 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, cb->ackreq = hdr->fc.ack_request; cb->secen = hdr->fc.security_enabled; - mac802154_print_addr("destination", &hdr->dest); - mac802154_print_addr("source", &hdr->source); + ieee802154_print_addr("destination", &hdr->dest); + ieee802154_print_addr("source", &hdr->source); cb->source = hdr->source; cb->dest = hdr->dest; @@ -192,13 +192,14 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, } static void -mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) +__ieee802154_rx_handle_packet(struct ieee802154_local *local, + struct sk_buff *skb) { int ret; struct ieee802154_sub_if_data *sdata; struct ieee802154_hdr hdr; - ret = mac802154_parse_frame_start(skb, &hdr); + ret = ieee802154_parse_frame_start(skb, &hdr); if (ret) { pr_debug("got invalid frame\n"); kfree_skb(skb); @@ -210,7 +211,7 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) !netif_running(sdata->dev)) continue; - mac802154_subif_frame(sdata, skb, &hdr); + ieee802154_subif_frame(sdata, skb, &hdr); skb = NULL; break; } @@ -220,7 +221,7 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) } static void -mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; @@ -271,8 +272,8 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) rcu_read_lock(); - mac802154_monitors_rx(local, skb); - mac802154_wpans_rx(local, skb); + ieee802154_monitors_rx(local, skb); + __ieee802154_rx_handle_packet(local, skb); rcu_read_unlock(); -- cgit v1.2.3 From da213f8e0cf03146925205b663413e4589b5b359 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 15:22:12 +0100 Subject: Bluetooth: Revert SMP self-test patches This reverts commits c6992e9ef2a17e9738b7bb8a03a7fe581a8f9977 and 4cd3362da899a59955146851dd860198b0aaaa75. The reason for the revert is that we cannot have more than one module initialization function and the SMP one breaks the build with modular kernels. As the proper fix for this is right now looking non-trivial it's better to simply revert the problematic patches in order to keep the upstream tree compilable. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/Kconfig | 6 --- net/bluetooth/smp.c | 120 -------------------------------------------------- 2 files changed, 126 deletions(-) (limited to 'net') diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 2675b4106b00..600fb29288f4 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -45,12 +45,6 @@ config BT_6LOWPAN help IPv6 compression over Bluetooth Low Energy. -config BT_SELFTEST - bool "Run self-tests on boot" - depends on BT && DEBUG_KERNEL - help - Run self-tests during boot. Currently limited to SMP. - source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/bnep/Kconfig" diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 983d1e0793f6..fea3782989f4 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1743,123 +1743,3 @@ void smp_unregister(struct hci_dev *hdev) hdev->smp_data = NULL; l2cap_chan_put(chan); } - -#ifdef CONFIG_BT_SELFTEST - -static int __init test_ah(struct crypto_blkcipher *tfm_aes) -{ - u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, - 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; - u8 r[3] = { 0x94, 0x81, 0x70 }; - u8 exp[3] = { 0xaa, 0xfb, 0x0d }; - u8 res[3]; - int err; - - err = smp_ah(tfm_aes, irk, r, res); - if (err) - return err; - - if (memcmp(res, exp, 3) != 0) - return -EINVAL; - - return 0; -} - -static int __init test_c1(struct crypto_blkcipher *tfm_aes) -{ - u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 r[16] = { 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, - 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; - u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; - u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; - u8 _iat = 0x01; - u8 _rat = 0x00; - bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; - bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; - u8 exp[16] = { 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, - 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; - u8 res[16]; - int err; - - err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); - if (err) - return err; - - if (memcmp(res, exp, 16) != 0) - return -EINVAL; - - return 0; -} - -static int __init test_s1(struct crypto_blkcipher *tfm_aes) -{ - u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 r1[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; - u8 r2[16] = { 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; - u8 exp[16] = { 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, - 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; - u8 res[16]; - int err; - - err = smp_s1(tfm_aes, k, r1, r2, res); - if (err) - return err; - - if (memcmp(res, exp, 16) != 0) - return -EINVAL; - - return 0; -} - -static int __init run_selftests(struct crypto_blkcipher *tfm_aes) -{ - int err; - - err = test_ah(tfm_aes); - if (err) { - BT_ERR("smp_ah test failed"); - return err; - } - - err = test_c1(tfm_aes); - if (err) { - BT_ERR("smp_c1 test failed"); - return err; - } - - err = test_s1(tfm_aes); - if (err) { - BT_ERR("smp_s1 test failed"); - return err; - } - - return 0; -} - -static int __init test_smp(void) -{ - struct crypto_blkcipher *tfm_aes; - int err; - - tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm_aes)) { - BT_ERR("Unable to create ECB crypto context"); - return PTR_ERR(tfm_aes); - } - - err = run_selftests(tfm_aes); - if (err < 0) - BT_ERR("Self tests failed"); - else - BT_INFO("Self-tests passed"); - - crypto_free_blkcipher(tfm_aes); - - return err; -} - -module_init(test_smp); - -#endif /* CONFIG_BT_SELFTEST */ -- cgit v1.2.3 From 90305829635d90a5053ec99a261035b4ce0a2649 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 28 Oct 2014 17:16:47 +0200 Subject: Bluetooth: 6lowpan: Converting rwlocks to use RCU The rwlocks are converted to use RCU. This helps performance as the irq locks are not needed any more. Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 222 +++++++++++++++++++++++++++--------------------- 1 file changed, 127 insertions(+), 95 deletions(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index aa6ebbfc5d31..a681247b0aee 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -53,7 +53,7 @@ struct skb_cb { * The list contains struct lowpan_dev elements. */ static LIST_HEAD(bt_6lowpan_devices); -static DEFINE_RWLOCK(devices_lock); +static DEFINE_SPINLOCK(devices_lock); /* If psm is set to 0 (default value), then 6lowpan is disabled. * Other values are used to indicate a Protocol Service Multiplexer @@ -67,6 +67,7 @@ static struct l2cap_chan *listen_chan; struct lowpan_peer { struct list_head list; + struct rcu_head rcu; struct l2cap_chan *chan; /* peer addresses in various formats */ @@ -86,6 +87,13 @@ struct lowpan_dev { struct delayed_work notify_peers; }; +static inline void peer_free(struct rcu_head *head) +{ + struct lowpan_peer *e = container_of(head, struct lowpan_peer, rcu); + + kfree(e); +} + static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) { return netdev_priv(netdev); @@ -93,13 +101,14 @@ static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) { - list_add(&peer->list, &dev->peers); + list_add_rcu(&peer->list, &dev->peers); atomic_inc(&dev->peer_count); } static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) { - list_del(&peer->list); + list_del_rcu(&peer->list); + call_rcu(&peer->rcu, peer_free); module_put(THIS_MODULE); @@ -114,31 +123,37 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, bdaddr_t *ba, __u8 type) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; BT_DBG("peers %d addr %pMR type %d", atomic_read(&dev->peer_count), ba, type); - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + rcu_read_lock(); + + list_for_each_entry_rcu(peer, &dev->peers, list) { BT_DBG("dst addr %pMR dst type %d", &peer->chan->dst, peer->chan->dst_type); if (bacmp(&peer->chan->dst, ba)) continue; - if (type == peer->chan->dst_type) + if (type == peer->chan->dst_type) { + rcu_read_unlock(); return peer; + } } + rcu_read_unlock(); + return NULL; } -static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev, - struct l2cap_chan *chan) +static inline struct lowpan_peer *__peer_lookup_chan(struct lowpan_dev *dev, + struct l2cap_chan *chan) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + list_for_each_entry_rcu(peer, &dev->peers, list) { if (peer->chan == chan) return peer; } @@ -146,12 +161,12 @@ static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev, return NULL; } -static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev, - struct l2cap_conn *conn) +static inline struct lowpan_peer *__peer_lookup_conn(struct lowpan_dev *dev, + struct l2cap_conn *conn) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + list_for_each_entry_rcu(peer, &dev->peers, list) { if (peer->chan->conn == conn) return peer; } @@ -163,7 +178,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, struct in6_addr *daddr, struct sk_buff *skb) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; struct in6_addr *nexthop; struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); int count = atomic_read(&dev->peer_count); @@ -174,9 +189,13 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, * send the packet. If only one peer exists, then we can send the * packet right away. */ - if (count == 1) - return list_first_entry(&dev->peers, struct lowpan_peer, - list); + if (count == 1) { + rcu_read_lock(); + peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer, + list); + rcu_read_unlock(); + return peer; + } if (!rt) { nexthop = &lowpan_cb(skb)->gw; @@ -195,53 +214,57 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, BT_DBG("gw %pI6c", nexthop); - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + rcu_read_lock(); + + list_for_each_entry_rcu(peer, &dev->peers, list) { BT_DBG("dst addr %pMR dst type %d ip %pI6c", &peer->chan->dst, peer->chan->dst_type, &peer->peer_addr); - if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) + if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) { + rcu_read_unlock(); return peer; + } } + rcu_read_unlock(); + return NULL; } static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_peer *peer = NULL; - unsigned long flags; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { - peer = peer_lookup_conn(entry, conn); + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + peer = __peer_lookup_conn(entry, conn); if (peer) break; } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return peer; } static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_dev *dev = NULL; - unsigned long flags; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { if (conn->hcon->hdev == entry->hdev) { dev = entry; break; } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return dev; } @@ -264,13 +287,12 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, u8 iphc0, iphc1; struct lowpan_dev *dev; struct lowpan_peer *peer; - unsigned long flags; dev = lowpan_dev(netdev); - read_lock_irqsave(&devices_lock, flags); - peer = peer_lookup_chan(dev, chan); - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_lock(); + peer = __peer_lookup_chan(dev, chan); + rcu_read_unlock(); if (!peer) goto drop; @@ -452,7 +474,6 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, if (ipv6_addr_is_multicast(&ipv6_daddr)) { lowpan_cb(skb)->chan = NULL; } else { - unsigned long flags; u8 addr_type; /* Get destination BT device from skb. @@ -463,19 +484,14 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, BT_DBG("dest addr %pMR type %d IP %pI6c", &addr, addr_type, &ipv6_daddr); - read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); - read_unlock_irqrestore(&devices_lock, flags); - if (!peer) { /* The packet might be sent to 6lowpan interface * because of routing (either via default route * or user set route) so get peer according to * the destination address. */ - read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_dst(dev, &ipv6_daddr, skb); - read_unlock_irqrestore(&devices_lock, flags); if (!peer) { BT_DBG("no such peer %pMR found", &addr); return -ENOENT; @@ -558,14 +574,13 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) { struct sk_buff *local_skb; - struct lowpan_dev *entry, *tmp; - unsigned long flags; + struct lowpan_dev *entry; int err = 0; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { - struct lowpan_peer *pentry, *ptmp; + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + struct lowpan_peer *pentry; struct lowpan_dev *dev; if (entry->netdev != netdev) @@ -573,7 +588,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) dev = lowpan_dev(entry->netdev); - list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { + list_for_each_entry_rcu(pentry, &dev->peers, list) { int ret; local_skb = skb_clone(skb, GFP_ATOMIC); @@ -590,7 +605,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return err; } @@ -792,7 +807,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, struct lowpan_dev *dev) { struct lowpan_peer *peer; - unsigned long flags; peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -815,10 +829,10 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, */ set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8); - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); INIT_LIST_HEAD(&peer->list); peer_add(dev, peer); - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); /* Notifying peers about us needs to be done without locks held */ INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers); @@ -831,7 +845,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) { struct net_device *netdev; int err = 0; - unsigned long flags; netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN, netdev_setup); @@ -861,10 +874,10 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) (*dev)->hdev = chan->conn->hcon->hdev; INIT_LIST_HEAD(&(*dev)->peers); - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); INIT_LIST_HEAD(&(*dev)->list); - list_add(&(*dev)->list, &bt_6lowpan_devices); - write_unlock_irqrestore(&devices_lock, flags); + list_add_rcu(&(*dev)->list, &bt_6lowpan_devices); + spin_unlock(&devices_lock); return 0; @@ -918,11 +931,10 @@ static void delete_netdev(struct work_struct *work) static void chan_close_cb(struct l2cap_chan *chan) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_dev *dev = NULL; struct lowpan_peer *peer; int err = -ENOENT; - unsigned long flags; bool last = false, removed = true; BT_DBG("chan %p conn %p", chan, chan->conn); @@ -937,11 +949,11 @@ static void chan_close_cb(struct l2cap_chan *chan) removed = false; } - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { dev = lowpan_dev(entry->netdev); - peer = peer_lookup_chan(dev, chan); + peer = __peer_lookup_chan(dev, chan); if (peer) { last = peer_del(dev, peer); err = 0; @@ -952,13 +964,12 @@ static void chan_close_cb(struct l2cap_chan *chan) atomic_read(&chan->kref.refcount)); l2cap_chan_put(chan); - kfree(peer); break; } } if (!err && last && dev && !atomic_read(&dev->peer_count)) { - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); cancel_delayed_work_sync(&dev->notify_peers); @@ -969,7 +980,7 @@ static void chan_close_cb(struct l2cap_chan *chan) schedule_work(&entry->delete_netdev); } } else { - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); } return; @@ -1161,10 +1172,9 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, static void disconnect_all_peers(void) { - struct lowpan_dev *entry, *tmp_dev; + struct lowpan_dev *entry; struct lowpan_peer *peer, *tmp_peer, *new_peer; struct list_head peers; - unsigned long flags; INIT_LIST_HEAD(&peers); @@ -1173,10 +1183,10 @@ static void disconnect_all_peers(void) * with the same list at the same time. */ - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { - list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(peer, &entry->peers, list) { new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC); if (!new_peer) break; @@ -1188,26 +1198,36 @@ static void disconnect_all_peers(void) } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); + spin_lock(&devices_lock); list_for_each_entry_safe(peer, tmp_peer, &peers, list) { l2cap_chan_close(peer->chan, ENOENT); - kfree(peer); + + list_del_rcu(&peer->list); + call_rcu(&peer->rcu, peer_free); + + module_put(THIS_MODULE); } + spin_unlock(&devices_lock); } -static int lowpan_psm_set(void *data, u64 val) -{ +struct set_psm { + struct work_struct work; u16 psm; +}; - psm = val; - if (psm == 0 || psm_6lowpan != psm) +static void do_psm_set(struct work_struct *work) +{ + struct set_psm *set_psm = container_of(work, struct set_psm, work); + + if (set_psm->psm == 0 || psm_6lowpan != set_psm->psm) /* Disconnect existing connections if 6lowpan is * disabled (psm = 0), or if psm changes. */ disconnect_all_peers(); - psm_6lowpan = psm; + psm_6lowpan = set_psm->psm; if (listen_chan) { l2cap_chan_close(listen_chan, 0); @@ -1216,6 +1236,22 @@ static int lowpan_psm_set(void *data, u64 val) listen_chan = bt_6lowpan_listen(); + kfree(set_psm); +} + +static int lowpan_psm_set(void *data, u64 val) +{ + struct set_psm *set_psm; + + set_psm = kzalloc(sizeof(*set_psm), GFP_KERNEL); + if (!set_psm) + return -ENOMEM; + + set_psm->psm = val; + INIT_WORK(&set_psm->work, do_psm_set); + + schedule_work(&set_psm->work); + return 0; } @@ -1297,19 +1333,18 @@ static ssize_t lowpan_control_write(struct file *fp, static int lowpan_control_show(struct seq_file *f, void *ptr) { - struct lowpan_dev *entry, *tmp_dev; - struct lowpan_peer *peer, *tmp_peer; - unsigned long flags; + struct lowpan_dev *entry; + struct lowpan_peer *peer; - read_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); - list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { - list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) + list_for_each_entry(entry, &bt_6lowpan_devices, list) { + list_for_each_entry(peer, &entry->peers, list) seq_printf(f, "%pMR (type %u)\n", &peer->chan->dst, peer->chan->dst_type); } - read_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); return 0; } @@ -1329,9 +1364,8 @@ static const struct file_operations lowpan_control_fops = { static void disconnect_devices(void) { - struct lowpan_dev *entry, *tmp, *new_dev; + struct lowpan_dev *entry, *new_dev; struct list_head devices; - unsigned long flags; INIT_LIST_HEAD(&devices); @@ -1340,9 +1374,9 @@ static void disconnect_devices(void) * devices list. */ - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC); if (!new_dev) break; @@ -1350,12 +1384,12 @@ static void disconnect_devices(void) new_dev->netdev = entry->netdev; INIT_LIST_HEAD(&new_dev->list); - list_add(&new_dev->list, &devices); + list_add_rcu(&new_dev->list, &devices); } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); - list_for_each_entry_safe(entry, tmp, &devices, list) { + list_for_each_entry(entry, &devices, list) { ifdown(entry->netdev); BT_DBG("Unregistering netdev %s %p", entry->netdev->name, entry->netdev); @@ -1368,17 +1402,15 @@ static int device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *netdev = netdev_notifier_info_to_dev(ptr); - struct lowpan_dev *entry, *tmp; - unsigned long flags; + struct lowpan_dev *entry; if (netdev->type != ARPHRD_6LOWPAN) return NOTIFY_DONE; switch (event) { case NETDEV_UNREGISTER: - write_lock_irqsave(&devices_lock, flags); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, - list) { + spin_lock(&devices_lock); + list_for_each_entry(entry, &bt_6lowpan_devices, list) { if (entry->netdev == netdev) { BT_DBG("Unregistered netdev %s %p", netdev->name, netdev); @@ -1387,7 +1419,7 @@ static int device_event(struct notifier_block *unused, break; } } - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); break; } -- cgit v1.2.3 From df092306d688438b39f7d433f24e091fa387afaf Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 28 Oct 2014 17:16:48 +0200 Subject: Bluetooth: 6lowpan: Fix lockdep splats When a device ndo_start_xmit() calls again dev_queue_xmit(), lockdep can complain because dev_queue_xmit() is re-entered and the spinlocks protecting tx queues share a common lockdep class. Same issue was fixed for ieee802154 in commit "20e7c4e80dcd" Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index a681247b0aee..7254bddaca2f 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -662,7 +662,26 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) return err < 0 ? NET_XMIT_DROP : err; } +static struct lock_class_key bt_tx_busylock; +static struct lock_class_key bt_netdev_xmit_lock_key; + +static void bt_set_lockdep_class_one(struct net_device *dev, + struct netdev_queue *txq, + void *_unused) +{ + lockdep_set_class(&txq->_xmit_lock, &bt_netdev_xmit_lock_key); +} + +static int bt_dev_init(struct net_device *dev) +{ + netdev_for_each_tx_queue(dev, bt_set_lockdep_class_one, NULL); + dev->qdisc_tx_busylock = &bt_tx_busylock; + + return 0; +} + static const struct net_device_ops netdev_ops = { + .ndo_init = bt_dev_init, .ndo_start_xmit = bt_xmit, }; -- cgit v1.2.3 From 49c922bb1ec01ac3a98e5881f6c85ea7ef52d53f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Oct 2014 21:12:20 -0700 Subject: Bluetooth: spelling fixes Fix spelling errors in comments. Signed-off-by: Stephen Hemminger Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 6 +++--- net/bluetooth/hci_event.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/l2cap_core.c | 2 +- net/bluetooth/smp.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cb05d7f16a34..ddf33900f7f3 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4477,7 +4477,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete) BT_DBG("length %u", skb_queue_len(&req->cmd_q)); - /* If an error occured during request building, remove all HCI + /* If an error occurred during request building, remove all HCI * commands queued on the HCI request queue. */ if (req->err) { @@ -4546,7 +4546,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, return -ENOMEM; } - /* Stand-alone HCI commands must be flaged as + /* Stand-alone HCI commands must be flagged as * single-command requests. */ bt_cb(skb)->req.start = true; @@ -4566,7 +4566,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); - /* If an error occured during request building, there is no point in + /* If an error occurred during request building, there is no point in * queueing the HCI command. We can simply return. */ if (req->err) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 96291530606d..f5704bae67a2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1045,7 +1045,7 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - /* If we're doing connection initation as peripheral. Set a + /* If we're doing connection initiation as peripheral. Set a * timeout in case something goes wrong. */ if (*sent) { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 115f149362ba..bbc4ac748263 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -987,7 +987,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, skb_queue_tail(&hdev->raw_q, skb); queue_work(hdev->workqueue, &hdev->tx_work); } else { - /* Stand-alone HCI commands must be flaged as + /* Stand-alone HCI commands must be flagged as * single-command requests. */ bt_cb(skb)->req.start = true; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d46c5127f6c3..fc15174c612c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4082,7 +4082,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, chan->num_conf_req++; } - /* Got Conf Rsp PENDING from remote side and asume we sent + /* Got Conf Rsp PENDING from remote side and assume we sent Conf Rsp PENDING in the code above */ if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fea3782989f4..3ebf65b50881 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -964,7 +964,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) if (sec_level > conn->hcon->pending_sec_level) conn->hcon->pending_sec_level = sec_level; - /* If we need MITM check that it can be acheived */ + /* If we need MITM check that it can be achieved */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; @@ -1022,7 +1022,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) auth = rsp->auth_req & AUTH_REQ_MASK; - /* If we need MITM check that it can be acheived */ + /* If we need MITM check that it can be achieved */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; -- cgit v1.2.3 From 980ffc0a2cec2c37589cc97993e1ad17252f4f47 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 22:23:26 +0100 Subject: Bluetooth: Fix LE connection timeout deadlock The le_conn_timeout() may call hci_le_conn_failed() which in turn may call hci_conn_del(). Trying to use the _sync variant for cancelling the conn timeout from hci_conn_del() could therefore result in a deadlock. This patch converts hci_conn_del() to use the non-sync variant so the deadlock is not possible. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 3.16.x --- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6a3225bf7bac..74b8e2421e96 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -518,7 +518,7 @@ int hci_conn_del(struct hci_conn *conn) /* Unacked frames */ hdev->acl_cnt += conn->sent; } else if (conn->type == LE_LINK) { - cancel_delayed_work_sync(&conn->le_conn_timeout); + cancel_delayed_work(&conn->le_conn_timeout); if (hdev->le_pkts) hdev->le_cnt += conn->sent; -- cgit v1.2.3 From 0b1db38ca26b322296cbd141f3080eccfe1cc3e1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 22:23:27 +0100 Subject: Bluetooth: Fix check for direct advertising These days we allow simultaneous LE scanning and advertising. Checking for whether advertising is enabled or not is therefore not a reliable way to determine whether directed advertising was used to trigger the connection creation. The appropriate place to check (instead of the hdev context) is the connection role that's stored in the hci_conn. This patch fixes such a check in le_conn_timeout() which could otherwise lead to incorrect HCI commands being sent. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 3.16.x --- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 74b8e2421e96..96887ae8375b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -416,7 +416,7 @@ static void le_conn_timeout(struct work_struct *work) * happen with broken hardware or if low duty cycle was used * (which doesn't have a timeout of its own). */ - if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) { + if (conn->role == HCI_ROLE_SLAVE) { u8 enable = 0x00; hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable); -- cgit v1.2.3 From b9ff77e50c6e469db63dfc8fcc62586522649cd3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:16 +0100 Subject: mac802154: monitor: merge into iface implementation This patch removes the monitor implementation file and put all monitor stuff into iface file. It's now small enough to put all necessary handling into iface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/iface.c | 30 +++++++++++++++++++++++++ net/mac802154/monitor.c | 59 ------------------------------------------------- 3 files changed, 31 insertions(+), 60 deletions(-) delete mode 100644 net/mac802154/monitor.c (limited to 'net') diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index e68debaf2a59..2e497d0c829a 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o iface.o llsec.o util.o + iface.o llsec.o util.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 7e4bffcbcd4d..dafb2c3ac109 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -320,6 +320,12 @@ static const struct net_device_ops mac802154_wpan_ops = { .ndo_set_mac_address = mac802154_wpan_mac_addr, }; +static const struct net_device_ops mac802154_monitor_ops = { + .ndo_open = mac802154_slave_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = ieee802154_monitor_start_xmit, +}; + static void mac802154_wpan_free(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); @@ -373,3 +379,27 @@ void mac802154_wpan_setup(struct net_device *dev) mac802154_llsec_init(&sdata->sec); } + +void mac802154_monitor_setup(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata; + + dev->addr_len = 0; + dev->hard_header_len = 0; + dev->needed_tailroom = 2; /* room for FCS */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 10; + dev->type = ARPHRD_IEEE802154_MONITOR; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = free_netdev; + dev->netdev_ops = &mac802154_monitor_ops; + dev->ml_priv = &mac802154_mlme_reduced; + + sdata = IEEE802154_DEV_TO_SUB_IF(dev); + sdata->type = IEEE802154_DEV_MONITOR; + + sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ + sdata->page = 0; +} diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c deleted file mode 100644 index dfdedc206c6a..000000000000 --- a/net/mac802154/monitor.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "ieee802154_i.h" - -static const struct net_device_ops mac802154_monitor_ops = { - .ndo_open = mac802154_slave_open, - .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = ieee802154_monitor_start_xmit, -}; - -void mac802154_monitor_setup(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - - dev->addr_len = 0; - dev->hard_header_len = 0; - dev->needed_tailroom = 2; /* room for FCS */ - dev->mtu = IEEE802154_MTU; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154_MONITOR; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; - - dev->destructor = free_netdev; - dev->netdev_ops = &mac802154_monitor_ops; - dev->ml_priv = &mac802154_mlme_reduced; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - sdata->type = IEEE802154_DEV_MONITOR; - - sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ - sdata->page = 0; -} -- cgit v1.2.3 From 19ec690a431d8ebf3e9d939160dc223ad40d7d63 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:17 +0100 Subject: mac802154: main: move open and close into iface These functions can be static inside the iface file, because it's not used anywhere else. This patch moves these functions into iface file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 --- net/mac802154/iface.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ net/mac802154/main.c | 59 -------------------------------------------- 3 files changed, 59 insertions(+), 62 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index ac907d943bae..4408c463af35 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -123,9 +123,6 @@ IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; -int mac802154_slave_open(struct net_device *dev); -int mac802154_slave_close(struct net_device *dev); - void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index dafb2c3ac109..0b21413081f1 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -142,6 +142,46 @@ void mac802154_get_mac_params(struct net_device *dev, mutex_unlock(&sdata->local->iflist_mtx); } +static int mac802154_slave_open(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_sub_if_data *subif; + struct ieee802154_local *local = sdata->local; + int res = 0; + + ASSERT_RTNL(); + + if (sdata->type == IEEE802154_DEV_WPAN) { + mutex_lock(&sdata->local->iflist_mtx); + list_for_each_entry(subif, &sdata->local->interfaces, list) { + if (subif != sdata && subif->type == sdata->type && + subif->running) { + mutex_unlock(&sdata->local->iflist_mtx); + return -EBUSY; + } + } + mutex_unlock(&sdata->local->iflist_mtx); + } + + mutex_lock(&sdata->local->iflist_mtx); + sdata->running = true; + mutex_unlock(&sdata->local->iflist_mtx); + + if (local->open_count++ == 0) { + res = local->ops->start(&local->hw); + WARN_ON(res); + if (res) + goto err; + } + + netif_start_queue(dev); + return 0; +err: + sdata->local->open_count--; + + return res; +} + static int mac802154_wpan_open(struct net_device *dev) { int rc; @@ -201,6 +241,25 @@ out: return rc; } +static int mac802154_slave_close(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_local *local = sdata->local; + + ASSERT_RTNL(); + + netif_stop_queue(dev); + + mutex_lock(&sdata->local->iflist_mtx); + sdata->running = false; + mutex_unlock(&sdata->local->iflist_mtx); + + if (!--local->open_count) + local->ops->stop(&local->hw); + + return 0; +} + static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata, struct ieee802154_hdr *hdr, const struct ieee802154_mac_cb *cb) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index ff0de0f990cb..2c6d77259822 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -29,65 +29,6 @@ #include "ieee802154_i.h" -int mac802154_slave_open(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct ieee802154_sub_if_data *subif; - struct ieee802154_local *local = sdata->local; - int res = 0; - - ASSERT_RTNL(); - - if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->local->iflist_mtx); - list_for_each_entry(subif, &sdata->local->interfaces, list) { - if (subif != sdata && subif->type == sdata->type && - subif->running) { - mutex_unlock(&sdata->local->iflist_mtx); - return -EBUSY; - } - } - mutex_unlock(&sdata->local->iflist_mtx); - } - - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = true; - mutex_unlock(&sdata->local->iflist_mtx); - - if (local->open_count++ == 0) { - res = local->ops->start(&local->hw); - WARN_ON(res); - if (res) - goto err; - } - - netif_start_queue(dev); - return 0; -err: - sdata->local->open_count--; - - return res; -} - -int mac802154_slave_close(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct ieee802154_local *local = sdata->local; - - ASSERT_RTNL(); - - netif_stop_queue(dev); - - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = false; - mutex_unlock(&sdata->local->iflist_mtx); - - if (!--local->open_count) - local->ops->stop(&local->hw); - - return 0; -} - static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { -- cgit v1.2.3 From 16301861004e50be9c47113cceca62f56516a9a2 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:18 +0100 Subject: mac802154: declare struct ieee802154_ops as const The ieee802154_ops structure should be never changed during runtime. This patch declare this structure as const to avoid a runtime change. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 2 +- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index a1558385bac9..662efd3e07b9 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1214,7 +1214,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) return rc; } -static struct ieee802154_ops at86rf230_ops = { +static const struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, .xmit_async = at86rf230_xmit, .ed = at86rf230_ed, diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index a31b5b62a353..b479c9d560f8 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -631,7 +631,7 @@ cc2520_filter(struct ieee802154_hw *hw, return 0; } -static struct ieee802154_ops cc2520_ops = { +static const struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, .stop = cc2520_stop, diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index db0703f0fa41..2a97cbb3aa01 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -129,7 +129,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) { spin_unlock(&priv->lock); } -static struct ieee802154_ops fakelb_ops = { +static const struct ieee802154_ops fakelb_ops = { .owner = THIS_MODULE, .xmit_sync = fakelb_hw_xmit, .ed = fakelb_hw_ed, diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 7abb237cb989..f19cf588de2e 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -579,7 +579,7 @@ out: return ret; } -static struct ieee802154_ops mrf24j40_ops = { +static const struct ieee802154_ops mrf24j40_ops = { .owner = THIS_MODULE, .xmit_sync = mrf24j40_tx, .ed = mrf24j40_ed, diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 4c4642ef244f..0ea44cda2920 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -197,7 +197,7 @@ struct ieee802154_ops { /* Basic interface to register ieee802154 hwice */ struct ieee802154_hw * -ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops); +ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); void ieee802154_free_hw(struct ieee802154_hw *hw); int ieee802154_register_hw(struct ieee802154_hw *hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw); diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4408c463af35..a379b971b13c 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -28,7 +28,7 @@ /* mac802154 device private data */ struct ieee802154_local { struct ieee802154_hw hw; - struct ieee802154_ops *ops; + const struct ieee802154_ops *ops; /* ieee802154 phy */ struct wpan_phy *phy; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 2c6d77259822..632707bc47b9 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -187,7 +187,7 @@ static void ieee802154_tasklet_handler(unsigned long data) } struct ieee802154_hw * -ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) +ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) { struct wpan_phy *phy; struct ieee802154_local *local; -- cgit v1.2.3 From b6eea9ca354aeb80d358ff52d046bb8a26bd2b17 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:20 +0100 Subject: mac802154: introduce driver-ops header This patch introduce a driver-ops header file with function wrappers to call the driver ops. These wrappers checking on right context information and warn if optional driver ops are called when these aren't implemented. This behaviour is like mac80211 driver-ops header file, just without function tracing calls. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 202 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 net/mac802154/driver-ops.h (limited to 'net') diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h new file mode 100644 index 000000000000..bf7980bbceff --- /dev/null +++ b/net/mac802154/driver-ops.h @@ -0,0 +1,202 @@ +#ifndef __MAC802154_DRVIER_OPS +#define __MAC802154_DRIVER_OPS + +#include +#include + +#include + +#include "ieee802154_i.h" + +static inline int +drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) +{ + return local->ops->xmit_async(&local->hw, skb); +} + +static inline int +drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) +{ + /* don't allow other operations while sync xmit */ + ASSERT_RTNL(); + + might_sleep(); + + return local->ops->xmit_sync(&local->hw, skb); +} + +static inline int drv_start(struct ieee802154_local *local) +{ + might_sleep(); + + return local->ops->start(&local->hw); +} + +static inline void drv_stop(struct ieee802154_local *local) +{ + might_sleep(); + + local->ops->stop(&local->hw); +} + +static inline int drv_set_channel(struct ieee802154_local *local, + const u8 page, const u8 channel) +{ + might_sleep(); + + return local->ops->set_channel(&local->hw, page, channel); +} + +static inline int drv_set_tx_power(struct ieee802154_local *local, + const s8 dbm) +{ + might_sleep(); + + if (!local->ops->set_txpower) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_txpower(&local->hw, dbm); +} + +static inline int drv_set_cca_mode(struct ieee802154_local *local, + const u8 cca_mode) +{ + might_sleep(); + + if (!local->ops->set_cca_mode) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_cca_mode(&local->hw, cca_mode); +} + +static inline int drv_set_lbt_mode(struct ieee802154_local *local, + const bool mode) +{ + might_sleep(); + + if (!local->ops->set_lbt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_lbt(&local->hw, mode); +} + +static inline int drv_set_cca_ed_level(struct ieee802154_local *local, + const s32 ed_level) +{ + might_sleep(); + + if (!local->ops->set_cca_ed_level) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_cca_ed_level(&local->hw, ed_level); +} + +static inline int drv_set_pan_id(struct ieee802154_local *local, + const __le16 pan_id) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.pan_id = pan_id; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_PANID_CHANGED); +} + +static inline int drv_set_extended_addr(struct ieee802154_local *local, + const __le64 extended_addr) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.ieee_addr = extended_addr; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_IEEEADDR_CHANGED); +} + +static inline int drv_set_short_addr(struct ieee802154_local *local, + const __le16 short_addr) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.short_addr = short_addr; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_SADDR_CHANGED); +} + +static inline int drv_set_pan_coord(struct ieee802154_local *local, + const bool is_coord) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.pan_coord = is_coord; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_PANC_CHANGED); +} + +static inline int drv_set_csma_params(struct ieee802154_local *local, + u8 min_be, u8 max_be, + u8 max_csma_backoffs) +{ + might_sleep(); + + if (!local->ops->set_csma_params) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_csma_params(&local->hw, min_be, max_be, + max_csma_backoffs); +} + +static inline int drv_set_max_frame_retries(struct ieee802154_local *local, + s8 max_frame_retries) +{ + might_sleep(); + + if (!local->ops->set_frame_retries) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_frame_retries(&local->hw, max_frame_retries); +} + +#endif /* __MAC802154_DRVIER_OPS */ -- cgit v1.2.3 From 59cb300f2b2ce1fc46696deb9a7bd066cd53a65a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:21 +0100 Subject: mac802154: use driver-ops function wrappers This patch replaces all directly called driver ops by previous introduced driver-ops function wrappers. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 25 ++++++++++++++----------- net/mac802154/main.c | 13 +++++++------ net/mac802154/mib.c | 3 ++- net/mac802154/tx.c | 5 +++-- 4 files changed, 26 insertions(+), 20 deletions(-) (limited to 'net') diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 0b21413081f1..025cd5aba13f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -30,6 +30,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" static int mac802154_wpan_update_llsec(struct net_device *dev) { @@ -168,7 +169,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); if (local->open_count++ == 0) { - res = local->ops->start(&local->hw); + res = drv_start(local); WARN_ON(res); if (res) goto err; @@ -186,6 +187,7 @@ static int mac802154_wpan_open(struct net_device *dev) { int rc; struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_local *local = sdata->local; struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); @@ -195,40 +197,41 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); if (phy->set_txpower) { - rc = phy->set_txpower(phy, sdata->mac_params.transmit_power); + rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) goto out; } if (phy->set_lbt) { - rc = phy->set_lbt(phy, sdata->mac_params.lbt); + rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); if (rc < 0) goto out; } if (phy->set_cca_mode) { - rc = phy->set_cca_mode(phy, sdata->mac_params.cca_mode); + rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode); if (rc < 0) goto out; } if (phy->set_cca_ed_level) { - rc = phy->set_cca_ed_level(phy, sdata->mac_params.cca_ed_level); + rc = drv_set_cca_ed_level(local, + sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } if (phy->set_csma_params) { - rc = phy->set_csma_params(phy, sdata->mac_params.min_be, - sdata->mac_params.max_be, - sdata->mac_params.csma_retries); + rc = drv_set_csma_params(local, sdata->mac_params.min_be, + sdata->mac_params.max_be, + sdata->mac_params.csma_retries); if (rc < 0) goto out; } if (phy->set_frame_retries) { - rc = phy->set_frame_retries(phy, - sdata->mac_params.frame_retries); + rc = drv_set_max_frame_retries(local, + sdata->mac_params.frame_retries); if (rc < 0) goto out; } @@ -255,7 +258,7 @@ static int mac802154_slave_close(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); if (!--local->open_count) - local->ops->stop(&local->hw); + drv_stop(local); return 0; } diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 632707bc47b9..24ecc09de2a4 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) @@ -124,28 +125,28 @@ static int mac802154_set_txpower(struct wpan_phy *phy, int db) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_txpower(&local->hw, db); + return drv_set_tx_power(local, db); } static int mac802154_set_lbt(struct wpan_phy *phy, bool on) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_lbt(&local->hw, on); + return drv_set_lbt_mode(local, on); } static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_cca_mode(&local->hw, mode); + return drv_set_cca_mode(local, mode); } static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_cca_ed_level(&local->hw, level); + return drv_set_cca_ed_level(local, level); } static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, @@ -153,14 +154,14 @@ static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_csma_params(&local->hw, min_be, max_be, retries); + return drv_set_csma_params(local, min_be, max_be, retries); } static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_frame_retries(&local->hw, retries); + return drv_set_max_frame_retries(local, retries); } static void ieee802154_tasklet_handler(unsigned long data) diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 16baff1ea313..3fbc217dbdcc 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -24,6 +24,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" struct phy_chan_notify_work { struct work_struct work; @@ -170,7 +171,7 @@ static void phy_chan_notify(struct work_struct *work) int res; mutex_lock(&sdata->local->phy->pib_lock); - res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); + res = drv_set_channel(local, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index e85767355c48..77973a84e9a2 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. @@ -55,7 +56,7 @@ static void ieee802154_xmit_worker(struct work_struct *work) if (!netif_running(dev)) goto err_tx; - res = local->ops->xmit_sync(&local->hw, skb); + res = drv_xmit_sync(local, skb); if (res) goto err_tx; @@ -96,7 +97,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) /* async is priority, otherwise sync is fallback */ if (local->ops->xmit_async) { - ret = local->ops->xmit_async(&local->hw, skb); + ret = drv_xmit_async(local, skb); if (ret) { ieee802154_wake_queue(&local->hw); goto err_tx; -- cgit v1.2.3 From a543c5989d7711d984608f4e12a73218642ca865 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:23 +0100 Subject: mac802154: remove driver ops in wpan-phy This patch removes the driver ops callbacks inside of wpan_phy struct. It was used to check if a phy supports this driver ops call. We do this now via hardware flags. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 8 ----- net/ieee802154/nl-mac.c | 19 ++--------- net/mac802154/iface.c | 12 +++---- net/mac802154/main.c | 85 ------------------------------------------------- 4 files changed, 8 insertions(+), 116 deletions(-) (limited to 'net') diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 5c674673ef20..440b9bece9c6 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -57,14 +57,6 @@ struct wpan_phy { const char *name, int type); void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); - int (*set_txpower)(struct wpan_phy *phy, int db); - int (*set_lbt)(struct wpan_phy *phy, bool on); - int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); - int (*set_cca_ed_level)(struct wpan_phy *phy, int level); - int (*set_csma_params)(struct wpan_phy *phy, u8 min_be, u8 max_be, - u8 retries); - int (*set_frame_retries)(struct wpan_phy *phy, s8 retries); - char priv[0] __aligned(NETDEV_ALIGN); }; diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index fb6866d1dd39..abd0f31bdc66 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -664,20 +664,6 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) phy = ops->get_phy(dev); - if ((!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) || - (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) || - (!phy->set_cca_ed_level && - info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) || - (!phy->set_csma_params && - (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] || - info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] || - info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])) || - (!phy->set_frame_retries && - info->attrs[IEEE802154_ATTR_FRAME_RETRIES])) { - rc = -EOPNOTSUPP; - goto out_phy; - } - ops->get_mac_params(dev, ¶ms); if (info->attrs[IEEE802154_ATTR_TXPOWER]) @@ -708,10 +694,9 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) wpan_phy_put(phy); dev_put(dev); - return rc; -out_phy: - wpan_phy_put(phy); + return 0; + out: dev_put(dev); return rc; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 025cd5aba13f..300877a1a0c9 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -196,32 +196,32 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); - if (phy->set_txpower) { + if (local->hw.flags & IEEE802154_HW_TXPOWER) { rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) goto out; } - if (phy->set_lbt) { + if (local->hw.flags & IEEE802154_HW_LBT) { rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); if (rc < 0) goto out; } - if (phy->set_cca_mode) { + if (local->hw.flags & IEEE802154_HW_CCA_MODE) { rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode); if (rc < 0) goto out; } - if (phy->set_cca_ed_level) { + if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) { rc = drv_set_cca_ed_level(local, sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } - if (phy->set_csma_params) { + if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { rc = drv_set_csma_params(local, sdata->mac_params.min_be, sdata->mac_params.max_be, sdata->mac_params.csma_retries); @@ -229,7 +229,7 @@ static int mac802154_wpan_open(struct net_device *dev) goto out; } - if (phy->set_frame_retries) { + if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { rc = drv_set_max_frame_retries(local, sdata->mac_params.frame_retries); if (rc < 0) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 24ecc09de2a4..9fa9514b3a36 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -121,49 +121,6 @@ err: return ERR_PTR(err); } -static int mac802154_set_txpower(struct wpan_phy *phy, int db) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_tx_power(local, db); -} - -static int mac802154_set_lbt(struct wpan_phy *phy, bool on) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_lbt_mode(local, on); -} - -static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_cca_mode(local, mode); -} - -static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_cca_ed_level(local, level); -} - -static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, - u8 max_be, u8 retries) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_csma_params(local, min_be, max_be, retries); -} - -static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_max_frame_retries(local, retries); -} - static void ieee802154_tasklet_handler(unsigned long data) { struct ieee802154_local *local = (struct ieee802154_local *)data; @@ -262,48 +219,6 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); int rc = -ENOSYS; - if (hw->flags & IEEE802154_HW_TXPOWER) { - if (!local->ops->set_txpower) - goto out; - - local->phy->set_txpower = mac802154_set_txpower; - } - - if (hw->flags & IEEE802154_HW_LBT) { - if (!local->ops->set_lbt) - goto out; - - local->phy->set_lbt = mac802154_set_lbt; - } - - if (hw->flags & IEEE802154_HW_CCA_MODE) { - if (!local->ops->set_cca_mode) - goto out; - - local->phy->set_cca_mode = mac802154_set_cca_mode; - } - - if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { - if (!local->ops->set_cca_ed_level) - goto out; - - local->phy->set_cca_ed_level = mac802154_set_cca_ed_level; - } - - if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { - if (!local->ops->set_csma_params) - goto out; - - local->phy->set_csma_params = mac802154_set_csma_params; - } - - if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { - if (!local->ops->set_frame_retries) - goto out; - - local->phy->set_frame_retries = mac802154_set_frame_retries; - } - local->workqueue = create_singlethread_workqueue(wpan_phy_name(local->phy)); if (!local->workqueue) { -- cgit v1.2.3 From 0ea3da64fa602efa0a89502eefdb396be84d2eba Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:24 +0100 Subject: mac802154: rework sdata state change to running This patch reworks the handling for setting the state like mac80211. We use bit's instead a bool variable. The mutex is not needed because it use test and set bits which are atomic operations. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 12 +++++++++++- net/mac802154/iface.c | 12 +++++------- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index a379b971b13c..e34fe51043f2 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -67,6 +67,10 @@ enum { IEEE802154_RX_MSG = 1, }; +enum ieee802154_sdata_state_bits { + SDATA_STATE_RUNNING, +}; + /* Slave interface definition. * * Slaves represent typical network interfaces available from userspace. @@ -80,7 +84,7 @@ struct ieee802154_sub_if_data { struct net_device *dev; int type; - bool running; + unsigned long state; spinlock_t mib_lock; @@ -120,6 +124,12 @@ IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) return netdev_priv(dev); } +static inline bool +ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) +{ + return test_bit(SDATA_STATE_RUNNING, &sdata->state); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 300877a1a0c9..e10fd786a11f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -156,7 +156,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_lock(&sdata->local->iflist_mtx); list_for_each_entry(subif, &sdata->local->interfaces, list) { if (subif != sdata && subif->type == sdata->type && - subif->running) { + ieee802154_sdata_running(subif)) { mutex_unlock(&sdata->local->iflist_mtx); return -EBUSY; } @@ -164,9 +164,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); } - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = true; - mutex_unlock(&sdata->local->iflist_mtx); + set_bit(SDATA_STATE_RUNNING, &sdata->state); if (local->open_count++ == 0) { res = drv_start(local); @@ -178,6 +176,8 @@ static int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: + /* might already be clear but that doesn't matter */ + clear_bit(SDATA_STATE_RUNNING, &sdata->state); sdata->local->open_count--; return res; @@ -253,9 +253,7 @@ static int mac802154_slave_close(struct net_device *dev) netif_stop_queue(dev); - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = false; - mutex_unlock(&sdata->local->iflist_mtx); + clear_bit(SDATA_STATE_RUNNING, &sdata->state); if (!--local->open_count) drv_stop(local); -- cgit v1.2.3 From 5d65cae4bf6ffe29bba90f621e947922c5fb80db Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:25 +0100 Subject: mac802154: rename running to started This variable should be handled like ieee80211_local struct of mac80211. We rename this variable to started now to have the same name convention. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index e34fe51043f2..f52afd4ced92 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -54,7 +54,7 @@ struct ieee802154_local { * This flag should be modified under slaves_mtx and RTNL, so you can * read them using any of protection methods. */ - bool running; + bool started; struct tasklet_struct tasklet; struct sk_buff_head skb_queue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9fa9514b3a36..7458f71c151c 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -47,7 +47,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); mutex_lock(&local->iflist_mtx); - if (!local->running) { + if (!local->started) { mutex_unlock(&local->iflist_mtx); return -ENODEV; } @@ -238,7 +238,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); mutex_lock(&local->iflist_mtx); - local->running = MAC802154_DEVICE_RUN; + local->started = MAC802154_DEVICE_RUN; mutex_unlock(&local->iflist_mtx); rtnl_unlock(); @@ -264,7 +264,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); mutex_lock(&local->iflist_mtx); - local->running = MAC802154_DEVICE_STOPPED; + local->started = MAC802154_DEVICE_STOPPED; mutex_unlock(&local->iflist_mtx); list_for_each_entry_safe(sdata, next, &local->interfaces, list) { -- cgit v1.2.3 From e363eca386d0c28d8c6c4f176e1fa48b09a75315 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:26 +0100 Subject: mac802154: move local started handling This patch removes the current handling of started boolean. This is actually dead code, because mac802154_netdev_register can't never be called before ieee802154_register_hw. This means that local->started is always be true when mac802154_netdev_register is called. Instead we using this now like mac80211 to indicate that an instance of sdata is running. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 4 ++++ net/mac802154/ieee802154_i.h | 7 ------- net/mac802154/main.c | 19 ------------------- 3 files changed, 4 insertions(+), 26 deletions(-) (limited to 'net') diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index bf7980bbceff..bb3ee03c1669 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -29,6 +29,8 @@ static inline int drv_start(struct ieee802154_local *local) { might_sleep(); + local->started = true; + return local->ops->start(&local->hw); } @@ -37,6 +39,8 @@ static inline void drv_stop(struct ieee802154_local *local) might_sleep(); local->ops->stop(&local->hw); + + local->started = false; } static inline int drv_set_channel(struct ieee802154_local *local, diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index f52afd4ced92..bf0b5f613c36 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -50,19 +50,12 @@ struct ieee802154_local { */ struct workqueue_struct *workqueue; - /* SoftMAC device is registered and running. One can add subinterfaces. - * This flag should be modified under slaves_mtx and RTNL, so you can - * read them using any of protection methods. - */ bool started; struct tasklet_struct tasklet; struct sk_buff_head skb_queue; }; -#define MAC802154_DEVICE_STOPPED 0x00 -#define MAC802154_DEVICE_RUN 0x01 - enum { IEEE802154_RX_MSG = 1, }; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 7458f71c151c..21dcc56930d1 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -46,13 +46,6 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&local->iflist_mtx); - if (!local->started) { - mutex_unlock(&local->iflist_mtx); - return -ENODEV; - } - mutex_unlock(&local->iflist_mtx); - err = register_netdev(dev); if (err < 0) return err; @@ -235,14 +228,6 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) if (rc < 0) goto out_wq; - rtnl_lock(); - - mutex_lock(&local->iflist_mtx); - local->started = MAC802154_DEVICE_RUN; - mutex_unlock(&local->iflist_mtx); - - rtnl_unlock(); - return 0; out_wq: @@ -263,10 +248,6 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->iflist_mtx); - local->started = MAC802154_DEVICE_STOPPED; - mutex_unlock(&local->iflist_mtx); - list_for_each_entry_safe(sdata, next, &local->interfaces, list) { mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); -- cgit v1.2.3 From 538181a879368f54544b91e414ea56a88008782b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:27 +0100 Subject: mac802154: add synchronization handling This patch adds synchronization handling in start and stop driver ops calls. This patch is mostly grab from mac80211 which was introduced by commit ea77f12f2cc0f31168f2e0259e65a22202ac4dc2 ("mac80211: remove tasklet enable/disable"). This is to be sure that we don't run into same issues. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'net') diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index bb3ee03c1669..4b820cfeb538 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -30,6 +30,7 @@ static inline int drv_start(struct ieee802154_local *local) might_sleep(); local->started = true; + smp_mb(); return local->ops->start(&local->hw); } @@ -40,6 +41,12 @@ static inline void drv_stop(struct ieee802154_local *local) local->ops->stop(&local->hw); + /* sync away all work on the tasklet before clearing started */ + tasklet_disable(&local->tasklet); + tasklet_enable(&local->tasklet); + + barrier(); + local->started = false; } -- cgit v1.2.3 From 33d4189f51f0dbb522a4d81aafc7edb2e048c570 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:28 +0100 Subject: mac802154: iface: remove assign to zero These variables should already be zero, so we remove the extra assign to zero. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'net') diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index e10fd786a11f..2423aa7671df 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -409,7 +409,6 @@ void mac802154_wpan_setup(struct net_device *dev) dev->tx_queue_len = 300; dev->type = ARPHRD_IEEE802154; dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; dev->destructor = mac802154_wpan_free; dev->netdev_ops = &mac802154_wpan_ops; @@ -419,7 +418,6 @@ void mac802154_wpan_setup(struct net_device *dev) sdata->type = IEEE802154_DEV_WPAN; sdata->chan = MAC802154_CHAN_NONE; - sdata->page = 0; spin_lock_init(&sdata->mib_lock); mutex_init(&sdata->sec_mtx); @@ -444,14 +442,11 @@ void mac802154_monitor_setup(struct net_device *dev) { struct ieee802154_sub_if_data *sdata; - dev->addr_len = 0; - dev->hard_header_len = 0; dev->needed_tailroom = 2; /* room for FCS */ dev->mtu = IEEE802154_MTU; dev->tx_queue_len = 10; dev->type = ARPHRD_IEEE802154_MONITOR; dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; dev->destructor = free_netdev; dev->netdev_ops = &mac802154_monitor_ops; @@ -461,5 +456,4 @@ void mac802154_monitor_setup(struct net_device *dev) sdata->type = IEEE802154_DEV_MONITOR; sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ - sdata->page = 0; } -- cgit v1.2.3 From 12439a53560097bc8e42cf14967717d14588dddd Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:29 +0100 Subject: mac802154: remove channel attributes from sdata These channel attributes was part of "channel context switch while xmit" which was removed by commit dc67c6b30f36d57b70b70547a30e7a8432540c6f ("mac802154: tx: remove xmit channel context switch"). This patch removes these unnecessary variables and use the current_page and current_channel by wpan_phy struct now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 --- net/mac802154/iface.c | 4 ---- net/mac802154/mib.c | 55 ++++++++------------------------------------ 3 files changed, 9 insertions(+), 53 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index bf0b5f613c36..46c9fe7ba2b2 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -85,9 +85,6 @@ struct ieee802154_sub_if_data { __le16 short_addr; __le64 extended_addr; - u8 chan; - u8 page; - struct ieee802154_mac_params mac_params; /* MAC BSN field */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 2423aa7671df..1c0274ed9370 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -417,8 +417,6 @@ void mac802154_wpan_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_WPAN; - sdata->chan = MAC802154_CHAN_NONE; - spin_lock_init(&sdata->mib_lock); mutex_init(&sdata->sec_mtx); @@ -454,6 +452,4 @@ void mac802154_monitor_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; - - sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ } diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 3fbc217dbdcc..0184fced2f62 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -26,11 +26,6 @@ #include "ieee802154_i.h" #include "driver-ops.h" -struct phy_chan_notify_work { - struct work_struct work; - struct net_device *dev; -}; - struct hw_addr_filt_notify_work { struct work_struct work; struct net_device *dev; @@ -161,54 +156,22 @@ u8 mac802154_dev_get_dsn(const struct net_device *dev) return sdata->dsn++; } -static void phy_chan_notify(struct work_struct *work) -{ - struct phy_chan_notify_work *nw = container_of(work, - struct phy_chan_notify_work, work); - struct net_device *dev = nw->dev; - struct ieee802154_local *local = mac802154_slave_get_priv(dev); - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - int res; - - mutex_lock(&sdata->local->phy->pib_lock); - res = drv_set_channel(local, sdata->page, sdata->chan); - if (res) { - pr_debug("set_channel failed\n"); - } else { - sdata->local->phy->current_channel = sdata->chan; - sdata->local->phy->current_page = sdata->page; - } - mutex_unlock(&sdata->local->phy->pib_lock); - - kfree(nw); -} - void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct phy_chan_notify_work *work; + struct ieee802154_local *local = sdata->local; + int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&sdata->mib_lock); - sdata->page = page; - sdata->chan = chan; - spin_unlock_bh(&sdata->mib_lock); - - mutex_lock(&sdata->local->phy->pib_lock); - if (sdata->local->phy->current_channel != sdata->chan || - sdata->local->phy->current_page != sdata->page) { - mutex_unlock(&sdata->local->phy->pib_lock); - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, phy_chan_notify); - work->dev = dev; - queue_work(sdata->local->workqueue, &work->work); + res = drv_set_channel(local, page, chan); + if (res) { + pr_debug("set_channel failed\n"); } else { - mutex_unlock(&sdata->local->phy->pib_lock); + mutex_lock(&local->phy->pib_lock); + local->phy->current_channel = chan; + local->phy->current_page = page; + mutex_unlock(&local->phy->pib_lock); } } -- cgit v1.2.3 From c7420c367d63a7e1414e010afb52c3837fd9134e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:30 +0100 Subject: mac802154: move mac_params functions into mac_cmd These functions can be static in mac_cmd file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 5 ----- net/mac802154/mac_cmd.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 46c9fe7ba2b2..7cebc9844c00 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -140,11 +140,6 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); u8 mac802154_dev_get_dsn(const struct net_device *dev); -int mac802154_set_mac_params(struct net_device *dev, - const struct ieee802154_mac_params *params); -void mac802154_get_mac_params(struct net_device *dev, - struct ieee802154_mac_params *params); - int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params); int mac802154_set_params(struct net_device *dev, diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index ed767f590ef9..fc261ab33347 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -82,6 +82,28 @@ static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) return to_phy(get_device(&sdata->local->phy->dev)); } +static int mac802154_set_mac_params(struct net_device *dev, + const struct ieee802154_mac_params *params) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + + mutex_lock(&sdata->local->iflist_mtx); + sdata->mac_params = *params; + mutex_unlock(&sdata->local->iflist_mtx); + + return 0; +} + +static void mac802154_get_mac_params(struct net_device *dev, + struct ieee802154_mac_params *params) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + + mutex_lock(&sdata->local->iflist_mtx); + *params = sdata->mac_params; + mutex_unlock(&sdata->local->iflist_mtx); +} + static struct ieee802154_llsec_ops mac802154_llsec_ops = { .get_params = mac802154_get_params, .set_params = mac802154_set_params, -- cgit v1.2.3 From 74457641558baded3c9f05bc3fb81293a2c02b2e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:31 +0100 Subject: mac802154: cleanup open count handling This patch cleanups the open_count variable increment in open and close calls of netdev. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 1c0274ed9370..c0bf5f9b9953 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -166,19 +166,19 @@ static int mac802154_slave_open(struct net_device *dev) set_bit(SDATA_STATE_RUNNING, &sdata->state); - if (local->open_count++ == 0) { + if (!local->open_count) { res = drv_start(local); WARN_ON(res); if (res) goto err; } + local->open_count++; netif_start_queue(dev); return 0; err: /* might already be clear but that doesn't matter */ clear_bit(SDATA_STATE_RUNNING, &sdata->state); - sdata->local->open_count--; return res; } @@ -252,10 +252,11 @@ static int mac802154_slave_close(struct net_device *dev) ASSERT_RTNL(); netif_stop_queue(dev); + local->open_count--; clear_bit(SDATA_STATE_RUNNING, &sdata->state); - if (!--local->open_count) + if (!local->open_count) drv_stop(local); return 0; -- cgit v1.2.3 From e23e9ec16bf4bbaf12fc030079b277cb00f618f4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:32 +0100 Subject: ieee802154: introduce sysfs file This patch moves the sysfs handling in a own file. This is like wireless sysfs file handling. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/Makefile | 2 +- net/ieee802154/core.c | 73 +++----------------------------------- net/ieee802154/sysfs.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ net/ieee802154/sysfs.h | 9 +++++ 4 files changed, 108 insertions(+), 70 deletions(-) create mode 100644 net/ieee802154/sysfs.c create mode 100644 net/ieee802154/sysfs.h (limited to 'net') diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index e58c4cbb3639..38354d4a70cb 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ - header_ops.o + header_ops.o sysfs.o af_802154-y := af_ieee802154.o raw.o dgram.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 760b7d752190..620abc2ba5fc 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -20,72 +20,7 @@ #include #include "ieee802154.h" - -#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ -static ssize_t name ## _show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ - int ret; \ - \ - mutex_lock(&phy->pib_lock); \ - ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ - mutex_unlock(&phy->pib_lock); \ - return ret; \ -} \ -static DEVICE_ATTR_RO(name) - -#define MASTER_SHOW(field, format_string) \ - MASTER_SHOW_COMPLEX(field, format_string, phy->field) - -MASTER_SHOW(current_channel, "%d"); -MASTER_SHOW(current_page, "%d"); -MASTER_SHOW(transmit_power, "%d +- 1 dB"); -MASTER_SHOW(cca_mode, "%d"); - -static ssize_t channels_supported_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); - int ret; - int i, len = 0; - - mutex_lock(&phy->pib_lock); - for (i = 0; i < 32; i++) { - ret = snprintf(buf + len, PAGE_SIZE - len, - "%#09x\n", phy->channels_supported[i]); - if (ret < 0) - break; - len += ret; - } - mutex_unlock(&phy->pib_lock); - return len; -} -static DEVICE_ATTR_RO(channels_supported); - -static struct attribute *pmib_attrs[] = { - &dev_attr_current_channel.attr, - &dev_attr_current_page.attr, - &dev_attr_channels_supported.attr, - &dev_attr_transmit_power.attr, - &dev_attr_cca_mode.attr, - NULL, -}; -ATTRIBUTE_GROUPS(pmib); - -static void wpan_phy_release(struct device *d) -{ - struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); - - kfree(phy); -} - -static struct class wpan_phy_class = { - .name = "ieee802154", - .dev_release = wpan_phy_release, - .dev_groups = pmib_groups, -}; +#include "sysfs.h" static DEFINE_MUTEX(wpan_phy_mutex); static int wpan_phy_idx; @@ -197,7 +132,7 @@ static int __init wpan_phy_class_init(void) { int rc; - rc = class_register(&wpan_phy_class); + rc = wpan_phy_sysfs_init(); if (rc) goto err; @@ -207,7 +142,7 @@ static int __init wpan_phy_class_init(void) return 0; err_nl: - class_unregister(&wpan_phy_class); + wpan_phy_sysfs_exit(); err: return rc; } @@ -216,7 +151,7 @@ subsys_initcall(wpan_phy_class_init); static void __exit wpan_phy_class_exit(void) { ieee802154_nl_exit(); - class_unregister(&wpan_phy_class); + wpan_phy_sysfs_exit(); } module_exit(wpan_phy_class_exit); diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c new file mode 100644 index 000000000000..eb9ca6f99122 --- /dev/null +++ b/net/ieee802154/sysfs.c @@ -0,0 +1,94 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/wireless/sysfs.c + */ + +#include + +#include + +#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ +static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ + int ret; \ + \ + mutex_lock(&phy->pib_lock); \ + ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ + mutex_unlock(&phy->pib_lock); \ + return ret; \ +} \ +static DEVICE_ATTR_RO(name) + +#define MASTER_SHOW(field, format_string) \ + MASTER_SHOW_COMPLEX(field, format_string, phy->field) + +MASTER_SHOW(current_channel, "%d"); +MASTER_SHOW(current_page, "%d"); +MASTER_SHOW(transmit_power, "%d +- 1 dB"); +MASTER_SHOW(cca_mode, "%d"); + +static ssize_t channels_supported_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); + int ret; + int i, len = 0; + + mutex_lock(&phy->pib_lock); + for (i = 0; i < 32; i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, + "%#09x\n", phy->channels_supported[i]); + if (ret < 0) + break; + len += ret; + } + mutex_unlock(&phy->pib_lock); + return len; +} +static DEVICE_ATTR_RO(channels_supported); + +static void wpan_phy_release(struct device *d) +{ + struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); + + kfree(phy); +} + +static struct attribute *pmib_attrs[] = { + &dev_attr_current_channel.attr, + &dev_attr_current_page.attr, + &dev_attr_channels_supported.attr, + &dev_attr_transmit_power.attr, + &dev_attr_cca_mode.attr, + NULL, +}; +ATTRIBUTE_GROUPS(pmib); + +struct class wpan_phy_class = { + .name = "ieee802154", + .dev_release = wpan_phy_release, + .dev_groups = pmib_groups, +}; + +int wpan_phy_sysfs_init(void) +{ + return class_register(&wpan_phy_class); +} + +void wpan_phy_sysfs_exit(void) +{ + class_unregister(&wpan_phy_class); +} diff --git a/net/ieee802154/sysfs.h b/net/ieee802154/sysfs.h new file mode 100644 index 000000000000..aa42e39ecbec --- /dev/null +++ b/net/ieee802154/sysfs.h @@ -0,0 +1,9 @@ +#ifndef __IEEE802154_SYSFS_H +#define __IEEE802154_SYSFS_H + +int wpan_phy_sysfs_init(void); +void wpan_phy_sysfs_exit(void); + +extern struct class wpan_phy_class; + +#endif /* __IEEE802154_SYSFS_H */ -- cgit v1.2.3 From 9cfd5a23a49c2a2cb9ff5537128d03547cbd2990 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 29 Oct 2014 10:16:00 +0200 Subject: Bluetooth: Wrong style spin lock used Use spin_lock_bh() as the code is called from softirq in networking subsystem. This is needed to prevent deadlocks when 6lowpan link is in use. Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ddf33900f7f3..91995f8ab0a0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4661,8 +4661,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, skb_shinfo(skb)->frag_list = NULL; - /* Queue all fragments atomically */ - spin_lock(&queue->lock); + /* Queue all fragments atomically. We need to use spin_lock_bh + * here because of 6LoWPAN links, as there this function is + * called from softirq and using normal spin lock could cause + * deadlocks. + */ + spin_lock_bh(&queue->lock); __skb_queue_tail(queue, skb); @@ -4679,7 +4683,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, __skb_queue_tail(queue, skb); } while (list); - spin_unlock(&queue->lock); + spin_unlock_bh(&queue->lock); } } -- cgit v1.2.3 From dcc6c2f5165788fdc37be9a13a909e8c16f254ce Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 25 Oct 2014 17:57:35 +0200 Subject: cfg80211: fix set but not used warning in nl80211_channel_switch() radar_detect_width is unused since commit 97dc94f1d933 ("cfg80211: remove channel_switch combination check") Signed-off-by: Fabian Frederick Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'net') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 12736a7cd506..33aff7466f2f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6038,7 +6038,6 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) * function is called under RTNL lock, so this should not be a problem. */ static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; - u8 radar_detect_width = 0; int err; bool need_new_beacon = false; int len, i; @@ -6174,10 +6173,8 @@ skip_beacons: if (err < 0) return err; - if (err > 0) { - radar_detect_width = BIT(params.chandef.width); + if (err > 0) params.radar_required = true; - } if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) params.block_tx = true; -- cgit v1.2.3 From fc1f48ffd5793e0a35c3b02375c2e2923e0f2bf3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 29 Oct 2014 17:05:39 +0100 Subject: cfg80211: fix integer signedness in chandef_primary_freqs() The helper function can't ever create negative values, so use u32 pointers as the function arguments as the caller does. Signed-off-by: Johannes Berg --- net/wireless/chan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 72d81e2154d5..8f39e33e71bb 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -115,7 +115,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) EXPORT_SYMBOL(cfg80211_chandef_valid); static void chandef_primary_freqs(const struct cfg80211_chan_def *c, - int *pri40, int *pri80) + u32 *pri40, u32 *pri80) { int tmp; -- cgit v1.2.3 From 55a2d0651762eb6f70d48ff94d21bc5718d5e47d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:28 +0100 Subject: mac802154: main: remove unnecessary include This patch removes an unnecessary include of driver-ops header file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 21dcc56930d1..86e533ed3775 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -28,7 +28,6 @@ #include #include "ieee802154_i.h" -#include "driver-ops.h" static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) -- cgit v1.2.3 From 94b792220ca9c080f4d1da8060f4c892c1b3b025 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:32 +0100 Subject: mac802154: add support for promiscuous mode This patch adds a new driver operation to bring the transceiver into promiscuous mode. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 7 +++++++ net/mac802154/driver-ops.h | 13 +++++++++++++ 2 files changed, 20 insertions(+) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 2f523fc1bf80..166ef6c52180 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -92,6 +92,8 @@ struct ieee802154_hw { #define IEEE802154_HW_FRAME_RETRIES 0x00000080 /* Indicates that transceiver will support hardware address filter setting. */ #define IEEE802154_HW_AFILT 0x00000100 +/* Indicates that transceiver will support promiscuous mode setting. */ +#define IEEE802154_HW_PROMISCUOUS 0x00000200 /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ @@ -173,6 +175,9 @@ struct ieee802154_hw { * set_frame_retries * Sets the retransmission attempt limit. Called with pib_lock held. * Returns either zero, or negative errno. + * + * set_promiscuous_mode + * Enables or disable promiscuous mode. */ struct ieee802154_ops { struct module *owner; @@ -197,6 +202,8 @@ struct ieee802154_ops { u8 min_be, u8 max_be, u8 retries); int (*set_frame_retries)(struct ieee802154_hw *hw, s8 retries); + int (*set_promiscuous_mode)(struct ieee802154_hw *hw, + const bool on); }; /* Basic interface to register ieee802154 hwice */ diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index 4b820cfeb538..dfd29ffb8fee 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -210,4 +210,17 @@ static inline int drv_set_max_frame_retries(struct ieee802154_local *local, return local->ops->set_frame_retries(&local->hw, max_frame_retries); } +static inline int drv_set_promiscuous_mode(struct ieee802154_local *local, + const bool on) +{ + might_sleep(); + + if (!local->ops->set_promiscuous_mode) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_promiscuous_mode(&local->hw, on); +} + #endif /* __MAC802154_DRVIER_OPS */ -- cgit v1.2.3 From 90386a7e3bcce60b6b83d0d1bd65d7b55a77fa60 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:34 +0100 Subject: mac802154: separate omit tx/rx flags This patch splits the IEEE802154_HW_OMIT_CKSUM hardware flag into IEEE802154_HW_TX_OMIT_CKSUM and IEEE802154_HW_RX_OMIT_CKSUM. This is useful to deliver the received crc from the driver layer to the monitor interface. At the moment we can't do that without change the xmit handling. The received checksum should be visible in monitor mode only. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 10 ++++++++-- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 166ef6c52180..bc1d40c826e3 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -73,8 +73,8 @@ struct ieee802154_hw { * however, so you are advised to review these flags carefully. */ -/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ -#define IEEE802154_HW_OMIT_CKSUM 0x00000001 +/* Indicates that xmitter will add FCS on it's own. */ +#define IEEE802154_HW_TX_OMIT_CKSUM 0x00000001 /* Indicates that receiver will autorespond with ACK frames. */ #define IEEE802154_HW_AACK 0x00000002 /* Indicates that transceiver will support transmit power setting. */ @@ -94,6 +94,12 @@ struct ieee802154_hw { #define IEEE802154_HW_AFILT 0x00000100 /* Indicates that transceiver will support promiscuous mode setting. */ #define IEEE802154_HW_PROMISCUOUS 0x00000200 +/* Indicates that receiver omits FCS. */ +#define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 + +/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ +#define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ + IEEE802154_HW_RX_OMIT_CKSUM) /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 86394befbf88..2aa80bdcbacf 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -255,7 +255,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) { u16 crc; if (skb->len < 2) { diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 77973a84e9a2..cc37b77f2632 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -83,7 +83,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) struct net_device *dev = skb->dev; int ret; - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); put_unaligned_le16(crc, skb_put(skb, 2)); -- cgit v1.2.3 From 08c511a7331cf6edb28895d7f46c3039180b30cb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:35 +0100 Subject: mac802154: rx: remove unnecessary parameter This patch removes a not used parameter in ieee802154_deliver_skb. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 2aa80bdcbacf..51a55d9200cb 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -29,7 +29,7 @@ #include "ieee802154_i.h" -static int ieee802154_deliver_skb(struct net_device *dev, struct sk_buff *skb) +static int ieee802154_deliver_skb(struct sk_buff *skb) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); @@ -103,7 +103,7 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, switch (mac_cb(skb)->type) { case IEEE802154_FC_TYPE_DATA: - return ieee802154_deliver_skb(sdata->dev, skb); + return ieee802154_deliver_skb(skb); default: pr_warn("ieee802154: bad frame received (type = %d)\n", mac_cb(skb)->type); -- cgit v1.2.3 From b7889497d306df0be52300b3060ebc12b4194f9a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:36 +0100 Subject: mac802154: rx: simplify crc receive handling This patch change the actual crc handling while receive. Currently the IEEE802154_HW_RX_OMIT_CKSUM flag is used to filter a frame with a bad crc. This patch changes the behaviour of IEEE802154_HW_RX_OMIT_CKSUM to add a crc while receiving for the monitor interface. After monitor receiving we remove the crc for frame parsing. This affect the driver layer because all drivers sets IEEE802154_HW_RX_OMIT_CKSUM and deliver without checksum. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 51a55d9200cb..b6a4bbfdbf90 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -225,8 +226,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data; skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -241,9 +240,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; skb2->pkt_type = PACKET_HOST; - data = skb_put(skb2, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; netif_rx_ni(skb2); } @@ -255,32 +251,26 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) { - u16 crc; + /* TODO: When a transceiver omits the checksum here, we + * add an own calculated one. This is currently an ugly + * solution because the monitor needs a crc here. + */ + if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { + u16 crc = crc_ccitt(0, skb->data, skb->len); - if (skb->len < 2) { - pr_debug("got invalid frame\n"); - goto fail; - } - crc = crc_ccitt(0, skb->data, skb->len); - if (crc) { - pr_debug("CRC mismatch\n"); - goto fail; - } - skb_trim(skb, skb->len - 2); /* CRC */ + put_unaligned_le16(crc, skb_put(skb, 2)); } rcu_read_lock(); ieee802154_monitors_rx(local, skb); - __ieee802154_rx_handle_packet(local, skb); - rcu_read_unlock(); + /* remove crc */ + skb_trim(skb, skb->len - 2); - return; + __ieee802154_rx_handle_packet(local, skb); -fail: - kfree_skb(skb); + rcu_read_unlock(); } EXPORT_SYMBOL(ieee802154_rx); -- cgit v1.2.3 From ec718f3db9b7968ca5dfb10c85c56ff27149df94 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:37 +0100 Subject: mac802154: rx: add software checksum filtering check This patch adds a new hardware flag which indicate that the transceiver doesn't support check for bad checksum via hardware. Also add a handling of this while receive. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 2 ++ net/mac802154/rx.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/include/net/mac802154.h b/include/net/mac802154.h index bc1d40c826e3..8f1de6844cb0 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -96,6 +96,8 @@ struct ieee802154_hw { #define IEEE802154_HW_PROMISCUOUS 0x00000200 /* Indicates that receiver omits FCS. */ #define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 +/* Indicates that receiver will not filter frames with bad checksum. */ +#define IEEE802154_HW_RX_DROP_BAD_CKSUM 0x00000800 /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index b6a4bbfdbf90..c9f1c72a1afc 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -248,6 +248,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); + u16 crc; WARN_ON_ONCE(softirq_count() == 0); @@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) * solution because the monitor needs a crc here. */ if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { - u16 crc = crc_ccitt(0, skb->data, skb->len); - + crc = crc_ccitt(0, skb->data, skb->len); put_unaligned_le16(crc, skb_put(skb, 2)); } @@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) ieee802154_monitors_rx(local, skb); + /* Check if transceiver doesn't validate the checksum. + * If not we validate the checksum here. + */ + if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) { + crc = crc_ccitt(0, skb->data, skb->len); + if (crc) { + rcu_read_unlock(); + kfree_skb(skb); + return; + } + } /* remove crc */ skb_trim(skb, skb->len - 2); -- cgit v1.2.3 From 1054ed81c4f5225d7a45fe5dec67430280bf3793 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:38 +0100 Subject: mac802154: rx: remove override pkt_type set to PACKET_HOST This patch removes pkt_type set to PACKET_HOST while monitor receiving. This should be PACKET_OTHERHOST on monitor mode which already set before. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c9f1c72a1afc..f15c50b97c3c 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -239,7 +239,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; - skb2->pkt_type = PACKET_HOST; netif_rx_ni(skb2); } -- cgit v1.2.3 From 21fdf0a1c10719f6edbb5961f5b076f5575d4bce Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:39 +0100 Subject: mac802154: rx: use netif_receive_skb This patch removes netif_rx_ni call. Instead we call netif_receive_skb, we can do that since commit c5c47e67bcd24638a059b1b5e9ec18c95f8634ca ("mac802154: rx: use tasklet instead workqueue"). Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index f15c50b97c3c..7669cdbba526 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -240,7 +240,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; - netif_rx_ni(skb2); + ieee802154_deliver_skb(skb2); } } -- cgit v1.2.3 From 18460672e0651705ca557c94a369003553c3f9d6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:40 +0100 Subject: mac802154: rx: add rx stats incrementation This patch adds rx stats incrementation when the monitor interface recevied a frame. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 7669cdbba526..6ba2769f5fb4 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -241,6 +241,9 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2->dev = sdata->dev; ieee802154_deliver_skb(skb2); + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; } } -- cgit v1.2.3 From 20b48120c14fb4bf6ebe4ed4cfa1b828e5e1dff8 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:41 +0100 Subject: mac802154: rx: monitor receive cleanup This patch replace the !netif_running(sdata->dev) instead we doing a !ieee802154_sdata_running(sdata). Also move this in two separate if branches to compare with mac80211 code. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 6ba2769f5fb4..971a8553e9b6 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -233,8 +233,10 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb->protocol = htons(ETH_P_IEEE802154); list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_MONITOR || - !netif_running(sdata->dev)) + if (sdata->type != IEEE802154_DEV_MONITOR) + continue; + + if (!ieee802154_sdata_running(sdata)) continue; skb2 = skb_clone(skb, GFP_ATOMIC); -- cgit v1.2.3 From 05f7de67921d8b382b14597c3955c5881d804d99 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:42 +0100 Subject: mac802154: rx: add error handling after skb_clone This patch adds error handling after skb_clone and deliver only if skb_clone was successful. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 971a8553e9b6..95961cccc253 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -240,12 +240,13 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) continue; skb2 = skb_clone(skb, GFP_ATOMIC); - skb2->dev = sdata->dev; + if (skb2) { + skb2->dev = sdata->dev; + ieee802154_deliver_skb(skb2); - ieee802154_deliver_skb(skb2); - - sdata->dev->stats.rx_packets++; - sdata->dev->stats.rx_bytes += skb->len; + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + } } } -- cgit v1.2.3 From 38130c31ef50de1999983601e448db2b1bc1057c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:44 +0100 Subject: mac802154: add basic support for monitor This patch adds basic support for monitor mode. Also change the open call that we set the transceiver mac setting on an interface up. Futher patches will add a better handling while interface up an interface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 + net/mac802154/iface.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 7cebc9844c00..1086a9d96f8f 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -84,6 +84,7 @@ struct ieee802154_sub_if_data { __le16 pan_id; __le16 short_addr; __le64 extended_addr; + bool promisuous_mode; struct ieee802154_mac_params mac_params; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0bf5f9b9953..f7a6f83301e2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -196,6 +196,12 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); + if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { + rc = drv_set_promiscuous_mode(local, sdata->promisuous_mode); + if (rc < 0) + goto out; + } + if (local->hw.flags & IEEE802154_HW_TXPOWER) { rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) @@ -382,7 +388,7 @@ static const struct net_device_ops mac802154_wpan_ops = { }; static const struct net_device_ops mac802154_monitor_ops = { - .ndo_open = mac802154_slave_open, + .ndo_open = mac802154_wpan_open, .ndo_stop = mac802154_slave_close, .ndo_start_xmit = ieee802154_monitor_start_xmit, }; @@ -434,6 +440,8 @@ void mac802154_wpan_setup(struct net_device *dev) sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + sdata->promisuous_mode = false; + mac802154_llsec_init(&sdata->sec); } @@ -453,4 +461,6 @@ void mac802154_monitor_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; + + sdata->promisuous_mode = true; } -- cgit v1.2.3 From daac197ca9966eca3a6b07600e579756a9a1d447 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 19:10:57 +0300 Subject: Bluetooth: 6lowpan: use after free in disconnect_devices() This was accidentally changed from list_for_each_entry_safe() to list_for_each_entry() so now it has a use after free bug. I've changed it back. Fixes: 90305829635d ('Bluetooth: 6lowpan: Converting rwlocks to use RCU') Signed-off-by: Dan Carpenter Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 7254bddaca2f..eef298d17452 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -1383,7 +1383,7 @@ static const struct file_operations lowpan_control_fops = { static void disconnect_devices(void) { - struct lowpan_dev *entry, *new_dev; + struct lowpan_dev *entry, *tmp, *new_dev; struct list_head devices; INIT_LIST_HEAD(&devices); @@ -1408,7 +1408,7 @@ static void disconnect_devices(void) rcu_read_unlock(); - list_for_each_entry(entry, &devices, list) { + list_for_each_entry_safe(entry, tmp, &devices, list) { ifdown(entry->netdev); BT_DBG("Unregistering netdev %s %p", entry->netdev->name, entry->netdev); -- cgit v1.2.3 From a4d5504d5c39cc84f1f828e19967595597a8136e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Oct 2014 23:37:53 +0100 Subject: Bluetooth: Clear LE white list when resetting controller The internal representation of the LE white list needs to be cleared when receiving a successful HCI_Reset command. A reset of the controller is expected to start with an empty LE white list. When the LE white list is not cleared on controller reset, the passive background scanning might skip programming the remote devices. Only changes to the LE white list are programmed when passive background is started. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org # 3.17.x --- net/bluetooth/hci_event.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f5704bae67a2..aa152140c3e2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -205,6 +205,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hdev->le_scan_type = LE_SCAN_PASSIVE; hdev->ssp_debug_mode = 0; + + hci_bdaddr_list_clear(&hdev->le_white_list); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- cgit v1.2.3 From d070f9137af960abd78525440684421fd5e0c0e7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 29 Oct 2014 22:55:58 -0700 Subject: mac80211: fix spelling errors Use codespell to find spelling errors. Signed-off-by: Stephen Hemminger Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 2 +- net/mac80211/chan.c | 2 +- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/rc80211_minstrel.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d6b01ad2f7d7..fbcc209687c8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -191,7 +191,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, * receive the key. When wpa_supplicant has roamed * using FT, it attempts to set the key before * association has completed, this rejects that attempt - * so it will set the key again after assocation. + * so it will set the key again after association. * * TODO: accept the key if we have a station entry and * add it to the device after the station. diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 4c74e8da64b9..ee71bb6f64f7 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1634,7 +1634,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, } break; case IEEE80211_CHANCTX_WILL_BE_REPLACED: - /* TODO: Perhaps the bandwith change could be treated as a + /* TODO: Perhaps the bandwidth change could be treated as a * reservation itself? */ ret = -EBUSY; goto out; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 146a818e52b5..eb425298fe69 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -131,7 +131,7 @@ enum ieee80211_bss_corrupt_data_flags { * * These are bss flags that are attached to a bss in the * @valid_data field of &struct ieee80211_bss. They show which parts - * of the data structure were recieved as a result of an un-corrupted + * of the data structure were received as a result of an un-corrupted * beacon/probe response. */ enum ieee80211_bss_valid_data_flags { diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 2baa7ed8789d..c2b91bf47f6d 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -191,7 +191,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) * (1) if any success probabilitiy >= 95%, out of those rates * choose the maximum throughput rate as max_prob_rate * (2) if all success probabilities < 95%, the rate with - * highest success probability is choosen as max_prob_rate */ + * highest success probability is chosen as max_prob_rate */ if (mrs->probability >= MINSTREL_FRAC(95, 100)) { if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) tmp_prob_rate = i; -- cgit v1.2.3 From de4fcbadde68e3429cc533c29abf6fbceda4628f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 31 Oct 2014 14:16:12 +0100 Subject: cfg80211: avoid using default in interface type switch Most code avoids having a default case in interface type switch statements already, to make it easier to find places that need to be extended. Change the code in the __cfg80211_leave() and nl80211_key_allowed() functions to not have a default case. Signed-off-by: Johannes Berg --- net/wireless/core.c | 14 +++++++++++++- net/wireless/nl80211.c | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/wireless/core.c b/net/wireless/core.c index 87bb502bc8de..da4dcb65ade4 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -869,7 +869,19 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_P2P_GO: __cfg80211_stop_ap(rdev, dev, true); break; - default: + case NL80211_IFTYPE_WDS: + /* must be handled by mac80211/driver, has no APIs */ + break; + case NL80211_IFTYPE_P2P_DEVICE: + /* cannot happen, has no netdev */ + break; + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MONITOR: + /* nothing to do */ + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NUM_NL80211_IFTYPES: + /* invalid */ break; } } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 33aff7466f2f..f7d918858d32 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -884,7 +884,11 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) if (!wdev->current_bss) return -ENOLINK; break; - default: + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_WDS: + case NUM_NL80211_IFTYPES: return -EINVAL; } -- cgit v1.2.3 From 5b3dc42b1b0db0264bbbe4ae44c15ab97bfd1e93 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 26 Oct 2014 00:32:53 +0200 Subject: mac80211: add support for driver tx power reporting The configured tx power is often limited by hardware capabilities, channel settings, antenna configuration, etc. Signed-off-by: Felix Fietkau [fix tracing compilation] Signed-off-by: Johannes Berg --- include/net/mac80211.h | 5 +++++ net/mac80211/cfg.c | 3 +++ net/mac80211/driver-ops.h | 14 ++++++++++++++ net/mac80211/trace.h | 27 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1614b2fc3bf6..03edbf6f6230 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2857,6 +2857,9 @@ enum ieee80211_roc_type { * @get_expected_throughput: extract the expected throughput towards the * specified station. The returned value is expressed in Kbps. It returns 0 * if the RC algorithm does not have proper data to provide. + * + * @get_txpower: get current maximum tx power (in dBm) based on configuration + * and hardware limits. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -3065,6 +3068,8 @@ struct ieee80211_ops { int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); u32 (*get_expected_throughput)(struct ieee80211_sta *sta); + int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int *dbm); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fbcc209687c8..b9659b8b70f8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2133,6 +2133,9 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); + if (local->ops->get_txpower) + return drv_get_txpower(local, sdata, dbm); + if (!local->use_chanctx) *dbm = local->hw.conf.power_level; else diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 3df28e0fa045..d1e128e5db41 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1279,4 +1279,18 @@ static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, return ret; } +static inline int drv_get_txpower(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, int *dbm) +{ + int ret; + + if (!local->ops->get_txpower) + return -EOPNOTSUPP; + + ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); + trace_drv_get_txpower(local, sdata, *dbm, ret); + + return ret; +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 976606aebac9..aeeace5ba47b 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2150,6 +2150,33 @@ DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch, TP_ARGS(local, sdata) ); +TRACE_EVENT(drv_get_txpower, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + int dbm, int ret), + + TP_ARGS(local, sdata, dbm, ret), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __field(int, dbm) + __field(int, ret) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + __entry->dbm = dbm; + __entry->ret = ret; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret + ) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- cgit v1.2.3 From 6e0bd6c35b021dc73a81ebd1ef79761233c48b50 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Mon, 3 Nov 2014 10:33:18 +0100 Subject: cfg80211: 802.11p OCB mode handling This patch adds new iface type (NL80211_IFTYPE_OCB) representing the OCB (Outside the Context of a BSS) mode. When establishing a connection to the network a cfg80211_join_ocb function is called (particular nl80211_command is added as well). A mandatory parameters during the ocb_join operation are 'center frequency' and 'channel width (5/10 MHz)'. Changes done in mac80211 are minimal possible required to avoid many warnings (warning: enumeration value 'NL80211_IFTYPE_OCB' not handled in switch) during compilation. Full functionality (where needed) is added in the following patch. Signed-off-by: Rostislav Lisovy Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 19 ++++++++++ include/uapi/linux/nl80211.h | 11 ++++++ net/mac80211/cfg.c | 1 + net/mac80211/chan.c | 2 + net/mac80211/iface.c | 5 +++ net/mac80211/util.c | 3 ++ net/wireless/Makefile | 2 +- net/wireless/chan.c | 8 ++++ net/wireless/core.c | 3 ++ net/wireless/core.h | 12 ++++++ net/wireless/nl80211.c | 39 ++++++++++++++++++++ net/wireless/ocb.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 21 +++++++++++ net/wireless/trace.h | 21 +++++++++++ net/wireless/util.c | 5 ++- 15 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 net/wireless/ocb.c (limited to 'net') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f67948e18600..5c3acd07acd9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1358,6 +1358,16 @@ struct mesh_setup { u32 basic_rates; }; +/** + * struct ocb_setup - 802.11p OCB mode setup configuration + * @chandef: defines the channel to use + * + * These parameters are fixed when connecting to the network + */ +struct ocb_setup { + struct cfg80211_chan_def chandef; +}; + /** * struct ieee80211_txq_params - TX queue parameters * @ac: AC identifier @@ -2352,6 +2362,11 @@ struct cfg80211_qos_map { * with the peer followed by immediate teardown when the addition is later * rejected) * @del_tx_ts: remove an existing TX TS + * + * @join_ocb: join the OCB network with the specified parameters + * (invoked with the wireless_dev mutex held) + * @leave_ocb: leave the current OCB network + * (invoked with the wireless_dev mutex held) */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2433,6 +2448,10 @@ struct cfg80211_ops { const struct mesh_setup *setup); int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); + int (*join_ocb)(struct wiphy *wiphy, struct net_device *dev, + struct ocb_setup *setup); + int (*leave_ocb)(struct wiphy *wiphy, struct net_device *dev); + int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f7daae59248e..9b3025e4377a 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -746,6 +746,11 @@ * destination %NL80211_ATTR_MAC on the interface identified by * %NL80211_ATTR_IFINDEX. * + * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and + * bandwidth of a channel must be given. + * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the + * network is determined by the network interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -922,6 +927,9 @@ enum nl80211_commands { NL80211_CMD_GET_MPP, + NL80211_CMD_JOIN_OCB, + NL80211_CMD_LEAVE_OCB, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2074,6 +2082,8 @@ enum nl80211_attrs { * and therefore can't be created in the normal ways, use the * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE * commands to create and destroy one + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS + * This mode corresponds to the MIB variable dot11OCBActivated=true * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -2093,6 +2103,7 @@ enum nl80211_iftype { NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, NL80211_IFTYPE_P2P_DEVICE, + NL80211_IFTYPE_OCB, /* keep last */ NUM_NL80211_IFTYPES, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b9659b8b70f8..1e2afc95ad09 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -230,6 +230,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_OCB: /* shouldn't happen */ WARN_ON_ONCE(1); break; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index ee71bb6f64f7..ff1f877e3b63 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -270,6 +270,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: width = vif->bss_conf.chandef.width; break; case NL80211_IFTYPE_UNSPECIFIED: @@ -909,6 +910,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata) case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: ieee80211_queue_work(&sdata->local->hw, &sdata->csa_finalize_work); break; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1ffcc0701244..d69e7532095f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -521,6 +521,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_OCB: /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: @@ -631,6 +632,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: netif_carrier_off(dev); break; case NL80211_IFTYPE_WDS: @@ -1351,6 +1353,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; ieee80211_sta_setup_sdata(sdata); break; + case NL80211_IFTYPE_OCB: + /* to be implemented in the future */ + break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; ieee80211_ibss_setup_sdata(sdata); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 666aa1306c45..d7d69c89ff34 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1841,6 +1841,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, changed); sdata_unlock(sdata); break; + case NL80211_IFTYPE_OCB: + /* to be implemented in the future */ + break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; /* fall through */ diff --git a/net/wireless/Makefile b/net/wireless/Makefile index a761670af31d..4c9e39f04ef8 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 8f39e33e71bb..85506f1d0789 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -366,6 +366,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -892,6 +893,13 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, *radar_detect |= BIT(wdev->chandef.width); } return; + case NL80211_IFTYPE_OCB: + if (wdev->chandef.chan) { + *chan = wdev->chandef.chan; + *chanmode = CHAN_MODE_SHARED; + return; + } + break; case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: diff --git a/net/wireless/core.c b/net/wireless/core.c index da4dcb65ade4..a4d27927aba2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -869,6 +869,9 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_P2P_GO: __cfg80211_stop_ap(rdev, dev, true); break; + case NL80211_IFTYPE_OCB: + __cfg80211_leave_ocb(rdev, dev); + break; case NL80211_IFTYPE_WDS: /* must be handled by mac80211/driver, has no APIs */ break; diff --git a/net/wireless/core.h b/net/wireless/core.h index 7e3a3cef7df9..61ee664cf2bd 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -290,6 +290,18 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, struct cfg80211_chan_def *chandef); +/* OCB */ +int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup); +int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup); +int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev); +int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev); + /* AP */ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, struct net_device *dev, bool notify); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f7d918858d32..1a31736914e5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -885,6 +885,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) return -ENOLINK; break; case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_WDS: @@ -8275,6 +8276,28 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } +static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct ocb_setup setup = {}; + int err; + + err = nl80211_parse_chandef(rdev, info, &setup.chandef); + if (err) + return err; + + return cfg80211_join_ocb(rdev, dev, &setup); +} + +static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + + return cfg80211_leave_ocb(rdev, dev); +} + static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -10218,6 +10241,22 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_JOIN_OCB, + .doit = nl80211_join_ocb, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_LEAVE_OCB, + .doit = nl80211_leave_ocb, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, #ifdef CONFIG_PM { .cmd = NL80211_CMD_GET_WOWLAN, diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c new file mode 100644 index 000000000000..c00d4a792319 --- /dev/null +++ b/net/wireless/ocb.c @@ -0,0 +1,88 @@ +/* + * OCB mode implementation + * + * Copyright: (c) 2014 Czech Technical University in Prague + * (c) 2014 Volkswagen Group Research + * Author: Rostislav Lisovy + * Funded by: Volkswagen Group Research + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include "nl80211.h" +#include "core.h" +#include "rdev-ops.h" + +int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) + return -EOPNOTSUPP; + + if (WARN_ON(!setup->chandef.chan)) + return -EINVAL; + + err = rdev_join_ocb(rdev, dev, setup); + if (!err) + wdev->chandef = setup->chandef; + + return err; +} + +int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_join_ocb(rdev, dev, setup); + wdev_unlock(wdev); + + return err; +} + +int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) + return -EOPNOTSUPP; + + if (!rdev->ops->leave_ocb) + return -EOPNOTSUPP; + + err = rdev_leave_ocb(rdev, dev); + if (!err) + memset(&wdev->chandef, 0, sizeof(wdev->chandef)); + + return err; +} + +int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_leave_ocb(rdev, dev); + wdev_unlock(wdev); + + return err; +} diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 71b1db3cc645..1b3864cd50ca 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -348,6 +348,27 @@ static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev, return ret; } +static inline int rdev_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + int ret; + trace_rdev_join_ocb(&rdev->wiphy, dev, setup); + ret = rdev->ops->join_ocb(&rdev->wiphy, dev, setup); + trace_rdev_return_int(&rdev->wiphy, ret); + return ret; +} + +static inline int rdev_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + int ret; + trace_rdev_leave_ocb(&rdev->wiphy, dev); + ret = rdev->ops->leave_ocb(&rdev->wiphy, dev); + trace_rdev_return_int(&rdev->wiphy, ret); + return ret; +} + static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, struct net_device *dev, struct bss_parameters *params) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index cdb2c2ef1ae1..277a85df910e 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -600,6 +600,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss, TP_ARGS(wiphy, netdev) ); +DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), + TP_ARGS(wiphy, netdev) +); + DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), TP_ARGS(wiphy, netdev) @@ -1316,6 +1321,22 @@ TRACE_EVENT(rdev_join_ibss, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) ); +TRACE_EVENT(rdev_join_ocb, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + const struct ocb_setup *setup), + TP_ARGS(wiphy, netdev, setup), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG) +); + TRACE_EVENT(rdev_set_wiphy_params, TP_PROTO(struct wiphy *wiphy, u32 changed), TP_ARGS(wiphy, changed), diff --git a/net/wireless/util.c b/net/wireless/util.c index 5e233a577d0f..d0ac795445b7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -442,7 +442,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, break; case cpu_to_le16(0): if (iftype != NL80211_IFTYPE_ADHOC && - iftype != NL80211_IFTYPE_STATION) + iftype != NL80211_IFTYPE_STATION && + iftype != NL80211_IFTYPE_OCB) return -1; break; } @@ -519,6 +520,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, memcpy(hdr.addr3, skb->data, ETH_ALEN); hdrlen = 24; break; + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_ADHOC: /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -937,6 +939,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->use_4addr) break; /* fall through */ + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_ADHOC: dev->priv_flags |= IFF_DONT_BRIDGE; -- cgit v1.2.3 From 239281f803e2efdb77d906ef296086b6917e5d71 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Mon, 3 Nov 2014 10:33:19 +0100 Subject: mac80211: 802.11p OCB mode support This patch adds 802.11p OCB (Outside the Context of a BSS) mode support. When communicating in OCB mode a mandatory wildcard BSSID (48 '1' bits) is used. The EDCA parameters handling function was changed to support 802.11p specific values. The insertion of a newly discovered STAs is done in the similar way as in the IBSS mode -- through the deferred insertion. The OCB mode uses a periodic 'housekeeping task' for expiration of disconnected STAs (in the similar manner as in the MESH mode). New Kconfig option for verbose OCB debugging outputs is added. Signed-off-by: Rostislav Lisovy Signed-off-by: Johannes Berg --- include/net/mac80211.h | 2 + net/mac80211/Kconfig | 11 ++ net/mac80211/Makefile | 3 +- net/mac80211/cfg.c | 13 +++ net/mac80211/chan.c | 1 + net/mac80211/debug.h | 10 ++ net/mac80211/driver-ops.h | 3 +- net/mac80211/ieee80211_i.h | 29 ++++++ net/mac80211/iface.c | 20 +++- net/mac80211/ocb.c | 250 +++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/rx.c | 35 +++++++ net/mac80211/tx.c | 15 +++ net/mac80211/util.c | 30 ++++-- net/mac80211/wme.c | 4 + 14 files changed, 417 insertions(+), 9 deletions(-) create mode 100644 net/mac80211/ocb.c (limited to 'net') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 03edbf6f6230..db54635d65c5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -263,6 +263,7 @@ struct ieee80211_vif_chanctx_switch { * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, * note that this is only called when it changes after the channel * context had been assigned. + * @BSS_CHANGED_OCB: OCB join status changed */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -287,6 +288,7 @@ enum ieee80211_bss_change { BSS_CHANGED_P2P_PS = 1<<19, BSS_CHANGED_BEACON_INFO = 1<<20, BSS_CHANGED_BANDWIDTH = 1<<21, + BSS_CHANGED_OCB = 1<<22, /* when adding here, make sure to change ieee80211_reconfig */ }; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 67cf8125d75d..75cc6801a431 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -176,6 +176,17 @@ config MAC80211_HT_DEBUG Do not select this option. +config MAC80211_OCB_DEBUG + bool "Verbose OCB debugging" + depends on MAC80211_DEBUG_MENU + ---help--- + Selecting this option causes mac80211 to print out + very verbose OCB debugging messages. It should not + be selected on production systems as those messages + are remotely triggerable. + + Do not select this option. + config MAC80211_IBSS_DEBUG bool "Verbose IBSS debugging" depends on MAC80211_DEBUG_MENU diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 7273d2796dd1..e53671b1105e 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -27,7 +27,8 @@ mac80211-y := \ event.o \ chan.o \ trace.o mlme.o \ - tdls.o + tdls.o \ + ocb.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1e2afc95ad09..06185940cbb6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2019,6 +2019,17 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); } +static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev, + struct ocb_setup *setup) +{ + return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup); +} + +static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev) +{ + return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev)); +} + static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, int rate[IEEE80211_NUM_BANDS]) { @@ -3693,6 +3704,8 @@ const struct cfg80211_ops mac80211_config_ops = { .join_mesh = ieee80211_join_mesh, .leave_mesh = ieee80211_leave_mesh, #endif + .join_ocb = ieee80211_join_ocb, + .leave_ocb = ieee80211_leave_ocb, .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, .set_monitor_channel = ieee80211_set_monitor_channel, diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index ff1f877e3b63..c7c514220298 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -675,6 +675,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: break; default: WARN_ON_ONCE(1); diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h index 493d68061f0c..1956b3115dd5 100644 --- a/net/mac80211/debug.h +++ b/net/mac80211/debug.h @@ -2,6 +2,12 @@ #define __MAC80211_DEBUG_H #include +#ifdef CONFIG_MAC80211_OCB_DEBUG +#define MAC80211_OCB_DEBUG 1 +#else +#define MAC80211_OCB_DEBUG 0 +#endif + #ifdef CONFIG_MAC80211_IBSS_DEBUG #define MAC80211_IBSS_DEBUG 1 #else @@ -131,6 +137,10 @@ do { \ _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ sdata, fmt, ##__VA_ARGS__) +#define ocb_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_OCB_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + #define ibss_dbg(sdata, fmt, ...) \ _sdata_dbg(MAC80211_IBSS_DEBUG, \ sdata, fmt, ##__VA_ARGS__) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index d1e128e5db41..8e1889ff2e53 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -214,7 +214,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, BSS_CHANGED_BEACON_ENABLED) && sdata->vif.type != NL80211_IFTYPE_AP && sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_OCB)) return; if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eb425298fe69..fbd6bee9c959 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -576,6 +576,25 @@ struct ieee80211_if_ibss { } state; }; +/** + * struct ieee80211_if_ocb - OCB mode state + * + * @housekeeping_timer: timer for periodic invocation of a housekeeping task + * @wrkq_flags: OCB deferred task action + * @incomplete_lock: delayed STA insertion lock + * @incomplete_stations: list of STAs waiting for delayed insertion + * @joined: indication if the interface is connected to an OCB network + */ +struct ieee80211_if_ocb { + struct timer_list housekeeping_timer; + unsigned long wrkq_flags; + + spinlock_t incomplete_lock; + struct list_head incomplete_stations; + + bool joined; +}; + /** * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface * @@ -869,6 +888,7 @@ struct ieee80211_sub_if_data { struct ieee80211_if_managed mgd; struct ieee80211_if_ibss ibss; struct ieee80211_if_mesh mesh; + struct ieee80211_if_ocb ocb; u32 mntr_flags; } u; @@ -1505,6 +1525,15 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); +/* OCB code */ +void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata); +void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, + const u8 *bssid, const u8 *addr, u32 supp_rates); +void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata); +int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, + struct ocb_setup *setup); +int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata); + /* mesh code */ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d69e7532095f..6b631c049eba 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -258,6 +258,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { + /* + * Only OCB and monitor mode may coexist + */ + if ((sdata->vif.type == NL80211_IFTYPE_OCB && + nsdata->vif.type != NL80211_IFTYPE_MONITOR) || + (sdata->vif.type != NL80211_IFTYPE_MONITOR && + nsdata->vif.type == NL80211_IFTYPE_OCB)) + return -EBUSY; + /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution @@ -1283,6 +1292,9 @@ static void ieee80211_iface_work(struct work_struct *work) break; ieee80211_mesh_work(sdata); break; + case NL80211_IFTYPE_OCB: + ieee80211_ocb_work(sdata); + break; default: break; } @@ -1302,6 +1314,9 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { + static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff, + 0xff, 0xff, 0xff}; + /* clear type-dependent union */ memset(&sdata->u, 0, sizeof(sdata->u)); @@ -1354,7 +1369,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, ieee80211_sta_setup_sdata(sdata); break; case NL80211_IFTYPE_OCB: - /* to be implemented in the future */ + sdata->vif.bss_conf.bssid = bssid_wildcard; + ieee80211_ocb_setup_sdata(sdata); break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; @@ -1403,6 +1419,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could maybe also all others here? * Just not sure how that interacts @@ -1418,6 +1435,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could probably support everything * but WDS here (WDS do_open can fail diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c new file mode 100644 index 000000000000..358d5f9d8207 --- /dev/null +++ b/net/mac80211/ocb.c @@ -0,0 +1,250 @@ +/* + * OCB mode implementation + * + * Copyright: (c) 2014 Czech Technical University in Prague + * (c) 2014 Volkswagen Group Research + * Author: Rostislav Lisovy + * Funded by: Volkswagen Group Research + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211_i.h" +#include "driver-ops.h" +#include "rate.h" + +#define IEEE80211_OCB_HOUSEKEEPING_INTERVAL (60 * HZ) +#define IEEE80211_OCB_PEER_INACTIVITY_LIMIT (240 * HZ) +#define IEEE80211_OCB_MAX_STA_ENTRIES 128 + +/** + * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks + * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks + * + * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb + */ +enum ocb_deferred_task_flags { + OCB_WORK_HOUSEKEEPING, +}; + +void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, + const u8 *bssid, const u8 *addr, + u32 supp_rates) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_supported_band *sband; + enum nl80211_bss_scan_width scan_width; + struct sta_info *sta; + int band; + + /* XXX: Consider removing the least recently used entry and + * allow new one to be added. + */ + if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) { + net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n", + sdata->name, addr); + return; + } + + ocb_dbg(sdata, "Adding new OCB station %pM\n", addr); + + rcu_read_lock(); + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + if (WARN_ON_ONCE(!chanctx_conf)) { + rcu_read_unlock(); + return; + } + band = chanctx_conf->def.chan->band; + scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def); + rcu_read_unlock(); + + sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); + if (!sta) + return; + + sta->last_rx = jiffies; + + /* Add only mandatory rates for now */ + sband = local->hw.wiphy->bands[band]; + sta->sta.supp_rates[band] = + ieee80211_mandatory_rates(sband, scan_width); + + spin_lock(&ifocb->incomplete_lock); + list_add(&sta->list, &ifocb->incomplete_stations); + spin_unlock(&ifocb->incomplete_lock); + ieee80211_queue_work(&local->hw, &sdata->work); +} + +static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) + __acquires(RCU) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + u8 addr[ETH_ALEN]; + + memcpy(addr, sta->sta.addr, ETH_ALEN); + + ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n", + addr, sdata->name); + + sta_info_move_state(sta, IEEE80211_STA_AUTH); + sta_info_move_state(sta, IEEE80211_STA_ASSOC); + sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); + + rate_control_rate_init(sta); + + /* If it fails, maybe we raced another insertion? */ + if (sta_info_insert_rcu(sta)) + return sta_info_get(sdata, addr); + return sta; +} + +static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + ocb_dbg(sdata, "Running ocb housekeeping\n"); + + ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT); + + mod_timer(&ifocb->housekeeping_timer, + round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL)); +} + +void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct sta_info *sta; + + if (ifocb->joined != true) + return; + + sdata_lock(sdata); + + spin_lock_bh(&ifocb->incomplete_lock); + while (!list_empty(&ifocb->incomplete_stations)) { + sta = list_first_entry(&ifocb->incomplete_stations, + struct sta_info, list); + list_del(&sta->list); + spin_unlock_bh(&ifocb->incomplete_lock); + + ieee80211_ocb_finish_sta(sta); + rcu_read_unlock(); + spin_lock_bh(&ifocb->incomplete_lock); + } + spin_unlock_bh(&ifocb->incomplete_lock); + + if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags)) + ieee80211_ocb_housekeeping(sdata); + + sdata_unlock(sdata); +} + +static void ieee80211_ocb_housekeeping_timer(unsigned long data) +{ + struct ieee80211_sub_if_data *sdata = (void *)data; + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + + ieee80211_queue_work(&local->hw, &sdata->work); +} + +void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + setup_timer(&ifocb->housekeeping_timer, + ieee80211_ocb_housekeeping_timer, + (unsigned long)sdata); + INIT_LIST_HEAD(&ifocb->incomplete_stations); + spin_lock_init(&ifocb->incomplete_lock); +} + +int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, + struct ocb_setup *setup) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + u32 changed = BSS_CHANGED_OCB; + int err; + + if (ifocb->joined == true) + return -EINVAL; + + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; + sdata->smps_mode = IEEE80211_SMPS_OFF; + sdata->needed_rx_chains = sdata->local->rx_chains; + + mutex_lock(&sdata->local->mtx); + err = ieee80211_vif_use_channel(sdata, &setup->chandef, + IEEE80211_CHANCTX_SHARED); + mutex_unlock(&sdata->local->mtx); + if (err) + return err; + + ieee80211_bss_info_change_notify(sdata, changed); + + ifocb->joined = true; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + ieee80211_queue_work(&local->hw, &sdata->work); + + netif_carrier_on(sdata->dev); + return 0; +} + +int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + + ifocb->joined = false; + sta_info_flush(sdata); + + spin_lock_bh(&ifocb->incomplete_lock); + while (!list_empty(&ifocb->incomplete_stations)) { + sta = list_first_entry(&ifocb->incomplete_stations, + struct sta_info, list); + list_del(&sta->list); + spin_unlock_bh(&ifocb->incomplete_lock); + + sta_info_free(local, sta); + spin_lock_bh(&ifocb->incomplete_lock); + } + spin_unlock_bh(&ifocb->incomplete_lock); + + netif_carrier_off(sdata->dev); + clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB); + + mutex_lock(&sdata->local->mtx); + ieee80211_vif_release_channel(sdata); + mutex_unlock(&sdata->local->mtx); + + skb_queue_purge(&sdata->skb_queue); + + del_timer_sync(&sdata->u.ocb.housekeeping_timer); + /* If the timer fired while we waited for it, it will have + * requeued the work. Now the work will be running again + * but will not rearm the timer again because it checks + * whether we are connected to the network or not -- at this + * point we shouldn't be anymore. + */ + + return 0; +} diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b04ca4049c95..bc63aa0c5401 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1032,6 +1032,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) ieee80211_is_pspoll(hdr->frame_control)) && rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && rx->sdata->vif.type != NL80211_IFTYPE_WDS && + rx->sdata->vif.type != NL80211_IFTYPE_OCB && (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { /* * accept port control frames from the AP even when it's not @@ -1272,6 +1273,12 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->last_rx_rate_vht_nss = status->vht_nss; } } + } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { + u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, + NL80211_IFTYPE_OCB); + /* OCB uses wild-card BSSID */ + if (is_broadcast_ether_addr(bssid)) + sta->last_rx = jiffies; } else if (!is_multicast_ether_addr(hdr->addr1)) { /* * Mesh beacons will update last_rx when if they are found to @@ -2820,6 +2827,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) if (!ieee80211_vif_is_mesh(&sdata->vif) && sdata->vif.type != NL80211_IFTYPE_ADHOC && + sdata->vif.type != NL80211_IFTYPE_OCB && sdata->vif.type != NL80211_IFTYPE_STATION) return RX_DROP_MONITOR; @@ -3130,6 +3138,33 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, BIT(rate_idx)); } break; + case NL80211_IFTYPE_OCB: + if (!bssid) + return false; + if (ieee80211_is_beacon(hdr->frame_control)) { + return false; + } else if (!is_broadcast_ether_addr(bssid)) { + ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n"); + return false; + } else if (!multicast && + !ether_addr_equal(sdata->dev->dev_addr, + hdr->addr1)) { + /* if we are in promisc mode we also accept + * packets not destined for us + */ + if (!(sdata->dev->flags & IFF_PROMISC)) + return false; + rx->flags &= ~IEEE80211_RX_RA_MATCH; + } else if (!rx->sta) { + int rate_idx; + if (status->flag & RX_FLAG_HT) + rate_idx = 0; /* TODO: HT rates */ + else + rate_idx = status->rate_idx; + ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2, + BIT(rate_idx)); + } + break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 900632a250ec..3ffd91f295a6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -296,6 +296,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) */ return TX_DROP; + if (tx->sdata->vif.type == NL80211_IFTYPE_OCB) + return TX_CONTINUE; + if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) return TX_CONTINUE; @@ -2013,6 +2016,17 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, goto fail_rcu; band = chanctx_conf->def.chan->band; break; + case NL80211_IFTYPE_OCB: + /* DA SA BSSID */ + memcpy(hdr.addr1, skb->data, ETH_ALEN); + memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); + eth_broadcast_addr(hdr.addr3); + hdrlen = 24; + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + if (!chanctx_conf) + goto fail_rcu; + band = chanctx_conf->def.chan->band; + break; case NL80211_IFTYPE_ADHOC: /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -2057,6 +2071,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, * EAPOL frames from the local station. */ if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && + (sdata->vif.type != NL80211_IFTYPE_OCB) && !multicast && !authorized && (cpu_to_be16(ethertype) != sdata->control_port_protocol || !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d7d69c89ff34..91e16b4d4e3c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1101,6 +1101,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx_conf *chanctx_conf; int ac; bool use_11b, enable_qos; + bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */ int aCWmin, aCWmax; if (!local->ops->conf_tx) @@ -1125,6 +1126,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, */ enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); + is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB); + /* Set defaults according to 802.11-2007 Table 7-37 */ aCWmax = 1023; if (use_11b) @@ -1146,7 +1149,10 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; - qparam.aifs = 7; + if (is_ocb) + qparam.aifs = 9; + else + qparam.aifs = 7; break; /* never happens but let's not leave undefined */ default: @@ -1154,21 +1160,32 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; - qparam.aifs = 3; + if (is_ocb) + qparam.aifs = 6; + else + qparam.aifs = 3; break; case IEEE80211_AC_VI: qparam.cw_max = aCWmin; qparam.cw_min = (aCWmin + 1) / 2 - 1; - if (use_11b) + if (is_ocb) + qparam.txop = 0; + else if (use_11b) qparam.txop = 6016/32; else qparam.txop = 3008/32; - qparam.aifs = 2; + + if (is_ocb) + qparam.aifs = 3; + else + qparam.aifs = 2; break; case IEEE80211_AC_VO: qparam.cw_max = (aCWmin + 1) / 2 - 1; qparam.cw_min = (aCWmin + 1) / 4 - 1; - if (use_11b) + if (is_ocb) + qparam.txop = 0; + else if (use_11b) qparam.txop = 3264/32; else qparam.txop = 1504/32; @@ -1842,7 +1859,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) sdata_unlock(sdata); break; case NL80211_IFTYPE_OCB: - /* to be implemented in the future */ + changed |= BSS_CHANGED_OCB; + ieee80211_bss_info_change_notify(sdata, changed); break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index d3c5672d775f..fdf52db95b33 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -148,6 +148,10 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_ADHOC: ra = skb->data; break; + case NL80211_IFTYPE_OCB: + /* all stations are required to support WME */ + qos = true; + break; default: break; } -- cgit v1.2.3 From 8ed2874715c17f27bb7b9bacbcfa41bc88a64476 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Oct 2014 12:03:19 +0100 Subject: mac80211: handle RIC data element in reassociation request When the RIC data element (RDE) is included in the IEs coming from userspace for an association request, its handling is currently broken as any IEs that are contained within it would be split off from it and inserted again after all the IEs that mac80211 generates (e.g. HT, VHT.) To fix this, treat the RIC element specially, and stop after it only when we find something that doesn't actually belong to it. This assumes userspace is actually correctly building it, directly after the fast BSS transition IE and before all the others like extended capabilities. This leaves as a potential problem the case where userspace is building the following IEs: [RDE] [vendor resource description] [vendor non-resource IE] In this case, we'd erroneously consider all three IEs to be part of the RIC data together, and not split them between the two vendor IEs. Unfortunately, it isn't easily possible to distinguish vendor IEs, so this isn't easy to fix. Luckily, this case is rare as normally wpa_supplicant will include an extended capabilities IE in the IEs, and that certainly will break the two vendor IEs apart correctly. Reviewed-by: Eliad Peller Reviewed-by: Beni Lev Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 4 ++++ net/mac80211/mlme.c | 27 ++++++++++++++++++++++++--- net/mac80211/util.c | 26 ++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fbd6bee9c959..a51c993ece73 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1903,6 +1903,10 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); +size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, + const u8 *after_ric, int n_after_ric, + size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u16 cap); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c078cd344ca4..213a420704a6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -775,11 +775,30 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) WLAN_EID_QOS_CAPA, WLAN_EID_RRM_ENABLED_CAPABILITIES, WLAN_EID_MOBILITY_DOMAIN, + WLAN_EID_FAST_BSS_TRANSITION, /* reassoc only */ + WLAN_EID_RIC_DATA, /* reassoc only */ WLAN_EID_SUPPORTED_REGULATORY_CLASSES, }; - noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, - before_ht, ARRAY_SIZE(before_ht), - offset); + static const u8 after_ric[] = { + WLAN_EID_SUPPORTED_REGULATORY_CLASSES, + WLAN_EID_HT_CAPABILITY, + WLAN_EID_BSS_COEX_2040, + WLAN_EID_EXT_CAPABILITY, + WLAN_EID_QOS_TRAFFIC_CAPA, + WLAN_EID_TIM_BCAST_REQ, + WLAN_EID_INTERWORKING, + /* 60GHz doesn't happen right now */ + WLAN_EID_VHT_CAPABILITY, + WLAN_EID_OPMODE_NOTIF, + }; + + noffset = ieee80211_ie_split_ric(assoc_data->ie, + assoc_data->ie_len, + before_ht, + ARRAY_SIZE(before_ht), + after_ric, + ARRAY_SIZE(after_ric), + offset); pos = skb_put(skb, noffset - offset); memcpy(pos, assoc_data->ie + offset, noffset - offset); offset = noffset; @@ -813,6 +832,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) WLAN_EID_TIM_BCAST_REQ, WLAN_EID_INTERWORKING, }; + + /* RIC already taken above, so no need to handle here anymore */ noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, before_vht, ARRAY_SIZE(before_vht), offset); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 91e16b4d4e3c..5f7b0e935b65 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2101,16 +2101,34 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } -size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset) +size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, + const u8 *after_ric, int n_after_ric, + size_t offset) { size_t pos = offset; - while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) - pos += 2 + ies[pos + 1]; + while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { + if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { + pos += 2 + ies[pos + 1]; + + while (pos < ielen && + !ieee80211_id_in_list(after_ric, n_after_ric, + ies[pos])) + pos += 2 + ies[pos + 1]; + } else { + pos += 2 + ies[pos + 1]; + } + } return pos; } + +size_t ieee80211_ie_split(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, size_t offset) +{ + return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset); +} EXPORT_SYMBOL(ieee80211_ie_split); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) -- cgit v1.2.3 From 13a8098af93e31788684c1f2682739beb93dc680 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Tue, 4 Nov 2014 11:33:04 +0200 Subject: mac80211: increase U-APSD max service period length Deliver up to 128 frames during service period instead of 8 if unlimited is specified by the client during association. 8 was just an arbitrary value; so is 128 since unlimited can be any number. However for large traffic bursts, increasing this value looks reasonable. Also, it seems that a few certification tests expect more frames to be delivered during SP. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 2cd48cefcbdc..adc25371b171 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1531,7 +1531,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta) break; case 0: /* XXX: what is a good value? */ - n_frames = 8; + n_frames = 128; break; } -- cgit v1.2.3 From cf2c92d840c1424bcb3bb501147c79c9b067ad77 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 4 Nov 2014 11:43:54 +0200 Subject: mac80211: replace restart_complete() with reconfig_complete() Drivers might want to know also when mac80211 has completed reconfiguring after resume (e.g. in order to know when frames can be passed to mac80211). Rename restart_complete() to a more-generic reconfig_complete(), and add a new enum to indicate the reconfiguration type. Update the current users with the new prototype. Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 8 ++++++-- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 +++++++++++++++++--- include/net/mac80211.h | 29 +++++++++++++++++++++++------ net/mac80211/driver-ops.h | 10 ++++++---- net/mac80211/trace.h | 23 ++++++++++++++++++++--- net/mac80211/util.c | 5 ++++- 7 files changed, 77 insertions(+), 20 deletions(-) (limited to 'net') diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fe531ea6926c..cc8f1fc65044 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -321,7 +321,7 @@ enum ath10k_state { * stopped in ath10k_core_restart() work holding conf_mutex. The state * RESTARTED means that the device is up and mac80211 has started hw * reconfiguration. Once mac80211 is done with the reconfiguration we - * set the state to STATE_ON in restart_complete(). */ + * set the state to STATE_ON in reconfig_complete(). */ ATH10K_STATE_RESTARTING, ATH10K_STATE_RESTARTED, diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 46709301a51e..f57459a2f51a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3929,10 +3929,14 @@ exit: } #endif -static void ath10k_restart_complete(struct ieee80211_hw *hw) +static void ath10k_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) { struct ath10k *ar = hw->priv; + if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) + return; + mutex_lock(&ar->conf_mutex); /* If device failed to restart it will be in a different state, e.g. @@ -4450,7 +4454,7 @@ static const struct ieee80211_ops ath10k_ops = { .tx_last_beacon = ath10k_tx_last_beacon, .set_antenna = ath10k_set_antenna, .get_antenna = ath10k_get_antenna, - .restart_complete = ath10k_restart_complete, + .reconfig_complete = ath10k_reconfig_complete, .get_survey = ath10k_get_survey, .set_bitrate_mask = ath10k_set_bitrate_mask, .sta_rc_update = ath10k_sta_rc_update, diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c7a73c68bdab..e16c29dc9d49 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -857,9 +857,8 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw) return ret; } -static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) +static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; mutex_lock(&mvm->mutex); @@ -877,6 +876,21 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) mutex_unlock(&mvm->mutex); } +static void +iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + + switch (reconfig_type) { + case IEEE80211_RECONFIG_TYPE_RESTART: + iwl_mvm_restart_complete(mvm); + break; + case IEEE80211_RECONFIG_TYPE_SUSPEND: + break; + } +} + void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) { lockdep_assert_held(&mvm->mutex); @@ -3014,7 +3028,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, .ampdu_action = iwl_mvm_mac_ampdu_action, .start = iwl_mvm_mac_start, - .restart_complete = iwl_mvm_mac_restart_complete, + .reconfig_complete = iwl_mvm_mac_reconfig_complete, .stop = iwl_mvm_mac_stop, .add_interface = iwl_mvm_mac_add_interface, .remove_interface = iwl_mvm_mac_remove_interface, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index db54635d65c5..5f203a6a5e7e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2388,6 +2388,22 @@ enum ieee80211_roc_type { IEEE80211_ROC_TYPE_MGMT_TX, }; +/** + * enum ieee80211_reconfig_complete_type - reconfig type + * + * This enum is used by the reconfig_complete() callback to indicate what + * reconfiguration type was completed. + * + * @IEEE80211_RECONFIG_TYPE_RESTART: hw restart type + * (also due to resume() callback returning 1) + * @IEEE80211_RECONFIG_TYPE_SUSPEND: suspend type (regardless + * of wowlan configuration) + */ +enum ieee80211_reconfig_type { + IEEE80211_RECONFIG_TYPE_RESTART, + IEEE80211_RECONFIG_TYPE_SUSPEND, +}; + /** * struct ieee80211_ops - callbacks from mac80211 to the driver * @@ -2823,11 +2839,11 @@ enum ieee80211_roc_type { * disabled/enabled via @bss_info_changed. * @stop_ap: Stop operation on the AP interface. * - * @restart_complete: Called after a call to ieee80211_restart_hw(), when the - * reconfiguration has completed. This can help the driver implement the - * reconfiguration step. Also called when reconfiguring because the - * driver's resume function returned 1, as this is just like an "inline" - * hardware restart. This callback may sleep. + * @reconfig_complete: Called after a call to ieee80211_restart_hw() and + * during resume, when the reconfiguration has completed. + * This can help the driver implement the reconfiguration step (and + * indicate mac80211 is ready to receive frames). + * This callback may sleep. * * @ipv6_addr_change: IPv6 address assignment on the given interface changed. * Currently, this is only called for managed or P2P client interfaces. @@ -3050,7 +3066,8 @@ struct ieee80211_ops { int n_vifs, enum ieee80211_chanctx_switch_mode mode); - void (*restart_complete)(struct ieee80211_hw *hw); + void (*reconfig_complete)(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type); #if IS_ENABLED(CONFIG_IPV6) void (*ipv6_addr_change)(struct ieee80211_hw *hw, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 8e1889ff2e53..9759dd1f0734 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1152,13 +1152,15 @@ static inline void drv_stop_ap(struct ieee80211_local *local, trace_drv_return_void(local); } -static inline void drv_restart_complete(struct ieee80211_local *local) +static inline void +drv_reconfig_complete(struct ieee80211_local *local, + enum ieee80211_reconfig_type reconfig_type) { might_sleep(); - trace_drv_restart_complete(local); - if (local->ops->restart_complete) - local->ops->restart_complete(&local->hw); + trace_drv_reconfig_complete(local, reconfig_type); + if (local->ops->reconfig_complete) + local->ops->reconfig_complete(&local->hw, reconfig_type); trace_drv_return_void(local); } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index aeeace5ba47b..809a4983eb4a 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1562,9 +1562,26 @@ DEFINE_EVENT(local_sdata_evt, drv_stop_ap, TP_ARGS(local, sdata) ); -DEFINE_EVENT(local_only_evt, drv_restart_complete, - TP_PROTO(struct ieee80211_local *local), - TP_ARGS(local) +TRACE_EVENT(drv_reconfig_complete, + TP_PROTO(struct ieee80211_local *local, + enum ieee80211_reconfig_type reconfig_type), + TP_ARGS(local, reconfig_type), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u8, reconfig_type) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->reconfig_type = reconfig_type; + ), + + TP_printk( + LOCAL_PR_FMT " reconfig_type:%d", + LOCAL_PR_ARG, __entry->reconfig_type + ) + ); #if IS_ENABLED(CONFIG_IPV6) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5f7b0e935b65..f9319a5dca64 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1998,7 +1998,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) * We may want to change that later, however. */ if (!local->suspended || reconfig_due_to_wowlan) - drv_restart_complete(local); + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); if (!local->suspended) return 0; @@ -2009,6 +2009,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) mb(); local->resuming = false; + if (!reconfig_due_to_wowlan) + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); + list_for_each_entry(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; -- cgit v1.2.3