forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * Copyright (c) 2010 Broadcom Corporation
3
- *
4
- * Permission to use, copy, modify, and/or distribute this software for any
5
- * purpose with or without fee is hereby granted, provided that the above
6
- * copyright notice and this permission notice appear in all copies.
7
- *
8
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
154 */
165
176 #include <linux/kernel.h>
....@@ -43,6 +32,36 @@
4332
4433 #define BRCMF_BSSIDX_INVALID -1
4534
35
+#define RXS_PBPRES BIT(2)
36
+
37
+#define D11_PHY_HDR_LEN 6
38
+
39
+struct d11rxhdr_le {
40
+ __le16 RxFrameSize;
41
+ u16 PAD;
42
+ __le16 PhyRxStatus_0;
43
+ __le16 PhyRxStatus_1;
44
+ __le16 PhyRxStatus_2;
45
+ __le16 PhyRxStatus_3;
46
+ __le16 PhyRxStatus_4;
47
+ __le16 PhyRxStatus_5;
48
+ __le16 RxStatus1;
49
+ __le16 RxStatus2;
50
+ __le16 RxTSFTime;
51
+ __le16 RxChan;
52
+ u8 unknown[12];
53
+} __packed;
54
+
55
+struct wlc_d11rxhdr {
56
+ struct d11rxhdr_le rxhdr;
57
+ __le32 tsf_l;
58
+ s8 rssi;
59
+ s8 rxpwr0;
60
+ s8 rxpwr1;
61
+ s8 do_rssi_ma;
62
+ s8 rxpwr[4];
63
+} __packed;
64
+
4665 char *brcmf_ifname(struct brcmf_if *ifp)
4766 {
4867 if (!ifp)
....@@ -60,7 +79,7 @@
6079 s32 bsscfgidx;
6180
6281 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
63
- brcmf_err("ifidx %d out of range\n", ifidx);
82
+ bphy_err(drvr, "ifidx %d out of range\n", ifidx);
6483 return NULL;
6584 }
6685
....@@ -111,7 +130,9 @@
111130
112131 static void _brcmf_set_multicast_list(struct work_struct *work)
113132 {
114
- struct brcmf_if *ifp;
133
+ struct brcmf_if *ifp = container_of(work, struct brcmf_if,
134
+ multicast_work);
135
+ struct brcmf_pub *drvr = ifp->drvr;
115136 struct net_device *ndev;
116137 struct netdev_hw_addr *ha;
117138 u32 cmd_value, cnt;
....@@ -119,8 +140,6 @@
119140 char *buf, *bufp;
120141 u32 buflen;
121142 s32 err;
122
-
123
- ifp = container_of(work, struct brcmf_if, multicast_work);
124143
125144 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
126145
....@@ -151,7 +170,7 @@
151170
152171 err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
153172 if (err < 0) {
154
- brcmf_err("Setting mcast_list failed, %d\n", err);
173
+ bphy_err(drvr, "Setting mcast_list failed, %d\n", err);
155174 cmd_value = cnt ? true : cmd_value;
156175 }
157176
....@@ -164,24 +183,24 @@
164183 */
165184 err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
166185 if (err < 0)
167
- brcmf_err("Setting allmulti failed, %d\n", err);
186
+ bphy_err(drvr, "Setting allmulti failed, %d\n", err);
168187
169188 /*Finally, pick up the PROMISC flag */
170189 cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
171190 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
172191 if (err < 0)
173
- brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
174
- err);
192
+ bphy_err(drvr, "Setting BRCMF_C_SET_PROMISC failed, %d\n",
193
+ err);
175194 brcmf_configure_arp_nd_offload(ifp, !cmd_value);
176195 }
177196
178197 #if IS_ENABLED(CONFIG_IPV6)
179198 static void _brcmf_update_ndtable(struct work_struct *work)
180199 {
181
- struct brcmf_if *ifp;
200
+ struct brcmf_if *ifp = container_of(work, struct brcmf_if,
201
+ ndoffload_work);
202
+ struct brcmf_pub *drvr = ifp->drvr;
182203 int i, ret;
183
-
184
- ifp = container_of(work, struct brcmf_if, ndoffload_work);
185204
186205 /* clear the table in firmware */
187206 ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
....@@ -195,7 +214,7 @@
195214 &ifp->ipv6_addr_tbl[i],
196215 sizeof(struct in6_addr));
197216 if (ret)
198
- brcmf_err("add nd ip err %d\n", ret);
217
+ bphy_err(drvr, "add nd ip err %d\n", ret);
199218 }
200219 }
201220 #else
....@@ -208,6 +227,7 @@
208227 {
209228 struct brcmf_if *ifp = netdev_priv(ndev);
210229 struct sockaddr *sa = (struct sockaddr *)addr;
230
+ struct brcmf_pub *drvr = ifp->drvr;
211231 int err;
212232
213233 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
....@@ -215,7 +235,7 @@
215235 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data,
216236 ETH_ALEN);
217237 if (err < 0) {
218
- brcmf_err("Setting cur_etheraddr failed, %d\n", err);
238
+ bphy_err(drvr, "Setting cur_etheraddr failed, %d\n", err);
219239 } else {
220240 brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);
221241 memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);
....@@ -270,12 +290,13 @@
270290 struct brcmf_pub *drvr = ifp->drvr;
271291 struct ethhdr *eh;
272292 int head_delta;
293
+ unsigned int tx_bytes = skb->len;
273294
274295 brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
275296
276297 /* Can the device send data? */
277298 if (drvr->bus_if->state != BRCMF_BUS_UP) {
278
- brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
299
+ bphy_err(drvr, "xmit rejected state=%d\n", drvr->bus_if->state);
279300 netif_stop_queue(ndev);
280301 dev_kfree_skb(skb);
281302 ret = -ENODEV;
....@@ -309,8 +330,8 @@
309330 ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0,
310331 GFP_ATOMIC);
311332 if (ret < 0) {
312
- brcmf_err("%s: failed to expand headroom\n",
313
- brcmf_ifname(ifp));
333
+ bphy_err(drvr, "%s: failed to expand headroom\n",
334
+ brcmf_ifname(ifp));
314335 atomic_inc(&drvr->bus_if->stats.pktcow_failed);
315336 goto done;
316337 }
....@@ -332,6 +353,9 @@
332353 if ((skb->priority == 0) || (skb->priority > 7))
333354 skb->priority = cfg80211_classify8021d(skb, NULL);
334355
356
+ /* set pacing shift for packet aggregation */
357
+ sk_pacing_shift_update(skb->sk, 8);
358
+
335359 ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
336360 if (ret < 0)
337361 brcmf_txfinalize(ifp, skb, false);
....@@ -341,7 +365,7 @@
341365 ndev->stats.tx_dropped++;
342366 } else {
343367 ndev->stats.tx_packets++;
344
- ndev->stats.tx_bytes += skb->len;
368
+ ndev->stats.tx_bytes += tx_bytes;
345369 }
346370
347371 /* Return ok: we always eat the packet */
....@@ -372,7 +396,7 @@
372396 spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
373397 }
374398
375
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
399
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq)
376400 {
377401 /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
378402 * STA connects to the AP interface. This is an obsoleted standard most
....@@ -395,20 +419,46 @@
395419 ifp->ndev->stats.rx_packets++;
396420
397421 brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol));
398
- if (in_interrupt())
422
+ if (inirq) {
399423 netif_rx(skb);
400
- else
424
+ } else {
401425 /* If the receive is not processed inside an ISR,
402426 * the softirqd must be woken explicitly to service
403427 * the NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
404428 */
405429 netif_rx_ni(skb);
430
+ }
406431 }
407432
408433 void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
409434 {
410435 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
411436 /* Do nothing */
437
+ } else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {
438
+ struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data;
439
+ struct ieee80211_radiotap_header *radiotap;
440
+ unsigned int offset;
441
+ u16 RxStatus1;
442
+
443
+ RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);
444
+
445
+ offset = sizeof(struct wlc_d11rxhdr);
446
+ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU
447
+ * subframes
448
+ */
449
+ if (RxStatus1 & RXS_PBPRES)
450
+ offset += 2;
451
+ offset += D11_PHY_HDR_LEN;
452
+
453
+ skb_pull(skb, offset);
454
+
455
+ /* TODO: use RX header to fill some radiotap data */
456
+ radiotap = skb_push(skb, sizeof(*radiotap));
457
+ memset(radiotap, 0, sizeof(*radiotap));
458
+ radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
459
+
460
+ /* TODO: 4 bytes with receive status? */
461
+ skb->len -= 4;
412462 } else {
413463 struct ieee80211_radiotap_header *radiotap;
414464
....@@ -426,7 +476,7 @@
426476 skb->pkt_type = PACKET_OTHERHOST;
427477 skb->protocol = htons(ETH_P_802_2);
428478
429
- brcmf_netif_rx(ifp, skb);
479
+ brcmf_netif_rx(ifp, skb, false);
430480 }
431481
432482 static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
....@@ -448,7 +498,8 @@
448498 return 0;
449499 }
450500
451
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
501
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,
502
+ bool inirq)
452503 {
453504 struct brcmf_if *ifp;
454505 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
....@@ -460,14 +511,16 @@
460511 return;
461512
462513 if (brcmf_proto_is_reorder_skb(skb)) {
463
- brcmf_proto_rxreorder(ifp, skb);
514
+ brcmf_proto_rxreorder(ifp, skb, inirq);
464515 } else {
465516 /* Process special event packets */
466
- if (handle_event)
467
- brcmf_fweh_process_skb(ifp->drvr, skb,
468
- BCMILCP_SUBTYPE_VENDOR_LONG);
517
+ if (handle_event) {
518
+ gfp_t gfp = inirq ? GFP_ATOMIC : GFP_KERNEL;
469519
470
- brcmf_netif_rx(ifp, skb);
520
+ brcmf_fweh_process_skb(ifp->drvr, skb,
521
+ BCMILCP_SUBTYPE_VENDOR_LONG, gfp);
522
+ }
523
+ brcmf_netif_rx(ifp, skb, inirq);
471524 }
472525 }
473526
....@@ -482,7 +535,7 @@
482535 if (brcmf_rx_hdrpull(drvr, skb, &ifp))
483536 return;
484537
485
- brcmf_fweh_process_skb(ifp->drvr, skb, 0);
538
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
486539 brcmu_pkt_buf_free_skb(skb);
487540 }
488541
....@@ -534,8 +587,6 @@
534587
535588 brcmf_cfg80211_down(ndev);
536589
537
- brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0);
538
-
539590 brcmf_net_setcarrier(ifp, false);
540591
541592 return 0;
....@@ -552,7 +603,7 @@
552603
553604 /* If bus is not ready, can't continue */
554605 if (bus_if->state != BRCMF_BUS_UP) {
555
- brcmf_err("failed bus is not ready\n");
606
+ bphy_err(drvr, "failed bus is not ready\n");
556607 return -EAGAIN;
557608 }
558609
....@@ -566,7 +617,7 @@
566617 ndev->features &= ~NETIF_F_IP_CSUM;
567618
568619 if (brcmf_cfg80211_up(ndev)) {
569
- brcmf_err("failed to bring up cfg80211\n");
620
+ bphy_err(drvr, "failed to bring up cfg80211\n");
570621 return -EIO;
571622 }
572623
....@@ -611,9 +662,11 @@
611662 else
612663 err = register_netdev(ndev);
613664 if (err != 0) {
614
- brcmf_err("couldn't register the net device\n");
665
+ bphy_err(drvr, "couldn't register the net device\n");
615666 goto fail;
616667 }
668
+
669
+ netif_carrier_off(ndev);
617670
618671 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
619672 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
....@@ -625,7 +678,7 @@
625678 return -EBADE;
626679 }
627680
628
-static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
681
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
629682 {
630683 if (ndev->reg_state == NETREG_REGISTERED) {
631684 if (rtnl_locked)
....@@ -636,6 +689,81 @@
636689 brcmf_cfg80211_free_netdev(ndev);
637690 free_netdev(ndev);
638691 }
692
+}
693
+
694
+static int brcmf_net_mon_open(struct net_device *ndev)
695
+{
696
+ struct brcmf_if *ifp = netdev_priv(ndev);
697
+ struct brcmf_pub *drvr = ifp->drvr;
698
+ u32 monitor;
699
+ int err;
700
+
701
+ brcmf_dbg(TRACE, "Enter\n");
702
+
703
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);
704
+ if (err) {
705
+ bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);
706
+ return err;
707
+ } else if (monitor) {
708
+ bphy_err(drvr, "Monitor mode is already enabled\n");
709
+ return -EEXIST;
710
+ }
711
+
712
+ monitor = 3;
713
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
714
+ if (err)
715
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
716
+
717
+ return err;
718
+}
719
+
720
+static int brcmf_net_mon_stop(struct net_device *ndev)
721
+{
722
+ struct brcmf_if *ifp = netdev_priv(ndev);
723
+ struct brcmf_pub *drvr = ifp->drvr;
724
+ u32 monitor;
725
+ int err;
726
+
727
+ brcmf_dbg(TRACE, "Enter\n");
728
+
729
+ monitor = 0;
730
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
731
+ if (err)
732
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
733
+
734
+ return err;
735
+}
736
+
737
+static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb,
738
+ struct net_device *ndev)
739
+{
740
+ dev_kfree_skb_any(skb);
741
+
742
+ return NETDEV_TX_OK;
743
+}
744
+
745
+static const struct net_device_ops brcmf_netdev_ops_mon = {
746
+ .ndo_open = brcmf_net_mon_open,
747
+ .ndo_stop = brcmf_net_mon_stop,
748
+ .ndo_start_xmit = brcmf_net_mon_start_xmit,
749
+};
750
+
751
+int brcmf_net_mon_attach(struct brcmf_if *ifp)
752
+{
753
+ struct brcmf_pub *drvr = ifp->drvr;
754
+ struct net_device *ndev;
755
+ int err;
756
+
757
+ brcmf_dbg(TRACE, "Enter\n");
758
+
759
+ ndev = ifp->ndev;
760
+ ndev->netdev_ops = &brcmf_netdev_ops_mon;
761
+
762
+ err = register_netdevice(ndev);
763
+ if (err)
764
+ bphy_err(drvr, "Failed to register %s device\n", ndev->name);
765
+
766
+ return err;
639767 }
640768
641769 void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
....@@ -688,6 +816,7 @@
688816
689817 static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
690818 {
819
+ struct brcmf_pub *drvr = ifp->drvr;
691820 struct net_device *ndev;
692821
693822 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
....@@ -700,7 +829,7 @@
700829 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
701830
702831 if (register_netdev(ndev) != 0) {
703
- brcmf_err("couldn't register the p2p net device\n");
832
+ bphy_err(drvr, "couldn't register the p2p net device\n");
704833 goto fail;
705834 }
706835
....@@ -729,8 +858,8 @@
729858 */
730859 if (ifp) {
731860 if (ifidx) {
732
- brcmf_err("ERROR: netdev:%s already exists\n",
733
- ifp->ndev->name);
861
+ bphy_err(drvr, "ERROR: netdev:%s already exists\n",
862
+ ifp->ndev->name);
734863 netif_stop_queue(ifp->ndev);
735864 brcmf_net_detach(ifp->ndev, false);
736865 drvr->iflist[bsscfgidx] = NULL;
....@@ -788,7 +917,7 @@
788917
789918 ifp = drvr->iflist[bsscfgidx];
790919 if (!ifp) {
791
- brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx);
920
+ bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx);
792921 return;
793922 }
794923 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,
....@@ -842,16 +971,17 @@
842971 const struct brcmf_event_msg *evtmsg,
843972 void *data)
844973 {
974
+ struct brcmf_pub *drvr = ifp->drvr;
845975 int err;
846976
847977 brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
848978
849
- brcmf_err("PSM's watchdog has fired!\n");
979
+ bphy_err(drvr, "PSM's watchdog has fired!\n");
850980
851981 err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
852982 evtmsg->datalen);
853983 if (err)
854
- brcmf_err("Failed to get memory dump, %d\n", err);
984
+ bphy_err(drvr, "Failed to get memory dump, %d\n", err);
855985
856986 return err;
857987 }
....@@ -895,7 +1025,7 @@
8951025 ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table,
8961026 sizeof(addr_table));
8971027 if (ret) {
898
- brcmf_err("fail to get arp ip table err:%d\n", ret);
1028
+ bphy_err(drvr, "fail to get arp ip table err:%d\n", ret);
8991029 return NOTIFY_OK;
9001030 }
9011031
....@@ -912,7 +1042,7 @@
9121042 ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
9131043 &ifa->ifa_address, sizeof(ifa->ifa_address));
9141044 if (ret)
915
- brcmf_err("add arp ip err %d\n", ret);
1045
+ bphy_err(drvr, "add arp ip err %d\n", ret);
9161046 }
9171047 break;
9181048 case NETDEV_DOWN:
....@@ -924,8 +1054,8 @@
9241054 ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear",
9251055 NULL, 0);
9261056 if (ret) {
927
- brcmf_err("fail to clear arp ip table err:%d\n",
928
- ret);
1057
+ bphy_err(drvr, "fail to clear arp ip table err:%d\n",
1058
+ ret);
9291059 return NOTIFY_OK;
9301060 }
9311061 for (i = 0; i < ARPOL_MAX_ENTRIES; i++) {
....@@ -935,8 +1065,8 @@
9351065 &addr_table[i],
9361066 sizeof(addr_table[i]));
9371067 if (ret)
938
- brcmf_err("add arp ip err %d\n",
939
- ret);
1068
+ bphy_err(drvr, "add arp ip err %d\n",
1069
+ ret);
9401070 }
9411071 }
9421072 break;
....@@ -1030,6 +1160,37 @@
10301160 return 0;
10311161 }
10321162
1163
+static void brcmf_core_bus_reset(struct work_struct *work)
1164
+{
1165
+ struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
1166
+ bus_reset);
1167
+
1168
+ brcmf_bus_reset(drvr->bus_if);
1169
+}
1170
+
1171
+static ssize_t bus_reset_write(struct file *file, const char __user *user_buf,
1172
+ size_t count, loff_t *ppos)
1173
+{
1174
+ struct brcmf_pub *drvr = file->private_data;
1175
+ u8 value;
1176
+
1177
+ if (kstrtou8_from_user(user_buf, count, 0, &value))
1178
+ return -EINVAL;
1179
+
1180
+ if (value != 1)
1181
+ return -EINVAL;
1182
+
1183
+ schedule_work(&drvr->bus_reset);
1184
+
1185
+ return count;
1186
+}
1187
+
1188
+static const struct file_operations bus_reset_fops = {
1189
+ .open = simple_open,
1190
+ .llseek = no_llseek,
1191
+ .write = bus_reset_write,
1192
+};
1193
+
10331194 static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
10341195 {
10351196 int ret = -1;
....@@ -1101,8 +1262,12 @@
11011262 #endif
11021263 #endif /* CONFIG_INET */
11031264
1265
+ INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset);
1266
+
11041267 /* populate debugfs */
11051268 brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1269
+ debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr,
1270
+ &bus_reset_fops);
11061271 brcmf_feat_debugfs_create(drvr);
11071272 brcmf_proto_debugfs_create(drvr);
11081273 brcmf_bus_debugfs_create(bus_if);
....@@ -1110,7 +1275,7 @@
11101275 return 0;
11111276
11121277 fail:
1113
- brcmf_err("failed: %d\n", ret);
1278
+ bphy_err(drvr, "failed: %d\n", ret);
11141279 if (drvr->config) {
11151280 brcmf_cfg80211_detach(drvr->config);
11161281 drvr->config = NULL;
....@@ -1126,13 +1291,11 @@
11261291 return ret;
11271292 }
11281293
1129
-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
1294
+int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)
11301295 {
11311296 struct wiphy *wiphy;
11321297 struct cfg80211_ops *ops;
11331298 struct brcmf_pub *drvr = NULL;
1134
- int ret = 0;
1135
- int i;
11361299
11371300 brcmf_dbg(TRACE, "Enter\n");
11381301
....@@ -1141,12 +1304,30 @@
11411304 return -ENOMEM;
11421305
11431306 wiphy = wiphy_new(ops, sizeof(*drvr));
1144
- if (!wiphy)
1307
+ if (!wiphy) {
1308
+ kfree(ops);
11451309 return -ENOMEM;
1310
+ }
11461311
11471312 set_wiphy_dev(wiphy, dev);
11481313 drvr = wiphy_priv(wiphy);
11491314 drvr->wiphy = wiphy;
1315
+ drvr->ops = ops;
1316
+ drvr->bus_if = dev_get_drvdata(dev);
1317
+ drvr->bus_if->drvr = drvr;
1318
+ drvr->settings = settings;
1319
+
1320
+ return 0;
1321
+}
1322
+
1323
+int brcmf_attach(struct device *dev)
1324
+{
1325
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1326
+ struct brcmf_pub *drvr = bus_if->drvr;
1327
+ int ret = 0;
1328
+ int i;
1329
+
1330
+ brcmf_dbg(TRACE, "Enter\n");
11501331
11511332 for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
11521333 drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
....@@ -1155,14 +1336,11 @@
11551336
11561337 /* Link to bus module */
11571338 drvr->hdrlen = 0;
1158
- drvr->bus_if = dev_get_drvdata(dev);
1159
- drvr->bus_if->drvr = drvr;
1160
- drvr->settings = settings;
11611339
11621340 /* Attach and link in the protocol */
11631341 ret = brcmf_proto_attach(drvr);
11641342 if (ret != 0) {
1165
- brcmf_err("brcmf_prot_attach failed\n");
1343
+ bphy_err(drvr, "brcmf_prot_attach failed\n");
11661344 goto fail;
11671345 }
11681346
....@@ -1173,18 +1351,16 @@
11731351 /* attach firmware event handler */
11741352 brcmf_fweh_attach(drvr);
11751353
1176
- ret = brcmf_bus_started(drvr, ops);
1354
+ ret = brcmf_bus_started(drvr, drvr->ops);
11771355 if (ret != 0) {
1178
- brcmf_err("dongle is not responding: err=%d\n", ret);
1356
+ bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
11791357 goto fail;
11801358 }
11811359
1182
- drvr->config->ops = ops;
11831360 return 0;
11841361
11851362 fail:
11861363 brcmf_detach(dev);
1187
- kfree(ops);
11881364
11891365 return ret;
11901366 }
....@@ -1219,6 +1395,18 @@
12191395 brcmf_dbg(TRACE, "failed to create coredump\n");
12201396 }
12211397
1398
+void brcmf_fw_crashed(struct device *dev)
1399
+{
1400
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1401
+ struct brcmf_pub *drvr = bus_if->drvr;
1402
+
1403
+ bphy_err(drvr, "Firmware has halted or crashed\n");
1404
+
1405
+ brcmf_dev_coredump(dev);
1406
+
1407
+ schedule_work(&drvr->bus_reset);
1408
+}
1409
+
12221410 void brcmf_detach(struct device *dev)
12231411 {
12241412 s32 i;
....@@ -1238,32 +1426,41 @@
12381426 unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
12391427 #endif
12401428
1241
- /* stop firmware event handling */
1242
- brcmf_fweh_detach(drvr);
1243
- if (drvr->config)
1244
- brcmf_p2p_detach(&drvr->config->p2p);
1245
-
12461429 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1430
+ /* make sure primary interface removed last */
1431
+ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {
1432
+ if (drvr->iflist[i])
1433
+ brcmf_remove_interface(drvr->iflist[i], false);
1434
+ }
1435
+ brcmf_bus_stop(drvr->bus_if);
12471436
1248
- brcmf_proto_detach_pre_delif(drvr);
1437
+ brcmf_fweh_detach(drvr);
1438
+ brcmf_proto_detach(drvr);
12491439
12501440 if (drvr->mon_if) {
12511441 brcmf_net_detach(drvr->mon_if->ndev, false);
12521442 drvr->mon_if = NULL;
12531443 }
12541444
1255
- /* make sure primary interface removed last */
1256
- for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1257
- brcmf_remove_interface(drvr->iflist[i], false);
1445
+ if (drvr->config) {
1446
+ brcmf_p2p_detach(&drvr->config->p2p);
1447
+ brcmf_cfg80211_detach(drvr->config);
1448
+ drvr->config = NULL;
1449
+ }
1450
+}
12581451
1259
- brcmf_cfg80211_detach(drvr->config);
1260
- drvr->config = NULL;
1452
+void brcmf_free(struct device *dev)
1453
+{
1454
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1455
+ struct brcmf_pub *drvr = bus_if->drvr;
12611456
1262
- brcmf_bus_stop(drvr->bus_if);
1263
-
1264
- brcmf_proto_detach_post_delif(drvr);
1457
+ if (!drvr)
1458
+ return;
12651459
12661460 bus_if->drvr = NULL;
1461
+
1462
+ kfree(drvr->ops);
1463
+
12671464 wiphy_free(drvr->wiphy);
12681465 }
12691466
....@@ -1282,6 +1479,7 @@
12821479
12831480 int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
12841481 {
1482
+ struct brcmf_pub *drvr = ifp->drvr;
12851483 int err;
12861484
12871485 err = wait_event_timeout(ifp->pend_8021x_wait,
....@@ -1289,7 +1487,7 @@
12891487 MAX_WAIT_FOR_8021X_TX);
12901488
12911489 if (!err)
1292
- brcmf_err("Timed out waiting for no pending 802.1x packets\n");
1490
+ bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");
12931491
12941492 return !err;
12951493 }
....@@ -1321,40 +1519,34 @@
13211519 }
13221520 }
13231521
1324
-static void brcmf_driver_register(struct work_struct *work)
1325
-{
1326
-#ifdef CONFIG_BRCMFMAC_SDIO
1327
- brcmf_sdio_register();
1328
-#endif
1329
-#ifdef CONFIG_BRCMFMAC_USB
1330
- brcmf_usb_register();
1331
-#endif
1332
-#ifdef CONFIG_BRCMFMAC_PCIE
1333
- brcmf_pcie_register();
1334
-#endif
1335
-}
1336
-static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
1337
-
13381522 int __init brcmf_core_init(void)
13391523 {
1340
- if (!schedule_work(&brcmf_driver_work))
1341
- return -EBUSY;
1524
+ int err;
13421525
1526
+ err = brcmf_sdio_register();
1527
+ if (err)
1528
+ return err;
1529
+
1530
+ err = brcmf_usb_register();
1531
+ if (err)
1532
+ goto error_usb_register;
1533
+
1534
+ err = brcmf_pcie_register();
1535
+ if (err)
1536
+ goto error_pcie_register;
13431537 return 0;
1538
+
1539
+error_pcie_register:
1540
+ brcmf_usb_exit();
1541
+error_usb_register:
1542
+ brcmf_sdio_exit();
1543
+ return err;
13441544 }
13451545
13461546 void __exit brcmf_core_exit(void)
13471547 {
1348
- cancel_work_sync(&brcmf_driver_work);
1349
-
1350
-#ifdef CONFIG_BRCMFMAC_SDIO
13511548 brcmf_sdio_exit();
1352
-#endif
1353
-#ifdef CONFIG_BRCMFMAC_USB
13541549 brcmf_usb_exit();
1355
-#endif
1356
-#ifdef CONFIG_BRCMFMAC_PCIE
13571550 brcmf_pcie_exit();
1358
-#endif
13591551 }
13601552