aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c167
1 files changed, 125 insertions, 42 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8dce0077b023..53a2340f52bc 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -198,7 +198,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
198static int ath5k_pci_suspend(struct device *dev); 198static int ath5k_pci_suspend(struct device *dev);
199static int ath5k_pci_resume(struct device *dev); 199static int ath5k_pci_resume(struct device *dev);
200 200
201SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); 201static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
202#define ATH5K_PM_OPS (&ath5k_pm_ops) 202#define ATH5K_PM_OPS (&ath5k_pm_ops)
203#else 203#else
204#define ATH5K_PM_OPS NULL 204#define ATH5K_PM_OPS NULL
@@ -230,7 +230,7 @@ static void ath5k_remove_interface(struct ieee80211_hw *hw,
230 struct ieee80211_vif *vif); 230 struct ieee80211_vif *vif);
231static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 231static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
233 int mc_count, struct dev_addr_list *mc_list); 233 struct netdev_hw_addr_list *mc_list);
234static void ath5k_configure_filter(struct ieee80211_hw *hw, 234static void ath5k_configure_filter(struct ieee80211_hw *hw,
235 unsigned int changed_flags, 235 unsigned int changed_flags,
236 unsigned int *new_flags, 236 unsigned int *new_flags,
@@ -307,7 +307,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
307 struct ath5k_buf *bf); 307 struct ath5k_buf *bf);
308static int ath5k_txbuf_setup(struct ath5k_softc *sc, 308static int ath5k_txbuf_setup(struct ath5k_softc *sc,
309 struct ath5k_buf *bf, 309 struct ath5k_buf *bf,
310 struct ath5k_txq *txq); 310 struct ath5k_txq *txq, int padsize);
311static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 311static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
312 struct ath5k_buf *bf) 312 struct ath5k_buf *bf)
313{ 313{
@@ -1137,8 +1137,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1137 struct ath5k_hw *ah = sc->ah; 1137 struct ath5k_hw *ah = sc->ah;
1138 u32 rfilt; 1138 u32 rfilt;
1139 1139
1140 ah->ah_op_mode = sc->opmode;
1141
1142 /* configure rx filter */ 1140 /* configure rx filter */
1143 rfilt = sc->filter_flags; 1141 rfilt = sc->filter_flags;
1144 ath5k_hw_set_rx_filter(ah, rfilt); 1142 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1147,8 +1145,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1147 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 1145 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1148 1146
1149 /* configure operational mode */ 1147 /* configure operational mode */
1150 ath5k_hw_set_opmode(ah); 1148 ath5k_hw_set_opmode(ah, sc->opmode);
1151 1149
1150 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 1151 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1153} 1152}
1154 1153
@@ -1271,7 +1270,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1271 1270
1272static int 1271static int
1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1272ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1274 struct ath5k_txq *txq) 1273 struct ath5k_txq *txq, int padsize)
1275{ 1274{
1276 struct ath5k_hw *ah = sc->ah; 1275 struct ath5k_hw *ah = sc->ah;
1277 struct ath5k_desc *ds = bf->desc; 1276 struct ath5k_desc *ds = bf->desc;
@@ -1323,7 +1322,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1323 sc->vif, pktlen, info)); 1322 sc->vif, pktlen, info));
1324 } 1323 }
1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1324 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1326 ieee80211_get_hdrlen_from_skb(skb), 1325 ieee80211_get_hdrlen_from_skb(skb), padsize,
1327 get_hw_packet_type(skb), 1326 get_hw_packet_type(skb),
1328 (sc->power_level * 2), 1327 (sc->power_level * 2),
1329 hw_rate, 1328 hw_rate,
@@ -1805,6 +1804,67 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1805 } 1804 }
1806} 1805}
1807 1806
1807/*
1808 * Compute padding position. skb must contains an IEEE 802.11 frame
1809 */
1810static int ath5k_common_padpos(struct sk_buff *skb)
1811{
1812 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1813 __le16 frame_control = hdr->frame_control;
1814 int padpos = 24;
1815
1816 if (ieee80211_has_a4(frame_control)) {
1817 padpos += ETH_ALEN;
1818 }
1819 if (ieee80211_is_data_qos(frame_control)) {
1820 padpos += IEEE80211_QOS_CTL_LEN;
1821 }
1822
1823 return padpos;
1824}
1825
1826/*
1827 * This function expects a 802.11 frame and returns the number of
1828 * bytes added, or -1 if we don't have enought header room.
1829 */
1830
1831static int ath5k_add_padding(struct sk_buff *skb)
1832{
1833 int padpos = ath5k_common_padpos(skb);
1834 int padsize = padpos & 3;
1835
1836 if (padsize && skb->len>padpos) {
1837
1838 if (skb_headroom(skb) < padsize)
1839 return -1;
1840
1841 skb_push(skb, padsize);
1842 memmove(skb->data, skb->data+padsize, padpos);
1843 return padsize;
1844 }
1845
1846 return 0;
1847}
1848
1849/*
1850 * This function expects a 802.11 frame and returns the number of
1851 * bytes removed
1852 */
1853
1854static int ath5k_remove_padding(struct sk_buff *skb)
1855{
1856 int padpos = ath5k_common_padpos(skb);
1857 int padsize = padpos & 3;
1858
1859 if (padsize && skb->len>=padpos+padsize) {
1860 memmove(skb->data + padsize, skb->data, padpos);
1861 skb_pull(skb, padsize);
1862 return padsize;
1863 }
1864
1865 return 0;
1866}
1867
1808static void 1868static void
1809ath5k_tasklet_rx(unsigned long data) 1869ath5k_tasklet_rx(unsigned long data)
1810{ 1870{
@@ -1818,8 +1878,6 @@ ath5k_tasklet_rx(unsigned long data)
1818 struct ath5k_buf *bf; 1878 struct ath5k_buf *bf;
1819 struct ath5k_desc *ds; 1879 struct ath5k_desc *ds;
1820 int ret; 1880 int ret;
1821 int hdrlen;
1822 int padsize;
1823 int rx_flag; 1881 int rx_flag;
1824 1882
1825 spin_lock(&sc->rxbuflock); 1883 spin_lock(&sc->rxbuflock);
@@ -1844,18 +1902,28 @@ ath5k_tasklet_rx(unsigned long data)
1844 break; 1902 break;
1845 else if (unlikely(ret)) { 1903 else if (unlikely(ret)) {
1846 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 1904 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1905 sc->stats.rxerr_proc++;
1847 spin_unlock(&sc->rxbuflock); 1906 spin_unlock(&sc->rxbuflock);
1848 return; 1907 return;
1849 } 1908 }
1850 1909
1910 sc->stats.rx_all_count++;
1911
1851 if (unlikely(rs.rs_more)) { 1912 if (unlikely(rs.rs_more)) {
1852 ATH5K_WARN(sc, "unsupported jumbo\n"); 1913 ATH5K_WARN(sc, "unsupported jumbo\n");
1914 sc->stats.rxerr_jumbo++;
1853 goto next; 1915 goto next;
1854 } 1916 }
1855 1917
1856 if (unlikely(rs.rs_status)) { 1918 if (unlikely(rs.rs_status)) {
1857 if (rs.rs_status & AR5K_RXERR_PHY) 1919 if (rs.rs_status & AR5K_RXERR_CRC)
1920 sc->stats.rxerr_crc++;
1921 if (rs.rs_status & AR5K_RXERR_FIFO)
1922 sc->stats.rxerr_fifo++;
1923 if (rs.rs_status & AR5K_RXERR_PHY) {
1924 sc->stats.rxerr_phy++;
1858 goto next; 1925 goto next;
1926 }
1859 if (rs.rs_status & AR5K_RXERR_DECRYPT) { 1927 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1860 /* 1928 /*
1861 * Decrypt error. If the error occurred 1929 * Decrypt error. If the error occurred
@@ -1867,12 +1935,14 @@ ath5k_tasklet_rx(unsigned long data)
1867 * 1935 *
1868 * XXX do key cache faulting 1936 * XXX do key cache faulting
1869 */ 1937 */
1938 sc->stats.rxerr_decrypt++;
1870 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && 1939 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1871 !(rs.rs_status & AR5K_RXERR_CRC)) 1940 !(rs.rs_status & AR5K_RXERR_CRC))
1872 goto accept; 1941 goto accept;
1873 } 1942 }
1874 if (rs.rs_status & AR5K_RXERR_MIC) { 1943 if (rs.rs_status & AR5K_RXERR_MIC) {
1875 rx_flag |= RX_FLAG_MMIC_ERROR; 1944 rx_flag |= RX_FLAG_MMIC_ERROR;
1945 sc->stats.rxerr_mic++;
1876 goto accept; 1946 goto accept;
1877 } 1947 }
1878 1948
@@ -1904,12 +1974,8 @@ accept:
1904 * bytes and we can optimize this a bit. In addition, we must 1974 * bytes and we can optimize this a bit. In addition, we must
1905 * not try to remove padding from short control frames that do 1975 * not try to remove padding from short control frames that do
1906 * not have payload. */ 1976 * not have payload. */
1907 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1977 ath5k_remove_padding(skb);
1908 padsize = ath5k_pad_size(hdrlen); 1978
1909 if (padsize) {
1910 memmove(skb->data + padsize, skb->data, hdrlen);
1911 skb_pull(skb, padsize);
1912 }
1913 rxs = IEEE80211_SKB_RXCB(skb); 1979 rxs = IEEE80211_SKB_RXCB(skb);
1914 1980
1915 /* 1981 /*
@@ -1942,6 +2008,12 @@ accept:
1942 rxs->signal = rxs->noise + rs.rs_rssi; 2008 rxs->signal = rxs->noise + rs.rs_rssi;
1943 2009
1944 rxs->antenna = rs.rs_antenna; 2010 rxs->antenna = rs.rs_antenna;
2011
2012 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2013 sc->stats.antenna_rx[rs.rs_antenna]++;
2014 else
2015 sc->stats.antenna_rx[0]++; /* invalid */
2016
1945 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 2017 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1946 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 2018 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1947 2019
@@ -1996,6 +2068,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1996 break; 2068 break;
1997 } 2069 }
1998 2070
2071 sc->stats.tx_all_count++;
1999 skb = bf->skb; 2072 skb = bf->skb;
2000 info = IEEE80211_SKB_CB(skb); 2073 info = IEEE80211_SKB_CB(skb);
2001 bf->skb = NULL; 2074 bf->skb = NULL;
@@ -2022,13 +2095,30 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2022 2095
2023 if (unlikely(ts.ts_status)) { 2096 if (unlikely(ts.ts_status)) {
2024 sc->ll_stats.dot11ACKFailureCount++; 2097 sc->ll_stats.dot11ACKFailureCount++;
2025 if (ts.ts_status & AR5K_TXERR_FILT) 2098 if (ts.ts_status & AR5K_TXERR_FILT) {
2026 info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2099 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2100 sc->stats.txerr_filt++;
2101 }
2102 if (ts.ts_status & AR5K_TXERR_XRETRY)
2103 sc->stats.txerr_retry++;
2104 if (ts.ts_status & AR5K_TXERR_FIFO)
2105 sc->stats.txerr_fifo++;
2027 } else { 2106 } else {
2028 info->flags |= IEEE80211_TX_STAT_ACK; 2107 info->flags |= IEEE80211_TX_STAT_ACK;
2029 info->status.ack_signal = ts.ts_rssi; 2108 info->status.ack_signal = ts.ts_rssi;
2030 } 2109 }
2031 2110
2111 /*
2112 * Remove MAC header padding before giving the frame
2113 * back to mac80211.
2114 */
2115 ath5k_remove_padding(skb);
2116
2117 if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
2118 sc->stats.antenna_tx[ts.ts_antenna]++;
2119 else
2120 sc->stats.antenna_tx[0]++; /* invalid */
2121
2032 ieee80211_tx_status(sc->hw, skb); 2122 ieee80211_tx_status(sc->hw, skb);
2033 2123
2034 spin_lock(&sc->txbuflock); 2124 spin_lock(&sc->txbuflock);
@@ -2072,6 +2162,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2072 int ret = 0; 2162 int ret = 0;
2073 u8 antenna; 2163 u8 antenna;
2074 u32 flags; 2164 u32 flags;
2165 const int padsize = 0;
2075 2166
2076 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2167 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
2077 PCI_DMA_TODEVICE); 2168 PCI_DMA_TODEVICE);
@@ -2119,7 +2210,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2119 * from tx power (value is in dB units already) */ 2210 * from tx power (value is in dB units already) */
2120 ds->ds_data = bf->skbaddr; 2211 ds->ds_data = bf->skbaddr;
2121 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2212 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2122 ieee80211_get_hdrlen_from_skb(skb), 2213 ieee80211_get_hdrlen_from_skb(skb), padsize,
2123 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2214 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2124 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 2215 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2125 1, AR5K_TXKEYIX_INVALID, 2216 1, AR5K_TXKEYIX_INVALID,
@@ -2679,7 +2770,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2679 struct ath5k_softc *sc = hw->priv; 2770 struct ath5k_softc *sc = hw->priv;
2680 struct ath5k_buf *bf; 2771 struct ath5k_buf *bf;
2681 unsigned long flags; 2772 unsigned long flags;
2682 int hdrlen;
2683 int padsize; 2773 int padsize;
2684 2774
2685 ath5k_debug_dump_skb(sc, skb, "TX ", 1); 2775 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
@@ -2691,17 +2781,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2691 * the hardware expects the header padded to 4 byte boundaries 2781 * the hardware expects the header padded to 4 byte boundaries
2692 * if this is not the case we add the padding after the header 2782 * if this is not the case we add the padding after the header
2693 */ 2783 */
2694 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2784 padsize = ath5k_add_padding(skb);
2695 padsize = ath5k_pad_size(hdrlen); 2785 if (padsize < 0) {
2696 if (padsize) { 2786 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
2697 2787 " headroom to pad");
2698 if (skb_headroom(skb) < padsize) { 2788 goto drop_packet;
2699 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2700 " headroom to pad %d\n", hdrlen, padsize);
2701 goto drop_packet;
2702 }
2703 skb_push(skb, padsize);
2704 memmove(skb->data, skb->data+padsize, hdrlen);
2705 } 2789 }
2706 2790
2707 spin_lock_irqsave(&sc->txbuflock, flags); 2791 spin_lock_irqsave(&sc->txbuflock, flags);
@@ -2720,7 +2804,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2720 2804
2721 bf->skb = skb; 2805 bf->skb = skb;
2722 2806
2723 if (ath5k_txbuf_setup(sc, bf, txq)) { 2807 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
2724 bf->skb = NULL; 2808 bf->skb = NULL;
2725 spin_lock_irqsave(&sc->txbuflock, flags); 2809 spin_lock_irqsave(&sc->txbuflock, flags);
2726 list_add_tail(&bf->list, &sc->txbuf); 2810 list_add_tail(&bf->list, &sc->txbuf);
@@ -2835,6 +2919,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2835 goto end; 2919 goto end;
2836 } 2920 }
2837 2921
2922 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
2923
2838 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2924 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2839 ath5k_mode_setup(sc); 2925 ath5k_mode_setup(sc);
2840 2926
@@ -2905,7 +2991,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2905 * then we must allow the user to set how many tx antennas we 2991 * then we must allow the user to set how many tx antennas we
2906 * have available 2992 * have available
2907 */ 2993 */
2908 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 2994 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
2909 2995
2910unlock: 2996unlock:
2911 mutex_unlock(&sc->lock); 2997 mutex_unlock(&sc->lock);
@@ -2913,22 +2999,20 @@ unlock:
2913} 2999}
2914 3000
2915static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 3001static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2916 int mc_count, struct dev_addr_list *mclist) 3002 struct netdev_hw_addr_list *mc_list)
2917{ 3003{
2918 u32 mfilt[2], val; 3004 u32 mfilt[2], val;
2919 int i;
2920 u8 pos; 3005 u8 pos;
3006 struct netdev_hw_addr *ha;
2921 3007
2922 mfilt[0] = 0; 3008 mfilt[0] = 0;
2923 mfilt[1] = 1; 3009 mfilt[1] = 1;
2924 3010
2925 for (i = 0; i < mc_count; i++) { 3011 netdev_hw_addr_list_for_each(ha, mc_list) {
2926 if (!mclist)
2927 break;
2928 /* calculate XOR of eight 6-bit values */ 3012 /* calculate XOR of eight 6-bit values */
2929 val = get_unaligned_le32(mclist->dmi_addr + 0); 3013 val = get_unaligned_le32(ha->addr + 0);
2930 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3014 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2931 val = get_unaligned_le32(mclist->dmi_addr + 3); 3015 val = get_unaligned_le32(ha->addr + 3);
2932 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3016 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2933 pos &= 0x3f; 3017 pos &= 0x3f;
2934 mfilt[pos / 32] |= (1 << (pos % 32)); 3018 mfilt[pos / 32] |= (1 << (pos % 32));
@@ -2936,8 +3020,7 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2936 * but not sure, needs testing, if we do use this we'd 3020 * but not sure, needs testing, if we do use this we'd
2937 * neet to inform below to not reset the mcast */ 3021 * neet to inform below to not reset the mcast */
2938 /* ath5k_hw_set_mcast_filterindex(ah, 3022 /* ath5k_hw_set_mcast_filterindex(ah,
2939 * mclist->dmi_addr[5]); */ 3023 * ha->addr[5]); */
2940 mclist = mclist->next;
2941 } 3024 }
2942 3025
2943 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 3026 return ((u64)(mfilt[1]) << 32) | mfilt[0];