madwifi: add some beacon setup/update related fixes (based on Bruno Randolf's patchset)
[openwrt.git] / package / madwifi / patches / 360-sta_nodes.patch
1 Drop stale AP nodes from the client list when disconnecting.
2 Fixes some reassoc issues.
3
4 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
5
6 --- a/net80211/ieee80211_proto.c
7 +++ b/net80211/ieee80211_proto.c
8 @@ -1348,7 +1348,7 @@
9                                 IEEE80211_SEND_MGMT(ni,
10                                         IEEE80211_FC0_SUBTYPE_DISASSOC,
11                                         IEEE80211_REASON_ASSOC_LEAVE);
12 -                               ieee80211_sta_leave(ni);
13 +                               ieee80211_node_leave(ni);
14                                 break;
15                         case IEEE80211_M_HOSTAP:
16                                 ieee80211_iterate_nodes(&ic->ic_sta,
17 @@ -1358,12 +1358,14 @@
18                                 break;
19                         }
20                         goto reset;
21 +               case IEEE80211_S_AUTH:
22                 case IEEE80211_S_ASSOC:
23                         switch (vap->iv_opmode) {
24                         case IEEE80211_M_STA:
25                                 IEEE80211_SEND_MGMT(ni,
26                                         IEEE80211_FC0_SUBTYPE_DEAUTH,
27                                         IEEE80211_REASON_AUTH_LEAVE);
28 +                               ieee80211_node_leave(ni);
29                                 break;
30                         case IEEE80211_M_HOSTAP:
31                                 ieee80211_iterate_nodes(&ic->ic_sta,
32 @@ -1376,7 +1378,6 @@
33                 case IEEE80211_S_SCAN:
34                         ieee80211_cancel_scan(vap);
35                         goto reset;
36 -               case IEEE80211_S_AUTH:
37                 reset:
38                         ieee80211_reset_bss(vap);
39                         break;
40 @@ -1429,10 +1430,12 @@
41                                         IEEE80211_SCAN_FOREVER,
42                                         vap->iv_des_nssid, vap->iv_des_ssid,
43                                         NULL);
44 +                       else
45 +                               ieee80211_node_leave(vap->iv_bss);
46                         break;
47                 case IEEE80211_S_RUN:           /* beacon miss */
48                         if (vap->iv_opmode == IEEE80211_M_STA) {
49 -                               ieee80211_sta_leave(ni);
50 +                               ieee80211_node_leave(ni);
51                                 vap->iv_flags &= ~IEEE80211_F_SIBSS;    /* XXX */
52                                 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
53                                         ieee80211_check_scan(vap,
54 @@ -1484,7 +1487,7 @@
55                                 vap->iv_state = ostate; /* stay RUN */
56                                 break;
57                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
58 -                               ieee80211_sta_leave(ni);
59 +                               ieee80211_node_leave(ni);
60                                 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
61                                         /* try to reauth */
62                                         IEEE80211_SEND_MGMT(ni,
63 @@ -1511,7 +1514,7 @@
64                                 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
65                         break;
66                 case IEEE80211_S_RUN:
67 -                       ieee80211_sta_leave(ni);
68 +                       ieee80211_node_leave(ni);
69                         if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
70                                 /* NB: caller specifies ASSOC/REASSOC by arg */
71                                 IEEE80211_SEND_MGMT(ni, arg ?
72 @@ -1779,6 +1782,7 @@
73                           ieee80211_state_name[nstate], 
74                           ieee80211_state_name[dstate]);
75  
76 +       ieee80211_update_link_status(vap, nstate, ostate);
77         switch (nstate) {
78         case IEEE80211_S_AUTH:
79         case IEEE80211_S_ASSOC:
80 --- a/net80211/ieee80211_linux.c
81 +++ b/net80211/ieee80211_linux.c
82 @@ -233,33 +233,59 @@
83  }
84  
85  void
86 -ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
87 +ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate)
88  {
89 -       struct ieee80211vap *vap = ni->ni_vap;
90         struct net_device *dev = vap->iv_dev;
91         union iwreq_data wreq;
92 +       int active;
93 +
94 +       if (vap->iv_opmode != IEEE80211_M_STA)
95 +               return;
96 +
97 +       if (ostate == nstate)
98 +               return;
99 +
100 +       if (nstate == IEEE80211_S_RUN)
101 +               active = 1;
102 +       else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate))
103 +               active = 0;
104 +       else
105 +               return;
106 +
107 +       if (active && !vap->iv_bss)
108 +               return;
109 +
110 +       memset(&wreq, 0, sizeof(wreq));
111 +       wreq.ap_addr.sa_family = ARPHRD_ETHER;
112  
113 -       if (ni == vap->iv_bss) {
114 -               if (newassoc)
115 -                       netif_carrier_on(dev);
116 -               memset(&wreq, 0, sizeof(wreq));
117 +       if (active) {
118 +               //netif_carrier_on(vap->iv_dev);
119                 IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid);
120 -               wreq.addr.sa_family = ARPHRD_ETHER;
121 -#ifdef ATH_SUPERG_XR
122 -               if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
123 -                       dev = vap->iv_xrvap->iv_dev;
124 -#endif
125 -               wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
126         } else {
127 -               memset(&wreq, 0, sizeof(wreq));
128 -               IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
129 -               wreq.addr.sa_family = ARPHRD_ETHER;
130 +               //netif_carrier_off(vap->iv_dev);
131 +               memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
132 +       }
133 +       wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
134 +}
135 +
136 +void
137 +ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
138 +{
139 +       struct ieee80211vap *vap = ni->ni_vap;
140 +       struct net_device *dev = vap->iv_dev;
141 +       union iwreq_data wreq;
142 +
143 +       if (ni == vap->iv_bss)
144 +               return;
145 +
146 +       memset(&wreq, 0, sizeof(wreq));
147 +       IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
148 +       wreq.addr.sa_family = ARPHRD_ETHER;
149  #ifdef ATH_SUPERG_XR
150 -               if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
151 -                       dev = vap->iv_xrvap->iv_dev;
152 +       if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
153 +               dev = vap->iv_xrvap->iv_dev;
154  #endif
155 -               wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
156 -       }
157 +       wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
158  }
159  
160  void
161 @@ -269,18 +295,14 @@
162         struct net_device *dev = vap->iv_dev;
163         union iwreq_data wreq;
164  
165 -       if (ni == vap->iv_bss) {
166 -               netif_carrier_off(dev);
167 -               memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
168 -               wreq.ap_addr.sa_family = ARPHRD_ETHER;
169 -               wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
170 -       } else {
171 -               /* fire off wireless event station leaving */
172 -               memset(&wreq, 0, sizeof(wreq));
173 -               IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
174 -               wreq.addr.sa_family = ARPHRD_ETHER;
175 -               wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
176 -       }
177 +       if (ni == vap->iv_bss)
178 +               return;
179 +
180 +       /* fire off wireless event station leaving */
181 +       memset(&wreq, 0, sizeof(wreq));
182 +       IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
183 +       wreq.addr.sa_family = ARPHRD_ETHER;
184 +       wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
185  }
186  
187  void
188 --- a/net80211/ieee80211_node.c
189 +++ b/net80211/ieee80211_node.c
190 @@ -2332,6 +2332,7 @@
191                 count_suppchans(ic, ni, -1);
192         IEEE80211_UNLOCK_IRQ(ic);
193  
194 +done:
195         /*
196          * Cleanup station state.  In particular clear various
197          * state that might otherwise be reused if the node
198 @@ -2339,7 +2340,7 @@
199          * (and memory is reclaimed).
200          */
201         ieee80211_sta_leave(ni);
202 -done:
203 +
204         /* Run a cleanup */
205  #ifdef IEEE80211_DEBUG_REFCNT
206         ic->ic_node_cleanup_debug(ni, __func__, __LINE__);
207 --- a/net80211/ieee80211_node.h
208 +++ b/net80211/ieee80211_node.h
209 @@ -60,7 +60,7 @@
210  #define        IEEE80211_INACT_PROBE   (30/IEEE80211_INACT_WAIT)       /* probe */
211  #define        IEEE80211_INACT_SCAN    (300/IEEE80211_INACT_WAIT)      /* scanned */
212  
213 -#define        IEEE80211_TRANS_WAIT    5                               /* mgt frame tx timer (secs) */
214 +#define        IEEE80211_TRANS_WAIT    300                             /* mgt frame tx timer (msecs) */
215  
216  #define        IEEE80211_NODE_HASHSIZE 32
217  /* simple hash is enough for variation of macaddr */
218 --- a/net80211/ieee80211_output.c
219 +++ b/net80211/ieee80211_output.c
220 @@ -2141,7 +2141,7 @@
221  
222         ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type);
223         if (timer)
224 -               mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
225 +               mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer));
226         return 0;
227  bad:
228         return ret;
229 --- a/net80211/ieee80211_wireless.c
230 +++ b/net80211/ieee80211_wireless.c
231 @@ -514,8 +514,9 @@
232                         vap->iv_flags |= IEEE80211_F_DESBSSID;
233  
234                 IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data);
235 -               if (IS_UP_AUTO(vap))
236 +               if (IS_UP(vap->iv_dev)) {
237                         ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
238 +               }
239         }
240         return 0;
241  }
242 --- a/net80211/ieee80211_linux.h
243 +++ b/net80211/ieee80211_linux.h
244 @@ -643,6 +643,7 @@
245  #define        free_netdev(dev)        kfree(dev)
246  #endif
247  
248 +void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate);
249  void ieee80211_ioctl_vattach(struct ieee80211vap *);
250  void ieee80211_ioctl_vdetach(struct ieee80211vap *);
251  struct ifreq;