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