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