hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
....@@ -1,16 +1,6 @@
1
-/* Copyright (c) 2014 Broadcom Corporation
2
- *
3
- * Permission to use, copy, modify, and/or distribute this software for any
4
- * purpose with or without fee is hereby granted, provided that the above
5
- * copyright notice and this permission notice appear in all copies.
6
- *
7
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1
+// SPDX-License-Identifier: ISC
2
+/*
3
+ * Copyright (c) 2014 Broadcom Corporation
144 */
155
166 /*******************************************************************************
....@@ -64,6 +54,7 @@
6454 #define BRCMF_IOCTL_REQ_PKTID 0xFFFE
6555
6656 #define BRCMF_MSGBUF_MAX_PKT_SIZE 2048
57
+#define BRCMF_MSGBUF_MAX_CTL_PKT_SIZE 8192
6758 #define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32
6859 #define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8
6960 #define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8
....@@ -132,6 +123,22 @@
132123 struct msgbuf_completion_hdr {
133124 __le16 status;
134125 __le16 flow_ring_id;
126
+};
127
+
128
+/* Data struct for the MSGBUF_TYPE_GEN_STATUS */
129
+struct msgbuf_gen_status {
130
+ struct msgbuf_common_hdr msg;
131
+ struct msgbuf_completion_hdr compl_hdr;
132
+ __le16 write_idx;
133
+ __le32 rsvd0[3];
134
+};
135
+
136
+/* Data struct for the MSGBUF_TYPE_RING_STATUS */
137
+struct msgbuf_ring_status {
138
+ struct msgbuf_common_hdr msg;
139
+ struct msgbuf_completion_hdr compl_hdr;
140
+ __le16 write_idx;
141
+ __le16 rsvd0[5];
135142 };
136143
137144 struct msgbuf_rx_event {
....@@ -431,7 +438,7 @@
431438 brcmf_commonring_lock(commonring);
432439 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
433440 if (!ret_ptr) {
434
- brcmf_err("Failed to reserve space in commonring\n");
441
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
435442 brcmf_commonring_unlock(commonring);
436443 return -ENOMEM;
437444 }
....@@ -495,7 +502,7 @@
495502
496503 timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);
497504 if (!timeout) {
498
- brcmf_err("Timeout on response for query command\n");
505
+ bphy_err(drvr, "Timeout on response for query command\n");
499506 return -EIO;
500507 }
501508
....@@ -529,7 +536,8 @@
529536 return -ENODEV;
530537 }
531538
532
-static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
539
+static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb,
540
+ bool inirq)
533541 {
534542 }
535543
....@@ -572,6 +580,7 @@
572580 brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
573581 struct brcmf_msgbuf_work_item *work)
574582 {
583
+ struct brcmf_pub *drvr = msgbuf->drvr;
575584 struct msgbuf_tx_flowring_create_req *create;
576585 struct brcmf_commonring *commonring;
577586 void *ret_ptr;
....@@ -587,7 +596,7 @@
587596 &msgbuf->flowring_dma_handle[flowid],
588597 GFP_KERNEL);
589598 if (!dma_buf) {
590
- brcmf_err("dma_alloc_coherent failed\n");
599
+ bphy_err(drvr, "dma_alloc_coherent failed\n");
591600 brcmf_flowring_delete(msgbuf->flow, flowid);
592601 return BRCMF_FLOWRING_INVALID_ID;
593602 }
....@@ -600,7 +609,7 @@
600609 brcmf_commonring_lock(commonring);
601610 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
602611 if (!ret_ptr) {
603
- brcmf_err("Failed to reserve space in commonring\n");
612
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
604613 brcmf_commonring_unlock(commonring);
605614 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
606615 return BRCMF_FLOWRING_INVALID_ID;
....@@ -627,7 +636,7 @@
627636 err = brcmf_commonring_write_complete(commonring);
628637 brcmf_commonring_unlock(commonring);
629638 if (err) {
630
- brcmf_err("Failed to write commonring\n");
639
+ bphy_err(drvr, "Failed to write commonring\n");
631640 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
632641 return BRCMF_FLOWRING_INVALID_ID;
633642 }
....@@ -686,6 +695,7 @@
686695 static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
687696 {
688697 struct brcmf_flowring *flow = msgbuf->flow;
698
+ struct brcmf_pub *drvr = msgbuf->drvr;
689699 struct brcmf_commonring *commonring;
690700 void *ret_ptr;
691701 u32 count;
....@@ -705,8 +715,8 @@
705715 while (brcmf_flowring_qlen(flow, flowid)) {
706716 skb = brcmf_flowring_dequeue(flow, flowid);
707717 if (skb == NULL) {
708
- brcmf_err("No SKB, but qlen %d\n",
709
- brcmf_flowring_qlen(flow, flowid));
718
+ bphy_err(drvr, "No SKB, but qlen %d\n",
719
+ brcmf_flowring_qlen(flow, flowid));
710720 break;
711721 }
712722 skb_orphan(skb);
....@@ -714,7 +724,7 @@
714724 msgbuf->tx_pktids, skb, ETH_HLEN,
715725 &physaddr, &pktid)) {
716726 brcmf_flowring_reinsert(flow, flowid, skb);
717
- brcmf_err("No PKTID available !!\n");
727
+ bphy_err(drvr, "No PKTID available !!\n");
718728 break;
719729 }
720730 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
....@@ -729,7 +739,7 @@
729739 tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr;
730740
731741 tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST;
732
- tx_msghdr->msg.request_id = cpu_to_le32(pktid);
742
+ tx_msghdr->msg.request_id = cpu_to_le32(pktid + 1);
733743 tx_msghdr->msg.ifidx = brcmf_flowring_ifidx_get(flow, flowid);
734744 tx_msghdr->flags = BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3;
735745 tx_msghdr->flags |= (skb->priority & 0x07) <<
....@@ -866,7 +876,7 @@
866876 u16 flowid;
867877
868878 tx_status = (struct msgbuf_tx_status *)buf;
869
- idx = le32_to_cpu(tx_status->msg.request_id);
879
+ idx = le32_to_cpu(tx_status->msg.request_id) - 1;
870880 flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
871881 flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
872882 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
....@@ -885,6 +895,7 @@
885895
886896 static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
887897 {
898
+ struct brcmf_pub *drvr = msgbuf->drvr;
888899 struct brcmf_commonring *commonring;
889900 void *ret_ptr;
890901 struct sk_buff *skb;
....@@ -912,7 +923,7 @@
912923 skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
913924
914925 if (skb == NULL) {
915
- brcmf_err("Failed to alloc SKB\n");
926
+ bphy_err(drvr, "Failed to alloc SKB\n");
916927 brcmf_commonring_write_cancel(commonring, alloced - i);
917928 break;
918929 }
....@@ -922,7 +933,7 @@
922933 msgbuf->rx_pktids, skb, 0,
923934 &physaddr, &pktid)) {
924935 dev_kfree_skb_any(skb);
925
- brcmf_err("No PKTID available !!\n");
936
+ bphy_err(drvr, "No PKTID available !!\n");
926937 brcmf_commonring_write_cancel(commonring, alloced - i);
927938 break;
928939 }
....@@ -992,6 +1003,7 @@
9921003 brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
9931004 u32 count)
9941005 {
1006
+ struct brcmf_pub *drvr = msgbuf->drvr;
9951007 struct brcmf_commonring *commonring;
9961008 void *ret_ptr;
9971009 struct sk_buff *skb;
....@@ -1009,7 +1021,7 @@
10091021 count,
10101022 &alloced);
10111023 if (!ret_ptr) {
1012
- brcmf_err("Failed to reserve space in commonring\n");
1024
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
10131025 brcmf_commonring_unlock(commonring);
10141026 return 0;
10151027 }
....@@ -1018,10 +1030,10 @@
10181030 rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
10191031 memset(rx_bufpost, 0, sizeof(*rx_bufpost));
10201032
1021
- skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
1033
+ skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE);
10221034
10231035 if (skb == NULL) {
1024
- brcmf_err("Failed to alloc SKB\n");
1036
+ bphy_err(drvr, "Failed to alloc SKB\n");
10251037 brcmf_commonring_write_cancel(commonring, alloced - i);
10261038 break;
10271039 }
....@@ -1031,7 +1043,7 @@
10311043 msgbuf->rx_pktids, skb, 0,
10321044 &physaddr, &pktid)) {
10331045 dev_kfree_skb_any(skb);
1034
- brcmf_err("No PKTID available !!\n");
1046
+ bphy_err(drvr, "No PKTID available !!\n");
10351047 brcmf_commonring_write_cancel(commonring, alloced - i);
10361048 break;
10371049 }
....@@ -1083,6 +1095,7 @@
10831095
10841096 static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
10851097 {
1098
+ struct brcmf_pub *drvr = msgbuf->drvr;
10861099 struct msgbuf_rx_event *event;
10871100 u32 idx;
10881101 u16 buflen;
....@@ -1109,14 +1122,14 @@
11091122
11101123 ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
11111124 if (!ifp || !ifp->ndev) {
1112
- brcmf_err("Received pkt for invalid ifidx %d\n",
1113
- event->msg.ifidx);
1125
+ bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1126
+ event->msg.ifidx);
11141127 goto exit;
11151128 }
11161129
11171130 skb->protocol = eth_type_trans(skb, ifp->ndev);
11181131
1119
- brcmf_fweh_process_skb(ifp->drvr, skb, 0);
1132
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
11201133
11211134 exit:
11221135 brcmu_pkt_buf_free_skb(skb);
....@@ -1126,6 +1139,7 @@
11261139 static void
11271140 brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
11281141 {
1142
+ struct brcmf_pub *drvr = msgbuf->drvr;
11291143 struct msgbuf_rx_complete *rx_complete;
11301144 struct sk_buff *skb;
11311145 u16 data_offset;
....@@ -1159,7 +1173,7 @@
11591173 ifp = msgbuf->drvr->mon_if;
11601174
11611175 if (!ifp) {
1162
- brcmf_err("Received unexpected monitor pkt\n");
1176
+ bphy_err(drvr, "Received unexpected monitor pkt\n");
11631177 brcmu_pkt_buf_free_skb(skb);
11641178 return;
11651179 }
....@@ -1170,21 +1184,49 @@
11701184
11711185 ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
11721186 if (!ifp || !ifp->ndev) {
1173
- brcmf_err("Received pkt for invalid ifidx %d\n",
1174
- rx_complete->msg.ifidx);
1187
+ bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1188
+ rx_complete->msg.ifidx);
11751189 brcmu_pkt_buf_free_skb(skb);
11761190 return;
11771191 }
11781192
11791193 skb->protocol = eth_type_trans(skb, ifp->ndev);
1180
- brcmf_netif_rx(ifp, skb);
1194
+ brcmf_netif_rx(ifp, skb, false);
11811195 }
11821196
1197
+static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf,
1198
+ void *buf)
1199
+{
1200
+ struct msgbuf_gen_status *gen_status = buf;
1201
+ struct brcmf_pub *drvr = msgbuf->drvr;
1202
+ int err;
1203
+
1204
+ err = le16_to_cpu(gen_status->compl_hdr.status);
1205
+ if (err)
1206
+ bphy_err(drvr, "Firmware reported general error: %d\n", err);
1207
+}
1208
+
1209
+static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf,
1210
+ void *buf)
1211
+{
1212
+ struct msgbuf_ring_status *ring_status = buf;
1213
+ struct brcmf_pub *drvr = msgbuf->drvr;
1214
+ int err;
1215
+
1216
+ err = le16_to_cpu(ring_status->compl_hdr.status);
1217
+ if (err) {
1218
+ int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id);
1219
+
1220
+ bphy_err(drvr, "Firmware reported ring %d error: %d\n", ring,
1221
+ err);
1222
+ }
1223
+}
11831224
11841225 static void
11851226 brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
11861227 void *buf)
11871228 {
1229
+ struct brcmf_pub *drvr = msgbuf->drvr;
11881230 struct msgbuf_flowring_create_resp *flowring_create_resp;
11891231 u16 status;
11901232 u16 flowid;
....@@ -1196,7 +1238,7 @@
11961238 status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
11971239
11981240 if (status) {
1199
- brcmf_err("Flowring creation failed, code %d\n", status);
1241
+ bphy_err(drvr, "Flowring creation failed, code %d\n", status);
12001242 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
12011243 return;
12021244 }
....@@ -1213,6 +1255,7 @@
12131255 brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
12141256 void *buf)
12151257 {
1258
+ struct brcmf_pub *drvr = msgbuf->drvr;
12161259 struct msgbuf_flowring_delete_resp *flowring_delete_resp;
12171260 u16 status;
12181261 u16 flowid;
....@@ -1224,7 +1267,7 @@
12241267 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
12251268
12261269 if (status) {
1227
- brcmf_err("Flowring deletion failed, code %d\n", status);
1270
+ bphy_err(drvr, "Flowring deletion failed, code %d\n", status);
12281271 brcmf_flowring_delete(msgbuf->flow, flowid);
12291272 return;
12301273 }
....@@ -1237,10 +1280,19 @@
12371280
12381281 static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
12391282 {
1283
+ struct brcmf_pub *drvr = msgbuf->drvr;
12401284 struct msgbuf_common_hdr *msg;
12411285
12421286 msg = (struct msgbuf_common_hdr *)buf;
12431287 switch (msg->msgtype) {
1288
+ case MSGBUF_TYPE_GEN_STATUS:
1289
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_GEN_STATUS\n");
1290
+ brcmf_msgbuf_process_gen_status(msgbuf, buf);
1291
+ break;
1292
+ case MSGBUF_TYPE_RING_STATUS:
1293
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n");
1294
+ brcmf_msgbuf_process_ring_status(msgbuf, buf);
1295
+ break;
12441296 case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
12451297 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n");
12461298 brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);
....@@ -1269,7 +1321,7 @@
12691321 brcmf_msgbuf_process_rx_complete(msgbuf, buf);
12701322 break;
12711323 default:
1272
- brcmf_err("Unsupported msgtype %d\n", msg->msgtype);
1324
+ bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype);
12731325 break;
12741326 }
12751327 }
....@@ -1348,11 +1400,18 @@
13481400 u8 ifidx;
13491401 int err;
13501402
1403
+ /* no need to submit if firmware can not be reached */
1404
+ if (drvr->bus_if->state != BRCMF_BUS_UP) {
1405
+ brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n");
1406
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1407
+ return;
1408
+ }
1409
+
13511410 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
13521411 brcmf_commonring_lock(commonring);
13531412 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
13541413 if (!ret_ptr) {
1355
- brcmf_err("FW unaware, flowring will be removed !!\n");
1414
+ bphy_err(drvr, "FW unaware, flowring will be removed !!\n");
13561415 brcmf_commonring_unlock(commonring);
13571416 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
13581417 return;
....@@ -1376,7 +1435,7 @@
13761435 err = brcmf_commonring_write_complete(commonring);
13771436 brcmf_commonring_unlock(commonring);
13781437 if (err) {
1379
- brcmf_err("Failed to submit RING_DELETE, flowring will be removed\n");
1438
+ bphy_err(drvr, "Failed to submit RING_DELETE, flowring will be removed\n");
13801439 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
13811440 }
13821441 }
....@@ -1411,7 +1470,6 @@
14111470 seq_printf(seq, "\nh2d_flowrings: depth %u\n",
14121471 BRCMF_H2D_TXFLOWRING_MAX_ITEM);
14131472 seq_puts(seq, "Active flowrings:\n");
1414
- hash = msgbuf->flow->hash;
14151473 for (i = 0; i < msgbuf->flow->nrofrings; i++) {
14161474 if (!msgbuf->flow->rings[i])
14171475 continue;
....@@ -1451,8 +1509,8 @@
14511509 if_msgbuf = drvr->bus_if->msgbuf;
14521510
14531511 if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
1454
- brcmf_err("driver not configured for this many flowrings %d\n",
1455
- if_msgbuf->max_flowrings);
1512
+ bphy_err(drvr, "driver not configured for this many flowrings %d\n",
1513
+ if_msgbuf->max_flowrings);
14561514 if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
14571515 }
14581516
....@@ -1462,7 +1520,7 @@
14621520
14631521 msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow");
14641522 if (msgbuf->txflow_wq == NULL) {
1465
- brcmf_err("workqueue creation failed\n");
1523
+ bphy_err(drvr, "workqueue creation failed\n");
14661524 goto fail;
14671525 }
14681526 INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);