aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c423
1 files changed, 185 insertions, 238 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2c3a99d6c9a..eb9eb766ac2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -52,7 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL");
52 52
53/* Interface control information */ 53/* Interface control information */
54struct brcmf_if { 54struct brcmf_if {
55 struct brcmf_info *info; /* back pointer to brcmf_info */ 55 struct brcmf_pub *drvr; /* back pointer to brcmf_pub */
56 /* OS/stack specifics */ 56 /* OS/stack specifics */
57 struct net_device *ndev; 57 struct net_device *ndev;
58 struct net_device_stats stats; 58 struct net_device_stats stats;
@@ -60,26 +60,11 @@ struct brcmf_if {
60 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ 60 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
61}; 61};
62 62
63/* Local private structure (extension of pub) */
64struct brcmf_info {
65 struct brcmf_pub pub;
66
67 /* OS/stack specifics */
68 struct brcmf_if *iflist[BRCMF_MAX_IFS];
69
70 struct mutex proto_block;
71
72 struct work_struct setmacaddr_work;
73 struct work_struct multicast_work;
74 u8 macvalue[ETH_ALEN];
75 atomic_t pend_8021x_cnt;
76};
77
78/* Error bits */ 63/* Error bits */
79int brcmf_msg_level = BRCMF_ERROR_VAL; 64int brcmf_msg_level = BRCMF_ERROR_VAL;
80module_param(brcmf_msg_level, int, 0); 65module_param(brcmf_msg_level, int, 0);
81 66
82int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) 67int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name)
83{ 68{
84 int i = BRCMF_MAX_IFS; 69 int i = BRCMF_MAX_IFS;
85 struct brcmf_if *ifp; 70 struct brcmf_if *ifp;
@@ -88,7 +73,7 @@ int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
88 return 0; 73 return 0;
89 74
90 while (--i > 0) { 75 while (--i > 0) {
91 ifp = drvr_priv->iflist[i]; 76 ifp = drvr->iflist[i];
92 if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) 77 if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
93 break; 78 break;
94 } 79 }
@@ -100,20 +85,18 @@ int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
100 85
101char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 86char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
102{ 87{
103 struct brcmf_info *drvr_priv = drvr->info;
104
105 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { 88 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
106 brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx); 89 brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
107 return "<if_bad>"; 90 return "<if_bad>";
108 } 91 }
109 92
110 if (drvr_priv->iflist[ifidx] == NULL) { 93 if (drvr->iflist[ifidx] == NULL) {
111 brcmf_dbg(ERROR, "null i/f %d\n", ifidx); 94 brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
112 return "<if_null>"; 95 return "<if_null>";
113 } 96 }
114 97
115 if (drvr_priv->iflist[ifidx]->ndev) 98 if (drvr->iflist[ifidx]->ndev)
116 return drvr_priv->iflist[ifidx]->ndev->name; 99 return drvr->iflist[ifidx]->ndev->name;
117 100
118 return "<if_none>"; 101 return "<if_none>";
119} 102}
@@ -131,10 +114,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
131 uint buflen; 114 uint buflen;
132 int ret; 115 int ret;
133 116
134 struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info, 117 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
135 multicast_work); 118 multicast_work);
136 119
137 ndev = drvr_priv->iflist[0]->ndev; 120 ndev = drvr->iflist[0]->ndev;
138 cnt = netdev_mc_count(ndev); 121 cnt = netdev_mc_count(ndev);
139 122
140 /* Determine initial value of allmulti flag */ 123 /* Determine initial value of allmulti flag */
@@ -168,10 +151,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
168 dcmd.len = buflen; 151 dcmd.len = buflen;
169 dcmd.set = true; 152 dcmd.set = true;
170 153
171 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); 154 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
172 if (ret < 0) { 155 if (ret < 0) {
173 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", 156 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
174 brcmf_ifname(&drvr_priv->pub, 0), cnt); 157 brcmf_ifname(drvr, 0), cnt);
175 dcmd_value = cnt ? true : dcmd_value; 158 dcmd_value = cnt ? true : dcmd_value;
176 } 159 }
177 160
@@ -193,7 +176,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
193 ("allmulti", (void *)&dcmd_le_value, 176 ("allmulti", (void *)&dcmd_le_value,
194 sizeof(dcmd_le_value), buf, buflen)) { 177 sizeof(dcmd_le_value), buf, buflen)) {
195 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", 178 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
196 brcmf_ifname(&drvr_priv->pub, 0), 179 brcmf_ifname(drvr, 0),
197 (int)sizeof(dcmd_value), buflen); 180 (int)sizeof(dcmd_value), buflen);
198 kfree(buf); 181 kfree(buf);
199 return; 182 return;
@@ -205,10 +188,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
205 dcmd.len = buflen; 188 dcmd.len = buflen;
206 dcmd.set = true; 189 dcmd.set = true;
207 190
208 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); 191 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
209 if (ret < 0) { 192 if (ret < 0) {
210 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", 193 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
211 brcmf_ifname(&drvr_priv->pub, 0), 194 brcmf_ifname(drvr, 0),
212 le32_to_cpu(dcmd_le_value)); 195 le32_to_cpu(dcmd_le_value));
213 } 196 }
214 197
@@ -226,10 +209,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
226 dcmd.len = sizeof(dcmd_le_value); 209 dcmd.len = sizeof(dcmd_le_value);
227 dcmd.set = true; 210 dcmd.set = true;
228 211
229 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); 212 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
230 if (ret < 0) { 213 if (ret < 0) {
231 brcmf_dbg(ERROR, "%s: set promisc %d failed\n", 214 brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
232 brcmf_ifname(&drvr_priv->pub, 0), 215 brcmf_ifname(drvr, 0),
233 le32_to_cpu(dcmd_le_value)); 216 le32_to_cpu(dcmd_le_value));
234 } 217 }
235} 218}
@@ -241,14 +224,14 @@ _brcmf_set_mac_address(struct work_struct *work)
241 struct brcmf_dcmd dcmd; 224 struct brcmf_dcmd dcmd;
242 int ret; 225 int ret;
243 226
244 struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info, 227 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
245 setmacaddr_work); 228 setmacaddr_work);
246 229
247 brcmf_dbg(TRACE, "enter\n"); 230 brcmf_dbg(TRACE, "enter\n");
248 if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue, 231 if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
249 ETH_ALEN, buf, 32)) { 232 ETH_ALEN, buf, 32)) {
250 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", 233 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
251 brcmf_ifname(&drvr_priv->pub, 0)); 234 brcmf_ifname(drvr, 0));
252 return; 235 return;
253 } 236 }
254 memset(&dcmd, 0, sizeof(dcmd)); 237 memset(&dcmd, 0, sizeof(dcmd));
@@ -257,13 +240,13 @@ _brcmf_set_mac_address(struct work_struct *work)
257 dcmd.len = 32; 240 dcmd.len = 32;
258 dcmd.set = true; 241 dcmd.set = true;
259 242
260 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); 243 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
261 if (ret < 0) 244 if (ret < 0)
262 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", 245 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
263 brcmf_ifname(&drvr_priv->pub, 0)); 246 brcmf_ifname(drvr, 0));
264 else 247 else
265 memcpy(drvr_priv->iflist[0]->ndev->dev_addr, 248 memcpy(drvr->iflist[0]->ndev->dev_addr,
266 drvr_priv->macvalue, ETH_ALEN); 249 drvr->macvalue, ETH_ALEN);
267 250
268 return; 251 return;
269} 252}
@@ -271,28 +254,26 @@ _brcmf_set_mac_address(struct work_struct *work)
271static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 254static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
272{ 255{
273 struct brcmf_if *ifp = netdev_priv(ndev); 256 struct brcmf_if *ifp = netdev_priv(ndev);
274 struct brcmf_info *drvr_priv = ifp->info; 257 struct brcmf_pub *drvr = ifp->drvr;
275 struct sockaddr *sa = (struct sockaddr *)addr; 258 struct sockaddr *sa = (struct sockaddr *)addr;
276 259
277 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); 260 memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN);
278 schedule_work(&drvr_priv->setmacaddr_work); 261 schedule_work(&drvr->setmacaddr_work);
279 return 0; 262 return 0;
280} 263}
281 264
282static void brcmf_netdev_set_multicast_list(struct net_device *ndev) 265static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
283{ 266{
284 struct brcmf_if *ifp = netdev_priv(ndev); 267 struct brcmf_if *ifp = netdev_priv(ndev);
285 struct brcmf_info *drvr_priv = ifp->info; 268 struct brcmf_pub *drvr = ifp->drvr;
286 269
287 schedule_work(&drvr_priv->multicast_work); 270 schedule_work(&drvr->multicast_work);
288} 271}
289 272
290int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) 273int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
291{ 274{
292 struct brcmf_info *drvr_priv = drvr->info;
293
294 /* Reject if down */ 275 /* Reject if down */
295 if (!drvr->up || (drvr->bus_if->state == BRCMF_BUS_DOWN)) 276 if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN))
296 return -ENODEV; 277 return -ENODEV;
297 278
298 /* Update multicast statistic */ 279 /* Update multicast statistic */
@@ -303,112 +284,113 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
303 if (is_multicast_ether_addr(eh->h_dest)) 284 if (is_multicast_ether_addr(eh->h_dest))
304 drvr->tx_multicast++; 285 drvr->tx_multicast++;
305 if (ntohs(eh->h_proto) == ETH_P_PAE) 286 if (ntohs(eh->h_proto) == ETH_P_PAE)
306 atomic_inc(&drvr_priv->pend_8021x_cnt); 287 atomic_inc(&drvr->pend_8021x_cnt);
307 } 288 }
308 289
309 /* If the protocol uses a data header, apply it */ 290 /* If the protocol uses a data header, apply it */
310 brcmf_proto_hdrpush(drvr, ifidx, pktbuf); 291 brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
311 292
312 /* Use bus module to send data frame */ 293 /* Use bus module to send data frame */
313 return brcmf_sdbrcm_bus_txdata(drvr->dev, pktbuf); 294 return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf);
314} 295}
315 296
316static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 297static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
317{ 298{
318 int ret; 299 int ret;
319 struct brcmf_if *ifp = netdev_priv(ndev); 300 struct brcmf_if *ifp = netdev_priv(ndev);
320 struct brcmf_info *drvr_priv = ifp->info; 301 struct brcmf_pub *drvr = ifp->drvr;
321 302
322 brcmf_dbg(TRACE, "Enter\n"); 303 brcmf_dbg(TRACE, "Enter\n");
323 304
324 /* Reject if down */ 305 /* Reject if down */
325 if (!drvr_priv->pub.up || 306 if (!drvr->bus_if->drvr_up ||
326 (drvr_priv->pub.bus_if->state == BRCMF_BUS_DOWN)) { 307 (drvr->bus_if->state == BRCMF_BUS_DOWN)) {
327 brcmf_dbg(ERROR, "xmit rejected pub.up=%d state=%d\n", 308 brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
328 drvr_priv->pub.up, 309 drvr->bus_if->drvr_up,
329 drvr_priv->pub.bus_if->state); 310 drvr->bus_if->state);
330 netif_stop_queue(ndev); 311 netif_stop_queue(ndev);
331 return -ENODEV; 312 return -ENODEV;
332 } 313 }
333 314
334 if (!drvr_priv->iflist[ifp->idx]) { 315 if (!drvr->iflist[ifp->idx]) {
335 brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); 316 brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx);
336 netif_stop_queue(ndev); 317 netif_stop_queue(ndev);
337 return -ENODEV; 318 return -ENODEV;
338 } 319 }
339 320
340 /* Make sure there's enough room for any header */ 321 /* Make sure there's enough room for any header */
341 if (skb_headroom(skb) < drvr_priv->pub.hdrlen) { 322 if (skb_headroom(skb) < drvr->hdrlen) {
342 struct sk_buff *skb2; 323 struct sk_buff *skb2;
343 324
344 brcmf_dbg(INFO, "%s: insufficient headroom\n", 325 brcmf_dbg(INFO, "%s: insufficient headroom\n",
345 brcmf_ifname(&drvr_priv->pub, ifp->idx)); 326 brcmf_ifname(drvr, ifp->idx));
346 drvr_priv->pub.tx_realloc++; 327 drvr->bus_if->tx_realloc++;
347 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); 328 skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
348 dev_kfree_skb(skb); 329 dev_kfree_skb(skb);
349 skb = skb2; 330 skb = skb2;
350 if (skb == NULL) { 331 if (skb == NULL) {
351 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", 332 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
352 brcmf_ifname(&drvr_priv->pub, ifp->idx)); 333 brcmf_ifname(drvr, ifp->idx));
353 ret = -ENOMEM; 334 ret = -ENOMEM;
354 goto done; 335 goto done;
355 } 336 }
356 } 337 }
357 338
358 ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb); 339 ret = brcmf_sendpkt(drvr, ifp->idx, skb);
359 340
360done: 341done:
361 if (ret) 342 if (ret)
362 drvr_priv->pub.dstats.tx_dropped++; 343 drvr->bus_if->dstats.tx_dropped++;
363 else 344 else
364 drvr_priv->pub.tx_packets++; 345 drvr->bus_if->dstats.tx_packets++;
365 346
366 /* Return ok: we always eat the packet */ 347 /* Return ok: we always eat the packet */
367 return 0; 348 return 0;
368} 349}
369 350
370void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state) 351void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
371{ 352{
372 struct net_device *ndev; 353 struct net_device *ndev;
373 struct brcmf_info *drvr_priv = drvr->info; 354 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
355 struct brcmf_pub *drvr = bus_if->drvr;
374 356
375 brcmf_dbg(TRACE, "Enter\n"); 357 brcmf_dbg(TRACE, "Enter\n");
376 358
377 drvr->txoff = state; 359 ndev = drvr->iflist[ifidx]->ndev;
378 ndev = drvr_priv->iflist[ifidx]->ndev;
379 if (state == ON) 360 if (state == ON)
380 netif_stop_queue(ndev); 361 netif_stop_queue(ndev);
381 else 362 else
382 netif_wake_queue(ndev); 363 netif_wake_queue(ndev);
383} 364}
384 365
385static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, 366static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
386 void *pktdata, struct brcmf_event_msg *event, 367 void *pktdata, struct brcmf_event_msg *event,
387 void **data) 368 void **data)
388{ 369{
389 int bcmerror = 0; 370 int bcmerror = 0;
390 371
391 bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data); 372 bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data);
392 if (bcmerror != 0) 373 if (bcmerror != 0)
393 return bcmerror; 374 return bcmerror;
394 375
395 if (drvr_priv->iflist[*ifidx]->ndev) 376 if (drvr->iflist[*ifidx]->ndev)
396 brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->ndev, 377 brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
397 event, *data); 378 event, *data);
398 379
399 return bcmerror; 380 return bcmerror;
400} 381}
401 382
402void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, 383void brcmf_rx_frame(struct device *dev, int ifidx,
403 struct sk_buff_head *skb_list) 384 struct sk_buff_head *skb_list)
404{ 385{
405 struct brcmf_info *drvr_priv = drvr->info;
406 unsigned char *eth; 386 unsigned char *eth;
407 uint len; 387 uint len;
408 void *data; 388 void *data;
409 struct sk_buff *skb, *pnext; 389 struct sk_buff *skb, *pnext;
410 struct brcmf_if *ifp; 390 struct brcmf_if *ifp;
411 struct brcmf_event_msg event; 391 struct brcmf_event_msg event;
392 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
393 struct brcmf_pub *drvr = bus_if->drvr;
412 394
413 brcmf_dbg(TRACE, "Enter\n"); 395 brcmf_dbg(TRACE, "Enter\n");
414 396
@@ -430,9 +412,9 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
430 eth = skb->data; 412 eth = skb->data;
431 len = skb->len; 413 len = skb->len;
432 414
433 ifp = drvr_priv->iflist[ifidx]; 415 ifp = drvr->iflist[ifidx];
434 if (ifp == NULL) 416 if (ifp == NULL)
435 ifp = drvr_priv->iflist[0]; 417 ifp = drvr->iflist[0];
436 418
437 if (!ifp || !ifp->ndev || 419 if (!ifp || !ifp->ndev ||
438 ifp->ndev->reg_state != NETREG_REGISTERED) { 420 ifp->ndev->reg_state != NETREG_REGISTERED) {
@@ -444,7 +426,7 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
444 skb->protocol = eth_type_trans(skb, skb->dev); 426 skb->protocol = eth_type_trans(skb, skb->dev);
445 427
446 if (skb->pkt_type == PACKET_MULTICAST) 428 if (skb->pkt_type == PACKET_MULTICAST)
447 drvr_priv->pub.rx_multicast++; 429 bus_if->dstats.multicast++;
448 430
449 skb->data = eth; 431 skb->data = eth;
450 skb->len = len; 432 skb->len = len;
@@ -454,17 +436,17 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
454 436
455 /* Process special event packets and then discard them */ 437 /* Process special event packets and then discard them */
456 if (ntohs(skb->protocol) == ETH_P_LINK_CTL) 438 if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
457 brcmf_host_event(drvr_priv, &ifidx, 439 brcmf_host_event(drvr, &ifidx,
458 skb_mac_header(skb), 440 skb_mac_header(skb),
459 &event, &data); 441 &event, &data);
460 442
461 if (drvr_priv->iflist[ifidx]) { 443 if (drvr->iflist[ifidx]) {
462 ifp = drvr_priv->iflist[ifidx]; 444 ifp = drvr->iflist[ifidx];
463 ifp->ndev->last_rx = jiffies; 445 ifp->ndev->last_rx = jiffies;
464 } 446 }
465 447
466 drvr->dstats.rx_bytes += skb->len; 448 bus_if->dstats.rx_bytes += skb->len;
467 drvr->rx_packets++; /* Local count */ 449 bus_if->dstats.rx_packets++; /* Local count */
468 450
469 if (in_interrupt()) 451 if (in_interrupt())
470 netif_rx(skb); 452 netif_rx(skb);
@@ -479,51 +461,48 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
479 } 461 }
480} 462}
481 463
482void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) 464void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
483{ 465{
484 uint ifidx; 466 uint ifidx;
485 struct brcmf_info *drvr_priv = drvr->info;
486 struct ethhdr *eh; 467 struct ethhdr *eh;
487 u16 type; 468 u16 type;
469 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
470 struct brcmf_pub *drvr = bus_if->drvr;
488 471
489 brcmf_proto_hdrpull(drvr, &ifidx, txp); 472 brcmf_proto_hdrpull(dev, &ifidx, txp);
490 473
491 eh = (struct ethhdr *)(txp->data); 474 eh = (struct ethhdr *)(txp->data);
492 type = ntohs(eh->h_proto); 475 type = ntohs(eh->h_proto);
493 476
494 if (type == ETH_P_PAE) 477 if (type == ETH_P_PAE)
495 atomic_dec(&drvr_priv->pend_8021x_cnt); 478 atomic_dec(&drvr->pend_8021x_cnt);
496 479
497} 480}
498 481
499static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 482static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
500{ 483{
501 struct brcmf_if *ifp = netdev_priv(ndev); 484 struct brcmf_if *ifp = netdev_priv(ndev);
502 struct brcmf_info *drvr_priv = ifp->info; 485 struct brcmf_bus *bus_if = ifp->drvr->bus_if;
503 486
504 brcmf_dbg(TRACE, "Enter\n"); 487 brcmf_dbg(TRACE, "Enter\n");
505 488
506 if (drvr_priv->pub.up)
507 /* Use the protocol to get dongle stats */
508 brcmf_proto_dstats(&drvr_priv->pub);
509
510 /* Copy dongle stats to net device stats */ 489 /* Copy dongle stats to net device stats */
511 ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets; 490 ifp->stats.rx_packets = bus_if->dstats.rx_packets;
512 ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets; 491 ifp->stats.tx_packets = bus_if->dstats.tx_packets;
513 ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes; 492 ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
514 ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes; 493 ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
515 ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors; 494 ifp->stats.rx_errors = bus_if->dstats.rx_errors;
516 ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors; 495 ifp->stats.tx_errors = bus_if->dstats.tx_errors;
517 ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped; 496 ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
518 ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped; 497 ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
519 ifp->stats.multicast = drvr_priv->pub.dstats.multicast; 498 ifp->stats.multicast = bus_if->dstats.multicast;
520 499
521 return &ifp->stats; 500 return &ifp->stats;
522} 501}
523 502
524/* Retrieve current toe component enables, which are kept 503/* Retrieve current toe component enables, which are kept
525 as a bitmap in toe_ol iovar */ 504 as a bitmap in toe_ol iovar */
526static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) 505static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol)
527{ 506{
528 struct brcmf_dcmd dcmd; 507 struct brcmf_dcmd dcmd;
529 __le32 toe_le; 508 __le32 toe_le;
@@ -538,17 +517,17 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
538 dcmd.set = false; 517 dcmd.set = false;
539 518
540 strcpy(buf, "toe_ol"); 519 strcpy(buf, "toe_ol");
541 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); 520 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
542 if (ret < 0) { 521 if (ret < 0) {
543 /* Check for older dongle image that doesn't support toe_ol */ 522 /* Check for older dongle image that doesn't support toe_ol */
544 if (ret == -EIO) { 523 if (ret == -EIO) {
545 brcmf_dbg(ERROR, "%s: toe not supported by device\n", 524 brcmf_dbg(ERROR, "%s: toe not supported by device\n",
546 brcmf_ifname(&drvr_priv->pub, ifidx)); 525 brcmf_ifname(drvr, ifidx));
547 return -EOPNOTSUPP; 526 return -EOPNOTSUPP;
548 } 527 }
549 528
550 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", 529 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
551 brcmf_ifname(&drvr_priv->pub, ifidx), ret); 530 brcmf_ifname(drvr, ifidx), ret);
552 return ret; 531 return ret;
553 } 532 }
554 533
@@ -559,7 +538,7 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
559 538
560/* Set current toe component enables in toe_ol iovar, 539/* Set current toe component enables in toe_ol iovar,
561 and set toe global enable iovar */ 540 and set toe global enable iovar */
562static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) 541static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
563{ 542{
564 struct brcmf_dcmd dcmd; 543 struct brcmf_dcmd dcmd;
565 char buf[32]; 544 char buf[32];
@@ -577,10 +556,10 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
577 strcpy(buf, "toe_ol"); 556 strcpy(buf, "toe_ol");
578 memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); 557 memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
579 558
580 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); 559 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
581 if (ret < 0) { 560 if (ret < 0) {
582 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", 561 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
583 brcmf_ifname(&drvr_priv->pub, ifidx), ret); 562 brcmf_ifname(drvr, ifidx), ret);
584 return ret; 563 return ret;
585 } 564 }
586 565
@@ -590,10 +569,10 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
590 strcpy(buf, "toe"); 569 strcpy(buf, "toe");
591 memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); 570 memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
592 571
593 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); 572 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
594 if (ret < 0) { 573 if (ret < 0) {
595 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", 574 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
596 brcmf_ifname(&drvr_priv->pub, ifidx), ret); 575 brcmf_ifname(drvr, ifidx), ret);
597 return ret; 576 return ret;
598 } 577 }
599 578
@@ -604,18 +583,18 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
604 struct ethtool_drvinfo *info) 583 struct ethtool_drvinfo *info)
605{ 584{
606 struct brcmf_if *ifp = netdev_priv(ndev); 585 struct brcmf_if *ifp = netdev_priv(ndev);
607 struct brcmf_info *drvr_priv = ifp->info; 586 struct brcmf_pub *drvr = ifp->drvr;
608 587
609 sprintf(info->driver, KBUILD_MODNAME); 588 sprintf(info->driver, KBUILD_MODNAME);
610 sprintf(info->version, "%lu", drvr_priv->pub.drv_version); 589 sprintf(info->version, "%lu", drvr->drv_version);
611 sprintf(info->bus_info, "%s", dev_name(drvr_priv->pub.dev)); 590 sprintf(info->bus_info, "%s", dev_name(drvr->dev));
612} 591}
613 592
614static struct ethtool_ops brcmf_ethtool_ops = { 593static struct ethtool_ops brcmf_ethtool_ops = {
615 .get_drvinfo = brcmf_ethtool_get_drvinfo 594 .get_drvinfo = brcmf_ethtool_get_drvinfo
616}; 595};
617 596
618static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) 597static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
619{ 598{
620 struct ethtool_drvinfo info; 599 struct ethtool_drvinfo info;
621 char drvname[sizeof(info.driver)]; 600 char drvname[sizeof(info.driver)];
@@ -649,18 +628,18 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
649 } 628 }
650 629
651 /* otherwise, require dongle to be up */ 630 /* otherwise, require dongle to be up */
652 else if (!drvr_priv->pub.up) { 631 else if (!drvr->bus_if->drvr_up) {
653 brcmf_dbg(ERROR, "dongle is not up\n"); 632 brcmf_dbg(ERROR, "dongle is not up\n");
654 return -ENODEV; 633 return -ENODEV;
655 } 634 }
656 635
657 /* finally, report dongle driver type */ 636 /* finally, report dongle driver type */
658 else if (drvr_priv->pub.iswl) 637 else if (drvr->iswl)
659 sprintf(info.driver, "wl"); 638 sprintf(info.driver, "wl");
660 else 639 else
661 sprintf(info.driver, "xx"); 640 sprintf(info.driver, "xx");
662 641
663 sprintf(info.version, "%lu", drvr_priv->pub.drv_version); 642 sprintf(info.version, "%lu", drvr->drv_version);
664 if (copy_to_user(uaddr, &info, sizeof(info))) 643 if (copy_to_user(uaddr, &info, sizeof(info)))
665 return -EFAULT; 644 return -EFAULT;
666 brcmf_dbg(CTL, "given %*s, returning %s\n", 645 brcmf_dbg(CTL, "given %*s, returning %s\n",
@@ -670,7 +649,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
670 /* Get toe offload components from dongle */ 649 /* Get toe offload components from dongle */
671 case ETHTOOL_GRXCSUM: 650 case ETHTOOL_GRXCSUM:
672 case ETHTOOL_GTXCSUM: 651 case ETHTOOL_GTXCSUM:
673 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); 652 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
674 if (ret < 0) 653 if (ret < 0)
675 return ret; 654 return ret;
676 655
@@ -691,7 +670,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
691 return -EFAULT; 670 return -EFAULT;
692 671
693 /* Read the current settings, update and write back */ 672 /* Read the current settings, update and write back */
694 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); 673 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
695 if (ret < 0) 674 if (ret < 0)
696 return ret; 675 return ret;
697 676
@@ -703,17 +682,17 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
703 else 682 else
704 toe_cmpnt &= ~csum_dir; 683 toe_cmpnt &= ~csum_dir;
705 684
706 ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt); 685 ret = brcmf_toe_set(drvr, 0, toe_cmpnt);
707 if (ret < 0) 686 if (ret < 0)
708 return ret; 687 return ret;
709 688
710 /* If setting TX checksum mode, tell Linux the new mode */ 689 /* If setting TX checksum mode, tell Linux the new mode */
711 if (cmd == ETHTOOL_STXCSUM) { 690 if (cmd == ETHTOOL_STXCSUM) {
712 if (edata.data) 691 if (edata.data)
713 drvr_priv->iflist[0]->ndev->features |= 692 drvr->iflist[0]->ndev->features |=
714 NETIF_F_IP_CSUM; 693 NETIF_F_IP_CSUM;
715 else 694 else
716 drvr_priv->iflist[0]->ndev->features &= 695 drvr->iflist[0]->ndev->features &=
717 ~NETIF_F_IP_CSUM; 696 ~NETIF_F_IP_CSUM;
718 } 697 }
719 698
@@ -730,15 +709,15 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
730 int cmd) 709 int cmd)
731{ 710{
732 struct brcmf_if *ifp = netdev_priv(ndev); 711 struct brcmf_if *ifp = netdev_priv(ndev);
733 struct brcmf_info *drvr_priv = ifp->info; 712 struct brcmf_pub *drvr = ifp->drvr;
734 713
735 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); 714 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
736 715
737 if (!drvr_priv->iflist[ifp->idx]) 716 if (!drvr->iflist[ifp->idx])
738 return -1; 717 return -1;
739 718
740 if (cmd == SIOCETHTOOL) 719 if (cmd == SIOCETHTOOL)
741 return brcmf_ethtool(drvr_priv, ifr->ifr_data); 720 return brcmf_ethtool(drvr, ifr->ifr_data);
742 721
743 return -EOPNOTSUPP; 722 return -EOPNOTSUPP;
744} 723}
@@ -751,7 +730,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
751 int buflen = 0; 730 int buflen = 0;
752 bool is_set_key_cmd; 731 bool is_set_key_cmd;
753 struct brcmf_if *ifp = netdev_priv(ndev); 732 struct brcmf_if *ifp = netdev_priv(ndev);
754 struct brcmf_info *drvr_priv = ifp->info; 733 struct brcmf_pub *drvr = ifp->drvr;
755 734
756 memset(&dcmd, 0, sizeof(dcmd)); 735 memset(&dcmd, 0, sizeof(dcmd));
757 dcmd.cmd = cmd; 736 dcmd.cmd = cmd;
@@ -762,13 +741,13 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
762 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); 741 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
763 742
764 /* send to dongle (must be up, and wl) */ 743 /* send to dongle (must be up, and wl) */
765 if ((drvr_priv->pub.bus_if->state != BRCMF_BUS_DATA)) { 744 if ((drvr->bus_if->state != BRCMF_BUS_DATA)) {
766 brcmf_dbg(ERROR, "DONGLE_DOWN\n"); 745 brcmf_dbg(ERROR, "DONGLE_DOWN\n");
767 err = -EIO; 746 err = -EIO;
768 goto done; 747 goto done;
769 } 748 }
770 749
771 if (!drvr_priv->pub.iswl) { 750 if (!drvr->iswl) {
772 err = -EIO; 751 err = -EIO;
773 goto done; 752 goto done;
774 } 753 }
@@ -785,7 +764,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
785 if (is_set_key_cmd) 764 if (is_set_key_cmd)
786 brcmf_netdev_wait_pend8021x(ndev); 765 brcmf_netdev_wait_pend8021x(ndev);
787 766
788 err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen); 767 err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen);
789 768
790done: 769done:
791 if (err > 0) 770 if (err > 0)
@@ -797,15 +776,15 @@ done:
797static int brcmf_netdev_stop(struct net_device *ndev) 776static int brcmf_netdev_stop(struct net_device *ndev)
798{ 777{
799 struct brcmf_if *ifp = netdev_priv(ndev); 778 struct brcmf_if *ifp = netdev_priv(ndev);
800 struct brcmf_pub *drvr = &ifp->info->pub; 779 struct brcmf_pub *drvr = ifp->drvr;
801 780
802 brcmf_dbg(TRACE, "Enter\n"); 781 brcmf_dbg(TRACE, "Enter\n");
803 brcmf_cfg80211_down(drvr->config); 782 brcmf_cfg80211_down(drvr->config);
804 if (drvr->up == 0) 783 if (drvr->bus_if->drvr_up == 0)
805 return 0; 784 return 0;
806 785
807 /* Set state and stop OS transmissions */ 786 /* Set state and stop OS transmissions */
808 drvr->up = false; 787 drvr->bus_if->drvr_up = false;
809 netif_stop_queue(ndev); 788 netif_stop_queue(ndev);
810 789
811 return 0; 790 return 0;
@@ -814,7 +793,7 @@ static int brcmf_netdev_stop(struct net_device *ndev)
814static int brcmf_netdev_open(struct net_device *ndev) 793static int brcmf_netdev_open(struct net_device *ndev)
815{ 794{
816 struct brcmf_if *ifp = netdev_priv(ndev); 795 struct brcmf_if *ifp = netdev_priv(ndev);
817 struct brcmf_info *drvr_priv = ifp->info; 796 struct brcmf_pub *drvr = ifp->drvr;
818 u32 toe_ol; 797 u32 toe_ol;
819 s32 ret = 0; 798 s32 ret = 0;
820 799
@@ -822,28 +801,28 @@ static int brcmf_netdev_open(struct net_device *ndev)
822 801
823 if (ifp->idx == 0) { /* do it only for primary eth0 */ 802 if (ifp->idx == 0) { /* do it only for primary eth0 */
824 /* try to bring up bus */ 803 /* try to bring up bus */
825 ret = brcmf_bus_start(&drvr_priv->pub); 804 ret = brcmf_bus_start(drvr->dev);
826 if (ret != 0) { 805 if (ret != 0) {
827 brcmf_dbg(ERROR, "failed with code %d\n", ret); 806 brcmf_dbg(ERROR, "failed with code %d\n", ret);
828 return -1; 807 return -1;
829 } 808 }
830 atomic_set(&drvr_priv->pend_8021x_cnt, 0); 809 atomic_set(&drvr->pend_8021x_cnt, 0);
831 810
832 memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); 811 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
833 812
834 /* Get current TOE mode from dongle */ 813 /* Get current TOE mode from dongle */
835 if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0 814 if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0
836 && (toe_ol & TOE_TX_CSUM_OL) != 0) 815 && (toe_ol & TOE_TX_CSUM_OL) != 0)
837 drvr_priv->iflist[ifp->idx]->ndev->features |= 816 drvr->iflist[ifp->idx]->ndev->features |=
838 NETIF_F_IP_CSUM; 817 NETIF_F_IP_CSUM;
839 else 818 else
840 drvr_priv->iflist[ifp->idx]->ndev->features &= 819 drvr->iflist[ifp->idx]->ndev->features &=
841 ~NETIF_F_IP_CSUM; 820 ~NETIF_F_IP_CSUM;
842 } 821 }
843 /* Allow transmit calls */ 822 /* Allow transmit calls */
844 netif_start_queue(ndev); 823 netif_start_queue(ndev);
845 drvr_priv->pub.up = true; 824 drvr->bus_if->drvr_up = true;
846 if (brcmf_cfg80211_up(drvr_priv->pub.config)) { 825 if (brcmf_cfg80211_up(drvr->config)) {
847 brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); 826 brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
848 return -1; 827 return -1;
849 } 828 }
@@ -862,14 +841,16 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
862}; 841};
863 842
864int 843int
865brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) 844brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
866{ 845{
867 struct brcmf_if *ifp; 846 struct brcmf_if *ifp;
868 struct net_device *ndev; 847 struct net_device *ndev;
848 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
849 struct brcmf_pub *drvr = bus_if->drvr;
869 850
870 brcmf_dbg(TRACE, "idx %d\n", ifidx); 851 brcmf_dbg(TRACE, "idx %d\n", ifidx);
871 852
872 ifp = drvr_priv->iflist[ifidx]; 853 ifp = drvr->iflist[ifidx];
873 /* 854 /*
874 * Delete the existing interface before overwriting it 855 * Delete the existing interface before overwriting it
875 * in case we missed the BRCMF_E_IF_DEL event. 856 * in case we missed the BRCMF_E_IF_DEL event.
@@ -880,7 +861,7 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr)
880 netif_stop_queue(ifp->ndev); 861 netif_stop_queue(ifp->ndev);
881 unregister_netdev(ifp->ndev); 862 unregister_netdev(ifp->ndev);
882 free_netdev(ifp->ndev); 863 free_netdev(ifp->ndev);
883 drvr_priv->iflist[ifidx] = NULL; 864 drvr->iflist[ifidx] = NULL;
884 } 865 }
885 866
886 /* Allocate netdev, including space for private structure */ 867 /* Allocate netdev, including space for private structure */
@@ -892,16 +873,16 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr)
892 873
893 ifp = netdev_priv(ndev); 874 ifp = netdev_priv(ndev);
894 ifp->ndev = ndev; 875 ifp->ndev = ndev;
895 ifp->info = drvr_priv; 876 ifp->drvr = drvr;
896 drvr_priv->iflist[ifidx] = ifp; 877 drvr->iflist[ifidx] = ifp;
897 ifp->idx = ifidx; 878 ifp->idx = ifidx;
898 if (mac_addr != NULL) 879 if (mac_addr != NULL)
899 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); 880 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
900 881
901 if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) { 882 if (brcmf_net_attach(drvr, ifp->idx)) {
902 brcmf_dbg(ERROR, "brcmf_net_attach failed"); 883 brcmf_dbg(ERROR, "brcmf_net_attach failed");
903 free_netdev(ifp->ndev); 884 free_netdev(ifp->ndev);
904 drvr_priv->iflist[ifidx] = NULL; 885 drvr->iflist[ifidx] = NULL;
905 return -EOPNOTSUPP; 886 return -EOPNOTSUPP;
906 } 887 }
907 888
@@ -911,13 +892,13 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr)
911 return 0; 892 return 0;
912} 893}
913 894
914void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) 895void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
915{ 896{
916 struct brcmf_if *ifp; 897 struct brcmf_if *ifp;
917 898
918 brcmf_dbg(TRACE, "idx %d\n", ifidx); 899 brcmf_dbg(TRACE, "idx %d\n", ifidx);
919 900
920 ifp = drvr_priv->iflist[ifidx]; 901 ifp = drvr->iflist[ifidx];
921 if (!ifp) { 902 if (!ifp) {
922 brcmf_dbg(ERROR, "Null interface\n"); 903 brcmf_dbg(ERROR, "Null interface\n");
923 return; 904 return;
@@ -934,72 +915,70 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
934 } 915 }
935 916
936 unregister_netdev(ifp->ndev); 917 unregister_netdev(ifp->ndev);
937 drvr_priv->iflist[ifidx] = NULL; 918 drvr->iflist[ifidx] = NULL;
938 if (ifidx == 0) 919 if (ifidx == 0)
939 brcmf_cfg80211_detach(drvr_priv->pub.config); 920 brcmf_cfg80211_detach(drvr->config);
940 free_netdev(ifp->ndev); 921 free_netdev(ifp->ndev);
941 } 922 }
942} 923}
943 924
944struct brcmf_pub *brcmf_attach(struct brcmf_sdio *bus, uint bus_hdrlen, 925int brcmf_attach(uint bus_hdrlen, struct device *dev)
945 struct device *dev)
946{ 926{
947 struct brcmf_info *drvr_priv = NULL; 927 struct brcmf_pub *drvr = NULL;
928 int ret = 0;
948 929
949 brcmf_dbg(TRACE, "Enter\n"); 930 brcmf_dbg(TRACE, "Enter\n");
950 931
951 /* Allocate primary brcmf_info */ 932 /* Allocate primary brcmf_info */
952 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); 933 drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
953 if (!drvr_priv) 934 if (!drvr)
954 goto fail; 935 return -ENOMEM;
955
956 mutex_init(&drvr_priv->proto_block);
957 936
958 /* Link to info module */ 937 mutex_init(&drvr->proto_block);
959 drvr_priv->pub.info = drvr_priv;
960 938
961 /* Link to bus module */ 939 /* Link to bus module */
962 drvr_priv->pub.bus = bus; 940 drvr->hdrlen = bus_hdrlen;
963 drvr_priv->pub.hdrlen = bus_hdrlen; 941 drvr->bus_if = dev_get_drvdata(dev);
964 drvr_priv->pub.bus_if = dev_get_drvdata(dev); 942 drvr->bus_if->drvr = drvr;
965 drvr_priv->pub.dev = dev; 943 drvr->dev = dev;
966 944
967 /* Attach and link in the protocol */ 945 /* Attach and link in the protocol */
968 if (brcmf_proto_attach(&drvr_priv->pub) != 0) { 946 ret = brcmf_proto_attach(drvr);
947 if (ret != 0) {
969 brcmf_dbg(ERROR, "brcmf_prot_attach failed\n"); 948 brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
970 goto fail; 949 goto fail;
971 } 950 }
972 951
973 INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); 952 INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address);
974 INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); 953 INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list);
975 954
976 return &drvr_priv->pub; 955 return ret;
977 956
978fail: 957fail:
979 if (drvr_priv) 958 brcmf_detach(dev);
980 brcmf_detach(&drvr_priv->pub);
981 959
982 return NULL; 960 return ret;
983} 961}
984 962
985int brcmf_bus_start(struct brcmf_pub *drvr) 963int brcmf_bus_start(struct device *dev)
986{ 964{
987 int ret = -1; 965 int ret = -1;
988 struct brcmf_info *drvr_priv = drvr->info;
989 /* Room for "event_msgs" + '\0' + bitvec */ 966 /* Room for "event_msgs" + '\0' + bitvec */
990 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; 967 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
968 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
969 struct brcmf_pub *drvr = bus_if->drvr;
991 970
992 brcmf_dbg(TRACE, "\n"); 971 brcmf_dbg(TRACE, "\n");
993 972
994 /* Bring up the bus */ 973 /* Bring up the bus */
995 ret = brcmf_sdbrcm_bus_init(drvr_priv->pub.dev); 974 ret = bus_if->brcmf_bus_init(dev);
996 if (ret != 0) { 975 if (ret != 0) {
997 brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret); 976 brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
998 return ret; 977 return ret;
999 } 978 }
1000 979
1001 /* If bus is not ready, can't come up */ 980 /* If bus is not ready, can't come up */
1002 if (drvr_priv->pub.bus_if->state != BRCMF_BUS_DATA) { 981 if (bus_if->state != BRCMF_BUS_DATA) {
1003 brcmf_dbg(ERROR, "failed bus is not ready\n"); 982 brcmf_dbg(ERROR, "failed bus is not ready\n");
1004 return -ENODEV; 983 return -ENODEV;
1005 } 984 }
@@ -1036,7 +1015,7 @@ int brcmf_bus_start(struct brcmf_pub *drvr)
1036 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; 1015 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
1037 1016
1038 /* Bus is ready, do any protocol initialization */ 1017 /* Bus is ready, do any protocol initialization */
1039 ret = brcmf_proto_init(&drvr_priv->pub); 1018 ret = brcmf_proto_init(drvr);
1040 if (ret < 0) 1019 if (ret < 0)
1041 return ret; 1020 return ret;
1042 1021
@@ -1045,14 +1024,13 @@ int brcmf_bus_start(struct brcmf_pub *drvr)
1045 1024
1046int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) 1025int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1047{ 1026{
1048 struct brcmf_info *drvr_priv = drvr->info;
1049 struct net_device *ndev; 1027 struct net_device *ndev;
1050 u8 temp_addr[ETH_ALEN] = { 1028 u8 temp_addr[ETH_ALEN] = {
1051 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; 1029 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1052 1030
1053 brcmf_dbg(TRACE, "ifidx %d\n", ifidx); 1031 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
1054 1032
1055 ndev = drvr_priv->iflist[ifidx]->ndev; 1033 ndev = drvr->iflist[ifidx]->ndev;
1056 ndev->netdev_ops = &brcmf_netdev_ops_pri; 1034 ndev->netdev_ops = &brcmf_netdev_ops_pri;
1057 1035
1058 /* 1036 /*
@@ -1060,7 +1038,7 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1060 */ 1038 */
1061 if (ifidx != 0) { 1039 if (ifidx != 0) {
1062 /* for virtual interfaces use the primary MAC */ 1040 /* for virtual interfaces use the primary MAC */
1063 memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN); 1041 memcpy(temp_addr, drvr->mac, ETH_ALEN);
1064 1042
1065 } 1043 }
1066 1044
@@ -1071,11 +1049,11 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1071 - Locally Administered address */ 1049 - Locally Administered address */
1072 1050
1073 } 1051 }
1074 ndev->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen; 1052 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
1075 ndev->ethtool_ops = &brcmf_ethtool_ops; 1053 ndev->ethtool_ops = &brcmf_ethtool_ops;
1076 1054
1077 drvr_priv->pub.rxsz = ndev->mtu + ndev->hard_header_len + 1055 drvr->rxsz = ndev->mtu + ndev->hard_header_len +
1078 drvr_priv->pub.hdrlen; 1056 drvr->hdrlen;
1079 1057
1080 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); 1058 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
1081 1059
@@ -1104,77 +1082,46 @@ fail:
1104 1082
1105static void brcmf_bus_detach(struct brcmf_pub *drvr) 1083static void brcmf_bus_detach(struct brcmf_pub *drvr)
1106{ 1084{
1107 struct brcmf_info *drvr_priv;
1108
1109 brcmf_dbg(TRACE, "Enter\n"); 1085 brcmf_dbg(TRACE, "Enter\n");
1110 1086
1111 if (drvr) { 1087 if (drvr) {
1112 drvr_priv = drvr->info; 1088 /* Stop the protocol module */
1113 if (drvr_priv) { 1089 brcmf_proto_stop(drvr);
1114 /* Stop the protocol module */
1115 brcmf_proto_stop(&drvr_priv->pub);
1116 1090
1117 /* Stop the bus module */ 1091 /* Stop the bus module */
1118 brcmf_sdbrcm_bus_stop(drvr_priv->pub.dev); 1092 drvr->bus_if->brcmf_bus_stop(drvr->dev);
1119 }
1120 } 1093 }
1121} 1094}
1122 1095
1123void brcmf_detach(struct brcmf_pub *drvr) 1096void brcmf_detach(struct device *dev)
1124{ 1097{
1125 struct brcmf_info *drvr_priv; 1098 int i;
1099 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1100 struct brcmf_pub *drvr = bus_if->drvr;
1126 1101
1127 brcmf_dbg(TRACE, "Enter\n"); 1102 brcmf_dbg(TRACE, "Enter\n");
1128 1103
1129 if (drvr) {
1130 drvr_priv = drvr->info;
1131 if (drvr_priv) {
1132 int i;
1133 1104
1134 /* make sure primary interface removed last */ 1105 /* make sure primary interface removed last */
1135 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 1106 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1136 if (drvr_priv->iflist[i]) 1107 if (drvr->iflist[i])
1137 brcmf_del_if(drvr_priv, i); 1108 brcmf_del_if(drvr, i);
1138 1109
1139 cancel_work_sync(&drvr_priv->setmacaddr_work); 1110 cancel_work_sync(&drvr->setmacaddr_work);
1140 cancel_work_sync(&drvr_priv->multicast_work); 1111 cancel_work_sync(&drvr->multicast_work);
1141 1112
1142 brcmf_bus_detach(drvr); 1113 brcmf_bus_detach(drvr);
1143 1114
1144 if (drvr->prot) 1115 if (drvr->prot)
1145 brcmf_proto_detach(drvr); 1116 brcmf_proto_detach(drvr);
1146 1117
1147 kfree(drvr_priv); 1118 bus_if->drvr = NULL;
1148 } 1119 kfree(drvr);
1149 }
1150}
1151
1152int brcmf_os_proto_block(struct brcmf_pub *drvr)
1153{
1154 struct brcmf_info *drvr_priv = drvr->info;
1155
1156 if (drvr_priv) {
1157 mutex_lock(&drvr_priv->proto_block);
1158 return 1;
1159 }
1160 return 0;
1161}
1162
1163int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
1164{
1165 struct brcmf_info *drvr_priv = drvr->info;
1166
1167 if (drvr_priv) {
1168 mutex_unlock(&drvr_priv->proto_block);
1169 return 1;
1170 }
1171
1172 return 0;
1173} 1120}
1174 1121
1175static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) 1122static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
1176{ 1123{
1177 return atomic_read(&drvr_priv->pend_8021x_cnt); 1124 return atomic_read(&drvr->pend_8021x_cnt);
1178} 1125}
1179 1126
1180#define MAX_WAIT_FOR_8021X_TX 10 1127#define MAX_WAIT_FOR_8021X_TX 10
@@ -1182,10 +1129,10 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1182int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 1129int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1183{ 1130{
1184 struct brcmf_if *ifp = netdev_priv(ndev); 1131 struct brcmf_if *ifp = netdev_priv(ndev);
1185 struct brcmf_info *drvr_priv = ifp->info; 1132 struct brcmf_pub *drvr = ifp->drvr;
1186 int timeout = 10 * HZ / 1000; 1133 int timeout = 10 * HZ / 1000;
1187 int ntimes = MAX_WAIT_FOR_8021X_TX; 1134 int ntimes = MAX_WAIT_FOR_8021X_TX;
1188 int pend = brcmf_get_pend_8021x_cnt(drvr_priv); 1135 int pend = brcmf_get_pend_8021x_cnt(drvr);
1189 1136
1190 while (ntimes && pend) { 1137 while (ntimes && pend) {
1191 if (pend) { 1138 if (pend) {
@@ -1194,7 +1141,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1194 set_current_state(TASK_RUNNING); 1141 set_current_state(TASK_RUNNING);
1195 ntimes--; 1142 ntimes--;
1196 } 1143 }
1197 pend = brcmf_get_pend_8021x_cnt(drvr_priv); 1144 pend = brcmf_get_pend_8021x_cnt(drvr);
1198 } 1145 }
1199 return pend; 1146 return pend;
1200} 1147}