diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 178 |
1 files changed, 165 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e37bbeab9233..db4250d1c8b3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -282,6 +282,104 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | |||
282 | } | 282 | } |
283 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); | 283 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); |
284 | 284 | ||
285 | void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) | ||
286 | { | ||
287 | __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE); | ||
288 | u32 word; | ||
289 | |||
290 | /* | ||
291 | * Initialize TX Info descriptor | ||
292 | */ | ||
293 | rt2x00_desc_read(txwi, 0, &word); | ||
294 | rt2x00_set_field32(&word, TXWI_W0_FRAG, | ||
295 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | ||
296 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); | ||
297 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); | ||
298 | rt2x00_set_field32(&word, TXWI_W0_TS, | ||
299 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | ||
300 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, | ||
301 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); | ||
302 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); | ||
303 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop); | ||
304 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); | ||
305 | rt2x00_set_field32(&word, TXWI_W0_BW, | ||
306 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); | ||
307 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, | ||
308 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); | ||
309 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); | ||
310 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); | ||
311 | rt2x00_desc_write(txwi, 0, word); | ||
312 | |||
313 | rt2x00_desc_read(txwi, 1, &word); | ||
314 | rt2x00_set_field32(&word, TXWI_W1_ACK, | ||
315 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); | ||
316 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, | ||
317 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | ||
318 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); | ||
319 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, | ||
320 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | ||
321 | txdesc->key_idx : 0xff); | ||
322 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | ||
323 | txdesc->length); | ||
324 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); | ||
325 | rt2x00_desc_write(txwi, 1, word); | ||
326 | |||
327 | /* | ||
328 | * Always write 0 to IV/EIV fields, hardware will insert the IV | ||
329 | * from the IVEIV register when TXD_W3_WIV is set to 0. | ||
330 | * When TXD_W3_WIV is set to 1 it will use the IV data | ||
331 | * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which | ||
332 | * crypto entry in the registers should be used to encrypt the frame. | ||
333 | */ | ||
334 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | ||
335 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(rt2800_write_txwi); | ||
338 | |||
339 | void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc) | ||
340 | { | ||
341 | __le32 *rxwi = (__le32 *) skb->data; | ||
342 | u32 word; | ||
343 | |||
344 | rt2x00_desc_read(rxwi, 0, &word); | ||
345 | |||
346 | rxdesc->cipher = rt2x00_get_field32(word, RXWI_W0_UDF); | ||
347 | rxdesc->size = rt2x00_get_field32(word, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); | ||
348 | |||
349 | rt2x00_desc_read(rxwi, 1, &word); | ||
350 | |||
351 | if (rt2x00_get_field32(word, RXWI_W1_SHORT_GI)) | ||
352 | rxdesc->flags |= RX_FLAG_SHORT_GI; | ||
353 | |||
354 | if (rt2x00_get_field32(word, RXWI_W1_BW)) | ||
355 | rxdesc->flags |= RX_FLAG_40MHZ; | ||
356 | |||
357 | /* | ||
358 | * Detect RX rate, always use MCS as signal type. | ||
359 | */ | ||
360 | rxdesc->dev_flags |= RXDONE_SIGNAL_MCS; | ||
361 | rxdesc->signal = rt2x00_get_field32(word, RXWI_W1_MCS); | ||
362 | rxdesc->rate_mode = rt2x00_get_field32(word, RXWI_W1_PHYMODE); | ||
363 | |||
364 | /* | ||
365 | * Mask of 0x8 bit to remove the short preamble flag. | ||
366 | */ | ||
367 | if (rxdesc->rate_mode == RATE_MODE_CCK) | ||
368 | rxdesc->signal &= ~0x8; | ||
369 | |||
370 | rt2x00_desc_read(rxwi, 2, &word); | ||
371 | |||
372 | rxdesc->rssi = | ||
373 | (rt2x00_get_field32(word, RXWI_W2_RSSI0) + | ||
374 | rt2x00_get_field32(word, RXWI_W2_RSSI1)) / 2; | ||
375 | |||
376 | /* | ||
377 | * Remove RXWI descriptor from start of buffer. | ||
378 | */ | ||
379 | skb_pull(skb, RXWI_DESC_SIZE); | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | ||
382 | |||
285 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 383 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
286 | const struct rt2x00debug rt2800_rt2x00debug = { | 384 | const struct rt2x00debug rt2800_rt2x00debug = { |
287 | .owner = THIS_MODULE, | 385 | .owner = THIS_MODULE, |
@@ -640,8 +738,6 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp) | |||
640 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | 738 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); |
641 | 739 | ||
642 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | 740 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); |
643 | rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs); | ||
644 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs); | ||
645 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); | 741 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); |
646 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); | 742 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); |
647 | 743 | ||
@@ -1415,9 +1511,16 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1415 | 1511 | ||
1416 | rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca); | 1512 | rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca); |
1417 | 1513 | ||
1514 | /* | ||
1515 | * Usually the CCK SIFS time should be set to 10 and the OFDM SIFS | ||
1516 | * time should be set to 16. However, the original Ralink driver uses | ||
1517 | * 16 for both and indeed using a value of 10 for CCK SIFS results in | ||
1518 | * connection problems with 11g + CTS protection. Hence, use the same | ||
1519 | * defaults as the Ralink driver: 16 for both, CCK and OFDM SIFS. | ||
1520 | */ | ||
1418 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | 1521 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); |
1419 | rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, 32); | 1522 | rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, 16); |
1420 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, 32); | 1523 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, 16); |
1421 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4); | 1524 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4); |
1422 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, 314); | 1525 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, 314); |
1423 | rt2x00_set_field32(®, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1); | 1526 | rt2x00_set_field32(®, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1); |
@@ -2219,7 +2322,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2219 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); | 2322 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); |
2220 | 2323 | ||
2221 | /* | 2324 | /* |
2222 | * RF value list for rt28x0 | 2325 | * RF value list for rt28xx |
2223 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) | 2326 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) |
2224 | */ | 2327 | */ |
2225 | static const struct rf_channel rf_vals[] = { | 2328 | static const struct rf_channel rf_vals[] = { |
@@ -2294,10 +2397,10 @@ static const struct rf_channel rf_vals[] = { | |||
2294 | }; | 2397 | }; |
2295 | 2398 | ||
2296 | /* | 2399 | /* |
2297 | * RF value list for rt3070 | 2400 | * RF value list for rt3xxx |
2298 | * Supports: 2.4 GHz | 2401 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052) |
2299 | */ | 2402 | */ |
2300 | static const struct rf_channel rf_vals_302x[] = { | 2403 | static const struct rf_channel rf_vals_3x[] = { |
2301 | {1, 241, 2, 2 }, | 2404 | {1, 241, 2, 2 }, |
2302 | {2, 241, 2, 7 }, | 2405 | {2, 241, 2, 7 }, |
2303 | {3, 242, 2, 2 }, | 2406 | {3, 242, 2, 2 }, |
@@ -2312,6 +2415,51 @@ static const struct rf_channel rf_vals_302x[] = { | |||
2312 | {12, 246, 2, 7 }, | 2415 | {12, 246, 2, 7 }, |
2313 | {13, 247, 2, 2 }, | 2416 | {13, 247, 2, 2 }, |
2314 | {14, 248, 2, 4 }, | 2417 | {14, 248, 2, 4 }, |
2418 | |||
2419 | /* 802.11 UNI / HyperLan 2 */ | ||
2420 | {36, 0x56, 0, 4}, | ||
2421 | {38, 0x56, 0, 6}, | ||
2422 | {40, 0x56, 0, 8}, | ||
2423 | {44, 0x57, 0, 0}, | ||
2424 | {46, 0x57, 0, 2}, | ||
2425 | {48, 0x57, 0, 4}, | ||
2426 | {52, 0x57, 0, 8}, | ||
2427 | {54, 0x57, 0, 10}, | ||
2428 | {56, 0x58, 0, 0}, | ||
2429 | {60, 0x58, 0, 4}, | ||
2430 | {62, 0x58, 0, 6}, | ||
2431 | {64, 0x58, 0, 8}, | ||
2432 | |||
2433 | /* 802.11 HyperLan 2 */ | ||
2434 | {100, 0x5b, 0, 8}, | ||
2435 | {102, 0x5b, 0, 10}, | ||
2436 | {104, 0x5c, 0, 0}, | ||
2437 | {108, 0x5c, 0, 4}, | ||
2438 | {110, 0x5c, 0, 6}, | ||
2439 | {112, 0x5c, 0, 8}, | ||
2440 | {116, 0x5d, 0, 0}, | ||
2441 | {118, 0x5d, 0, 2}, | ||
2442 | {120, 0x5d, 0, 4}, | ||
2443 | {124, 0x5d, 0, 8}, | ||
2444 | {126, 0x5d, 0, 10}, | ||
2445 | {128, 0x5e, 0, 0}, | ||
2446 | {132, 0x5e, 0, 4}, | ||
2447 | {134, 0x5e, 0, 6}, | ||
2448 | {136, 0x5e, 0, 8}, | ||
2449 | {140, 0x5f, 0, 0}, | ||
2450 | |||
2451 | /* 802.11 UNII */ | ||
2452 | {149, 0x5f, 0, 9}, | ||
2453 | {151, 0x5f, 0, 11}, | ||
2454 | {153, 0x60, 0, 1}, | ||
2455 | {157, 0x60, 0, 5}, | ||
2456 | {159, 0x60, 0, 7}, | ||
2457 | {161, 0x60, 0, 9}, | ||
2458 | {165, 0x61, 0, 1}, | ||
2459 | {167, 0x61, 0, 3}, | ||
2460 | {169, 0x61, 0, 5}, | ||
2461 | {171, 0x61, 0, 7}, | ||
2462 | {173, 0x61, 0, 9}, | ||
2315 | }; | 2463 | }; |
2316 | 2464 | ||
2317 | int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | 2465 | int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) |
@@ -2352,11 +2500,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2352 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | 2500 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2353 | 2501 | ||
2354 | if (rt2x00_rf(rt2x00dev, RF2820) || | 2502 | if (rt2x00_rf(rt2x00dev, RF2820) || |
2355 | rt2x00_rf(rt2x00dev, RF2720) || | 2503 | rt2x00_rf(rt2x00dev, RF2720)) { |
2356 | rt2x00_rf(rt2x00dev, RF3052)) { | ||
2357 | spec->num_channels = 14; | 2504 | spec->num_channels = 14; |
2358 | spec->channels = rf_vals; | 2505 | spec->channels = rf_vals; |
2359 | } else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) { | 2506 | } else if (rt2x00_rf(rt2x00dev, RF2850) || |
2507 | rt2x00_rf(rt2x00dev, RF2750)) { | ||
2360 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | 2508 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2361 | spec->num_channels = ARRAY_SIZE(rf_vals); | 2509 | spec->num_channels = ARRAY_SIZE(rf_vals); |
2362 | spec->channels = rf_vals; | 2510 | spec->channels = rf_vals; |
@@ -2364,8 +2512,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2364 | rt2x00_rf(rt2x00dev, RF2020) || | 2512 | rt2x00_rf(rt2x00dev, RF2020) || |
2365 | rt2x00_rf(rt2x00dev, RF3021) || | 2513 | rt2x00_rf(rt2x00dev, RF3021) || |
2366 | rt2x00_rf(rt2x00dev, RF3022)) { | 2514 | rt2x00_rf(rt2x00dev, RF3022)) { |
2367 | spec->num_channels = ARRAY_SIZE(rf_vals_302x); | 2515 | spec->num_channels = 14; |
2368 | spec->channels = rf_vals_302x; | 2516 | spec->channels = rf_vals_3x; |
2517 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { | ||
2518 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
2519 | spec->num_channels = ARRAY_SIZE(rf_vals_3x); | ||
2520 | spec->channels = rf_vals_3x; | ||
2369 | } | 2521 | } |
2370 | 2522 | ||
2371 | /* | 2523 | /* |