aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c65
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
3158static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) 3158static 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
4131static 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
4152static 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
4129static struct cfg80211_ops wl_cfg80211_ops = { 4178static 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
4172static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type) 4220static 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) {