hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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,9 +330,10 @@
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);
336
+ dev_kfree_skb(skb);
315337 goto done;
316338 }
317339 }
....@@ -332,6 +354,9 @@
332354 if ((skb->priority == 0) || (skb->priority > 7))
333355 skb->priority = cfg80211_classify8021d(skb, NULL);
334356
357
+ /* set pacing shift for packet aggregation */
358
+ sk_pacing_shift_update(skb->sk, 8);
359
+
335360 ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
336361 if (ret < 0)
337362 brcmf_txfinalize(ifp, skb, false);
....@@ -341,7 +366,7 @@
341366 ndev->stats.tx_dropped++;
342367 } else {
343368 ndev->stats.tx_packets++;
344
- ndev->stats.tx_bytes += skb->len;
369
+ ndev->stats.tx_bytes += tx_bytes;
345370 }
346371
347372 /* Return ok: we always eat the packet */
....@@ -372,7 +397,7 @@
372397 spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
373398 }
374399
375
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
400
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq)
376401 {
377402 /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
378403 * STA connects to the AP interface. This is an obsoleted standard most
....@@ -395,20 +420,46 @@
395420 ifp->ndev->stats.rx_packets++;
396421
397422 brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol));
398
- if (in_interrupt())
423
+ if (inirq) {
399424 netif_rx(skb);
400
- else
425
+ } else {
401426 /* If the receive is not processed inside an ISR,
402427 * the softirqd must be woken explicitly to service
403428 * the NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
404429 */
405430 netif_rx_ni(skb);
431
+ }
406432 }
407433
408434 void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
409435 {
410436 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
411437 /* Do nothing */
438
+ } else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {
439
+ struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data;
440
+ struct ieee80211_radiotap_header *radiotap;
441
+ unsigned int offset;
442
+ u16 RxStatus1;
443
+
444
+ RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);
445
+
446
+ offset = sizeof(struct wlc_d11rxhdr);
447
+ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU
448
+ * subframes
449
+ */
450
+ if (RxStatus1 & RXS_PBPRES)
451
+ offset += 2;
452
+ offset += D11_PHY_HDR_LEN;
453
+
454
+ skb_pull(skb, offset);
455
+
456
+ /* TODO: use RX header to fill some radiotap data */
457
+ radiotap = skb_push(skb, sizeof(*radiotap));
458
+ memset(radiotap, 0, sizeof(*radiotap));
459
+ radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
460
+
461
+ /* TODO: 4 bytes with receive status? */
462
+ skb->len -= 4;
412463 } else {
413464 struct ieee80211_radiotap_header *radiotap;
414465
....@@ -426,7 +477,7 @@
426477 skb->pkt_type = PACKET_OTHERHOST;
427478 skb->protocol = htons(ETH_P_802_2);
428479
429
- brcmf_netif_rx(ifp, skb);
480
+ brcmf_netif_rx(ifp, skb, false);
430481 }
431482
432483 static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
....@@ -448,7 +499,8 @@
448499 return 0;
449500 }
450501
451
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
502
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,
503
+ bool inirq)
452504 {
453505 struct brcmf_if *ifp;
454506 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
....@@ -460,14 +512,16 @@
460512 return;
461513
462514 if (brcmf_proto_is_reorder_skb(skb)) {
463
- brcmf_proto_rxreorder(ifp, skb);
515
+ brcmf_proto_rxreorder(ifp, skb, inirq);
464516 } else {
465517 /* Process special event packets */
466
- if (handle_event)
467
- brcmf_fweh_process_skb(ifp->drvr, skb,
468
- BCMILCP_SUBTYPE_VENDOR_LONG);
518
+ if (handle_event) {
519
+ gfp_t gfp = inirq ? GFP_ATOMIC : GFP_KERNEL;
469520
470
- brcmf_netif_rx(ifp, skb);
521
+ brcmf_fweh_process_skb(ifp->drvr, skb,
522
+ BCMILCP_SUBTYPE_VENDOR_LONG, gfp);
523
+ }
524
+ brcmf_netif_rx(ifp, skb, inirq);
471525 }
472526 }
473527
....@@ -482,7 +536,7 @@
482536 if (brcmf_rx_hdrpull(drvr, skb, &ifp))
483537 return;
484538
485
- brcmf_fweh_process_skb(ifp->drvr, skb, 0);
539
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
486540 brcmu_pkt_buf_free_skb(skb);
487541 }
488542
....@@ -534,8 +588,6 @@
534588
535589 brcmf_cfg80211_down(ndev);
536590
537
- brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0);
538
-
539591 brcmf_net_setcarrier(ifp, false);
540592
541593 return 0;
....@@ -552,7 +604,7 @@
552604
553605 /* If bus is not ready, can't continue */
554606 if (bus_if->state != BRCMF_BUS_UP) {
555
- brcmf_err("failed bus is not ready\n");
607
+ bphy_err(drvr, "failed bus is not ready\n");
556608 return -EAGAIN;
557609 }
558610
....@@ -566,7 +618,7 @@
566618 ndev->features &= ~NETIF_F_IP_CSUM;
567619
568620 if (brcmf_cfg80211_up(ndev)) {
569
- brcmf_err("failed to bring up cfg80211\n");
621
+ bphy_err(drvr, "failed to bring up cfg80211\n");
570622 return -EIO;
571623 }
572624
....@@ -611,9 +663,11 @@
611663 else
612664 err = register_netdev(ndev);
613665 if (err != 0) {
614
- brcmf_err("couldn't register the net device\n");
666
+ bphy_err(drvr, "couldn't register the net device\n");
615667 goto fail;
616668 }
669
+
670
+ netif_carrier_off(ndev);
617671
618672 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
619673 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
....@@ -625,7 +679,7 @@
625679 return -EBADE;
626680 }
627681
628
-static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
682
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
629683 {
630684 if (ndev->reg_state == NETREG_REGISTERED) {
631685 if (rtnl_locked)
....@@ -636,6 +690,81 @@
636690 brcmf_cfg80211_free_netdev(ndev);
637691 free_netdev(ndev);
638692 }
693
+}
694
+
695
+static int brcmf_net_mon_open(struct net_device *ndev)
696
+{
697
+ struct brcmf_if *ifp = netdev_priv(ndev);
698
+ struct brcmf_pub *drvr = ifp->drvr;
699
+ u32 monitor;
700
+ int err;
701
+
702
+ brcmf_dbg(TRACE, "Enter\n");
703
+
704
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);
705
+ if (err) {
706
+ bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);
707
+ return err;
708
+ } else if (monitor) {
709
+ bphy_err(drvr, "Monitor mode is already enabled\n");
710
+ return -EEXIST;
711
+ }
712
+
713
+ monitor = 3;
714
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
715
+ if (err)
716
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
717
+
718
+ return err;
719
+}
720
+
721
+static int brcmf_net_mon_stop(struct net_device *ndev)
722
+{
723
+ struct brcmf_if *ifp = netdev_priv(ndev);
724
+ struct brcmf_pub *drvr = ifp->drvr;
725
+ u32 monitor;
726
+ int err;
727
+
728
+ brcmf_dbg(TRACE, "Enter\n");
729
+
730
+ monitor = 0;
731
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
732
+ if (err)
733
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
734
+
735
+ return err;
736
+}
737
+
738
+static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb,
739
+ struct net_device *ndev)
740
+{
741
+ dev_kfree_skb_any(skb);
742
+
743
+ return NETDEV_TX_OK;
744
+}
745
+
746
+static const struct net_device_ops brcmf_netdev_ops_mon = {
747
+ .ndo_open = brcmf_net_mon_open,
748
+ .ndo_stop = brcmf_net_mon_stop,
749
+ .ndo_start_xmit = brcmf_net_mon_start_xmit,
750
+};
751
+
752
+int brcmf_net_mon_attach(struct brcmf_if *ifp)
753
+{
754
+ struct brcmf_pub *drvr = ifp->drvr;
755
+ struct net_device *ndev;
756
+ int err;
757
+
758
+ brcmf_dbg(TRACE, "Enter\n");
759
+
760
+ ndev = ifp->ndev;
761
+ ndev->netdev_ops = &brcmf_netdev_ops_mon;
762
+
763
+ err = register_netdevice(ndev);
764
+ if (err)
765
+ bphy_err(drvr, "Failed to register %s device\n", ndev->name);
766
+
767
+ return err;
639768 }
640769
641770 void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
....@@ -688,6 +817,7 @@
688817
689818 static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
690819 {
820
+ struct brcmf_pub *drvr = ifp->drvr;
691821 struct net_device *ndev;
692822
693823 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
....@@ -700,7 +830,7 @@
700830 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
701831
702832 if (register_netdev(ndev) != 0) {
703
- brcmf_err("couldn't register the p2p net device\n");
833
+ bphy_err(drvr, "couldn't register the p2p net device\n");
704834 goto fail;
705835 }
706836
....@@ -729,8 +859,8 @@
729859 */
730860 if (ifp) {
731861 if (ifidx) {
732
- brcmf_err("ERROR: netdev:%s already exists\n",
733
- ifp->ndev->name);
862
+ bphy_err(drvr, "ERROR: netdev:%s already exists\n",
863
+ ifp->ndev->name);
734864 netif_stop_queue(ifp->ndev);
735865 brcmf_net_detach(ifp->ndev, false);
736866 drvr->iflist[bsscfgidx] = NULL;
....@@ -788,7 +918,7 @@
788918
789919 ifp = drvr->iflist[bsscfgidx];
790920 if (!ifp) {
791
- brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx);
921
+ bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx);
792922 return;
793923 }
794924 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,
....@@ -842,16 +972,17 @@
842972 const struct brcmf_event_msg *evtmsg,
843973 void *data)
844974 {
975
+ struct brcmf_pub *drvr = ifp->drvr;
845976 int err;
846977
847978 brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
848979
849
- brcmf_err("PSM's watchdog has fired!\n");
980
+ bphy_err(drvr, "PSM's watchdog has fired!\n");
850981
851982 err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
852983 evtmsg->datalen);
853984 if (err)
854
- brcmf_err("Failed to get memory dump, %d\n", err);
985
+ bphy_err(drvr, "Failed to get memory dump, %d\n", err);
855986
856987 return err;
857988 }
....@@ -895,7 +1026,7 @@
8951026 ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table,
8961027 sizeof(addr_table));
8971028 if (ret) {
898
- brcmf_err("fail to get arp ip table err:%d\n", ret);
1029
+ bphy_err(drvr, "fail to get arp ip table err:%d\n", ret);
8991030 return NOTIFY_OK;
9001031 }
9011032
....@@ -912,7 +1043,7 @@
9121043 ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
9131044 &ifa->ifa_address, sizeof(ifa->ifa_address));
9141045 if (ret)
915
- brcmf_err("add arp ip err %d\n", ret);
1046
+ bphy_err(drvr, "add arp ip err %d\n", ret);
9161047 }
9171048 break;
9181049 case NETDEV_DOWN:
....@@ -924,8 +1055,8 @@
9241055 ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear",
9251056 NULL, 0);
9261057 if (ret) {
927
- brcmf_err("fail to clear arp ip table err:%d\n",
928
- ret);
1058
+ bphy_err(drvr, "fail to clear arp ip table err:%d\n",
1059
+ ret);
9291060 return NOTIFY_OK;
9301061 }
9311062 for (i = 0; i < ARPOL_MAX_ENTRIES; i++) {
....@@ -935,8 +1066,8 @@
9351066 &addr_table[i],
9361067 sizeof(addr_table[i]));
9371068 if (ret)
938
- brcmf_err("add arp ip err %d\n",
939
- ret);
1069
+ bphy_err(drvr, "add arp ip err %d\n",
1070
+ ret);
9401071 }
9411072 }
9421073 break;
....@@ -1030,6 +1161,37 @@
10301161 return 0;
10311162 }
10321163
1164
+static void brcmf_core_bus_reset(struct work_struct *work)
1165
+{
1166
+ struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
1167
+ bus_reset);
1168
+
1169
+ brcmf_bus_reset(drvr->bus_if);
1170
+}
1171
+
1172
+static ssize_t bus_reset_write(struct file *file, const char __user *user_buf,
1173
+ size_t count, loff_t *ppos)
1174
+{
1175
+ struct brcmf_pub *drvr = file->private_data;
1176
+ u8 value;
1177
+
1178
+ if (kstrtou8_from_user(user_buf, count, 0, &value))
1179
+ return -EINVAL;
1180
+
1181
+ if (value != 1)
1182
+ return -EINVAL;
1183
+
1184
+ schedule_work(&drvr->bus_reset);
1185
+
1186
+ return count;
1187
+}
1188
+
1189
+static const struct file_operations bus_reset_fops = {
1190
+ .open = simple_open,
1191
+ .llseek = no_llseek,
1192
+ .write = bus_reset_write,
1193
+};
1194
+
10331195 static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
10341196 {
10351197 int ret = -1;
....@@ -1101,8 +1263,12 @@
11011263 #endif
11021264 #endif /* CONFIG_INET */
11031265
1266
+ INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset);
1267
+
11041268 /* populate debugfs */
11051269 brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1270
+ debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr,
1271
+ &bus_reset_fops);
11061272 brcmf_feat_debugfs_create(drvr);
11071273 brcmf_proto_debugfs_create(drvr);
11081274 brcmf_bus_debugfs_create(bus_if);
....@@ -1110,7 +1276,7 @@
11101276 return 0;
11111277
11121278 fail:
1113
- brcmf_err("failed: %d\n", ret);
1279
+ bphy_err(drvr, "failed: %d\n", ret);
11141280 if (drvr->config) {
11151281 brcmf_cfg80211_detach(drvr->config);
11161282 drvr->config = NULL;
....@@ -1126,13 +1292,11 @@
11261292 return ret;
11271293 }
11281294
1129
-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
1295
+int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)
11301296 {
11311297 struct wiphy *wiphy;
11321298 struct cfg80211_ops *ops;
11331299 struct brcmf_pub *drvr = NULL;
1134
- int ret = 0;
1135
- int i;
11361300
11371301 brcmf_dbg(TRACE, "Enter\n");
11381302
....@@ -1141,12 +1305,30 @@
11411305 return -ENOMEM;
11421306
11431307 wiphy = wiphy_new(ops, sizeof(*drvr));
1144
- if (!wiphy)
1308
+ if (!wiphy) {
1309
+ kfree(ops);
11451310 return -ENOMEM;
1311
+ }
11461312
11471313 set_wiphy_dev(wiphy, dev);
11481314 drvr = wiphy_priv(wiphy);
11491315 drvr->wiphy = wiphy;
1316
+ drvr->ops = ops;
1317
+ drvr->bus_if = dev_get_drvdata(dev);
1318
+ drvr->bus_if->drvr = drvr;
1319
+ drvr->settings = settings;
1320
+
1321
+ return 0;
1322
+}
1323
+
1324
+int brcmf_attach(struct device *dev)
1325
+{
1326
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1327
+ struct brcmf_pub *drvr = bus_if->drvr;
1328
+ int ret = 0;
1329
+ int i;
1330
+
1331
+ brcmf_dbg(TRACE, "Enter\n");
11501332
11511333 for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
11521334 drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
....@@ -1155,14 +1337,11 @@
11551337
11561338 /* Link to bus module */
11571339 drvr->hdrlen = 0;
1158
- drvr->bus_if = dev_get_drvdata(dev);
1159
- drvr->bus_if->drvr = drvr;
1160
- drvr->settings = settings;
11611340
11621341 /* Attach and link in the protocol */
11631342 ret = brcmf_proto_attach(drvr);
11641343 if (ret != 0) {
1165
- brcmf_err("brcmf_prot_attach failed\n");
1344
+ bphy_err(drvr, "brcmf_prot_attach failed\n");
11661345 goto fail;
11671346 }
11681347
....@@ -1173,18 +1352,16 @@
11731352 /* attach firmware event handler */
11741353 brcmf_fweh_attach(drvr);
11751354
1176
- ret = brcmf_bus_started(drvr, ops);
1355
+ ret = brcmf_bus_started(drvr, drvr->ops);
11771356 if (ret != 0) {
1178
- brcmf_err("dongle is not responding: err=%d\n", ret);
1357
+ bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
11791358 goto fail;
11801359 }
11811360
1182
- drvr->config->ops = ops;
11831361 return 0;
11841362
11851363 fail:
11861364 brcmf_detach(dev);
1187
- kfree(ops);
11881365
11891366 return ret;
11901367 }
....@@ -1219,6 +1396,18 @@
12191396 brcmf_dbg(TRACE, "failed to create coredump\n");
12201397 }
12211398
1399
+void brcmf_fw_crashed(struct device *dev)
1400
+{
1401
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1402
+ struct brcmf_pub *drvr = bus_if->drvr;
1403
+
1404
+ bphy_err(drvr, "Firmware has halted or crashed\n");
1405
+
1406
+ brcmf_dev_coredump(dev);
1407
+
1408
+ schedule_work(&drvr->bus_reset);
1409
+}
1410
+
12221411 void brcmf_detach(struct device *dev)
12231412 {
12241413 s32 i;
....@@ -1238,32 +1427,41 @@
12381427 unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
12391428 #endif
12401429
1241
- /* stop firmware event handling */
1242
- brcmf_fweh_detach(drvr);
1243
- if (drvr->config)
1244
- brcmf_p2p_detach(&drvr->config->p2p);
1245
-
12461430 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1431
+ /* make sure primary interface removed last */
1432
+ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {
1433
+ if (drvr->iflist[i])
1434
+ brcmf_remove_interface(drvr->iflist[i], false);
1435
+ }
1436
+ brcmf_bus_stop(drvr->bus_if);
12471437
1248
- brcmf_proto_detach_pre_delif(drvr);
1438
+ brcmf_fweh_detach(drvr);
1439
+ brcmf_proto_detach(drvr);
12491440
12501441 if (drvr->mon_if) {
12511442 brcmf_net_detach(drvr->mon_if->ndev, false);
12521443 drvr->mon_if = NULL;
12531444 }
12541445
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);
1446
+ if (drvr->config) {
1447
+ brcmf_p2p_detach(&drvr->config->p2p);
1448
+ brcmf_cfg80211_detach(drvr->config);
1449
+ drvr->config = NULL;
1450
+ }
1451
+}
12581452
1259
- brcmf_cfg80211_detach(drvr->config);
1260
- drvr->config = NULL;
1453
+void brcmf_free(struct device *dev)
1454
+{
1455
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1456
+ struct brcmf_pub *drvr = bus_if->drvr;
12611457
1262
- brcmf_bus_stop(drvr->bus_if);
1263
-
1264
- brcmf_proto_detach_post_delif(drvr);
1458
+ if (!drvr)
1459
+ return;
12651460
12661461 bus_if->drvr = NULL;
1462
+
1463
+ kfree(drvr->ops);
1464
+
12671465 wiphy_free(drvr->wiphy);
12681466 }
12691467
....@@ -1282,6 +1480,7 @@
12821480
12831481 int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
12841482 {
1483
+ struct brcmf_pub *drvr = ifp->drvr;
12851484 int err;
12861485
12871486 err = wait_event_timeout(ifp->pend_8021x_wait,
....@@ -1289,7 +1488,7 @@
12891488 MAX_WAIT_FOR_8021X_TX);
12901489
12911490 if (!err)
1292
- brcmf_err("Timed out waiting for no pending 802.1x packets\n");
1491
+ bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");
12931492
12941493 return !err;
12951494 }
....@@ -1321,40 +1520,34 @@
13211520 }
13221521 }
13231522
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
-
13381523 int __init brcmf_core_init(void)
13391524 {
1340
- if (!schedule_work(&brcmf_driver_work))
1341
- return -EBUSY;
1525
+ int err;
13421526
1527
+ err = brcmf_sdio_register();
1528
+ if (err)
1529
+ return err;
1530
+
1531
+ err = brcmf_usb_register();
1532
+ if (err)
1533
+ goto error_usb_register;
1534
+
1535
+ err = brcmf_pcie_register();
1536
+ if (err)
1537
+ goto error_pcie_register;
13431538 return 0;
1539
+
1540
+error_pcie_register:
1541
+ brcmf_usb_exit();
1542
+error_usb_register:
1543
+ brcmf_sdio_exit();
1544
+ return err;
13441545 }
13451546
13461547 void __exit brcmf_core_exit(void)
13471548 {
1348
- cancel_work_sync(&brcmf_driver_work);
1349
-
1350
-#ifdef CONFIG_BRCMFMAC_SDIO
13511549 brcmf_sdio_exit();
1352
-#endif
1353
-#ifdef CONFIG_BRCMFMAC_USB
13541550 brcmf_usb_exit();
1355
-#endif
1356
-#ifdef CONFIG_BRCMFMAC_PCIE
13571551 brcmf_pcie_exit();
1358
-#endif
13591552 }
13601553