From 2944f45d9db851e186774df7c9cbf075f4a585c6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Sep 2010 18:37:20 +0200 Subject: mac80211: add a note about iterating interfaces during add_interface() Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/mac80211.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f91fc331369b..19a5cb4a6582 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2293,6 +2293,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted); * This function allows the iterator function to sleep, when the iterator * function is atomic @ieee80211_iterate_active_interfaces_atomic can * be used. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call @@ -2310,6 +2311,7 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, * hardware that are currently active and calls the callback for them. * This function requires the iterator callback function to be atomic, * if that is not desired, use @ieee80211_iterate_active_interfaces instead. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call, cannot sleep -- cgit v1.2.3 From 9c376639297d3dd82d40e54c9cdca8da9dfc22f1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 20 Aug 2010 15:13:59 -0700 Subject: include/net/cfg80211.h: wiphy_ messages use dev_printk The output becomes: [ 41.261941] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- include/net/cfg80211.h | 37 ++++++++++++------------------------- net/wireless/core.c | 49 ------------------------------------------------- 2 files changed, 12 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4c8c727d0cca..a0613ff62c97 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2558,49 +2558,36 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, /* wiphy_printk helpers, similar to dev_printk */ #define wiphy_printk(level, wiphy, format, args...) \ - printk(level "%s: " format, wiphy_name(wiphy), ##args) + dev_printk(level, &(wiphy)->dev, format, ##args) #define wiphy_emerg(wiphy, format, args...) \ - wiphy_printk(KERN_EMERG, wiphy, format, ##args) + dev_emerg(&(wiphy)->dev, format, ##args) #define wiphy_alert(wiphy, format, args...) \ - wiphy_printk(KERN_ALERT, wiphy, format, ##args) + dev_alert(&(wiphy)->dev, format, ##args) #define wiphy_crit(wiphy, format, args...) \ - wiphy_printk(KERN_CRIT, wiphy, format, ##args) + dev_crit(&(wiphy)->dev, format, ##args) #define wiphy_err(wiphy, format, args...) \ - wiphy_printk(KERN_ERR, wiphy, format, ##args) + dev_err(&(wiphy)->dev, format, ##args) #define wiphy_warn(wiphy, format, args...) \ - wiphy_printk(KERN_WARNING, wiphy, format, ##args) + dev_warn(&(wiphy)->dev, format, ##args) #define wiphy_notice(wiphy, format, args...) \ - wiphy_printk(KERN_NOTICE, wiphy, format, ##args) + dev_notice(&(wiphy)->dev, format, ##args) #define wiphy_info(wiphy, format, args...) \ - wiphy_printk(KERN_INFO, wiphy, format, ##args) + dev_info(&(wiphy)->dev, format, ##args) -int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - -#if defined(DEBUG) -#define wiphy_dbg(wiphy, format, args...) \ +#define wiphy_debug(wiphy, format, args...) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args) -#elif defined(CONFIG_DYNAMIC_DEBUG) + #define wiphy_dbg(wiphy, format, args...) \ - dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args) -#else -#define wiphy_dbg(wiphy, format, args...) \ -({ \ - if (0) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ -}) -#endif + dev_dbg(&(wiphy)->dev, format, ##args) #if defined(VERBOSE_DEBUG) #define wiphy_vdbg wiphy_dbg #else - #define wiphy_vdbg(wiphy, format, args...) \ ({ \ if (0) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ + 0; \ }) #endif diff --git a/net/wireless/core.c b/net/wireless/core.c index d52630bbab04..b8191cf86226 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -912,52 +912,3 @@ static void __exit cfg80211_exit(void) destroy_workqueue(cfg80211_wq); } module_exit(cfg80211_exit); - -static int ___wiphy_printk(const char *level, const struct wiphy *wiphy, - struct va_format *vaf) -{ - if (!wiphy) - return printk("%s(NULL wiphy *): %pV", level, vaf); - - return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf); -} - -int __wiphy_printk(const char *level, const struct wiphy *wiphy, - const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - int r; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - r = ___wiphy_printk(level, wiphy, &vaf); - va_end(args); - - return r; -} -EXPORT_SYMBOL(__wiphy_printk); - -#define define_wiphy_printk_level(func, kern_level) \ -int func(const struct wiphy *wiphy, const char *fmt, ...) \ -{ \ - struct va_format vaf; \ - va_list args; \ - int r; \ - \ - va_start(args, fmt); \ - \ - vaf.fmt = fmt; \ - vaf.va = &args; \ - \ - r = ___wiphy_printk(kern_level, wiphy, &vaf); \ - va_end(args); \ - \ - return r; \ -} \ -EXPORT_SYMBOL(func); - -define_wiphy_printk_level(wiphy_debug, KERN_DEBUG); -- cgit v1.2.3 From 074ac8df9f93f2a35a356d92fd7f16cd846f0a03 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Sep 2010 14:58:22 +0200 Subject: cfg80211/nl80211: introduce p2p device types This adds P2P-STA and P2P-GO as device types so we can distinguish between those and normal STA or AP (respectively) type interfaces. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ net/wireless/core.c | 2 ++ net/wireless/mlme.c | 3 ++- net/wireless/nl80211.c | 56 ++++++++++++++++++++++++++++++++++--------------- net/wireless/sme.c | 9 +++++--- net/wireless/util.c | 15 ++++++++++--- 6 files changed, 65 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 31603e8b5581..f0518b0278a9 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1020,6 +1020,8 @@ enum nl80211_attrs { * @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -1036,6 +1038,8 @@ enum nl80211_iftype { NL80211_IFTYPE_WDS, NL80211_IFTYPE_MONITOR, NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, /* keep last */ NUM_NL80211_IFTYPES, diff --git a/net/wireless/core.c b/net/wireless/core.c index b8191cf86226..ff9615a7ee7a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -726,6 +726,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, dev->ethtool_ops = &cfg80211_ethtool_ops; if ((wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) dev->priv_flags |= IFF_DONT_BRIDGE; break; @@ -734,6 +735,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, true); break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: wdev_lock(wdev); #ifdef CONFIG_CFG80211_WEXT diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 8515b1e5c578..46f371160896 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -882,7 +882,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, if (!wdev->current_bss || memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, ETH_ALEN) != 0 || - (wdev->iftype == NL80211_IFTYPE_STATION && + ((wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && memcmp(wdev->current_bss->pub.bssid, mgmt->da, ETH_ALEN) != 0)) { wdev_unlock(wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1d6ef24254fe..f15b1af2c768 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -410,12 +410,14 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: break; case NL80211_IFTYPE_ADHOC: if (!wdev->current_bss) return -ENOLINK; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: if (wdev->sme_state != CFG80211_SME_CONNECTED) return -ENOLINK; break; @@ -766,7 +768,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_WDS || wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_MONITOR; + wdev->iftype == NL80211_IFTYPE_MONITOR || + wdev->iftype == NL80211_IFTYPE_P2P_GO; } static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, @@ -1693,7 +1696,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -1785,7 +1789,8 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -2128,10 +2133,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) switch (dev->ieee80211_ptr->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: /* disallow mesh-specific things */ if (params.plink_action) err = -EINVAL; break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: /* disallow everything but AUTHORIZED flag */ if (params.plink_action) @@ -2233,7 +2240,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) goto out_rtnl; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EINVAL; goto out; } @@ -2286,7 +2294,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EINVAL; goto out; } @@ -2660,7 +2669,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -3363,6 +3373,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, } switch (wdev->iftype) { + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: if (intbss == wdev->current_bss) NLA_PUT_U32(msg, NL80211_BSS_STATUS, @@ -3649,7 +3660,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3804,7 +3816,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3888,7 +3901,8 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3954,7 +3968,8 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4332,7 +4347,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4408,7 +4424,8 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4496,7 +4513,8 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4541,7 +4559,8 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) if (err) goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4823,7 +4842,8 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) goto unlock_rtnl; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4875,7 +4895,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) } if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -5093,7 +5114,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, goto unlock_rdev; } - if (wdev->iftype != NL80211_IFTYPE_STATION) { + if (wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto unlock_rdev; } diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a8c2d6b877ae..f161b9844542 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTING) @@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) @@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) diff --git a/net/wireless/util.c b/net/wireless/util.c index bca32eb8f446..fb5448f7d55a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -326,7 +326,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { case cpu_to_le16(IEEE80211_FCTL_TODS): if (unlikely(iftype != NL80211_IFTYPE_AP && - iftype != NL80211_IFTYPE_AP_VLAN)) + iftype != NL80211_IFTYPE_AP_VLAN && + iftype != NL80211_IFTYPE_P2P_GO)) return -1; break; case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): @@ -354,7 +355,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, break; case cpu_to_le16(IEEE80211_FCTL_FROMDS): if ((iftype != NL80211_IFTYPE_STATION && - iftype != NL80211_IFTYPE_MESH_POINT) || + iftype != NL80211_IFTYPE_P2P_CLIENT && + iftype != NL80211_IFTYPE_MESH_POINT) || (is_multicast_ether_addr(dst) && !compare_ether_addr(src, addr))) return -1; @@ -431,6 +433,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); /* DA BSSID SA */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -439,6 +442,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, hdrlen = 24; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: fc |= cpu_to_le16(IEEE80211_FCTL_TODS); /* BSSID SA DA */ memcpy(hdr.addr1, bssid, ETH_ALEN); @@ -778,7 +782,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* if it's part of a bridge, reject changing type to station/ibss */ if ((dev->priv_flags & IFF_BRIDGE_PORT) && - (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) + (ntype == NL80211_IFTYPE_ADHOC || + ntype == NL80211_IFTYPE_STATION || + ntype == NL80211_IFTYPE_P2P_CLIENT)) return -EBUSY; if (ntype != otype) { @@ -789,6 +795,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, cfg80211_leave_ibss(rdev, dev, false); break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: cfg80211_disconnect(rdev, dev, WLAN_REASON_DEAUTH_LEAVING, true); break; @@ -817,9 +824,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->use_4addr) break; /* fall through */ + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_ADHOC: dev->priv_flags |= IFF_DONT_BRIDGE; break; + case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: -- cgit v1.2.3 From 2ca27bcff7127da1aa7dd39cd2a6f7cb187e327f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Sep 2010 14:58:23 +0200 Subject: mac80211: add p2p device type support When a driver advertises p2p device support, mac80211 will handle it, but internally it will rewrite the interface type to STA/AP rather than P2P-STA/GO since otherwise a lot of paths need to be touched that are otherwise identical. A p2p boolean tells drivers whether or not a given interface will be used for p2p or not. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 15 +++++++++++---- include/net/mac80211.h | 27 ++++++++++++++++++++++++++- net/mac80211/cfg.c | 25 ++++++++++++++++++------- net/mac80211/driver-ops.h | 6 +++--- net/mac80211/driver-trace.h | 21 +++++++++++++-------- net/mac80211/iface.c | 29 ++++++++++++++++++++++++++--- net/mac80211/main.c | 15 +++++++++++++++ net/mac80211/rx.c | 4 +--- net/mac80211/util.c | 18 ++++-------------- 9 files changed, 117 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 92b486d46eb9..7eaaa3bab547 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -595,7 +595,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_set_magic(vif); return 0; } @@ -603,11 +604,14 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum nl80211_iftype newtype) + enum nl80211_iftype newtype, + bool newp2p) { + newtype = ieee80211_iftype_p2p(newtype, newp2p); wiphy_debug(hw->wiphy, "%s (old type=%d, new type=%d, mac_addr=%pM)\n", - __func__, vif->type, newtype, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + newtype, vif->addr); hwsim_check_magic(vif); return 0; @@ -617,7 +621,8 @@ static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_check_magic(vif); hwsim_clear_magic(vif); } @@ -1310,6 +1315,8 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 19a5cb4a6582..12a49f0ba32c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -769,6 +769,8 @@ struct ieee80211_channel_switch { * @bss_conf: BSS configuration for this interface, either our own * or the BSS we're associated to * @addr: address of this interface + * @p2p: indicates whether this AP or STA interface is a p2p + * interface, i.e. a GO or p2p-sta respectively * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -776,6 +778,7 @@ struct ieee80211_vif { enum nl80211_iftype type; struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN]; + bool p2p; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -1701,7 +1704,7 @@ struct ieee80211_ops { struct ieee80211_vif *vif); int (*change_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum nl80211_iftype new_type); + enum nl80211_iftype new_type, bool p2p); void (*remove_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int (*config)(struct ieee80211_hw *hw, u32 changed); @@ -2721,4 +2724,26 @@ conf_is_ht(struct ieee80211_conf *conf) return conf->channel_type != NL80211_CHAN_NO_HT; } +static inline enum nl80211_iftype +ieee80211_iftype_p2p(enum nl80211_iftype type, bool p2p) +{ + if (p2p) { + switch (type) { + case NL80211_IFTYPE_STATION: + return NL80211_IFTYPE_P2P_CLIENT; + case NL80211_IFTYPE_AP: + return NL80211_IFTYPE_P2P_GO; + default: + break; + } + } + return type; +} + +static inline enum nl80211_iftype +ieee80211_vif_type_p2p(struct ieee80211_vif *vif) +{ + return ieee80211_iftype_p2p(vif->type, vif->p2p); +} + #endif /* MAC80211_H */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 171e8ff8e028..c981604b71e6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1151,15 +1151,26 @@ static int ieee80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *req) { - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) + switch (ieee80211_vif_type_p2p(&sdata->vif)) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_P2P_CLIENT: + break; + case NL80211_IFTYPE_P2P_GO: + if (sdata->local->ops->hw_scan) + break; + /* FIXME: implement NoA while scanning in software */ + return -EOPNOTSUPP; + case NL80211_IFTYPE_AP: + if (sdata->u.ap.beacon) + return -EOPNOTSUPP; + break; + default: return -EOPNOTSUPP; + } return ieee80211_request_scan(sdata, req); } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 6064b7b09e01..16983825f8e8 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -56,14 +56,14 @@ static inline int drv_add_interface(struct ieee80211_local *local, static inline int drv_change_interface(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - enum nl80211_iftype type) + enum nl80211_iftype type, bool p2p) { int ret; might_sleep(); - trace_drv_change_interface(local, sdata, type); - ret = local->ops->change_interface(&local->hw, &sdata->vif, type); + trace_drv_change_interface(local, sdata, type, p2p); + ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); trace_drv_return_int(local, ret); return ret; } diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index f6f3d89e43fa..6831fb1641c8 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -25,12 +25,14 @@ static inline void trace_ ## name(proto) {} #define STA_PR_FMT " sta:%pM" #define STA_PR_ARG __entry->sta_addr -#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ +#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ + __field(bool, p2p) \ __string(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ +#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ + __entry->p2p = sdata->vif.p2p; \ __assign_str(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_PR_FMT " vif:%s(%d)" -#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type +#define VIF_PR_FMT " vif:%s(%d%s)" +#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" /* * Tracing for driver callbacks. @@ -139,25 +141,28 @@ TRACE_EVENT(drv_add_interface, TRACE_EVENT(drv_change_interface, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - enum nl80211_iftype type), + enum nl80211_iftype type, bool p2p), - TP_ARGS(local, sdata, type), + TP_ARGS(local, sdata, type, p2p), TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY __field(u32, new_type) + __field(bool, new_p2p) ), TP_fast_assign( LOCAL_ASSIGN; VIF_ASSIGN; __entry->new_type = type; + __entry->new_p2p = p2p; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " new type:%d", - LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type + LOCAL_PR_FMT VIF_PR_FMT " new type:%d%s", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type, + __entry->new_p2p ? "/p2p" : "" ) ); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 95908aaa8a68..66785739dad3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -188,6 +188,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: /* cannot happen */ WARN_ON(1); break; @@ -844,6 +846,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, /* and set some type-dependent values */ sdata->vif.type = type; + sdata->vif.p2p = false; sdata->dev->netdev_ops = &ieee80211_dataif_ops; sdata->wdev.iftype = type; @@ -857,10 +860,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, INIT_WORK(&sdata->work, ieee80211_iface_work); switch (type) { + case NL80211_IFTYPE_P2P_GO: + type = NL80211_IFTYPE_AP; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_AP: skb_queue_head_init(&sdata->u.ap.ps_bc_buf); INIT_LIST_HEAD(&sdata->u.ap.vlans); break; + case NL80211_IFTYPE_P2P_CLIENT: + type = NL80211_IFTYPE_STATION; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_STATION: ieee80211_sta_setup_sdata(sdata); break; @@ -894,6 +907,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; int ret, err; + enum nl80211_iftype internal_type = type; + bool p2p = false; ASSERT_RTNL(); @@ -926,11 +941,19 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, * code isn't prepared to handle). */ break; + case NL80211_IFTYPE_P2P_CLIENT: + p2p = true; + internal_type = NL80211_IFTYPE_STATION; + break; + case NL80211_IFTYPE_P2P_GO: + p2p = true; + internal_type = NL80211_IFTYPE_AP; + break; default: return -EBUSY; } - ret = ieee80211_check_concurrent_iface(sdata, type); + ret = ieee80211_check_concurrent_iface(sdata, internal_type); if (ret) return ret; @@ -938,7 +961,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ieee80211_teardown_sdata(sdata->dev); - ret = drv_change_interface(local, sdata, type); + ret = drv_change_interface(local, sdata, internal_type, p2p); if (ret) type = sdata->vif.type; @@ -957,7 +980,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, ASSERT_RTNL(); - if (type == sdata->vif.type) + if (type == ieee80211_vif_type_p2p(&sdata->vif)) return 0; /* Setting ad-hoc mode on non-IBSS channel is not supported. */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7fb114856977..18fdeca43d98 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -459,6 +459,21 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4), }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, }; struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ac205a33690f..c0368152b721 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2588,9 +2588,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_UNSPECIFIED: - case NUM_NL80211_IFTYPES: + default: /* should never get here */ WARN_ON(1); break; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9f21a69f0917..737f4267c335 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -474,16 +474,10 @@ void ieee80211_iterate_active_interfaces( list_for_each_entry(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -508,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic( list_for_each_entry_rcu(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -1193,6 +1181,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: WARN_ON(1); break; } -- cgit v1.2.3 From c1f9a095600e07fefe64eb94eb711f410100824a Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 13:16:02 +0200 Subject: wl12xx: make wl12xx.h common to both spi and sdio Move wl12xx.h outside of the spi-specific location, so it can be shared with both spi and sdio solutions. Update all users of spi/wl12xx.h accordingly Signed-off-by: Ohad Ben-Cohen Acked-by: Luciano Coelho Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- arch/arm/mach-omap2/board-omap3pandora.c | 1 + arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- drivers/net/wireless/wl12xx/wl1251_sdio.c | 2 +- drivers/net/wireless/wl12xx/wl1251_spi.c | 2 +- drivers/net/wireless/wl12xx/wl1271_spi.c | 2 +- include/linux/spi/wl12xx.h | 34 ---------------------------- include/linux/wl12xx.h | 34 ++++++++++++++++++++++++++++ 8 files changed, 40 insertions(+), 39 deletions(-) delete mode 100644 include/linux/spi/wl12xx.h create mode 100644 include/linux/wl12xx.h (limited to 'include') diff --git a/MAINTAINERS b/MAINTAINERS index 80cea03a737e..e9aec08e575a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6324,7 +6324,7 @@ W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/wl12xx/wl1271* -F: include/linux/spi/wl12xx.h +F: include/linux/wl12xx.h WL3501 WIRELESS PCMCIA CARD DRIVER M: Arnaldo Carvalho de Melo diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index c0f4f12eba54..9b62b6283c6e 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 03483920ed6e..1cf994299cbe 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index c0b68b0a9aa8..74ba9ced5393 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "wl1251.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 334ded9881c0..320de79667a6 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "wl1251.h" #include "wl1251_reg.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 4cb99c541e2a..c3fdab75ad2a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "wl1271.h" diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h deleted file mode 100644 index a20bccf0b5c2..000000000000 --- a/include/linux/spi/wl12xx.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * 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. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef _LINUX_SPI_WL12XX_H -#define _LINUX_SPI_WL12XX_H - -struct wl12xx_platform_data { - void (*set_power)(bool enable); - /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ - int irq; - bool use_eeprom; -}; - -#endif diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h new file mode 100644 index 000000000000..015687a1776d --- /dev/null +++ b/include/linux/wl12xx.h @@ -0,0 +1,34 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * 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. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef _LINUX_WL12XX_H +#define _LINUX_WL12XX_H + +struct wl12xx_platform_data { + void (*set_power)(bool enable); + /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ + int irq; + bool use_eeprom; +}; + +#endif -- cgit v1.2.3 From 61ee7007a5d61aa066076da578e8e8084e122d7d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:31:12 +0200 Subject: wl12xx: add platform data passing support Add a simple mechanism to pass platform data to the SDIO instances of wl12xx. This way there is no confusion over who owns the 'embedded data', typechecking is preserved, and no possibility for the wrong driver to pick up the data. Originally proposed by Russell King. Signed-off-by: Ohad Ben-Cohen Signed-off-by: John W. Linville --- drivers/net/wireless/Makefile | 2 ++ drivers/net/wireless/wl12xx/Kconfig | 5 +++- drivers/net/wireless/wl12xx/wl12xx_platform_data.c | 28 ++++++++++++++++++++++ include/linux/wl12xx.h | 3 +++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/wl12xx/wl12xx_platform_data.c (limited to 'include') diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 5d4ce4d2b32b..85af697574a6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -50,5 +50,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o obj-$(CONFIG_WL12XX) += wl12xx/ +# small builtin driver bit +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/wl12xx_platform_data.o obj-$(CONFIG_IWM) += iwmc3200wifi/ diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 2f98058be451..4a8bb25c1739 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -74,4 +74,7 @@ config WL1271_SDIO If you choose to build a module, it'll be called wl1271_sdio. Say N if unsure. - +config WL12XX_PLATFORM_DATA + bool + depends on WL1271_SDIO != n + default y diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c new file mode 100644 index 000000000000..973b11060a8f --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c @@ -0,0 +1,28 @@ +#include +#include +#include + +static const struct wl12xx_platform_data *platform_data; + +int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + if (platform_data) + return -EBUSY; + if (!data) + return -EINVAL; + + platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!platform_data) + return -ENOMEM; + + return 0; +} + +const struct wl12xx_platform_data *wl12xx_get_platform_data(void) +{ + if (!platform_data) + return ERR_PTR(-ENODEV); + + return platform_data; +} +EXPORT_SYMBOL(wl12xx_get_platform_data); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 015687a1776d..bd70563107fa 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -31,4 +31,7 @@ struct wl12xx_platform_data { bool use_eeprom; }; +int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); +const struct wl12xx_platform_data *wl12xx_get_platform_data(void); + #endif -- cgit v1.2.3 From 15cea99306ae14ce5f7c3d3989bcc17202e2b0be Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:31:51 +0200 Subject: wl1271: make ref_clock configurable by board The wl1271 device is using a reference clock that may change between board to board. Make the ref_clock parameter configurable by board settings instead of having a hard coded value in the sources. Signed-off-by: Ohad Ben-Cohen Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_boot.c | 11 +++++++---- drivers/net/wireless/wl12xx/wl1271_boot.h | 1 - drivers/net/wireless/wl12xx/wl1271_sdio.c | 1 + drivers/net/wireless/wl12xx/wl1271_spi.c | 2 ++ include/linux/wl12xx.h | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index faa5925efe30..4134f4495b95 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -330,6 +330,7 @@ struct wl1271 { void (*set_power)(bool enable); int irq; + int ref_clock; spinlock_t wl_lock; diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index f36430b0336d..fc21db810812 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -457,17 +457,20 @@ int wl1271_boot(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; + int ref_clock = wl->ref_clock; wl1271_boot_hw_version(wl); - if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4) + if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; - else if (REF_CLOCK == 1 || REF_CLOCK == 3) + else if (ref_clock == 1 || ref_clock == 3) /* ref clk: 26/52 */ clk = 0x5; + else + return -EINVAL; - if (REF_CLOCK != 0) { + if (ref_clock != 0) { u16 val; /* Set clock type (open drain) */ val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); @@ -516,7 +519,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); /* 2 */ - clk |= (REF_CLOCK << 1) << 4; + clk |= (ref_clock << 1) << 4; wl1271_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, &part_table[PART_WORK]); diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h index f829699d597e..f73b0b15a280 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.h +++ b/drivers/net/wireless/wl12xx/wl1271_boot.h @@ -46,7 +46,6 @@ struct wl1271_static_data { /* delay between retries */ #define INIT_LOOP_DELAY 50 -#define REF_CLOCK 2 #define WU_COUNTER_PAUSE_VAL 0x3FF #define WELP_ARM_COMMAND_VAL 0x4 diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 987ecdc9406d..f2f04663627c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -234,6 +234,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, } wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index de56d8d9ee66..ced0a9e2c7e1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -372,6 +372,8 @@ static int __devinit wl1271_probe(struct spi_device *spi) goto out_free; } + wl->ref_clock = pdata->board_ref_clock; + wl->irq = spi->irq; if (wl->irq < 0) { wl1271_error("irq missing in platform data"); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index bd70563107fa..95deae3968f4 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -29,6 +29,7 @@ struct wl12xx_platform_data { /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; + int board_ref_clock; }; int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); -- cgit v1.2.3