*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE,
+ (tsf_sync == TSF_SYNC_BEACON));
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
return 0;
}
-static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
+ struct data_entry *entry)
{
- struct data_ring *ring = rt2x00dev->rx;
- __le32 *rxd;
- unsigned int i;
+ __le32 *rxd = entry->priv;
u32 word;
- memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
- for (i = 0; i < ring->stats.limit; i++) {
- rxd = ring->entry[i].priv;
-
- rt2x00_desc_read(rxd, 5, &word);
- rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
- ring->entry[i].data_dma);
- rt2x00_desc_write(rxd, 5, word);
+ rt2x00_desc_read(rxd, 5, &word);
+ rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
+ entry->data_dma);
+ rt2x00_desc_write(rxd, 5, word);
- rt2x00_desc_read(rxd, 0, &word);
- rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
- rt2x00_desc_write(rxd, 0, word);
- }
-
- rt2x00_ring_index_clear(rt2x00dev->rx);
+ rt2x00_desc_read(rxd, 0, &word);
+ rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+ rt2x00_desc_write(rxd, 0, word);
}
-static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
+static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
+ struct data_entry *entry)
{
- struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
- __le32 *txd;
- unsigned int i;
+ __le32 *txd = entry->priv;
u32 word;
- memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
- for (i = 0; i < ring->stats.limit; i++) {
- txd = ring->entry[i].priv;
-
- rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
- rt2x00_desc_write(txd, 1, word);
-
- rt2x00_desc_read(txd, 5, &word);
- rt2x00_set_field32(&word, TXD_W5_PID_TYPE, queue);
- rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, i);
- rt2x00_desc_write(txd, 5, word);
+ rt2x00_desc_read(txd, 1, &word);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
+ rt2x00_desc_write(txd, 1, word);
- rt2x00_desc_read(txd, 6, &word);
- rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
- ring->entry[i].data_dma);
- rt2x00_desc_write(txd, 6, word);
+ rt2x00_desc_read(txd, 5, &word);
+ rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx);
+ rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
+ rt2x00_desc_write(txd, 5, word);
- rt2x00_desc_read(txd, 0, &word);
- rt2x00_set_field32(&word, TXD_W0_VALID, 0);
- rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
- rt2x00_desc_write(txd, 0, word);
- }
+ rt2x00_desc_read(txd, 6, &word);
+ rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+ entry->data_dma);
+ rt2x00_desc_write(txd, 6, word);
- rt2x00_ring_index_clear(ring);
+ rt2x00_desc_read(txd, 0, &word);
+ rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+ rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+ rt2x00_desc_write(txd, 0, word);
}
static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- /*
- * Initialize rings.
- */
- rt61pci_init_rxring(rt2x00dev);
- rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
- rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
- rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2);
- rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3);
- rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4);
-
/*
* Initialize registers.
*/
rt61pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt61pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
* TX descriptor initialization
*/
static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- __le32 *txd,
- struct txdata_entry_desc *desc,
- struct ieee80211_hdr *ieee80211hdr,
- unsigned int length,
- struct ieee80211_tx_control *control)
+ struct sk_buff *skb,
+ struct txdata_entry_desc *desc,
+ struct ieee80211_tx_control *control)
{
+ struct skb_desc *skbdesc = get_skb_desc(skb);
+ __le32 *txd = skbdesc->desc;
u32 word;
/*
rt2x00_desc_write(txd, 5, word);
rt2x00_desc_read(txd, 11, &word);
- rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length);
+ rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len);
rt2x00_desc_write(txd, 11, word);
rt2x00_desc_read(txd, 0, &word);
!!(control->flags &
IEEE80211_TXCTL_LONG_RETRY_LIMIT));
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
rt2x00_set_field32(&word, TXD_W0_BURST,
test_bit(ENTRY_TXD_BURST, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
-
- return;
+ desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
}
/*
WARNING(rt2x00dev,
"TX status report missed for entry %p\n",
entry_done);
- rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0);
+ rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+ 0);
entry_done = rt2x00_get_data_entry_done(ring);
}
struct dev_addr_list *mc_list)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- struct interface *intf = &rt2x00dev->interface;
u32 reg;
/*
* Apply some rules to the filters:
* - Some filters imply different filters to be set.
* - Some things we can't filter out at all.
- * - Some filters are set based on interface type.
+ * - Multicast filter seems to kill broadcast traffic so never use it.
*/
- if (mc_count)
- *total_flags |= FIF_ALLMULTI;
+ *total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
- if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
- *total_flags |= FIF_PROMISC_IN_BSS;
/*
* Check if there is any work left for us.
*/
- if (intf->filter == *total_flags)
+ if (rt2x00dev->packet_filter == *total_flags)
return;
- intf->filter = *total_flags;
+ rt2x00dev->packet_filter = *total_flags;
/*
* Start configuration steps.
struct ieee80211_tx_control *control)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct skb_desc *desc;
+ struct data_ring *ring;
+ struct data_entry *entry;
/*
* Just in case the ieee80211 doesn't set this,
* initialization.
*/
control->queue = IEEE80211_TX_QUEUE_BEACON;
+ ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+ entry = rt2x00_get_data_entry(ring);
/*
* We need to append the descriptor in front of the
}
/*
- * First we create the beacon.
+ * Add the descriptor in front of the skb.
+ */
+ skb_push(skb, ring->desc_size);
+ memset(skb->data, 0, ring->desc_size);
+
+ /*
+ * Fill in skb descriptor
*/
- skb_push(skb, TXD_DESC_SIZE);
- memset(skb->data, 0, TXD_DESC_SIZE);
+ desc = get_skb_desc(skb);
+ desc->desc_len = ring->desc_size;
+ desc->data_len = skb->len - ring->desc_size;
+ desc->desc = skb->data;
+ desc->data = skb->data + ring->desc_size;
+ desc->ring = ring;
+ desc->entry = entry;
- rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
- (struct ieee80211_hdr *)(skb->data +
- TXD_DESC_SIZE),
- skb->len - TXD_DESC_SIZE, control);
+ rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
/*
* Write entire beacon with descriptor to register,
.configure_filter = rt61pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt61pci_set_retry_limit,
- .erp_ie_changed = rt2x00mac_erp_ie_changed,
+ .bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt61pci_get_tsf,
.load_firmware = rt61pci_load_firmware,
.initialize = rt2x00pci_initialize,
.uninitialize = rt2x00pci_uninitialize,
+ .init_rxentry = rt61pci_init_rxentry,
+ .init_txentry = rt61pci_init_txentry,
.set_device_state = rt61pci_set_device_state,
.rfkill_poll = rt61pci_rfkill_poll,
.link_stats = rt61pci_link_stats,