diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 74 |
1 files changed, 35 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index fc4db8834c36..73e7e613a3c9 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -283,7 +283,8 @@ static int ath5k_rx_start(struct ath5k_softc *sc); | |||
283 | static void ath5k_rx_stop(struct ath5k_softc *sc); | 283 | static void ath5k_rx_stop(struct ath5k_softc *sc); |
284 | static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, | 284 | static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, |
285 | struct ath5k_desc *ds, | 285 | struct ath5k_desc *ds, |
286 | struct sk_buff *skb); | 286 | struct sk_buff *skb, |
287 | struct ath5k_rx_status *rs); | ||
287 | static void ath5k_tasklet_rx(unsigned long data); | 288 | static void ath5k_tasklet_rx(unsigned long data); |
288 | /* Tx handling */ | 289 | /* Tx handling */ |
289 | static void ath5k_tx_processq(struct ath5k_softc *sc, | 290 | static void ath5k_tx_processq(struct ath5k_softc *sc, |
@@ -1563,8 +1564,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1563 | */ | 1564 | */ |
1564 | spin_lock_bh(&txq->lock); | 1565 | spin_lock_bh(&txq->lock); |
1565 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1566 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
1566 | ath5k_debug_printtxbuf(sc, bf, !sc->ah->ah_proc_tx_desc(sc->ah, | 1567 | ath5k_debug_printtxbuf(sc, bf); |
1567 | bf->desc)); | ||
1568 | 1568 | ||
1569 | ath5k_txbuf_free(sc, bf); | 1569 | ath5k_txbuf_free(sc, bf); |
1570 | 1570 | ||
@@ -1689,20 +1689,20 @@ ath5k_rx_stop(struct ath5k_softc *sc) | |||
1689 | 1689 | ||
1690 | static unsigned int | 1690 | static unsigned int |
1691 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | 1691 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, |
1692 | struct sk_buff *skb) | 1692 | struct sk_buff *skb, struct ath5k_rx_status *rs) |
1693 | { | 1693 | { |
1694 | struct ieee80211_hdr *hdr = (void *)skb->data; | 1694 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1695 | unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); | 1695 | unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); |
1696 | 1696 | ||
1697 | if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && | 1697 | if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1698 | ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID) | 1698 | rs->rs_keyix != AR5K_RXKEYIX_INVALID) |
1699 | return RX_FLAG_DECRYPTED; | 1699 | return RX_FLAG_DECRYPTED; |
1700 | 1700 | ||
1701 | /* Apparently when a default key is used to decrypt the packet | 1701 | /* Apparently when a default key is used to decrypt the packet |
1702 | the hw does not set the index used to decrypt. In such cases | 1702 | the hw does not set the index used to decrypt. In such cases |
1703 | get the index from the packet. */ | 1703 | get the index from the packet. */ |
1704 | if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && | 1704 | if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && |
1705 | !(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && | 1705 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1706 | skb->len >= hlen + 4) { | 1706 | skb->len >= hlen + 4) { |
1707 | keyix = skb->data[hlen + 3] >> 6; | 1707 | keyix = skb->data[hlen + 3] >> 6; |
1708 | 1708 | ||
@@ -1745,12 +1745,11 @@ static void | |||
1745 | ath5k_tasklet_rx(unsigned long data) | 1745 | ath5k_tasklet_rx(unsigned long data) |
1746 | { | 1746 | { |
1747 | struct ieee80211_rx_status rxs = {}; | 1747 | struct ieee80211_rx_status rxs = {}; |
1748 | struct ath5k_rx_status rs = {}; | ||
1748 | struct sk_buff *skb; | 1749 | struct sk_buff *skb; |
1749 | struct ath5k_softc *sc = (void *)data; | 1750 | struct ath5k_softc *sc = (void *)data; |
1750 | struct ath5k_buf *bf; | 1751 | struct ath5k_buf *bf; |
1751 | struct ath5k_desc *ds; | 1752 | struct ath5k_desc *ds; |
1752 | u16 len; | ||
1753 | u8 stat; | ||
1754 | int ret; | 1753 | int ret; |
1755 | int hdrlen; | 1754 | int hdrlen; |
1756 | int pad; | 1755 | int pad; |
@@ -1773,7 +1772,7 @@ ath5k_tasklet_rx(unsigned long data) | |||
1773 | if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */ | 1772 | if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */ |
1774 | break; | 1773 | break; |
1775 | 1774 | ||
1776 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds); | 1775 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); |
1777 | if (unlikely(ret == -EINPROGRESS)) | 1776 | if (unlikely(ret == -EINPROGRESS)) |
1778 | break; | 1777 | break; |
1779 | else if (unlikely(ret)) { | 1778 | else if (unlikely(ret)) { |
@@ -1782,16 +1781,15 @@ ath5k_tasklet_rx(unsigned long data) | |||
1782 | return; | 1781 | return; |
1783 | } | 1782 | } |
1784 | 1783 | ||
1785 | if (unlikely(ds->ds_rxstat.rs_more)) { | 1784 | if (unlikely(rs.rs_more)) { |
1786 | ATH5K_WARN(sc, "unsupported jumbo\n"); | 1785 | ATH5K_WARN(sc, "unsupported jumbo\n"); |
1787 | goto next; | 1786 | goto next; |
1788 | } | 1787 | } |
1789 | 1788 | ||
1790 | stat = ds->ds_rxstat.rs_status; | 1789 | if (unlikely(rs.rs_status)) { |
1791 | if (unlikely(stat)) { | 1790 | if (rs.rs_status & AR5K_RXERR_PHY) |
1792 | if (stat & AR5K_RXERR_PHY) | ||
1793 | goto next; | 1791 | goto next; |
1794 | if (stat & AR5K_RXERR_DECRYPT) { | 1792 | if (rs.rs_status & AR5K_RXERR_DECRYPT) { |
1795 | /* | 1793 | /* |
1796 | * Decrypt error. If the error occurred | 1794 | * Decrypt error. If the error occurred |
1797 | * because there was no hardware key, then | 1795 | * because there was no hardware key, then |
@@ -1802,30 +1800,29 @@ ath5k_tasklet_rx(unsigned long data) | |||
1802 | * | 1800 | * |
1803 | * XXX do key cache faulting | 1801 | * XXX do key cache faulting |
1804 | */ | 1802 | */ |
1805 | if (ds->ds_rxstat.rs_keyix == | 1803 | if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && |
1806 | AR5K_RXKEYIX_INVALID && | 1804 | !(rs.rs_status & AR5K_RXERR_CRC)) |
1807 | !(stat & AR5K_RXERR_CRC)) | ||
1808 | goto accept; | 1805 | goto accept; |
1809 | } | 1806 | } |
1810 | if (stat & AR5K_RXERR_MIC) { | 1807 | if (rs.rs_status & AR5K_RXERR_MIC) { |
1811 | rxs.flag |= RX_FLAG_MMIC_ERROR; | 1808 | rxs.flag |= RX_FLAG_MMIC_ERROR; |
1812 | goto accept; | 1809 | goto accept; |
1813 | } | 1810 | } |
1814 | 1811 | ||
1815 | /* let crypto-error packets fall through in MNTR */ | 1812 | /* let crypto-error packets fall through in MNTR */ |
1816 | if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | 1813 | if ((rs.rs_status & |
1814 | ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | ||
1817 | sc->opmode != IEEE80211_IF_TYPE_MNTR) | 1815 | sc->opmode != IEEE80211_IF_TYPE_MNTR) |
1818 | goto next; | 1816 | goto next; |
1819 | } | 1817 | } |
1820 | accept: | 1818 | accept: |
1821 | len = ds->ds_rxstat.rs_datalen; | 1819 | pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, |
1822 | pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len, | 1820 | rs.rs_datalen, PCI_DMA_FROMDEVICE); |
1823 | PCI_DMA_FROMDEVICE); | ||
1824 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 1821 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, |
1825 | PCI_DMA_FROMDEVICE); | 1822 | PCI_DMA_FROMDEVICE); |
1826 | bf->skb = NULL; | 1823 | bf->skb = NULL; |
1827 | 1824 | ||
1828 | skb_put(skb, len); | 1825 | skb_put(skb, rs.rs_datalen); |
1829 | 1826 | ||
1830 | /* | 1827 | /* |
1831 | * the hardware adds a padding to 4 byte boundaries between | 1828 | * the hardware adds a padding to 4 byte boundaries between |
@@ -1848,7 +1845,7 @@ accept: | |||
1848 | * 32768usec (about 32ms). it might be necessary to move this to | 1845 | * 32768usec (about 32ms). it might be necessary to move this to |
1849 | * the interrupt handler, like it is done in madwifi. | 1846 | * the interrupt handler, like it is done in madwifi. |
1850 | */ | 1847 | */ |
1851 | rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); | 1848 | rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp); |
1852 | rxs.flag |= RX_FLAG_TSFT; | 1849 | rxs.flag |= RX_FLAG_TSFT; |
1853 | 1850 | ||
1854 | rxs.freq = sc->curchan->center_freq; | 1851 | rxs.freq = sc->curchan->center_freq; |
@@ -1862,17 +1859,16 @@ accept: | |||
1862 | /* noise floor in dBm, from the last noise calibration */ | 1859 | /* noise floor in dBm, from the last noise calibration */ |
1863 | rxs.noise = sc->ah->ah_noise_floor; | 1860 | rxs.noise = sc->ah->ah_noise_floor; |
1864 | /* signal level in dBm */ | 1861 | /* signal level in dBm */ |
1865 | rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi; | 1862 | rxs.ssi = rxs.noise + rs.rs_rssi; |
1866 | /* | 1863 | /* |
1867 | * "signal" is actually displayed as Link Quality by iwconfig | 1864 | * "signal" is actually displayed as Link Quality by iwconfig |
1868 | * we provide a percentage based on rssi (assuming max rssi 64) | 1865 | * we provide a percentage based on rssi (assuming max rssi 64) |
1869 | */ | 1866 | */ |
1870 | rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; | 1867 | rxs.signal = rs.rs_rssi * 100 / 64; |
1871 | 1868 | ||
1872 | rxs.antenna = ds->ds_rxstat.rs_antenna; | 1869 | rxs.antenna = rs.rs_antenna; |
1873 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, | 1870 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1874 | ds->ds_rxstat.rs_rate); | 1871 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
1875 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); | ||
1876 | 1872 | ||
1877 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1873 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
1878 | 1874 | ||
@@ -1881,7 +1877,7 @@ accept: | |||
1881 | ath5k_check_ibss_hw_merge(sc, skb); | 1877 | ath5k_check_ibss_hw_merge(sc, skb); |
1882 | 1878 | ||
1883 | __ieee80211_rx(sc->hw, skb, &rxs); | 1879 | __ieee80211_rx(sc->hw, skb, &rxs); |
1884 | sc->led_rxrate = ds->ds_rxstat.rs_rate; | 1880 | sc->led_rxrate = rs.rs_rate; |
1885 | ath5k_led_event(sc, ATH_LED_RX); | 1881 | ath5k_led_event(sc, ATH_LED_RX); |
1886 | next: | 1882 | next: |
1887 | list_move_tail(&bf->list, &sc->rxbuf); | 1883 | list_move_tail(&bf->list, &sc->rxbuf); |
@@ -1900,6 +1896,7 @@ static void | |||
1900 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | 1896 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) |
1901 | { | 1897 | { |
1902 | struct ieee80211_tx_status txs = {}; | 1898 | struct ieee80211_tx_status txs = {}; |
1899 | struct ath5k_tx_status ts = {}; | ||
1903 | struct ath5k_buf *bf, *bf0; | 1900 | struct ath5k_buf *bf, *bf0; |
1904 | struct ath5k_desc *ds; | 1901 | struct ath5k_desc *ds; |
1905 | struct sk_buff *skb; | 1902 | struct sk_buff *skb; |
@@ -1912,7 +1909,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1912 | /* TODO only one segment */ | 1909 | /* TODO only one segment */ |
1913 | pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, | 1910 | pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, |
1914 | sc->desc_len, PCI_DMA_FROMDEVICE); | 1911 | sc->desc_len, PCI_DMA_FROMDEVICE); |
1915 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds); | 1912 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); |
1916 | if (unlikely(ret == -EINPROGRESS)) | 1913 | if (unlikely(ret == -EINPROGRESS)) |
1917 | break; | 1914 | break; |
1918 | else if (unlikely(ret)) { | 1915 | else if (unlikely(ret)) { |
@@ -1927,17 +1924,16 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1927 | PCI_DMA_TODEVICE); | 1924 | PCI_DMA_TODEVICE); |
1928 | 1925 | ||
1929 | txs.control = bf->ctl; | 1926 | txs.control = bf->ctl; |
1930 | txs.retry_count = ds->ds_txstat.ts_shortretry + | 1927 | txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; |
1931 | ds->ds_txstat.ts_longretry / 6; | 1928 | if (unlikely(ts.ts_status)) { |
1932 | if (unlikely(ds->ds_txstat.ts_status)) { | ||
1933 | sc->ll_stats.dot11ACKFailureCount++; | 1929 | sc->ll_stats.dot11ACKFailureCount++; |
1934 | if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY) | 1930 | if (ts.ts_status & AR5K_TXERR_XRETRY) |
1935 | txs.excessive_retries = 1; | 1931 | txs.excessive_retries = 1; |
1936 | else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT) | 1932 | else if (ts.ts_status & AR5K_TXERR_FILT) |
1937 | txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; | 1933 | txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; |
1938 | } else { | 1934 | } else { |
1939 | txs.flags |= IEEE80211_TX_STATUS_ACK; | 1935 | txs.flags |= IEEE80211_TX_STATUS_ACK; |
1940 | txs.ack_signal = ds->ds_txstat.ts_rssi; | 1936 | txs.ack_signal = ts.ts_rssi; |
1941 | } | 1937 | } |
1942 | 1938 | ||
1943 | ieee80211_tx_status(sc->hw, skb, &txs); | 1939 | ieee80211_tx_status(sc->hw, skb, &txs); |