[mac80211] add RT5350 wifi support
[openwrt.git] / package / mac80211 / patches / 871-brcmsmac-add-support-for-probe-response-template.patch
1 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
2 +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
3 @@ -541,6 +541,15 @@ brcms_ops_bss_info_changed(struct ieee80
4                 spin_unlock_bh(&wl->lock);
5         }
6  
7 +       if (changed & BSS_CHANGED_AP_PROBE_RESP) {
8 +               struct sk_buff *probe_resp;
9 +
10 +               spin_lock_bh(&wl->lock);
11 +               probe_resp = ieee80211_proberesp_get(hw, vif);
12 +               brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
13 +               spin_unlock_bh(&wl->lock);
14 +       }
15 +
16         if (changed & BSS_CHANGED_BEACON_ENABLED) {
17                 /* Beaconing should be enabled/disabled (beaconing modes) */
18                 brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
19 @@ -1039,6 +1048,8 @@ static int ieee_hw_init(struct ieee80211
20         hw->channel_change_time = 7 * 1000;
21         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
22  
23 +       hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
24 +
25         hw->rate_control_algorithm = "minstrel_ht";
26  
27         hw->sta_data_size = 0;
28 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
29 +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
30 @@ -453,6 +453,8 @@ static void brcms_c_detach_mfree(struct
31         kfree(wlc->hw);
32         if (wlc->beacon)
33                 dev_kfree_skb_any(wlc->beacon);
34 +       if (wlc->probe_resp)
35 +               dev_kfree_skb_any(wlc->probe_resp);
36  
37         /* free the wlc */
38         kfree(wlc);
39 @@ -7327,69 +7329,6 @@ brcms_c_mod_prb_rsp_rate_table(struct br
40         }
41  }
42  
43 -/*     Max buffering needed for beacon template/prb resp template is 142 bytes.
44 - *
45 - *     PLCP header is 6 bytes.
46 - *     802.11 A3 header is 24 bytes.
47 - *     Max beacon frame body template length is 112 bytes.
48 - *     Max probe resp frame body template length is 110 bytes.
49 - *
50 - *      *len on input contains the max length of the packet available.
51 - *
52 - *     The *len value is set to the number of bytes in buf used, and starts
53 - *     with the PLCP and included up to, but not including, the 4 byte FCS.
54 - */
55 -static void
56 -brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
57 -                        u32 bcn_rspec,
58 -                        struct brcms_bss_cfg *cfg, u16 *buf, int *len)
59 -{
60 -       static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
61 -       struct cck_phy_hdr *plcp;
62 -       struct ieee80211_mgmt *h;
63 -       int hdr_len, body_len;
64 -
65 -       hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
66 -
67 -       /* calc buffer size provided for frame body */
68 -       body_len = *len - hdr_len;
69 -       /* return actual size */
70 -       *len = hdr_len + body_len;
71 -
72 -       /* format PHY and MAC headers */
73 -       memset(buf, 0, hdr_len);
74 -
75 -       plcp = (struct cck_phy_hdr *) buf;
76 -
77 -       /*
78 -        * PLCP for Probe Response frames are filled in from
79 -        * core's rate table
80 -        */
81 -       if (type == IEEE80211_STYPE_BEACON)
82 -               /* fill in PLCP */
83 -               brcms_c_compute_plcp(wlc, bcn_rspec,
84 -                                (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
85 -                                (u8 *) plcp);
86 -
87 -       /* "Regular" and 16 MBSS but not for 4 MBSS */
88 -       /* Update the phytxctl for the beacon based on the rspec */
89 -       brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
90 -
91 -       h = (struct ieee80211_mgmt *)&plcp[1];
92 -
93 -       /* fill in 802.11 header */
94 -       h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
95 -
96 -       /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
97 -       /* A1 filled in by MAC for prb resp, broadcast for bcn */
98 -       if (type == IEEE80211_STYPE_BEACON)
99 -               memcpy(&h->da, &ether_bcast, ETH_ALEN);
100 -       memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
101 -       memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
102 -
103 -       /* SEQ filled in by MAC */
104 -}
105 -
106  int brcms_c_get_header_len(void)
107  {
108         return TXOFF;
109 @@ -7531,6 +7470,20 @@ void brcms_c_set_new_beacon(struct brcms
110         brcms_c_update_beacon(wlc);
111  }
112  
113 +void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
114 +                               struct sk_buff *probe_resp)
115 +{
116 +       if (!probe_resp)
117 +               return;
118 +       if (wlc->probe_resp)
119 +               dev_kfree_skb_any(wlc->probe_resp);
120 +       wlc->probe_resp = probe_resp;
121 +
122 +       /* add PLCP */
123 +       skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
124 +       brcms_c_update_probe_resp(wlc, false);
125 +}
126 +
127  /* Write ssid into shared memory */
128  static void
129  brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
130 @@ -7550,30 +7503,19 @@ brcms_c_shm_ssid_upd(struct brcms_c_info
131  static void
132  brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
133                               struct brcms_bss_cfg *cfg,
134 +                             struct sk_buff *probe_resp,
135                               bool suspend)
136  {
137 -       u16 *prb_resp;
138 -       int len = BCN_TMPL_LEN;
139 +       int len;
140  
141 -       prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
142 -       if (!prb_resp)
143 -               return;
144 -
145 -       /*
146 -        * write the probe response to hardware, or save in
147 -        * the config structure
148 -        */
149 -
150 -       /* create the probe response template */
151 -       brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
152 -                                cfg, prb_resp, &len);
153 +       len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
154  
155         if (suspend)
156                 brcms_c_suspend_mac_and_wait(wlc);
157  
158         /* write the probe response into the template region */
159         brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
160 -                                   (len + 3) & ~3, prb_resp);
161 +                                   (len + 3) & ~3, probe_resp->data);
162  
163         /* write the length of the probe response frame (+PLCP/-FCS) */
164         brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
165 @@ -7587,13 +7529,11 @@ brcms_c_bss_update_probe_resp(struct brc
166          * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
167          * by subtracting the PLCP len and adding the FCS.
168          */
169 -       len += (-D11_PHY_HDR_LEN + FCS_LEN);
170 -       brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
171 +       brcms_c_mod_prb_rsp_rate_table(wlc,
172 +                                     (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
173  
174         if (suspend)
175                 brcms_c_enable_mac(wlc);
176 -
177 -       kfree(prb_resp);
178  }
179  
180  void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
181 @@ -7602,8 +7542,12 @@ void brcms_c_update_probe_resp(struct br
182  
183         /* update AP or IBSS probe responses */
184         if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
185 -                            bsscfg->type == BRCMS_TYPE_ADHOC))
186 -               brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
187 +                            bsscfg->type == BRCMS_TYPE_ADHOC)) {
188 +               if (!wlc->probe_resp)
189 +                       return;
190 +               brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
191 +                                             suspend);
192 +       }
193  }
194  
195  int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
196 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
197 +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
198 @@ -567,6 +567,7 @@ struct brcms_c_info {
199         struct sk_buff *beacon;
200         u16 beacon_tim_offset;
201         u16 beacon_dtim_period;
202 +       struct sk_buff *probe_resp;
203  };
204  
205  /* antsel module specific state */
206 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
207 +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
208 @@ -336,6 +336,8 @@ extern void brcms_c_update_beacon(struct
209  extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
210                                    struct sk_buff *beacon, u16 tim_offset,
211                                    u16 dtim_period);
212 +extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
213 +                                      struct sk_buff *probe_resp);
214  extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
215                              size_t ssid_len);
216