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 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 */
1603static 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, &reg);
1615 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
1616 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
1617 rt2x00_set_field32(&reg, 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
1603static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 1638static 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
2358static 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, &reg);
2397 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
2398 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
2399 rt2x00_set_field32(&reg, 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
2424static const struct ieee80211_ops rt61pci_mac80211_ops = { 2393static 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
2442static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { 2410static 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,