aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/tx.c')
-rw-r--r--drivers/net/wireless/libertas/tx.c74
1 files changed, 40 insertions, 34 deletions
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index d4b13478c9a7..17c437635a00 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -5,7 +5,6 @@
5 5
6#include "hostcmd.h" 6#include "hostcmd.h"
7#include "radiotap.h" 7#include "radiotap.h"
8#include "sbi.h"
9#include "decl.h" 8#include "decl.h"
10#include "defs.h" 9#include "defs.h"
11#include "dev.h" 10#include "dev.h"
@@ -68,7 +67,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
68 u32 new_rate; 67 u32 new_rate;
69 u8 *ptr = priv->adapter->tmptxbuf; 68 u8 *ptr = priv->adapter->tmptxbuf;
70 69
71 ENTER(); 70 lbs_deb_enter(LBS_DEB_TX);
72 71
73 if (priv->adapter->surpriseremoved) 72 if (priv->adapter->surpriseremoved)
74 return -1; 73 return -1;
@@ -78,7 +77,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
78 min_t(unsigned int, skb->len, 100)); 77 min_t(unsigned int, skb->len, 100));
79 78
80 if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) { 79 if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
81 lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n", 80 lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
82 skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE); 81 skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
83 ret = -1; 82 ret = -1;
84 goto done; 83 goto done;
@@ -86,13 +85,13 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
86 85
87 memset(plocaltxpd, 0, sizeof(struct txpd)); 86 memset(plocaltxpd, 0, sizeof(struct txpd));
88 87
89 plocaltxpd->tx_packet_length = skb->len; 88 plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
90 89
91 /* offset of actual data */ 90 /* offset of actual data */
92 plocaltxpd->tx_packet_location = sizeof(struct txpd); 91 plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
93 92
94 /* TxCtrl set by user or default */ 93 /* TxCtrl set by user or default */
95 plocaltxpd->tx_control = adapter->pkttxctrl; 94 plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl);
96 95
97 p802x_hdr = skb->data; 96 p802x_hdr = skb->data;
98 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) { 97 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
@@ -103,15 +102,16 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
103 /* set txpd fields from the radiotap header */ 102 /* set txpd fields from the radiotap header */
104 new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate); 103 new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
105 if (new_rate != 0) { 104 if (new_rate != 0) {
106 /* erase tx_control[4:0] */ 105 /* use new tx_control[4:0] */
107 plocaltxpd->tx_control &= ~0x1f; 106 new_rate |= (adapter->pkttxctrl & ~0x1f);
108 /* write new tx_control[4:0] */ 107 plocaltxpd->tx_control = cpu_to_le32(new_rate);
109 plocaltxpd->tx_control |= new_rate;
110 } 108 }
111 109
112 /* skip the radiotap header */ 110 /* skip the radiotap header */
113 p802x_hdr += sizeof(struct tx_radiotap_hdr); 111 p802x_hdr += sizeof(struct tx_radiotap_hdr);
114 plocaltxpd->tx_packet_length -= sizeof(struct tx_radiotap_hdr); 112 plocaltxpd->tx_packet_length =
113 cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
114 - sizeof(struct tx_radiotap_hdr));
115 115
116 } 116 }
117 /* copy destination address from 802.3 or 802.11 header */ 117 /* copy destination address from 802.3 or 802.11 header */
@@ -123,28 +123,28 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
123 lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd)); 123 lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
124 124
125 if (IS_MESH_FRAME(skb)) { 125 if (IS_MESH_FRAME(skb)) {
126 plocaltxpd->tx_control |= TxPD_MESH_FRAME; 126 plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
127 } 127 }
128 128
129 memcpy(ptr, plocaltxpd, sizeof(struct txpd)); 129 memcpy(ptr, plocaltxpd, sizeof(struct txpd));
130 130
131 ptr += sizeof(struct txpd); 131 ptr += sizeof(struct txpd);
132 132
133 lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, plocaltxpd->tx_packet_length); 133 lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
134 memcpy(ptr, p802x_hdr, plocaltxpd->tx_packet_length); 134 memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
135 ret = libertas_sbi_host_to_card(priv, MVMS_DAT, 135 ret = priv->hw_host_to_card(priv, MVMS_DAT,
136 priv->adapter->tmptxbuf, 136 priv->adapter->tmptxbuf,
137 plocaltxpd->tx_packet_length + 137 le16_to_cpu(plocaltxpd->tx_packet_length) +
138 sizeof(struct txpd)); 138 sizeof(struct txpd));
139 139
140 if (ret) { 140 if (ret) {
141 lbs_pr_debug(1, "Tx error: libertas_sbi_host_to_card failed: 0x%X\n", ret); 141 lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
142 goto done; 142 goto done;
143 } 143 }
144 144
145 lbs_pr_debug(1, "SendSinglePacket succeeds\n"); 145 lbs_deb_tx("SendSinglePacket succeeds\n");
146 146
147 done: 147done:
148 if (!ret) { 148 if (!ret) {
149 priv->stats.tx_packets++; 149 priv->stats.tx_packets++;
150 priv->stats.tx_bytes += skb->len; 150 priv->stats.tx_bytes += skb->len;
@@ -158,7 +158,8 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
158 received from FW */ 158 received from FW */
159 skb_orphan(skb); 159 skb_orphan(skb);
160 /* stop processing outgoing pkts */ 160 /* stop processing outgoing pkts */
161 netif_stop_queue(priv->wlan_dev.netdev); 161 netif_stop_queue(priv->dev);
162 netif_stop_queue(priv->mesh_dev);
162 /* freeze any packets already in our queues */ 163 /* freeze any packets already in our queues */
163 priv->adapter->TxLockFlag = 1; 164 priv->adapter->TxLockFlag = 1;
164 } else { 165 } else {
@@ -166,7 +167,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
166 priv->adapter->currenttxskb = NULL; 167 priv->adapter->currenttxskb = NULL;
167 } 168 }
168 169
169 LEAVE(); 170 lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
170 return ret; 171 return ret;
171} 172}
172 173
@@ -195,10 +196,13 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
195 196
196 WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE); 197 WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
197 adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb; 198 adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
198 if (adapter->tx_queue_idx == NR_TX_QUEUE) 199 if (adapter->tx_queue_idx == NR_TX_QUEUE) {
199 netif_stop_queue(priv->wlan_dev.netdev); 200 netif_stop_queue(priv->dev);
200 else 201 netif_stop_queue(priv->mesh_dev);
201 netif_start_queue(priv->wlan_dev.netdev); 202 } else {
203 netif_start_queue(priv->dev);
204 netif_start_queue(priv->mesh_dev);
205 }
202 206
203 spin_unlock(&adapter->txqueue_lock); 207 spin_unlock(&adapter->txqueue_lock);
204} 208}
@@ -214,13 +218,12 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
214{ 218{
215 int ret = -1; 219 int ret = -1;
216 220
217 ENTER(); 221 lbs_deb_enter(LBS_DEB_TX);
218
219 lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100)); 222 lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100));
220 223
221 if (priv->wlan_dev.dnld_sent) { 224 if (priv->dnld_sent) {
222 lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n", 225 lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
223 priv->wlan_dev.dnld_sent); 226 priv->dnld_sent);
224 goto done; 227 goto done;
225 } 228 }
226 229
@@ -234,7 +237,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
234 237
235 ret = SendSinglePacket(priv, skb); 238 ret = SendSinglePacket(priv, skb);
236done: 239done:
237 LEAVE(); 240 lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
238 return ret; 241 return ret;
239} 242}
240 243
@@ -280,6 +283,9 @@ void libertas_send_tx_feedback(wlan_private * priv)
280 libertas_upload_rx_packet(priv, adapter->currenttxskb); 283 libertas_upload_rx_packet(priv, adapter->currenttxskb);
281 adapter->currenttxskb = NULL; 284 adapter->currenttxskb = NULL;
282 priv->adapter->TxLockFlag = 0; 285 priv->adapter->TxLockFlag = 0;
283 if (priv->adapter->connect_status == libertas_connected) 286 if (priv->adapter->connect_status == libertas_connected) {
284 netif_wake_queue(priv->wlan_dev.netdev); 287 netif_wake_queue(priv->dev);
288 netif_wake_queue(priv->mesh_dev);
289 }
285} 290}
291EXPORT_SYMBOL_GPL(libertas_send_tx_feedback);