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 if (priv
->wake_up_count
)
211 --priv
->wake_up_count
;
213 /* Turn on wake up to listen next beacon */
214 if (priv
->wake_up_count
== 1)
215 vnt_schedule_command(priv
,
216 WLAN_CMD_TBTT_WAKEUP
);
218 priv
->current_tsf
= le64_to_cpu(int_data
->tsf
);
220 low_stats
->dot11RTSSuccessCount
+= int_data
->rts_success
;
221 low_stats
->dot11RTSFailureCount
+= int_data
->rts_fail
;
222 low_stats
->dot11ACKFailureCount
+= int_data
->ack_fail
;
223 low_stats
->dot11FCSErrorCount
+= int_data
->fcs_err
;
227 static void vnt_start_interrupt_urb_complete(struct urb
*urb
)
229 struct vnt_private
*priv
= urb
->context
;
230 int status
= urb
->status
;
245 dev_dbg(&priv
->usb
->dev
, "%s status = %d\n", __func__
, status
);
247 vnt_int_process_data(priv
);
249 status
= usb_submit_urb(priv
->interrupt_urb
, GFP_ATOMIC
);
251 dev_dbg(&priv
->usb
->dev
, "Submit int URB failed %d\n", status
);
254 int vnt_start_interrupt_urb(struct vnt_private
*priv
)
258 dev_dbg(&priv
->usb
->dev
, "---->Interrupt Polling Thread\n");
260 usb_fill_int_urb(priv
->interrupt_urb
,
262 usb_rcvintpipe(priv
->usb
, 1),
263 priv
->int_buf
.data_buf
,
265 vnt_start_interrupt_urb_complete
,
269 ret
= usb_submit_urb(priv
->interrupt_urb
, GFP_ATOMIC
);
271 dev_dbg(&priv
->usb
->dev
, "Submit int URB failed %d\n", ret
);
276 static int vnt_rx_data(struct vnt_private
*priv
, struct vnt_rcb
*ptr_rcb
,
277 unsigned long bytes_received
)
279 struct ieee80211_hw
*hw
= priv
->hw
;
280 struct ieee80211_supported_band
*sband
;
282 struct ieee80211_rx_status
*rx_status
;
283 struct vnt_rx_header
*head
;
284 struct vnt_rx_tail
*tail
;
287 u16 rx_bitrate
, pay_load_with_padding
;
292 rx_status
= IEEE80211_SKB_RXCB(skb
);
294 /* [31:16]RcvByteCount ( not include 4-byte Status ) */
295 head
= (struct vnt_rx_header
*)skb
->data
;
296 frame_size
= head
->wbk_status
>> 16;
299 if (bytes_received
!= frame_size
) {
300 dev_dbg(&priv
->usb
->dev
, "------- WRONG Length 1\n");
304 if ((bytes_received
> 2372) || (bytes_received
<= 40)) {
305 /* Frame Size error drop this packet.*/
306 dev_dbg(&priv
->usb
->dev
, "------ WRONG Length 2\n");
310 /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
311 /* -8TSF - 4RSR - 4SQ3 - ?Padding */
313 /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
315 /*Fix hardware bug => PLCP_Length error */
316 if (((bytes_received
- head
->pay_load_len
) > 27) ||
317 ((bytes_received
- head
->pay_load_len
) < 24) ||
318 (bytes_received
< head
->pay_load_len
)) {
319 dev_dbg(&priv
->usb
->dev
, "Wrong PLCP Length %x\n",
324 sband
= hw
->wiphy
->bands
[hw
->conf
.chandef
.chan
->band
];
325 rx_bitrate
= head
->rx_rate
* 5; /* rx_rate * 5 */
327 for (ii
= 0; ii
< sband
->n_bitrates
; ii
++) {
328 if (sband
->bitrates
[ii
].bitrate
== rx_bitrate
) {
334 if (ii
== sband
->n_bitrates
) {
335 dev_dbg(&priv
->usb
->dev
, "Wrong Rx Bit Rate %d\n", rx_bitrate
);
339 pay_load_with_padding
= ((head
->pay_load_len
/ 4) +
340 ((head
->pay_load_len
% 4) ? 1 : 0)) * 4;
342 tail
= (struct vnt_rx_tail
*)(skb
->data
+
343 sizeof(*head
) + pay_load_with_padding
);
344 priv
->tsf_time
= le64_to_cpu(tail
->tsf_time
);
346 if (tail
->rsr
& (RSR_IVLDTYP
| RSR_IVLDLEN
))
349 vnt_rf_rssi_to_dbm(priv
, tail
->rssi
, &rx_dbm
);
351 priv
->bb_pre_ed_rssi
= (u8
)-rx_dbm
+ 1;
352 priv
->current_rssi
= priv
->bb_pre_ed_rssi
;
354 skb_pull(skb
, sizeof(*head
));
355 skb_trim(skb
, head
->pay_load_len
);
357 rx_status
->mactime
= priv
->tsf_time
;
358 rx_status
->band
= hw
->conf
.chandef
.chan
->band
;
359 rx_status
->signal
= rx_dbm
;
361 rx_status
->freq
= hw
->conf
.chandef
.chan
->center_freq
;
363 if (!(tail
->rsr
& RSR_CRCOK
))
364 rx_status
->flag
|= RX_FLAG_FAILED_FCS_CRC
;
366 rx_status
->rate_idx
= rate_idx
;
368 if (tail
->new_rsr
& NEWRSR_DECRYPTOK
)
369 rx_status
->flag
|= RX_FLAG_DECRYPTED
;
371 ieee80211_rx_irqsafe(priv
->hw
, skb
);
376 static void vnt_submit_rx_urb_complete(struct urb
*urb
)
378 struct vnt_rcb
*rcb
= urb
->context
;
379 struct vnt_private
*priv
= rcb
->priv
;
381 switch (urb
->status
) {
390 dev_dbg(&priv
->usb
->dev
, "BULK In failed %d\n", urb
->status
);
394 if (urb
->actual_length
) {
395 if (vnt_rx_data(priv
, rcb
, urb
->actual_length
)) {
396 rcb
->skb
= dev_alloc_skb(priv
->rx_buf_sz
);
400 skb_push(rcb
->skb
, skb_headroom(rcb
->skb
));
401 skb_trim(rcb
->skb
, 0);
404 urb
->transfer_buffer
= skb_put(rcb
->skb
,
405 skb_tailroom(rcb
->skb
));
408 if (usb_submit_urb(urb
, GFP_ATOMIC
))
409 dev_dbg(&priv
->usb
->dev
, "Failed to re submit rx skb\n");
412 int vnt_submit_rx_urb(struct vnt_private
*priv
, struct vnt_rcb
*rcb
)
415 struct urb
*urb
= rcb
->urb
;
418 dev_dbg(&priv
->usb
->dev
, "rcb->skb is null\n");
423 usb_fill_bulk_urb(urb
,
425 usb_rcvbulkpipe(priv
->usb
, 2),
426 skb_put(rcb
->skb
, skb_tailroom(rcb
->skb
)),
427 MAX_TOTAL_SIZE_WITH_ALL_HEADERS
,
428 vnt_submit_rx_urb_complete
,
431 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
433 dev_dbg(&priv
->usb
->dev
, "Submit Rx URB failed %d\n", ret
);
438 static void vnt_tx_context_complete(struct urb
*urb
)
440 struct vnt_usb_send_context
*context
= urb
->context
;
441 struct vnt_private
*priv
= context
->priv
;
443 switch (urb
->status
) {
445 dev_dbg(&priv
->usb
->dev
, "Write %d bytes\n", context
->buf_len
);
450 context
->in_use
= false;
454 dev_dbg(&priv
->usb
->dev
, "BULK Out failed %d\n", urb
->status
);
458 if (context
->type
== CONTEXT_DATA_PACKET
)
459 ieee80211_wake_queues(priv
->hw
);
461 if (urb
->status
|| context
->type
== CONTEXT_BEACON_PACKET
) {
463 ieee80211_free_txskb(priv
->hw
, context
->skb
);
465 context
->in_use
= false;
469 int vnt_tx_context(struct vnt_private
*priv
,
470 struct vnt_usb_send_context
*context
)
473 struct urb
*urb
= context
->urb
;
475 if (test_bit(DEVICE_FLAGS_DISCONNECTED
, &priv
->flags
)) {
476 context
->in_use
= false;
480 usb_fill_bulk_urb(urb
,
482 usb_sndbulkpipe(priv
->usb
, 3),
485 vnt_tx_context_complete
,
488 status
= usb_submit_urb(urb
, GFP_ATOMIC
);
490 dev_dbg(&priv
->usb
->dev
, "Submit Tx URB failed %d\n", status
);
492 context
->in_use
= false;