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