diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 165 |
1 files changed, 90 insertions, 75 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index e8d63aaab7bc..892baa907a6b 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -277,59 +277,14 @@ static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | |||
277 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg)); | 277 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg)); |
278 | } | 278 | } |
279 | 279 | ||
280 | static void rt2500pci_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
281 | const unsigned int filter) | ||
282 | { | ||
283 | int promisc = !!(filter & IFF_PROMISC); | ||
284 | int multicast = !!(filter & IFF_MULTICAST); | ||
285 | int broadcast = !!(filter & IFF_BROADCAST); | ||
286 | u32 reg; | ||
287 | |||
288 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
289 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, !promisc); | ||
290 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, !multicast); | ||
291 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, !broadcast); | ||
292 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
293 | } | ||
294 | |||
295 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) | 280 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) |
296 | { | 281 | { |
282 | struct interface *intf = &rt2x00dev->interface; | ||
297 | u32 reg; | 283 | u32 reg; |
298 | 284 | ||
299 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 285 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
300 | 286 | ||
301 | /* | 287 | /* |
302 | * Apply hardware packet filter. | ||
303 | */ | ||
304 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
305 | |||
306 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
307 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
308 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 1); | ||
309 | else | ||
310 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 0); | ||
311 | |||
312 | /* | ||
313 | * If there is a non-monitor interface present | ||
314 | * the packet should be strict (even if a monitor interface is present!). | ||
315 | * When there is only 1 interface present which is in monitor mode | ||
316 | * we should start accepting _all_ frames. | ||
317 | */ | ||
318 | if (is_interface_present(&rt2x00dev->interface)) { | ||
319 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 1); | ||
320 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 1); | ||
321 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 1); | ||
322 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
323 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
324 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 0); | ||
325 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 0); | ||
326 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 0); | ||
327 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 0); | ||
328 | } | ||
329 | |||
330 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
331 | |||
332 | /* | ||
333 | * Enable beacon config | 288 | * Enable beacon config |
334 | */ | 289 | */ |
335 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 290 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
@@ -345,20 +300,16 @@ static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) | |||
345 | * Enable synchronisation. | 300 | * Enable synchronisation. |
346 | */ | 301 | */ |
347 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 302 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
348 | if (is_interface_present(&rt2x00dev->interface)) { | 303 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
349 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 304 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
350 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
351 | } | ||
352 | |||
353 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 305 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
354 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | 306 | if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) || |
307 | is_interface_type(intf, IEEE80211_IF_TYPE_AP)) | ||
355 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); | 308 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); |
356 | else if (type == IEEE80211_IF_TYPE_STA) | 309 | else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA)) |
357 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); | 310 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); |
358 | else if (is_monitor_present(&rt2x00dev->interface) && | 311 | else |
359 | !is_interface_present(&rt2x00dev->interface)) | ||
360 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | 312 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); |
361 | |||
362 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 313 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
363 | } | 314 | } |
364 | 315 | ||
@@ -1269,7 +1220,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1269 | */ | 1220 | */ |
1270 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1221 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1271 | struct data_desc *txd, | 1222 | struct data_desc *txd, |
1272 | struct data_entry_desc *desc, | 1223 | struct txdata_entry_desc *desc, |
1273 | struct ieee80211_hdr *ieee80211hdr, | 1224 | struct ieee80211_hdr *ieee80211hdr, |
1274 | unsigned int length, | 1225 | unsigned int length, |
1275 | struct ieee80211_tx_control *control) | 1226 | struct ieee80211_tx_control *control) |
@@ -1349,8 +1300,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1349 | /* | 1300 | /* |
1350 | * RX control handlers | 1301 | * RX control handlers |
1351 | */ | 1302 | */ |
1352 | static int rt2500pci_fill_rxdone(struct data_entry *entry, | 1303 | static void rt2500pci_fill_rxdone(struct data_entry *entry, |
1353 | int *signal, int *rssi, int *ofdm, int *size) | 1304 | struct rxdata_entry_desc *desc) |
1354 | { | 1305 | { |
1355 | struct data_desc *rxd = entry->priv; | 1306 | struct data_desc *rxd = entry->priv; |
1356 | u32 word0; | 1307 | u32 word0; |
@@ -1359,18 +1310,17 @@ static int rt2500pci_fill_rxdone(struct data_entry *entry, | |||
1359 | rt2x00_desc_read(rxd, 0, &word0); | 1310 | rt2x00_desc_read(rxd, 0, &word0); |
1360 | rt2x00_desc_read(rxd, 2, &word2); | 1311 | rt2x00_desc_read(rxd, 2, &word2); |
1361 | 1312 | ||
1362 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | 1313 | desc->flags = 0; |
1363 | rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR) || | 1314 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1364 | rt2x00_get_field32(word0, RXD_W0_ICV_ERROR)) | 1315 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1365 | return -EINVAL; | 1316 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1317 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | ||
1366 | 1318 | ||
1367 | *signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1319 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); |
1368 | *rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1320 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - |
1369 | entry->ring->rt2x00dev->rssi_offset; | 1321 | entry->ring->rt2x00dev->rssi_offset; |
1370 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1322 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1371 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1323 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1372 | |||
1373 | return 0; | ||
1374 | } | 1324 | } |
1375 | 1325 | ||
1376 | /* | 1326 | /* |
@@ -1779,10 +1729,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1779 | /* | 1729 | /* |
1780 | * Initialize all hw fields. | 1730 | * Initialize all hw fields. |
1781 | */ | 1731 | */ |
1782 | rt2x00dev->hw->flags = | 1732 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; |
1783 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1784 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
1785 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
1786 | rt2x00dev->hw->extra_tx_headroom = 0; | 1733 | rt2x00dev->hw->extra_tx_headroom = 0; |
1787 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1734 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1788 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1735 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
@@ -1867,6 +1814,73 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1867 | /* | 1814 | /* |
1868 | * IEEE80211 stack callback functions. | 1815 | * IEEE80211 stack callback functions. |
1869 | */ | 1816 | */ |
1817 | static void rt2500pci_configure_filter(struct ieee80211_hw *hw, | ||
1818 | unsigned int changed_flags, | ||
1819 | unsigned int *total_flags, | ||
1820 | int mc_count, | ||
1821 | struct dev_addr_list *mc_list) | ||
1822 | { | ||
1823 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1824 | struct interface *intf = &rt2x00dev->interface; | ||
1825 | u32 reg; | ||
1826 | |||
1827 | /* | ||
1828 | * Mask off any flags we are going to ignore from | ||
1829 | * the total_flags field. | ||
1830 | */ | ||
1831 | *total_flags &= | ||
1832 | FIF_ALLMULTI | | ||
1833 | FIF_FCSFAIL | | ||
1834 | FIF_PLCPFAIL | | ||
1835 | FIF_CONTROL | | ||
1836 | FIF_OTHER_BSS | | ||
1837 | FIF_PROMISC_IN_BSS; | ||
1838 | |||
1839 | /* | ||
1840 | * Apply some rules to the filters: | ||
1841 | * - Some filters imply different filters to be set. | ||
1842 | * - Some things we can't filter out at all. | ||
1843 | * - Some filters are set based on interface type. | ||
1844 | */ | ||
1845 | if (mc_count) | ||
1846 | *total_flags |= FIF_ALLMULTI; | ||
1847 | if (changed_flags & FIF_OTHER_BSS || | ||
1848 | changed_flags & FIF_PROMISC_IN_BSS) | ||
1849 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1850 | if (is_interface_type(intf, IEEE80211_IF_TYPE_AP)) | ||
1851 | *total_flags |= FIF_PROMISC_IN_BSS; | ||
1852 | |||
1853 | /* | ||
1854 | * Check if there is any work left for us. | ||
1855 | */ | ||
1856 | if (intf->filter == *total_flags) | ||
1857 | return; | ||
1858 | intf->filter = *total_flags; | ||
1859 | |||
1860 | /* | ||
1861 | * Start configuration steps. | ||
1862 | * Note that the version error will always be dropped | ||
1863 | * and broadcast frames will always be accepted since | ||
1864 | * there is no filter for it at this time. | ||
1865 | */ | ||
1866 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
1867 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, | ||
1868 | !(*total_flags & FIF_FCSFAIL)); | ||
1869 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, | ||
1870 | !(*total_flags & FIF_PLCPFAIL)); | ||
1871 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | ||
1872 | !(*total_flags & FIF_CONTROL)); | ||
1873 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | ||
1874 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1875 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | ||
1876 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1877 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
1878 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, | ||
1879 | !(*total_flags & FIF_ALLMULTI)); | ||
1880 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); | ||
1881 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
1882 | } | ||
1883 | |||
1870 | static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, | 1884 | static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, |
1871 | u32 short_retry, u32 long_retry) | 1885 | u32 short_retry, u32 long_retry) |
1872 | { | 1886 | { |
@@ -1914,11 +1928,13 @@ static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | |||
1914 | 1928 | ||
1915 | static const struct ieee80211_ops rt2500pci_mac80211_ops = { | 1929 | static const struct ieee80211_ops rt2500pci_mac80211_ops = { |
1916 | .tx = rt2x00mac_tx, | 1930 | .tx = rt2x00mac_tx, |
1931 | .start = rt2x00mac_start, | ||
1932 | .stop = rt2x00mac_stop, | ||
1917 | .add_interface = rt2x00mac_add_interface, | 1933 | .add_interface = rt2x00mac_add_interface, |
1918 | .remove_interface = rt2x00mac_remove_interface, | 1934 | .remove_interface = rt2x00mac_remove_interface, |
1919 | .config = rt2x00mac_config, | 1935 | .config = rt2x00mac_config, |
1920 | .config_interface = rt2x00mac_config_interface, | 1936 | .config_interface = rt2x00mac_config_interface, |
1921 | .set_multicast_list = rt2x00mac_set_multicast_list, | 1937 | .configure_filter = rt2500pci_configure_filter, |
1922 | .get_stats = rt2x00mac_get_stats, | 1938 | .get_stats = rt2x00mac_get_stats, |
1923 | .set_retry_limit = rt2500pci_set_retry_limit, | 1939 | .set_retry_limit = rt2500pci_set_retry_limit, |
1924 | .conf_tx = rt2x00mac_conf_tx, | 1940 | .conf_tx = rt2x00mac_conf_tx, |
@@ -1947,7 +1963,6 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1947 | .fill_rxdone = rt2500pci_fill_rxdone, | 1963 | .fill_rxdone = rt2500pci_fill_rxdone, |
1948 | .config_mac_addr = rt2500pci_config_mac_addr, | 1964 | .config_mac_addr = rt2500pci_config_mac_addr, |
1949 | .config_bssid = rt2500pci_config_bssid, | 1965 | .config_bssid = rt2500pci_config_bssid, |
1950 | .config_packet_filter = rt2500pci_config_packet_filter, | ||
1951 | .config_type = rt2500pci_config_type, | 1966 | .config_type = rt2500pci_config_type, |
1952 | .config = rt2500pci_config, | 1967 | .config = rt2500pci_config, |
1953 | }; | 1968 | }; |