09059defe57c8b4ba177bf2929b78427a4bab286
[oweals/openwrt.git] /
1 From 837482e69a3f0d7cbc73922020012f83635f5ddb Mon Sep 17 00:00:00 2001
2 From: Wright Feng <wright.feng@cypress.com>
3 Date: Thu, 12 Dec 2019 00:52:50 +0100
4 Subject: [PATCH 6/7] brcmfmac: add RSDB condition when setting interface
5  combinations
6
7 With firmware RSDB feature
8 1. The maximum support interface is four.
9 2. The maximum difference channel is two.
10 3. The maximum interfaces of {station/p2p client/AP} are two.
11 4. The maximum interface of p2p device is one.
12
13 Signed-off-by: Wright Feng <wright.feng@cypress.com>
14 Signed-off-by: Soeren Moch <smoch@web.de>
15 Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
16 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
17 ---
18  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 54 ++++++++++++++++---
19  1 file changed, 46 insertions(+), 8 deletions(-)
20
21 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
22 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
23 @@ -6520,6 +6520,9 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
24   *     #STA <= 1, #AP <= 1, channels = 1, 2 total
25   *     #AP <= 4, matching BI, channels = 1, 4 total
26   *
27 + * no p2p and rsdb:
28 + *     #STA <= 2, #AP <= 2, channels = 2, 4 total
29 + *
30   * p2p, no mchan, and mbss:
31   *
32   *     #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
33 @@ -6531,6 +6534,10 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
34   *     #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
35   *     #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
36   *     #AP <= 4, matching BI, channels = 1, 4 total
37 + *
38 + * p2p, rsdb, and no mbss:
39 + *     #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
40 + *      channels = 2, 4 total
41   */
42  static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
43  {
44 @@ -6538,13 +6545,14 @@ static int brcmf_setup_ifmodes(struct wi
45         struct ieee80211_iface_limit *c0_limits = NULL;
46         struct ieee80211_iface_limit *p2p_limits = NULL;
47         struct ieee80211_iface_limit *mbss_limits = NULL;
48 -       bool mbss, p2p;
49 +       bool mbss, p2p, rsdb;
50         int i, c, n_combos;
51  
52         mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
53         p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
54 +       rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
55  
56 -       n_combos = 1 + !!p2p + !!mbss;
57 +       n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
58         combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
59         if (!combo)
60                 goto err;
61 @@ -6555,16 +6563,36 @@ static int brcmf_setup_ifmodes(struct wi
62  
63         c = 0;
64         i = 0;
65 -       c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
66 +       if (p2p && rsdb)
67 +               c0_limits = kcalloc(4, sizeof(*c0_limits), GFP_KERNEL);
68 +       else if (p2p)
69 +               c0_limits = kcalloc(3, sizeof(*c0_limits), GFP_KERNEL);
70 +       else
71 +               c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
72         if (!c0_limits)
73                 goto err;
74 -       c0_limits[i].max = 1;
75 -       c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
76 -       if (p2p) {
77 +       if (p2p && rsdb) {
78 +               combo[c].num_different_channels = 2;
79 +               wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
80 +                                         BIT(NL80211_IFTYPE_P2P_GO) |
81 +                                         BIT(NL80211_IFTYPE_P2P_DEVICE);
82 +               c0_limits[i].max = 2;
83 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
84 +               c0_limits[i].max = 1;
85 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
86 +               c0_limits[i].max = 2;
87 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
88 +                                      BIT(NL80211_IFTYPE_P2P_GO);
89 +               c0_limits[i].max = 2;
90 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
91 +               combo[c].max_interfaces = 5;
92 +       } else if (p2p) {
93                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
94                         combo[c].num_different_channels = 2;
95                 else
96                         combo[c].num_different_channels = 1;
97 +               c0_limits[i].max = 1;
98 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
99                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
100                                           BIT(NL80211_IFTYPE_P2P_GO) |
101                                           BIT(NL80211_IFTYPE_P2P_DEVICE);
102 @@ -6573,16 +6601,26 @@ static int brcmf_setup_ifmodes(struct wi
103                 c0_limits[i].max = 1;
104                 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
105                                        BIT(NL80211_IFTYPE_P2P_GO);
106 +               combo[c].max_interfaces = i;
107 +       } else if (rsdb) {
108 +               combo[c].num_different_channels = 2;
109 +               c0_limits[i].max = 2;
110 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
111 +               c0_limits[i].max = 2;
112 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
113 +               combo[c].max_interfaces = 3;
114         } else {
115                 combo[c].num_different_channels = 1;
116                 c0_limits[i].max = 1;
117 +               c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
118 +               c0_limits[i].max = 1;
119                 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
120 +               combo[c].max_interfaces = i;
121         }
122 -       combo[c].max_interfaces = i;
123         combo[c].n_limits = i;
124         combo[c].limits = c0_limits;
125  
126 -       if (p2p) {
127 +       if (p2p && !rsdb) {
128                 c++;
129                 i = 0;
130                 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);