1 // SPDX-License-Identifier: ISC
2 /*
3 * Copyright (c) 2014 Broadcom Corporation
4 */
5
6 /*******************************************************************************
7 * Communicates with the dongle by using dcmd codes.
8 * For certain dcmd codes, the dongle interprets string data from the host.
9 ******************************************************************************/
10
11 #include <linux/types.h>
12 #include <linux/netdevice.h>
13 #include <linux/etherdevice.h>
14
15 #include <brcmu_utils.h>
16 #include <brcmu_wifi.h>
17
18 #include "core.h"
19 #include "debug.h"
20 #include "proto.h"
21 #include "msgbuf.h"
22 #include "commonring.h"
23 #include "flowring.h"
24 #include "bus.h"
25 #include "tracepoint.h"
26
27
28 #define MSGBUF_IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
29
30 #define MSGBUF_TYPE_GEN_STATUS 0x1
31 #define MSGBUF_TYPE_RING_STATUS 0x2
32 #define MSGBUF_TYPE_FLOW_RING_CREATE 0x3
33 #define MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT 0x4
34 #define MSGBUF_TYPE_FLOW_RING_DELETE 0x5
35 #define MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT 0x6
36 #define MSGBUF_TYPE_FLOW_RING_FLUSH 0x7
37 #define MSGBUF_TYPE_FLOW_RING_FLUSH_CMPLT 0x8
38 #define MSGBUF_TYPE_IOCTLPTR_REQ 0x9
39 #define MSGBUF_TYPE_IOCTLPTR_REQ_ACK 0xA
40 #define MSGBUF_TYPE_IOCTLRESP_BUF_POST 0xB
41 #define MSGBUF_TYPE_IOCTL_CMPLT 0xC
42 #define MSGBUF_TYPE_EVENT_BUF_POST 0xD
43 #define MSGBUF_TYPE_WL_EVENT 0xE
44 #define MSGBUF_TYPE_TX_POST 0xF
45 #define MSGBUF_TYPE_TX_STATUS 0x10
46 #define MSGBUF_TYPE_RXBUF_POST 0x11
47 #define MSGBUF_TYPE_RX_CMPLT 0x12
48 #define MSGBUF_TYPE_LPBK_DMAXFER 0x13
49 #define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14
50
51 #define NR_TX_PKTIDS 2048
52 #define NR_RX_PKTIDS 1024
53
54 #define BRCMF_IOCTL_REQ_PKTID 0xFFFE
55
56 #define BRCMF_MSGBUF_MAX_PKT_SIZE 2048
57 #define BRCMF_MSGBUF_MAX_CTL_PKT_SIZE 8192
58 #define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32
59 #define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8
60 #define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8
61
62 #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3 0x01
63 #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_11 0x02
64 #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK 0x07
65 #define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT 5
66
67 #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32
68 #define BRCMF_MSGBUF_TX_FLUSH_CNT2 96
69
70 #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96
71 #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
72 #define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48
73
74 #define BRCMF_MAX_TXSTATUS_WAIT_RETRIES 10
75
76 struct msgbuf_common_hdr {
77 u8 msgtype;
78 u8 ifidx;
79 u8 flags;
80 u8 rsvd0;
81 __le32 request_id;
82 };
83
84 struct msgbuf_ioctl_req_hdr {
85 struct msgbuf_common_hdr msg;
86 __le32 cmd;
87 __le16 trans_id;
88 __le16 input_buf_len;
89 __le16 output_buf_len;
90 __le16 rsvd0[3];
91 struct msgbuf_buf_addr req_buf_addr;
92 __le32 rsvd1[2];
93 };
94
95 struct msgbuf_tx_msghdr {
96 struct msgbuf_common_hdr msg;
97 u8 txhdr[ETH_HLEN];
98 u8 flags;
99 u8 seg_cnt;
100 struct msgbuf_buf_addr metadata_buf_addr;
101 struct msgbuf_buf_addr data_buf_addr;
102 __le16 metadata_buf_len;
103 __le16 data_len;
104 __le32 rsvd0;
105 };
106
107 struct msgbuf_rx_bufpost {
108 struct msgbuf_common_hdr msg;
109 __le16 metadata_buf_len;
110 __le16 data_buf_len;
111 __le32 rsvd0;
112 struct msgbuf_buf_addr metadata_buf_addr;
113 struct msgbuf_buf_addr data_buf_addr;
114 };
115
116 struct msgbuf_rx_ioctl_resp_or_event {
117 struct msgbuf_common_hdr msg;
118 __le16 host_buf_len;
119 __le16 rsvd0[3];
120 struct msgbuf_buf_addr host_buf_addr;
121 __le32 rsvd1[4];
122 };
123
124 struct msgbuf_completion_hdr {
125 __le16 status;
126 __le16 flow_ring_id;
127 };
128
129 /* Data struct for the MSGBUF_TYPE_GEN_STATUS */
130 struct msgbuf_gen_status {
131 struct msgbuf_common_hdr msg;
132 struct msgbuf_completion_hdr compl_hdr;
133 __le16 write_idx;
134 __le32 rsvd0[3];
135 };
136
137 /* Data struct for the MSGBUF_TYPE_RING_STATUS */
138 struct msgbuf_ring_status {
139 struct msgbuf_common_hdr msg;
140 struct msgbuf_completion_hdr compl_hdr;
141 __le16 write_idx;
142 __le16 rsvd0[5];
143 };
144
145 struct msgbuf_rx_event {
146 struct msgbuf_common_hdr msg;
147 struct msgbuf_completion_hdr compl_hdr;
148 __le16 event_data_len;
149 __le16 seqnum;
150 __le16 rsvd0[4];
151 };
152
153 struct msgbuf_ioctl_resp_hdr {
154 struct msgbuf_common_hdr msg;
155 struct msgbuf_completion_hdr compl_hdr;
156 __le16 resp_len;
157 __le16 trans_id;
158 __le32 cmd;
159 __le32 rsvd0;
160 };
161
162 struct msgbuf_tx_status {
163 struct msgbuf_common_hdr msg;
164 struct msgbuf_completion_hdr compl_hdr;
165 __le16 metadata_len;
166 __le16 tx_status;
167 };
168
169 struct msgbuf_rx_complete {
170 struct msgbuf_common_hdr msg;
171 struct msgbuf_completion_hdr compl_hdr;
172 __le16 metadata_len;
173 __le16 data_len;
174 __le16 data_offset;
175 __le16 flags;
176 __le32 rx_status_0;
177 __le32 rx_status_1;
178 __le32 rsvd0;
179 };
180
181 struct msgbuf_tx_flowring_create_req {
182 struct msgbuf_common_hdr msg;
183 u8 da[ETH_ALEN];
184 u8 sa[ETH_ALEN];
185 u8 tid;
186 u8 if_flags;
187 __le16 flow_ring_id;
188 u8 tc;
189 u8 priority;
190 __le16 int_vector;
191 __le16 max_items;
192 __le16 len_item;
193 struct msgbuf_buf_addr flow_ring_addr;
194 };
195
196 struct msgbuf_tx_flowring_delete_req {
197 struct msgbuf_common_hdr msg;
198 __le16 flow_ring_id;
199 __le16 reason;
200 __le32 rsvd0[7];
201 };
202
203 struct msgbuf_flowring_create_resp {
204 struct msgbuf_common_hdr msg;
205 struct msgbuf_completion_hdr compl_hdr;
206 __le32 rsvd0[3];
207 };
208
209 struct msgbuf_flowring_delete_resp {
210 struct msgbuf_common_hdr msg;
211 struct msgbuf_completion_hdr compl_hdr;
212 __le32 rsvd0[3];
213 };
214
215 struct msgbuf_flowring_flush_resp {
216 struct msgbuf_common_hdr msg;
217 struct msgbuf_completion_hdr compl_hdr;
218 __le32 rsvd0[3];
219 };
220
221 struct brcmf_msgbuf_work_item {
222 struct list_head queue;
223 u32 flowid;
224 int ifidx;
225 u8 sa[ETH_ALEN];
226 u8 da[ETH_ALEN];
227 };
228
229 struct brcmf_msgbuf {
230 struct brcmf_pub *drvr;
231
232 struct brcmf_commonring **commonrings;
233 struct brcmf_commonring **flowrings;
234 dma_addr_t *flowring_dma_handle;
235
236 u16 max_flowrings;
237 u16 max_submissionrings;
238 u16 max_completionrings;
239
240 u16 rx_dataoffset;
241 u32 max_rxbufpost;
242 u16 rx_metadata_offset;
243 u32 rxbufpost;
244
245 u32 max_ioctlrespbuf;
246 u32 cur_ioctlrespbuf;
247 u32 max_eventbuf;
248 u32 cur_eventbuf;
249
250 void *ioctbuf;
251 dma_addr_t ioctbuf_handle;
252 u32 ioctbuf_phys_hi;
253 u32 ioctbuf_phys_lo;
254 int ioctl_resp_status;
255 u32 ioctl_resp_ret_len;
256 u32 ioctl_resp_pktid;
257
258 u16 data_seq_no;
259 u16 ioctl_seq_no;
260 u32 reqid;
261 wait_queue_head_t ioctl_resp_wait;
262 bool ctl_completed;
263
264 struct brcmf_msgbuf_pktids *tx_pktids;
265 struct brcmf_msgbuf_pktids *rx_pktids;
266 struct brcmf_flowring *flow;
267
268 struct workqueue_struct *txflow_wq;
269 struct work_struct txflow_work;
270 unsigned long *flow_map;
271 unsigned long *txstatus_done_map;
272
273 struct work_struct flowring_work;
274 spinlock_t flowring_work_lock;
275 struct list_head work_queue;
276 };
277
278 struct brcmf_msgbuf_pktid {
279 atomic_t allocated;
280 u16 data_offset;
281 struct sk_buff *skb;
282 dma_addr_t physaddr;
283 };
284
285 struct brcmf_msgbuf_pktids {
286 u32 array_size;
287 u32 last_allocated_idx;
288 enum dma_data_direction direction;
289 struct brcmf_msgbuf_pktid *array;
290 };
291
292 static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf);
293
294
295 static struct brcmf_msgbuf_pktids *
brcmf_msgbuf_init_pktids(u32 nr_array_entries,enum dma_data_direction direction)296 brcmf_msgbuf_init_pktids(u32 nr_array_entries,
297 enum dma_data_direction direction)
298 {
299 struct brcmf_msgbuf_pktid *array;
300 struct brcmf_msgbuf_pktids *pktids;
301
302 array = kzalloc_objs(*array, nr_array_entries);
303 if (!array)
304 return NULL;
305
306 pktids = kzalloc_obj(*pktids);
307 if (!pktids) {
308 kfree(array);
309 return NULL;
310 }
311 pktids->array = array;
312 pktids->array_size = nr_array_entries;
313 pktids->direction = direction;
314
315 return pktids;
316 }
317
318
319 static int
brcmf_msgbuf_alloc_pktid(struct device * dev,struct brcmf_msgbuf_pktids * pktids,struct sk_buff * skb,u16 data_offset,dma_addr_t * physaddr,u32 * idx)320 brcmf_msgbuf_alloc_pktid(struct device *dev,
321 struct brcmf_msgbuf_pktids *pktids,
322 struct sk_buff *skb, u16 data_offset,
323 dma_addr_t *physaddr, u32 *idx)
324 {
325 struct brcmf_msgbuf_pktid *array;
326 u32 count;
327
328 array = pktids->array;
329
330 *physaddr = dma_map_single(dev, skb->data + data_offset,
331 skb->len - data_offset, pktids->direction);
332
333 if (dma_mapping_error(dev, *physaddr)) {
334 brcmf_err("dma_map_single failed !!\n");
335 return -ENOMEM;
336 }
337
338 *idx = pktids->last_allocated_idx;
339
340 count = 0;
341 do {
342 (*idx)++;
343 if (*idx == pktids->array_size)
344 *idx = 0;
345 if (array[*idx].allocated.counter == 0)
346 if (atomic_cmpxchg(&array[*idx].allocated, 0, 1) == 0)
347 break;
348 count++;
349 } while (count < pktids->array_size);
350
351 if (count == pktids->array_size) {
352 dma_unmap_single(dev, *physaddr, skb->len - data_offset,
353 pktids->direction);
354 return -ENOMEM;
355 }
356
357 array[*idx].data_offset = data_offset;
358 array[*idx].physaddr = *physaddr;
359 array[*idx].skb = skb;
360
361 pktids->last_allocated_idx = *idx;
362
363 return 0;
364 }
365
366
367 static struct sk_buff *
brcmf_msgbuf_get_pktid(struct device * dev,struct brcmf_msgbuf_pktids * pktids,u32 idx)368 brcmf_msgbuf_get_pktid(struct device *dev, struct brcmf_msgbuf_pktids *pktids,
369 u32 idx)
370 {
371 struct brcmf_msgbuf_pktid *pktid;
372 struct sk_buff *skb;
373
374 if (idx >= pktids->array_size) {
375 brcmf_err("Invalid packet id %d (max %d)\n", idx,
376 pktids->array_size);
377 return NULL;
378 }
379 if (pktids->array[idx].allocated.counter) {
380 pktid = &pktids->array[idx];
381 dma_unmap_single(dev, pktid->physaddr,
382 pktid->skb->len - pktid->data_offset,
383 pktids->direction);
384 skb = pktid->skb;
385 pktid->allocated.counter = 0;
386 return skb;
387 } else {
388 brcmf_err("Invalid packet id %d (not in use)\n", idx);
389 }
390
391 return NULL;
392 }
393
394
395 static void
brcmf_msgbuf_release_array(struct device * dev,struct brcmf_msgbuf_pktids * pktids)396 brcmf_msgbuf_release_array(struct device *dev,
397 struct brcmf_msgbuf_pktids *pktids)
398 {
399 struct brcmf_msgbuf_pktid *array;
400 struct brcmf_msgbuf_pktid *pktid;
401 u32 count;
402
403 array = pktids->array;
404 count = 0;
405 do {
406 if (array[count].allocated.counter) {
407 pktid = &array[count];
408 dma_unmap_single(dev, pktid->physaddr,
409 pktid->skb->len - pktid->data_offset,
410 pktids->direction);
411 brcmu_pkt_buf_free_skb(pktid->skb);
412 }
413 count++;
414 } while (count < pktids->array_size);
415
416 kfree(array);
417 kfree(pktids);
418 }
419
420
brcmf_msgbuf_release_pktids(struct brcmf_msgbuf * msgbuf)421 static void brcmf_msgbuf_release_pktids(struct brcmf_msgbuf *msgbuf)
422 {
423 if (msgbuf->rx_pktids)
424 brcmf_msgbuf_release_array(msgbuf->drvr->bus_if->dev,
425 msgbuf->rx_pktids);
426 if (msgbuf->tx_pktids)
427 brcmf_msgbuf_release_array(msgbuf->drvr->bus_if->dev,
428 msgbuf->tx_pktids);
429 }
430
431
brcmf_msgbuf_tx_ioctl(struct brcmf_pub * drvr,int ifidx,uint cmd,void * buf,uint len)432 static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx,
433 uint cmd, void *buf, uint len)
434 {
435 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
436 struct brcmf_commonring *commonring;
437 struct msgbuf_ioctl_req_hdr *request;
438 u16 buf_len;
439 void *ret_ptr;
440 int err;
441
442 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
443 brcmf_commonring_lock(commonring);
444 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
445 if (!ret_ptr) {
446 bphy_err(drvr, "Failed to reserve space in commonring\n");
447 brcmf_commonring_unlock(commonring);
448 return -ENOMEM;
449 }
450
451 msgbuf->reqid++;
452
453 request = (struct msgbuf_ioctl_req_hdr *)ret_ptr;
454 request->msg.msgtype = MSGBUF_TYPE_IOCTLPTR_REQ;
455 request->msg.ifidx = (u8)ifidx;
456 request->msg.flags = 0;
457 request->msg.request_id = cpu_to_le32(BRCMF_IOCTL_REQ_PKTID);
458 request->cmd = cpu_to_le32(cmd);
459 request->output_buf_len = cpu_to_le16(len);
460 request->trans_id = cpu_to_le16(msgbuf->reqid);
461
462 buf_len = min_t(u16, len, BRCMF_TX_IOCTL_MAX_MSG_SIZE);
463 request->input_buf_len = cpu_to_le16(buf_len);
464 request->req_buf_addr.high_addr = cpu_to_le32(msgbuf->ioctbuf_phys_hi);
465 request->req_buf_addr.low_addr = cpu_to_le32(msgbuf->ioctbuf_phys_lo);
466 if (buf)
467 memcpy(msgbuf->ioctbuf, buf, buf_len);
468 else
469 memset(msgbuf->ioctbuf, 0, buf_len);
470
471 err = brcmf_commonring_write_complete(commonring);
472 brcmf_commonring_unlock(commonring);
473
474 return err;
475 }
476
477
brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf * msgbuf)478 static int brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf *msgbuf)
479 {
480 return wait_event_timeout(msgbuf->ioctl_resp_wait,
481 msgbuf->ctl_completed,
482 MSGBUF_IOCTL_RESP_TIMEOUT);
483 }
484
485
brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf * msgbuf)486 static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
487 {
488 msgbuf->ctl_completed = true;
489 wake_up(&msgbuf->ioctl_resp_wait);
490 }
491
492
brcmf_msgbuf_query_dcmd(struct brcmf_pub * drvr,int ifidx,uint cmd,void * buf,uint len,int * fwerr)493 static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
494 uint cmd, void *buf, uint len, int *fwerr)
495 {
496 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
497 struct sk_buff *skb = NULL;
498 int timeout;
499 int err;
500
501 brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
502 *fwerr = 0;
503 msgbuf->ctl_completed = false;
504 err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
505 if (err)
506 return err;
507
508 timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);
509 if (!timeout) {
510 bphy_err(drvr, "Timeout on response for query command\n");
511 return -EIO;
512 }
513
514 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
515 msgbuf->rx_pktids,
516 msgbuf->ioctl_resp_pktid);
517 if (msgbuf->ioctl_resp_ret_len != 0) {
518 if (!skb)
519 return -EBADF;
520
521 memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ?
522 len : msgbuf->ioctl_resp_ret_len);
523 }
524 brcmu_pkt_buf_free_skb(skb);
525
526 *fwerr = msgbuf->ioctl_resp_status;
527 return 0;
528 }
529
530
brcmf_msgbuf_set_dcmd(struct brcmf_pub * drvr,int ifidx,uint cmd,void * buf,uint len,int * fwerr)531 static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,
532 uint cmd, void *buf, uint len, int *fwerr)
533 {
534 return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
535 }
536
537
brcmf_msgbuf_hdrpull(struct brcmf_pub * drvr,bool do_fws,struct sk_buff * skb,struct brcmf_if ** ifp)538 static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
539 struct sk_buff *skb, struct brcmf_if **ifp)
540 {
541 return -ENODEV;
542 }
543
brcmf_msgbuf_rxreorder(struct brcmf_if * ifp,struct sk_buff * skb)544 static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
545 {
546 }
547
548 static void
brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf * msgbuf,u16 flowid)549 brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid)
550 {
551 u32 dma_sz;
552 void *dma_buf;
553
554 brcmf_dbg(MSGBUF, "Removing flowring %d\n", flowid);
555
556 dma_sz = BRCMF_H2D_TXFLOWRING_MAX_ITEM * BRCMF_H2D_TXFLOWRING_ITEMSIZE;
557 dma_buf = msgbuf->flowrings[flowid]->buf_addr;
558 dma_free_coherent(msgbuf->drvr->bus_if->dev, dma_sz, dma_buf,
559 msgbuf->flowring_dma_handle[flowid]);
560
561 brcmf_flowring_delete(msgbuf->flow, flowid);
562 }
563
brcmf_msgbuf_get_flowid(struct brcmf_msgbuf * msgbuf,u16 flow_ring_id,u16 * flowid)564 static bool brcmf_msgbuf_get_flowid(struct brcmf_msgbuf *msgbuf,
565 u16 flow_ring_id, u16 *flowid)
566 {
567 u32 id = flow_ring_id;
568
569 if (id < BRCMF_H2D_MSGRING_FLOWRING_IDSTART) {
570 bphy_err(msgbuf->drvr, "invalid flowring id %u\n",
571 flow_ring_id);
572 return false;
573 }
574
575 id -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
576 if (id >= msgbuf->max_flowrings) {
577 bphy_err(msgbuf->drvr, "invalid flowring id %u\n",
578 flow_ring_id);
579 return false;
580 }
581
582 *flowid = id;
583 return true;
584 }
585
586
587 static struct brcmf_msgbuf_work_item *
brcmf_msgbuf_dequeue_work(struct brcmf_msgbuf * msgbuf)588 brcmf_msgbuf_dequeue_work(struct brcmf_msgbuf *msgbuf)
589 {
590 struct brcmf_msgbuf_work_item *work = NULL;
591 ulong flags;
592
593 spin_lock_irqsave(&msgbuf->flowring_work_lock, flags);
594 if (!list_empty(&msgbuf->work_queue)) {
595 work = list_first_entry(&msgbuf->work_queue,
596 struct brcmf_msgbuf_work_item, queue);
597 list_del(&work->queue);
598 }
599 spin_unlock_irqrestore(&msgbuf->flowring_work_lock, flags);
600
601 return work;
602 }
603
604
605 static u32
brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf * msgbuf,struct brcmf_msgbuf_work_item * work)606 brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
607 struct brcmf_msgbuf_work_item *work)
608 {
609 struct brcmf_pub *drvr = msgbuf->drvr;
610 struct msgbuf_tx_flowring_create_req *create;
611 struct brcmf_commonring *commonring;
612 void *ret_ptr;
613 u32 flowid;
614 void *dma_buf;
615 u32 dma_sz;
616 u64 address;
617 int err;
618
619 flowid = work->flowid;
620 dma_sz = BRCMF_H2D_TXFLOWRING_MAX_ITEM * BRCMF_H2D_TXFLOWRING_ITEMSIZE;
621 dma_buf = dma_alloc_coherent(msgbuf->drvr->bus_if->dev, dma_sz,
622 &msgbuf->flowring_dma_handle[flowid],
623 GFP_KERNEL);
624 if (!dma_buf) {
625 bphy_err(drvr, "dma_alloc_coherent failed\n");
626 brcmf_flowring_delete(msgbuf->flow, flowid);
627 return BRCMF_FLOWRING_INVALID_ID;
628 }
629
630 brcmf_commonring_config(msgbuf->flowrings[flowid],
631 BRCMF_H2D_TXFLOWRING_MAX_ITEM,
632 BRCMF_H2D_TXFLOWRING_ITEMSIZE, dma_buf);
633
634 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
635 brcmf_commonring_lock(commonring);
636 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
637 if (!ret_ptr) {
638 bphy_err(drvr, "Failed to reserve space in commonring\n");
639 brcmf_commonring_unlock(commonring);
640 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
641 return BRCMF_FLOWRING_INVALID_ID;
642 }
643
644 create = (struct msgbuf_tx_flowring_create_req *)ret_ptr;
645 create->msg.msgtype = MSGBUF_TYPE_FLOW_RING_CREATE;
646 create->msg.ifidx = work->ifidx;
647 create->msg.request_id = 0;
648 create->tid = brcmf_flowring_tid(msgbuf->flow, flowid);
649 create->flow_ring_id = cpu_to_le16(flowid +
650 BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
651 memcpy(create->sa, work->sa, ETH_ALEN);
652 memcpy(create->da, work->da, ETH_ALEN);
653 address = (u64)msgbuf->flowring_dma_handle[flowid];
654 create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32);
655 create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff);
656 create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM);
657 create->len_item = cpu_to_le16(BRCMF_H2D_TXFLOWRING_ITEMSIZE);
658
659 brcmf_dbg(MSGBUF, "Send Flow Create Req flow ID %d for peer %pM prio %d ifindex %d\n",
660 flowid, work->da, create->tid, work->ifidx);
661
662 err = brcmf_commonring_write_complete(commonring);
663 brcmf_commonring_unlock(commonring);
664 if (err) {
665 bphy_err(drvr, "Failed to write commonring\n");
666 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
667 return BRCMF_FLOWRING_INVALID_ID;
668 }
669
670 return flowid;
671 }
672
673
brcmf_msgbuf_flowring_worker(struct work_struct * work)674 static void brcmf_msgbuf_flowring_worker(struct work_struct *work)
675 {
676 struct brcmf_msgbuf *msgbuf;
677 struct brcmf_msgbuf_work_item *create;
678
679 msgbuf = container_of(work, struct brcmf_msgbuf, flowring_work);
680
681 while ((create = brcmf_msgbuf_dequeue_work(msgbuf))) {
682 brcmf_msgbuf_flowring_create_worker(msgbuf, create);
683 kfree(create);
684 }
685 }
686
687
brcmf_msgbuf_flowring_create(struct brcmf_msgbuf * msgbuf,int ifidx,struct sk_buff * skb)688 static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx,
689 struct sk_buff *skb)
690 {
691 struct brcmf_msgbuf_work_item *create;
692 struct ethhdr *eh = (struct ethhdr *)(skb->data);
693 u32 flowid;
694 ulong flags;
695
696 create = kzalloc_obj(*create, GFP_ATOMIC);
697 if (create == NULL)
698 return BRCMF_FLOWRING_INVALID_ID;
699
700 flowid = brcmf_flowring_create(msgbuf->flow, eh->h_dest,
701 skb->priority, ifidx);
702 if (flowid == BRCMF_FLOWRING_INVALID_ID) {
703 kfree(create);
704 return flowid;
705 }
706
707 create->flowid = flowid;
708 create->ifidx = ifidx;
709 memcpy(create->sa, eh->h_source, ETH_ALEN);
710 memcpy(create->da, eh->h_dest, ETH_ALEN);
711
712 spin_lock_irqsave(&msgbuf->flowring_work_lock, flags);
713 list_add_tail(&create->queue, &msgbuf->work_queue);
714 spin_unlock_irqrestore(&msgbuf->flowring_work_lock, flags);
715 schedule_work(&msgbuf->flowring_work);
716
717 return flowid;
718 }
719
720
brcmf_msgbuf_txflow(struct brcmf_msgbuf * msgbuf,u16 flowid)721 static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
722 {
723 struct brcmf_flowring *flow = msgbuf->flow;
724 struct brcmf_pub *drvr = msgbuf->drvr;
725 struct brcmf_commonring *commonring;
726 void *ret_ptr;
727 u32 count;
728 struct sk_buff *skb;
729 dma_addr_t physaddr;
730 u32 pktid;
731 struct msgbuf_tx_msghdr *tx_msghdr;
732 u64 address;
733
734 commonring = msgbuf->flowrings[flowid];
735 if (!brcmf_commonring_write_available(commonring))
736 return;
737
738 brcmf_commonring_lock(commonring);
739
740 count = BRCMF_MSGBUF_TX_FLUSH_CNT2 - BRCMF_MSGBUF_TX_FLUSH_CNT1;
741 while (brcmf_flowring_qlen(flow, flowid)) {
742 skb = brcmf_flowring_dequeue(flow, flowid);
743 if (skb == NULL) {
744 bphy_err(drvr, "No SKB, but qlen %d\n",
745 brcmf_flowring_qlen(flow, flowid));
746 break;
747 }
748 skb_orphan(skb);
749 if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
750 msgbuf->tx_pktids, skb, ETH_HLEN,
751 &physaddr, &pktid)) {
752 brcmf_flowring_reinsert(flow, flowid, skb);
753 bphy_err(drvr, "No PKTID available !!\n");
754 break;
755 }
756 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
757 if (!ret_ptr) {
758 brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
759 msgbuf->tx_pktids, pktid);
760 brcmf_flowring_reinsert(flow, flowid, skb);
761 break;
762 }
763 count++;
764
765 tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr;
766
767 tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST;
768 tx_msghdr->msg.request_id = cpu_to_le32(pktid + 1);
769 tx_msghdr->msg.ifidx = brcmf_flowring_ifidx_get(flow, flowid);
770 tx_msghdr->flags = BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3;
771 tx_msghdr->flags |= (skb->priority & 0x07) <<
772 BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT;
773 tx_msghdr->seg_cnt = 1;
774 memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN);
775 tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN);
776 address = (u64)physaddr;
777 tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32);
778 tx_msghdr->data_buf_addr.low_addr =
779 cpu_to_le32(address & 0xffffffff);
780 tx_msghdr->metadata_buf_len = 0;
781 tx_msghdr->metadata_buf_addr.high_addr = 0;
782 tx_msghdr->metadata_buf_addr.low_addr = 0;
783 atomic_inc(&commonring->outstanding_tx);
784 if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) {
785 brcmf_commonring_write_complete(commonring);
786 count = 0;
787 }
788 }
789 if (count)
790 brcmf_commonring_write_complete(commonring);
791 brcmf_commonring_unlock(commonring);
792 }
793
794
brcmf_msgbuf_txflow_worker(struct work_struct * worker)795 static void brcmf_msgbuf_txflow_worker(struct work_struct *worker)
796 {
797 struct brcmf_msgbuf *msgbuf;
798 u32 flowid;
799
800 msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work);
801 for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->max_flowrings) {
802 clear_bit(flowid, msgbuf->flow_map);
803 brcmf_msgbuf_txflow(msgbuf, flowid);
804 }
805 }
806
807
brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf * msgbuf,u32 flowid,bool force)808 static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,
809 bool force)
810 {
811 struct brcmf_commonring *commonring;
812
813 set_bit(flowid, msgbuf->flow_map);
814 commonring = msgbuf->flowrings[flowid];
815 if ((force) || (atomic_read(&commonring->outstanding_tx) <
816 BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
817 queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
818
819 return 0;
820 }
821
822
brcmf_msgbuf_tx_queue_data(struct brcmf_pub * drvr,int ifidx,struct sk_buff * skb)823 static int brcmf_msgbuf_tx_queue_data(struct brcmf_pub *drvr, int ifidx,
824 struct sk_buff *skb)
825 {
826 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
827 struct brcmf_flowring *flow = msgbuf->flow;
828 struct ethhdr *eh = (struct ethhdr *)(skb->data);
829 u32 flowid;
830 u32 queue_count;
831 bool force;
832
833 flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx);
834 if (flowid == BRCMF_FLOWRING_INVALID_ID) {
835 flowid = brcmf_msgbuf_flowring_create(msgbuf, ifidx, skb);
836 if (flowid == BRCMF_FLOWRING_INVALID_ID) {
837 return -ENOMEM;
838 } else {
839 brcmf_flowring_enqueue(flow, flowid, skb);
840 return 0;
841 }
842 }
843 queue_count = brcmf_flowring_enqueue(flow, flowid, skb);
844 force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0);
845 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, force);
846
847 return 0;
848 }
849
850
851 static void
brcmf_msgbuf_configure_addr_mode(struct brcmf_pub * drvr,int ifidx,enum proto_addr_mode addr_mode)852 brcmf_msgbuf_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
853 enum proto_addr_mode addr_mode)
854 {
855 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
856
857 brcmf_flowring_configure_addr_mode(msgbuf->flow, ifidx, addr_mode);
858 }
859
860
861 static void
brcmf_msgbuf_delete_peer(struct brcmf_pub * drvr,int ifidx,u8 peer[ETH_ALEN])862 brcmf_msgbuf_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
863 {
864 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
865
866 brcmf_flowring_delete_peer(msgbuf->flow, ifidx, peer);
867 }
868
869
870 static void
brcmf_msgbuf_add_tdls_peer(struct brcmf_pub * drvr,int ifidx,u8 peer[ETH_ALEN])871 brcmf_msgbuf_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
872 {
873 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
874
875 brcmf_flowring_add_tdls_peer(msgbuf->flow, ifidx, peer);
876 }
877
878
879 static void
brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf * msgbuf,void * buf)880 brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf)
881 {
882 struct msgbuf_ioctl_resp_hdr *ioctl_resp;
883
884 ioctl_resp = (struct msgbuf_ioctl_resp_hdr *)buf;
885
886 msgbuf->ioctl_resp_status =
887 (s16)le16_to_cpu(ioctl_resp->compl_hdr.status);
888 msgbuf->ioctl_resp_ret_len = le16_to_cpu(ioctl_resp->resp_len);
889 msgbuf->ioctl_resp_pktid = le32_to_cpu(ioctl_resp->msg.request_id);
890
891 brcmf_msgbuf_ioctl_resp_wake(msgbuf);
892
893 if (msgbuf->cur_ioctlrespbuf)
894 msgbuf->cur_ioctlrespbuf--;
895 brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
896 }
897
898
899 static void
brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf * msgbuf,void * buf)900 brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
901 {
902 struct brcmf_commonring *commonring;
903 struct msgbuf_tx_status *tx_status;
904 u32 idx;
905 struct sk_buff *skb;
906 u16 flow_ring_id;
907 u16 flowid;
908
909 tx_status = (struct msgbuf_tx_status *)buf;
910 idx = le32_to_cpu(tx_status->msg.request_id) - 1;
911 flow_ring_id = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
912 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
913 msgbuf->tx_pktids, idx);
914 if (!skb)
915 return;
916
917 if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid)) {
918 brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
919 skb, false);
920 return;
921 }
922
923 set_bit(flowid, msgbuf->txstatus_done_map);
924 commonring = msgbuf->flowrings[flowid];
925 atomic_dec(&commonring->outstanding_tx);
926
927 brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
928 skb, true);
929 }
930
931
brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf * msgbuf,u32 count)932 static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
933 {
934 struct brcmf_pub *drvr = msgbuf->drvr;
935 struct brcmf_commonring *commonring;
936 void *ret_ptr;
937 struct sk_buff *skb;
938 u16 alloced;
939 u32 pktlen;
940 dma_addr_t physaddr;
941 struct msgbuf_rx_bufpost *rx_bufpost;
942 u64 address;
943 u32 pktid;
944 u32 i;
945
946 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
947 ret_ptr = brcmf_commonring_reserve_for_write_multiple(commonring,
948 count,
949 &alloced);
950 if (!ret_ptr) {
951 brcmf_dbg(MSGBUF, "Failed to reserve space in commonring\n");
952 return 0;
953 }
954
955 for (i = 0; i < alloced; i++) {
956 rx_bufpost = (struct msgbuf_rx_bufpost *)ret_ptr;
957 memset(rx_bufpost, 0, sizeof(*rx_bufpost));
958
959 skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
960
961 if (skb == NULL) {
962 bphy_err(drvr, "Failed to alloc SKB\n");
963 brcmf_commonring_write_cancel(commonring, alloced - i);
964 break;
965 }
966
967 pktlen = skb->len;
968 if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
969 msgbuf->rx_pktids, skb, 0,
970 &physaddr, &pktid)) {
971 dev_kfree_skb_any(skb);
972 bphy_err(drvr, "No PKTID available !!\n");
973 brcmf_commonring_write_cancel(commonring, alloced - i);
974 break;
975 }
976
977 if (msgbuf->rx_metadata_offset) {
978 address = (u64)physaddr;
979 rx_bufpost->metadata_buf_len =
980 cpu_to_le16(msgbuf->rx_metadata_offset);
981 rx_bufpost->metadata_buf_addr.high_addr =
982 cpu_to_le32(address >> 32);
983 rx_bufpost->metadata_buf_addr.low_addr =
984 cpu_to_le32(address & 0xffffffff);
985
986 skb_pull(skb, msgbuf->rx_metadata_offset);
987 pktlen = skb->len;
988 physaddr += msgbuf->rx_metadata_offset;
989 }
990 rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST;
991 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
992
993 address = (u64)physaddr;
994 rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen);
995 rx_bufpost->data_buf_addr.high_addr =
996 cpu_to_le32(address >> 32);
997 rx_bufpost->data_buf_addr.low_addr =
998 cpu_to_le32(address & 0xffffffff);
999
1000 ret_ptr += brcmf_commonring_len_item(commonring);
1001 }
1002
1003 if (i)
1004 brcmf_commonring_write_complete(commonring);
1005
1006 return i;
1007 }
1008
1009
1010 static void
brcmf_msgbuf_rxbuf_data_fill(struct brcmf_msgbuf * msgbuf)1011 brcmf_msgbuf_rxbuf_data_fill(struct brcmf_msgbuf *msgbuf)
1012 {
1013 u32 fillbufs;
1014 u32 retcount;
1015
1016 fillbufs = msgbuf->max_rxbufpost - msgbuf->rxbufpost;
1017
1018 while (fillbufs) {
1019 retcount = brcmf_msgbuf_rxbuf_data_post(msgbuf, fillbufs);
1020 if (!retcount)
1021 break;
1022 msgbuf->rxbufpost += retcount;
1023 fillbufs -= retcount;
1024 }
1025 }
1026
1027
1028 static void
brcmf_msgbuf_update_rxbufpost_count(struct brcmf_msgbuf * msgbuf,u16 rxcnt)1029 brcmf_msgbuf_update_rxbufpost_count(struct brcmf_msgbuf *msgbuf, u16 rxcnt)
1030 {
1031 msgbuf->rxbufpost -= rxcnt;
1032 if (msgbuf->rxbufpost <= (msgbuf->max_rxbufpost -
1033 BRCMF_MSGBUF_RXBUFPOST_THRESHOLD))
1034 brcmf_msgbuf_rxbuf_data_fill(msgbuf);
1035 }
1036
1037
1038 static u32
brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf * msgbuf,bool event_buf,u32 count)1039 brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
1040 u32 count)
1041 {
1042 struct brcmf_pub *drvr = msgbuf->drvr;
1043 struct brcmf_commonring *commonring;
1044 void *ret_ptr;
1045 struct sk_buff *skb;
1046 u16 alloced;
1047 u32 pktlen;
1048 dma_addr_t physaddr;
1049 struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost;
1050 u64 address;
1051 u32 pktid;
1052 u32 i;
1053
1054 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
1055 brcmf_commonring_lock(commonring);
1056 ret_ptr = brcmf_commonring_reserve_for_write_multiple(commonring,
1057 count,
1058 &alloced);
1059 if (!ret_ptr) {
1060 bphy_err(drvr, "Failed to reserve space in commonring\n");
1061 brcmf_commonring_unlock(commonring);
1062 return 0;
1063 }
1064
1065 for (i = 0; i < alloced; i++) {
1066 rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
1067 memset(rx_bufpost, 0, sizeof(*rx_bufpost));
1068
1069 skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE);
1070
1071 if (skb == NULL) {
1072 bphy_err(drvr, "Failed to alloc SKB\n");
1073 brcmf_commonring_write_cancel(commonring, alloced - i);
1074 break;
1075 }
1076
1077 pktlen = skb->len;
1078 if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
1079 msgbuf->rx_pktids, skb, 0,
1080 &physaddr, &pktid)) {
1081 dev_kfree_skb_any(skb);
1082 bphy_err(drvr, "No PKTID available !!\n");
1083 brcmf_commonring_write_cancel(commonring, alloced - i);
1084 break;
1085 }
1086 if (event_buf)
1087 rx_bufpost->msg.msgtype = MSGBUF_TYPE_EVENT_BUF_POST;
1088 else
1089 rx_bufpost->msg.msgtype =
1090 MSGBUF_TYPE_IOCTLRESP_BUF_POST;
1091 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
1092
1093 address = (u64)physaddr;
1094 rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen);
1095 rx_bufpost->host_buf_addr.high_addr =
1096 cpu_to_le32(address >> 32);
1097 rx_bufpost->host_buf_addr.low_addr =
1098 cpu_to_le32(address & 0xffffffff);
1099
1100 ret_ptr += brcmf_commonring_len_item(commonring);
1101 }
1102
1103 if (i)
1104 brcmf_commonring_write_complete(commonring);
1105
1106 brcmf_commonring_unlock(commonring);
1107
1108 return i;
1109 }
1110
1111
brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf * msgbuf)1112 static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf)
1113 {
1114 u32 count;
1115
1116 count = msgbuf->max_ioctlrespbuf - msgbuf->cur_ioctlrespbuf;
1117 count = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, false, count);
1118 msgbuf->cur_ioctlrespbuf += count;
1119 }
1120
1121
brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf * msgbuf)1122 static void brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf *msgbuf)
1123 {
1124 u32 count;
1125
1126 count = msgbuf->max_eventbuf - msgbuf->cur_eventbuf;
1127 count = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, true, count);
1128 msgbuf->cur_eventbuf += count;
1129 }
1130
1131
brcmf_msgbuf_process_event(struct brcmf_msgbuf * msgbuf,void * buf)1132 static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
1133 {
1134 struct brcmf_pub *drvr = msgbuf->drvr;
1135 struct msgbuf_rx_event *event;
1136 u32 idx;
1137 u16 buflen;
1138 struct sk_buff *skb;
1139 struct brcmf_if *ifp;
1140
1141 event = (struct msgbuf_rx_event *)buf;
1142 idx = le32_to_cpu(event->msg.request_id);
1143 buflen = le16_to_cpu(event->event_data_len);
1144
1145 if (msgbuf->cur_eventbuf)
1146 msgbuf->cur_eventbuf--;
1147 brcmf_msgbuf_rxbuf_event_post(msgbuf);
1148
1149 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
1150 msgbuf->rx_pktids, idx);
1151 if (!skb)
1152 return;
1153
1154 if (msgbuf->rx_dataoffset)
1155 skb_pull(skb, msgbuf->rx_dataoffset);
1156
1157 skb_trim(skb, buflen);
1158
1159 ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
1160 if (!ifp || !ifp->ndev) {
1161 bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1162 event->msg.ifidx);
1163 goto exit;
1164 }
1165
1166 skb->protocol = eth_type_trans(skb, ifp->ndev);
1167
1168 brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
1169
1170 exit:
1171 brcmu_pkt_buf_free_skb(skb);
1172 }
1173
1174
1175 static void
brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf * msgbuf,void * buf)1176 brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
1177 {
1178 struct brcmf_pub *drvr = msgbuf->drvr;
1179 struct msgbuf_rx_complete *rx_complete;
1180 struct sk_buff *skb;
1181 u16 data_offset;
1182 u16 buflen;
1183 u16 flags;
1184 u32 idx;
1185 struct brcmf_if *ifp;
1186
1187 brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1);
1188
1189 rx_complete = (struct msgbuf_rx_complete *)buf;
1190 data_offset = le16_to_cpu(rx_complete->data_offset);
1191 buflen = le16_to_cpu(rx_complete->data_len);
1192 idx = le32_to_cpu(rx_complete->msg.request_id);
1193 flags = le16_to_cpu(rx_complete->flags);
1194
1195 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
1196 msgbuf->rx_pktids, idx);
1197 if (!skb)
1198 return;
1199
1200 if (data_offset)
1201 skb_pull(skb, data_offset);
1202 else if (msgbuf->rx_dataoffset)
1203 skb_pull(skb, msgbuf->rx_dataoffset);
1204
1205 skb_trim(skb, buflen);
1206
1207 if ((flags & BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK) ==
1208 BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_11) {
1209 ifp = msgbuf->drvr->mon_if;
1210
1211 if (!ifp) {
1212 bphy_err(drvr, "Received unexpected monitor pkt\n");
1213 brcmu_pkt_buf_free_skb(skb);
1214 return;
1215 }
1216
1217 brcmf_netif_mon_rx(ifp, skb);
1218 return;
1219 }
1220
1221 ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
1222 if (!ifp || !ifp->ndev) {
1223 bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
1224 rx_complete->msg.ifidx);
1225 brcmu_pkt_buf_free_skb(skb);
1226 return;
1227 }
1228
1229 skb->protocol = eth_type_trans(skb, ifp->ndev);
1230 brcmf_netif_rx(ifp, skb);
1231 }
1232
brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf * msgbuf,void * buf)1233 static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf,
1234 void *buf)
1235 {
1236 struct msgbuf_gen_status *gen_status = buf;
1237 struct brcmf_pub *drvr = msgbuf->drvr;
1238 int err;
1239
1240 err = le16_to_cpu(gen_status->compl_hdr.status);
1241 if (err)
1242 bphy_err(drvr, "Firmware reported general error: %d\n", err);
1243 }
1244
brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf * msgbuf,void * buf)1245 static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf,
1246 void *buf)
1247 {
1248 struct msgbuf_ring_status *ring_status = buf;
1249 struct brcmf_pub *drvr = msgbuf->drvr;
1250 int err;
1251
1252 err = le16_to_cpu(ring_status->compl_hdr.status);
1253 if (err) {
1254 int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id);
1255
1256 bphy_err(drvr, "Firmware reported ring %d error: %d\n", ring,
1257 err);
1258 }
1259 }
1260
1261 static void
brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf * msgbuf,void * buf)1262 brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
1263 void *buf)
1264 {
1265 struct brcmf_pub *drvr = msgbuf->drvr;
1266 struct msgbuf_flowring_create_resp *flowring_create_resp;
1267 u16 status;
1268 u16 flowid;
1269 u16 flow_ring_id;
1270
1271 flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
1272
1273 flow_ring_id = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
1274 status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
1275
1276 if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid))
1277 return;
1278
1279 if (status) {
1280 bphy_err(drvr, "Flowring creation failed, code %d\n", status);
1281 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1282 return;
1283 }
1284 brcmf_dbg(MSGBUF, "Flowring %d Create response status %d\n", flowid,
1285 status);
1286
1287 brcmf_flowring_open(msgbuf->flow, flowid);
1288
1289 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);
1290 }
1291
1292
1293 static void
brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf * msgbuf,void * buf)1294 brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
1295 void *buf)
1296 {
1297 struct brcmf_pub *drvr = msgbuf->drvr;
1298 struct msgbuf_flowring_delete_resp *flowring_delete_resp;
1299 u16 status;
1300 u16 flowid;
1301 u16 flow_ring_id;
1302
1303 flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
1304
1305 flow_ring_id = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
1306 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
1307
1308 if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid))
1309 return;
1310
1311 if (status) {
1312 bphy_err(drvr, "Flowring deletion failed, code %d\n", status);
1313 brcmf_flowring_delete(msgbuf->flow, flowid);
1314 return;
1315 }
1316 brcmf_dbg(MSGBUF, "Flowring %d Delete response status %d\n", flowid,
1317 status);
1318
1319 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1320 }
1321
1322
brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf * msgbuf,void * buf)1323 static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
1324 {
1325 struct brcmf_pub *drvr = msgbuf->drvr;
1326 struct msgbuf_common_hdr *msg;
1327
1328 msg = (struct msgbuf_common_hdr *)buf;
1329 switch (msg->msgtype) {
1330 case MSGBUF_TYPE_GEN_STATUS:
1331 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_GEN_STATUS\n");
1332 brcmf_msgbuf_process_gen_status(msgbuf, buf);
1333 break;
1334 case MSGBUF_TYPE_RING_STATUS:
1335 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n");
1336 brcmf_msgbuf_process_ring_status(msgbuf, buf);
1337 break;
1338 case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
1339 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n");
1340 brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);
1341 break;
1342 case MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT:
1343 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT\n");
1344 brcmf_msgbuf_process_flow_ring_delete_response(msgbuf, buf);
1345 break;
1346 case MSGBUF_TYPE_IOCTLPTR_REQ_ACK:
1347 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_IOCTLPTR_REQ_ACK\n");
1348 break;
1349 case MSGBUF_TYPE_IOCTL_CMPLT:
1350 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_IOCTL_CMPLT\n");
1351 brcmf_msgbuf_process_ioctl_complete(msgbuf, buf);
1352 break;
1353 case MSGBUF_TYPE_WL_EVENT:
1354 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_WL_EVENT\n");
1355 brcmf_msgbuf_process_event(msgbuf, buf);
1356 break;
1357 case MSGBUF_TYPE_TX_STATUS:
1358 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_TX_STATUS\n");
1359 brcmf_msgbuf_process_txstatus(msgbuf, buf);
1360 break;
1361 case MSGBUF_TYPE_RX_CMPLT:
1362 brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RX_CMPLT\n");
1363 brcmf_msgbuf_process_rx_complete(msgbuf, buf);
1364 break;
1365 default:
1366 bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype);
1367 break;
1368 }
1369 }
1370
1371
brcmf_msgbuf_process_rx(struct brcmf_msgbuf * msgbuf,struct brcmf_commonring * commonring)1372 static void brcmf_msgbuf_process_rx(struct brcmf_msgbuf *msgbuf,
1373 struct brcmf_commonring *commonring)
1374 {
1375 void *buf;
1376 u16 count;
1377 u16 processed;
1378
1379 again:
1380 buf = brcmf_commonring_get_read_ptr(commonring, &count);
1381 if (buf == NULL)
1382 return;
1383
1384 processed = 0;
1385 while (count) {
1386 brcmf_msgbuf_process_msgtype(msgbuf,
1387 buf + msgbuf->rx_dataoffset);
1388 buf += brcmf_commonring_len_item(commonring);
1389 processed++;
1390 if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) {
1391 brcmf_commonring_read_complete(commonring, processed);
1392 processed = 0;
1393 }
1394 count--;
1395 }
1396 if (processed)
1397 brcmf_commonring_read_complete(commonring, processed);
1398
1399 if (commonring->r_ptr == 0)
1400 goto again;
1401 }
1402
1403
brcmf_proto_msgbuf_rx_trigger(struct device * dev)1404 int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
1405 {
1406 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1407 struct brcmf_pub *drvr = bus_if->drvr;
1408 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1409 struct brcmf_commonring *commonring;
1410 void *buf;
1411 u32 flowid;
1412 int qlen;
1413
1414 buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
1415 brcmf_msgbuf_process_rx(msgbuf, buf);
1416 buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
1417 brcmf_msgbuf_process_rx(msgbuf, buf);
1418 buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
1419 brcmf_msgbuf_process_rx(msgbuf, buf);
1420
1421 for_each_set_bit(flowid, msgbuf->txstatus_done_map,
1422 msgbuf->max_flowrings) {
1423 clear_bit(flowid, msgbuf->txstatus_done_map);
1424 commonring = msgbuf->flowrings[flowid];
1425 qlen = brcmf_flowring_qlen(msgbuf->flow, flowid);
1426 if ((qlen > BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) ||
1427 ((qlen) && (atomic_read(&commonring->outstanding_tx) <
1428 BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS)))
1429 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);
1430 }
1431
1432 return 0;
1433 }
1434
1435
brcmf_msgbuf_delete_flowring(struct brcmf_pub * drvr,u16 flowid)1436 void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
1437 {
1438 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1439 struct msgbuf_tx_flowring_delete_req *delete;
1440 struct brcmf_commonring *commonring;
1441 struct brcmf_commonring *commonring_del = msgbuf->flowrings[flowid];
1442 struct brcmf_flowring *flow = msgbuf->flow;
1443 void *ret_ptr;
1444 u8 ifidx;
1445 int err;
1446 int retry = BRCMF_MAX_TXSTATUS_WAIT_RETRIES;
1447
1448 /* make sure it is not in txflow */
1449 brcmf_commonring_lock(commonring_del);
1450 flow->rings[flowid]->status = RING_CLOSING;
1451 brcmf_commonring_unlock(commonring_del);
1452
1453 /* wait for commonring txflow finished */
1454 while (retry && atomic_read(&commonring_del->outstanding_tx)) {
1455 usleep_range(5000, 10000);
1456 retry--;
1457 }
1458 if (!retry) {
1459 brcmf_err("timed out waiting for txstatus\n");
1460 atomic_set(&commonring_del->outstanding_tx, 0);
1461 }
1462
1463 /* no need to submit if firmware can not be reached */
1464 if (drvr->bus_if->state != BRCMF_BUS_UP) {
1465 brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n");
1466 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1467 return;
1468 }
1469
1470 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
1471 brcmf_commonring_lock(commonring);
1472 ret_ptr = brcmf_commonring_reserve_for_write(commonring);
1473 if (!ret_ptr) {
1474 bphy_err(drvr, "FW unaware, flowring will be removed !!\n");
1475 brcmf_commonring_unlock(commonring);
1476 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1477 return;
1478 }
1479
1480 delete = (struct msgbuf_tx_flowring_delete_req *)ret_ptr;
1481
1482 ifidx = brcmf_flowring_ifidx_get(msgbuf->flow, flowid);
1483
1484 delete->msg.msgtype = MSGBUF_TYPE_FLOW_RING_DELETE;
1485 delete->msg.ifidx = ifidx;
1486 delete->msg.request_id = 0;
1487
1488 delete->flow_ring_id = cpu_to_le16(flowid +
1489 BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
1490 delete->reason = 0;
1491
1492 brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n",
1493 flowid, ifidx);
1494
1495 err = brcmf_commonring_write_complete(commonring);
1496 brcmf_commonring_unlock(commonring);
1497 if (err) {
1498 bphy_err(drvr, "Failed to submit RING_DELETE, flowring will be removed\n");
1499 brcmf_msgbuf_remove_flowring(msgbuf, flowid);
1500 }
1501 }
1502
1503 #ifdef DEBUG
brcmf_msgbuf_stats_read(struct seq_file * seq,void * data)1504 static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
1505 {
1506 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
1507 struct brcmf_pub *drvr = bus_if->drvr;
1508 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1509 struct brcmf_commonring *commonring;
1510 u16 i;
1511 struct brcmf_flowring_ring *ring;
1512 struct brcmf_flowring_hash *hash;
1513
1514 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
1515 seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n",
1516 commonring->r_ptr, commonring->w_ptr, commonring->depth);
1517 commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
1518 seq_printf(seq, "h2d_rx_submit: rp %4u, wp %4u, depth %4u\n",
1519 commonring->r_ptr, commonring->w_ptr, commonring->depth);
1520 commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
1521 seq_printf(seq, "d2h_ctl_cmplt: rp %4u, wp %4u, depth %4u\n",
1522 commonring->r_ptr, commonring->w_ptr, commonring->depth);
1523 commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
1524 seq_printf(seq, "d2h_tx_cmplt: rp %4u, wp %4u, depth %4u\n",
1525 commonring->r_ptr, commonring->w_ptr, commonring->depth);
1526 commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
1527 seq_printf(seq, "d2h_rx_cmplt: rp %4u, wp %4u, depth %4u\n",
1528 commonring->r_ptr, commonring->w_ptr, commonring->depth);
1529
1530 seq_printf(seq, "\nh2d_flowrings: depth %u\n",
1531 BRCMF_H2D_TXFLOWRING_MAX_ITEM);
1532 seq_puts(seq, "Active flowrings:\n");
1533 for (i = 0; i < msgbuf->flow->nrofrings; i++) {
1534 if (!msgbuf->flow->rings[i])
1535 continue;
1536 ring = msgbuf->flow->rings[i];
1537 if (ring->status != RING_OPEN)
1538 continue;
1539 commonring = msgbuf->flowrings[i];
1540 hash = &msgbuf->flow->hash[ring->hash_id];
1541 seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n"
1542 " ifidx %u, fifo %u, da %pM\n",
1543 i, commonring->r_ptr, commonring->w_ptr,
1544 skb_queue_len(&ring->skblist), ring->blocked,
1545 hash->ifidx, hash->fifo, hash->mac);
1546 }
1547
1548 return 0;
1549 }
1550 #else
brcmf_msgbuf_stats_read(struct seq_file * seq,void * data)1551 static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
1552 {
1553 return 0;
1554 }
1555 #endif
1556
brcmf_msgbuf_debugfs_create(struct brcmf_pub * drvr)1557 static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr)
1558 {
1559 brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read);
1560 }
1561
brcmf_proto_msgbuf_attach(struct brcmf_pub * drvr)1562 int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1563 {
1564 struct brcmf_bus_msgbuf *if_msgbuf;
1565 struct brcmf_msgbuf *msgbuf;
1566 u64 address;
1567 u32 count;
1568
1569 if_msgbuf = drvr->bus_if->msgbuf;
1570
1571 if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
1572 bphy_err(drvr, "driver not configured for this many flowrings %d\n",
1573 if_msgbuf->max_flowrings);
1574 if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
1575 }
1576
1577 msgbuf = kzalloc_obj(*msgbuf);
1578 if (!msgbuf)
1579 goto fail;
1580
1581 msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow");
1582 if (msgbuf->txflow_wq == NULL) {
1583 bphy_err(drvr, "workqueue creation failed\n");
1584 goto fail;
1585 }
1586 INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);
1587 count = BITS_TO_LONGS(if_msgbuf->max_flowrings);
1588 count = count * sizeof(unsigned long);
1589 msgbuf->flow_map = kzalloc(count, GFP_KERNEL);
1590 if (!msgbuf->flow_map)
1591 goto fail;
1592
1593 msgbuf->txstatus_done_map = kzalloc(count, GFP_KERNEL);
1594 if (!msgbuf->txstatus_done_map)
1595 goto fail;
1596
1597 msgbuf->drvr = drvr;
1598 msgbuf->ioctbuf = dma_alloc_coherent(drvr->bus_if->dev,
1599 BRCMF_TX_IOCTL_MAX_MSG_SIZE,
1600 &msgbuf->ioctbuf_handle,
1601 GFP_KERNEL);
1602 if (!msgbuf->ioctbuf)
1603 goto fail;
1604 address = (u64)msgbuf->ioctbuf_handle;
1605 msgbuf->ioctbuf_phys_hi = address >> 32;
1606 msgbuf->ioctbuf_phys_lo = address & 0xffffffff;
1607
1608 drvr->proto->hdrpull = brcmf_msgbuf_hdrpull;
1609 drvr->proto->query_dcmd = brcmf_msgbuf_query_dcmd;
1610 drvr->proto->set_dcmd = brcmf_msgbuf_set_dcmd;
1611 drvr->proto->tx_queue_data = brcmf_msgbuf_tx_queue_data;
1612 drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode;
1613 drvr->proto->delete_peer = brcmf_msgbuf_delete_peer;
1614 drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer;
1615 drvr->proto->rxreorder = brcmf_msgbuf_rxreorder;
1616 drvr->proto->debugfs_create = brcmf_msgbuf_debugfs_create;
1617 drvr->proto->pd = msgbuf;
1618
1619 init_waitqueue_head(&msgbuf->ioctl_resp_wait);
1620
1621 msgbuf->commonrings =
1622 (struct brcmf_commonring **)if_msgbuf->commonrings;
1623 msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings;
1624 msgbuf->max_flowrings = if_msgbuf->max_flowrings;
1625 msgbuf->flowring_dma_handle =
1626 kzalloc_objs(*msgbuf->flowring_dma_handle,
1627 msgbuf->max_flowrings);
1628 if (!msgbuf->flowring_dma_handle)
1629 goto fail;
1630
1631 msgbuf->rx_dataoffset = if_msgbuf->rx_dataoffset;
1632 msgbuf->max_rxbufpost = if_msgbuf->max_rxbufpost;
1633
1634 msgbuf->max_ioctlrespbuf = BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST;
1635 msgbuf->max_eventbuf = BRCMF_MSGBUF_MAX_EVENTBUF_POST;
1636
1637 msgbuf->tx_pktids = brcmf_msgbuf_init_pktids(NR_TX_PKTIDS,
1638 DMA_TO_DEVICE);
1639 if (!msgbuf->tx_pktids)
1640 goto fail;
1641 msgbuf->rx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,
1642 DMA_FROM_DEVICE);
1643 if (!msgbuf->rx_pktids)
1644 goto fail;
1645
1646 msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev,
1647 if_msgbuf->max_flowrings);
1648 if (!msgbuf->flow)
1649 goto fail;
1650
1651
1652 brcmf_dbg(MSGBUF, "Feeding buffers, rx data %d, rx event %d, rx ioctl resp %d\n",
1653 msgbuf->max_rxbufpost, msgbuf->max_eventbuf,
1654 msgbuf->max_ioctlrespbuf);
1655 count = 0;
1656 do {
1657 brcmf_msgbuf_rxbuf_data_fill(msgbuf);
1658 if (msgbuf->max_rxbufpost != msgbuf->rxbufpost)
1659 msleep(10);
1660 else
1661 break;
1662 count++;
1663 } while (count < 10);
1664 brcmf_msgbuf_rxbuf_event_post(msgbuf);
1665 brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
1666
1667 INIT_WORK(&msgbuf->flowring_work, brcmf_msgbuf_flowring_worker);
1668 spin_lock_init(&msgbuf->flowring_work_lock);
1669 INIT_LIST_HEAD(&msgbuf->work_queue);
1670
1671 return 0;
1672
1673 fail:
1674 if (msgbuf) {
1675 kfree(msgbuf->flow_map);
1676 kfree(msgbuf->txstatus_done_map);
1677 brcmf_msgbuf_release_pktids(msgbuf);
1678 kfree(msgbuf->flowring_dma_handle);
1679 if (msgbuf->ioctbuf)
1680 dma_free_coherent(drvr->bus_if->dev,
1681 BRCMF_TX_IOCTL_MAX_MSG_SIZE,
1682 msgbuf->ioctbuf,
1683 msgbuf->ioctbuf_handle);
1684 if (msgbuf->txflow_wq)
1685 destroy_workqueue(msgbuf->txflow_wq);
1686 kfree(msgbuf);
1687 }
1688 return -ENOMEM;
1689 }
1690
1691
brcmf_proto_msgbuf_detach(struct brcmf_pub * drvr)1692 void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr)
1693 {
1694 struct brcmf_msgbuf *msgbuf;
1695 struct brcmf_msgbuf_work_item *work;
1696
1697 brcmf_dbg(TRACE, "Enter\n");
1698 if (drvr->proto->pd) {
1699 msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1700 cancel_work_sync(&msgbuf->flowring_work);
1701 while (!list_empty(&msgbuf->work_queue)) {
1702 work = list_first_entry(&msgbuf->work_queue,
1703 struct brcmf_msgbuf_work_item,
1704 queue);
1705 list_del(&work->queue);
1706 kfree(work);
1707 }
1708 kfree(msgbuf->flow_map);
1709 kfree(msgbuf->txstatus_done_map);
1710 if (msgbuf->txflow_wq)
1711 destroy_workqueue(msgbuf->txflow_wq);
1712
1713 brcmf_flowring_detach(msgbuf->flow);
1714 dma_free_coherent(drvr->bus_if->dev,
1715 BRCMF_TX_IOCTL_MAX_MSG_SIZE,
1716 msgbuf->ioctbuf, msgbuf->ioctbuf_handle);
1717 brcmf_msgbuf_release_pktids(msgbuf);
1718 kfree(msgbuf->flowring_dma_handle);
1719 kfree(msgbuf);
1720 drvr->proto->pd = NULL;
1721 }
1722 }
1723