mac80211: brcmfmac: add beamforming support
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 376-0007-brcmfmac-Add-beamforming-support.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Wed, 25 Nov 2015 11:32:43 +0100
3 Subject: [PATCH] brcmfmac: Add beamforming support.
4
5 Some devices support beamforming. This patch enables tx beamforming
6 if supported and reports beamforming capabilities per channel if
7 supported.
8
9 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
10 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
11 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
12 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
13 Signed-off-by: Arend van Spriel <arend@broadcom.com>
14 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
15 ---
16
17 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
18 +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
19 @@ -5671,7 +5671,8 @@ static __le16 brcmf_get_mcs_map(u32 ncha
20  }
21  
22  static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
23 -                                u32 bw_cap[2], u32 nchain)
24 +                                u32 bw_cap[2], u32 nchain, u32 txstreams,
25 +                                u32 txbf_bfe_cap, u32 txbf_bfr_cap)
26  {
27         __le16 mcs_map;
28  
29 @@ -5690,6 +5691,25 @@ static void brcmf_update_vht_cap(struct
30         mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
31         band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
32         band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
33 +
34 +       /* Beamforming support information */
35 +       if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
36 +               band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
37 +       if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
38 +               band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
39 +       if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
40 +               band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
41 +       if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
42 +               band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
43 +
44 +       if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
45 +               band->vht_cap.cap |=
46 +                       (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
47 +               band->vht_cap.cap |= ((txstreams - 1) <<
48 +                               IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
49 +               band->vht_cap.cap |=
50 +                       IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
51 +       }
52  }
53  
54  static int brcmf_setup_wiphybands(struct wiphy *wiphy)
55 @@ -5704,6 +5724,9 @@ static int brcmf_setup_wiphybands(struct
56         int err;
57         s32 i;
58         struct ieee80211_supported_band *band;
59 +       u32 txstreams = 0;
60 +       u32 txbf_bfe_cap = 0;
61 +       u32 txbf_bfr_cap = 0;
62  
63         (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
64         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
65 @@ -5732,6 +5755,14 @@ static int brcmf_setup_wiphybands(struct
66                 return err;
67         }
68  
69 +       if (vhtmode) {
70 +               (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
71 +               (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
72 +                                             &txbf_bfe_cap);
73 +               (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
74 +                                             &txbf_bfr_cap);
75 +       }
76 +
77         wiphy = cfg_to_wiphy(cfg);
78         for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
79                 band = wiphy->bands[i];
80 @@ -5741,7 +5772,8 @@ static int brcmf_setup_wiphybands(struct
81                 if (nmode)
82                         brcmf_update_ht_cap(band, bw_cap, nchain);
83                 if (vhtmode)
84 -                       brcmf_update_vht_cap(band, bw_cap, nchain);
85 +                       brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
86 +                                            txbf_bfe_cap, txbf_bfr_cap);
87         }
88  
89         return 0;
90 --- a/drivers/net/wireless/brcm80211/brcmfmac/common.c
91 +++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c
92 @@ -153,6 +153,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
93                 goto done;
94         }
95  
96 +       /* Enable tx beamforming, errors can be ignored (not supported) */
97 +       (void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
98 +
99         /* do bus specific preinit here */
100         err = brcmf_bus_preinit(ifp->drvr->bus_if);
101  done:
102 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
103 +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
104 @@ -121,6 +121,11 @@
105  
106  #define BRCMF_MAX_ASSOCLIST            128
107  
108 +#define BRCMF_TXBF_SU_BFE_CAP          BIT(0)
109 +#define BRCMF_TXBF_MU_BFE_CAP          BIT(1)
110 +#define BRCMF_TXBF_SU_BFR_CAP          BIT(0)
111 +#define BRCMF_TXBF_MU_BFR_CAP          BIT(1)
112 +
113  /* join preference types for join_pref iovar */
114  enum brcmf_join_pref_types {
115         BRCMF_JOIN_PREF_RSSI = 1,