aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-08-10 06:27:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-15 16:07:54 -0400
commit89c2f382fff4ec8adf04264925e07e951d0552ce (patch)
treea7c32d05ffb41fa7a0491f3ed2ab0fbbd60a25c4
parent2ee8382fc6c763c76396a6aaff77a27089eed3aa (diff)
brcmfmac: add support for manual TDLS operations
Implement the .tdls_oper() callback and indicate TDLS support in the wiphy flags. Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h21
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c57
2 files changed, 77 insertions, 1 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 665ef69e974b..ecabb04f33c3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -69,4 +69,25 @@ struct brcmf_fil_bss_enable_le {
69 __le32 enable; 69 __le32 enable;
70}; 70};
71 71
72/**
73 * struct tdls_iovar - common structure for tdls iovars.
74 *
75 * @ea: ether address of peer station.
76 * @mode: mode value depending on specific tdls iovar.
77 * @chanspec: channel specification.
78 * @pad: unused (for future use).
79 */
80struct brcmf_tdls_iovar_le {
81 u8 ea[ETH_ALEN]; /* Station address */
82 u8 mode; /* mode: depends on iovar */
83 __le16 chanspec;
84 __le32 pad; /* future */
85};
86
87enum brcmf_tdls_manual_ep_ops {
88 BRCMF_TDLS_MANUAL_EP_CREATE = 1,
89 BRCMF_TDLS_MANUAL_EP_DELETE = 3,
90 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6
91};
92
72#endif /* FWIL_TYPES_H_ */ 93#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index c3dfea3f307d..0370e44cec11 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4126,6 +4126,53 @@ static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4126 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); 4126 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4127} 4127}
4128 4128
4129static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4130{
4131 int ret;
4132
4133 switch (oper) {
4134 case NL80211_TDLS_DISCOVERY_REQ:
4135 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4136 break;
4137 case NL80211_TDLS_SETUP:
4138 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4139 break;
4140 case NL80211_TDLS_TEARDOWN:
4141 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4142 break;
4143 default:
4144 brcmf_err("unsupported operation: %d\n", oper);
4145 ret = -EOPNOTSUPP;
4146 }
4147 return ret;
4148}
4149
4150static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4151 struct net_device *ndev, u8 *peer,
4152 enum nl80211_tdls_operation oper)
4153{
4154 struct brcmf_if *ifp;
4155 struct brcmf_tdls_iovar_le info;
4156 int ret = 0;
4157
4158 ret = brcmf_convert_nl80211_tdls_oper(oper);
4159 if (ret < 0)
4160 return ret;
4161
4162 ifp = netdev_priv(ndev);
4163 memset(&info, 0, sizeof(info));
4164 info.mode = (u8)ret;
4165 if (peer)
4166 memcpy(info.ea, peer, ETH_ALEN);
4167
4168 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4169 &info, sizeof(info));
4170 if (ret < 0)
4171 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4172
4173 return ret;
4174}
4175
4129static struct cfg80211_ops wl_cfg80211_ops = { 4176static struct cfg80211_ops wl_cfg80211_ops = {
4130 .add_virtual_intf = brcmf_cfg80211_add_iface, 4177 .add_virtual_intf = brcmf_cfg80211_add_iface,
4131 .del_virtual_intf = brcmf_cfg80211_del_iface, 4178 .del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -4164,6 +4211,7 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4164 .stop_p2p_device = brcmf_p2p_stop_device, 4211 .stop_p2p_device = brcmf_p2p_stop_device,
4165 .crit_proto_start = brcmf_cfg80211_crit_proto_start, 4212 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4166 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, 4213 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4214 .tdls_oper = brcmf_cfg80211_tdls_oper,
4167 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode) 4215 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4168}; 4216};
4169 4217
@@ -4285,7 +4333,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4285 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 4333 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4286 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | 4334 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4287 WIPHY_FLAG_OFFCHAN_TX | 4335 WIPHY_FLAG_OFFCHAN_TX |
4288 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 4336 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4337 WIPHY_FLAG_SUPPORTS_TDLS;
4289 wiphy->mgmt_stypes = brcmf_txrx_stypes; 4338 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4290 wiphy->max_remain_on_channel_duration = 5000; 4339 wiphy->max_remain_on_channel_duration = 5000;
4291 brcmf_wiphy_pno_params(wiphy); 4340 brcmf_wiphy_pno_params(wiphy);
@@ -4906,6 +4955,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4906 goto cfg80211_p2p_attach_out; 4955 goto cfg80211_p2p_attach_out;
4907 } 4956 }
4908 4957
4958 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4959 if (err) {
4960 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
4961 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
4962 }
4963
4909 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, 4964 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4910 &io_type); 4965 &io_type);
4911 if (err) { 4966 if (err) {