diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 61766ed800e..feb8c09a33a 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1041,11 +1041,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1041 | * TX data initialization | 1041 | * TX data initialization |
1042 | */ | 1042 | */ |
1043 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1043 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1044 | unsigned int queue) | 1044 | const unsigned int queue) |
1045 | { | 1045 | { |
1046 | u32 reg; | 1046 | u32 reg; |
1047 | 1047 | ||
1048 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1048 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1049 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1049 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1050 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1050 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1051 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1051 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
@@ -1060,7 +1060,7 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1060 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1060 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1061 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1061 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1062 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1062 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1063 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1063 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1064 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1064 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1065 | } | 1065 | } |
1066 | 1066 | ||
@@ -1165,7 +1165,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1165 | * 3 - Atim ring transmit done interrupt. | 1165 | * 3 - Atim ring transmit done interrupt. |
1166 | */ | 1166 | */ |
1167 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1167 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1168 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1168 | rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1169 | 1169 | ||
1170 | /* | 1170 | /* |
1171 | * 4 - Priority ring transmit done interrupt. | 1171 | * 4 - Priority ring transmit done interrupt. |
@@ -1510,6 +1510,49 @@ static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | |||
1510 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1510 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1514 | struct ieee80211_tx_control *control) | ||
1515 | { | ||
1516 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1517 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1518 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1519 | struct skb_frame_desc *skbdesc; | ||
1520 | |||
1521 | if (unlikely(!intf->beacon)) | ||
1522 | return -ENOBUFS; | ||
1523 | |||
1524 | priv_tx = intf->beacon->priv_data; | ||
1525 | |||
1526 | /* | ||
1527 | * Fill in skb descriptor | ||
1528 | */ | ||
1529 | skbdesc = get_skb_frame_desc(skb); | ||
1530 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1531 | skbdesc->data = skb->data; | ||
1532 | skbdesc->data_len = skb->len; | ||
1533 | skbdesc->desc = priv_tx->desc; | ||
1534 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1535 | skbdesc->entry = intf->beacon; | ||
1536 | |||
1537 | /* | ||
1538 | * mac80211 doesn't provide the control->queue variable | ||
1539 | * for beacons. Set our own queue identification so | ||
1540 | * it can be used during descriptor initialization. | ||
1541 | */ | ||
1542 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1543 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1544 | |||
1545 | /* | ||
1546 | * Enable beacon generation. | ||
1547 | * Write entire beacon with descriptor to register, | ||
1548 | * and kick the beacon generator. | ||
1549 | */ | ||
1550 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1551 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1552 | |||
1553 | return 0; | ||
1554 | } | ||
1555 | |||
1513 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1556 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
1514 | { | 1557 | { |
1515 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1558 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -1535,7 +1578,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1535 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1578 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1536 | .get_tsf = rt2400pci_get_tsf, | 1579 | .get_tsf = rt2400pci_get_tsf, |
1537 | .reset_tsf = rt2400pci_reset_tsf, | 1580 | .reset_tsf = rt2400pci_reset_tsf, |
1538 | .beacon_update = rt2x00pci_beacon_update, | 1581 | .beacon_update = rt2400pci_beacon_update, |
1539 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1582 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1540 | }; | 1583 | }; |
1541 | 1584 | ||