diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 029be3c6c030..02f1148c577e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -502,26 +502,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
502 | struct rt2x00intf_conf *conf, | 502 | struct rt2x00intf_conf *conf, |
503 | const unsigned int flags) | 503 | const unsigned int flags) |
504 | { | 504 | { |
505 | unsigned int beacon_base; | ||
506 | u32 reg; | 505 | u32 reg; |
507 | 506 | ||
508 | if (flags & CONFIG_UPDATE_TYPE) { | 507 | if (flags & CONFIG_UPDATE_TYPE) { |
509 | /* | 508 | /* |
510 | * Clear current synchronisation setup. | ||
511 | * For the Beacon base registers we only need to clear | ||
512 | * the first byte since that byte contains the VALID and OWNER | ||
513 | * bits which (when set to 0) will invalidate the entire beacon. | ||
514 | */ | ||
515 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
516 | rt2x00usb_register_write(rt2x00dev, beacon_base, 0); | ||
517 | |||
518 | /* | ||
519 | * Enable synchronisation. | 509 | * Enable synchronisation. |
520 | */ | 510 | */ |
521 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 511 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
522 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
523 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 512 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
524 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
525 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 513 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
526 | } | 514 | } |
527 | 515 | ||
@@ -1440,9 +1428,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1440 | rt73usb_disable_radio(rt2x00dev); | 1428 | rt73usb_disable_radio(rt2x00dev); |
1441 | break; | 1429 | break; |
1442 | case STATE_RADIO_IRQ_ON: | 1430 | case STATE_RADIO_IRQ_ON: |
1443 | case STATE_RADIO_IRQ_ON_ISR: | ||
1444 | case STATE_RADIO_IRQ_OFF: | 1431 | case STATE_RADIO_IRQ_OFF: |
1445 | case STATE_RADIO_IRQ_OFF_ISR: | ||
1446 | /* No support, but no error either */ | 1432 | /* No support, but no error either */ |
1447 | break; | 1433 | break; |
1448 | case STATE_DEEP_SLEEP: | 1434 | case STATE_DEEP_SLEEP: |
@@ -1488,7 +1474,7 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, | |||
1488 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1474 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1489 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1475 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1490 | (txdesc->rate_mode == RATE_MODE_OFDM)); | 1476 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1491 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1477 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1492 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1478 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1493 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1479 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1494 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, | 1480 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, |
@@ -1513,10 +1499,12 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, | |||
1513 | rt2x00_desc_write(txd, 1, word); | 1499 | rt2x00_desc_write(txd, 1, word); |
1514 | 1500 | ||
1515 | rt2x00_desc_read(txd, 2, &word); | 1501 | rt2x00_desc_read(txd, 2, &word); |
1516 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); | 1502 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1517 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); | 1503 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); |
1518 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); | 1504 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, |
1519 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1505 | txdesc->u.plcp.length_low); |
1506 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, | ||
1507 | txdesc->u.plcp.length_high); | ||
1520 | rt2x00_desc_write(txd, 2, word); | 1508 | rt2x00_desc_write(txd, 2, word); |
1521 | 1509 | ||
1522 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1510 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
@@ -1547,13 +1535,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1547 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1535 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
1548 | unsigned int beacon_base; | 1536 | unsigned int beacon_base; |
1549 | unsigned int padding_len; | 1537 | unsigned int padding_len; |
1550 | u32 reg; | 1538 | u32 orig_reg, reg; |
1551 | 1539 | ||
1552 | /* | 1540 | /* |
1553 | * Disable beaconing while we are reloading the beacon data, | 1541 | * Disable beaconing while we are reloading the beacon data, |
1554 | * otherwise we might be sending out invalid data. | 1542 | * otherwise we might be sending out invalid data. |
1555 | */ | 1543 | */ |
1556 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1544 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1545 | orig_reg = reg; | ||
1557 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1546 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
1558 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1547 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1559 | 1548 | ||
@@ -1577,7 +1566,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1577 | * Write entire beacon with descriptor and padding to register. | 1566 | * Write entire beacon with descriptor and padding to register. |
1578 | */ | 1567 | */ |
1579 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 1568 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
1580 | skb_pad(entry->skb, padding_len); | 1569 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
1570 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | ||
1571 | /* skb freed by skb_pad() on failure */ | ||
1572 | entry->skb = NULL; | ||
1573 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); | ||
1574 | return; | ||
1575 | } | ||
1576 | |||
1581 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 1577 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
1582 | rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, | 1578 | rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, |
1583 | entry->skb->len + padding_len); | 1579 | entry->skb->len + padding_len); |
@@ -1590,8 +1586,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1590 | */ | 1586 | */ |
1591 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); | 1587 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); |
1592 | 1588 | ||
1593 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1594 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1595 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1589 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1596 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1590 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1597 | 1591 | ||
@@ -1602,6 +1596,33 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1602 | entry->skb = NULL; | 1596 | entry->skb = NULL; |
1603 | } | 1597 | } |
1604 | 1598 | ||
1599 | static void rt73usb_clear_beacon(struct queue_entry *entry) | ||
1600 | { | ||
1601 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1602 | unsigned int beacon_base; | ||
1603 | u32 reg; | ||
1604 | |||
1605 | /* | ||
1606 | * Disable beaconing while we are reloading the beacon data, | ||
1607 | * otherwise we might be sending out invalid data. | ||
1608 | */ | ||
1609 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1610 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1611 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1612 | |||
1613 | /* | ||
1614 | * Clear beacon. | ||
1615 | */ | ||
1616 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1617 | rt2x00usb_register_write(rt2x00dev, beacon_base, 0); | ||
1618 | |||
1619 | /* | ||
1620 | * Enable beaconing again. | ||
1621 | */ | ||
1622 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
1623 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1624 | } | ||
1625 | |||
1605 | static int rt73usb_get_tx_data_len(struct queue_entry *entry) | 1626 | static int rt73usb_get_tx_data_len(struct queue_entry *entry) |
1606 | { | 1627 | { |
1607 | int length; | 1628 | int length; |
@@ -1698,9 +1719,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1698 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | 1719 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; |
1699 | 1720 | ||
1700 | /* | 1721 | /* |
1701 | * FIXME: Legacy driver indicates that the frame does | 1722 | * The hardware has already checked the Michael Mic and has |
1702 | * contain the Michael Mic. Unfortunately, in rt2x00 | 1723 | * stripped it from the frame. Signal this to mac80211. |
1703 | * the MIC seems to be missing completely... | ||
1704 | */ | 1724 | */ |
1705 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | 1725 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; |
1706 | 1726 | ||
@@ -2229,7 +2249,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2229 | if (queue_idx >= 4) | 2249 | if (queue_idx >= 4) |
2230 | return 0; | 2250 | return 0; |
2231 | 2251 | ||
2232 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 2252 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
2233 | 2253 | ||
2234 | /* Update WMM TXOP register */ | 2254 | /* Update WMM TXOP register */ |
2235 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); | 2255 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); |
@@ -2313,6 +2333,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2313 | .flush_queue = rt2x00usb_flush_queue, | 2333 | .flush_queue = rt2x00usb_flush_queue, |
2314 | .write_tx_desc = rt73usb_write_tx_desc, | 2334 | .write_tx_desc = rt73usb_write_tx_desc, |
2315 | .write_beacon = rt73usb_write_beacon, | 2335 | .write_beacon = rt73usb_write_beacon, |
2336 | .clear_beacon = rt73usb_clear_beacon, | ||
2316 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2337 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2317 | .fill_rxdone = rt73usb_fill_rxdone, | 2338 | .fill_rxdone = rt73usb_fill_rxdone, |
2318 | .config_shared_key = rt73usb_config_shared_key, | 2339 | .config_shared_key = rt73usb_config_shared_key, |