diff options
Diffstat (limited to 'drivers/net/wireless/rtl8180_dev.c')
-rw-r--r-- | drivers/net/wireless/rtl8180_dev.c | 103 |
1 files changed, 70 insertions, 33 deletions
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 5e9a8ace0d81..b1b3a478335b 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -49,6 +49,41 @@ static struct pci_device_id rtl8180_table[] __devinitdata = { | |||
49 | 49 | ||
50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); | 50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); |
51 | 51 | ||
52 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
53 | { .bitrate = 10, .hw_value = 0, }, | ||
54 | { .bitrate = 20, .hw_value = 1, }, | ||
55 | { .bitrate = 55, .hw_value = 2, }, | ||
56 | { .bitrate = 110, .hw_value = 3, }, | ||
57 | { .bitrate = 60, .hw_value = 4, }, | ||
58 | { .bitrate = 90, .hw_value = 5, }, | ||
59 | { .bitrate = 120, .hw_value = 6, }, | ||
60 | { .bitrate = 180, .hw_value = 7, }, | ||
61 | { .bitrate = 240, .hw_value = 8, }, | ||
62 | { .bitrate = 360, .hw_value = 9, }, | ||
63 | { .bitrate = 480, .hw_value = 10, }, | ||
64 | { .bitrate = 540, .hw_value = 11, }, | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
68 | { .center_freq = 2412 }, | ||
69 | { .center_freq = 2417 }, | ||
70 | { .center_freq = 2422 }, | ||
71 | { .center_freq = 2427 }, | ||
72 | { .center_freq = 2432 }, | ||
73 | { .center_freq = 2437 }, | ||
74 | { .center_freq = 2442 }, | ||
75 | { .center_freq = 2447 }, | ||
76 | { .center_freq = 2452 }, | ||
77 | { .center_freq = 2457 }, | ||
78 | { .center_freq = 2462 }, | ||
79 | { .center_freq = 2467 }, | ||
80 | { .center_freq = 2472 }, | ||
81 | { .center_freq = 2484 }, | ||
82 | }; | ||
83 | |||
84 | |||
85 | |||
86 | |||
52 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | 87 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) |
53 | { | 88 | { |
54 | struct rtl8180_priv *priv = dev->priv; | 89 | struct rtl8180_priv *priv = dev->priv; |
@@ -99,10 +134,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
99 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
100 | rx_status.signal = flags2 & 0xFF; | 135 | rx_status.signal = flags2 & 0xFF; |
101 | rx_status.ssi = (flags2 >> 8) & 0x7F; | 136 | rx_status.ssi = (flags2 >> 8) & 0x7F; |
102 | rx_status.rate = (flags >> 20) & 0xF; | 137 | /* XXX: is this correct? */ |
103 | rx_status.freq = dev->conf.freq; | 138 | rx_status.rate_idx = (flags >> 20) & 0xF; |
104 | rx_status.channel = dev->conf.channel; | 139 | rx_status.freq = dev->conf.channel->center_freq; |
105 | rx_status.phymode = dev->conf.phymode; | 140 | rx_status.band = dev->conf.channel->band; |
106 | rx_status.mactime = le64_to_cpu(entry->tsft); | 141 | rx_status.mactime = le64_to_cpu(entry->tsft); |
107 | rx_status.flag |= RX_FLAG_TSFT; | 142 | rx_status.flag |= RX_FLAG_TSFT; |
108 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) | 143 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) |
@@ -222,18 +257,25 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
222 | mapping = pci_map_single(priv->pdev, skb->data, | 257 | mapping = pci_map_single(priv->pdev, skb->data, |
223 | skb->len, PCI_DMA_TODEVICE); | 258 | skb->len, PCI_DMA_TODEVICE); |
224 | 259 | ||
260 | BUG_ON(!control->tx_rate); | ||
261 | |||
225 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | | 262 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | |
226 | RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) | | 263 | RTL8180_TX_DESC_FLAG_LS | |
227 | (control->rts_cts_rate << 19) | skb->len; | 264 | (control->tx_rate->hw_value << 24) | skb->len; |
228 | 265 | ||
229 | if (priv->r8185) | 266 | if (priv->r8185) |
230 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | | 267 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | |
231 | RTL8180_TX_DESC_FLAG_NO_ENC; | 268 | RTL8180_TX_DESC_FLAG_NO_ENC; |
232 | 269 | ||
233 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 270 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
271 | BUG_ON(!control->rts_cts_rate); | ||
234 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; | 272 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; |
235 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 273 | tx_flags |= control->rts_cts_rate->hw_value << 19; |
274 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | ||
275 | BUG_ON(!control->rts_cts_rate); | ||
236 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; | 276 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; |
277 | tx_flags |= control->rts_cts_rate->hw_value << 19; | ||
278 | } | ||
237 | 279 | ||
238 | *((struct ieee80211_tx_control **) skb->cb) = | 280 | *((struct ieee80211_tx_control **) skb->cb) = |
239 | kmemdup(control, sizeof(*control), GFP_ATOMIC); | 281 | kmemdup(control, sizeof(*control), GFP_ATOMIC); |
@@ -246,9 +288,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
246 | unsigned int remainder; | 288 | unsigned int remainder; |
247 | 289 | ||
248 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), | 290 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), |
249 | (control->rate->rate * 2) / 10); | 291 | (control->tx_rate->bitrate * 2) / 10); |
250 | remainder = (16 * (skb->len + 4)) % | 292 | remainder = (16 * (skb->len + 4)) % |
251 | ((control->rate->rate * 2) / 10); | 293 | ((control->tx_rate->bitrate * 2) / 10); |
252 | if (remainder > 0 && remainder <= 6) | 294 | if (remainder > 0 && remainder <= 6) |
253 | plcp_len |= 1 << 15; | 295 | plcp_len |= 1 << 15; |
254 | } | 296 | } |
@@ -261,8 +303,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
261 | entry->plcp_len = cpu_to_le16(plcp_len); | 303 | entry->plcp_len = cpu_to_le16(plcp_len); |
262 | entry->tx_buf = cpu_to_le32(mapping); | 304 | entry->tx_buf = cpu_to_le32(mapping); |
263 | entry->frame_len = cpu_to_le32(skb->len); | 305 | entry->frame_len = cpu_to_le32(skb->len); |
264 | entry->flags2 = control->alt_retry_rate != -1 ? | 306 | entry->flags2 = control->alt_retry_rate != NULL ? |
265 | control->alt_retry_rate << 4 : 0; | 307 | control->alt_retry_rate->bitrate << 4 : 0; |
266 | entry->retry_limit = control->retry_limit; | 308 | entry->retry_limit = control->retry_limit; |
267 | entry->flags = cpu_to_le32(tx_flags); | 309 | entry->flags = cpu_to_le32(tx_flags); |
268 | __skb_queue_tail(&ring->queue, skb); | 310 | __skb_queue_tail(&ring->queue, skb); |
@@ -838,19 +880,19 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
838 | goto err_free_dev; | 880 | goto err_free_dev; |
839 | } | 881 | } |
840 | 882 | ||
883 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); | ||
884 | BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); | ||
885 | |||
841 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); | 886 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); |
842 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); | 887 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); |
843 | priv->modes[0].mode = MODE_IEEE80211G; | 888 | |
844 | priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); | 889 | priv->band.band = IEEE80211_BAND_2GHZ; |
845 | priv->modes[0].rates = priv->rates; | 890 | priv->band.channels = priv->channels; |
846 | priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); | 891 | priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); |
847 | priv->modes[0].channels = priv->channels; | 892 | priv->band.bitrates = priv->rates; |
848 | priv->modes[1].mode = MODE_IEEE80211B; | 893 | priv->band.n_bitrates = 4; |
849 | priv->modes[1].num_rates = 4; | 894 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
850 | priv->modes[1].rates = priv->rates; | 895 | |
851 | priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); | ||
852 | priv->modes[1].channels = priv->channels; | ||
853 | priv->mode = IEEE80211_IF_TYPE_INVALID; | ||
854 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 896 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
855 | IEEE80211_HW_RX_INCLUDES_FCS; | 897 | IEEE80211_HW_RX_INCLUDES_FCS; |
856 | dev->queues = 1; | 898 | dev->queues = 1; |
@@ -879,15 +921,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
879 | 921 | ||
880 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; | 922 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; |
881 | if (priv->r8185) { | 923 | if (priv->r8185) { |
882 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[0]))) | 924 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
883 | goto err_iounmap; | ||
884 | |||
885 | pci_try_set_mwi(pdev); | 925 | pci_try_set_mwi(pdev); |
886 | } | 926 | } |
887 | 927 | ||
888 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[1]))) | ||
889 | goto err_iounmap; | ||
890 | |||
891 | eeprom.data = dev; | 928 | eeprom.data = dev; |
892 | eeprom.register_read = rtl8180_eeprom_register_read; | 929 | eeprom.register_read = rtl8180_eeprom_register_read; |
893 | eeprom.register_write = rtl8180_eeprom_register_write; | 930 | eeprom.register_write = rtl8180_eeprom_register_write; |
@@ -950,8 +987,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
950 | for (i = 0; i < 14; i += 2) { | 987 | for (i = 0; i < 14; i += 2) { |
951 | u16 txpwr; | 988 | u16 txpwr; |
952 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); | 989 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); |
953 | priv->channels[i].val = txpwr & 0xFF; | 990 | priv->channels[i].hw_value = txpwr & 0xFF; |
954 | priv->channels[i + 1].val = txpwr >> 8; | 991 | priv->channels[i + 1].hw_value = txpwr >> 8; |
955 | } | 992 | } |
956 | 993 | ||
957 | /* OFDM TX power */ | 994 | /* OFDM TX power */ |
@@ -959,8 +996,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
959 | for (i = 0; i < 14; i += 2) { | 996 | for (i = 0; i < 14; i += 2) { |
960 | u16 txpwr; | 997 | u16 txpwr; |
961 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); | 998 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); |
962 | priv->channels[i].val |= (txpwr & 0xFF) << 8; | 999 | priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; |
963 | priv->channels[i + 1].val |= txpwr & 0xFF00; | 1000 | priv->channels[i + 1].hw_value |= txpwr & 0xFF00; |
964 | } | 1001 | } |
965 | } | 1002 | } |
966 | 1003 | ||