hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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 {
....@@ -339,8 +346,11 @@
339346 count++;
340347 } while (count < pktids->array_size);
341348
342
- if (count == pktids->array_size)
349
+ if (count == pktids->array_size) {
350
+ dma_unmap_single(dev, *physaddr, skb->len - data_offset,
351
+ pktids->direction);
343352 return -ENOMEM;
353
+ }
344354
345355 array[*idx].data_offset = data_offset;
346356 array[*idx].physaddr = *physaddr;
....@@ -431,7 +441,7 @@
431441 brcmf_commonring_lock(commonring);
432442 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
433443 if (!ret_ptr) {
434
- brcmf_err("Failed to reserve space in commonring\n");
444
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
435445 brcmf_commonring_unlock(commonring);
436446 return -ENOMEM;
437447 }
....@@ -495,7 +505,7 @@
495505
496506 timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);
497507 if (!timeout) {
498
- brcmf_err("Timeout on response for query command\n");
508
+ bphy_err(drvr, "Timeout on response for query command\n");
499509 return -EIO;
500510 }
501511
....@@ -529,7 +539,8 @@
529539 return -ENODEV;
530540 }
531541
532
-static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
542
+static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb,
543
+ bool inirq)
533544 {
534545 }
535546
....@@ -572,6 +583,7 @@
572583 brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
573584 struct brcmf_msgbuf_work_item *work)
574585 {
586
+ struct brcmf_pub *drvr = msgbuf->drvr;
575587 struct msgbuf_tx_flowring_create_req *create;
576588 struct brcmf_commonring *commonring;
577589 void *ret_ptr;
....@@ -587,7 +599,7 @@
587599 &msgbuf->flowring_dma_handle[flowid],
588600 GFP_KERNEL);
589601 if (!dma_buf) {
590
- brcmf_err("dma_alloc_coherent failed\n");
602
+ bphy_err(drvr, "dma_alloc_coherent failed\n");
591603 brcmf_flowring_delete(msgbuf->flow, flowid);
592604 return BRCMF_FLOWRING_INVALID_ID;
593605 }
....@@ -600,7 +612,7 @@
600612 brcmf_commonring_lock(commonring);
601613 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
602614 if (!ret_ptr) {
603
- brcmf_err("Failed to reserve space in commonring\n");
615
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
604616 brcmf_commonring_unlock(commonring);
605617 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
606618 return BRCMF_FLOWRING_INVALID_ID;
....@@ -627,7 +639,7 @@
627639 err = brcmf_commonring_write_complete(commonring);
628640 brcmf_commonring_unlock(commonring);
629641 if (err) {
630
- brcmf_err("Failed to write commonring\n");
642
+ bphy_err(drvr, "Failed to write commonring\n");
631643 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
632644 return BRCMF_FLOWRING_INVALID_ID;
633645 }
....@@ -686,6 +698,7 @@
686698 static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
687699 {
688700 struct brcmf_flowring *flow = msgbuf->flow;
701
+ struct brcmf_pub *drvr = msgbuf->drvr;
689702 struct brcmf_commonring *commonring;
690703 void *ret_ptr;
691704 u32 count;
....@@ -705,8 +718,8 @@
705718 while (brcmf_flowring_qlen(flow, flowid)) {
706719 skb = brcmf_flowring_dequeue(flow, flowid);
707720 if (skb == NULL) {
708
- brcmf_err("No SKB, but qlen %d\n",
709
- brcmf_flowring_qlen(flow, flowid));
721
+ bphy_err(drvr, "No SKB, but qlen %d\n",
722
+ brcmf_flowring_qlen(flow, flowid));
710723 break;
711724 }
712725 skb_orphan(skb);
....@@ -714,7 +727,7 @@
714727 msgbuf->tx_pktids, skb, ETH_HLEN,
715728 &physaddr, &pktid)) {
716729 brcmf_flowring_reinsert(flow, flowid, skb);
717
- brcmf_err("No PKTID available !!\n");
730
+ bphy_err(drvr, "No PKTID available !!\n");
718731 break;
719732 }
720733 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
....@@ -729,7 +742,7 @@
729742 tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr;
730743
731744 tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST;
732
- tx_msghdr->msg.request_id = cpu_to_le32(pktid);
745
+ tx_msghdr->msg.request_id = cpu_to_le32(pktid + 1);
733746 tx_msghdr->msg.ifidx = brcmf_flowring_ifidx_get(flow, flowid);
734747 tx_msghdr->flags = BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3;
735748 tx_msghdr->flags |= (skb->priority & 0x07) <<
....@@ -866,7 +879,7 @@
866879 u16 flowid;
867880
868881 tx_status = (struct msgbuf_tx_status *)buf;
869
- idx = le32_to_cpu(tx_status->msg.request_id);
882
+ idx = le32_to_cpu(tx_status->msg.request_id) - 1;
870883 flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
871884 flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
872885 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
....@@ -885,6 +898,7 @@
885898
886899 static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
887900 {
901
+ struct brcmf_pub *drvr = msgbuf->drvr;
888902 struct brcmf_commonring *commonring;
889903 void *ret_ptr;
890904 struct sk_buff *skb;
....@@ -912,7 +926,7 @@
912926 skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
913927
914928 if (skb == NULL) {
915
- brcmf_err("Failed to alloc SKB\n");
929
+ bphy_err(drvr, "Failed to alloc SKB\n");
916930 brcmf_commonring_write_cancel(commonring, alloced - i);
917931 break;
918932 }
....@@ -922,7 +936,7 @@
922936 msgbuf->rx_pktids, skb, 0,
923937 &physaddr, &pktid)) {
924938 dev_kfree_skb_any(skb);
925
- brcmf_err("No PKTID available !!\n");
939
+ bphy_err(drvr, "No PKTID available !!\n");
926940 brcmf_commonring_write_cancel(commonring, alloced - i);
927941 break;
928942 }
....@@ -992,6 +1006,7 @@
9921006 brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
9931007 u32 count)
9941008 {
1009
+ struct brcmf_pub *drvr = msgbuf->drvr;
9951010 struct brcmf_commonring *commonring;
9961011 void *ret_ptr;
9971012 struct sk_buff *skb;
....@@ -1009,7 +1024,7 @@
10091024 count,
10101025 &alloced);
10111026 if (!ret_ptr) {
1012
- brcmf_err("Failed to reserve space in commonring\n");
1027
+ bphy_err(drvr, "Failed to reserve space in commonring\n");
10131028 brcmf_commonring_unlock(commonring);
10141029 return 0;
10151030 }
....@@ -1018,10 +1033,10 @@
10181033 rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
10191034 memset(rx_bufpost, 0, sizeof(*rx_bufpost));
10201035
1021
- skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
1036
+ skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE);
10221037
10231038 if (skb == NULL) {
1024
- brcmf_err("Failed to alloc SKB\n");
1039
+ bphy_err(drvr, "Failed to alloc SKB\n");
10251040 brcmf_commonring_write_cancel(commonring, alloced - i);
10261041 break;
10271042 }
....@@ -1031,7 +1046,7 @@
10311046 msgbuf->rx_pktids, skb, 0,
10321047 &physaddr, &pktid)) {
10331048 dev_kfree_skb_any(skb);
1034
- brcmf_err("No PKTID available !!\n");
1049
+ bphy_err(drvr, "No PKTID available !!\n");
10351050 brcmf_commonring_write_cancel(commonring, alloced - i);
10361051 break;
10371052 }
....@@ -1083,6 +1098,7 @@
10831098
10841099 static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
10851100 {
1101
+ struct brcmf_pub *drvr = msgbuf->drvr;
10861102 struct msgbuf_rx_event *event;
10871103 u32 idx;
10881104 u16 buflen;
....@@ -1109,14 +1125,14 @@
11091125
11101126 ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
11111127 if (!ifp || !ifp->ndev) {
1112
- brcmf_err("Received pkt for invalid ifidx %d\n",
1113
- event->msg.ifidx);
1128
+ bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1129
+ event->msg.ifidx);
11141130 goto exit;
11151131 }
11161132
11171133 skb->protocol = eth_type_trans(skb, ifp->ndev);
11181134
1119
- brcmf_fweh_process_skb(ifp->drvr, skb, 0);
1135
+ brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
11201136
11211137 exit:
11221138 brcmu_pkt_buf_free_skb(skb);
....@@ -1126,6 +1142,7 @@
11261142 static void
11271143 brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
11281144 {
1145
+ struct brcmf_pub *drvr = msgbuf->drvr;
11291146 struct msgbuf_rx_complete *rx_complete;
11301147 struct sk_buff *skb;
11311148 u16 data_offset;
....@@ -1159,7 +1176,7 @@
11591176 ifp = msgbuf->drvr->mon_if;
11601177
11611178 if (!ifp) {
1162
- brcmf_err("Received unexpected monitor pkt\n");
1179
+ bphy_err(drvr, "Received unexpected monitor pkt\n");
11631180 brcmu_pkt_buf_free_skb(skb);
11641181 return;
11651182 }
....@@ -1170,21 +1187,49 @@
11701187
11711188 ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
11721189 if (!ifp || !ifp->ndev) {
1173
- brcmf_err("Received pkt for invalid ifidx %d\n",
1174
- rx_complete->msg.ifidx);
1190
+ bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1191
+ rx_complete->msg.ifidx);
11751192 brcmu_pkt_buf_free_skb(skb);
11761193 return;
11771194 }
11781195
11791196 skb->protocol = eth_type_trans(skb, ifp->ndev);
1180
- brcmf_netif_rx(ifp, skb);
1197
+ brcmf_netif_rx(ifp, skb, false);
11811198 }
11821199
1200
+static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf,
1201
+ void *buf)
1202
+{
1203
+ struct msgbuf_gen_status *gen_status = buf;
1204
+ struct brcmf_pub *drvr = msgbuf->drvr;
1205
+ int err;
1206
+
1207
+ err = le16_to_cpu(gen_status->compl_hdr.status);
1208
+ if (err)
1209
+ bphy_err(drvr, "Firmware reported general error: %d\n", err);
1210
+}
1211
+
1212
+static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf,
1213
+ void *buf)
1214
+{
1215
+ struct msgbuf_ring_status *ring_status = buf;
1216
+ struct brcmf_pub *drvr = msgbuf->drvr;
1217
+ int err;
1218
+
1219
+ err = le16_to_cpu(ring_status->compl_hdr.status);
1220
+ if (err) {
1221
+ int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id);
1222
+
1223
+ bphy_err(drvr, "Firmware reported ring %d error: %d\n", ring,
1224
+ err);
1225
+ }
1226
+}
11831227
11841228 static void
11851229 brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
11861230 void *buf)
11871231 {
1232
+ struct brcmf_pub *drvr = msgbuf->drvr;
11881233 struct msgbuf_flowring_create_resp *flowring_create_resp;
11891234 u16 status;
11901235 u16 flowid;
....@@ -1196,7 +1241,7 @@
11961241 status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
11971242
11981243 if (status) {
1199
- brcmf_err("Flowring creation failed, code %d\n", status);
1244
+ bphy_err(drvr, "Flowring creation failed, code %d\n", status);
12001245 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
12011246 return;
12021247 }
....@@ -1213,6 +1258,7 @@
12131258 brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
12141259 void *buf)
12151260 {
1261
+ struct brcmf_pub *drvr = msgbuf->drvr;
12161262 struct msgbuf_flowring_delete_resp *flowring_delete_resp;
12171263 u16 status;
12181264 u16 flowid;
....@@ -1224,7 +1270,7 @@
12241270 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
12251271
12261272 if (status) {
1227
- brcmf_err("Flowring deletion failed, code %d\n", status);
1273
+ bphy_err(drvr, "Flowring deletion failed, code %d\n", status);
12281274 brcmf_flowring_delete(msgbuf->flow, flowid);
12291275 return;
12301276 }
....@@ -1237,10 +1283,19 @@
12371283
12381284 static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
12391285 {
1286
+ struct brcmf_pub *drvr = msgbuf->drvr;
12401287 struct msgbuf_common_hdr *msg;
12411288
12421289 msg = (struct msgbuf_common_hdr *)buf;
12431290 switch (msg->msgtype) {
1291
+ case MSGBUF_TYPE_GEN_STATUS:
1292
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_GEN_STATUS\n");
1293
+ brcmf_msgbuf_process_gen_status(msgbuf, buf);
1294
+ break;
1295
+ case MSGBUF_TYPE_RING_STATUS:
1296
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n");
1297
+ brcmf_msgbuf_process_ring_status(msgbuf, buf);
1298
+ break;
12441299 case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
12451300 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n");
12461301 brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);
....@@ -1269,7 +1324,7 @@
12691324 brcmf_msgbuf_process_rx_complete(msgbuf, buf);
12701325 break;
12711326 default:
1272
- brcmf_err("Unsupported msgtype %d\n", msg->msgtype);
1327
+ bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype);
12731328 break;
12741329 }
12751330 }
....@@ -1348,11 +1403,18 @@
13481403 u8 ifidx;
13491404 int err;
13501405
1406
+ /* no need to submit if firmware can not be reached */
1407
+ if (drvr->bus_if->state != BRCMF_BUS_UP) {
1408
+ brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n");
1409
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1410
+ return;
1411
+ }
1412
+
13511413 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
13521414 brcmf_commonring_lock(commonring);
13531415 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
13541416 if (!ret_ptr) {
1355
- brcmf_err("FW unaware, flowring will be removed !!\n");
1417
+ bphy_err(drvr, "FW unaware, flowring will be removed !!\n");
13561418 brcmf_commonring_unlock(commonring);
13571419 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
13581420 return;
....@@ -1376,7 +1438,7 @@
13761438 err = brcmf_commonring_write_complete(commonring);
13771439 brcmf_commonring_unlock(commonring);
13781440 if (err) {
1379
- brcmf_err("Failed to submit RING_DELETE, flowring will be removed\n");
1441
+ bphy_err(drvr, "Failed to submit RING_DELETE, flowring will be removed\n");
13801442 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
13811443 }
13821444 }
....@@ -1411,7 +1473,6 @@
14111473 seq_printf(seq, "\nh2d_flowrings: depth %u\n",
14121474 BRCMF_H2D_TXFLOWRING_MAX_ITEM);
14131475 seq_puts(seq, "Active flowrings:\n");
1414
- hash = msgbuf->flow->hash;
14151476 for (i = 0; i < msgbuf->flow->nrofrings; i++) {
14161477 if (!msgbuf->flow->rings[i])
14171478 continue;
....@@ -1451,8 +1512,8 @@
14511512 if_msgbuf = drvr->bus_if->msgbuf;
14521513
14531514 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);
1515
+ bphy_err(drvr, "driver not configured for this many flowrings %d\n",
1516
+ if_msgbuf->max_flowrings);
14561517 if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
14571518 }
14581519
....@@ -1462,7 +1523,7 @@
14621523
14631524 msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow");
14641525 if (msgbuf->txflow_wq == NULL) {
1465
- brcmf_err("workqueue creation failed\n");
1526
+ bphy_err(drvr, "workqueue creation failed\n");
14661527 goto fail;
14671528 }
14681529 INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);