diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 456944a6a2db..6262612dec45 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | |||
@@ -73,6 +73,8 @@ | |||
73 | #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 | 73 | #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 |
74 | #define BRCMF_MSGBUF_TX_FLUSH_CNT2 96 | 74 | #define BRCMF_MSGBUF_TX_FLUSH_CNT2 96 |
75 | 75 | ||
76 | #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 64 | ||
77 | #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 | ||
76 | 78 | ||
77 | struct msgbuf_common_hdr { | 79 | struct msgbuf_common_hdr { |
78 | u8 msgtype; | 80 | u8 msgtype; |
@@ -583,7 +585,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf, | |||
583 | u32 flowid; | 585 | u32 flowid; |
584 | void *dma_buf; | 586 | void *dma_buf; |
585 | u32 dma_sz; | 587 | u32 dma_sz; |
586 | long long address; | 588 | u64 address; |
587 | int err; | 589 | int err; |
588 | 590 | ||
589 | flowid = work->flowid; | 591 | flowid = work->flowid; |
@@ -620,7 +622,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf, | |||
620 | BRCMF_NROF_H2D_COMMON_MSGRINGS); | 622 | BRCMF_NROF_H2D_COMMON_MSGRINGS); |
621 | memcpy(create->sa, work->sa, ETH_ALEN); | 623 | memcpy(create->sa, work->sa, ETH_ALEN); |
622 | memcpy(create->da, work->da, ETH_ALEN); | 624 | memcpy(create->da, work->da, ETH_ALEN); |
623 | address = (long long)(long)msgbuf->flowring_dma_handle[flowid]; | 625 | address = (u64)msgbuf->flowring_dma_handle[flowid]; |
624 | create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32); | 626 | create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32); |
625 | create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff); | 627 | create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff); |
626 | create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM); | 628 | create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM); |
@@ -698,7 +700,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid) | |||
698 | dma_addr_t physaddr; | 700 | dma_addr_t physaddr; |
699 | u32 pktid; | 701 | u32 pktid; |
700 | struct msgbuf_tx_msghdr *tx_msghdr; | 702 | struct msgbuf_tx_msghdr *tx_msghdr; |
701 | long long address; | 703 | u64 address; |
702 | 704 | ||
703 | commonring = msgbuf->flowrings[flowid]; | 705 | commonring = msgbuf->flowrings[flowid]; |
704 | if (!brcmf_commonring_write_available(commonring)) | 706 | if (!brcmf_commonring_write_available(commonring)) |
@@ -742,13 +744,14 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid) | |||
742 | tx_msghdr->seg_cnt = 1; | 744 | tx_msghdr->seg_cnt = 1; |
743 | memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN); | 745 | memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN); |
744 | tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN); | 746 | tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN); |
745 | address = (long long)(long)physaddr; | 747 | address = (u64)physaddr; |
746 | tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32); | 748 | tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32); |
747 | tx_msghdr->data_buf_addr.low_addr = | 749 | tx_msghdr->data_buf_addr.low_addr = |
748 | cpu_to_le32(address & 0xffffffff); | 750 | cpu_to_le32(address & 0xffffffff); |
749 | tx_msghdr->metadata_buf_len = 0; | 751 | tx_msghdr->metadata_buf_len = 0; |
750 | tx_msghdr->metadata_buf_addr.high_addr = 0; | 752 | tx_msghdr->metadata_buf_addr.high_addr = 0; |
751 | tx_msghdr->metadata_buf_addr.low_addr = 0; | 753 | tx_msghdr->metadata_buf_addr.low_addr = 0; |
754 | atomic_inc(&commonring->outstanding_tx); | ||
752 | if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) { | 755 | if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) { |
753 | brcmf_commonring_write_complete(commonring); | 756 | brcmf_commonring_write_complete(commonring); |
754 | count = 0; | 757 | count = 0; |
@@ -773,10 +776,16 @@ static void brcmf_msgbuf_txflow_worker(struct work_struct *worker) | |||
773 | } | 776 | } |
774 | 777 | ||
775 | 778 | ||
776 | static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid) | 779 | static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid, |
780 | bool force) | ||
777 | { | 781 | { |
782 | struct brcmf_commonring *commonring; | ||
783 | |||
778 | set_bit(flowid, msgbuf->flow_map); | 784 | set_bit(flowid, msgbuf->flow_map); |
779 | queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work); | 785 | commonring = msgbuf->flowrings[flowid]; |
786 | if ((force) || (atomic_read(&commonring->outstanding_tx) < | ||
787 | BRCMF_MSGBUF_DELAY_TXWORKER_THRS)) | ||
788 | queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work); | ||
780 | 789 | ||
781 | return 0; | 790 | return 0; |
782 | } | 791 | } |
@@ -797,7 +806,7 @@ static int brcmf_msgbuf_txdata(struct brcmf_pub *drvr, int ifidx, | |||
797 | return -ENOMEM; | 806 | return -ENOMEM; |
798 | } | 807 | } |
799 | brcmf_flowring_enqueue(flow, flowid, skb); | 808 | brcmf_flowring_enqueue(flow, flowid, skb); |
800 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid); | 809 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid, false); |
801 | 810 | ||
802 | return 0; | 811 | return 0; |
803 | } | 812 | } |
@@ -854,6 +863,7 @@ brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf) | |||
854 | static void | 863 | static void |
855 | brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) | 864 | brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) |
856 | { | 865 | { |
866 | struct brcmf_commonring *commonring; | ||
857 | struct msgbuf_tx_status *tx_status; | 867 | struct msgbuf_tx_status *tx_status; |
858 | u32 idx; | 868 | u32 idx; |
859 | struct sk_buff *skb; | 869 | struct sk_buff *skb; |
@@ -871,6 +881,8 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) | |||
871 | } | 881 | } |
872 | 882 | ||
873 | set_bit(flowid, msgbuf->txstatus_done_map); | 883 | set_bit(flowid, msgbuf->txstatus_done_map); |
884 | commonring = msgbuf->flowrings[flowid]; | ||
885 | atomic_dec(&commonring->outstanding_tx); | ||
874 | 886 | ||
875 | brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true); | 887 | brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true); |
876 | } | 888 | } |
@@ -885,7 +897,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) | |||
885 | u32 pktlen; | 897 | u32 pktlen; |
886 | dma_addr_t physaddr; | 898 | dma_addr_t physaddr; |
887 | struct msgbuf_rx_bufpost *rx_bufpost; | 899 | struct msgbuf_rx_bufpost *rx_bufpost; |
888 | long long address; | 900 | u64 address; |
889 | u32 pktid; | 901 | u32 pktid; |
890 | u32 i; | 902 | u32 i; |
891 | 903 | ||
@@ -894,7 +906,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) | |||
894 | count, | 906 | count, |
895 | &alloced); | 907 | &alloced); |
896 | if (!ret_ptr) { | 908 | if (!ret_ptr) { |
897 | brcmf_err("Failed to reserve space in commonring\n"); | 909 | brcmf_dbg(MSGBUF, "Failed to reserve space in commonring\n"); |
898 | return 0; | 910 | return 0; |
899 | } | 911 | } |
900 | 912 | ||
@@ -921,7 +933,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) | |||
921 | } | 933 | } |
922 | 934 | ||
923 | if (msgbuf->rx_metadata_offset) { | 935 | if (msgbuf->rx_metadata_offset) { |
924 | address = (long long)(long)physaddr; | 936 | address = (u64)physaddr; |
925 | rx_bufpost->metadata_buf_len = | 937 | rx_bufpost->metadata_buf_len = |
926 | cpu_to_le16(msgbuf->rx_metadata_offset); | 938 | cpu_to_le16(msgbuf->rx_metadata_offset); |
927 | rx_bufpost->metadata_buf_addr.high_addr = | 939 | rx_bufpost->metadata_buf_addr.high_addr = |
@@ -936,7 +948,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) | |||
936 | rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST; | 948 | rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST; |
937 | rx_bufpost->msg.request_id = cpu_to_le32(pktid); | 949 | rx_bufpost->msg.request_id = cpu_to_le32(pktid); |
938 | 950 | ||
939 | address = (long long)(long)physaddr; | 951 | address = (u64)physaddr; |
940 | rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen); | 952 | rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen); |
941 | rx_bufpost->data_buf_addr.high_addr = | 953 | rx_bufpost->data_buf_addr.high_addr = |
942 | cpu_to_le32(address >> 32); | 954 | cpu_to_le32(address >> 32); |
@@ -992,7 +1004,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf, | |||
992 | u32 pktlen; | 1004 | u32 pktlen; |
993 | dma_addr_t physaddr; | 1005 | dma_addr_t physaddr; |
994 | struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost; | 1006 | struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost; |
995 | long long address; | 1007 | u64 address; |
996 | u32 pktid; | 1008 | u32 pktid; |
997 | u32 i; | 1009 | u32 i; |
998 | 1010 | ||
@@ -1035,7 +1047,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf, | |||
1035 | MSGBUF_TYPE_IOCTLRESP_BUF_POST; | 1047 | MSGBUF_TYPE_IOCTLRESP_BUF_POST; |
1036 | rx_bufpost->msg.request_id = cpu_to_le32(pktid); | 1048 | rx_bufpost->msg.request_id = cpu_to_le32(pktid); |
1037 | 1049 | ||
1038 | address = (long long)(long)physaddr; | 1050 | address = (u64)physaddr; |
1039 | rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen); | 1051 | rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen); |
1040 | rx_bufpost->host_buf_addr.high_addr = | 1052 | rx_bufpost->host_buf_addr.high_addr = |
1041 | cpu_to_le32(address >> 32); | 1053 | cpu_to_le32(address >> 32); |
@@ -1181,7 +1193,7 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, | |||
1181 | 1193 | ||
1182 | brcmf_flowring_open(msgbuf->flow, flowid); | 1194 | brcmf_flowring_open(msgbuf->flow, flowid); |
1183 | 1195 | ||
1184 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid); | 1196 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true); |
1185 | } | 1197 | } |
1186 | 1198 | ||
1187 | 1199 | ||
@@ -1280,8 +1292,10 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev) | |||
1280 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 1292 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
1281 | struct brcmf_pub *drvr = bus_if->drvr; | 1293 | struct brcmf_pub *drvr = bus_if->drvr; |
1282 | struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; | 1294 | struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; |
1295 | struct brcmf_commonring *commonring; | ||
1283 | void *buf; | 1296 | void *buf; |
1284 | u32 flowid; | 1297 | u32 flowid; |
1298 | int qlen; | ||
1285 | 1299 | ||
1286 | buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE]; | 1300 | buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE]; |
1287 | brcmf_msgbuf_process_rx(msgbuf, buf); | 1301 | brcmf_msgbuf_process_rx(msgbuf, buf); |
@@ -1293,8 +1307,12 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev) | |||
1293 | for_each_set_bit(flowid, msgbuf->txstatus_done_map, | 1307 | for_each_set_bit(flowid, msgbuf->txstatus_done_map, |
1294 | msgbuf->nrof_flowrings) { | 1308 | msgbuf->nrof_flowrings) { |
1295 | clear_bit(flowid, msgbuf->txstatus_done_map); | 1309 | clear_bit(flowid, msgbuf->txstatus_done_map); |
1296 | if (brcmf_flowring_qlen(msgbuf->flow, flowid)) | 1310 | commonring = msgbuf->flowrings[flowid]; |
1297 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid); | 1311 | qlen = brcmf_flowring_qlen(msgbuf->flow, flowid); |
1312 | if ((qlen > BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) || | ||
1313 | ((qlen) && (atomic_read(&commonring->outstanding_tx) < | ||
1314 | BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS))) | ||
1315 | brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true); | ||
1298 | } | 1316 | } |
1299 | 1317 | ||
1300 | return 0; | 1318 | return 0; |
@@ -1348,7 +1366,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) | |||
1348 | { | 1366 | { |
1349 | struct brcmf_bus_msgbuf *if_msgbuf; | 1367 | struct brcmf_bus_msgbuf *if_msgbuf; |
1350 | struct brcmf_msgbuf *msgbuf; | 1368 | struct brcmf_msgbuf *msgbuf; |
1351 | long long address; | 1369 | u64 address; |
1352 | u32 count; | 1370 | u32 count; |
1353 | 1371 | ||
1354 | if_msgbuf = drvr->bus_if->msgbuf; | 1372 | if_msgbuf = drvr->bus_if->msgbuf; |
@@ -1379,7 +1397,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) | |||
1379 | GFP_KERNEL); | 1397 | GFP_KERNEL); |
1380 | if (!msgbuf->ioctbuf) | 1398 | if (!msgbuf->ioctbuf) |
1381 | goto fail; | 1399 | goto fail; |
1382 | address = (long long)(long)msgbuf->ioctbuf_handle; | 1400 | address = (u64)msgbuf->ioctbuf_handle; |
1383 | msgbuf->ioctbuf_phys_hi = address >> 32; | 1401 | msgbuf->ioctbuf_phys_hi = address >> 32; |
1384 | msgbuf->ioctbuf_phys_lo = address & 0xffffffff; | 1402 | msgbuf->ioctbuf_phys_lo = address & 0xffffffff; |
1385 | 1403 | ||