diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 103 |
1 files changed, 36 insertions, 67 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 852d193a11a9..80c4445e6286 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1591,6 +1591,41 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1591 | /* | 1591 | /* |
1592 | * TX data initialization | 1592 | * TX data initialization |
1593 | */ | 1593 | */ |
1594 | static void rt61pci_write_beacon(struct queue_entry *entry) | ||
1595 | { | ||
1596 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1597 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1598 | unsigned int beacon_base; | ||
1599 | u32 reg; | ||
1600 | |||
1601 | /* | ||
1602 | * Disable beaconing while we are reloading the beacon data, | ||
1603 | * otherwise we might be sending out invalid data. | ||
1604 | */ | ||
1605 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1606 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1607 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1608 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1609 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1610 | |||
1611 | /* | ||
1612 | * Write entire beacon with descriptor to register. | ||
1613 | */ | ||
1614 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1615 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1616 | beacon_base, | ||
1617 | skbdesc->desc, skbdesc->desc_len); | ||
1618 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1619 | beacon_base + skbdesc->desc_len, | ||
1620 | entry->skb->data, entry->skb->len); | ||
1621 | |||
1622 | /* | ||
1623 | * Clean up beacon skb. | ||
1624 | */ | ||
1625 | dev_kfree_skb_any(entry->skb); | ||
1626 | entry->skb = NULL; | ||
1627 | } | ||
1628 | |||
1594 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1629 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1595 | const enum data_queue_qid queue) | 1630 | const enum data_queue_qid queue) |
1596 | { | 1631 | { |
@@ -2346,72 +2381,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2346 | return tsf; | 2381 | return tsf; |
2347 | } | 2382 | } |
2348 | 2383 | ||
2349 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2350 | { | ||
2351 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2352 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
2353 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
2354 | struct queue_entry_priv_pci *entry_priv; | ||
2355 | struct skb_frame_desc *skbdesc; | ||
2356 | struct txentry_desc txdesc; | ||
2357 | unsigned int beacon_base; | ||
2358 | u32 reg; | ||
2359 | |||
2360 | if (unlikely(!intf->beacon)) | ||
2361 | return -ENOBUFS; | ||
2362 | |||
2363 | /* | ||
2364 | * Copy all TX descriptor information into txdesc, | ||
2365 | * after that we are free to use the skb->cb array | ||
2366 | * for our information. | ||
2367 | */ | ||
2368 | intf->beacon->skb = skb; | ||
2369 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
2370 | |||
2371 | entry_priv = intf->beacon->priv_data; | ||
2372 | memset(entry_priv->desc, 0, intf->beacon->queue->desc_size); | ||
2373 | |||
2374 | /* | ||
2375 | * Fill in skb descriptor | ||
2376 | */ | ||
2377 | skbdesc = get_skb_frame_desc(skb); | ||
2378 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2379 | skbdesc->desc = entry_priv->desc; | ||
2380 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2381 | skbdesc->entry = intf->beacon; | ||
2382 | |||
2383 | /* | ||
2384 | * Disable beaconing while we are reloading the beacon data, | ||
2385 | * otherwise we might be sending out invalid data. | ||
2386 | */ | ||
2387 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2388 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2389 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2390 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2391 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2392 | |||
2393 | /* | ||
2394 | * Write entire beacon with descriptor to register, | ||
2395 | * and kick the beacon generator. | ||
2396 | */ | ||
2397 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2398 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2399 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2400 | skbdesc->desc, skbdesc->desc_len); | ||
2401 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2402 | beacon_base + skbdesc->desc_len, | ||
2403 | skb->data, skb->len); | ||
2404 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2405 | |||
2406 | /* | ||
2407 | * Clean up beacon skb. | ||
2408 | */ | ||
2409 | dev_kfree_skb_any(skb); | ||
2410 | intf->beacon->skb = NULL; | ||
2411 | |||
2412 | return 0; | ||
2413 | } | ||
2414 | |||
2415 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | 2384 | static const struct ieee80211_ops rt61pci_mac80211_ops = { |
2416 | .tx = rt2x00mac_tx, | 2385 | .tx = rt2x00mac_tx, |
2417 | .start = rt2x00mac_start, | 2386 | .start = rt2x00mac_start, |
@@ -2446,9 +2415,9 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2446 | .link_tuner = rt61pci_link_tuner, | 2415 | .link_tuner = rt61pci_link_tuner, |
2447 | .write_tx_desc = rt61pci_write_tx_desc, | 2416 | .write_tx_desc = rt61pci_write_tx_desc, |
2448 | .write_tx_data = rt2x00pci_write_tx_data, | 2417 | .write_tx_data = rt2x00pci_write_tx_data, |
2418 | .write_beacon = rt61pci_write_beacon, | ||
2449 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2419 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2450 | .fill_rxdone = rt61pci_fill_rxdone, | 2420 | .fill_rxdone = rt61pci_fill_rxdone, |
2451 | .beacon_update = rt61pci_beacon_update, | ||
2452 | .config_filter = rt61pci_config_filter, | 2421 | .config_filter = rt61pci_config_filter, |
2453 | .config_intf = rt61pci_config_intf, | 2422 | .config_intf = rt61pci_config_intf, |
2454 | .config_erp = rt61pci_config_erp, | 2423 | .config_erp = rt61pci_config_erp, |