diff options
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.c | 334 |
1 files changed, 250 insertions, 84 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 0b0975d88b43..c8c547457eb4 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -104,6 +104,23 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | |||
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
107 | static void wil_txdesc_unmap(struct device *dev, struct vring_tx_desc *d, | ||
108 | struct wil_ctx *ctx) | ||
109 | { | ||
110 | dma_addr_t pa = wil_desc_addr(&d->dma.addr); | ||
111 | u16 dmalen = le16_to_cpu(d->dma.length); | ||
112 | switch (ctx->mapped_as) { | ||
113 | case wil_mapped_as_single: | ||
114 | dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); | ||
115 | break; | ||
116 | case wil_mapped_as_page: | ||
117 | dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE); | ||
118 | break; | ||
119 | default: | ||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | |||
107 | static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, | 124 | static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, |
108 | int tx) | 125 | int tx) |
109 | { | 126 | { |
@@ -122,15 +139,7 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, | |||
122 | 139 | ||
123 | ctx = &vring->ctx[vring->swtail]; | 140 | ctx = &vring->ctx[vring->swtail]; |
124 | *d = *_d; | 141 | *d = *_d; |
125 | pa = wil_desc_addr(&d->dma.addr); | 142 | wil_txdesc_unmap(dev, d, ctx); |
126 | dmalen = le16_to_cpu(d->dma.length); | ||
127 | if (vring->ctx[vring->swtail].mapped_as_page) { | ||
128 | dma_unmap_page(dev, pa, dmalen, | ||
129 | DMA_TO_DEVICE); | ||
130 | } else { | ||
131 | dma_unmap_single(dev, pa, dmalen, | ||
132 | DMA_TO_DEVICE); | ||
133 | } | ||
134 | if (ctx->skb) | 143 | if (ctx->skb) |
135 | dev_kfree_skb_any(ctx->skb); | 144 | dev_kfree_skb_any(ctx->skb); |
136 | vring->swtail = wil_vring_next_tail(vring); | 145 | vring->swtail = wil_vring_next_tail(vring); |
@@ -344,6 +353,9 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
344 | u16 dmalen; | 353 | u16 dmalen; |
345 | u8 ftype; | 354 | u8 ftype; |
346 | u8 ds_bits; | 355 | u8 ds_bits; |
356 | int cid; | ||
357 | struct wil_net_stats *stats; | ||
358 | |||
347 | 359 | ||
348 | BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); | 360 | BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); |
349 | 361 | ||
@@ -383,8 +395,10 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
383 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, | 395 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, |
384 | skb->data, skb_headlen(skb), false); | 396 | skb->data, skb_headlen(skb), false); |
385 | 397 | ||
386 | 398 | cid = wil_rxdesc_cid(d); | |
387 | wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); | 399 | stats = &wil->sta[cid].stats; |
400 | stats->last_mcs_rx = wil_rxdesc_mcs(d); | ||
401 | wil->stats.last_mcs_rx = stats->last_mcs_rx; | ||
388 | 402 | ||
389 | /* use radiotap header only if required */ | 403 | /* use radiotap header only if required */ |
390 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) | 404 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) |
@@ -472,21 +486,28 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count) | |||
472 | * Pass Rx packet to the netif. Update statistics. | 486 | * Pass Rx packet to the netif. Update statistics. |
473 | * Called in softirq context (NAPI poll). | 487 | * Called in softirq context (NAPI poll). |
474 | */ | 488 | */ |
475 | static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | 489 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) |
476 | { | 490 | { |
477 | int rc; | 491 | gro_result_t rc; |
492 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
478 | unsigned int len = skb->len; | 493 | unsigned int len = skb->len; |
494 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); | ||
495 | int cid = wil_rxdesc_cid(d); | ||
496 | struct wil_net_stats *stats = &wil->sta[cid].stats; | ||
479 | 497 | ||
480 | skb_orphan(skb); | 498 | skb_orphan(skb); |
481 | 499 | ||
482 | rc = netif_receive_skb(skb); | 500 | rc = napi_gro_receive(&wil->napi_rx, skb); |
483 | 501 | ||
484 | if (likely(rc == NET_RX_SUCCESS)) { | 502 | if (unlikely(rc == GRO_DROP)) { |
503 | ndev->stats.rx_dropped++; | ||
504 | stats->rx_dropped++; | ||
505 | wil_dbg_txrx(wil, "Rx drop %d bytes\n", len); | ||
506 | } else { | ||
485 | ndev->stats.rx_packets++; | 507 | ndev->stats.rx_packets++; |
508 | stats->rx_packets++; | ||
486 | ndev->stats.rx_bytes += len; | 509 | ndev->stats.rx_bytes += len; |
487 | 510 | stats->rx_bytes += len; | |
488 | } else { | ||
489 | ndev->stats.rx_dropped++; | ||
490 | } | 511 | } |
491 | } | 512 | } |
492 | 513 | ||
@@ -515,12 +536,18 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota) | |||
515 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 536 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
516 | skb->pkt_type = PACKET_OTHERHOST; | 537 | skb->pkt_type = PACKET_OTHERHOST; |
517 | skb->protocol = htons(ETH_P_802_2); | 538 | skb->protocol = htons(ETH_P_802_2); |
518 | 539 | wil_netif_rx_any(skb, ndev); | |
519 | } else { | 540 | } else { |
541 | struct ethhdr *eth = (void *)skb->data; | ||
542 | |||
520 | skb->protocol = eth_type_trans(skb, ndev); | 543 | skb->protocol = eth_type_trans(skb, ndev); |
544 | |||
545 | if (is_unicast_ether_addr(eth->h_dest)) | ||
546 | wil_rx_reorder(wil, skb); | ||
547 | else | ||
548 | wil_netif_rx_any(skb, ndev); | ||
521 | } | 549 | } |
522 | 550 | ||
523 | wil_netif_rx_any(skb, ndev); | ||
524 | } | 551 | } |
525 | wil_rx_refill(wil, v->size); | 552 | wil_rx_refill(wil, v->size); |
526 | } | 553 | } |
@@ -530,6 +557,11 @@ int wil_rx_init(struct wil6210_priv *wil) | |||
530 | struct vring *vring = &wil->vring_rx; | 557 | struct vring *vring = &wil->vring_rx; |
531 | int rc; | 558 | int rc; |
532 | 559 | ||
560 | if (vring->va) { | ||
561 | wil_err(wil, "Rx ring already allocated\n"); | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
533 | vring->size = WIL6210_RX_RING_SIZE; | 565 | vring->size = WIL6210_RX_RING_SIZE; |
534 | rc = wil_vring_alloc(wil, vring); | 566 | rc = wil_vring_alloc(wil, vring); |
535 | if (rc) | 567 | if (rc) |
@@ -570,7 +602,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
570 | .ring_size = cpu_to_le16(size), | 602 | .ring_size = cpu_to_le16(size), |
571 | }, | 603 | }, |
572 | .ringid = id, | 604 | .ringid = id, |
573 | .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), | 605 | .cidxtid = mk_cidxtid(cid, tid), |
574 | .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, | 606 | .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, |
575 | .mac_ctrl = 0, | 607 | .mac_ctrl = 0, |
576 | .to_resolution = 0, | 608 | .to_resolution = 0, |
@@ -586,6 +618,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
586 | struct wmi_vring_cfg_done_event cmd; | 618 | struct wmi_vring_cfg_done_event cmd; |
587 | } __packed reply; | 619 | } __packed reply; |
588 | struct vring *vring = &wil->vring_tx[id]; | 620 | struct vring *vring = &wil->vring_tx[id]; |
621 | struct vring_tx_data *txdata = &wil->vring_tx_data[id]; | ||
589 | 622 | ||
590 | if (vring->va) { | 623 | if (vring->va) { |
591 | wil_err(wil, "Tx ring [%d] already allocated\n", id); | 624 | wil_err(wil, "Tx ring [%d] already allocated\n", id); |
@@ -593,11 +626,15 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
593 | goto out; | 626 | goto out; |
594 | } | 627 | } |
595 | 628 | ||
629 | memset(txdata, 0, sizeof(*txdata)); | ||
596 | vring->size = size; | 630 | vring->size = size; |
597 | rc = wil_vring_alloc(wil, vring); | 631 | rc = wil_vring_alloc(wil, vring); |
598 | if (rc) | 632 | if (rc) |
599 | goto out; | 633 | goto out; |
600 | 634 | ||
635 | wil->vring2cid_tid[id][0] = cid; | ||
636 | wil->vring2cid_tid[id][1] = tid; | ||
637 | |||
601 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); | 638 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
602 | 639 | ||
603 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), | 640 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), |
@@ -613,6 +650,8 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
613 | } | 650 | } |
614 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); | 651 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); |
615 | 652 | ||
653 | txdata->enabled = 1; | ||
654 | |||
616 | return 0; | 655 | return 0; |
617 | out_free: | 656 | out_free: |
618 | wil_vring_free(wil, vring, 1); | 657 | wil_vring_free(wil, vring, 1); |
@@ -625,23 +664,116 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id) | |||
625 | { | 664 | { |
626 | struct vring *vring = &wil->vring_tx[id]; | 665 | struct vring *vring = &wil->vring_tx[id]; |
627 | 666 | ||
667 | WARN_ON(!mutex_is_locked(&wil->mutex)); | ||
668 | |||
628 | if (!vring->va) | 669 | if (!vring->va) |
629 | return; | 670 | return; |
630 | 671 | ||
672 | /* make sure NAPI won't touch this vring */ | ||
673 | wil->vring_tx_data[id].enabled = 0; | ||
674 | if (test_bit(wil_status_napi_en, &wil->status)) | ||
675 | napi_synchronize(&wil->napi_tx); | ||
676 | |||
631 | wil_vring_free(wil, vring, 1); | 677 | wil_vring_free(wil, vring, 1); |
632 | } | 678 | } |
633 | 679 | ||
634 | static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, | 680 | static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, |
635 | struct sk_buff *skb) | 681 | struct sk_buff *skb) |
636 | { | 682 | { |
637 | struct vring *v = &wil->vring_tx[0]; | 683 | int i; |
684 | struct ethhdr *eth = (void *)skb->data; | ||
685 | int cid = wil_find_cid(wil, eth->h_dest); | ||
686 | |||
687 | if (cid < 0) | ||
688 | return NULL; | ||
638 | 689 | ||
639 | if (v->va) | 690 | if (!wil->sta[cid].data_port_open && |
640 | return v; | 691 | (skb->protocol != cpu_to_be16(ETH_P_PAE))) |
692 | return NULL; | ||
693 | |||
694 | /* TODO: fix for multiple TID */ | ||
695 | for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) { | ||
696 | if (wil->vring2cid_tid[i][0] == cid) { | ||
697 | struct vring *v = &wil->vring_tx[i]; | ||
698 | wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n", | ||
699 | __func__, eth->h_dest, i); | ||
700 | if (v->va) { | ||
701 | return v; | ||
702 | } else { | ||
703 | wil_dbg_txrx(wil, "vring[%d] not valid\n", i); | ||
704 | return NULL; | ||
705 | } | ||
706 | } | ||
707 | } | ||
641 | 708 | ||
642 | return NULL; | 709 | return NULL; |
643 | } | 710 | } |
644 | 711 | ||
712 | static void wil_set_da_for_vring(struct wil6210_priv *wil, | ||
713 | struct sk_buff *skb, int vring_index) | ||
714 | { | ||
715 | struct ethhdr *eth = (void *)skb->data; | ||
716 | int cid = wil->vring2cid_tid[vring_index][0]; | ||
717 | memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN); | ||
718 | } | ||
719 | |||
720 | static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | ||
721 | struct sk_buff *skb); | ||
722 | /* | ||
723 | * Find 1-st vring and return it; set dest address for this vring in skb | ||
724 | * duplicate skb and send it to other active vrings | ||
725 | */ | ||
726 | static struct vring *wil_tx_bcast(struct wil6210_priv *wil, | ||
727 | struct sk_buff *skb) | ||
728 | { | ||
729 | struct vring *v, *v2; | ||
730 | struct sk_buff *skb2; | ||
731 | int i; | ||
732 | u8 cid; | ||
733 | |||
734 | /* find 1-st vring eligible for data */ | ||
735 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { | ||
736 | v = &wil->vring_tx[i]; | ||
737 | if (!v->va) | ||
738 | continue; | ||
739 | |||
740 | cid = wil->vring2cid_tid[i][0]; | ||
741 | if (!wil->sta[cid].data_port_open) | ||
742 | continue; | ||
743 | |||
744 | goto found; | ||
745 | } | ||
746 | |||
747 | wil_err(wil, "Tx while no vrings active?\n"); | ||
748 | |||
749 | return NULL; | ||
750 | |||
751 | found: | ||
752 | wil_dbg_txrx(wil, "BCAST -> ring %d\n", i); | ||
753 | wil_set_da_for_vring(wil, skb, i); | ||
754 | |||
755 | /* find other active vrings and duplicate skb for each */ | ||
756 | for (i++; i < WIL6210_MAX_TX_RINGS; i++) { | ||
757 | v2 = &wil->vring_tx[i]; | ||
758 | if (!v2->va) | ||
759 | continue; | ||
760 | cid = wil->vring2cid_tid[i][0]; | ||
761 | if (!wil->sta[cid].data_port_open) | ||
762 | continue; | ||
763 | |||
764 | skb2 = skb_copy(skb, GFP_ATOMIC); | ||
765 | if (skb2) { | ||
766 | wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); | ||
767 | wil_set_da_for_vring(wil, skb2, i); | ||
768 | wil_tx_vring(wil, v2, skb2); | ||
769 | } else { | ||
770 | wil_err(wil, "skb_copy failed\n"); | ||
771 | } | ||
772 | } | ||
773 | |||
774 | return v; | ||
775 | } | ||
776 | |||
645 | static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, | 777 | static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, |
646 | int vring_index) | 778 | int vring_index) |
647 | { | 779 | { |
@@ -667,6 +799,13 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, | |||
667 | return 0; | 799 | return 0; |
668 | } | 800 | } |
669 | 801 | ||
802 | static inline | ||
803 | void wil_tx_desc_set_nr_frags(struct vring_tx_desc *d, int nr_frags) | ||
804 | { | ||
805 | d->mac.d[2] |= ((nr_frags + 1) << | ||
806 | MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); | ||
807 | } | ||
808 | |||
670 | static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, | 809 | static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, |
671 | struct vring_tx_desc *d, | 810 | struct vring_tx_desc *d, |
672 | struct sk_buff *skb) | 811 | struct sk_buff *skb) |
@@ -731,8 +870,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
731 | 870 | ||
732 | wil_dbg_txrx(wil, "%s()\n", __func__); | 871 | wil_dbg_txrx(wil, "%s()\n", __func__); |
733 | 872 | ||
734 | if (avail < vring->size/8) | ||
735 | netif_tx_stop_all_queues(wil_to_ndev(wil)); | ||
736 | if (avail < 1 + nr_frags) { | 873 | if (avail < 1 + nr_frags) { |
737 | wil_err(wil, "Tx ring full. No space for %d fragments\n", | 874 | wil_err(wil, "Tx ring full. No space for %d fragments\n", |
738 | 1 + nr_frags); | 875 | 1 + nr_frags); |
@@ -740,9 +877,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
740 | } | 877 | } |
741 | _d = &(vring->va[i].tx); | 878 | _d = &(vring->va[i].tx); |
742 | 879 | ||
743 | /* FIXME FW can accept only unicast frames for the peer */ | ||
744 | memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN); | ||
745 | |||
746 | pa = dma_map_single(dev, skb->data, | 880 | pa = dma_map_single(dev, skb->data, |
747 | skb_headlen(skb), DMA_TO_DEVICE); | 881 | skb_headlen(skb), DMA_TO_DEVICE); |
748 | 882 | ||
@@ -753,6 +887,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
753 | 887 | ||
754 | if (unlikely(dma_mapping_error(dev, pa))) | 888 | if (unlikely(dma_mapping_error(dev, pa))) |
755 | return -EINVAL; | 889 | return -EINVAL; |
890 | vring->ctx[i].mapped_as = wil_mapped_as_single; | ||
756 | /* 1-st segment */ | 891 | /* 1-st segment */ |
757 | wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); | 892 | wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); |
758 | /* Process TCP/UDP checksum offloading */ | 893 | /* Process TCP/UDP checksum offloading */ |
@@ -762,8 +897,8 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
762 | goto dma_error; | 897 | goto dma_error; |
763 | } | 898 | } |
764 | 899 | ||
765 | d->mac.d[2] |= ((nr_frags + 1) << | 900 | vring->ctx[i].nr_frags = nr_frags; |
766 | MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); | 901 | wil_tx_desc_set_nr_frags(d, nr_frags); |
767 | if (nr_frags) | 902 | if (nr_frags) |
768 | *_d = *d; | 903 | *_d = *d; |
769 | 904 | ||
@@ -778,8 +913,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
778 | DMA_TO_DEVICE); | 913 | DMA_TO_DEVICE); |
779 | if (unlikely(dma_mapping_error(dev, pa))) | 914 | if (unlikely(dma_mapping_error(dev, pa))) |
780 | goto dma_error; | 915 | goto dma_error; |
916 | vring->ctx[i].mapped_as = wil_mapped_as_page; | ||
781 | wil_tx_desc_map(d, pa, len, vring_index); | 917 | wil_tx_desc_map(d, pa, len, vring_index); |
782 | vring->ctx[i].mapped_as_page = 1; | 918 | /* no need to check return code - |
919 | * if it succeeded for 1-st descriptor, | ||
920 | * it will succeed here too | ||
921 | */ | ||
922 | wil_tx_desc_offload_cksum_set(wil, d, skb); | ||
783 | *_d = *d; | 923 | *_d = *d; |
784 | } | 924 | } |
785 | /* for the last seg only */ | 925 | /* for the last seg only */ |
@@ -808,7 +948,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
808 | /* unmap what we have mapped */ | 948 | /* unmap what we have mapped */ |
809 | nr_frags = f + 1; /* frags mapped + one for skb head */ | 949 | nr_frags = f + 1; /* frags mapped + one for skb head */ |
810 | for (f = 0; f < nr_frags; f++) { | 950 | for (f = 0; f < nr_frags; f++) { |
811 | u16 dmalen; | ||
812 | struct wil_ctx *ctx; | 951 | struct wil_ctx *ctx; |
813 | 952 | ||
814 | i = (swhead + f) % vring->size; | 953 | i = (swhead + f) % vring->size; |
@@ -816,12 +955,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
816 | _d = &(vring->va[i].tx); | 955 | _d = &(vring->va[i].tx); |
817 | *d = *_d; | 956 | *d = *_d; |
818 | _d->dma.status = TX_DMA_STATUS_DU; | 957 | _d->dma.status = TX_DMA_STATUS_DU; |
819 | pa = wil_desc_addr(&d->dma.addr); | 958 | wil_txdesc_unmap(dev, d, ctx); |
820 | dmalen = le16_to_cpu(d->dma.length); | ||
821 | if (ctx->mapped_as_page) | ||
822 | dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE); | ||
823 | else | ||
824 | dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); | ||
825 | 959 | ||
826 | if (ctx->skb) | 960 | if (ctx->skb) |
827 | dev_kfree_skb_any(ctx->skb); | 961 | dev_kfree_skb_any(ctx->skb); |
@@ -836,12 +970,17 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
836 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 970 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
837 | { | 971 | { |
838 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 972 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
973 | struct ethhdr *eth = (void *)skb->data; | ||
839 | struct vring *vring; | 974 | struct vring *vring; |
975 | static bool pr_once_fw; | ||
840 | int rc; | 976 | int rc; |
841 | 977 | ||
842 | wil_dbg_txrx(wil, "%s()\n", __func__); | 978 | wil_dbg_txrx(wil, "%s()\n", __func__); |
843 | if (!test_bit(wil_status_fwready, &wil->status)) { | 979 | if (!test_bit(wil_status_fwready, &wil->status)) { |
844 | wil_err(wil, "FW not ready\n"); | 980 | if (!pr_once_fw) { |
981 | wil_err(wil, "FW not ready\n"); | ||
982 | pr_once_fw = true; | ||
983 | } | ||
845 | goto drop; | 984 | goto drop; |
846 | } | 985 | } |
847 | if (!test_bit(wil_status_fwconnected, &wil->status)) { | 986 | if (!test_bit(wil_status_fwconnected, &wil->status)) { |
@@ -852,16 +991,25 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
852 | wil_err(wil, "Xmit in monitor mode not supported\n"); | 991 | wil_err(wil, "Xmit in monitor mode not supported\n"); |
853 | goto drop; | 992 | goto drop; |
854 | } | 993 | } |
994 | pr_once_fw = false; | ||
855 | 995 | ||
856 | /* find vring */ | 996 | /* find vring */ |
857 | vring = wil_find_tx_vring(wil, skb); | 997 | if (is_unicast_ether_addr(eth->h_dest)) { |
998 | vring = wil_find_tx_vring(wil, skb); | ||
999 | } else { | ||
1000 | vring = wil_tx_bcast(wil, skb); | ||
1001 | } | ||
858 | if (!vring) { | 1002 | if (!vring) { |
859 | wil_err(wil, "No Tx VRING available\n"); | 1003 | wil_err(wil, "No Tx VRING found for %pM\n", eth->h_dest); |
860 | goto drop; | 1004 | goto drop; |
861 | } | 1005 | } |
862 | /* set up vring entry */ | 1006 | /* set up vring entry */ |
863 | rc = wil_tx_vring(wil, vring, skb); | 1007 | rc = wil_tx_vring(wil, vring, skb); |
864 | 1008 | ||
1009 | /* do we still have enough room in the vring? */ | ||
1010 | if (wil_vring_avail_tx(vring) < vring->size/8) | ||
1011 | netif_tx_stop_all_queues(wil_to_ndev(wil)); | ||
1012 | |||
865 | switch (rc) { | 1013 | switch (rc) { |
866 | case 0: | 1014 | case 0: |
867 | /* statistics will be updated on the tx_complete */ | 1015 | /* statistics will be updated on the tx_complete */ |
@@ -891,64 +1039,82 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
891 | struct net_device *ndev = wil_to_ndev(wil); | 1039 | struct net_device *ndev = wil_to_ndev(wil); |
892 | struct device *dev = wil_to_dev(wil); | 1040 | struct device *dev = wil_to_dev(wil); |
893 | struct vring *vring = &wil->vring_tx[ringid]; | 1041 | struct vring *vring = &wil->vring_tx[ringid]; |
1042 | struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; | ||
894 | int done = 0; | 1043 | int done = 0; |
1044 | int cid = wil->vring2cid_tid[ringid][0]; | ||
1045 | struct wil_net_stats *stats = &wil->sta[cid].stats; | ||
1046 | volatile struct vring_tx_desc *_d; | ||
895 | 1047 | ||
896 | if (!vring->va) { | 1048 | if (!vring->va) { |
897 | wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); | 1049 | wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); |
898 | return 0; | 1050 | return 0; |
899 | } | 1051 | } |
900 | 1052 | ||
1053 | if (!txdata->enabled) { | ||
1054 | wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid); | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
901 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); | 1058 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); |
902 | 1059 | ||
903 | while (!wil_vring_is_empty(vring)) { | 1060 | while (!wil_vring_is_empty(vring)) { |
904 | volatile struct vring_tx_desc *_d = | 1061 | int new_swtail; |
905 | &vring->va[vring->swtail].tx; | ||
906 | struct vring_tx_desc dd, *d = ⅆ | ||
907 | dma_addr_t pa; | ||
908 | u16 dmalen; | ||
909 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; | 1062 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; |
910 | struct sk_buff *skb = ctx->skb; | 1063 | /** |
911 | 1064 | * For the fragmented skb, HW will set DU bit only for the | |
912 | *d = *_d; | 1065 | * last fragment. look for it |
1066 | */ | ||
1067 | int lf = (vring->swtail + ctx->nr_frags) % vring->size; | ||
1068 | /* TODO: check we are not past head */ | ||
913 | 1069 | ||
914 | if (!(d->dma.status & TX_DMA_STATUS_DU)) | 1070 | _d = &vring->va[lf].tx; |
1071 | if (!(_d->dma.status & TX_DMA_STATUS_DU)) | ||
915 | break; | 1072 | break; |
916 | 1073 | ||
917 | dmalen = le16_to_cpu(d->dma.length); | 1074 | new_swtail = (lf + 1) % vring->size; |
918 | trace_wil6210_tx_done(ringid, vring->swtail, dmalen, | 1075 | while (vring->swtail != new_swtail) { |
919 | d->dma.error); | 1076 | struct vring_tx_desc dd, *d = ⅆ |
920 | wil_dbg_txrx(wil, | 1077 | u16 dmalen; |
921 | "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", | 1078 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; |
922 | vring->swtail, dmalen, d->dma.status, | 1079 | struct sk_buff *skb = ctx->skb; |
923 | d->dma.error); | 1080 | _d = &vring->va[vring->swtail].tx; |
924 | wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, | 1081 | |
925 | (const void *)d, sizeof(*d), false); | 1082 | *d = *_d; |
926 | 1083 | ||
927 | pa = wil_desc_addr(&d->dma.addr); | 1084 | dmalen = le16_to_cpu(d->dma.length); |
928 | if (ctx->mapped_as_page) | 1085 | trace_wil6210_tx_done(ringid, vring->swtail, dmalen, |
929 | dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE); | 1086 | d->dma.error); |
930 | else | 1087 | wil_dbg_txrx(wil, |
931 | dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); | 1088 | "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", |
932 | 1089 | vring->swtail, dmalen, d->dma.status, | |
933 | if (skb) { | 1090 | d->dma.error); |
934 | if (d->dma.error == 0) { | 1091 | wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, |
935 | ndev->stats.tx_packets++; | 1092 | (const void *)d, sizeof(*d), false); |
936 | ndev->stats.tx_bytes += skb->len; | 1093 | |
937 | } else { | 1094 | wil_txdesc_unmap(dev, d, ctx); |
938 | ndev->stats.tx_errors++; | 1095 | |
939 | } | 1096 | if (skb) { |
1097 | if (d->dma.error == 0) { | ||
1098 | ndev->stats.tx_packets++; | ||
1099 | stats->tx_packets++; | ||
1100 | ndev->stats.tx_bytes += skb->len; | ||
1101 | stats->tx_bytes += skb->len; | ||
1102 | } else { | ||
1103 | ndev->stats.tx_errors++; | ||
1104 | stats->tx_errors++; | ||
1105 | } | ||
940 | 1106 | ||
941 | dev_kfree_skb_any(skb); | 1107 | dev_kfree_skb_any(skb); |
1108 | } | ||
1109 | memset(ctx, 0, sizeof(*ctx)); | ||
1110 | /* There is no need to touch HW descriptor: | ||
1111 | * - ststus bit TX_DMA_STATUS_DU is set by design, | ||
1112 | * so hardware will not try to process this desc., | ||
1113 | * - rest of descriptor will be initialized on Tx. | ||
1114 | */ | ||
1115 | vring->swtail = wil_vring_next_tail(vring); | ||
1116 | done++; | ||
942 | } | 1117 | } |
943 | memset(ctx, 0, sizeof(*ctx)); | ||
944 | /* | ||
945 | * There is no need to touch HW descriptor: | ||
946 | * - ststus bit TX_DMA_STATUS_DU is set by design, | ||
947 | * so hardware will not try to process this desc., | ||
948 | * - rest of descriptor will be initialized on Tx. | ||
949 | */ | ||
950 | vring->swtail = wil_vring_next_tail(vring); | ||
951 | done++; | ||
952 | } | 1118 | } |
953 | if (wil_vring_avail_tx(vring) > vring->size/4) | 1119 | if (wil_vring_avail_tx(vring) > vring->size/4) |
954 | netif_tx_wake_all_queues(wil_to_ndev(wil)); | 1120 | netif_tx_wake_all_queues(wil_to_ndev(wil)); |