aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt61pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c103
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 */
1594static 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, &reg);
1606 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
1607 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
1608 rt2x00_set_field32(&reg, 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
1594static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 1629static 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
2349static 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, &reg);
2388 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
2389 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
2390 rt2x00_set_field32(&reg, 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
2415static const struct ieee80211_ops rt61pci_mac80211_ops = { 2384static 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,