1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
8 * Purpose: Handle USB control endpoint
15 * vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM
16 * vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM
17 * vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM
18 * vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM
21 * 04-05-2004 Jerry Chen: Initial release
22 * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,
34 #define USB_CTL_WAIT 500 /* ms */
36 int vnt_control_out(struct vnt_private
*priv
, u8 request
, u16 value
,
37 u16 index
, u16 length
, const u8
*buffer
)
42 if (test_bit(DEVICE_FLAGS_DISCONNECTED
, &priv
->flags
)) {
47 mutex_lock(&priv
->usb_lock
);
49 usb_buffer
= kmemdup(buffer
, length
, GFP_KERNEL
);
55 ret
= usb_control_msg(priv
->usb
,
56 usb_sndctrlpipe(priv
->usb
, 0),
58 index
, usb_buffer
, length
, USB_CTL_WAIT
);
62 if (ret
== (int)length
)
68 mutex_unlock(&priv
->usb_lock
);
73 int vnt_control_out_u8(struct vnt_private
*priv
, u8 reg
, u8 reg_off
, u8 data
)
75 return vnt_control_out(priv
, MESSAGE_TYPE_WRITE
,
76 reg_off
, reg
, sizeof(u8
), &data
);
79 int vnt_control_out_blocks(struct vnt_private
*priv
,
80 u16 block
, u8 reg
, u16 length
, u8
*data
)
84 for (i
= 0; i
< length
; i
+= block
) {
85 u16 len
= min_t(int, length
- i
, block
);
87 ret
= vnt_control_out(priv
, MESSAGE_TYPE_WRITE
,
88 i
, reg
, len
, data
+ i
);
96 int vnt_control_in(struct vnt_private
*priv
, u8 request
, u16 value
,
97 u16 index
, u16 length
, u8
*buffer
)
102 if (test_bit(DEVICE_FLAGS_DISCONNECTED
, &priv
->flags
)) {
107 mutex_lock(&priv
->usb_lock
);
109 usb_buffer
= kmalloc(length
, GFP_KERNEL
);
115 ret
= usb_control_msg(priv
->usb
,
116 usb_rcvctrlpipe(priv
->usb
, 0),
117 request
, 0xc0, value
,
118 index
, usb_buffer
, length
, USB_CTL_WAIT
);
121 memcpy(buffer
, usb_buffer
, length
);
125 if (ret
== (int)length
)
131 mutex_unlock(&priv
->usb_lock
);
136 int vnt_control_in_u8(struct vnt_private
*priv
, u8 reg
, u8 reg_off
, u8
*data
)
138 return vnt_control_in(priv
, MESSAGE_TYPE_READ
,
139 reg_off
, reg
, sizeof(u8
), data
);
142 static int vnt_int_report_rate(struct vnt_private
*priv
, u8 pkt_no
, u8 tsr
)
144 struct vnt_usb_send_context
*context
;
145 struct ieee80211_tx_info
*info
;
146 u8 tx_retry
= (tsr
& 0xf0) >> 4;
149 if (pkt_no
>= priv
->num_tx_context
)
152 context
= priv
->tx_context
[pkt_no
];
157 info
= IEEE80211_SKB_CB(context
->skb
);
158 idx
= info
->control
.rates
[0].idx
;
160 ieee80211_tx_info_clear_status(info
);
162 info
->status
.rates
[0].count
= tx_retry
;
164 if (!(tsr
& TSR_TMO
)) {
165 info
->status
.rates
[0].idx
= idx
;
167 if (!(info
->flags
& IEEE80211_TX_CTL_NO_ACK
))
168 info
->flags
|= IEEE80211_TX_STAT_ACK
;
171 ieee80211_tx_status_irqsafe(priv
->hw
, context
->skb
);
173 context
->in_use
= false;
178 static void vnt_int_process_data(struct vnt_private
*priv
)
180 struct vnt_interrupt_data
*int_data
;
181 struct ieee80211_low_level_stats
*low_stats
= &priv
->low_stats
;
183 dev_dbg(&priv
->usb
->dev
, "---->s_nsInterruptProcessData\n");
185 int_data
= (struct vnt_interrupt_data
*)priv
->int_buf
.data_buf
;
187 if (int_data
->tsr0
& TSR_VALID
)
188 vnt_int_report_rate(priv
, int_data
->pkt0
, int_data
->tsr0
);
190 if (int_data
->tsr1
& TSR_VALID
)
191 vnt_int_report_rate(priv
, int_data
->pkt1
, int_data
->tsr1
);
193 if (int_data
->tsr2
& TSR_VALID
)
194 vnt_int_report_rate(priv
, int_data
->pkt2
, int_data
->tsr2
);
196 if (int_data
->tsr3
& TSR_VALID
)
197 vnt_int_report_rate(priv
, int_data
->pkt3
, int_data
->tsr3
);
199 if (int_data
->isr0
!= 0) {
200 if (int_data
->isr0
& ISR_BNTX
&&
201 priv
->op_mode
== NL80211_IFTYPE_AP
)
202 vnt_schedule_command(priv
, WLAN_CMD_BECON_SEND
);
204 if (int_data
->isr0
& ISR_TBTT
&&
205 priv
->hw
->conf
.flags
& IEEE80211_CONF_PS
) {
206 if (!priv
->wake_up_count
)
207 priv
->wake_up_count
=
208 priv
->hw
->conf
.listen_interval
;
210 --priv
->wake_up_count
;
212 /* Turn on wake up to listen next beacon */
213 if (priv
->wake_up_count
== 1)
214 vnt_schedule_command(priv
,
215 WLAN_CMD_TBTT_WAKEUP
);
217 priv
->current_tsf
= le64_to_cpu(int_data
->tsf
);
219 low_stats
->dot11RTSSuccessCount
+= int_data
->rts_success
;
220 low_stats
->dot11RTSFailureCount
+= int_data
->rts_fail
;
221 low_stats
->dot11ACKFailureCount
+= int_data
->ack_fail
;
222 low_stats
->dot11FCSErrorCount
+= int_data
->fcs_err
;
226 static void vnt_start_interrupt_urb_complete(struct urb
*urb
)
228 struct vnt_private
*priv
= urb
->context
;
229 int status
= urb
->status
;
244 dev_dbg(&priv
->usb
->dev
, "%s status = %d\n", __func__
, status
);
246 vnt_int_process_data(priv
);
248 status
= usb_submit_urb(priv
->interrupt_urb
, GFP_ATOMIC
);
250 dev_dbg(&priv
->usb
->dev
, "Submit int URB failed %d\n", status
);
253 int vnt_start_interrupt_urb(struct vnt_private
*priv
)
257 dev_dbg(&priv
->usb
->dev
, "---->Interrupt Polling Thread\n");
259 usb_fill_int_urb(priv
->interrupt_urb
,
261 usb_rcvintpipe(priv
->usb
, 1),
262 priv
->int_buf
.data_buf
,
264 vnt_start_interrupt_urb_complete
,
268 ret
= usb_submit_urb(priv
->interrupt_urb
, GFP_ATOMIC
);
270 dev_dbg(&priv
->usb
->dev
, "Submit int URB failed %d\n", ret
);
275 static int vnt_rx_data(struct vnt_private
*priv
, struct vnt_rcb
*ptr_rcb
,
276 unsigned long bytes_received
)
278 struct ieee80211_hw
*hw
= priv
->hw
;
279 struct ieee80211_supported_band
*sband
;
281 struct ieee80211_rx_status
*rx_status
;
282 struct vnt_rx_header
*head
;
283 struct vnt_rx_tail
*tail
;
286 u16 rx_bitrate
, pay_load_with_padding
;
291 rx_status
= IEEE80211_SKB_RXCB(skb
);
293 /* [31:16]RcvByteCount ( not include 4-byte Status ) */
294 head
= (struct vnt_rx_header
*)skb
->data
;
295 frame_size
= head
->wbk_status
>> 16;
298 if (bytes_received
!= frame_size
) {
299 dev_dbg(&priv
->usb
->dev
, "------- WRONG Length 1\n");
303 if ((bytes_received
> 2372) || (bytes_received
<= 40)) {
304 /* Frame Size error drop this packet.*/
305 dev_dbg(&priv
->usb
->dev
, "------ WRONG Length 2\n");
309 /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
310 /* -8TSF - 4RSR - 4SQ3 - ?Padding */
312 /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
314 /*Fix hardware bug => PLCP_Length error */
315 if (((bytes_received
- head
->pay_load_len
) > 27) ||
316 ((bytes_received
- head
->pay_load_len
) < 24) ||
317 (bytes_received
< head
->pay_load_len
)) {
318 dev_dbg(&priv
->usb
->dev
, "Wrong PLCP Length %x\n",
323 sband
= hw
->wiphy
->bands
[hw
->conf
.chandef
.chan
->band
];
324 rx_bitrate
= head
->rx_rate
* 5; /* rx_rate * 5 */
326 for (ii
= 0; ii
< sband
->n_bitrates
; ii
++) {
327 if (sband
->bitrates
[ii
].bitrate
== rx_bitrate
) {
333 if (ii
== sband
->n_bitrates
) {
334 dev_dbg(&priv
->usb
->dev
, "Wrong Rx Bit Rate %d\n", rx_bitrate
);
338 pay_load_with_padding
= ((head
->pay_load_len
/ 4) +
339 ((head
->pay_load_len
% 4) ? 1 : 0)) * 4;
341 tail
= (struct vnt_rx_tail
*)(skb
->data
+
342 sizeof(*head
) + pay_load_with_padding
);
343 priv
->tsf_time
= le64_to_cpu(tail
->tsf_time
);
345 if (tail
->rsr
& (RSR_IVLDTYP
| RSR_IVLDLEN
))
348 vnt_rf_rssi_to_dbm(priv
, tail
->rssi
, &rx_dbm
);
350 priv
->bb_pre_ed_rssi
= (u8
)-rx_dbm
+ 1;
351 priv
->current_rssi
= priv
->bb_pre_ed_rssi
;
353 skb_pull(skb
, sizeof(*head
));
354 skb_trim(skb
, head
->pay_load_len
);
356 rx_status
->mactime
= priv
->tsf_time
;
357 rx_status
->band
= hw
->conf
.chandef
.chan
->band
;
358 rx_status
->signal
= rx_dbm
;
360 rx_status
->freq
= hw
->conf
.chandef
.chan
->center_freq
;
362 if (!(tail
->rsr
& RSR_CRCOK
))
363 rx_status
->flag
|= RX_FLAG_FAILED_FCS_CRC
;
365 rx_status
->rate_idx
= rate_idx
;
367 if (tail
->new_rsr
& NEWRSR_DECRYPTOK
)
368 rx_status
->flag
|= RX_FLAG_DECRYPTED
;
370 ieee80211_rx_irqsafe(priv
->hw
, skb
);
375 static void vnt_submit_rx_urb_complete(struct urb
*urb
)
377 struct vnt_rcb
*rcb
= urb
->context
;
378 struct vnt_private
*priv
= rcb
->priv
;
380 switch (urb
->status
) {
389 dev_dbg(&priv
->usb
->dev
, "BULK In failed %d\n", urb
->status
);
393 if (urb
->actual_length
) {
394 if (vnt_rx_data(priv
, rcb
, urb
->actual_length
)) {
395 rcb
->skb
= dev_alloc_skb(priv
->rx_buf_sz
);
399 skb_push(rcb
->skb
, skb_headroom(rcb
->skb
));
400 skb_trim(rcb
->skb
, 0);
403 urb
->transfer_buffer
= skb_put(rcb
->skb
,
404 skb_tailroom(rcb
->skb
));
407 if (usb_submit_urb(urb
, GFP_ATOMIC
))
408 dev_dbg(&priv
->usb
->dev
, "Failed to re submit rx skb\n");
411 int vnt_submit_rx_urb(struct vnt_private
*priv
, struct vnt_rcb
*rcb
)
414 struct urb
*urb
= rcb
->urb
;
417 dev_dbg(&priv
->usb
->dev
, "rcb->skb is null\n");
422 usb_fill_bulk_urb(urb
,
424 usb_rcvbulkpipe(priv
->usb
, 2),
425 skb_put(rcb
->skb
, skb_tailroom(rcb
->skb
)),
426 MAX_TOTAL_SIZE_WITH_ALL_HEADERS
,
427 vnt_submit_rx_urb_complete
,
430 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
432 dev_dbg(&priv
->usb
->dev
, "Submit Rx URB failed %d\n", ret
);
437 static void vnt_tx_context_complete(struct urb
*urb
)
439 struct vnt_usb_send_context
*context
= urb
->context
;
440 struct vnt_private
*priv
= context
->priv
;
442 switch (urb
->status
) {
444 dev_dbg(&priv
->usb
->dev
, "Write %d bytes\n", context
->buf_len
);
449 context
->in_use
= false;
453 dev_dbg(&priv
->usb
->dev
, "BULK Out failed %d\n", urb
->status
);
457 if (context
->type
== CONTEXT_DATA_PACKET
)
458 ieee80211_wake_queues(priv
->hw
);
460 if (urb
->status
|| context
->type
== CONTEXT_BEACON_PACKET
) {
462 ieee80211_free_txskb(priv
->hw
, context
->skb
);
464 context
->in_use
= false;
468 int vnt_tx_context(struct vnt_private
*priv
,
469 struct vnt_usb_send_context
*context
)
472 struct urb
*urb
= context
->urb
;
474 if (test_bit(DEVICE_FLAGS_DISCONNECTED
, &priv
->flags
)) {
475 context
->in_use
= false;
479 usb_fill_bulk_urb(urb
,
481 usb_sndbulkpipe(priv
->usb
, 3),
484 vnt_tx_context_complete
,
487 status
= usb_submit_urb(urb
, GFP_ATOMIC
);
489 dev_dbg(&priv
->usb
->dev
, "Submit Tx URB failed %d\n", status
);
491 context
->in_use
= false;