diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 7fa71f73cfe8..571f013cebbb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -3155,7 +3155,9 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, | |||
3155 | } | 3155 | } |
3156 | 3156 | ||
3157 | #ifdef CONFIG_NL80211_TESTMODE | 3157 | #ifdef CONFIG_NL80211_TESTMODE |
3158 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) | 3158 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, |
3159 | struct wireless_dev *wdev, | ||
3160 | void *data, int len) | ||
3159 | { | 3161 | { |
3160 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3162 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
3161 | struct net_device *ndev = cfg_to_ndev(cfg); | 3163 | struct net_device *ndev = cfg_to_ndev(cfg); |
@@ -4126,6 +4128,53 @@ static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy, | |||
4126 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | 4128 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); |
4127 | } | 4129 | } |
4128 | 4130 | ||
4131 | static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper) | ||
4132 | { | ||
4133 | int ret; | ||
4134 | |||
4135 | switch (oper) { | ||
4136 | case NL80211_TDLS_DISCOVERY_REQ: | ||
4137 | ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY; | ||
4138 | break; | ||
4139 | case NL80211_TDLS_SETUP: | ||
4140 | ret = BRCMF_TDLS_MANUAL_EP_CREATE; | ||
4141 | break; | ||
4142 | case NL80211_TDLS_TEARDOWN: | ||
4143 | ret = BRCMF_TDLS_MANUAL_EP_DELETE; | ||
4144 | break; | ||
4145 | default: | ||
4146 | brcmf_err("unsupported operation: %d\n", oper); | ||
4147 | ret = -EOPNOTSUPP; | ||
4148 | } | ||
4149 | return ret; | ||
4150 | } | ||
4151 | |||
4152 | static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy, | ||
4153 | struct net_device *ndev, u8 *peer, | ||
4154 | enum nl80211_tdls_operation oper) | ||
4155 | { | ||
4156 | struct brcmf_if *ifp; | ||
4157 | struct brcmf_tdls_iovar_le info; | ||
4158 | int ret = 0; | ||
4159 | |||
4160 | ret = brcmf_convert_nl80211_tdls_oper(oper); | ||
4161 | if (ret < 0) | ||
4162 | return ret; | ||
4163 | |||
4164 | ifp = netdev_priv(ndev); | ||
4165 | memset(&info, 0, sizeof(info)); | ||
4166 | info.mode = (u8)ret; | ||
4167 | if (peer) | ||
4168 | memcpy(info.ea, peer, ETH_ALEN); | ||
4169 | |||
4170 | ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint", | ||
4171 | &info, sizeof(info)); | ||
4172 | if (ret < 0) | ||
4173 | brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret); | ||
4174 | |||
4175 | return ret; | ||
4176 | } | ||
4177 | |||
4129 | static struct cfg80211_ops wl_cfg80211_ops = { | 4178 | static struct cfg80211_ops wl_cfg80211_ops = { |
4130 | .add_virtual_intf = brcmf_cfg80211_add_iface, | 4179 | .add_virtual_intf = brcmf_cfg80211_add_iface, |
4131 | .del_virtual_intf = brcmf_cfg80211_del_iface, | 4180 | .del_virtual_intf = brcmf_cfg80211_del_iface, |
@@ -4164,9 +4213,8 @@ static struct cfg80211_ops wl_cfg80211_ops = { | |||
4164 | .stop_p2p_device = brcmf_p2p_stop_device, | 4213 | .stop_p2p_device = brcmf_p2p_stop_device, |
4165 | .crit_proto_start = brcmf_cfg80211_crit_proto_start, | 4214 | .crit_proto_start = brcmf_cfg80211_crit_proto_start, |
4166 | .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, | 4215 | .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, |
4167 | #ifdef CONFIG_NL80211_TESTMODE | 4216 | .tdls_oper = brcmf_cfg80211_tdls_oper, |
4168 | .testmode_cmd = brcmf_cfg80211_testmode | 4217 | CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode) |
4169 | #endif | ||
4170 | }; | 4218 | }; |
4171 | 4219 | ||
4172 | static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type) | 4220 | static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type) |
@@ -4287,7 +4335,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
4287 | wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); | 4335 | wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); |
4288 | wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | | 4336 | wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | |
4289 | WIPHY_FLAG_OFFCHAN_TX | | 4337 | WIPHY_FLAG_OFFCHAN_TX | |
4290 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 4338 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
4339 | WIPHY_FLAG_SUPPORTS_TDLS; | ||
4291 | wiphy->mgmt_stypes = brcmf_txrx_stypes; | 4340 | wiphy->mgmt_stypes = brcmf_txrx_stypes; |
4292 | wiphy->max_remain_on_channel_duration = 5000; | 4341 | wiphy->max_remain_on_channel_duration = 5000; |
4293 | brcmf_wiphy_pno_params(wiphy); | 4342 | brcmf_wiphy_pno_params(wiphy); |
@@ -4908,6 +4957,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
4908 | goto cfg80211_p2p_attach_out; | 4957 | goto cfg80211_p2p_attach_out; |
4909 | } | 4958 | } |
4910 | 4959 | ||
4960 | err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); | ||
4961 | if (err) { | ||
4962 | brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); | ||
4963 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; | ||
4964 | } | ||
4965 | |||
4911 | err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, | 4966 | err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, |
4912 | &io_type); | 4967 | &io_type); |
4913 | if (err) { | 4968 | if (err) { |