aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2015-03-15 10:00:23 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-03-20 02:33:23 -0400
commit41d6b093b7f8f2755a0a64ad4277c01bf78ced3e (patch)
tree3fa9b570c909db7ae9e4c8709d8aca7aee12d769
parent62bfd30031faebcbf25db37bf228eeab0e25b2c3 (diff)
wil6210: implement broadcast/multicast data
Use dedicated vring for multicast frames; this vring allocated for AP and PBSS (both P2P GO and client) configurations For short frames, use MCS0; for long - MCS1 Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c11
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c18
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c33
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c175
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h6
5 files changed, 167 insertions, 76 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index c9f362c68c17..8f7596f60263 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -783,8 +783,17 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
783 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, 783 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
784 channel->hw_value); 784 channel->hw_value);
785 if (rc) 785 if (rc)
786 netif_carrier_off(ndev); 786 goto err_pcp_start;
787 787
788 rc = wil_bcast_init(wil);
789 if (rc)
790 goto err_bcast;
791
792 goto out; /* success */
793err_bcast:
794 wmi_pcp_stop(wil);
795err_pcp_start:
796 netif_carrier_off(ndev);
788out: 797out:
789 mutex_unlock(&wil->mutex); 798 mutex_unlock(&wil->mutex);
790 return rc; 799 return rc;
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index a42cb89ff725..bbc22d88f78f 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -121,12 +121,18 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
121 121
122 snprintf(name, sizeof(name), "tx_%2d", i); 122 snprintf(name, sizeof(name), "tx_%2d", i);
123 123
124 seq_printf(s, 124 if (cid < WIL6210_MAX_CID)
125 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %s\n", 125 seq_printf(s,
126 wil->sta[cid].addr, cid, tid, 126 "\n%pM CID %d TID %d BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
127 txdata->agg_wsize, txdata->agg_timeout, 127 wil->sta[cid].addr, cid, tid,
128 txdata->agg_amsdu ? "+" : "-", 128 txdata->agg_wsize,
129 used, avail, sidle); 129 txdata->agg_timeout,
130 txdata->agg_amsdu ? "+" : "-",
131 used, avail, sidle);
132 else
133 seq_printf(s,
134 "\nBroadcast [%3d|%3d] idle %s\n",
135 used, avail, sidle);
130 136
131 wil_print_vring(s, wil, name, vring, '_', 'H'); 137 wil_print_vring(s, wil, name, vring, '_', 'H');
132 } 138 }
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index a5fd605e52eb..c2a238426425 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -68,6 +68,7 @@ MODULE_PARM_DESC(mtu_max, " Max MTU value.");
68 68
69static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT; 69static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT;
70static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT; 70static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT;
71static uint bcast_ring_order = WIL_BCAST_RING_SIZE_ORDER_DEFAULT;
71 72
72static int ring_order_set(const char *val, const struct kernel_param *kp) 73static int ring_order_set(const char *val, const struct kernel_param *kp)
73{ 74{
@@ -216,6 +217,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
216 switch (wdev->iftype) { 217 switch (wdev->iftype) {
217 case NL80211_IFTYPE_STATION: 218 case NL80211_IFTYPE_STATION:
218 case NL80211_IFTYPE_P2P_CLIENT: 219 case NL80211_IFTYPE_P2P_CLIENT:
220 wil_bcast_fini(wil);
219 netif_tx_stop_all_queues(ndev); 221 netif_tx_stop_all_queues(ndev);
220 netif_carrier_off(ndev); 222 netif_carrier_off(ndev);
221 223
@@ -360,6 +362,35 @@ static int wil_find_free_vring(struct wil6210_priv *wil)
360 return -EINVAL; 362 return -EINVAL;
361} 363}
362 364
365int wil_bcast_init(struct wil6210_priv *wil)
366{
367 int ri = wil->bcast_vring, rc;
368
369 if ((ri >= 0) && wil->vring_tx[ri].va)
370 return 0;
371
372 ri = wil_find_free_vring(wil);
373 if (ri < 0)
374 return ri;
375
376 rc = wil_vring_init_bcast(wil, ri, 1 << bcast_ring_order);
377 if (rc == 0)
378 wil->bcast_vring = ri;
379
380 return rc;
381}
382
383void wil_bcast_fini(struct wil6210_priv *wil)
384{
385 int ri = wil->bcast_vring;
386
387 if (ri < 0)
388 return;
389
390 wil->bcast_vring = -1;
391 wil_vring_fini_tx(wil, ri);
392}
393
363static void wil_connect_worker(struct work_struct *work) 394static void wil_connect_worker(struct work_struct *work)
364{ 395{
365 int rc; 396 int rc;
@@ -407,6 +438,7 @@ int wil_priv_init(struct wil6210_priv *wil)
407 init_completion(&wil->wmi_call); 438 init_completion(&wil->wmi_call);
408 439
409 wil->pending_connect_cid = -1; 440 wil->pending_connect_cid = -1;
441 wil->bcast_vring = -1;
410 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 442 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
411 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil); 443 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil);
412 444
@@ -656,6 +688,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
656 688
657 cancel_work_sync(&wil->disconnect_worker); 689 cancel_work_sync(&wil->disconnect_worker);
658 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 690 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
691 wil_bcast_fini(wil);
659 692
660 /* prevent NAPI from being scheduled */ 693 /* prevent NAPI from being scheduled */
661 bitmap_zero(wil->status, wil_status_last); 694 bitmap_zero(wil->status, wil_status_last);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 2453470bc191..1fe390f6d7d7 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -523,7 +523,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
523 struct wireless_dev *wdev = wil_to_wdev(wil); 523 struct wireless_dev *wdev = wil_to_wdev(wil);
524 unsigned int len = skb->len; 524 unsigned int len = skb->len;
525 struct vring_rx_desc *d = wil_skb_rxdesc(skb); 525 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
526 int cid = wil_rxdesc_cid(d); 526 int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */
527 struct ethhdr *eth = (void *)skb->data; 527 struct ethhdr *eth = (void *)skb->data;
528 /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication 528 /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication
529 * is not suitable, need to look at data 529 * is not suitable, need to look at data
@@ -749,6 +749,72 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
749 return rc; 749 return rc;
750} 750}
751 751
752int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
753{
754 int rc;
755 struct wmi_bcast_vring_cfg_cmd cmd = {
756 .action = cpu_to_le32(WMI_VRING_CMD_ADD),
757 .vring_cfg = {
758 .tx_sw_ring = {
759 .max_mpdu_size =
760 cpu_to_le16(wil_mtu2macbuf(mtu_max)),
761 .ring_size = cpu_to_le16(size),
762 },
763 .ringid = id,
764 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3,
765 },
766 };
767 struct {
768 struct wil6210_mbox_hdr_wmi wmi;
769 struct wmi_vring_cfg_done_event cmd;
770 } __packed reply;
771 struct vring *vring = &wil->vring_tx[id];
772 struct vring_tx_data *txdata = &wil->vring_tx_data[id];
773
774 wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
775 cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
776
777 if (vring->va) {
778 wil_err(wil, "Tx ring [%d] already allocated\n", id);
779 rc = -EINVAL;
780 goto out;
781 }
782
783 memset(txdata, 0, sizeof(*txdata));
784 spin_lock_init(&txdata->lock);
785 vring->size = size;
786 rc = wil_vring_alloc(wil, vring);
787 if (rc)
788 goto out;
789
790 wil->vring2cid_tid[id][0] = WIL6210_MAX_CID; /* CID */
791 wil->vring2cid_tid[id][1] = 0; /* TID */
792
793 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
794
795 rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, &cmd, sizeof(cmd),
796 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
797 if (rc)
798 goto out_free;
799
800 if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) {
801 wil_err(wil, "Tx config failed, status 0x%02x\n",
802 reply.cmd.status);
803 rc = -EINVAL;
804 goto out_free;
805 }
806 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
807
808 txdata->enabled = 1;
809
810 return 0;
811 out_free:
812 wil_vring_free(wil, vring, 1);
813 out:
814
815 return rc;
816}
817
752void wil_vring_fini_tx(struct wil6210_priv *wil, int id) 818void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
753{ 819{
754 struct vring *vring = &wil->vring_tx[id]; 820 struct vring *vring = &wil->vring_tx[id];
@@ -772,7 +838,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
772 memset(txdata, 0, sizeof(*txdata)); 838 memset(txdata, 0, sizeof(*txdata));
773} 839}
774 840
775static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, 841static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
776 struct sk_buff *skb) 842 struct sk_buff *skb)
777{ 843{
778 int i; 844 int i;
@@ -805,15 +871,6 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
805 return NULL; 871 return NULL;
806} 872}
807 873
808static void wil_set_da_for_vring(struct wil6210_priv *wil,
809 struct sk_buff *skb, int vring_index)
810{
811 struct ethhdr *eth = (void *)skb->data;
812 int cid = wil->vring2cid_tid[vring_index][0];
813
814 memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN);
815}
816
817static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 874static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
818 struct sk_buff *skb); 875 struct sk_buff *skb);
819 876
@@ -834,6 +891,9 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
834 continue; 891 continue;
835 892
836 cid = wil->vring2cid_tid[i][0]; 893 cid = wil->vring2cid_tid[i][0];
894 if (cid >= WIL6210_MAX_CID) /* skip BCAST */
895 continue;
896
837 if (!wil->sta[cid].data_port_open && 897 if (!wil->sta[cid].data_port_open &&
838 (skb->protocol != cpu_to_be16(ETH_P_PAE))) 898 (skb->protocol != cpu_to_be16(ETH_P_PAE)))
839 break; 899 break;
@@ -848,57 +908,17 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
848 return NULL; 908 return NULL;
849} 909}
850 910
851/* 911static struct vring *wil_find_tx_bcast(struct wil6210_priv *wil,
852 * Find 1-st vring and return it; set dest address for this vring in skb 912 struct sk_buff *skb)
853 * duplicate skb and send it to other active vrings
854 */
855static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
856 struct sk_buff *skb)
857{ 913{
858 struct vring *v, *v2; 914 struct vring *v;
859 struct sk_buff *skb2; 915 int i = wil->bcast_vring;
860 int i;
861 u8 cid;
862
863 /* find 1-st vring eligible for data */
864 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
865 v = &wil->vring_tx[i];
866 if (!v->va)
867 continue;
868
869 cid = wil->vring2cid_tid[i][0];
870 if (!wil->sta[cid].data_port_open)
871 continue;
872
873 goto found;
874 }
875
876 wil_dbg_txrx(wil, "Tx while no vrings active?\n");
877
878 return NULL;
879
880found:
881 wil_dbg_txrx(wil, "BCAST -> ring %d\n", i);
882 wil_set_da_for_vring(wil, skb, i);
883
884 /* find other active vrings and duplicate skb for each */
885 for (i++; i < WIL6210_MAX_TX_RINGS; i++) {
886 v2 = &wil->vring_tx[i];
887 if (!v2->va)
888 continue;
889 cid = wil->vring2cid_tid[i][0];
890 if (!wil->sta[cid].data_port_open)
891 continue;
892 916
893 skb2 = skb_copy(skb, GFP_ATOMIC); 917 if (i < 0)
894 if (skb2) { 918 return NULL;
895 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); 919 v = &wil->vring_tx[i];
896 wil_set_da_for_vring(wil, skb2, i); 920 if (!v->va)
897 wil_tx_vring(wil, v2, skb2); 921 return NULL;
898 } else {
899 wil_err(wil, "skb_copy failed\n");
900 }
901 }
902 922
903 return v; 923 return v;
904} 924}
@@ -995,6 +1015,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
995 uint i = swhead; 1015 uint i = swhead;
996 dma_addr_t pa; 1016 dma_addr_t pa;
997 int used; 1017 int used;
1018 bool mcast = (vring_index == wil->bcast_vring);
1019 uint len = skb_headlen(skb);
998 1020
999 wil_dbg_txrx(wil, "%s()\n", __func__); 1021 wil_dbg_txrx(wil, "%s()\n", __func__);
1000 1022
@@ -1020,7 +1042,17 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1020 return -EINVAL; 1042 return -EINVAL;
1021 vring->ctx[i].mapped_as = wil_mapped_as_single; 1043 vring->ctx[i].mapped_as = wil_mapped_as_single;
1022 /* 1-st segment */ 1044 /* 1-st segment */
1023 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 1045 wil_tx_desc_map(d, pa, len, vring_index);
1046 if (unlikely(mcast)) {
1047 d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_0_MCS_EN_POS); /* MCS 0 */
1048 if (unlikely(len > WIL_BCAST_MCS0_LIMIT)) {
1049 /* set MCS 1 */
1050 d->mac.d[0] |= (1 << MAC_CFG_DESC_TX_0_MCS_INDEX_POS);
1051 /* packet mode 2 */
1052 d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_PKT_MODE_EN_POS) |
1053 (2 << MAC_CFG_DESC_TX_1_PKT_MODE_POS);
1054 }
1055 }
1024 /* Process TCP/UDP checksum offloading */ 1056 /* Process TCP/UDP checksum offloading */
1025 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) { 1057 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) {
1026 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n", 1058 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
@@ -1126,6 +1158,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1126{ 1158{
1127 struct wil6210_priv *wil = ndev_to_wil(ndev); 1159 struct wil6210_priv *wil = ndev_to_wil(ndev);
1128 struct ethhdr *eth = (void *)skb->data; 1160 struct ethhdr *eth = (void *)skb->data;
1161 bool bcast = is_multicast_ether_addr(eth->h_dest);
1129 struct vring *vring; 1162 struct vring *vring;
1130 static bool pr_once_fw; 1163 static bool pr_once_fw;
1131 int rc; 1164 int rc;
@@ -1153,10 +1186,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1153 /* in STA mode (ESS), all to same VRING */ 1186 /* in STA mode (ESS), all to same VRING */
1154 vring = wil_find_tx_vring_sta(wil, skb); 1187 vring = wil_find_tx_vring_sta(wil, skb);
1155 } else { /* direct communication, find matching VRING */ 1188 } else { /* direct communication, find matching VRING */
1156 if (is_unicast_ether_addr(eth->h_dest)) 1189 vring = bcast ? wil_find_tx_bcast(wil, skb) :
1157 vring = wil_find_tx_vring(wil, skb); 1190 wil_find_tx_ucast(wil, skb);
1158 else
1159 vring = wil_tx_bcast(wil, skb);
1160 } 1191 }
1161 if (unlikely(!vring)) { 1192 if (unlikely(!vring)) {
1162 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1193 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
@@ -1219,7 +1250,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1219 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; 1250 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid];
1220 int done = 0; 1251 int done = 0;
1221 int cid = wil->vring2cid_tid[ringid][0]; 1252 int cid = wil->vring2cid_tid[ringid][0];
1222 struct wil_net_stats *stats = &wil->sta[cid].stats; 1253 struct wil_net_stats *stats = NULL;
1223 volatile struct vring_tx_desc *_d; 1254 volatile struct vring_tx_desc *_d;
1224 int used_before_complete; 1255 int used_before_complete;
1225 int used_new; 1256 int used_new;
@@ -1238,6 +1269,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1238 1269
1239 used_before_complete = wil_vring_used_tx(vring); 1270 used_before_complete = wil_vring_used_tx(vring);
1240 1271
1272 if (cid < WIL6210_MAX_CID)
1273 stats = &wil->sta[cid].stats;
1274
1241 while (!wil_vring_is_empty(vring)) { 1275 while (!wil_vring_is_empty(vring)) {
1242 int new_swtail; 1276 int new_swtail;
1243 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1277 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
@@ -1279,12 +1313,15 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1279 if (skb) { 1313 if (skb) {
1280 if (likely(d->dma.error == 0)) { 1314 if (likely(d->dma.error == 0)) {
1281 ndev->stats.tx_packets++; 1315 ndev->stats.tx_packets++;
1282 stats->tx_packets++;
1283 ndev->stats.tx_bytes += skb->len; 1316 ndev->stats.tx_bytes += skb->len;
1284 stats->tx_bytes += skb->len; 1317 if (stats) {
1318 stats->tx_packets++;
1319 stats->tx_bytes += skb->len;
1320 }
1285 } else { 1321 } else {
1286 ndev->stats.tx_errors++; 1322 ndev->stats.tx_errors++;
1287 stats->tx_errors++; 1323 if (stats)
1324 stats->tx_errors++;
1288 } 1325 }
1289 wil_consume_skb(skb, d->dma.error == 0); 1326 wil_consume_skb(skb, d->dma.error == 0);
1290 } 1327 }
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index a6b096eb7dee..4310972c9e16 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -50,6 +50,8 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
50#define WIL_TX_Q_LEN_DEFAULT (4000) 50#define WIL_TX_Q_LEN_DEFAULT (4000)
51#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10) 51#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10)
52#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10) 52#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10)
53#define WIL_BCAST_RING_SIZE_ORDER_DEFAULT (7)
54#define WIL_BCAST_MCS0_LIMIT (1024) /* limit for MCS0 frame size */
53/* limit ring size in range [32..32k] */ 55/* limit ring size in range [32..32k] */
54#define WIL_RING_SIZE_ORDER_MIN (5) 56#define WIL_RING_SIZE_ORDER_MIN (5)
55#define WIL_RING_SIZE_ORDER_MAX (15) 57#define WIL_RING_SIZE_ORDER_MAX (15)
@@ -595,6 +597,7 @@ struct wil6210_priv {
595 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS]; 597 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS];
596 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ 598 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
597 struct wil_sta_info sta[WIL6210_MAX_CID]; 599 struct wil_sta_info sta[WIL6210_MAX_CID];
600 int bcast_vring;
598 /* scan */ 601 /* scan */
599 struct cfg80211_scan_request *scan_request; 602 struct cfg80211_scan_request *scan_request;
600 603
@@ -757,6 +760,9 @@ void wil_rx_fini(struct wil6210_priv *wil);
757int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 760int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
758 int cid, int tid); 761 int cid, int tid);
759void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 762void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
763int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size);
764int wil_bcast_init(struct wil6210_priv *wil);
765void wil_bcast_fini(struct wil6210_priv *wil);
760 766
761netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 767netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
762int wil_tx_complete(struct wil6210_priv *wil, int ringid); 768int wil_tx_complete(struct wil6210_priv *wil, int ringid);