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.c164
1 files changed, 90 insertions, 74 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 09c8c96e2f83..dea7a8a4fa00 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -312,23 +312,9 @@ static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
312 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, &reg, sizeof(reg)); 312 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, &reg, sizeof(reg));
313} 313}
314 314
315static void rt61pci_config_packet_filter(struct rt2x00_dev *rt2x00dev,
316 const unsigned int filter)
317{
318 int promisc = !!(filter & IFF_PROMISC);
319 int multicast = !!(filter & IFF_MULTICAST);
320 int broadcast = !!(filter & IFF_BROADCAST);
321 u32 reg;
322
323 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
324 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME, !promisc);
325 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST, !multicast);
326 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BORADCAST, !broadcast);
327 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
328}
329
330static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) 315static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
331{ 316{
317 struct interface *intf = &rt2x00dev->interface;
332 u32 reg; 318 u32 reg;
333 319
334 /* 320 /*
@@ -344,56 +330,19 @@ static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
344 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); 330 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
345 331
346 /* 332 /*
347 * Apply hardware packet filter.
348 */
349 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
350
351 if (!is_monitor_present(&rt2x00dev->interface) &&
352 (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
353 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS, 1);
354 else
355 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS, 0);
356
357 /*
358 * If there is a non-monitor interface present
359 * the packet should be strict (even if a monitor interface is present!).
360 * When there is only 1 interface present which is in monitor mode
361 * we should start accepting _all_ frames.
362 */
363 if (is_interface_present(&rt2x00dev->interface)) {
364 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC, 1);
365 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL, 1);
366 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL, 1);
367 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
368 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS, 1);
369 } else if (is_monitor_present(&rt2x00dev->interface)) {
370 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC, 0);
371 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL, 0);
372 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL, 0);
373 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 0);
374 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS, 0);
375 }
376
377 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
378
379 /*
380 * Enable synchronisation. 333 * Enable synchronisation.
381 */ 334 */
382 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg); 335 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
383 if (is_interface_present(&rt2x00dev->interface)) { 336 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
384 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1); 337 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
385 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
386 }
387
388 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0); 338 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
389 if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) 339 if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
340 is_interface_type(intf, IEEE80211_IF_TYPE_AP))
390 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 2); 341 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 2);
391 else if (type == IEEE80211_IF_TYPE_STA) 342 else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
392 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 1); 343 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 1);
393 else if (is_monitor_present(&rt2x00dev->interface) && 344 else
394 !is_interface_present(&rt2x00dev->interface))
395 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 0); 345 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 0);
396
397 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); 346 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
398} 347}
399 348
@@ -1686,7 +1635,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1686 */ 1635 */
1687static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, 1636static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1688 struct data_desc *txd, 1637 struct data_desc *txd,
1689 struct data_entry_desc *desc, 1638 struct txdata_entry_desc *desc,
1690 struct ieee80211_hdr *ieee80211hdr, 1639 struct ieee80211_hdr *ieee80211hdr,
1691 unsigned int length, 1640 unsigned int length,
1692 struct ieee80211_tx_control *control) 1641 struct ieee80211_tx_control *control)
@@ -1826,8 +1775,8 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
1826 return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; 1775 return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;
1827} 1776}
1828 1777
1829static int rt61pci_fill_rxdone(struct data_entry *entry, 1778static void rt61pci_fill_rxdone(struct data_entry *entry,
1830 int *signal, int *rssi, int *ofdm, int *size) 1779 struct rxdata_entry_desc *desc)
1831{ 1780{
1832 struct data_desc *rxd = entry->priv; 1781 struct data_desc *rxd = entry->priv;
1833 u32 word0; 1782 u32 word0;
@@ -1836,19 +1785,19 @@ static int rt61pci_fill_rxdone(struct data_entry *entry,
1836 rt2x00_desc_read(rxd, 0, &word0); 1785 rt2x00_desc_read(rxd, 0, &word0);
1837 rt2x00_desc_read(rxd, 1, &word1); 1786 rt2x00_desc_read(rxd, 1, &word1);
1838 1787
1839 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || 1788 desc->flags = 0;
1840 rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) 1789 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1841 return -EINVAL; 1790 desc->flags |= RX_FLAG_FAILED_FCS_CRC;
1842 1791
1843 /* 1792 /*
1844 * Obtain the status about this packet. 1793 * Obtain the status about this packet.
1845 */ 1794 */
1846 *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); 1795 desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
1847 *rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); 1796 desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
1848 *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); 1797 desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
1849 *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); 1798 desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
1850 1799
1851 return 0; 1800 return;
1852} 1801}
1853 1802
1854/* 1803/*
@@ -2340,9 +2289,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2340 */ 2289 */
2341 rt2x00dev->hw->flags = 2290 rt2x00dev->hw->flags =
2342 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 2291 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
2343 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2292 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
2344 IEEE80211_HW_MONITOR_DURING_OPER |
2345 IEEE80211_HW_NO_PROBE_FILTERING;
2346 rt2x00dev->hw->extra_tx_headroom = 0; 2293 rt2x00dev->hw->extra_tx_headroom = 0;
2347 rt2x00dev->hw->max_signal = MAX_SIGNAL; 2294 rt2x00dev->hw->max_signal = MAX_SIGNAL;
2348 rt2x00dev->hw->max_rssi = MAX_RX_SSI; 2295 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -2426,6 +2373,74 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
2426/* 2373/*
2427 * IEEE80211 stack callback functions. 2374 * IEEE80211 stack callback functions.
2428 */ 2375 */
2376static void rt61pci_configure_filter(struct ieee80211_hw *hw,
2377 unsigned int changed_flags,
2378 unsigned int *total_flags,
2379 int mc_count,
2380 struct dev_addr_list *mc_list)
2381{
2382 struct rt2x00_dev *rt2x00dev = hw->priv;
2383 struct interface *intf = &rt2x00dev->interface;
2384 u32 reg;
2385
2386 /*
2387 * Mask off any flags we are going to ignore from
2388 * the total_flags field.
2389 */
2390 *total_flags &=
2391 FIF_ALLMULTI |
2392 FIF_FCSFAIL |
2393 FIF_PLCPFAIL |
2394 FIF_CONTROL |
2395 FIF_OTHER_BSS |
2396 FIF_PROMISC_IN_BSS;
2397
2398 /*
2399 * Apply some rules to the filters:
2400 * - Some filters imply different filters to be set.
2401 * - Some things we can't filter out at all.
2402 * - Some filters are set based on interface type.
2403 */
2404 if (mc_count)
2405 *total_flags |= FIF_ALLMULTI;
2406 if (changed_flags & FIF_OTHER_BSS ||
2407 changed_flags & FIF_PROMISC_IN_BSS)
2408 *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
2409 if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
2410 *total_flags |= FIF_PROMISC_IN_BSS;
2411
2412 /*
2413 * Check if there is any work left for us.
2414 */
2415 if (intf->filter == *total_flags)
2416 return;
2417 intf->filter = *total_flags;
2418
2419 /*
2420 * Start configuration steps.
2421 * Note that the version error will always be dropped
2422 * and broadcast frames will always be accepted since
2423 * there is no filter for it at this time.
2424 */
2425 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
2426 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
2427 !(*total_flags & FIF_FCSFAIL));
2428 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
2429 !(*total_flags & FIF_PLCPFAIL));
2430 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
2431 !(*total_flags & FIF_CONTROL));
2432 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
2433 !(*total_flags & FIF_PROMISC_IN_BSS));
2434 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
2435 !(*total_flags & FIF_PROMISC_IN_BSS));
2436 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
2437 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST,
2438 !(*total_flags & FIF_ALLMULTI));
2439 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BORADCAST, 0);
2440 rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS, 1);
2441 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
2442}
2443
2429static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, 2444static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
2430 u32 short_retry, u32 long_retry) 2445 u32 short_retry, u32 long_retry)
2431{ 2446{
@@ -2506,11 +2521,13 @@ int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
2506 2521
2507static const struct ieee80211_ops rt61pci_mac80211_ops = { 2522static const struct ieee80211_ops rt61pci_mac80211_ops = {
2508 .tx = rt2x00mac_tx, 2523 .tx = rt2x00mac_tx,
2524 .start = rt2x00mac_start,
2525 .stop = rt2x00mac_stop,
2509 .add_interface = rt2x00mac_add_interface, 2526 .add_interface = rt2x00mac_add_interface,
2510 .remove_interface = rt2x00mac_remove_interface, 2527 .remove_interface = rt2x00mac_remove_interface,
2511 .config = rt2x00mac_config, 2528 .config = rt2x00mac_config,
2512 .config_interface = rt2x00mac_config_interface, 2529 .config_interface = rt2x00mac_config_interface,
2513 .set_multicast_list = rt2x00mac_set_multicast_list, 2530 .configure_filter = rt61pci_configure_filter,
2514 .get_stats = rt2x00mac_get_stats, 2531 .get_stats = rt2x00mac_get_stats,
2515 .set_retry_limit = rt61pci_set_retry_limit, 2532 .set_retry_limit = rt61pci_set_retry_limit,
2516 .conf_tx = rt2x00mac_conf_tx, 2533 .conf_tx = rt2x00mac_conf_tx,
@@ -2540,7 +2557,6 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2540 .fill_rxdone = rt61pci_fill_rxdone, 2557 .fill_rxdone = rt61pci_fill_rxdone,
2541 .config_mac_addr = rt61pci_config_mac_addr, 2558 .config_mac_addr = rt61pci_config_mac_addr,
2542 .config_bssid = rt61pci_config_bssid, 2559 .config_bssid = rt61pci_config_bssid,
2543 .config_packet_filter = rt61pci_config_packet_filter,
2544 .config_type = rt61pci_config_type, 2560 .config_type = rt61pci_config_type,
2545 .config = rt61pci_config, 2561 .config = rt61pci_config,
2546}; 2562};