diff options
Diffstat (limited to 'drivers/net/wireless/libertas/tx.c')
-rw-r--r-- | drivers/net/wireless/libertas/tx.c | 74 |
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: | 147 | done: |
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); |
236 | done: | 239 | done: |
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 | } |
291 | EXPORT_SYMBOL_GPL(libertas_send_tx_feedback); | ||