1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. |
4 | * All rights reserved. |
5 | * |
6 | * Purpose: Provide functions to setup NIC operation mode |
7 | * Functions: |
8 | * s_vSafeResetTx - Rest Tx |
9 | * card_set_rspinf - Set RSPINF |
10 | * CARDvUpdateBasicTopRate - Update BasicTopRate |
11 | * CARDbAddBasicRate - Add to BasicRateSet |
12 | * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet |
13 | * card_get_tsf_offset - Calculate TSFOffset |
14 | * vt6655_get_current_tsf - Read Current NIC TSF counter |
15 | * card_get_next_tbtt - Calculate Next Beacon TSF counter |
16 | * CARDvSetFirstNextTBTT - Set NIC Beacon time |
17 | * CARDvUpdateNextTBTT - Sync. NIC Beacon time |
18 | * card_radio_power_off - Turn Off NIC Radio Power |
19 | * |
20 | * Revision History: |
21 | * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. |
22 | * 08-26-2003 Kyle Hsu: Modify the definition type of iobase. |
23 | * 09-01-2003 Bryan YC Fan: Add vUpdateIFS(). |
24 | * |
25 | */ |
26 | |
27 | #include "card.h" |
28 | #include "baseband.h" |
29 | #include "mac.h" |
30 | #include "desc.h" |
31 | #include "rf.h" |
32 | #include "power.h" |
33 | |
34 | /*--------------------- Static Definitions -------------------------*/ |
35 | |
36 | #define C_SIFS_A 16 /* micro sec. */ |
37 | #define C_SIFS_BG 10 |
38 | |
39 | #define C_EIFS 80 /* micro sec. */ |
40 | |
41 | #define C_SLOT_SHORT 9 /* micro sec. */ |
42 | #define C_SLOT_LONG 20 |
43 | |
44 | #define C_CWMIN_A 15 /* slot time */ |
45 | #define C_CWMIN_B 31 |
46 | |
47 | #define C_CWMAX 1023 /* slot time */ |
48 | |
49 | #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ |
50 | |
51 | /*--------------------- Static Variables --------------------------*/ |
52 | |
53 | static const unsigned short rx_bcn_tsf_off[MAX_RATE] = { |
54 | 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; |
55 | |
56 | /*--------------------- Static Functions --------------------------*/ |
57 | |
58 | static void vt6655_mac_set_bb_type(void __iomem *iobase, u32 mask) |
59 | { |
60 | u32 reg_value; |
61 | |
62 | reg_value = ioread32(iobase + MAC_REG_ENCFG); |
63 | reg_value = reg_value & ~ENCFG_BBTYPE_MASK; |
64 | reg_value = reg_value | mask; |
65 | iowrite32(reg_value, iobase + MAC_REG_ENCFG); |
66 | } |
67 | |
68 | /*--------------------- Export Functions --------------------------*/ |
69 | |
70 | /* |
71 | * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. |
72 | * |
73 | * Parameters: |
74 | * In: |
75 | * wRate - Tx Rate |
76 | * byPktType - Tx Packet type |
77 | * Out: |
78 | * tx_rate - pointer to RSPINF TxRate field |
79 | * rsv_time - pointer to RSPINF RsvTime field |
80 | * |
81 | * Return Value: none |
82 | */ |
83 | static void calculate_ofdmr_parameter(unsigned char rate, |
84 | u8 bb_type, |
85 | unsigned char *tx_rate, |
86 | unsigned char *rsv_time) |
87 | { |
88 | switch (rate) { |
89 | case RATE_6M: |
90 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
91 | *tx_rate = 0x9B; |
92 | *rsv_time = 44; |
93 | } else { |
94 | *tx_rate = 0x8B; |
95 | *rsv_time = 50; |
96 | } |
97 | break; |
98 | |
99 | case RATE_9M: |
100 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
101 | *tx_rate = 0x9F; |
102 | *rsv_time = 36; |
103 | } else { |
104 | *tx_rate = 0x8F; |
105 | *rsv_time = 42; |
106 | } |
107 | break; |
108 | |
109 | case RATE_12M: |
110 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
111 | *tx_rate = 0x9A; |
112 | *rsv_time = 32; |
113 | } else { |
114 | *tx_rate = 0x8A; |
115 | *rsv_time = 38; |
116 | } |
117 | break; |
118 | |
119 | case RATE_18M: |
120 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
121 | *tx_rate = 0x9E; |
122 | *rsv_time = 28; |
123 | } else { |
124 | *tx_rate = 0x8E; |
125 | *rsv_time = 34; |
126 | } |
127 | break; |
128 | |
129 | case RATE_36M: |
130 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
131 | *tx_rate = 0x9D; |
132 | *rsv_time = 24; |
133 | } else { |
134 | *tx_rate = 0x8D; |
135 | *rsv_time = 30; |
136 | } |
137 | break; |
138 | |
139 | case RATE_48M: |
140 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
141 | *tx_rate = 0x98; |
142 | *rsv_time = 24; |
143 | } else { |
144 | *tx_rate = 0x88; |
145 | *rsv_time = 30; |
146 | } |
147 | break; |
148 | |
149 | case RATE_54M: |
150 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
151 | *tx_rate = 0x9C; |
152 | *rsv_time = 24; |
153 | } else { |
154 | *tx_rate = 0x8C; |
155 | *rsv_time = 30; |
156 | } |
157 | break; |
158 | |
159 | case RATE_24M: |
160 | default: |
161 | if (bb_type == BB_TYPE_11A) { /* 5GHZ */ |
162 | *tx_rate = 0x99; |
163 | *rsv_time = 28; |
164 | } else { |
165 | *tx_rate = 0x89; |
166 | *rsv_time = 34; |
167 | } |
168 | break; |
169 | } |
170 | } |
171 | |
172 | /*--------------------- Export Functions --------------------------*/ |
173 | |
174 | /* |
175 | * Description: Update IFS |
176 | * |
177 | * Parameters: |
178 | * In: |
179 | * priv - The adapter to be set |
180 | * Out: |
181 | * none |
182 | * |
183 | * Return Value: None. |
184 | */ |
185 | bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type) |
186 | { |
187 | unsigned char cw_max_min = 0; |
188 | unsigned char slot = 0; |
189 | unsigned char sifs = 0; |
190 | unsigned char difs = 0; |
191 | int i; |
192 | |
193 | /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ |
194 | if (bb_type == BB_TYPE_11A) { |
195 | vt6655_mac_set_bb_type(iobase: priv->port_offset, BB_TYPE_11A); |
196 | bb_write_embedded(priv, by_bb_addr: 0x88, by_data: 0x03); |
197 | slot = C_SLOT_SHORT; |
198 | sifs = C_SIFS_A; |
199 | difs = C_SIFS_A + 2 * C_SLOT_SHORT; |
200 | cw_max_min = 0xA4; |
201 | } else if (bb_type == BB_TYPE_11B) { |
202 | vt6655_mac_set_bb_type(iobase: priv->port_offset, BB_TYPE_11B); |
203 | bb_write_embedded(priv, by_bb_addr: 0x88, by_data: 0x02); |
204 | slot = C_SLOT_LONG; |
205 | sifs = C_SIFS_BG; |
206 | difs = C_SIFS_BG + 2 * C_SLOT_LONG; |
207 | cw_max_min = 0xA5; |
208 | } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ |
209 | vt6655_mac_set_bb_type(iobase: priv->port_offset, BB_TYPE_11G); |
210 | bb_write_embedded(priv, by_bb_addr: 0x88, by_data: 0x08); |
211 | sifs = C_SIFS_BG; |
212 | |
213 | if (priv->short_slot_time) { |
214 | slot = C_SLOT_SHORT; |
215 | difs = C_SIFS_BG + 2 * C_SLOT_SHORT; |
216 | } else { |
217 | slot = C_SLOT_LONG; |
218 | difs = C_SIFS_BG + 2 * C_SLOT_LONG; |
219 | } |
220 | |
221 | cw_max_min = 0xa4; |
222 | |
223 | for (i = RATE_54M; i >= RATE_6M; i--) { |
224 | if (priv->basic_rates & ((u32)(0x1 << i))) { |
225 | cw_max_min |= 0x1; |
226 | break; |
227 | } |
228 | } |
229 | } |
230 | |
231 | if (priv->rf_type == RF_RFMD2959) { |
232 | /* |
233 | * bcs TX_PE will reserve 3 us hardware's processing |
234 | * time here is 2 us. |
235 | */ |
236 | sifs -= 3; |
237 | difs -= 3; |
238 | /* |
239 | * TX_PE will reserve 3 us for MAX2829 A mode only, it is for |
240 | * better TX throughput; MAC will need 2 us to process, so the |
241 | * SIFS, DIFS can be shorter by 2 us. |
242 | */ |
243 | } |
244 | |
245 | if (priv->sifs != sifs) { |
246 | priv->sifs = sifs; |
247 | iowrite8(priv->sifs, priv->port_offset + MAC_REG_SIFS); |
248 | } |
249 | if (priv->difs != difs) { |
250 | priv->difs = difs; |
251 | iowrite8(priv->difs, priv->port_offset + MAC_REG_DIFS); |
252 | } |
253 | if (priv->eifs != C_EIFS) { |
254 | priv->eifs = C_EIFS; |
255 | iowrite8(priv->eifs, priv->port_offset + MAC_REG_EIFS); |
256 | } |
257 | if (priv->slot != slot) { |
258 | priv->slot = slot; |
259 | iowrite8(priv->slot, priv->port_offset + MAC_REG_SLOT); |
260 | |
261 | bb_set_short_slot_time(priv); |
262 | } |
263 | if (priv->cw_max_min != cw_max_min) { |
264 | priv->cw_max_min = cw_max_min; |
265 | iowrite8(priv->cw_max_min, priv->port_offset + MAC_REG_CWMAXMIN0); |
266 | } |
267 | |
268 | priv->packet_type = card_get_pkt_type(priv); |
269 | |
270 | card_set_rspinf(priv, bb_type); |
271 | |
272 | return true; |
273 | } |
274 | |
275 | /* |
276 | * Description: Sync. TSF counter to BSS |
277 | * Get TSF offset and write to HW |
278 | * |
279 | * Parameters: |
280 | * In: |
281 | * priv - The adapter to be sync. |
282 | * rx_rate - data rate of receive beacon |
283 | * bss_timestamp - Rx BCN's TSF |
284 | * qwLocalTSF - Local TSF |
285 | * Out: |
286 | * none |
287 | * |
288 | * Return Value: none |
289 | */ |
290 | bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, |
291 | u64 bss_timestamp) |
292 | { |
293 | u64 local_tsf; |
294 | u64 tsf_offset = 0; |
295 | |
296 | local_tsf = vt6655_get_current_tsf(priv); |
297 | |
298 | if (bss_timestamp != local_tsf) { |
299 | tsf_offset = card_get_tsf_offset(rx_rate, qwTSF1: bss_timestamp, |
300 | qwTSF2: local_tsf); |
301 | /* adjust TSF, HW's TSF add TSF Offset reg */ |
302 | tsf_offset = le64_to_cpu(tsf_offset); |
303 | iowrite32((u32)tsf_offset, priv->port_offset + MAC_REG_TSFOFST); |
304 | iowrite32((u32)(tsf_offset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4); |
305 | vt6655_mac_reg_bits_on(iobase: priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); |
306 | } |
307 | return true; |
308 | } |
309 | |
310 | /* |
311 | * Description: Set NIC TSF counter for first Beacon time |
312 | * Get NEXTTBTT from adjusted TSF and Beacon Interval |
313 | * |
314 | * Parameters: |
315 | * In: |
316 | * priv - The adapter to be set. |
317 | * beacon_interval - Beacon Interval |
318 | * Out: |
319 | * none |
320 | * |
321 | * Return Value: true if succeed; otherwise false |
322 | */ |
323 | bool card_set_beacon_period(struct vnt_private *priv, |
324 | unsigned short beacon_interval) |
325 | { |
326 | u64 next_tbtt; |
327 | |
328 | next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ |
329 | |
330 | next_tbtt = card_get_next_tbtt(qwTSF: next_tbtt, beacon_interval); |
331 | |
332 | /* set HW beacon interval */ |
333 | iowrite16(beacon_interval, priv->port_offset + MAC_REG_BI); |
334 | priv->beacon_interval = beacon_interval; |
335 | /* Set NextTBTT */ |
336 | next_tbtt = le64_to_cpu(next_tbtt); |
337 | iowrite32((u32)next_tbtt, priv->port_offset + MAC_REG_NEXTTBTT); |
338 | iowrite32((u32)(next_tbtt >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4); |
339 | vt6655_mac_reg_bits_on(iobase: priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); |
340 | |
341 | return true; |
342 | } |
343 | |
344 | /* |
345 | * Description: Turn off Radio power |
346 | * |
347 | * Parameters: |
348 | * In: |
349 | * priv - The adapter to be turned off |
350 | * Out: |
351 | * none |
352 | * |
353 | */ |
354 | void card_radio_power_off(struct vnt_private *priv) |
355 | { |
356 | if (priv->radio_off) |
357 | return; |
358 | |
359 | switch (priv->rf_type) { |
360 | case RF_RFMD2959: |
361 | vt6655_mac_word_reg_bits_off(iobase: priv->port_offset, MAC_REG_SOFTPWRCTL, |
362 | SOFTPWRCTL_TXPEINV); |
363 | vt6655_mac_word_reg_bits_on(iobase: priv->port_offset, MAC_REG_SOFTPWRCTL, |
364 | SOFTPWRCTL_SWPE1); |
365 | break; |
366 | |
367 | case RF_AIROHA: |
368 | case RF_AL2230S: |
369 | vt6655_mac_word_reg_bits_off(iobase: priv->port_offset, MAC_REG_SOFTPWRCTL, |
370 | SOFTPWRCTL_SWPE2); |
371 | vt6655_mac_word_reg_bits_off(iobase: priv->port_offset, MAC_REG_SOFTPWRCTL, |
372 | SOFTPWRCTL_SWPE3); |
373 | break; |
374 | } |
375 | |
376 | vt6655_mac_reg_bits_off(iobase: priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON); |
377 | |
378 | bb_set_deep_sleep(priv, by_local_id: priv->local_id); |
379 | |
380 | priv->radio_off = true; |
381 | pr_debug("chester power off\n" ); |
382 | vt6655_mac_reg_bits_on(iobase: priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ |
383 | } |
384 | |
385 | void card_safe_reset_tx(struct vnt_private *priv) |
386 | { |
387 | unsigned int uu; |
388 | struct vnt_tx_desc *curr_td; |
389 | |
390 | /* initialize TD index */ |
391 | priv->tail_td[0] = &priv->apTD0Rings[0]; |
392 | priv->apCurrTD[0] = &priv->apTD0Rings[0]; |
393 | |
394 | priv->tail_td[1] = &priv->apTD1Rings[0]; |
395 | priv->apCurrTD[1] = &priv->apTD1Rings[0]; |
396 | |
397 | for (uu = 0; uu < TYPE_MAXTD; uu++) |
398 | priv->iTDUsed[uu] = 0; |
399 | |
400 | for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) { |
401 | curr_td = &priv->apTD0Rings[uu]; |
402 | curr_td->td0.owner = OWNED_BY_HOST; |
403 | /* init all Tx Packet pointer to NULL */ |
404 | } |
405 | for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) { |
406 | curr_td = &priv->apTD1Rings[uu]; |
407 | curr_td->td0.owner = OWNED_BY_HOST; |
408 | /* init all Tx Packet pointer to NULL */ |
409 | } |
410 | |
411 | /* set MAC TD pointer */ |
412 | vt6655_mac_set_curr_tx_desc_addr(TYPE_TXDMA0, priv, curr_desc_addr: priv->td0_pool_dma); |
413 | |
414 | vt6655_mac_set_curr_tx_desc_addr(TYPE_AC0DMA, priv, curr_desc_addr: priv->td1_pool_dma); |
415 | |
416 | /* set MAC Beacon TX pointer */ |
417 | iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR); |
418 | } |
419 | |
420 | /* |
421 | * Description: |
422 | * Reset Rx |
423 | * |
424 | * Parameters: |
425 | * In: |
426 | * priv - Pointer to the adapter |
427 | * Out: |
428 | * none |
429 | * |
430 | * Return Value: none |
431 | */ |
432 | void CARDvSafeResetRx(struct vnt_private *priv) |
433 | { |
434 | unsigned int uu; |
435 | struct vnt_rx_desc *pDesc; |
436 | |
437 | /* initialize RD index */ |
438 | priv->pCurrRD[0] = &priv->aRD0Ring[0]; |
439 | priv->pCurrRD[1] = &priv->aRD1Ring[0]; |
440 | |
441 | /* init state, all RD is chip's */ |
442 | for (uu = 0; uu < priv->opts.rx_descs0; uu++) { |
443 | pDesc = &priv->aRD0Ring[uu]; |
444 | pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); |
445 | pDesc->rd0.owner = OWNED_BY_NIC; |
446 | pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); |
447 | } |
448 | |
449 | /* init state, all RD is chip's */ |
450 | for (uu = 0; uu < priv->opts.rx_descs1; uu++) { |
451 | pDesc = &priv->aRD1Ring[uu]; |
452 | pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); |
453 | pDesc->rd0.owner = OWNED_BY_NIC; |
454 | pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); |
455 | } |
456 | |
457 | /* set perPkt mode */ |
458 | iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0); |
459 | iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1); |
460 | /* set MAC RD pointer */ |
461 | vt6655_mac_set_curr_rx_0_desc_addr(priv, curr_desc_addr: priv->rd0_pool_dma); |
462 | |
463 | vt6655_mac_set_curr_rx_1_desc_addr(priv, curr_desc_addr: priv->rd1_pool_dma); |
464 | } |
465 | |
466 | /* |
467 | * Description: Get response Control frame rate in CCK mode |
468 | * |
469 | * Parameters: |
470 | * In: |
471 | * priv - The adapter to be set |
472 | * wRateIdx - Receiving data rate |
473 | * Out: |
474 | * none |
475 | * |
476 | * Return Value: response Control frame rate |
477 | */ |
478 | static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv, |
479 | unsigned short wRateIdx) |
480 | { |
481 | unsigned int ui = (unsigned int)wRateIdx; |
482 | |
483 | while (ui > RATE_1M) { |
484 | if (priv->basic_rates & ((u32)0x1 << ui)) |
485 | return (unsigned short)ui; |
486 | |
487 | ui--; |
488 | } |
489 | return (unsigned short)RATE_1M; |
490 | } |
491 | |
492 | /* |
493 | * Description: Get response Control frame rate in OFDM mode |
494 | * |
495 | * Parameters: |
496 | * In: |
497 | * priv - The adapter to be set |
498 | * wRateIdx - Receiving data rate |
499 | * Out: |
500 | * none |
501 | * |
502 | * Return Value: response Control frame rate |
503 | */ |
504 | static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, |
505 | unsigned short wRateIdx) |
506 | { |
507 | unsigned int ui = (unsigned int)wRateIdx; |
508 | |
509 | pr_debug("BASIC RATE: %X\n" , priv->basic_rates); |
510 | |
511 | if (!CARDbIsOFDMinBasicRate(priv: (void *)priv)) { |
512 | pr_debug("%s:(NO OFDM) %d\n" , __func__, wRateIdx); |
513 | if (wRateIdx > RATE_24M) |
514 | wRateIdx = RATE_24M; |
515 | return wRateIdx; |
516 | } |
517 | while (ui > RATE_11M) { |
518 | if (priv->basic_rates & ((u32)0x1 << ui)) { |
519 | pr_debug("%s : %d\n" , __func__, ui); |
520 | return (unsigned short)ui; |
521 | } |
522 | ui--; |
523 | } |
524 | pr_debug("%s: 6M\n" , __func__); |
525 | return (unsigned short)RATE_24M; |
526 | } |
527 | |
528 | /* |
529 | * Description: Set RSPINF |
530 | * |
531 | * Parameters: |
532 | * In: |
533 | * priv - The adapter to be set |
534 | * Out: |
535 | * none |
536 | * |
537 | * Return Value: None. |
538 | */ |
539 | void card_set_rspinf(struct vnt_private *priv, u8 bb_type) |
540 | { |
541 | union vnt_phy_field_swap phy; |
542 | unsigned char byTxRate, byRsvTime; /* For OFDM */ |
543 | unsigned long flags; |
544 | |
545 | spin_lock_irqsave(&priv->lock, flags); |
546 | |
547 | /* Set to Page1 */ |
548 | VT6655_MAC_SELECT_PAGE1(priv->port_offset); |
549 | |
550 | /* RSPINF_b_1 */ |
551 | vnt_get_phy_field(priv, frame_length: 14, |
552 | tx_rate: CARDwGetCCKControlRate(priv, RATE_1M), |
553 | PK_TYPE_11B, phy: &phy.field_read); |
554 | |
555 | /* swap over to get correct write order */ |
556 | swap(phy.swap[0], phy.swap[1]); |
557 | |
558 | iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1); |
559 | |
560 | /* RSPINF_b_2 */ |
561 | vnt_get_phy_field(priv, frame_length: 14, |
562 | tx_rate: CARDwGetCCKControlRate(priv, RATE_2M), |
563 | PK_TYPE_11B, phy: &phy.field_read); |
564 | |
565 | swap(phy.swap[0], phy.swap[1]); |
566 | |
567 | iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2); |
568 | |
569 | /* RSPINF_b_5 */ |
570 | vnt_get_phy_field(priv, frame_length: 14, |
571 | tx_rate: CARDwGetCCKControlRate(priv, RATE_5M), |
572 | PK_TYPE_11B, phy: &phy.field_read); |
573 | |
574 | swap(phy.swap[0], phy.swap[1]); |
575 | |
576 | iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5); |
577 | |
578 | /* RSPINF_b_11 */ |
579 | vnt_get_phy_field(priv, frame_length: 14, |
580 | tx_rate: CARDwGetCCKControlRate(priv, RATE_11M), |
581 | PK_TYPE_11B, phy: &phy.field_read); |
582 | |
583 | swap(phy.swap[0], phy.swap[1]); |
584 | |
585 | iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11); |
586 | |
587 | /* RSPINF_a_6 */ |
588 | calculate_ofdmr_parameter(RATE_6M, |
589 | bb_type, |
590 | tx_rate: &byTxRate, |
591 | rsv_time: &byRsvTime); |
592 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6); |
593 | /* RSPINF_a_9 */ |
594 | calculate_ofdmr_parameter(RATE_9M, |
595 | bb_type, |
596 | tx_rate: &byTxRate, |
597 | rsv_time: &byRsvTime); |
598 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9); |
599 | /* RSPINF_a_12 */ |
600 | calculate_ofdmr_parameter(RATE_12M, |
601 | bb_type, |
602 | tx_rate: &byTxRate, |
603 | rsv_time: &byRsvTime); |
604 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12); |
605 | /* RSPINF_a_18 */ |
606 | calculate_ofdmr_parameter(RATE_18M, |
607 | bb_type, |
608 | tx_rate: &byTxRate, |
609 | rsv_time: &byRsvTime); |
610 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18); |
611 | /* RSPINF_a_24 */ |
612 | calculate_ofdmr_parameter(RATE_24M, |
613 | bb_type, |
614 | tx_rate: &byTxRate, |
615 | rsv_time: &byRsvTime); |
616 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24); |
617 | /* RSPINF_a_36 */ |
618 | calculate_ofdmr_parameter(rate: CARDwGetOFDMControlRate(priv: (void *)priv, |
619 | RATE_36M), |
620 | bb_type, |
621 | tx_rate: &byTxRate, |
622 | rsv_time: &byRsvTime); |
623 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36); |
624 | /* RSPINF_a_48 */ |
625 | calculate_ofdmr_parameter(rate: CARDwGetOFDMControlRate(priv: (void *)priv, |
626 | RATE_48M), |
627 | bb_type, |
628 | tx_rate: &byTxRate, |
629 | rsv_time: &byRsvTime); |
630 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48); |
631 | /* RSPINF_a_54 */ |
632 | calculate_ofdmr_parameter(rate: CARDwGetOFDMControlRate(priv: (void *)priv, |
633 | RATE_54M), |
634 | bb_type, |
635 | tx_rate: &byTxRate, |
636 | rsv_time: &byRsvTime); |
637 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54); |
638 | /* RSPINF_a_72 */ |
639 | calculate_ofdmr_parameter(rate: CARDwGetOFDMControlRate(priv: (void *)priv, |
640 | RATE_54M), |
641 | bb_type, |
642 | tx_rate: &byTxRate, |
643 | rsv_time: &byRsvTime); |
644 | iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72); |
645 | /* Set to Page0 */ |
646 | VT6655_MAC_SELECT_PAGE0(priv->port_offset); |
647 | |
648 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
649 | } |
650 | |
651 | void CARDvUpdateBasicTopRate(struct vnt_private *priv) |
652 | { |
653 | unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; |
654 | unsigned char ii; |
655 | |
656 | /* Determines the highest basic rate. */ |
657 | for (ii = RATE_54M; ii >= RATE_6M; ii--) { |
658 | if ((priv->basic_rates) & ((u32)(1 << ii))) { |
659 | byTopOFDM = ii; |
660 | break; |
661 | } |
662 | } |
663 | priv->byTopOFDMBasicRate = byTopOFDM; |
664 | |
665 | for (ii = RATE_11M;; ii--) { |
666 | if ((priv->basic_rates) & ((u32)(1 << ii))) { |
667 | byTopCCK = ii; |
668 | break; |
669 | } |
670 | if (ii == RATE_1M) |
671 | break; |
672 | } |
673 | priv->byTopCCKBasicRate = byTopCCK; |
674 | } |
675 | |
676 | bool CARDbIsOFDMinBasicRate(struct vnt_private *priv) |
677 | { |
678 | int ii; |
679 | |
680 | for (ii = RATE_54M; ii >= RATE_6M; ii--) { |
681 | if ((priv->basic_rates) & ((u32)BIT(ii))) |
682 | return true; |
683 | } |
684 | return false; |
685 | } |
686 | |
687 | unsigned char card_get_pkt_type(struct vnt_private *priv) |
688 | { |
689 | if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) |
690 | return (unsigned char)priv->byBBType; |
691 | else if (CARDbIsOFDMinBasicRate(priv: (void *)priv)) |
692 | return PK_TYPE_11GA; |
693 | else |
694 | return PK_TYPE_11GB; |
695 | } |
696 | |
697 | /* |
698 | * Description: Calculate TSF offset of two TSF input |
699 | * Get TSF Offset from RxBCN's TSF and local TSF |
700 | * |
701 | * Parameters: |
702 | * In: |
703 | * priv - The adapter to be sync. |
704 | * qwTSF1 - Rx BCN's TSF |
705 | * qwTSF2 - Local TSF |
706 | * Out: |
707 | * none |
708 | * |
709 | * Return Value: TSF Offset value |
710 | */ |
711 | u64 card_get_tsf_offset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2) |
712 | { |
713 | unsigned short wRxBcnTSFOffst; |
714 | |
715 | wRxBcnTSFOffst = rx_bcn_tsf_off[rx_rate % MAX_RATE]; |
716 | |
717 | qwTSF2 += (u64)wRxBcnTSFOffst; |
718 | |
719 | return qwTSF1 - qwTSF2; |
720 | } |
721 | |
722 | /* |
723 | * Description: Read NIC TSF counter |
724 | * Get local TSF counter |
725 | * |
726 | * Parameters: |
727 | * In: |
728 | * priv - The adapter to be read |
729 | * Out: |
730 | * none |
731 | * |
732 | * Return Value: Current TSF counter |
733 | */ |
734 | u64 vt6655_get_current_tsf(struct vnt_private *priv) |
735 | { |
736 | void __iomem *iobase = priv->port_offset; |
737 | unsigned short ww; |
738 | unsigned char data; |
739 | u32 low, high; |
740 | |
741 | vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); |
742 | for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
743 | data = ioread8(iobase + MAC_REG_TFTCTL); |
744 | if (!(data & TFTCTL_TSFCNTRRD)) |
745 | break; |
746 | } |
747 | if (ww == W_MAX_TIMEOUT) |
748 | return 0; |
749 | low = ioread32(iobase + MAC_REG_TSFCNTR); |
750 | high = ioread32(iobase + MAC_REG_TSFCNTR + 4); |
751 | return le64_to_cpu(low + ((u64)high << 32)); |
752 | } |
753 | |
754 | /* |
755 | * Description: Read NIC TSF counter |
756 | * Get NEXTTBTT from adjusted TSF and Beacon Interval |
757 | * |
758 | * Parameters: |
759 | * In: |
760 | * qwTSF - Current TSF counter |
761 | * wbeaconInterval - Beacon Interval |
762 | * Out: |
763 | * qwCurrTSF - Current TSF counter |
764 | * |
765 | * Return Value: TSF value of next Beacon |
766 | */ |
767 | u64 card_get_next_tbtt(u64 qwTSF, unsigned short beacon_interval) |
768 | { |
769 | u32 beacon_int; |
770 | |
771 | beacon_int = beacon_interval * 1024; |
772 | if (beacon_int) { |
773 | do_div(qwTSF, beacon_int); |
774 | qwTSF += 1; |
775 | qwTSF *= beacon_int; |
776 | } |
777 | |
778 | return qwTSF; |
779 | } |
780 | |
781 | /* |
782 | * Description: Set NIC TSF counter for first Beacon time |
783 | * Get NEXTTBTT from adjusted TSF and Beacon Interval |
784 | * |
785 | * Parameters: |
786 | * In: |
787 | * iobase - IO Base |
788 | * beacon_interval - Beacon Interval |
789 | * Out: |
790 | * none |
791 | * |
792 | * Return Value: none |
793 | */ |
794 | void CARDvSetFirstNextTBTT(struct vnt_private *priv, |
795 | unsigned short beacon_interval) |
796 | { |
797 | void __iomem *iobase = priv->port_offset; |
798 | u64 next_tbtt; |
799 | |
800 | next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ |
801 | |
802 | next_tbtt = card_get_next_tbtt(qwTSF: next_tbtt, beacon_interval); |
803 | /* Set NextTBTT */ |
804 | next_tbtt = le64_to_cpu(next_tbtt); |
805 | iowrite32((u32)next_tbtt, iobase + MAC_REG_NEXTTBTT); |
806 | iowrite32((u32)(next_tbtt >> 32), iobase + MAC_REG_NEXTTBTT + 4); |
807 | vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); |
808 | } |
809 | |
810 | /* |
811 | * Description: Sync NIC TSF counter for Beacon time |
812 | * Get NEXTTBTT and write to HW |
813 | * |
814 | * Parameters: |
815 | * In: |
816 | * priv - The adapter to be set |
817 | * qwTSF - Current TSF counter |
818 | * beacon_interval - Beacon Interval |
819 | * Out: |
820 | * none |
821 | * |
822 | * Return Value: none |
823 | */ |
824 | void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, |
825 | unsigned short beacon_interval) |
826 | { |
827 | void __iomem *iobase = priv->port_offset; |
828 | |
829 | qwTSF = card_get_next_tbtt(qwTSF, beacon_interval); |
830 | /* Set NextTBTT */ |
831 | qwTSF = le64_to_cpu(qwTSF); |
832 | iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT); |
833 | iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4); |
834 | vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); |
835 | pr_debug("Card:Update Next TBTT[%8llx]\n" , qwTSF); |
836 | } |
837 | |