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 5a1330c5de71..70ef7bf434ab 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1600,6 +1600,41 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1600 | /* | 1600 | /* |
1601 | * TX data initialization | 1601 | * TX data initialization |
1602 | */ | 1602 | */ |
1603 | static void rt61pci_write_beacon(struct queue_entry *entry) | ||
1604 | { | ||
1605 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1606 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1607 | unsigned int beacon_base; | ||
1608 | u32 reg; | ||
1609 | |||
1610 | /* | ||
1611 | * Disable beaconing while we are reloading the beacon data, | ||
1612 | * otherwise we might be sending out invalid data. | ||
1613 | */ | ||
1614 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1615 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1616 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1617 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1618 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1619 | |||
1620 | /* | ||
1621 | * Write entire beacon with descriptor to register. | ||
1622 | */ | ||
1623 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1624 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1625 | beacon_base, | ||
1626 | skbdesc->desc, skbdesc->desc_len); | ||
1627 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1628 | beacon_base + skbdesc->desc_len, | ||
1629 | entry->skb->data, entry->skb->len); | ||
1630 | |||
1631 | /* | ||
1632 | * Clean up beacon skb. | ||
1633 | */ | ||
1634 | dev_kfree_skb_any(entry->skb); | ||
1635 | entry->skb = NULL; | ||
1636 | } | ||
1637 | |||
1603 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1638 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1604 | const enum data_queue_qid queue) | 1639 | const enum data_queue_qid queue) |
1605 | { | 1640 | { |
@@ -2355,72 +2390,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2355 | return tsf; | 2390 | return tsf; |
2356 | } | 2391 | } |
2357 | 2392 | ||
2358 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2359 | { | ||
2360 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2361 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
2362 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
2363 | struct queue_entry_priv_pci *entry_priv; | ||
2364 | struct skb_frame_desc *skbdesc; | ||
2365 | struct txentry_desc txdesc; | ||
2366 | unsigned int beacon_base; | ||
2367 | u32 reg; | ||
2368 | |||
2369 | if (unlikely(!intf->beacon)) | ||
2370 | return -ENOBUFS; | ||
2371 | |||
2372 | /* | ||
2373 | * Copy all TX descriptor information into txdesc, | ||
2374 | * after that we are free to use the skb->cb array | ||
2375 | * for our information. | ||
2376 | */ | ||
2377 | intf->beacon->skb = skb; | ||
2378 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
2379 | |||
2380 | entry_priv = intf->beacon->priv_data; | ||
2381 | memset(entry_priv->desc, 0, intf->beacon->queue->desc_size); | ||
2382 | |||
2383 | /* | ||
2384 | * Fill in skb descriptor | ||
2385 | */ | ||
2386 | skbdesc = get_skb_frame_desc(skb); | ||
2387 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2388 | skbdesc->desc = entry_priv->desc; | ||
2389 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2390 | skbdesc->entry = intf->beacon; | ||
2391 | |||
2392 | /* | ||
2393 | * Disable beaconing while we are reloading the beacon data, | ||
2394 | * otherwise we might be sending out invalid data. | ||
2395 | */ | ||
2396 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2397 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2398 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2399 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2400 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2401 | |||
2402 | /* | ||
2403 | * Write entire beacon with descriptor to register, | ||
2404 | * and kick the beacon generator. | ||
2405 | */ | ||
2406 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2407 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2408 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2409 | skbdesc->desc, skbdesc->desc_len); | ||
2410 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2411 | beacon_base + skbdesc->desc_len, | ||
2412 | skb->data, skb->len); | ||
2413 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2414 | |||
2415 | /* | ||
2416 | * Clean up beacon skb. | ||
2417 | */ | ||
2418 | dev_kfree_skb_any(skb); | ||
2419 | intf->beacon->skb = NULL; | ||
2420 | |||
2421 | return 0; | ||
2422 | } | ||
2423 | |||
2424 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | 2393 | static const struct ieee80211_ops rt61pci_mac80211_ops = { |
2425 | .tx = rt2x00mac_tx, | 2394 | .tx = rt2x00mac_tx, |
2426 | .start = rt2x00mac_start, | 2395 | .start = rt2x00mac_start, |
@@ -2436,7 +2405,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2436 | .conf_tx = rt2x00mac_conf_tx, | 2405 | .conf_tx = rt2x00mac_conf_tx, |
2437 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2406 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2438 | .get_tsf = rt61pci_get_tsf, | 2407 | .get_tsf = rt61pci_get_tsf, |
2439 | .beacon_update = rt61pci_beacon_update, | ||
2440 | }; | 2408 | }; |
2441 | 2409 | ||
2442 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2410 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
@@ -2456,6 +2424,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2456 | .link_tuner = rt61pci_link_tuner, | 2424 | .link_tuner = rt61pci_link_tuner, |
2457 | .write_tx_desc = rt61pci_write_tx_desc, | 2425 | .write_tx_desc = rt61pci_write_tx_desc, |
2458 | .write_tx_data = rt2x00pci_write_tx_data, | 2426 | .write_tx_data = rt2x00pci_write_tx_data, |
2427 | .write_beacon = rt61pci_write_beacon, | ||
2459 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2428 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2460 | .fill_rxdone = rt61pci_fill_rxdone, | 2429 | .fill_rxdone = rt61pci_fill_rxdone, |
2461 | .config_filter = rt61pci_config_filter, | 2430 | .config_filter = rt61pci_config_filter, |