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